//
// Copyright 2015 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//

// BlitGL.cpp: Implements the BlitGL class, a helper for blitting textures

#include "libANGLE/renderer/gl/BlitGL.h"

#include "common/FixedVector.h"
#include "common/utilities.h"
#include "common/vector_utils.h"
#include "image_util/copyimage.h"
#include "libANGLE/Context.h"
#include "libANGLE/Framebuffer.h"
#include "libANGLE/formatutils.h"
#include "libANGLE/renderer/Format.h"
#include "libANGLE/renderer/gl/ContextGL.h"
#include "libANGLE/renderer/gl/FramebufferGL.h"
#include "libANGLE/renderer/gl/FunctionsGL.h"
#include "libANGLE/renderer/gl/RenderbufferGL.h"
#include "libANGLE/renderer/gl/StateManagerGL.h"
#include "libANGLE/renderer/gl/TextureGL.h"
#include "libANGLE/renderer/gl/formatutilsgl.h"
#include "libANGLE/renderer/gl/renderergl_utils.h"
#include "libANGLE/renderer/renderer_utils.h"
#include "platform/FeaturesGL.h"

using angle::Vector2;

namespace rx
{

namespace
{

angle::Result CheckCompileStatus(const gl::Context *context,
                                 const rx::FunctionsGL *functions,
                                 GLuint shader)
{
    GLint compileStatus = GL_FALSE;
    ANGLE_GL_TRY(context, functions->getShaderiv(shader, GL_COMPILE_STATUS, &compileStatus));

    ASSERT(compileStatus == GL_TRUE);
    ANGLE_CHECK(GetImplAs<ContextGL>(context), compileStatus == GL_TRUE,
                "Failed to compile internal blit shader.", GL_OUT_OF_MEMORY);

    return angle::Result::Continue;
}

angle::Result CheckLinkStatus(const gl::Context *context,
                              const rx::FunctionsGL *functions,
                              GLuint program)
{
    GLint linkStatus = GL_FALSE;
    ANGLE_GL_TRY(context, functions->getProgramiv(program, GL_LINK_STATUS, &linkStatus));
    ASSERT(linkStatus == GL_TRUE);
    ANGLE_CHECK(GetImplAs<ContextGL>(context), linkStatus == GL_TRUE,
                "Failed to link internal blit program.", GL_OUT_OF_MEMORY);

    return angle::Result::Continue;
}

class ScopedGLState : angle::NonCopyable
{
  public:
    enum
    {
        KEEP_SCISSOR = 1,
    };

    ScopedGLState() {}

    ~ScopedGLState() { ASSERT(mExited); }

    angle::Result enter(const gl::Context *context, gl::Rectangle viewport, int keepState = 0)
    {
        ContextGL *contextGL         = GetImplAs<ContextGL>(context);
        StateManagerGL *stateManager = contextGL->getStateManager();

        if (!(keepState & KEEP_SCISSOR))
        {
            stateManager->setScissorTestEnabled(false);
        }
        stateManager->setViewport(viewport);
        stateManager->setDepthRange(0.0f, 1.0f);
        stateManager->setBlendEnabled(false);
        stateManager->setColorMask(true, true, true, true);
        stateManager->setSampleAlphaToCoverageEnabled(false);
        stateManager->setSampleCoverageEnabled(false);
        stateManager->setDepthTestEnabled(false);
        stateManager->setStencilTestEnabled(false);
        stateManager->setCullFaceEnabled(false);
        stateManager->setPolygonOffsetFillEnabled(false);
        stateManager->setRasterizerDiscardEnabled(false);

        stateManager->pauseTransformFeedback();
        return stateManager->pauseAllQueries(context);
    }

    angle::Result exit(const gl::Context *context)
    {
        mExited = true;

        ContextGL *contextGL         = GetImplAs<ContextGL>(context);
        StateManagerGL *stateManager = contextGL->getStateManager();

        // XFB resuming will be done automatically
        return stateManager->resumeAllQueries(context);
    }

    void willUseTextureUnit(const gl::Context *context, int unit)
    {
        ContextGL *contextGL = GetImplAs<ContextGL>(context);

        if (contextGL->getFunctions()->bindSampler)
        {
            contextGL->getStateManager()->bindSampler(unit, 0);
        }
    }

  private:
    bool mExited = false;
};

angle::Result SetClearState(StateManagerGL *stateManager,
                            bool colorClear,
                            bool depthClear,
                            bool stencilClear,
                            GLbitfield *outClearMask)
{
    *outClearMask = 0;
    if (colorClear)
    {
        stateManager->setClearColor(gl::ColorF(0.0f, 0.0f, 0.0f, 0.0f));
        stateManager->setColorMask(true, true, true, true);
        *outClearMask |= GL_COLOR_BUFFER_BIT;
    }
    if (depthClear)
    {
        stateManager->setDepthMask(true);
        stateManager->setClearDepth(1.0f);
        *outClearMask |= GL_DEPTH_BUFFER_BIT;
    }
    if (stencilClear)
    {
        stateManager->setClearStencil(0);
        *outClearMask |= GL_STENCIL_BUFFER_BIT;
    }

    stateManager->setScissorTestEnabled(false);

    return angle::Result::Continue;
}

using ClearBindTargetVector = angle::FixedVector<GLenum, 3>;

angle::Result PrepareForClear(StateManagerGL *stateManager,
                              GLenum sizedInternalFormat,
                              ClearBindTargetVector *outBindtargets,
                              ClearBindTargetVector *outUnbindTargets,
                              GLbitfield *outClearMask)
{
    const gl::InternalFormat &internalFormatInfo =
        gl::GetSizedInternalFormatInfo(sizedInternalFormat);
    bool bindDepth   = internalFormatInfo.depthBits > 0;
    bool bindStencil = internalFormatInfo.stencilBits > 0;
    bool bindColor   = !bindDepth && !bindStencil;

    outBindtargets->clear();
    if (bindColor)
    {
        outBindtargets->push_back(GL_COLOR_ATTACHMENT0);
    }
    else
    {
        outUnbindTargets->push_back(GL_COLOR_ATTACHMENT0);
    }
    if (bindDepth)
    {
        outBindtargets->push_back(GL_DEPTH_ATTACHMENT);
    }
    else
    {
        outUnbindTargets->push_back(GL_DEPTH_ATTACHMENT);
    }
    if (bindStencil)
    {
        outBindtargets->push_back(GL_STENCIL_ATTACHMENT);
    }
    else
    {
        outUnbindTargets->push_back(GL_STENCIL_ATTACHMENT);
    }

    ANGLE_TRY(SetClearState(stateManager, bindColor, bindDepth, bindStencil, outClearMask));

    return angle::Result::Continue;
}

angle::Result UnbindAttachments(const gl::Context *context,
                                const FunctionsGL *functions,
                                GLenum framebufferTarget,
                                const ClearBindTargetVector &bindTargets)
{
    for (GLenum bindTarget : bindTargets)
    {
        ANGLE_GL_TRY(context, functions->framebufferRenderbuffer(framebufferTarget, bindTarget,
                                                                 GL_RENDERBUFFER, 0));
    }
    return angle::Result::Continue;
}

}  // anonymous namespace

BlitGL::BlitGL(const FunctionsGL *functions,
               const angle::FeaturesGL &features,
               StateManagerGL *stateManager)
    : mFunctions(functions),
      mFeatures(features),
      mStateManager(stateManager),
      mScratchFBO(0),
      mVAO(0),
      mVertexBuffer(0)
{
    for (size_t i = 0; i < ArraySize(mScratchTextures); i++)
    {
        mScratchTextures[i] = 0;
    }

    ASSERT(mFunctions);
    ASSERT(mStateManager);
}

BlitGL::~BlitGL()
{
    for (const auto &blitProgram : mBlitPrograms)
    {
        mStateManager->deleteProgram(blitProgram.second.program);
    }
    mBlitPrograms.clear();

    for (size_t i = 0; i < ArraySize(mScratchTextures); i++)
    {
        if (mScratchTextures[i] != 0)
        {
            mStateManager->deleteTexture(mScratchTextures[i]);
            mScratchTextures[i] = 0;
        }
    }

    if (mScratchFBO != 0)
    {
        mStateManager->deleteFramebuffer(mScratchFBO);
        mScratchFBO = 0;
    }

    if (mVAO != 0)
    {
        mStateManager->deleteVertexArray(mVAO);
        mVAO = 0;
    }
}

angle::Result BlitGL::copyImageToLUMAWorkaroundTexture(const gl::Context *context,
                                                       GLuint texture,
                                                       gl::TextureType textureType,
                                                       gl::TextureTarget target,
                                                       GLenum lumaFormat,
                                                       size_t level,
                                                       const gl::Rectangle &sourceArea,
                                                       GLenum internalFormat,
                                                       gl::Framebuffer *source)
{
    mStateManager->bindTexture(textureType, texture);

    // Allocate the texture memory
    GLenum format = gl::GetUnsizedFormat(internalFormat);

    GLenum readType = GL_NONE;
    ANGLE_TRY(source->getImplementationColorReadType(context, &readType));

    gl::PixelUnpackState unpack;
    mStateManager->setPixelUnpackState(unpack);
    mStateManager->setPixelUnpackBuffer(
        context->getState().getTargetBuffer(gl::BufferBinding::PixelUnpack));
    ANGLE_GL_TRY_ALWAYS_CHECK(
        context,
        mFunctions->texImage2D(ToGLenum(target), static_cast<GLint>(level), internalFormat,
                               sourceArea.width, sourceArea.height, 0, format, readType, nullptr));

    return copySubImageToLUMAWorkaroundTexture(context, texture, textureType, target, lumaFormat,
                                               level, gl::Offset(0, 0, 0), sourceArea, source);
}

angle::Result BlitGL::copySubImageToLUMAWorkaroundTexture(const gl::Context *context,
                                                          GLuint texture,
                                                          gl::TextureType textureType,
                                                          gl::TextureTarget target,
                                                          GLenum lumaFormat,
                                                          size_t level,
                                                          const gl::Offset &destOffset,
                                                          const gl::Rectangle &sourceArea,
                                                          gl::Framebuffer *source)
{
    ANGLE_TRY(initializeResources(context));

    BlitProgram *blitProgram = nullptr;
    ANGLE_TRY(getBlitProgram(context, gl::TextureType::_2D, GL_FLOAT, GL_FLOAT, &blitProgram));

    // Blit the framebuffer to the first scratch texture
    const FramebufferGL *sourceFramebufferGL = GetImplAs<FramebufferGL>(source);
    mStateManager->bindFramebuffer(GL_FRAMEBUFFER, sourceFramebufferGL->getFramebufferID());

    GLenum readFormat = GL_NONE;
    ANGLE_TRY(source->getImplementationColorReadFormat(context, &readFormat));

    GLenum readType = GL_NONE;
    ANGLE_TRY(source->getImplementationColorReadType(context, &readType));

    nativegl::CopyTexImageImageFormat copyTexImageFormat =
        nativegl::GetCopyTexImageImageFormat(mFunctions, mFeatures, readFormat, readType);

    mStateManager->bindTexture(gl::TextureType::_2D, mScratchTextures[0]);
    ANGLE_GL_TRY_ALWAYS_CHECK(
        context, mFunctions->copyTexImage2D(GL_TEXTURE_2D, 0, copyTexImageFormat.internalFormat,
                                            sourceArea.x, sourceArea.y, sourceArea.width,
                                            sourceArea.height, 0));

    // Set the swizzle of the scratch texture so that the channels sample into the correct emulated
    // LUMA channels.
    GLint swizzle[4] = {
        (lumaFormat == GL_ALPHA) ? GL_ALPHA : GL_RED,
        (lumaFormat == GL_LUMINANCE_ALPHA) ? GL_ALPHA : GL_ZERO,
        GL_ZERO,
        GL_ZERO,
    };
    ANGLE_GL_TRY(context,
                 mFunctions->texParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzle));

    // Make a temporary framebuffer using the second scratch texture to render the swizzled result
    // to.
    mStateManager->bindTexture(gl::TextureType::_2D, mScratchTextures[1]);
    ANGLE_GL_TRY_ALWAYS_CHECK(
        context, mFunctions->texImage2D(GL_TEXTURE_2D, 0, copyTexImageFormat.internalFormat,
                                        sourceArea.width, sourceArea.height, 0,
                                        gl::GetUnsizedFormat(copyTexImageFormat.internalFormat),
                                        readType, nullptr));

    mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mScratchFBO);
    ANGLE_GL_TRY(context, mFunctions->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                                                           GL_TEXTURE_2D, mScratchTextures[1], 0));

    // Render to the destination texture, sampling from the scratch texture
    ScopedGLState scopedState;
    ANGLE_TRY(scopedState.enter(context, gl::Rectangle(0, 0, sourceArea.width, sourceArea.height)));
    scopedState.willUseTextureUnit(context, 0);

    ANGLE_TRY(setScratchTextureParameter(context, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
    ANGLE_TRY(setScratchTextureParameter(context, GL_TEXTURE_MAG_FILTER, GL_NEAREST));

    mStateManager->activeTexture(0);
    mStateManager->bindTexture(gl::TextureType::_2D, mScratchTextures[0]);

    mStateManager->useProgram(blitProgram->program);
    ANGLE_GL_TRY(context, mFunctions->uniform1i(blitProgram->sourceTextureLocation, 0));
    ANGLE_GL_TRY(context, mFunctions->uniform2f(blitProgram->scaleLocation, 1.0, 1.0));
    ANGLE_GL_TRY(context, mFunctions->uniform2f(blitProgram->offsetLocation, 0.0, 0.0));
    ANGLE_GL_TRY(context, mFunctions->uniform1i(blitProgram->multiplyAlphaLocation, 0));
    ANGLE_GL_TRY(context, mFunctions->uniform1i(blitProgram->unMultiplyAlphaLocation, 0));

    mStateManager->bindVertexArray(mVAO, 0);
    ANGLE_GL_TRY(context, mFunctions->drawArrays(GL_TRIANGLES, 0, 3));

    // Copy the swizzled texture to the destination texture
    mStateManager->bindTexture(textureType, texture);

    if (nativegl::UseTexImage3D(textureType))
    {
        ANGLE_GL_TRY(context,
                     mFunctions->copyTexSubImage3D(ToGLenum(target), static_cast<GLint>(level),
                                                   destOffset.x, destOffset.y, destOffset.z, 0, 0,
                                                   sourceArea.width, sourceArea.height));
    }
    else
    {
        ASSERT(nativegl::UseTexImage2D(textureType));
        ANGLE_GL_TRY(context, mFunctions->copyTexSubImage2D(
                                  ToGLenum(target), static_cast<GLint>(level), destOffset.x,
                                  destOffset.y, 0, 0, sourceArea.width, sourceArea.height));
    }

    // Finally orphan the scratch textures so they can be GCed by the driver.
    ANGLE_TRY(orphanScratchTextures(context));

    ANGLE_TRY(scopedState.exit(context));
    return angle::Result::Continue;
}

angle::Result BlitGL::blitColorBufferWithShader(const gl::Context *context,
                                                const gl::Framebuffer *source,
                                                const gl::Framebuffer *dest,
                                                const gl::Rectangle &sourceAreaIn,
                                                const gl::Rectangle &destAreaIn,
                                                GLenum filter)
{
    ANGLE_TRY(initializeResources(context));

    BlitProgram *blitProgram = nullptr;
    ANGLE_TRY(getBlitProgram(context, gl::TextureType::_2D, GL_FLOAT, GL_FLOAT, &blitProgram));

    // We'll keep things simple by removing reversed coordinates from the rectangles. In the end
    // we'll apply the reversal to the source texture coordinates if needed. The destination
    // rectangle will be set to the gl viewport, which can't be reversed.
    bool reverseX            = sourceAreaIn.isReversedX() != destAreaIn.isReversedX();
    bool reverseY            = sourceAreaIn.isReversedY() != destAreaIn.isReversedY();
    gl::Rectangle sourceArea = sourceAreaIn.removeReversal();
    gl::Rectangle destArea   = destAreaIn.removeReversal();

    const gl::FramebufferAttachment *readAttachment = source->getReadColorAttachment();
    ASSERT(readAttachment->getSamples() <= 1);

    // Compute the part of the source that will be sampled.
    gl::Rectangle inBoundsSource;
    {
        gl::Extents sourceSize = readAttachment->getSize();
        gl::Rectangle sourceBounds(0, 0, sourceSize.width, sourceSize.height);
        if (!gl::ClipRectangle(sourceArea, sourceBounds, &inBoundsSource))
        {
            // Early out when the sampled part is empty as the blit will be a noop,
            // and it prevents a division by zero in later computations.
            return angle::Result::Continue;
        }
    }

    // The blit will be emulated by getting the source of the blit in a texture and sampling it
    // with CLAMP_TO_EDGE.

    GLuint textureId;

    // TODO(cwallez) once texture dirty bits are landed, reuse attached texture instead of using
    // CopyTexImage2D
    {
        textureId = mScratchTextures[0];

        GLenum format                 = readAttachment->getFormat().info->internalFormat;
        const FramebufferGL *sourceGL = GetImplAs<FramebufferGL>(source);
        mStateManager->bindFramebuffer(GL_READ_FRAMEBUFFER, sourceGL->getFramebufferID());
        mStateManager->bindTexture(gl::TextureType::_2D, textureId);

        ANGLE_GL_TRY_ALWAYS_CHECK(
            context,
            mFunctions->copyTexImage2D(GL_TEXTURE_2D, 0, format, inBoundsSource.x, inBoundsSource.y,
                                       inBoundsSource.width, inBoundsSource.height, 0));

        // Translate sourceArea to be relative to the copied image.
        sourceArea.x -= inBoundsSource.x;
        sourceArea.y -= inBoundsSource.y;

        ANGLE_TRY(setScratchTextureParameter(context, GL_TEXTURE_MIN_FILTER, filter));
        ANGLE_TRY(setScratchTextureParameter(context, GL_TEXTURE_MAG_FILTER, filter));
        ANGLE_TRY(setScratchTextureParameter(context, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
        ANGLE_TRY(setScratchTextureParameter(context, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
    }

    // Transform the source area to the texture coordinate space (where 0.0 and 1.0 correspond to
    // the edges of the texture).
    Vector2 texCoordOffset(
        static_cast<float>(sourceArea.x) / static_cast<float>(inBoundsSource.width),
        static_cast<float>(sourceArea.y) / static_cast<float>(inBoundsSource.height));
    // texCoordScale is equal to the size of the source area in texture coordinates.
    Vector2 texCoordScale(
        static_cast<float>(sourceArea.width) / static_cast<float>(inBoundsSource.width),
        static_cast<float>(sourceArea.height) / static_cast<float>(inBoundsSource.height));

    if (reverseX)
    {
        texCoordOffset.x() = texCoordOffset.x() + texCoordScale.x();
        texCoordScale.x()  = -texCoordScale.x();
    }
    if (reverseY)
    {
        texCoordOffset.y() = texCoordOffset.y() + texCoordScale.y();
        texCoordScale.y()  = -texCoordScale.y();
    }

    // Reset all the state except scissor and use the viewport to draw exactly to the destination
    // rectangle
    ScopedGLState scopedState;
    ANGLE_TRY(scopedState.enter(context, destArea, ScopedGLState::KEEP_SCISSOR));
    scopedState.willUseTextureUnit(context, 0);

    // Set uniforms
    mStateManager->activeTexture(0);
    mStateManager->bindTexture(gl::TextureType::_2D, textureId);

    mStateManager->useProgram(blitProgram->program);
    ANGLE_GL_TRY(context, mFunctions->uniform1i(blitProgram->sourceTextureLocation, 0));
    ANGLE_GL_TRY(context, mFunctions->uniform2f(blitProgram->scaleLocation, texCoordScale.x(),
                                                texCoordScale.y()));
    ANGLE_GL_TRY(context, mFunctions->uniform2f(blitProgram->offsetLocation, texCoordOffset.x(),
                                                texCoordOffset.y()));
    ANGLE_GL_TRY(context, mFunctions->uniform1i(blitProgram->multiplyAlphaLocation, 0));
    ANGLE_GL_TRY(context, mFunctions->uniform1i(blitProgram->unMultiplyAlphaLocation, 0));

    const FramebufferGL *destGL = GetImplAs<FramebufferGL>(dest);
    mStateManager->bindFramebuffer(GL_DRAW_FRAMEBUFFER, destGL->getFramebufferID());

    mStateManager->bindVertexArray(mVAO, 0);
    ANGLE_GL_TRY(context, mFunctions->drawArrays(GL_TRIANGLES, 0, 3));

    ANGLE_TRY(scopedState.exit(context));
    return angle::Result::Continue;
}

angle::Result BlitGL::copySubTexture(const gl::Context *context,
                                     TextureGL *source,
                                     size_t sourceLevel,
                                     GLenum sourceComponentType,
                                     GLuint destID,
                                     gl::TextureTarget destTarget,
                                     size_t destLevel,
                                     GLenum destComponentType,
                                     const gl::Extents &sourceSize,
                                     const gl::Rectangle &sourceArea,
                                     const gl::Offset &destOffset,
                                     bool needsLumaWorkaround,
                                     GLenum lumaFormat,
                                     bool unpackFlipY,
                                     bool unpackPremultiplyAlpha,
                                     bool unpackUnmultiplyAlpha,
                                     bool *copySucceededOut)
{
    ASSERT(source->getType() == gl::TextureType::_2D ||
           source->getType() == gl::TextureType::External ||
           source->getType() == gl::TextureType::Rectangle);
    ANGLE_TRY(initializeResources(context));

    // Make sure the destination texture can be rendered to before setting anything else up.  Some
    // cube maps may not be renderable until all faces have been filled.
    mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mScratchFBO);
    ANGLE_GL_TRY(context, mFunctions->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                                                           ToGLenum(destTarget), destID,
                                                           static_cast<GLint>(destLevel)));
    GLenum status = ANGLE_GL_TRY(context, mFunctions->checkFramebufferStatus(GL_FRAMEBUFFER));
    if (status != GL_FRAMEBUFFER_COMPLETE)
    {
        *copySucceededOut = false;
        return angle::Result::Continue;
    }

    BlitProgram *blitProgram = nullptr;
    ANGLE_TRY(getBlitProgram(context, source->getType(), sourceComponentType, destComponentType,
                             &blitProgram));

    // Setup the source texture
    if (needsLumaWorkaround)
    {
        GLint luminance = (lumaFormat == GL_ALPHA) ? GL_ZERO : GL_RED;

        GLint alpha = GL_RED;
        if (lumaFormat == GL_LUMINANCE)
        {
            alpha = GL_ONE;
        }
        else if (lumaFormat == GL_LUMINANCE_ALPHA)
        {
            alpha = GL_GREEN;
        }
        else
        {
            ASSERT(lumaFormat == GL_ALPHA);
        }

        GLint swizzle[4] = {luminance, luminance, luminance, alpha};
        ANGLE_TRY(source->setSwizzle(context, swizzle));
    }
    ANGLE_TRY(source->setMinFilter(context, GL_NEAREST));
    ANGLE_TRY(source->setMagFilter(context, GL_NEAREST));
    ANGLE_TRY(source->setBaseLevel(context, static_cast<GLuint>(sourceLevel)));

    // Render to the destination texture, sampling from the source texture
    ScopedGLState scopedState;
    ANGLE_TRY(scopedState.enter(
        context, gl::Rectangle(destOffset.x, destOffset.y, sourceArea.width, sourceArea.height)));
    scopedState.willUseTextureUnit(context, 0);

    mStateManager->activeTexture(0);
    mStateManager->bindTexture(source->getType(), source->getTextureID());

    Vector2 scale(sourceArea.width, sourceArea.height);
    Vector2 offset(sourceArea.x, sourceArea.y);
    if (source->getType() != gl::TextureType::Rectangle)
    {
        scale.x() /= static_cast<float>(sourceSize.width);
        scale.y() /= static_cast<float>(sourceSize.height);
        offset.x() /= static_cast<float>(sourceSize.width);
        offset.y() /= static_cast<float>(sourceSize.height);
    }
    if (unpackFlipY)
    {
        offset.y() += scale.y();
        scale.y() = -scale.y();
    }

    mStateManager->useProgram(blitProgram->program);
    ANGLE_GL_TRY(context, mFunctions->uniform1i(blitProgram->sourceTextureLocation, 0));
    ANGLE_GL_TRY(context, mFunctions->uniform2f(blitProgram->scaleLocation, scale.x(), scale.y()));
    ANGLE_GL_TRY(context,
                 mFunctions->uniform2f(blitProgram->offsetLocation, offset.x(), offset.y()));
    if (unpackPremultiplyAlpha == unpackUnmultiplyAlpha)
    {
        ANGLE_GL_TRY(context, mFunctions->uniform1i(blitProgram->multiplyAlphaLocation, 0));
        ANGLE_GL_TRY(context, mFunctions->uniform1i(blitProgram->unMultiplyAlphaLocation, 0));
    }
    else
    {
        ANGLE_GL_TRY(context, mFunctions->uniform1i(blitProgram->multiplyAlphaLocation,
                                                    unpackPremultiplyAlpha));
        ANGLE_GL_TRY(context, mFunctions->uniform1i(blitProgram->unMultiplyAlphaLocation,
                                                    unpackUnmultiplyAlpha));
    }

    mStateManager->bindVertexArray(mVAO, 0);
    ANGLE_GL_TRY(context, mFunctions->drawArrays(GL_TRIANGLES, 0, 3));

    *copySucceededOut = true;
    ANGLE_TRY(scopedState.exit(context));
    return angle::Result::Continue;
}

angle::Result BlitGL::copySubTextureCPUReadback(const gl::Context *context,
                                                TextureGL *source,
                                                size_t sourceLevel,
                                                GLenum sourceSizedInternalFormat,
                                                TextureGL *dest,
                                                gl::TextureTarget destTarget,
                                                size_t destLevel,
                                                GLenum destFormat,
                                                GLenum destType,
                                                const gl::Extents &sourceSize,
                                                const gl::Rectangle &sourceArea,
                                                const gl::Offset &destOffset,
                                                bool needsLumaWorkaround,
                                                GLenum lumaFormat,
                                                bool unpackFlipY,
                                                bool unpackPremultiplyAlpha,
                                                bool unpackUnmultiplyAlpha)
{
    ANGLE_TRY(initializeResources(context));

    ContextGL *contextGL = GetImplAs<ContextGL>(context);

    ASSERT(source->getType() == gl::TextureType::_2D ||
           source->getType() == gl::TextureType::External ||
           source->getType() == gl::TextureType::Rectangle);
    const auto &destInternalFormatInfo = gl::GetInternalFormatInfo(destFormat, destType);
    const gl::InternalFormat &sourceInternalFormatInfo =
        gl::GetSizedInternalFormatInfo(sourceSizedInternalFormat);

    gl::Rectangle readPixelsArea = sourceArea;

    mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mScratchFBO);
    ANGLE_GL_TRY(context, mFunctions->framebufferTexture2D(
                              GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, ToGLenum(source->getType()),
                              source->getTextureID(), static_cast<GLint>(sourceLevel)));
    GLenum status = ANGLE_GL_TRY(context, mFunctions->checkFramebufferStatus(GL_FRAMEBUFFER));
    if (status != GL_FRAMEBUFFER_COMPLETE)
    {
        // The source texture cannot be read with glReadPixels. Copy it into another RGBA texture
        // and read that back instead.
        nativegl::TexImageFormat texImageFormat = nativegl::GetTexImageFormat(
            mFunctions, mFeatures, sourceInternalFormatInfo.internalFormat,
            sourceInternalFormatInfo.format, sourceInternalFormatInfo.type);

        gl::TextureType scratchTextureType = gl::TextureType::_2D;
        mStateManager->bindTexture(scratchTextureType, mScratchTextures[0]);
        ANGLE_GL_TRY_ALWAYS_CHECK(
            context,
            mFunctions->texImage2D(ToGLenum(scratchTextureType), 0, texImageFormat.internalFormat,
                                   sourceArea.width, sourceArea.height, 0, texImageFormat.format,
                                   texImageFormat.type, nullptr));

        bool copySucceeded = false;
        ANGLE_TRY(copySubTexture(
            context, source, sourceLevel, sourceInternalFormatInfo.componentType,
            mScratchTextures[0], NonCubeTextureTypeToTarget(scratchTextureType), 0,
            sourceInternalFormatInfo.componentType, sourceSize, sourceArea, gl::Offset(0, 0, 0),
            needsLumaWorkaround, lumaFormat, false, false, false, &copySucceeded));
        if (!copySucceeded)
        {
            // No fallback options if we can't render to the scratch texture.
            return angle::Result::Stop;
        }

        // Bind the scratch texture as the readback texture
        mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mScratchFBO);
        ANGLE_GL_TRY(context, mFunctions->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                                                               ToGLenum(scratchTextureType),
                                                               mScratchTextures[0], 0));

        // The scratch texture sized to sourceArea so adjust the readpixels area
        readPixelsArea.x = 0;
        readPixelsArea.y = 0;

        // Recheck the status
        status = ANGLE_GL_TRY(context, mFunctions->checkFramebufferStatus(GL_FRAMEBUFFER));
    }

    ASSERT(status == GL_FRAMEBUFFER_COMPLETE);

    // Create a buffer for holding the source and destination memory
    const size_t sourcePixelSize = 4;
    size_t sourceBufferSize      = readPixelsArea.width * readPixelsArea.height * sourcePixelSize;
    size_t destBufferSize =
        readPixelsArea.width * readPixelsArea.height * destInternalFormatInfo.pixelBytes;
    angle::MemoryBuffer *buffer = nullptr;
    ANGLE_CHECK_GL_ALLOC(contextGL,
                         context->getScratchBuffer(sourceBufferSize + destBufferSize, &buffer));

    uint8_t *sourceMemory = buffer->data();
    uint8_t *destMemory   = buffer->data() + sourceBufferSize;

    GLenum readPixelsFormat        = GL_NONE;
    PixelReadFunction readFunction = nullptr;
    if (sourceInternalFormatInfo.componentType == GL_UNSIGNED_INT)
    {
        readPixelsFormat = GL_RGBA_INTEGER;
        readFunction     = angle::ReadColor<angle::R8G8B8A8, GLuint>;
    }
    else
    {
        ASSERT(sourceInternalFormatInfo.componentType != GL_INT);
        readPixelsFormat = GL_RGBA;
        readFunction     = angle::ReadColor<angle::R8G8B8A8, GLfloat>;
    }

    gl::PixelUnpackState unpack;
    unpack.alignment = 1;
    mStateManager->setPixelUnpackState(unpack);
    mStateManager->setPixelUnpackBuffer(nullptr);
    ANGLE_GL_TRY(context, mFunctions->readPixels(readPixelsArea.x, readPixelsArea.y,
                                                 readPixelsArea.width, readPixelsArea.height,
                                                 readPixelsFormat, GL_UNSIGNED_BYTE, sourceMemory));

    angle::FormatID destFormatID =
        angle::Format::InternalFormatToID(destInternalFormatInfo.sizedInternalFormat);
    const auto &destFormatInfo = angle::Format::Get(destFormatID);
    CopyImageCHROMIUM(
        sourceMemory, readPixelsArea.width * sourcePixelSize, sourcePixelSize, 0, readFunction,
        destMemory, readPixelsArea.width * destInternalFormatInfo.pixelBytes,
        destInternalFormatInfo.pixelBytes, 0, destFormatInfo.pixelWriteFunction,
        destInternalFormatInfo.format, destInternalFormatInfo.componentType, readPixelsArea.width,
        readPixelsArea.height, 1, unpackFlipY, unpackPremultiplyAlpha, unpackUnmultiplyAlpha);

    gl::PixelPackState pack;
    pack.alignment = 1;
    mStateManager->setPixelPackState(pack);
    mStateManager->setPixelPackBuffer(nullptr);

    nativegl::TexSubImageFormat texSubImageFormat =
        nativegl::GetTexSubImageFormat(mFunctions, mFeatures, destFormat, destType);

    mStateManager->bindTexture(dest->getType(), dest->getTextureID());
    ANGLE_GL_TRY(context, mFunctions->texSubImage2D(
                              ToGLenum(destTarget), static_cast<GLint>(destLevel), destOffset.x,
                              destOffset.y, readPixelsArea.width, readPixelsArea.height,
                              texSubImageFormat.format, texSubImageFormat.type, destMemory));

    return angle::Result::Continue;
}

angle::Result BlitGL::copyTexSubImage(const gl::Context *context,
                                      TextureGL *source,
                                      size_t sourceLevel,
                                      TextureGL *dest,
                                      gl::TextureTarget destTarget,
                                      size_t destLevel,
                                      const gl::Rectangle &sourceArea,
                                      const gl::Offset &destOffset,
                                      bool *copySucceededOut)
{
    ANGLE_TRY(initializeResources(context));

    // Make sure the source texture can create a complete framebuffer before continuing.
    mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mScratchFBO);
    ANGLE_GL_TRY(context, mFunctions->framebufferTexture2D(
                              GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, ToGLenum(source->getType()),
                              source->getTextureID(), static_cast<GLint>(sourceLevel)));
    GLenum status = ANGLE_GL_TRY(context, mFunctions->checkFramebufferStatus(GL_FRAMEBUFFER));
    if (status != GL_FRAMEBUFFER_COMPLETE)
    {
        *copySucceededOut = false;
        return angle::Result::Continue;
    }

    mStateManager->bindTexture(dest->getType(), dest->getTextureID());

    ANGLE_GL_TRY(context,
                 mFunctions->copyTexSubImage2D(ToGLenum(destTarget), static_cast<GLint>(destLevel),
                                               destOffset.x, destOffset.y, sourceArea.x,
                                               sourceArea.y, sourceArea.width, sourceArea.height));

    *copySucceededOut = true;
    return angle::Result::Continue;
}

angle::Result BlitGL::clearRenderableTexture(const gl::Context *context,
                                             TextureGL *source,
                                             GLenum sizedInternalFormat,
                                             int numTextureLayers,
                                             const gl::ImageIndex &imageIndex,
                                             bool *clearSucceededOut)
{
    ANGLE_TRY(initializeResources(context));

    ClearBindTargetVector bindTargets;
    ClearBindTargetVector unbindTargets;
    GLbitfield clearMask = 0;
    ANGLE_TRY(PrepareForClear(mStateManager, sizedInternalFormat, &bindTargets, &unbindTargets,
                              &clearMask));

    mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mScratchFBO);
    ANGLE_TRY(UnbindAttachments(context, mFunctions, GL_FRAMEBUFFER, unbindTargets));

    if (nativegl::UseTexImage2D(source->getType()))
    {
        ASSERT(numTextureLayers == 1);
        for (GLenum bindTarget : bindTargets)
        {
            ANGLE_GL_TRY(context, mFunctions->framebufferTexture2D(
                                      GL_FRAMEBUFFER, bindTarget, ToGLenum(imageIndex.getTarget()),
                                      source->getTextureID(), imageIndex.getLevelIndex()));
        }

        GLenum status = ANGLE_GL_TRY(context, mFunctions->checkFramebufferStatus(GL_FRAMEBUFFER));
        if (status == GL_FRAMEBUFFER_COMPLETE)
        {
            ANGLE_GL_TRY(context, mFunctions->clear(clearMask));
        }
        else
        {
            ANGLE_TRY(UnbindAttachments(context, mFunctions, GL_FRAMEBUFFER, bindTargets));
            *clearSucceededOut = false;
            return angle::Result::Continue;
        }
    }
    else
    {
        ASSERT(nativegl::UseTexImage3D(source->getType()));

        // Check if it's possible to bind all layers of the texture at once
        if (mFunctions->framebufferTexture && !imageIndex.hasLayer())
        {
            for (GLenum bindTarget : bindTargets)
            {
                ANGLE_GL_TRY(context, mFunctions->framebufferTexture(GL_FRAMEBUFFER, bindTarget,
                                                                     source->getTextureID(),
                                                                     imageIndex.getLevelIndex()));
            }

            GLenum status =
                ANGLE_GL_TRY(context, mFunctions->checkFramebufferStatus(GL_FRAMEBUFFER));
            if (status == GL_FRAMEBUFFER_COMPLETE)
            {
                ANGLE_GL_TRY(context, mFunctions->clear(clearMask));
            }
            else
            {
                ANGLE_TRY(UnbindAttachments(context, mFunctions, GL_FRAMEBUFFER, bindTargets));
                *clearSucceededOut = false;
                return angle::Result::Continue;
            }
        }
        else
        {
            GLint firstLayer = 0;
            GLint layerCount = numTextureLayers;
            if (imageIndex.hasLayer())
            {
                firstLayer = imageIndex.getLayerIndex();
                layerCount = imageIndex.getLayerCount();
            }

            for (GLint layer = 0; layer < layerCount; layer++)
            {
                for (GLenum bindTarget : bindTargets)
                {
                    ANGLE_GL_TRY(context, mFunctions->framebufferTextureLayer(
                                              GL_FRAMEBUFFER, bindTarget, source->getTextureID(),
                                              imageIndex.getLevelIndex(), layer + firstLayer));
                }

                GLenum status =
                    ANGLE_GL_TRY(context, mFunctions->checkFramebufferStatus(GL_FRAMEBUFFER));
                if (status == GL_FRAMEBUFFER_COMPLETE)
                {
                    ANGLE_GL_TRY(context, mFunctions->clear(clearMask));
                }
                else
                {
                    ANGLE_TRY(UnbindAttachments(context, mFunctions, GL_FRAMEBUFFER, bindTargets));
                    *clearSucceededOut = false;
                    return angle::Result::Continue;
                }
            }
        }
    }

    ANGLE_TRY(UnbindAttachments(context, mFunctions, GL_FRAMEBUFFER, bindTargets));
    *clearSucceededOut = true;
    return angle::Result::Continue;
}

angle::Result BlitGL::clearRenderbuffer(const gl::Context *context,
                                        RenderbufferGL *source,
                                        GLenum sizedInternalFormat)
{
    ANGLE_TRY(initializeResources(context));

    ClearBindTargetVector bindTargets;
    ClearBindTargetVector unbindTargets;
    GLbitfield clearMask = 0;
    ANGLE_TRY(PrepareForClear(mStateManager, sizedInternalFormat, &bindTargets, &unbindTargets,
                              &clearMask));

    mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mScratchFBO);
    ANGLE_TRY(UnbindAttachments(context, mFunctions, GL_FRAMEBUFFER, unbindTargets));

    for (GLenum bindTarget : bindTargets)
    {
        ANGLE_GL_TRY(context,
                     mFunctions->framebufferRenderbuffer(
                         GL_FRAMEBUFFER, bindTarget, GL_RENDERBUFFER, source->getRenderbufferID()));
    }
    ANGLE_GL_TRY(context, mFunctions->clear(clearMask));

    // Unbind
    for (GLenum bindTarget : bindTargets)
    {
        ANGLE_GL_TRY(context, mFunctions->framebufferRenderbuffer(GL_FRAMEBUFFER, bindTarget,
                                                                  GL_RENDERBUFFER, 0));
    }

    return angle::Result::Continue;
}

angle::Result BlitGL::clearFramebuffer(const gl::Context *context, FramebufferGL *source)
{
    // initializeResources skipped because no local state is used

    // Clear all attachments
    GLbitfield clearMask = 0;
    ANGLE_TRY(SetClearState(mStateManager, true, true, true, &clearMask));

    mStateManager->bindFramebuffer(GL_FRAMEBUFFER, source->getFramebufferID());
    ANGLE_GL_TRY(context, mFunctions->clear(clearMask));

    return angle::Result::Continue;
}

angle::Result BlitGL::clearRenderableTextureAlphaToOne(const gl::Context *context,
                                                       GLuint texture,
                                                       gl::TextureTarget target,
                                                       size_t level)
{
    // Clearing the alpha of 3D textures is not supported/needed yet.
    ASSERT(nativegl::UseTexImage2D(TextureTargetToType(target)));

    ANGLE_TRY(initializeResources(context));

    mStateManager->setClearColor(gl::ColorF(0.0f, 0.0f, 0.0f, 1.0f));
    mStateManager->setColorMask(false, false, false, true);
    mStateManager->setScissorTestEnabled(false);

    mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mScratchFBO);
    ANGLE_GL_TRY(context, mFunctions->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                                                           ToGLenum(target), texture,
                                                           static_cast<GLint>(level)));
    ANGLE_GL_TRY(context, mFunctions->clear(GL_COLOR_BUFFER_BIT));

    // Unbind the texture from the the scratch framebuffer
    ANGLE_GL_TRY(context, mFunctions->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                                                              GL_RENDERBUFFER, 0));

    return angle::Result::Continue;
}

angle::Result BlitGL::initializeResources(const gl::Context *context)
{
    for (size_t i = 0; i < ArraySize(mScratchTextures); i++)
    {
        if (mScratchTextures[i] == 0)
        {
            ANGLE_GL_TRY(context, mFunctions->genTextures(1, &mScratchTextures[i]));
        }
    }

    if (mScratchFBO == 0)
    {
        ANGLE_GL_TRY(context, mFunctions->genFramebuffers(1, &mScratchFBO));
    }

    if (mVertexBuffer == 0)
    {
        ANGLE_GL_TRY(context, mFunctions->genBuffers(1, &mVertexBuffer));
        mStateManager->bindBuffer(gl::BufferBinding::Array, mVertexBuffer);

        // Use a single, large triangle, to avoid arithmetic precision issues where fragments
        // with the same Y coordinate don't get exactly the same interpolated texcoord Y.
        float vertexData[] = {
            -0.5f, 0.0f, 1.5f, 0.0f, 0.5f, 2.0f,
        };

        ANGLE_GL_TRY(context, mFunctions->bufferData(GL_ARRAY_BUFFER, sizeof(float) * 6, vertexData,
                                                     GL_STATIC_DRAW));
    }

    if (mVAO == 0)
    {
        ANGLE_GL_TRY(context, mFunctions->genVertexArrays(1, &mVAO));

        mStateManager->bindVertexArray(mVAO, 0);
        mStateManager->bindBuffer(gl::BufferBinding::Array, mVertexBuffer);

        // Enable all attributes with the same buffer so that it doesn't matter what location the
        // texcoord attribute is assigned
        GLint maxAttributes = 0;
        ANGLE_GL_TRY(context, mFunctions->getIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxAttributes));

        for (GLint i = 0; i < maxAttributes; i++)
        {
            ANGLE_GL_TRY(context, mFunctions->enableVertexAttribArray(i));
            ANGLE_GL_TRY(context,
                         mFunctions->vertexAttribPointer(i, 2, GL_FLOAT, GL_FALSE, 0, nullptr));
        }
    }

    return angle::Result::Continue;
}

angle::Result BlitGL::orphanScratchTextures(const gl::Context *context)
{
    for (auto texture : mScratchTextures)
    {
        mStateManager->bindTexture(gl::TextureType::_2D, texture);
        gl::PixelUnpackState unpack;
        mStateManager->setPixelUnpackState(unpack);
        mStateManager->setPixelUnpackBuffer(nullptr);
        GLint swizzle[4] = {GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA};
        ANGLE_GL_TRY(context,
                     mFunctions->texParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzle));
        ANGLE_GL_TRY(context, mFunctions->texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, 0, GL_RGBA,
                                                     GL_UNSIGNED_BYTE, nullptr));
    }
    return angle::Result::Continue;
}

angle::Result BlitGL::setScratchTextureParameter(const gl::Context *context,
                                                 GLenum param,
                                                 GLenum value)
{
    for (auto texture : mScratchTextures)
    {
        mStateManager->bindTexture(gl::TextureType::_2D, texture);
        ANGLE_GL_TRY(context, mFunctions->texParameteri(GL_TEXTURE_2D, param, value));
        ANGLE_GL_TRY(context, mFunctions->texParameteri(GL_TEXTURE_2D, param, value));
    }
    return angle::Result::Continue;
}

angle::Result BlitGL::getBlitProgram(const gl::Context *context,
                                     gl::TextureType sourceTextureType,
                                     GLenum sourceComponentType,
                                     GLenum destComponentType,
                                     BlitProgram **program)
{

    BlitProgramType programType(sourceTextureType, sourceComponentType, destComponentType);
    BlitProgram &result = mBlitPrograms[programType];
    if (result.program == 0)
    {
        result.program = ANGLE_GL_TRY(context, mFunctions->createProgram());

        // Depending on what types need to be output by the shaders, different versions need to be
        // used.
        std::string version;
        std::string vsInputVariableQualifier;
        std::string vsOutputVariableQualifier;
        std::string fsInputVariableQualifier;
        std::string fsOutputVariableQualifier;
        std::string sampleFunction;
        if (sourceComponentType != GL_UNSIGNED_INT && destComponentType != GL_UNSIGNED_INT &&
            sourceTextureType != gl::TextureType::Rectangle)
        {
            // Simple case, float-to-float with 2D or external textures.  Only needs ESSL/GLSL 100
            version                   = "100";
            vsInputVariableQualifier  = "attribute";
            vsOutputVariableQualifier = "varying";
            fsInputVariableQualifier  = "varying";
            fsOutputVariableQualifier = "";
            sampleFunction            = "texture2D";
        }
        else
        {
            // Need to use a higher version to support non-float output types
            if (mFunctions->standard == STANDARD_GL_DESKTOP)
            {
                version = "330";
            }
            else
            {
                ASSERT(mFunctions->standard == STANDARD_GL_ES);
                version = "300 es";
            }
            vsInputVariableQualifier  = "in";
            vsOutputVariableQualifier = "out";
            fsInputVariableQualifier  = "in";
            fsOutputVariableQualifier = "out";
            sampleFunction            = "texture";
        }

        {
            // Compile the vertex shader
            std::ostringstream vsSourceStream;
            vsSourceStream << "#version " << version << "\n";
            vsSourceStream << vsInputVariableQualifier << " vec2 a_texcoord;\n";
            vsSourceStream << "uniform vec2 u_scale;\n";
            vsSourceStream << "uniform vec2 u_offset;\n";
            vsSourceStream << vsOutputVariableQualifier << " vec2 v_texcoord;\n";
            vsSourceStream << "\n";
            vsSourceStream << "void main()\n";
            vsSourceStream << "{\n";
            vsSourceStream << "    gl_Position = vec4((a_texcoord * 2.0) - 1.0, 0.0, 1.0);\n";
            vsSourceStream << "    v_texcoord = a_texcoord * u_scale + u_offset;\n";
            vsSourceStream << "}\n";

            std::string vsSourceStr  = vsSourceStream.str();
            const char *vsSourceCStr = vsSourceStr.c_str();

            GLuint vs = ANGLE_GL_TRY(context, mFunctions->createShader(GL_VERTEX_SHADER));
            ANGLE_GL_TRY(context, mFunctions->shaderSource(vs, 1, &vsSourceCStr, nullptr));
            ANGLE_GL_TRY(context, mFunctions->compileShader(vs));
            ANGLE_TRY(CheckCompileStatus(context, mFunctions, vs));

            ANGLE_GL_TRY(context, mFunctions->attachShader(result.program, vs));
            ANGLE_GL_TRY(context, mFunctions->deleteShader(vs));
        }

        {
            // Sampling texture uniform changes depending on source texture type.
            std::string samplerType;
            switch (sourceTextureType)
            {
                case gl::TextureType::_2D:
                    switch (sourceComponentType)
                    {
                        case GL_UNSIGNED_INT:
                            samplerType = "usampler2D";
                            break;

                        default:  // Float type
                            samplerType = "sampler2D";
                            break;
                    }
                    break;

                case gl::TextureType::External:
                    ASSERT(sourceComponentType != GL_UNSIGNED_INT);
                    samplerType = "samplerExternalOES";
                    break;

                case gl::TextureType::Rectangle:
                    ASSERT(sourceComponentType != GL_UNSIGNED_INT);
                    samplerType = "sampler2DRect";
                    break;

                default:
                    UNREACHABLE();
                    break;
            }

            std::string samplerResultType;
            switch (sourceComponentType)
            {
                case GL_UNSIGNED_INT:
                    samplerResultType = "uvec4";
                    break;

                default:  // Float type
                    samplerResultType = "vec4";
                    break;
            }

            std::string extensionRequirements;
            switch (sourceTextureType)
            {
                case gl::TextureType::External:
                    extensionRequirements = "#extension GL_OES_EGL_image_external : require";
                    break;

                case gl::TextureType::Rectangle:
                    if (mFunctions->hasGLExtension("GL_ARB_texture_rectangle"))
                    {
                        extensionRequirements = "#extension GL_ARB_texture_rectangle : require";
                    }
                    else
                    {
                        ASSERT(mFunctions->isAtLeastGL(gl::Version(3, 1)));
                    }
                    break;

                default:
                    break;
            }

            // Output variables depend on the output type
            std::string outputType;
            std::string outputVariableName;
            std::string outputMultiplier;
            switch (destComponentType)
            {
                case GL_UNSIGNED_INT:
                    outputType         = "uvec4";
                    outputVariableName = "outputUint";
                    outputMultiplier   = "255.0";
                    break;

                default:  //  float type
                    if (version == "100")
                    {
                        outputType         = "";
                        outputVariableName = "gl_FragColor";
                        outputMultiplier   = "1.0";
                    }
                    else
                    {
                        outputType         = "vec4";
                        outputVariableName = "outputFloat";
                        outputMultiplier   = "1.0";
                    }
                    break;
            }

            // Compile the fragment shader
            std::ostringstream fsSourceStream;
            fsSourceStream << "#version " << version << "\n";
            fsSourceStream << extensionRequirements << "\n";
            fsSourceStream << "precision highp float;\n";
            fsSourceStream << "uniform " << samplerType << " u_source_texture;\n";

            // Write the rest of the uniforms and varyings
            fsSourceStream << "uniform bool u_multiply_alpha;\n";
            fsSourceStream << "uniform bool u_unmultiply_alpha;\n";
            fsSourceStream << fsInputVariableQualifier << " vec2 v_texcoord;\n";
            if (!outputType.empty())
            {
                fsSourceStream << fsOutputVariableQualifier << " " << outputType << " "
                               << outputVariableName << ";\n";
            }

            // Write the main body
            fsSourceStream << "\n";
            fsSourceStream << "void main()\n";
            fsSourceStream << "{\n";

            std::string maxTexcoord;
            switch (sourceTextureType)
            {
                case gl::TextureType::Rectangle:
                    // Valid texcoords are within source texture size
                    maxTexcoord = "vec2(textureSize(u_source_texture))";
                    break;

                default:
                    // Valid texcoords are in [0, 1]
                    maxTexcoord = "vec2(1.0)";
                    break;
            }

            // discard if the texcoord is invalid so the blitframebuffer workaround doesn't
            // write when the point sampled is outside of the source framebuffer.
            fsSourceStream << "    if (clamp(v_texcoord, vec2(0.0), " << maxTexcoord
                           << ") != v_texcoord)\n";
            fsSourceStream << "    {\n";
            fsSourceStream << "        discard;\n";
            fsSourceStream << "    }\n";

            // Sampling code depends on the input data type
            fsSourceStream << "    " << samplerResultType << " color = " << sampleFunction
                           << "(u_source_texture, v_texcoord);\n";

            // Perform the premultiply or unmultiply alpha logic
            fsSourceStream << "    if (u_multiply_alpha)\n";
            fsSourceStream << "    {\n";
            fsSourceStream << "        color.xyz = color.xyz * color.a;\n";
            fsSourceStream << "    }\n";
            fsSourceStream << "    if (u_unmultiply_alpha && color.a != 0.0)\n";
            fsSourceStream << "    {\n";
            fsSourceStream << "         color.xyz = color.xyz / color.a;\n";
            fsSourceStream << "    }\n";

            // Write the conversion to the destionation type
            fsSourceStream << "    color = color * " << outputMultiplier << ";\n";

            // Write the output assignment code
            fsSourceStream << "    " << outputVariableName << " = " << outputType << "(color);\n";
            fsSourceStream << "}\n";

            std::string fsSourceStr  = fsSourceStream.str();
            const char *fsSourceCStr = fsSourceStr.c_str();

            GLuint fs = ANGLE_GL_TRY(context, mFunctions->createShader(GL_FRAGMENT_SHADER));
            ANGLE_GL_TRY(context, mFunctions->shaderSource(fs, 1, &fsSourceCStr, nullptr));
            ANGLE_GL_TRY(context, mFunctions->compileShader(fs));
            ANGLE_TRY(CheckCompileStatus(context, mFunctions, fs));

            ANGLE_GL_TRY(context, mFunctions->attachShader(result.program, fs));
            ANGLE_GL_TRY(context, mFunctions->deleteShader(fs));
        }

        ANGLE_GL_TRY(context, mFunctions->linkProgram(result.program));
        ANGLE_TRY(CheckLinkStatus(context, mFunctions, result.program));

        result.sourceTextureLocation = ANGLE_GL_TRY(
            context, mFunctions->getUniformLocation(result.program, "u_source_texture"));
        result.scaleLocation =
            ANGLE_GL_TRY(context, mFunctions->getUniformLocation(result.program, "u_scale"));
        result.offsetLocation =
            ANGLE_GL_TRY(context, mFunctions->getUniformLocation(result.program, "u_offset"));
        result.multiplyAlphaLocation = ANGLE_GL_TRY(
            context, mFunctions->getUniformLocation(result.program, "u_multiply_alpha"));
        result.unMultiplyAlphaLocation = ANGLE_GL_TRY(
            context, mFunctions->getUniformLocation(result.program, "u_unmultiply_alpha"));
    }

    *program = &result;
    return angle::Result::Continue;
}

}  // namespace rx
