/*
 * 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 "ExtensionsGL.h"
#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;

RefPtr<GraphicsContextGL> GraphicsContextGL::create(const GraphicsContextGLAttributes& attributes, HostWindow* hostWindow)
{
    RefPtr<GraphicsContextGL> result;
    if (hostWindow)
        result = hostWindow->createGraphicsContextGL(attributes);
    if (!result)
        result = GraphicsContextGLOpenGL::create(attributes, hostWindow);
    return result;
}

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 ExtensionsGL::SRGB_EXT:
        *componentsPerPixel = 3;
        break;
    case GraphicsContextGL::RGBA:
    case GraphicsContextGL::RGBA_INTEGER:
    case ExtensionsGL::BGRA_EXT: // GL_EXT_texture_format_BGRA8888
    case ExtensionsGL::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.data().data(), 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;
    }
    for (auto* client : copyToVector(m_clients))
        client->didComposite();
}

} // namespace WebCore

#endif // ENABLE(WEBGL)
