//
// 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/vector_utils.h"
#include "libANGLE/formatutils.h"
#include "libANGLE/Framebuffer.h"
#include "libANGLE/renderer/gl/formatutilsgl.h"
#include "libANGLE/renderer/gl/FramebufferGL.h"
#include "libANGLE/renderer/gl/FunctionsGL.h"
#include "libANGLE/renderer/gl/TextureGL.h"
#include "libANGLE/renderer/gl/StateManagerGL.h"
#include "libANGLE/renderer/gl/WorkaroundsGL.h"

using angle::Vector2;

namespace rx
{

namespace
{

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

    ASSERT(compileStatus == GL_TRUE);
    if (compileStatus == GL_FALSE)
    {
        return gl::Error(GL_OUT_OF_MEMORY, "Failed to compile internal blit shader.");
    }

    return gl::NoError();
}

gl::Error CheckLinkStatus(const rx::FunctionsGL *functions, GLuint program)
{
    GLint linkStatus = GL_FALSE;
    functions->getProgramiv(program, GL_LINK_STATUS, &linkStatus);
    ASSERT(linkStatus == GL_TRUE);
    if (linkStatus == GL_FALSE)
    {
        return gl::Error(GL_OUT_OF_MEMORY, "Failed to link internal blit program.");
    }

    return gl::NoError();
}

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

    ScopedGLState(StateManagerGL *stateManager,
                  const FunctionsGL *functions,
                  gl::Rectangle viewport,
                  int keepState = 0)
        : mStateManager(stateManager), mFunctions(functions)
    {
        if (!(keepState & KEEP_SCISSOR))
        {
            mStateManager->setScissorTestEnabled(false);
        }
        mStateManager->setViewport(viewport);
        mStateManager->setDepthRange(0.0f, 1.0f);
        mStateManager->setBlendEnabled(false);
        mStateManager->setColorMask(true, true, true, true);
        mStateManager->setSampleAlphaToCoverageEnabled(false);
        mStateManager->setSampleCoverageEnabled(false);
        mStateManager->setDepthTestEnabled(false);
        mStateManager->setStencilTestEnabled(false);
        mStateManager->setCullFaceEnabled(false);
        mStateManager->setPolygonOffsetFillEnabled(false);
        mStateManager->setRasterizerDiscardEnabled(false);

        mStateManager->pauseTransformFeedback();
        mStateManager->pauseAllQueries();
    }

    ~ScopedGLState()
    {
        // XFB resuming will be done automatically
        mStateManager->resumeAllQueries();
    }

    void willUseTextureUnit(int unit)
    {
        if (mFunctions->bindSampler)
        {
            mStateManager->bindSampler(unit, 0);
        }
    }

  private:
    StateManagerGL *mStateManager;
    const FunctionsGL *mFunctions;
};

}  // anonymous namespace

BlitGL::BlitGL(const FunctionsGL *functions,
               const WorkaroundsGL &workarounds,
               StateManagerGL *stateManager)
    : mFunctions(functions),
      mWorkarounds(workarounds),
      mStateManager(stateManager),
      mBlitProgram(0),
      mSourceTextureLocation(-1),
      mScaleLocation(-1),
      mOffsetLocation(-1),
      mMultiplyAlphaLocation(-1),
      mUnMultiplyAlphaLocation(-1),
      mScratchFBO(0),
      mVAO(0),
      mVertexBuffer(0)
{
    for (size_t i = 0; i < ArraySize(mScratchTextures); i++)
    {
        mScratchTextures[i] = 0;
    }

    ASSERT(mFunctions);
    ASSERT(mStateManager);
}

BlitGL::~BlitGL()
{
    if (mBlitProgram != 0)
    {
        mStateManager->deleteProgram(mBlitProgram);
        mBlitProgram = 0;
    }

    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;
    }
}

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

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

    gl::PixelUnpackState unpack;
    mStateManager->setPixelUnpackState(unpack);
    mFunctions->texImage2D(target, static_cast<GLint>(level), internalFormat, sourceArea.width,
                           sourceArea.height, 0, format, source->getImplementationColorReadType(),
                           nullptr);

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

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

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

    nativegl::CopyTexImageImageFormat copyTexImageFormat = nativegl::GetCopyTexImageImageFormat(
        mFunctions, mWorkarounds, source->getImplementationColorReadFormat(),
        source->getImplementationColorReadType());

    mStateManager->bindTexture(GL_TEXTURE_2D, mScratchTextures[0]);
    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,
    };
    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_TEXTURE_2D, mScratchTextures[1]);
    mFunctions->texImage2D(GL_TEXTURE_2D, 0, copyTexImageFormat.internalFormat, sourceArea.width,
                           sourceArea.height, 0,
                           gl::GetUnsizedFormat(copyTexImageFormat.internalFormat),
                           source->getImplementationColorReadType(), nullptr);

    mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mScratchFBO);
    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(mStateManager, mFunctions,
                              gl::Rectangle(0, 0, sourceArea.width, sourceArea.height));
    scopedState.willUseTextureUnit(0);

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

    mStateManager->activeTexture(0);
    mStateManager->bindTexture(GL_TEXTURE_2D, mScratchTextures[0]);

    mStateManager->useProgram(mBlitProgram);
    mFunctions->uniform1i(mSourceTextureLocation, 0);
    mFunctions->uniform2f(mScaleLocation, 1.0, 1.0);
    mFunctions->uniform2f(mOffsetLocation, 0.0, 0.0);
    mFunctions->uniform1i(mMultiplyAlphaLocation, 0);
    mFunctions->uniform1i(mUnMultiplyAlphaLocation, 0);

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

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

    if (target == GL_TEXTURE_3D || target == GL_TEXTURE_2D_ARRAY)
    {
        mFunctions->copyTexSubImage3D(target, static_cast<GLint>(level), destOffset.x, destOffset.y,
                                      destOffset.z, 0, 0, sourceArea.width, sourceArea.height);
    }
    else
    {
        mFunctions->copyTexSubImage2D(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.
    orphanScratchTextures();

    return gl::NoError();
}

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

    // Normalize the destination area to have positive width and height because we will use
    // glViewport to set it, which doesn't allow negative width or height.
    gl::Rectangle sourceArea = sourceAreaIn;
    gl::Rectangle destArea   = destAreaIn;
    if (destArea.width < 0)
    {
        destArea.x += destArea.width;
        destArea.width = -destArea.width;
        sourceArea.x += sourceArea.width;
        sourceArea.width = -sourceArea.width;
    }
    if (destArea.height < 0)
    {
        destArea.y += destArea.height;
        destArea.height = -destArea.height;
        sourceArea.y += sourceArea.height;
        sourceArea.height = -sourceArea.height;
    }

    const gl::FramebufferAttachment *readAttachment = source->getReadColorbuffer();
    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);
        gl::ClipRectangle(sourceArea, sourceBounds, &inBoundsSource);

        // Note that inBoundsSource will have lost the orientation information.
        ASSERT(inBoundsSource.width >= 0 && inBoundsSource.height >= 0);

        // 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.
        if (inBoundsSource.width == 0 || inBoundsSource.height == 0)
        {
            return gl::NoError();
        }
    }

    // The blit will be emulated by getting the source of the blit in a texture and sampling it
    // with CLAMP_TO_EDGE. The quad used to draw can trivially compute texture coordinates going
    // from (0, 0) to (1, 1). These texture coordinates will need to be transformed to make two
    // regions match:
    //  - The region of the texture representing the source framebuffer region that will be sampled
    //  - The region of the drawn quad that corresponds to non-clamped blit, this is the same as the
    //    region of the source rectangle that is inside the source attachment.
    //
    //  These two regions, T (texture) and D (dest) are defined by their offset in texcoord space
    //  in (0, 1)^2 and their size in texcoord space in (-1, 1)^2. The size can be negative to
    //  represent the orientation of the blit.
    //
    //  Then if P is the quad texcoord, Q the texcoord inside T, and R the texture texcoord:
    //    - Q = (P - D.offset) / D.size
    //    - Q = (R - T.offset) / T.size
    //  Hence R = (P - D.offset) / D.size * T.size - T.offset
    //          = P * (T.size / D.size) + (T.offset - D.offset * T.size / D.size)

    GLuint textureId;
    Vector2 TOffset;
    Vector2 TSize;

    // TODO(cwallez) once texture dirty bits are landed, reuse attached texture instead of using
    // CopyTexImage2D
    {
        textureId = mScratchTextures[0];
        TOffset   = Vector2(0.0);
        TSize     = Vector2(1.0);
        if (sourceArea.width < 0)
        {
            TOffset.x() = 1.0;
            TSize.x()   = -1.0;
        }
        if (sourceArea.height < 0)
        {
            TOffset.y() = 1.0;
            TSize.y()   = -1.0;
        }

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

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

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

    // Compute normalized sampled draw quad region
    // It is the same as the region of the source rectangle that is in bounds.
    Vector2 DOffset;
    Vector2 DSize;
    {
        ASSERT(sourceArea.width != 0 && sourceArea.height != 0);
        gl::Rectangle orientedInBounds = inBoundsSource;
        if (sourceArea.width < 0)
        {
            orientedInBounds.x += orientedInBounds.width;
            orientedInBounds.width = -orientedInBounds.width;
        }
        if (sourceArea.height < 0)
        {
            orientedInBounds.y += orientedInBounds.height;
            orientedInBounds.height = -orientedInBounds.height;
        }

        DOffset =
            Vector2(static_cast<float>(orientedInBounds.x - sourceArea.x) / sourceArea.width,
                    static_cast<float>(orientedInBounds.y - sourceArea.y) / sourceArea.height);
        DSize = Vector2(static_cast<float>(orientedInBounds.width) / sourceArea.width,
                        static_cast<float>(orientedInBounds.height) / sourceArea.height);
    }

    ASSERT(DSize.x() != 0.0 && DSize.y() != 0.0);
    Vector2 texCoordScale  = TSize / DSize;
    Vector2 texCoordOffset = TOffset - DOffset * texCoordScale;

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

    // Set uniforms
    mStateManager->activeTexture(0);
    mStateManager->bindTexture(GL_TEXTURE_2D, textureId);

    mStateManager->useProgram(mBlitProgram);
    mFunctions->uniform1i(mSourceTextureLocation, 0);
    mFunctions->uniform2f(mScaleLocation, texCoordScale.x(), texCoordScale.y());
    mFunctions->uniform2f(mOffsetLocation, texCoordOffset.x(), texCoordOffset.y());
    mFunctions->uniform1i(mMultiplyAlphaLocation, 0);
    mFunctions->uniform1i(mUnMultiplyAlphaLocation, 0);

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

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

    return gl::NoError();
}

gl::Error BlitGL::copySubTexture(TextureGL *source,
                                 size_t sourceLevel,
                                 TextureGL *dest,
                                 GLenum destTarget,
                                 size_t destLevel,
                                 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());

    // 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};
        source->setSwizzle(swizzle);
    }
    source->setMinFilter(GL_NEAREST);
    source->setMagFilter(GL_NEAREST);
    source->setBaseLevel(static_cast<GLuint>(sourceLevel));

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

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

    Vector2 scale(sourceArea.width / static_cast<float>(sourceSize.width),
                  sourceArea.height / static_cast<float>(sourceSize.height));
    Vector2 offset(sourceArea.x / static_cast<float>(sourceSize.width),
                   sourceArea.y / static_cast<float>(sourceSize.height));
    if (unpackFlipY)
    {
        offset.y() += scale.y();
        scale.y() = -scale.y();
    }

    mStateManager->useProgram(mBlitProgram);
    mFunctions->uniform1i(mSourceTextureLocation, 0);
    mFunctions->uniform2f(mScaleLocation, scale.x(), scale.y());
    mFunctions->uniform2f(mOffsetLocation, offset.x(), offset.y());
    if (unpackPremultiplyAlpha == unpackUnmultiplyAlpha)
    {
        mFunctions->uniform1i(mMultiplyAlphaLocation, 0);
        mFunctions->uniform1i(mUnMultiplyAlphaLocation, 0);
    }
    else
    {
        mFunctions->uniform1i(mMultiplyAlphaLocation, unpackPremultiplyAlpha);
        mFunctions->uniform1i(mUnMultiplyAlphaLocation, unpackUnmultiplyAlpha);
    }

    mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mScratchFBO);
    mFunctions->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, destTarget,
                                     dest->getTextureID(), static_cast<GLint>(destLevel));

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

    return gl::NoError();
}

gl::Error BlitGL::copyTexSubImage(TextureGL *source,
                                  TextureGL *dest,
                                  const gl::Rectangle &sourceArea,
                                  const gl::Offset &destOffset)
{
    ANGLE_TRY(initializeResources());

    mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mScratchFBO);
    mFunctions->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
                                     source->getTextureID(), 0);

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

    mFunctions->copyTexSubImage2D(dest->getTarget(), 0, destOffset.x, destOffset.y, sourceArea.x,
                                  sourceArea.y, sourceArea.width, sourceArea.height);

    return gl::NoError();
}

gl::Error BlitGL::initializeResources()
{
    if (mBlitProgram == 0)
    {
        mBlitProgram = mFunctions->createProgram();

        // Compile the fragment shader
        const char *vsSource =
            "#version 100\n"
            "varying vec2 v_texcoord;\n"
            "uniform vec2 u_scale;\n"
            "uniform vec2 u_offset;\n"
            "attribute vec2 a_texcoord;\n"
            "\n"
            "void main()\n"
            "{\n"
            "    gl_Position = vec4((a_texcoord * 2.0) - 1.0, 0.0, 1.0);\n"
            "    v_texcoord = a_texcoord * u_scale + u_offset;\n"
            "}\n";

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

        mFunctions->attachShader(mBlitProgram, vs);
        mFunctions->deleteShader(vs);

        // Compile the vertex shader
        // It discards if the texcoord is outside (0, 1)^2 so the blitframebuffer workaround
        // doesn't write when the point sampled is outside of the source framebuffer.
        const char *fsSource =
            "#version 100\n"
            "precision highp float;"
            "uniform sampler2D u_source_texture;\n"
            "uniform bool u_multiply_alpha;\n"
            "uniform bool u_unmultiply_alpha;\n"
            "varying vec2 v_texcoord;\n"
            "\n"
            "void main()\n"
            "{\n"
            "    if (clamp(v_texcoord, vec2(0.0), vec2(1.0)) != v_texcoord)\n"
            "    {\n"
            "        discard;\n"
            "    }\n"
            "    vec4 color = texture2D(u_source_texture, v_texcoord);\n"
            "    if (u_multiply_alpha) {color.xyz = color.xyz * color.a;}"
            "    if (u_unmultiply_alpha && color.a != 0.0) {color.xyz = color.xyz / color.a;}"
            "    gl_FragColor = color;"
            "}\n";

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

        mFunctions->attachShader(mBlitProgram, fs);
        mFunctions->deleteShader(fs);

        mFunctions->linkProgram(mBlitProgram);
        ANGLE_TRY(CheckLinkStatus(mFunctions, mBlitProgram));

        mTexCoordAttributeLocation = mFunctions->getAttribLocation(mBlitProgram, "a_texcoord");
        mSourceTextureLocation = mFunctions->getUniformLocation(mBlitProgram, "u_source_texture");
        mScaleLocation         = mFunctions->getUniformLocation(mBlitProgram, "u_scale");
        mOffsetLocation        = mFunctions->getUniformLocation(mBlitProgram, "u_offset");
        mMultiplyAlphaLocation = mFunctions->getUniformLocation(mBlitProgram, "u_multiply_alpha");
        mUnMultiplyAlphaLocation =
            mFunctions->getUniformLocation(mBlitProgram, "u_unmultiply_alpha");
    }

    for (size_t i = 0; i < ArraySize(mScratchTextures); i++)
    {
        if (mScratchTextures[i] == 0)
        {
            mFunctions->genTextures(1, &mScratchTextures[i]);
        }
    }

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

    if (mVertexBuffer == 0)
    {
        mFunctions->genBuffers(1, &mVertexBuffer);
        mStateManager->bindBuffer(GL_ARRAY_BUFFER, 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,
        };

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

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

        mStateManager->bindVertexArray(mVAO, 0);
        mStateManager->bindBuffer(GL_ARRAY_BUFFER, mVertexBuffer);
        mFunctions->enableVertexAttribArray(mTexCoordAttributeLocation);
        mFunctions->vertexAttribPointer(mTexCoordAttributeLocation, 2, GL_FLOAT, GL_FALSE, 0,
                                        nullptr);
    }

    return gl::NoError();
}

void BlitGL::orphanScratchTextures()
{
    for (auto texture : mScratchTextures)
    {
        mStateManager->bindTexture(GL_TEXTURE_2D, texture);
        gl::PixelUnpackState unpack;
        mStateManager->setPixelUnpackState(unpack);
        mFunctions->texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                               nullptr);
    }
}

void BlitGL::setScratchTextureParameter(GLenum param, GLenum value)
{
    for (auto texture : mScratchTextures)
    {
        mStateManager->bindTexture(GL_TEXTURE_2D, texture);
        mFunctions->texParameteri(GL_TEXTURE_2D, param, value);
        mFunctions->texParameteri(GL_TEXTURE_2D, param, value);
    }
}

}  // namespace rx
