/*
 * Copyright (c) 2010, Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * 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.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "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 THE COPYRIGHT
 * OWNER 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 "platform/graphics/gpu/DrawingBuffer.h"

#include "gpu/command_buffer/client/gles2_interface.h"
#include "gpu/command_buffer/common/capabilities.h"
#include "platform/RuntimeEnabledFeatures.h"
#include "platform/TraceEvent.h"
#include "platform/graphics/GraphicsLayer.h"
#include "platform/graphics/ImageBuffer.h"
#include "platform/graphics/gpu/Extensions3DUtil.h"
#include "public/platform/Platform.h"
#include "public/platform/WebCompositorSupport.h"
#include "public/platform/WebExternalBitmap.h"
#include "public/platform/WebExternalTextureLayer.h"
#include "public/platform/WebGraphicsContext3DProvider.h"
#include "wtf/CheckedNumeric.h"
#include "wtf/PtrUtil.h"
#include "wtf/typed_arrays/ArrayBufferContents.h"
#include <algorithm>
#include <memory>

namespace blink {

namespace {

const float s_resourceAdjustedRatio = 0.5;

class ScopedTextureUnit0BindingRestorer {
    STACK_ALLOCATED();
    WTF_MAKE_NONCOPYABLE(ScopedTextureUnit0BindingRestorer);
public:
    ScopedTextureUnit0BindingRestorer(gpu::gles2::GLES2Interface* gl, GLenum activeTextureUnit, GLuint textureUnitZeroId)
        : m_gl(gl)
        , m_oldActiveTextureUnit(activeTextureUnit)
        , m_oldTextureUnitZeroId(textureUnitZeroId)
    {
        m_gl->ActiveTexture(GL_TEXTURE0);
    }
    ~ScopedTextureUnit0BindingRestorer()
    {
        m_gl->BindTexture(GL_TEXTURE_2D, m_oldTextureUnitZeroId);
        m_gl->ActiveTexture(m_oldActiveTextureUnit);
    }

private:
    gpu::gles2::GLES2Interface* m_gl;
    GLenum m_oldActiveTextureUnit;
    GLuint m_oldTextureUnitZeroId;
};

static bool shouldFailDrawingBufferCreationForTesting = false;

} // namespace

PassRefPtr<DrawingBuffer> DrawingBuffer::create(std::unique_ptr<WebGraphicsContext3DProvider> contextProvider,
    const IntSize& size, bool premultipliedAlpha, bool wantAlphaChannel,
    bool wantDepthBuffer, bool wantStencilBuffer, bool wantAntialiasing,
    PreserveDrawingBuffer preserve, WebGLVersion webGLVersion)
{
    ASSERT(contextProvider);

    if (shouldFailDrawingBufferCreationForTesting) {
        shouldFailDrawingBufferCreationForTesting = false;
        return nullptr;
    }

    std::unique_ptr<Extensions3DUtil> extensionsUtil = Extensions3DUtil::create(contextProvider->contextGL());
    if (!extensionsUtil->isValid()) {
        // This might be the first time we notice that the GL context is lost.
        return nullptr;
    }
    ASSERT(extensionsUtil->supportsExtension("GL_OES_packed_depth_stencil"));
    extensionsUtil->ensureExtensionEnabled("GL_OES_packed_depth_stencil");
    bool multisampleSupported = wantAntialiasing
        && (extensionsUtil->supportsExtension("GL_CHROMIUM_framebuffer_multisample")
            || extensionsUtil->supportsExtension("GL_EXT_multisampled_render_to_texture"))
        && extensionsUtil->supportsExtension("GL_OES_rgb8_rgba8");
    if (multisampleSupported) {
        extensionsUtil->ensureExtensionEnabled("GL_OES_rgb8_rgba8");
        if (extensionsUtil->supportsExtension("GL_CHROMIUM_framebuffer_multisample"))
            extensionsUtil->ensureExtensionEnabled("GL_CHROMIUM_framebuffer_multisample");
        else
            extensionsUtil->ensureExtensionEnabled("GL_EXT_multisampled_render_to_texture");
    }
    bool discardFramebufferSupported = extensionsUtil->supportsExtension("GL_EXT_discard_framebuffer");
    if (discardFramebufferSupported)
        extensionsUtil->ensureExtensionEnabled("GL_EXT_discard_framebuffer");

    RefPtr<DrawingBuffer> drawingBuffer = adoptRef(new DrawingBuffer(std::move(contextProvider), std::move(extensionsUtil),
        discardFramebufferSupported, wantAlphaChannel, premultipliedAlpha,
        preserve, webGLVersion, wantDepthBuffer, wantStencilBuffer));
    if (!drawingBuffer->initialize(size, multisampleSupported)) {
        drawingBuffer->beginDestruction();
        return PassRefPtr<DrawingBuffer>();
    }
    return drawingBuffer.release();
}

void DrawingBuffer::forceNextDrawingBufferCreationToFail()
{
    shouldFailDrawingBufferCreationForTesting = true;
}

DrawingBuffer::DrawingBuffer(
    std::unique_ptr<WebGraphicsContext3DProvider> contextProvider,
    std::unique_ptr<Extensions3DUtil> extensionsUtil,
    bool discardFramebufferSupported,
    bool wantAlphaChannel,
    bool premultipliedAlpha,
    PreserveDrawingBuffer preserve,
    WebGLVersion webGLVersion,
    bool wantDepth,
    bool wantStencil)
    : m_preserveDrawingBuffer(preserve)
    , m_webGLVersion(webGLVersion)
    , m_contextProvider(std::move(contextProvider))
    , m_gl(m_contextProvider->contextGL())
    , m_extensionsUtil(std::move(extensionsUtil))
    , m_discardFramebufferSupported(discardFramebufferSupported)
    , m_wantAlphaChannel(wantAlphaChannel)
    , m_premultipliedAlpha(premultipliedAlpha)
    , m_wantDepth(wantDepth)
    , m_wantStencil(wantStencil)
{
    memset(m_colorMask, 0, 4 * sizeof(GLboolean));
    memset(m_clearColor, 0, 4 * sizeof(GLfloat));
    // Used by browser tests to detect the use of a DrawingBuffer.
    TRACE_EVENT_INSTANT0("test_gpu", "DrawingBufferCreation", TRACE_EVENT_SCOPE_GLOBAL);
}

DrawingBuffer::~DrawingBuffer()
{
    ASSERT(m_destructionInProgress);
    ASSERT(m_textureMailboxes.isEmpty());
    m_layer.reset();
    m_contextProvider.reset();
}

void DrawingBuffer::markContentsChanged()
{
    m_contentsChanged = true;
    m_contentsChangeCommitted = false;
}

bool DrawingBuffer::bufferClearNeeded() const
{
    return m_bufferClearNeeded;
}

void DrawingBuffer::setBufferClearNeeded(bool flag)
{
    if (m_preserveDrawingBuffer == Discard) {
        m_bufferClearNeeded = flag;
    } else {
        ASSERT(!m_bufferClearNeeded);
    }
}

gpu::gles2::GLES2Interface* DrawingBuffer::contextGL()
{
    return m_gl;
}

WebGraphicsContext3DProvider* DrawingBuffer::contextProvider()
{
    return m_contextProvider.get();
}

void DrawingBuffer::setIsHidden(bool hidden)
{
    if (m_isHidden == hidden)
        return;
    m_isHidden = hidden;
    if (m_isHidden)
        freeRecycledMailboxes();
}

void DrawingBuffer::setFilterQuality(SkFilterQuality filterQuality)
{
    if (m_filterQuality != filterQuality) {
        m_filterQuality = filterQuality;
        if (m_layer)
            m_layer->setNearestNeighbor(filterQuality == kNone_SkFilterQuality);
    }
}

bool DrawingBuffer::requiresAlphaChannelToBePreserved()
{
    return !m_drawFramebufferBinding && defaultBufferRequiresAlphaChannelToBePreserved();
}

bool DrawingBuffer::defaultBufferRequiresAlphaChannelToBePreserved()
{
    if (wantExplicitResolve()) {
        return !m_wantAlphaChannel && getMultisampledRenderbufferFormat() == GL_RGBA8_OES;
    }

    bool rgbEmulation = contextProvider()->getCapabilities().emulate_rgb_buffer_with_rgba
        || (RuntimeEnabledFeatures::webGLImageChromiumEnabled() && contextProvider()->getCapabilities().chromium_image_rgb_emulation);
    return !m_wantAlphaChannel && rgbEmulation;
}

void DrawingBuffer::freeRecycledMailboxes()
{
    if (m_recycledMailboxQueue.isEmpty())
        return;
    while (!m_recycledMailboxQueue.isEmpty())
        deleteMailbox(m_recycledMailboxQueue.takeLast());
}

bool DrawingBuffer::prepareMailbox(WebExternalTextureMailbox* outMailbox, WebExternalBitmap* bitmap)
{
    if (m_destructionInProgress) {
        // It can be hit in the following sequence.
        // 1. WebGL draws something.
        // 2. The compositor begins the frame.
        // 3. Javascript makes a context lost using WEBGL_lose_context extension.
        // 4. Here.
        return false;
    }
    ASSERT(!m_isHidden);
    if (!m_contentsChanged)
        return false;

    if (m_newMailboxCallback)
        (*m_newMailboxCallback)();

    // Resolve the multisampled buffer into m_colorBuffer texture.
    if (m_antiAliasingMode != None)
        commit();

    if (bitmap) {
        bitmap->setSize(size());

        unsigned char* pixels = bitmap->pixels();
        if (!pixels)
            return false;

        bool needPremultiply = m_wantAlphaChannel && !m_premultipliedAlpha;
        WebGLImageConversion::AlphaOp op = needPremultiply ? WebGLImageConversion::AlphaDoPremultiply : WebGLImageConversion::AlphaDoNothing;
        readBackFramebuffer(pixels, size().width(), size().height(), ReadbackSkia, op);
    }

    // We must restore the texture binding since creating new textures,
    // consuming and producing mailboxes changes it.
    ScopedTextureUnit0BindingRestorer restorer(m_gl, m_activeTextureUnit, m_texture2DBinding);

    // First try to recycle an old buffer.
    RefPtr<MailboxInfo> frontColorBufferMailbox = recycledMailbox();

    // No buffer available to recycle, create a new one.
    if (!frontColorBufferMailbox)
        frontColorBufferMailbox = createNewMailbox(createTextureAndAllocateMemory(m_size));

    if (m_preserveDrawingBuffer == Discard) {
        std::swap(frontColorBufferMailbox->textureInfo, m_colorBuffer);
        attachColorBufferToReadFramebuffer();

        if (m_discardFramebufferSupported) {
            // Explicitly discard framebuffer to save GPU memory bandwidth for tile-based GPU arch.
            const GLenum attachments[3] = { GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT };
            m_gl->DiscardFramebufferEXT(GL_FRAMEBUFFER, 3, attachments);
        }
    } else {
        m_gl->CopySubTextureCHROMIUM(m_colorBuffer.textureId, frontColorBufferMailbox->textureInfo.textureId,
            0, 0, 0, 0, m_size.width(), m_size.height(), GL_FALSE, GL_FALSE, GL_FALSE);
    }

    restoreFramebufferBindings();
    m_contentsChanged = false;

    m_gl->ProduceTextureDirectCHROMIUM(frontColorBufferMailbox->textureInfo.textureId, frontColorBufferMailbox->textureInfo.parameters.target, frontColorBufferMailbox->mailbox.name);
    const GLuint64 fenceSync = m_gl->InsertFenceSyncCHROMIUM();
    if (RuntimeEnabledFeatures::webGLImageChromiumEnabled())
        m_gl->DescheduleUntilFinishedCHROMIUM();
    m_gl->Flush();
    m_gl->GenSyncTokenCHROMIUM(fenceSync, frontColorBufferMailbox->mailbox.syncToken);
    frontColorBufferMailbox->mailbox.validSyncToken = true;
    frontColorBufferMailbox->mailbox.allowOverlay = frontColorBufferMailbox->textureInfo.imageId != 0;
    frontColorBufferMailbox->mailbox.textureTarget = frontColorBufferMailbox->textureInfo.parameters.target;
    frontColorBufferMailbox->mailbox.textureSize = WebSize(m_size.width(), m_size.height());
    frontColorBufferMailbox->mailbox.gpuMemoryBufferId = frontColorBufferMailbox->textureInfo.gpuMemoryBufferId;
    setBufferClearNeeded(true);

    // set m_parentDrawingBuffer to make sure 'this' stays alive as long as it has live mailboxes
    ASSERT(!frontColorBufferMailbox->m_parentDrawingBuffer);
    frontColorBufferMailbox->m_parentDrawingBuffer = this;
    *outMailbox = frontColorBufferMailbox->mailbox;
    m_frontColorBuffer = { frontColorBufferMailbox->textureInfo, frontColorBufferMailbox->mailbox };
    return true;
}

void DrawingBuffer::mailboxReleased(const WebExternalTextureMailbox& mailbox, bool lostResource)
{
    if (m_destructionInProgress || m_gl->GetGraphicsResetStatusKHR() != GL_NO_ERROR || lostResource || m_isHidden) {
        mailboxReleasedWithoutRecycling(mailbox);
        return;
    }

    for (size_t i = 0; i < m_textureMailboxes.size(); i++) {
        RefPtr<MailboxInfo> mailboxInfo = m_textureMailboxes[i];
        if (nameEquals(mailboxInfo->mailbox, mailbox)) {
            memcpy(mailboxInfo->mailbox.syncToken, mailbox.syncToken,
                sizeof(mailboxInfo->mailbox.syncToken));
            mailboxInfo->mailbox.validSyncToken = mailbox.validSyncToken;
            ASSERT(mailboxInfo->m_parentDrawingBuffer.get() == this);
            mailboxInfo->m_parentDrawingBuffer.clear();
            m_recycledMailboxQueue.prepend(mailboxInfo->mailbox);
            return;
        }
    }
    ASSERT_NOT_REACHED();
}

DrawingBuffer::TextureParameters DrawingBuffer::chromiumImageTextureParameters()
{
#if OS(MACOSX)
    // A CHROMIUM_image backed texture requires a specialized set of parameters
    // on OSX.
    TextureParameters parameters;
    parameters.target = GC3D_TEXTURE_RECTANGLE_ARB;

    if (m_wantAlphaChannel) {
        parameters.creationInternalColorFormat = GL_RGBA;
        parameters.internalColorFormat = GL_RGBA;
    } else if (contextProvider()->getCapabilities().chromium_image_rgb_emulation) {
        parameters.creationInternalColorFormat = GL_RGB;
        parameters.internalColorFormat = GL_RGBA;
    } else {
        GLenum format = defaultBufferRequiresAlphaChannelToBePreserved() ? GL_RGBA : GL_RGB;
        parameters.creationInternalColorFormat = format;
        parameters.internalColorFormat = format;
    }

    // Unused when CHROMIUM_image is being used.
    parameters.colorFormat = 0;
    return parameters;
#else
    return defaultTextureParameters();
#endif
}

DrawingBuffer::TextureParameters DrawingBuffer::defaultTextureParameters()
{
    TextureParameters parameters;
    parameters.target = GL_TEXTURE_2D;
    if (m_wantAlphaChannel) {
        parameters.internalColorFormat = GL_RGBA;
        parameters.creationInternalColorFormat = GL_RGBA;
        parameters.colorFormat = GL_RGBA;
    } else if (contextProvider()->getCapabilities().emulate_rgb_buffer_with_rgba) {
        parameters.internalColorFormat = GL_RGBA;
        parameters.creationInternalColorFormat = GL_RGBA;
        parameters.colorFormat = GL_RGBA;
    } else {
        GLenum format = defaultBufferRequiresAlphaChannelToBePreserved() ? GL_RGBA : GL_RGB;
        parameters.creationInternalColorFormat = format;
        parameters.internalColorFormat = format;
        parameters.colorFormat = format;
    }
    return parameters;
}

void DrawingBuffer::mailboxReleasedWithoutRecycling(const WebExternalTextureMailbox& mailbox)
{
    ASSERT(m_textureMailboxes.size());
    // Ensure not to call the destructor until deleteMailbox() is completed.
    RefPtr<DrawingBuffer> self = this;
    deleteMailbox(mailbox);
}

PassRefPtr<DrawingBuffer::MailboxInfo> DrawingBuffer::recycledMailbox()
{
    if (m_recycledMailboxQueue.isEmpty())
        return PassRefPtr<MailboxInfo>();

    // Creation of image backed mailboxes is very expensive, so be less
    // aggressive about pruning them.
    size_t cacheLimit = 1;
    if (RuntimeEnabledFeatures::webGLImageChromiumEnabled())
        cacheLimit = 4;

    WebExternalTextureMailbox mailbox;
    while (m_recycledMailboxQueue.size() > cacheLimit) {
        mailbox = m_recycledMailboxQueue.takeLast();
        deleteMailbox(mailbox);
    }
    mailbox = m_recycledMailboxQueue.takeLast();

    RefPtr<MailboxInfo> mailboxInfo;
    for (size_t i = 0; i < m_textureMailboxes.size(); i++) {
        if (nameEquals(m_textureMailboxes[i]->mailbox, mailbox)) {
            mailboxInfo = m_textureMailboxes[i];
            break;
        }
    }
    ASSERT(mailboxInfo);

    if (mailboxInfo->mailbox.validSyncToken) {
        m_gl->WaitSyncTokenCHROMIUM(mailboxInfo->mailbox.syncToken);
        mailboxInfo->mailbox.validSyncToken = false;
    }

    if (mailboxInfo->size != m_size) {
        resizeTextureMemory(&mailboxInfo->textureInfo, m_size);
        mailboxInfo->size = m_size;
    }

    return mailboxInfo.release();
}

PassRefPtr<DrawingBuffer::MailboxInfo> DrawingBuffer::createNewMailbox(const TextureInfo& info)
{
    RefPtr<MailboxInfo> returnMailbox = adoptRef(new MailboxInfo());
    m_gl->GenMailboxCHROMIUM(returnMailbox->mailbox.name);
    returnMailbox->textureInfo = info;
    returnMailbox->size = m_size;
    m_textureMailboxes.append(returnMailbox);
    return returnMailbox.release();
}

void DrawingBuffer::deleteMailbox(const WebExternalTextureMailbox& mailbox)
{
    for (size_t i = 0; i < m_textureMailboxes.size(); i++) {
        if (nameEquals(m_textureMailboxes[i]->mailbox, mailbox)) {
            if (mailbox.validSyncToken)
                m_gl->WaitSyncTokenCHROMIUM(mailbox.syncToken);

            deleteChromiumImageForTexture(&m_textureMailboxes[i]->textureInfo);

            m_gl->DeleteTextures(1, &m_textureMailboxes[i]->textureInfo.textureId);
            m_textureMailboxes.remove(i);
            return;
        }
    }
    ASSERT_NOT_REACHED();
}

bool DrawingBuffer::initialize(const IntSize& size, bool useMultisampling)
{
    if (m_gl->GetGraphicsResetStatusKHR() != GL_NO_ERROR) {
        // Need to try to restore the context again later.
        return false;
    }

    m_gl->GetIntegerv(GL_MAX_TEXTURE_SIZE, &m_maxTextureSize);

    int maxSampleCount = 0;
    m_antiAliasingMode = None;
    if (useMultisampling) {
        m_gl->GetIntegerv(GL_MAX_SAMPLES_ANGLE, &maxSampleCount);
        m_antiAliasingMode = MSAAExplicitResolve;
        if (m_extensionsUtil->supportsExtension("GL_EXT_multisampled_render_to_texture")) {
            m_antiAliasingMode = MSAAImplicitResolve;
        } else if (m_extensionsUtil->supportsExtension("GL_CHROMIUM_screen_space_antialiasing")) {
            m_antiAliasingMode = ScreenSpaceAntialiasing;
        }
    }
    m_storageTextureSupported = m_webGLVersion > WebGL1 || m_extensionsUtil->supportsExtension("GL_EXT_texture_storage");
    m_sampleCount = std::min(4, maxSampleCount);

    m_gl->GenFramebuffers(1, &m_fbo);
    m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo);
    if (wantExplicitResolve()) {
        m_gl->GenFramebuffers(1, &m_multisampleFBO);
        m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO);
        m_gl->GenRenderbuffers(1, &m_multisampleRenderbuffer);
    }
    if (!reset(size))
        return false;

    if (m_depthStencilBuffer) {
        DCHECK(wantDepthOrStencil());
        m_hasImplicitStencilBuffer = !m_wantStencil;
    }

    if (m_gl->GetGraphicsResetStatusKHR() != GL_NO_ERROR) {
        // It's possible that the drawing buffer allocation provokes a context loss, so check again just in case. http://crbug.com/512302
        return false;
    }

    return true;
}

bool DrawingBuffer::copyToPlatformTexture(gpu::gles2::GLES2Interface* gl, GLuint texture, GLenum internalFormat,
    GLenum destType, GLint level, bool premultiplyAlpha, bool flipY, SourceDrawingBuffer sourceBuffer)
{
    if (m_contentsChanged) {
        if (m_antiAliasingMode != None) {
            commit();
            restoreFramebufferBindings();
        }
        m_gl->Flush();
    }

    // Assume that the destination target is GL_TEXTURE_2D.
    if (!Extensions3DUtil::canUseCopyTextureCHROMIUM(GL_TEXTURE_2D, internalFormat, destType, level))
        return false;

    // Contexts may be in a different share group. We must transfer the texture through a mailbox first
    WebExternalTextureMailbox mailbox;
    GLint textureId = 0;
    GLenum target = 0;
    if (sourceBuffer == FrontBuffer && m_frontColorBuffer.texInfo.textureId) {
        textureId = m_frontColorBuffer.texInfo.textureId;
        mailbox = m_frontColorBuffer.mailbox;
        target = m_frontColorBuffer.texInfo.parameters.target;
    } else {
        textureId = m_colorBuffer.textureId;
        target = m_colorBuffer.parameters.target;
        m_gl->GenMailboxCHROMIUM(mailbox.name);
        m_gl->ProduceTextureDirectCHROMIUM(textureId, target, mailbox.name);
        const GLuint64 fenceSync = m_gl->InsertFenceSyncCHROMIUM();
        m_gl->Flush();
        m_gl->GenSyncTokenCHROMIUM(fenceSync, mailbox.syncToken);
        mailbox.validSyncToken = true;
    }

    if (mailbox.validSyncToken)
        gl->WaitSyncTokenCHROMIUM(mailbox.syncToken);
    GLuint sourceTexture = gl->CreateAndConsumeTextureCHROMIUM(target, mailbox.name);

    GLboolean unpackPremultiplyAlphaNeeded = GL_FALSE;
    GLboolean unpackUnpremultiplyAlphaNeeded = GL_FALSE;
    if (m_wantAlphaChannel && m_premultipliedAlpha && !premultiplyAlpha)
        unpackUnpremultiplyAlphaNeeded = GL_TRUE;
    else if (m_wantAlphaChannel && !m_premultipliedAlpha && premultiplyAlpha)
        unpackPremultiplyAlphaNeeded = GL_TRUE;

    gl->CopyTextureCHROMIUM(sourceTexture, texture, internalFormat, destType, flipY, unpackPremultiplyAlphaNeeded, unpackUnpremultiplyAlphaNeeded);

    gl->DeleteTextures(1, &sourceTexture);

    const GLuint64 fenceSync = gl->InsertFenceSyncCHROMIUM();

    gl->Flush();
    GLbyte syncToken[24];
    gl->GenSyncTokenCHROMIUM(fenceSync, syncToken);
    m_gl->WaitSyncTokenCHROMIUM(syncToken);

    return true;
}

GLuint DrawingBuffer::framebuffer() const
{
    return m_fbo;
}

WebLayer* DrawingBuffer::platformLayer()
{
    if (!m_layer) {
        m_layer = wrapUnique(Platform::current()->compositorSupport()->createExternalTextureLayer(this));

        m_layer->setOpaque(!m_wantAlphaChannel);
        m_layer->setBlendBackgroundColor(m_wantAlphaChannel);
        m_layer->setPremultipliedAlpha(m_premultipliedAlpha);
        m_layer->setNearestNeighbor(m_filterQuality == kNone_SkFilterQuality);
        GraphicsLayer::registerContentsLayer(m_layer->layer());
    }

    return m_layer->layer();
}

void DrawingBuffer::clearPlatformLayer()
{
    if (m_layer)
        m_layer->clearTexture();

    m_gl->Flush();
}

void DrawingBuffer::beginDestruction()
{
    ASSERT(!m_destructionInProgress);
    m_destructionInProgress = true;

    clearPlatformLayer();

    while (!m_recycledMailboxQueue.isEmpty())
        deleteMailbox(m_recycledMailboxQueue.takeLast());

    if (m_multisampleFBO)
        m_gl->DeleteFramebuffers(1, &m_multisampleFBO);

    if (m_fbo)
        m_gl->DeleteFramebuffers(1, &m_fbo);

    if (m_multisampleRenderbuffer)
        m_gl->DeleteRenderbuffers(1, &m_multisampleRenderbuffer);

    if (m_depthStencilBuffer)
        m_gl->DeleteRenderbuffers(1, &m_depthStencilBuffer);

    if (m_colorBuffer.textureId) {
        deleteChromiumImageForTexture(&m_colorBuffer);
        m_gl->DeleteTextures(1, &m_colorBuffer.textureId);
    }

    setSize(IntSize());

    m_colorBuffer = TextureInfo();
    m_frontColorBuffer = FrontBufferInfo();
    m_multisampleRenderbuffer = 0;
    m_depthStencilBuffer = 0;
    m_multisampleFBO = 0;
    m_fbo = 0;

    if (m_layer)
        GraphicsLayer::unregisterContentsLayer(m_layer->layer());
}

GLuint DrawingBuffer::createColorTexture(const TextureParameters& parameters)
{
    GLuint offscreenColorTexture;
    m_gl->GenTextures(1, &offscreenColorTexture);
    m_gl->BindTexture(parameters.target, offscreenColorTexture);
    m_gl->TexParameteri(parameters.target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    m_gl->TexParameteri(parameters.target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    m_gl->TexParameteri(parameters.target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    m_gl->TexParameteri(parameters.target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    return offscreenColorTexture;
}

bool DrawingBuffer::resizeMultisampleFramebuffer(const IntSize& size)
{
    DCHECK(wantExplicitResolve());
    m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO);
    m_gl->BindRenderbuffer(GL_RENDERBUFFER, m_multisampleRenderbuffer);
    m_gl->RenderbufferStorageMultisampleCHROMIUM(GL_RENDERBUFFER, m_sampleCount, getMultisampledRenderbufferFormat(), size.width(), size.height());

    if (m_gl->GetError() == GL_OUT_OF_MEMORY)
        return false;

    m_gl->FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_multisampleRenderbuffer);

    return true;
}

void DrawingBuffer::resizeDepthStencil(const IntSize& size)
{
    m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO ? m_multisampleFBO : m_fbo);
    if (!m_depthStencilBuffer)
        m_gl->GenRenderbuffers(1, &m_depthStencilBuffer);
    m_gl->BindRenderbuffer(GL_RENDERBUFFER, m_depthStencilBuffer);
    if (m_antiAliasingMode == MSAAImplicitResolve)
        m_gl->RenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, m_sampleCount, GL_DEPTH24_STENCIL8_OES, size.width(), size.height());
    else if (m_antiAliasingMode == MSAAExplicitResolve)
        m_gl->RenderbufferStorageMultisampleCHROMIUM(GL_RENDERBUFFER, m_sampleCount, GL_DEPTH24_STENCIL8_OES, size.width(), size.height());
    else
        m_gl->RenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, size.width(), size.height());
    // For ES 2.0 contexts DEPTH_STENCIL is not available natively, so we emulate it
    // at the command buffer level for WebGL contexts.
    m_gl->FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_depthStencilBuffer);
    m_gl->BindRenderbuffer(GL_RENDERBUFFER, 0);
}

bool DrawingBuffer::resizeDefaultFramebuffer(const IntSize& size)
{
    // Resize or create m_colorBuffer.
    if (m_colorBuffer.textureId) {
        resizeTextureMemory(&m_colorBuffer, size);
    } else {
        m_colorBuffer = createTextureAndAllocateMemory(size);
    }

    attachColorBufferToReadFramebuffer();

    if (wantExplicitResolve()) {
        if (!resizeMultisampleFramebuffer(size))
            return false;
    }

    if (wantDepthOrStencil())
        resizeDepthStencil(size);

    if (wantExplicitResolve()) {
        m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO);
        if (m_gl->CheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
            return false;
    }

    m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo);
    return m_gl->CheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE;
}

void DrawingBuffer::clearFramebuffers(GLbitfield clearMask)
{
    // We will clear the multisample FBO, but we also need to clear the non-multisampled buffer.
    if (m_multisampleFBO) {
        m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo);
        m_gl->Clear(GL_COLOR_BUFFER_BIT);
    }

    m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO ? m_multisampleFBO : m_fbo);
    m_gl->Clear(clearMask);
}

void DrawingBuffer::setSize(const IntSize& size)
{
    if (m_size == size)
        return;

    m_size = size;
}

IntSize DrawingBuffer::adjustSize(const IntSize& desiredSize, const IntSize& curSize, int maxTextureSize)
{
    IntSize adjustedSize = desiredSize;

    // Clamp if the desired size is greater than the maximum texture size for the device.
    if (adjustedSize.height() > maxTextureSize)
        adjustedSize.setHeight(maxTextureSize);

    if (adjustedSize.width() > maxTextureSize)
        adjustedSize.setWidth(maxTextureSize);

    return adjustedSize;
}

bool DrawingBuffer::reset(const IntSize& newSize)
{
    CHECK(!newSize.isEmpty());
    IntSize adjustedSize = adjustSize(newSize, m_size, m_maxTextureSize);
    if (adjustedSize.isEmpty())
        return false;

    if (adjustedSize != m_size) {
        do {
            if (!resizeDefaultFramebuffer(adjustedSize)) {
                adjustedSize.scale(s_resourceAdjustedRatio);
                continue;
            }
            break;
        } while (!adjustedSize.isEmpty());

        setSize(adjustedSize);

        if (adjustedSize.isEmpty())
            return false;
    }

    m_gl->Disable(GL_SCISSOR_TEST);
    m_gl->ClearColor(0, 0, 0, defaultBufferRequiresAlphaChannelToBePreserved() ? 1 : 0);
    m_gl->ColorMask(true, true, true, true);

    GLbitfield clearMask = GL_COLOR_BUFFER_BIT;
    if (!!m_depthStencilBuffer) {
        m_gl->ClearDepthf(1.0f);
        clearMask |= GL_DEPTH_BUFFER_BIT;
        m_gl->DepthMask(true);
    }
    if (!!m_depthStencilBuffer) {
        m_gl->ClearStencil(0);
        clearMask |= GL_STENCIL_BUFFER_BIT;
        m_gl->StencilMaskSeparate(GL_FRONT, 0xFFFFFFFF);
    }

    clearFramebuffers(clearMask);
    return true;
}

void DrawingBuffer::commit()
{
    if (wantExplicitResolve() && !m_contentsChangeCommitted) {
        m_gl->BindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, m_multisampleFBO);
        m_gl->BindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, m_fbo);

        if (m_scissorEnabled)
            m_gl->Disable(GL_SCISSOR_TEST);

        int width = m_size.width();
        int height = m_size.height();
        // Use NEAREST, because there is no scale performed during the blit.
        GLuint filter = GL_NEAREST;

        m_gl->BlitFramebufferCHROMIUM(0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT, filter);

        // On old AMD GPUs on OS X, glColorMask doesn't work correctly for
        // multisampled renderbuffers and the alpha channel can be overwritten.
        // Clear the alpha channel of |m_fbo|.
        if (defaultBufferRequiresAlphaChannelToBePreserved()
            && contextProvider()->getCapabilities().disable_multisampling_color_mask_usage) {
            m_gl->ClearColor(0, 0, 0, 1);
            m_gl->ColorMask(false, false, false, true);
            m_gl->Clear(GL_COLOR_BUFFER_BIT);

            m_gl->ClearColor(m_clearColor[0], m_clearColor[1], m_clearColor[2], m_clearColor[3]);
            m_gl->ColorMask(m_colorMask[0], m_colorMask[1], m_colorMask[2], m_colorMask[3]);
        }

        if (m_scissorEnabled)
            m_gl->Enable(GL_SCISSOR_TEST);
    }

    m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo);
    if (m_antiAliasingMode == ScreenSpaceAntialiasing) {
        m_gl->ApplyScreenSpaceAntialiasingCHROMIUM();
    }
    m_contentsChangeCommitted = true;
}

void DrawingBuffer::restoreFramebufferBindings()
{
    if (m_drawFramebufferBinding && m_readFramebufferBinding) {
        if (m_drawFramebufferBinding == m_readFramebufferBinding) {
            m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_readFramebufferBinding);
        } else {
            m_gl->BindFramebuffer(GL_READ_FRAMEBUFFER, m_readFramebufferBinding);
            m_gl->BindFramebuffer(GL_DRAW_FRAMEBUFFER, m_drawFramebufferBinding);
        }
        return;
    }
    if (!m_drawFramebufferBinding && !m_readFramebufferBinding) {
        bind(GL_FRAMEBUFFER);
        return;
    }
    if (!m_drawFramebufferBinding) {
        bind(GL_DRAW_FRAMEBUFFER);
        m_gl->BindFramebuffer(GL_READ_FRAMEBUFFER, m_readFramebufferBinding);
    } else {
        bind(GL_READ_FRAMEBUFFER);
        m_gl->BindFramebuffer(GL_DRAW_FRAMEBUFFER, m_drawFramebufferBinding);
    }
}

bool DrawingBuffer::multisample() const
{
    return m_antiAliasingMode != None;
}

void DrawingBuffer::bind(GLenum target)
{
    m_gl->BindFramebuffer(target, wantExplicitResolve() ? m_multisampleFBO : m_fbo);
}

void DrawingBuffer::setPackAlignment(GLint param)
{
    m_packAlignment = param;
}

bool DrawingBuffer::paintRenderingResultsToImageData(int& width, int& height, SourceDrawingBuffer sourceBuffer, WTF::ArrayBufferContents& contents)
{
    ASSERT(!m_premultipliedAlpha);
    width = size().width();
    height = size().height();

    CheckedNumeric<int> dataSize = 4;
    dataSize *= width;
    dataSize *= height;
    if (!dataSize.IsValid())
        return false;

    WTF::ArrayBufferContents pixels(width * height, 4, WTF::ArrayBufferContents::NotShared, WTF::ArrayBufferContents::DontInitialize);

    GLuint fbo = 0;
    if (sourceBuffer == FrontBuffer && m_frontColorBuffer.texInfo.textureId) {
        m_gl->GenFramebuffers(1, &fbo);
        m_gl->BindFramebuffer(GL_FRAMEBUFFER, fbo);
        m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_frontColorBuffer.texInfo.parameters.target, m_frontColorBuffer.texInfo.textureId, 0);
    } else {
        m_gl->BindFramebuffer(GL_FRAMEBUFFER, framebuffer());
    }

    readBackFramebuffer(static_cast<unsigned char*>(pixels.data()), width, height, ReadbackRGBA, WebGLImageConversion::AlphaDoNothing);
    flipVertically(static_cast<uint8_t*>(pixels.data()), width, height);

    if (fbo) {
        m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_frontColorBuffer.texInfo.parameters.target, 0, 0);
        m_gl->DeleteFramebuffers(1, &fbo);
    }

    restoreFramebufferBindings();

    pixels.transfer(contents);
    return true;
}

void DrawingBuffer::readBackFramebuffer(unsigned char* pixels, int width, int height, ReadbackOrder readbackOrder, WebGLImageConversion::AlphaOp op)
{
    if (m_packAlignment > 4)
        m_gl->PixelStorei(GL_PACK_ALIGNMENT, 1);
    m_gl->ReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
    if (m_packAlignment > 4)
        m_gl->PixelStorei(GL_PACK_ALIGNMENT, m_packAlignment);

    size_t bufferSize = 4 * width * height;

    if (readbackOrder == ReadbackSkia) {
#if (SK_R32_SHIFT == 16) && !SK_B32_SHIFT
        // Swizzle red and blue channels to match SkBitmap's byte ordering.
        // TODO(kbr): expose GL_BGRA as extension.
        for (size_t i = 0; i < bufferSize; i += 4) {
            std::swap(pixels[i], pixels[i + 2]);
        }
#endif
    }

    if (op == WebGLImageConversion::AlphaDoPremultiply) {
        for (size_t i = 0; i < bufferSize; i += 4) {
            pixels[i + 0] = std::min(255, pixels[i + 0] * pixels[i + 3] / 255);
            pixels[i + 1] = std::min(255, pixels[i + 1] * pixels[i + 3] / 255);
            pixels[i + 2] = std::min(255, pixels[i + 2] * pixels[i + 3] / 255);
        }
    } else if (op != WebGLImageConversion::AlphaDoNothing) {
        ASSERT_NOT_REACHED();
    }
}

void DrawingBuffer::flipVertically(uint8_t* framebuffer, int width, int height)
{
    m_scanline.resize(width * 4);
    uint8_t* scanline = &m_scanline[0];
    unsigned rowBytes = width * 4;
    unsigned count = height / 2;
    for (unsigned i = 0; i < count; i++) {
        uint8_t* rowA = framebuffer + i * rowBytes;
        uint8_t* rowB = framebuffer + (height - i - 1) * rowBytes;
        memcpy(scanline, rowB, rowBytes);
        memcpy(rowB, rowA, rowBytes);
        memcpy(rowA, scanline, rowBytes);
    }
}

void DrawingBuffer::allocateConditionallyImmutableTexture(GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type)
{
    if (m_storageTextureSupported) {
        GLenum internalStorageFormat = GL_NONE;
        if (internalformat == GL_RGB) {
            internalStorageFormat = GL_RGB8;
        } else if (internalformat == GL_RGBA) {
            internalStorageFormat = GL_RGBA8;
        } else {
            NOTREACHED();
        }
        m_gl->TexStorage2DEXT(GL_TEXTURE_2D, 1, internalStorageFormat, width, height);
        return;
    }
    m_gl->TexImage2D(target, 0, internalformat, width, height, border, format, type, 0);
}

void DrawingBuffer::deleteChromiumImageForTexture(TextureInfo* info)
{
    if (info->imageId) {
        m_gl->BindTexture(info->parameters.target, info->textureId);
        m_gl->ReleaseTexImage2DCHROMIUM(info->parameters.target, info->imageId);
        m_gl->DestroyImageCHROMIUM(info->imageId);
        info->imageId = 0;
        info->gpuMemoryBufferId = -1;
    }
}

void DrawingBuffer::clearChromiumImageAlpha(const TextureInfo& info)
{
    if (m_wantAlphaChannel)
        return;
    if (!contextProvider()->getCapabilities().chromium_image_rgb_emulation)
        return;

    GLuint fbo = 0;
    m_gl->GenFramebuffers(1, &fbo);
    m_gl->BindFramebuffer(GL_FRAMEBUFFER, fbo);
    m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, info.parameters.target, info.textureId, 0);
    m_gl->ClearColor(0, 0, 0, 1);
    m_gl->ColorMask(false, false, false, true);
    m_gl->Clear(GL_COLOR_BUFFER_BIT);
    m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, info.parameters.target, 0, 0);
    m_gl->DeleteFramebuffers(1, &fbo);
    restoreFramebufferBindings();
    m_gl->ClearColor(m_clearColor[0], m_clearColor[1], m_clearColor[2], m_clearColor[3]);
    m_gl->ColorMask(m_colorMask[0], m_colorMask[1], m_colorMask[2], m_colorMask[3]);
}

DrawingBuffer::TextureInfo DrawingBuffer::createTextureAndAllocateMemory(const IntSize& size)
{
    if (!RuntimeEnabledFeatures::webGLImageChromiumEnabled())
        return createDefaultTextureAndAllocateMemory(size);

    TextureParameters parameters = chromiumImageTextureParameters();
    GLuint imageId = m_gl->CreateGpuMemoryBufferImageCHROMIUM(size.width(), size.height(), parameters.creationInternalColorFormat, GC3D_SCANOUT_CHROMIUM);
    GLint gpuMemoryBufferId = -1;
    GLuint textureId = createColorTexture(parameters);

    if (imageId) {
        m_gl->BindTexImage2DCHROMIUM(parameters.target, imageId);
        m_gl->GetImageivCHROMIUM(imageId, GC3D_GPU_MEMORY_BUFFER_ID, &gpuMemoryBufferId);
        DCHECK_NE(-1, gpuMemoryBufferId);
    }

    TextureInfo info;
    info.textureId = textureId;
    info.imageId = imageId;
    info.gpuMemoryBufferId = gpuMemoryBufferId;
    info.parameters = parameters;
    clearChromiumImageAlpha(info);
    return info;
}

DrawingBuffer::TextureInfo DrawingBuffer::createDefaultTextureAndAllocateMemory(const IntSize& size)
{
    DrawingBuffer::TextureInfo info;
    TextureParameters parameters = defaultTextureParameters();
    info.parameters = parameters;
    info.textureId = createColorTexture(parameters);
    allocateConditionallyImmutableTexture(parameters.target, parameters.creationInternalColorFormat,
        size.width(), size.height(), 0, parameters.colorFormat, GL_UNSIGNED_BYTE);
    info.immutable = m_storageTextureSupported;
    return info;
}

void DrawingBuffer::resizeTextureMemory(TextureInfo* info, const IntSize& size)
{
    ASSERT(info->textureId);
    if (!RuntimeEnabledFeatures::webGLImageChromiumEnabled()) {
        if (info->immutable) {
            DCHECK(m_storageTextureSupported);
            m_gl->DeleteTextures(1, &info->textureId);
            info->textureId = createColorTexture(info->parameters);
        }
        m_gl->BindTexture(info->parameters.target, info->textureId);
        allocateConditionallyImmutableTexture(info->parameters.target, info->parameters.creationInternalColorFormat,
            size.width(), size.height(), 0, info->parameters.colorFormat, GL_UNSIGNED_BYTE);
        info->immutable = m_storageTextureSupported;
        return;
    }

    DCHECK(!info->immutable);
    deleteChromiumImageForTexture(info);
    info->imageId = m_gl->CreateGpuMemoryBufferImageCHROMIUM(size.width(), size.height(), info->parameters.creationInternalColorFormat, GC3D_SCANOUT_CHROMIUM);
    if (info->imageId) {
        m_gl->BindTexture(info->parameters.target, info->textureId);
        m_gl->BindTexImage2DCHROMIUM(info->parameters.target, info->imageId);

        GLint gpuMemoryBufferId = -1;
        m_gl->GetImageivCHROMIUM(info->imageId, GC3D_GPU_MEMORY_BUFFER_ID, &gpuMemoryBufferId);
        DCHECK_NE(-1, gpuMemoryBufferId);
        info->gpuMemoryBufferId = gpuMemoryBufferId;

        clearChromiumImageAlpha(*info);
    } else {
        info->gpuMemoryBufferId = -1;

        // At this point, the texture still exists, but has no allocated
        // storage. This is intentional, and mimics the behavior of a texImage2D
        // failure.
    }
}

void DrawingBuffer::attachColorBufferToReadFramebuffer()
{
    m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo);

    GLenum target = m_colorBuffer.parameters.target;
    GLenum id = m_colorBuffer.textureId;

    m_gl->BindTexture(target, id);

    if (m_antiAliasingMode == MSAAImplicitResolve)
        m_gl->FramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, id, 0, m_sampleCount);
    else
        m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, id, 0);

    restoreTextureBindings();
    restoreFramebufferBindings();
}

bool DrawingBuffer::wantExplicitResolve()
{
    return m_antiAliasingMode == MSAAExplicitResolve;
}

bool DrawingBuffer::wantDepthOrStencil()
{
    return m_wantDepth || m_wantStencil;
}

GLenum DrawingBuffer::getMultisampledRenderbufferFormat()
{
    DCHECK(wantExplicitResolve());
    if (m_wantAlphaChannel)
        return GL_RGBA8_OES;
    if (RuntimeEnabledFeatures::webGLImageChromiumEnabled() && contextProvider()->getCapabilities().chromium_image_rgb_emulation)
        return GL_RGBA8_OES;
    if (contextProvider()->getCapabilities().disable_webgl_rgb_multisampling_usage)
        return GL_RGBA8_OES;
    return GL_RGB8_OES;
}

void DrawingBuffer::restoreTextureBindings()
{
    // This class potentially modifies the bindings for GL_TEXTURE_2D and
    // GL_TEXTURE_RECTANGLE. Only GL_TEXTURE_2D needs to be restored since
    // the public interface for WebGL does not support GL_TEXTURE_RECTANGLE.
    m_gl->BindTexture(GL_TEXTURE_2D, m_texture2DBinding);
}

} // namespace blink
