/*
 * Copyright (C) 2010, 2016 Apple Inc. All rights reserved.
 * Copyright (C) 2010 Google Inc. All rights reserved.
 * Copyright (C) 2010 Mozilla Corporation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 */

#include "config.h"
#include "GraphicsContextGL.h"
#include "GraphicsContextGLOpenGL.h"

#if ENABLE(WEBGL)

#include "FormatConverter.h"
#include "HostWindow.h"
#include "Image.h"
#include "ImageObserver.h"
#include "PixelBuffer.h"

namespace WebCore {

static GraphicsContextGL::DataFormat getDataFormat(GCGLenum destinationFormat, GCGLenum destinationType)
{
    switch (destinationType) {
    case GraphicsContextGL::BYTE:
        switch (destinationFormat) {
        case GraphicsContextGL::RED:
        case GraphicsContextGL::RED_INTEGER:
            return GraphicsContextGL::DataFormat::R8_S;
        case GraphicsContextGL::RG:
        case GraphicsContextGL::RG_INTEGER:
            return GraphicsContextGL::DataFormat::RG8_S;
        case GraphicsContextGL::RGB:
        case GraphicsContextGL::RGB_INTEGER:
            return GraphicsContextGL::DataFormat::RGB8_S;
        case GraphicsContextGL::RGBA:
        case GraphicsContextGL::RGBA_INTEGER:
            return GraphicsContextGL::DataFormat::RGBA8_S;
        default:
            return GraphicsContextGL::DataFormat::Invalid;
        }
    case GraphicsContextGL::UNSIGNED_BYTE:
        switch (destinationFormat) {
        case GraphicsContextGL::RGB:
        case GraphicsContextGL::RGB_INTEGER:
        case GraphicsContextGL::SRGB:
            return GraphicsContextGL::GraphicsContextGL::DataFormat::RGB8;
        case GraphicsContextGL::RGBA:
        case GraphicsContextGL::RGBA_INTEGER:
        case GraphicsContextGL::SRGB_ALPHA:
            return GraphicsContextGL::DataFormat::RGBA8;
        case GraphicsContextGL::ALPHA:
            return GraphicsContextGL::DataFormat::A8;
        case GraphicsContextGL::LUMINANCE:
        case GraphicsContextGL::RED:
        case GraphicsContextGL::RED_INTEGER:
            return GraphicsContextGL::DataFormat::R8;
        case GraphicsContextGL::RG:
        case GraphicsContextGL::RG_INTEGER:
            return GraphicsContextGL::DataFormat::RG8;
        case GraphicsContextGL::LUMINANCE_ALPHA:
            return GraphicsContextGL::DataFormat::RA8;
        default:
            return GraphicsContextGL::DataFormat::Invalid;
        }
    case GraphicsContextGL::SHORT:
        switch (destinationFormat) {
        case GraphicsContextGL::RED_INTEGER:
            return GraphicsContextGL::DataFormat::R16_S;
        case GraphicsContextGL::RG_INTEGER:
            return GraphicsContextGL::DataFormat::RG16_S;
        case GraphicsContextGL::RGB_INTEGER:
            return GraphicsContextGL::DataFormat::RGB16_S;
        case GraphicsContextGL::RGBA_INTEGER:
            return GraphicsContextGL::DataFormat::RGBA16_S;
        default:
            return GraphicsContextGL::DataFormat::Invalid;
        }
    case GraphicsContextGL::UNSIGNED_SHORT:
        switch (destinationFormat) {
        case GraphicsContextGL::RED_INTEGER:
            return GraphicsContextGL::DataFormat::R16;
        case GraphicsContextGL::DEPTH_COMPONENT:
            return GraphicsContextGL::DataFormat::D16;
        case GraphicsContextGL::RG_INTEGER:
            return GraphicsContextGL::DataFormat::RG16;
        case GraphicsContextGL::RGB_INTEGER:
            return GraphicsContextGL::DataFormat::RGB16;
        case GraphicsContextGL::RGBA_INTEGER:
            return GraphicsContextGL::DataFormat::RGBA16;
        default:
            return GraphicsContextGL::DataFormat::Invalid;
        }
    case GraphicsContextGL::INT:
        switch (destinationFormat) {
        case GraphicsContextGL::RED_INTEGER:
            return GraphicsContextGL::DataFormat::R32_S;
        case GraphicsContextGL::RG_INTEGER:
            return GraphicsContextGL::DataFormat::RG32_S;
        case GraphicsContextGL::RGB_INTEGER:
            return GraphicsContextGL::DataFormat::RGB32_S;
        case GraphicsContextGL::RGBA_INTEGER:
            return GraphicsContextGL::DataFormat::RGBA32_S;
        default:
            return GraphicsContextGL::DataFormat::Invalid;
        }
    case GraphicsContextGL::UNSIGNED_INT:
        switch (destinationFormat) {
        case GraphicsContextGL::RED_INTEGER:
            return GraphicsContextGL::DataFormat::R32;
        case GraphicsContextGL::DEPTH_COMPONENT:
            return GraphicsContextGL::DataFormat::D32;
        case GraphicsContextGL::RG_INTEGER:
            return GraphicsContextGL::DataFormat::RG32;
        case GraphicsContextGL::RGB_INTEGER:
            return GraphicsContextGL::DataFormat::RGB32;
        case GraphicsContextGL::RGBA_INTEGER:
            return GraphicsContextGL::DataFormat::RGBA32;
        default:
            return GraphicsContextGL::DataFormat::Invalid;
        }
    case GraphicsContextGL::HALF_FLOAT_OES: // OES_texture_half_float
    case GraphicsContextGL::HALF_FLOAT:
        switch (destinationFormat) {
        case GraphicsContextGL::RGBA:
            return GraphicsContextGL::DataFormat::RGBA16F;
        case GraphicsContextGL::RGB:
            return GraphicsContextGL::DataFormat::RGB16F;
        case GraphicsContextGL::RG:
            return GraphicsContextGL::DataFormat::RG16F;
        case GraphicsContextGL::ALPHA:
            return GraphicsContextGL::DataFormat::A16F;
        case GraphicsContextGL::LUMINANCE:
        case GraphicsContextGL::RED:
            return GraphicsContextGL::DataFormat::R16F;
        case GraphicsContextGL::LUMINANCE_ALPHA:
            return GraphicsContextGL::DataFormat::RA16F;
        case GraphicsContextGL::SRGB:
            return GraphicsContextGL::DataFormat::RGB16F;
        case GraphicsContextGL::SRGB_ALPHA:
            return GraphicsContextGL::DataFormat::RGBA16F;
        default:
            return GraphicsContextGL::DataFormat::Invalid;
        }
    case GraphicsContextGL::FLOAT: // OES_texture_float
        switch (destinationFormat) {
        case GraphicsContextGL::RGBA:
            return GraphicsContextGL::DataFormat::RGBA32F;
        case GraphicsContextGL::RGB:
            return GraphicsContextGL::DataFormat::RGB32F;
        case GraphicsContextGL::RG:
            return GraphicsContextGL::DataFormat::RG32F;
        case GraphicsContextGL::ALPHA:
            return GraphicsContextGL::DataFormat::A32F;
        case GraphicsContextGL::LUMINANCE:
        case GraphicsContextGL::RED:
            return GraphicsContextGL::DataFormat::R32F;
        case GraphicsContextGL::DEPTH_COMPONENT:
            return GraphicsContextGL::DataFormat::D32F;
        case GraphicsContextGL::LUMINANCE_ALPHA:
            return GraphicsContextGL::DataFormat::RA32F;
        case GraphicsContextGL::SRGB:
            return GraphicsContextGL::DataFormat::RGB32F;
        case GraphicsContextGL::SRGB_ALPHA:
            return GraphicsContextGL::DataFormat::RGBA32F;
        default:
            return GraphicsContextGL::DataFormat::Invalid;
        }
    case GraphicsContextGL::UNSIGNED_SHORT_4_4_4_4:
        return GraphicsContextGL::DataFormat::RGBA4444;
    case GraphicsContextGL::UNSIGNED_SHORT_5_5_5_1:
        return GraphicsContextGL::DataFormat::RGBA5551;
    case GraphicsContextGL::UNSIGNED_SHORT_5_6_5:
        return GraphicsContextGL::DataFormat::RGB565;
    case GraphicsContextGL::UNSIGNED_INT_5_9_9_9_REV:
        return GraphicsContextGL::DataFormat::RGB5999;
    case GraphicsContextGL::UNSIGNED_INT_24_8:
        return GraphicsContextGL::DataFormat::DS24_8;
    case GraphicsContextGL::UNSIGNED_INT_10F_11F_11F_REV:
        return GraphicsContextGL::DataFormat::RGB10F11F11F;
    case GraphicsContextGL::UNSIGNED_INT_2_10_10_10_REV:
        return GraphicsContextGL::DataFormat::RGBA2_10_10_10;
    default:
        return GraphicsContextGL::DataFormat::Invalid;
    }
    ASSERT_NOT_REACHED();
    return GraphicsContextGL::DataFormat::Invalid;
}

ALWAYS_INLINE static unsigned texelBytesForFormat(GraphicsContextGL::DataFormat format)
{
    switch (format) {
    case GraphicsContextGL::DataFormat::R8:
    case GraphicsContextGL::DataFormat::R8_S:
    case GraphicsContextGL::DataFormat::A8:
        return 1;
    case GraphicsContextGL::DataFormat::RG8:
    case GraphicsContextGL::DataFormat::RG8_S:
    case GraphicsContextGL::DataFormat::RA8:
    case GraphicsContextGL::DataFormat::AR8:
    case GraphicsContextGL::DataFormat::RGBA5551:
    case GraphicsContextGL::DataFormat::RGBA4444:
    case GraphicsContextGL::DataFormat::RGB565:
    case GraphicsContextGL::DataFormat::A16F:
    case GraphicsContextGL::DataFormat::R16:
    case GraphicsContextGL::DataFormat::R16_S:
    case GraphicsContextGL::DataFormat::R16F:
    case GraphicsContextGL::DataFormat::D16:
        return 2;
    case GraphicsContextGL::DataFormat::RGB8:
    case GraphicsContextGL::DataFormat::RGB8_S:
    case GraphicsContextGL::DataFormat::BGR8:
        return 3;
    case GraphicsContextGL::DataFormat::RGBA8:
    case GraphicsContextGL::DataFormat::RGBA8_S:
    case GraphicsContextGL::DataFormat::ARGB8:
    case GraphicsContextGL::DataFormat::ABGR8:
    case GraphicsContextGL::DataFormat::BGRA8:
    case GraphicsContextGL::DataFormat::R32:
    case GraphicsContextGL::DataFormat::R32_S:
    case GraphicsContextGL::DataFormat::R32F:
    case GraphicsContextGL::DataFormat::A32F:
    case GraphicsContextGL::DataFormat::RA16F:
    case GraphicsContextGL::DataFormat::RGBA2_10_10_10:
    case GraphicsContextGL::DataFormat::RGB10F11F11F:
    case GraphicsContextGL::DataFormat::RGB5999:
    case GraphicsContextGL::DataFormat::RG16:
    case GraphicsContextGL::DataFormat::RG16_S:
    case GraphicsContextGL::DataFormat::RG16F:
    case GraphicsContextGL::DataFormat::D32:
    case GraphicsContextGL::DataFormat::D32F:
    case GraphicsContextGL::DataFormat::DS24_8:
        return 4;
    case GraphicsContextGL::DataFormat::RGB16:
    case GraphicsContextGL::DataFormat::RGB16_S:
    case GraphicsContextGL::DataFormat::RGB16F:
        return 6;
    case GraphicsContextGL::DataFormat::RGBA16:
    case GraphicsContextGL::DataFormat::RGBA16_S:
    case GraphicsContextGL::DataFormat::RA32F:
    case GraphicsContextGL::DataFormat::RGBA16F:
    case GraphicsContextGL::DataFormat::RG32:
    case GraphicsContextGL::DataFormat::RG32_S:
    case GraphicsContextGL::DataFormat::RG32F:
        return 8;
    case GraphicsContextGL::DataFormat::RGB32:
    case GraphicsContextGL::DataFormat::RGB32_S:
    case GraphicsContextGL::DataFormat::RGB32F:
        return 12;
    case GraphicsContextGL::DataFormat::RGBA32:
    case GraphicsContextGL::DataFormat::RGBA32_S:
    case GraphicsContextGL::DataFormat::RGBA32F:
        return 16;
    default:
        return 0;
    }
}


// Helper for packImageData/extractImageData/extractTextureData which implement packing of pixel
// data into the specified OpenGL destination format and type.
// A sourceUnpackAlignment of zero indicates that the source
// data is tightly packed. Non-zero values may take a slow path.
// Destination data will have no gaps between rows.
static bool packPixels(const uint8_t* sourceData, GraphicsContextGL::DataFormat sourceDataFormat, unsigned sourceDataWidth, unsigned sourceDataHeight, const IntRect& sourceDataSubRectangle, int depth, unsigned sourceUnpackAlignment, int unpackImageHeight, unsigned destinationFormat, unsigned destinationType, GraphicsContextGL::AlphaOp alphaOp, void* destinationData, bool flipY)
{
    ASSERT(depth >= 1);
    UNUSED_PARAM(sourceDataHeight); // Derived from sourceDataSubRectangle.height().
    if (!unpackImageHeight)
        unpackImageHeight = sourceDataSubRectangle.height();
    int validSrc = sourceDataWidth * texelBytesForFormat(sourceDataFormat);
    int remainder = sourceUnpackAlignment ? (validSrc % sourceUnpackAlignment) : 0;
    int srcStride = remainder ? (validSrc + sourceUnpackAlignment - remainder) : validSrc;
    int srcRowOffset = sourceDataSubRectangle.x() * texelBytesForFormat(sourceDataFormat);

    GraphicsContextGL::DataFormat dstDataFormat = getDataFormat(destinationFormat, destinationType);
    if (dstDataFormat == GraphicsContextGL::DataFormat::Invalid)
        return false;
    int dstStride = sourceDataSubRectangle.width() * texelBytesForFormat(dstDataFormat);
    if (flipY) {
        destinationData = static_cast<uint8_t*>(destinationData) + dstStride * ((depth * sourceDataSubRectangle.height()) - 1);
        dstStride = -dstStride;
    }
    if (!GraphicsContextGL::hasAlpha(sourceDataFormat) || !GraphicsContextGL::hasColor(sourceDataFormat) || !GraphicsContextGL::hasColor(dstDataFormat))
        alphaOp = GraphicsContextGL::AlphaOp::DoNothing;

    if (sourceDataFormat == dstDataFormat && alphaOp == GraphicsContextGL::AlphaOp::DoNothing) {
        const uint8_t* basePtr = sourceData + srcStride * sourceDataSubRectangle.y();
        const uint8_t* baseEnd = sourceData + srcStride * sourceDataSubRectangle.maxY();

        // If packing multiple images into a 3D texture, and flipY is true,
        // then the sub-rectangle is pointing at the start of the
        // "bottommost" of those images. Since the source pointer strides in
        // the positive direction, we need to back it up to point at the
        // last, or "topmost", of these images.
        if (flipY && depth > 1) {
            const ptrdiff_t distanceToTopImage = (depth - 1) * srcStride * unpackImageHeight;
            basePtr -= distanceToTopImage;
            baseEnd -= distanceToTopImage;
        }

        unsigned rowSize = (dstStride > 0) ? dstStride: -dstStride;
        uint8_t* dst = static_cast<uint8_t*>(destinationData);

        for (int i = 0; i < depth; ++i) {
            const uint8_t* ptr = basePtr;
            const uint8_t* ptrEnd = baseEnd;
            while (ptr < ptrEnd) {
                memcpy(dst, ptr + srcRowOffset, rowSize);
                ptr += srcStride;
                dst += dstStride;
            }
            basePtr += unpackImageHeight * srcStride;
            baseEnd += unpackImageHeight * srcStride;
        }
        return true;
    }

    FormatConverter converter(
        sourceDataSubRectangle, depth,
        unpackImageHeight, sourceData, destinationData,
        srcStride, srcRowOffset, dstStride);
    converter.convert(sourceDataFormat, dstDataFormat, alphaOp);
    if (!converter.success())
        return false;
    return true;
}

GraphicsContextGL::Client::Client() = default;

GraphicsContextGL::Client::~Client() = default;

GraphicsContextGL::GraphicsContextGL(GraphicsContextGLAttributes attrs)
    : m_attrs(attrs)
{
}

GraphicsContextGL::~GraphicsContextGL() = default;

bool GraphicsContextGL::computeFormatAndTypeParameters(GCGLenum format, GCGLenum type, unsigned* componentsPerPixel, unsigned* bytesPerComponent)
{
    switch (format) {
    case GraphicsContextGL::ALPHA:
    case GraphicsContextGL::LUMINANCE:
    case GraphicsContextGL::RED:
    case GraphicsContextGL::RED_INTEGER:
    case GraphicsContextGL::DEPTH_COMPONENT:
    case GraphicsContextGL::DEPTH_STENCIL: // Treat it as one component.
        *componentsPerPixel = 1;
        break;
    case GraphicsContextGL::LUMINANCE_ALPHA:
    case GraphicsContextGL::RG:
    case GraphicsContextGL::RG_INTEGER:
        *componentsPerPixel = 2;
        break;
    case GraphicsContextGL::RGB:
    case GraphicsContextGL::RGB_INTEGER:
    case GraphicsContextGL::SRGB_EXT:
        *componentsPerPixel = 3;
        break;
    case GraphicsContextGL::RGBA:
    case GraphicsContextGL::RGBA_INTEGER:
    case GraphicsContextGL::BGRA_EXT: // GL_EXT_texture_format_BGRA8888
    case GraphicsContextGL::SRGB_ALPHA_EXT:
        *componentsPerPixel = 4;
        break;
    default:
        return false;
    }

    switch (type) {
    case GraphicsContextGL::BYTE:
        *bytesPerComponent = sizeof(GCGLbyte);
        break;
    case GraphicsContextGL::UNSIGNED_BYTE:
        *bytesPerComponent = sizeof(GCGLubyte);
        break;
    case GraphicsContextGL::SHORT:
        *bytesPerComponent = sizeof(GCGLshort);
        break;
    case GraphicsContextGL::UNSIGNED_SHORT:
        *bytesPerComponent = sizeof(GCGLushort);
        break;
    case GraphicsContextGL::UNSIGNED_SHORT_5_6_5:
    case GraphicsContextGL::UNSIGNED_SHORT_4_4_4_4:
    case GraphicsContextGL::UNSIGNED_SHORT_5_5_5_1:
        *componentsPerPixel = 1;
        *bytesPerComponent = sizeof(GCGLushort);
        break;
    case GraphicsContextGL::INT:
        *bytesPerComponent = sizeof(GCGLint);
        break;
    case GraphicsContextGL::UNSIGNED_INT:
        *bytesPerComponent = sizeof(GCGLuint);
        break;
    case GraphicsContextGL::UNSIGNED_INT_24_8:
    case GraphicsContextGL::UNSIGNED_INT_10F_11F_11F_REV:
    case GraphicsContextGL::UNSIGNED_INT_5_9_9_9_REV:
    case GraphicsContextGL::UNSIGNED_INT_2_10_10_10_REV:
        *componentsPerPixel = 1;
        *bytesPerComponent = sizeof(GCGLuint);
        break;
    case GraphicsContextGL::FLOAT: // OES_texture_float
        *bytesPerComponent = sizeof(GCGLfloat);
        break;
    case GraphicsContextGL::HALF_FLOAT:
    case GraphicsContextGL::HALF_FLOAT_OES: // OES_texture_half_float
        *bytesPerComponent = sizeof(GCGLhalffloat);
        break;
    case GraphicsContextGL::FLOAT_32_UNSIGNED_INT_24_8_REV:
        *bytesPerComponent = sizeof(GCGLfloat) + sizeof(GCGLuint);
        break;
    default:
        return false;
    }
    return true;
}

GCGLenum GraphicsContextGL::computeImageSizeInBytes(GCGLenum format, GCGLenum type, GCGLsizei width, GCGLsizei height, GCGLsizei depth, const PixelStoreParams& params, unsigned* imageSizeInBytes, unsigned* paddingInBytes, unsigned* skipSizeInBytes)
{
    ASSERT(imageSizeInBytes);
    ASSERT(params.alignment == 1 || params.alignment == 2 || params.alignment == 4 || params.alignment == 8);
    ASSERT(params.rowLength >= 0);
    ASSERT(params.imageHeight >= 0);
    ASSERT(params.skipPixels >= 0);
    ASSERT(params.skipRows >= 0);
    ASSERT(params.skipImages >= 0);
    if (width < 0 || height < 0 || depth < 0)
        return GraphicsContextGL::INVALID_VALUE;
    if (!width || !height || !depth) {
        *imageSizeInBytes = 0;
        if (paddingInBytes)
            *paddingInBytes = 0;
        if (skipSizeInBytes)
            *skipSizeInBytes = 0;
        return GraphicsContextGL::NO_ERROR;
    }

    int rowLength = params.rowLength > 0 ? params.rowLength : width;
    int imageHeight = params.imageHeight > 0 ? params.imageHeight : height;

    unsigned bytesPerComponent, componentsPerPixel;
    if (!computeFormatAndTypeParameters(format, type, &componentsPerPixel, &bytesPerComponent))
        return GraphicsContextGL::INVALID_ENUM;
    unsigned bytesPerGroup = bytesPerComponent * componentsPerPixel;
    CheckedUint32 checkedValue = static_cast<uint32_t>(rowLength);
    checkedValue *= bytesPerGroup;
    if (checkedValue.hasOverflowed())
        return GraphicsContextGL::INVALID_VALUE;

    unsigned lastRowSize;
    if (params.rowLength > 0 && params.rowLength != width) {
        CheckedUint32 tmp = width;
        tmp *= bytesPerGroup;
        if (tmp.hasOverflowed())
            return GraphicsContextGL::INVALID_VALUE;
        lastRowSize = tmp;
    } else
        lastRowSize = checkedValue;

    unsigned padding = 0;
    unsigned residual = checkedValue.value() % params.alignment;
    if (residual) {
        padding = params.alignment - residual;
        checkedValue += padding;
    }
    if (checkedValue.hasOverflowed())
        return GraphicsContextGL::INVALID_VALUE;
    unsigned paddedRowSize = checkedValue;

    CheckedUint32 rows = imageHeight;
    rows *= (depth - 1);
    // Last image is not affected by IMAGE_HEIGHT parameter.
    rows += height;
    if (rows.hasOverflowed())
        return GraphicsContextGL::INVALID_VALUE;
    checkedValue *= (rows - 1);
    // Last row is not affected by ROW_LENGTH parameter.
    checkedValue += lastRowSize;
    if (checkedValue.hasOverflowed())
        return GraphicsContextGL::INVALID_VALUE;
    *imageSizeInBytes = checkedValue;
    if (paddingInBytes)
        *paddingInBytes = padding;

    CheckedUint32 skipSize = 0;
    if (params.skipImages > 0) {
        CheckedUint32 tmp = paddedRowSize;
        tmp *= imageHeight;
        tmp *= params.skipImages;
        if (tmp.hasOverflowed())
            return GraphicsContextGL::INVALID_VALUE;
        skipSize += tmp;
    }
    if (params.skipRows > 0) {
        CheckedUint32 tmp = paddedRowSize;
        tmp *= params.skipRows;
        if (tmp.hasOverflowed())
            return GraphicsContextGL::INVALID_VALUE;
        skipSize += tmp;
    }
    if (params.skipPixels > 0) {
        CheckedUint32 tmp = bytesPerGroup;
        tmp *= params.skipPixels;
        if (tmp.hasOverflowed())
            return GraphicsContextGL::INVALID_VALUE;
        skipSize += tmp;
    }
    if (skipSize.hasOverflowed())
        return GraphicsContextGL::INVALID_VALUE;
    if (skipSizeInBytes)
        *skipSizeInBytes = skipSize;

    checkedValue += skipSize;
    if (checkedValue.hasOverflowed())
        return GraphicsContextGL::INVALID_VALUE;
    return GraphicsContextGL::NO_ERROR;
}

bool GraphicsContextGL::packImageData(Image* image, const void* pixels, GCGLenum format, GCGLenum type, bool flipY, AlphaOp alphaOp, DataFormat sourceFormat, unsigned sourceImageWidth, unsigned sourceImageHeight, const IntRect& sourceImageSubRectangle, int depth, unsigned sourceUnpackAlignment, int unpackImageHeight, Vector<uint8_t>& data)
{
    if (!image || !pixels)
        return false;

    unsigned packedSize;
    // Output data is tightly packed (alignment == 1).
    PixelStoreParams params;
    params.alignment = 1;
    if (computeImageSizeInBytes(format, type, sourceImageSubRectangle.width(), sourceImageSubRectangle.height(), depth, params, &packedSize, nullptr, nullptr) != GraphicsContextGL::NO_ERROR)
        return false;
    data.resize(packedSize);

    if (!packPixels(static_cast<const uint8_t*>(pixels), sourceFormat, sourceImageWidth, sourceImageHeight, sourceImageSubRectangle, depth, sourceUnpackAlignment, unpackImageHeight, format, type, alphaOp, data.data(), flipY))
        return false;
    if (ImageObserver* observer = image->imageObserver())
        observer->didDraw(*image);
    return true;
}

bool GraphicsContextGL::extractPixelBuffer(const PixelBuffer& pixelBuffer, DataFormat sourceDataFormat, const IntRect& sourceImageSubRectangle, int depth, int unpackImageHeight, GCGLenum format, GCGLenum type, bool flipY, bool premultiplyAlpha, Vector<uint8_t>& data)
{
    int width = pixelBuffer.size().width();
    int height = pixelBuffer.size().height();

    unsigned packedSize;
    // Output data is tightly packed (alignment == 1).
    PixelStoreParams params;
    params.alignment = 1;
    if (computeImageSizeInBytes(format, type, sourceImageSubRectangle.width(), sourceImageSubRectangle.height(), depth, params, &packedSize, nullptr, nullptr) != GraphicsContextGL::NO_ERROR)
        return false;
    data.resize(packedSize);

    if (!packPixels(pixelBuffer.bytes(), sourceDataFormat, width, height, sourceImageSubRectangle, depth, 0, unpackImageHeight, format, type, premultiplyAlpha ? AlphaOp::DoPremultiply : AlphaOp::DoNothing, data.data(), flipY))
        return false;

    return true;
}

bool GraphicsContextGL::extractTextureData(unsigned width, unsigned height, GCGLenum format, GCGLenum type, const PixelStoreParams& unpackParams, bool flipY, bool premultiplyAlpha, const void* pixels, Vector<uint8_t>& data)
{
    // Assumes format, type, etc. have already been validated.
    DataFormat sourceDataFormat = getDataFormat(format, type);
    if (sourceDataFormat == GraphicsContextGL::DataFormat::Invalid)
        return false;
    // Resize the output buffer.
    unsigned componentsPerPixel, bytesPerComponent;
    if (!computeFormatAndTypeParameters(format, type, &componentsPerPixel, &bytesPerComponent))
        return false;
    unsigned bytesPerPixel = componentsPerPixel * bytesPerComponent;
    data.resize(width * height * bytesPerPixel);

    unsigned imageSizeInBytes, skipSizeInBytes;
    computeImageSizeInBytes(format, type, width, height, 1, unpackParams, &imageSizeInBytes, nullptr, &skipSizeInBytes);
    const uint8_t* srcData = static_cast<const uint8_t*>(pixels);
    if (skipSizeInBytes)
        srcData += skipSizeInBytes;

    if (!packPixels(srcData, sourceDataFormat, unpackParams.rowLength ? unpackParams.rowLength : width, height, IntRect(0, 0, width, height), 1, unpackParams.alignment, 0, format, type, (premultiplyAlpha ? AlphaOp::DoPremultiply : AlphaOp::DoNothing), data.data(), flipY))
        return false;

    return true;
}

void GraphicsContextGL::markContextChanged()
{
    m_layerComposited = false;
}

bool GraphicsContextGL::layerComposited() const
{
    return m_layerComposited;
}

void GraphicsContextGL::setBuffersToAutoClear(GCGLbitfield buffers)
{
    if (!contextAttributes().preserveDrawingBuffer)
        m_buffersToAutoClear = buffers;
}

GCGLbitfield GraphicsContextGL::getBuffersToAutoClear() const
{
    return m_buffersToAutoClear;
}

void GraphicsContextGL::markLayerComposited()
{
    m_layerComposited = true;
    auto attrs = contextAttributes();
    if (!attrs.preserveDrawingBuffer) {
        m_buffersToAutoClear = GraphicsContextGL::COLOR_BUFFER_BIT;
        if (attrs.depth)
            m_buffersToAutoClear |= GraphicsContextGL::DEPTH_BUFFER_BIT;
        if (attrs.stencil)
            m_buffersToAutoClear |= GraphicsContextGL::STENCIL_BUFFER_BIT;
    }
    if (m_client)
        m_client->didComposite();
}


void GraphicsContextGL::forceContextLost()
{
    if (m_client)
        m_client->forceContextLost();
}

void GraphicsContextGL::dispatchContextChangedNotification()
{
    if (m_client)
        m_client->dispatchContextChangedNotification();
}

} // namespace WebCore

#endif // ENABLE(WEBGL)
