/*
 Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
 Copyright (C) 2012 Igalia S.L.
 Copyright (C) 2012 Adobe Systems Incorporated

 This library is free software; you can redistribute it and/or
 modify it under the terms of the GNU Library General Public
 License as published by the Free Software Foundation; either
 version 2 of the License, or (at your option) any later version.

 This library is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 Library General Public License for more details.

 You should have received a copy of the GNU Library General Public License
 along with this library; see the file COPYING.LIB.  If not, write to
 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 Boston, MA 02110-1301, USA.
 */

#include "config.h"
#include "TextureMapperGL.h"

#include "GraphicsContext.h"
#include "Image.h"
#include "LengthFunctions.h"
#include "NotImplemented.h"
#include "TextureMapperShaderManager.h"
#include "Timer.h"
#include <wtf/HashMap.h>
#include <wtf/OwnArrayPtr.h>
#include <wtf/PassOwnArrayPtr.h>
#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>

#if PLATFORM(QT)
#include "NativeImageQt.h"
#endif

#if USE(CAIRO)
#include "CairoUtilities.h"
#include "RefPtrCairo.h"
#include <cairo.h>
#endif

#if ENABLE(CSS_SHADERS)
#include "CustomFilterCompiledProgram.h"
#include "CustomFilterOperation.h"
#include "CustomFilterProgram.h"
#include "CustomFilterRenderer.h"
#include "CustomFilterValidatedProgram.h"
#include "ValidatedCustomFilterOperation.h"
#endif

#if !USE(TEXMAP_OPENGL_ES_2)
// FIXME: Move to Extensions3D.h.
#define GL_TEXTURE_RECTANGLE_ARB 0x84F5
#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367
#define GL_UNPACK_ROW_LENGTH 0x0CF2
#define GL_UNPACK_SKIP_PIXELS 0x0CF4
#define GL_UNPACK_SKIP_ROWS 0x0CF3
#endif

namespace WebCore {
struct TextureMapperGLData {
    WTF_MAKE_FAST_ALLOCATED;
public:
    struct SharedGLData : public RefCounted<SharedGLData> {

        typedef HashMap<PlatformGraphicsContext3D, SharedGLData*> GLContextDataMap;
        static GLContextDataMap& glContextDataMap()
        {
            static GLContextDataMap map;
            return map;
        }

        static PassRefPtr<SharedGLData> currentSharedGLData(GraphicsContext3D* context)
        {
            GLContextDataMap::iterator it = glContextDataMap().find(context->platformGraphicsContext3D());
            if (it != glContextDataMap().end())
                return it->value;

            return adoptRef(new SharedGLData(context));
        }



        TextureMapperShaderManager textureMapperShaderManager;

        SharedGLData(GraphicsContext3D* context)
            : textureMapperShaderManager(context)
        {
            glContextDataMap().add(context->platformGraphicsContext3D(), this);
        }

        ~SharedGLData()
        {
            GLContextDataMap::const_iterator end = glContextDataMap().end();
            GLContextDataMap::iterator it;
            for (it = glContextDataMap().begin(); it != end; ++it) {
                if (it->value == this)
                    break;
            }

            ASSERT(it != end);
            glContextDataMap().remove(it);
        }
    };

    SharedGLData& sharedGLData() const
    {
        return *m_sharedGLData;
    }

    void initializeStencil();

    TextureMapperGLData(GraphicsContext3D* context)
        : context(context)
        , PaintFlags(0)
        , previousProgram(0)
        , targetFrameBuffer(0)
        , didModifyStencil(false)
        , previousScissorState(0)
        , previousDepthState(0)
        , m_sharedGLData(TextureMapperGLData::SharedGLData::currentSharedGLData(this->context))
    { }

    GraphicsContext3D* context;
    TransformationMatrix projectionMatrix;
    TextureMapper::PaintFlags PaintFlags;
    GC3Dint previousProgram;
    GC3Dint targetFrameBuffer;
    bool didModifyStencil;
    GC3Dint previousScissorState;
    GC3Dint previousDepthState;
    GC3Dint viewport[4];
    GC3Dint previousScissor[4];
    RefPtr<SharedGLData> m_sharedGLData;
    RefPtr<BitmapTexture> currentSurface;
};

void TextureMapperGL::ClipStack::init(const IntRect& rect)
{
    clipStack.clear();
    clipState = TextureMapperGL::ClipState(rect);
}

void TextureMapperGL::ClipStack::push()
{
    clipStack.append(clipState);
}

void TextureMapperGL::ClipStack::pop()
{
    if (clipStack.isEmpty())
        return;
    clipState = clipStack.last();
    clipStack.removeLast();
}

static void scissorClip(GraphicsContext3D* context, const IntRect& rect)
{
    if (rect.isEmpty())
        return;

    GC3Dint viewport[4];
    context->getIntegerv(GraphicsContext3D::VIEWPORT, viewport);
    context->scissor(rect.x(), viewport[3] - rect.maxY(), rect.width(), rect.height());
}

void TextureMapperGL::ClipStack::apply(GraphicsContext3D* context)
{
    scissorClip(context, clipState.scissorBox);
    context->stencilOp(GraphicsContext3D::KEEP, GraphicsContext3D::KEEP, GraphicsContext3D::KEEP);
    context->stencilFunc(GraphicsContext3D::EQUAL, clipState.stencilIndex - 1, clipState.stencilIndex - 1);
    if (clipState.stencilIndex == 1)
        context->disable(GraphicsContext3D::STENCIL_TEST);
    else
        context->enable(GraphicsContext3D::STENCIL_TEST);
}


void TextureMapperGLData::initializeStencil()
{
    if (currentSurface) {
        static_cast<BitmapTextureGL*>(currentSurface.get())->initializeStencil();
        return;
    }

    if (didModifyStencil)
        return;

    context->clearStencil(0);
    context->clear(GraphicsContext3D::STENCIL_BUFFER_BIT);
    didModifyStencil = true;
}

BitmapTextureGL* toBitmapTextureGL(BitmapTexture* texture)
{
    if (!texture || !texture->isBackedByOpenGL())
        return 0;

    return static_cast<BitmapTextureGL*>(texture);
}

TextureMapperGL::TextureMapperGL()
    : TextureMapper(OpenGLMode)
    , m_context(0)
    , m_enableEdgeDistanceAntialiasing(false)
{
    m_context3D = GraphicsContext3D::createForCurrentGLContext();
    m_data = new TextureMapperGLData(m_context3D.get());
}

TextureMapperGL::ClipStack& TextureMapperGL::clipStack()
{
    return data().currentSurface ? toBitmapTextureGL(data().currentSurface.get())->m_clipStack : m_clipStack;
}

void TextureMapperGL::beginPainting(PaintFlags flags)
{
    m_context3D->getIntegerv(GraphicsContext3D::CURRENT_PROGRAM, &data().previousProgram);
    data().previousScissorState = m_context3D->isEnabled(GraphicsContext3D::SCISSOR_TEST);
    data().previousDepthState = m_context3D->isEnabled(GraphicsContext3D::DEPTH_TEST);
#if PLATFORM(QT)
    if (m_context) {
        QPainter* painter = m_context->platformContext();
        painter->save();
        painter->beginNativePainting();
    }
#endif
    m_context3D->disable(GraphicsContext3D::DEPTH_TEST);
    m_context3D->enable(GraphicsContext3D::SCISSOR_TEST);
    data().didModifyStencil = false;
    m_context3D->depthMask(0);
    m_context3D->getIntegerv(GraphicsContext3D::VIEWPORT, data().viewport);
    m_context3D->getIntegerv(GraphicsContext3D::SCISSOR_BOX, data().previousScissor);
    m_clipStack.init(IntRect(0, 0, data().viewport[2], data().viewport[3]));
    m_context3D->getIntegerv(GraphicsContext3D::FRAMEBUFFER_BINDING, &data().targetFrameBuffer);
    data().PaintFlags = flags;
    bindSurface(0);
}

void TextureMapperGL::endPainting()
{
    if (data().didModifyStencil) {
        m_context3D->clearStencil(1);
        m_context3D->clear(GraphicsContext3D::STENCIL_BUFFER_BIT);
    }

    m_context3D->useProgram(data().previousProgram);

    m_context3D->scissor(data().previousScissor[0], data().previousScissor[1], data().previousScissor[2], data().previousScissor[3]);
    if (data().previousScissorState)
        m_context3D->enable(GraphicsContext3D::SCISSOR_TEST);
    else
        m_context3D->disable(GraphicsContext3D::SCISSOR_TEST);

    if (data().previousDepthState)
        m_context3D->enable(GraphicsContext3D::DEPTH_TEST);
    else
        m_context3D->disable(GraphicsContext3D::DEPTH_TEST);

#if PLATFORM(QT)
    if (!m_context)
        return;
    QPainter* painter = m_context->platformContext();
    painter->endNativePainting();
    painter->restore();
#endif
}

void TextureMapperGL::drawQuad(const DrawQuad& quadToDraw, const TransformationMatrix& modelViewMatrix, TextureMapperShaderProgram* shaderProgram, GC3Denum drawingMode, bool needsBlending)
{
    m_context3D->enableVertexAttribArray(shaderProgram->vertexLocation());
    m_context3D->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, 0);

    const GC3Dfloat quad[] = {
        quadToDraw.targetRectMappedToUnitSquare.p1().x(), quadToDraw.targetRectMappedToUnitSquare.p1().y(),
        quadToDraw.targetRectMappedToUnitSquare.p2().x(), quadToDraw.targetRectMappedToUnitSquare.p2().y(),
        quadToDraw.targetRectMappedToUnitSquare.p3().x(), quadToDraw.targetRectMappedToUnitSquare.p3().y(),
        quadToDraw.targetRectMappedToUnitSquare.p4().x(), quadToDraw.targetRectMappedToUnitSquare.p4().y()
    };
    m_context3D->vertexAttribPointer(shaderProgram->vertexLocation(), 2, GraphicsContext3D::FLOAT, false, 0, GC3Dintptr(quad));

    TransformationMatrix matrix = TransformationMatrix(data().projectionMatrix).multiply(modelViewMatrix).multiply(TransformationMatrix(
            quadToDraw.originalTargetRect.width(), 0, 0, 0,
            0, quadToDraw.originalTargetRect.height(), 0, 0,
            0, 0, 1, 0,
            quadToDraw.originalTargetRect.x(), quadToDraw.originalTargetRect.y(), 0, 1));
    GC3Dfloat m4[] = {
        matrix.m11(), matrix.m12(), matrix.m13(), matrix.m14(),
        matrix.m21(), matrix.m22(), matrix.m23(), matrix.m24(),
        matrix.m31(), matrix.m32(), matrix.m33(), matrix.m34(),
        matrix.m41(), matrix.m42(), matrix.m43(), matrix.m44()
    };
    m_context3D->uniformMatrix4fv(shaderProgram->matrixLocation(), 1, false, m4);

    if (needsBlending) {
        m_context3D->blendFunc(GraphicsContext3D::ONE, GraphicsContext3D::ONE_MINUS_SRC_ALPHA);
        m_context3D->enable(GraphicsContext3D::BLEND);
    } else
        m_context3D->disable(GraphicsContext3D::BLEND);

    m_context3D->drawArrays(drawingMode, 0, 4);
    m_context3D->disableVertexAttribArray(shaderProgram->vertexLocation());
}

void TextureMapperGL::drawBorder(const Color& color, float width, const FloatRect& targetRect, const TransformationMatrix& modelViewMatrix)
{
    if (clipStack().current().scissorBox.isEmpty())
        return;

    RefPtr<TextureMapperShaderProgram> program = data().sharedGLData().textureMapperShaderManager.getShaderProgram(TextureMapperShaderManager::SolidColor);
    m_context3D->useProgram(program->programID());

    float r, g, b, a;
    color.getRGBA(r, g, b, a);
    m_context3D->uniform4f(program->colorLocation(), r, g, b, a);
    m_context3D->lineWidth(width);

    drawQuad(targetRect, modelViewMatrix, program.get(), GraphicsContext3D::LINE_LOOP, color.hasAlpha());
}

void TextureMapperGL::drawRepaintCounter(int value, int pointSize, const FloatPoint& targetPoint, const TransformationMatrix& modelViewMatrix)
{
#if PLATFORM(QT)
    QString counterString = QString::number(value);

    QFont font(QString::fromLatin1("Monospace"), pointSize, QFont::Bold);
    font.setStyleHint(QFont::TypeWriter);

    QFontMetrics fontMetrics(font);
    int width = fontMetrics.width(counterString) + 4;
    int height = fontMetrics.height();

    IntSize size(width, height);
    IntRect sourceRect(IntPoint::zero(), size);
    IntRect targetRect(roundedIntPoint(targetPoint), size);

    QImage image(size, NativeImageQt::defaultFormatForAlphaEnabledImages());
    QPainter painter(&image);
    painter.fillRect(sourceRect, Qt::blue); // Since we won't swap R+B for speed, this will paint red.
    painter.setFont(font);
    painter.setPen(Qt::white);
    painter.drawText(2, height * 0.85, counterString);

    RefPtr<BitmapTexture> texture = acquireTextureFromPool(size);
    const uchar* bits = image.bits();
    texture->updateContents(bits, sourceRect, IntPoint::zero(), image.bytesPerLine(), BitmapTexture::UpdateCanModifyOriginalImageData);
    drawTexture(*texture, targetRect, modelViewMatrix, 1.0f, 0, AllEdges);
#else
    UNUSED_PARAM(value);
    UNUSED_PARAM(pointSize);
    UNUSED_PARAM(targetPoint);
    UNUSED_PARAM(modelViewMatrix);
    notImplemented();
#endif
}

void TextureMapperGL::drawTexture(const BitmapTexture& texture, const FloatRect& targetRect, const TransformationMatrix& matrix, float opacity, const BitmapTexture* mask, unsigned exposedEdges)
{
    if (!texture.isValid())
        return;

    if (clipStack().current().scissorBox.isEmpty())
        return;

    const BitmapTextureGL& textureGL = static_cast<const BitmapTextureGL&>(texture);
    drawTexture(textureGL.id(), textureGL.isOpaque() ? 0 : SupportsBlending, textureGL.size(), targetRect, matrix, opacity, mask, exposedEdges);
}

#if !USE(TEXMAP_OPENGL_ES_2)
void TextureMapperGL::drawTextureRectangleARB(uint32_t texture, Flags flags, const IntSize& textureSize, const FloatRect& targetRect, const TransformationMatrix& modelViewMatrix, float opacity, const BitmapTexture* maskTexture)
{
    RefPtr<TextureMapperShaderProgram> program;
    if (maskTexture)
        program = data().sharedGLData().textureMapperShaderManager.getShaderProgram(TextureMapperShaderManager::MaskedRect);
    else
        program = data().sharedGLData().textureMapperShaderManager.getShaderProgram(TextureMapperShaderManager::Rect);
    m_context3D->useProgram(program->programID());

    m_context3D->enableVertexAttribArray(program->vertexLocation());
    m_context3D->activeTexture(GraphicsContext3D::TEXTURE0);
    m_context3D->bindTexture(GL_TEXTURE_RECTANGLE_ARB, texture);
    m_context3D->uniform1i(program->samplerLocation(), 0);

    m_context3D->uniform1f(program->flipLocation(), !!(flags & ShouldFlipTexture));
    m_context3D->uniform2f(program->samplerSizeLocation(), textureSize.width(), textureSize.height());
    m_context3D->uniform1f(program->opacityLocation(), opacity);

    if (maskTexture && maskTexture->isValid()) {
        const BitmapTextureGL* maskTextureGL = static_cast<const BitmapTextureGL*>(maskTexture);
        m_context3D->activeTexture(GraphicsContext3D::TEXTURE1);
        m_context3D->bindTexture(GraphicsContext3D::TEXTURE_2D, maskTextureGL->id());
        m_context3D->uniform1i(program->maskLocation(), 1);
        m_context3D->activeTexture(GraphicsContext3D::TEXTURE0);
    }

    bool needsBlending = (flags & SupportsBlending) || opacity < 0.99 || maskTexture;
    drawQuad(targetRect, modelViewMatrix, program.get(), GraphicsContext3D::TRIANGLE_FAN, needsBlending);
}
#endif // !USE(TEXMAP_OPENGL_ES_2)

void TextureMapperGL::drawTexture(uint32_t texture, Flags flags, const IntSize& /* textureSize */, const FloatRect& targetRect, const TransformationMatrix& modelViewMatrix, float opacity, const BitmapTexture* maskTexture, unsigned exposedEdges)
{
    bool needsAntialiasing = m_enableEdgeDistanceAntialiasing && !modelViewMatrix.isIntegerTranslation();
    if (needsAntialiasing && drawTextureWithAntialiasing(texture, flags, targetRect, modelViewMatrix, opacity, maskTexture, exposedEdges))
       return;

    RefPtr<TextureMapperShaderProgram> program;
    if (maskTexture)
        program = data().sharedGLData().textureMapperShaderManager.getShaderProgram(TextureMapperShaderManager::Masked);
    else
        program = data().sharedGLData().textureMapperShaderManager.getShaderProgram(TextureMapperShaderManager::Default);
    m_context3D->useProgram(program->programID());

    drawTexturedQuadWithProgram(program.get(), texture, flags, targetRect, modelViewMatrix, opacity, maskTexture);
}

static TransformationMatrix viewportMatrix(GraphicsContext3D* context3D)
{
    GC3Dint viewport[4];
    context3D->getIntegerv(GraphicsContext3D::VIEWPORT, viewport);

    TransformationMatrix matrix;
    matrix.translate3d(viewport[0], viewport[1], 0);
    matrix.scale3d(viewport[2], viewport[3], 0);

    // Map x, y and z to unit square from OpenGL normalized device
    // coordinates which are -1 to 1 on every axis.
    matrix.translate3d(0.5, 0.5, 0.5);
    matrix.scale3d(0.5, 0.5, 0.5);

    return matrix;
}

static void scaleLineEquationCoeffecientsToOptimizeDistanceCalculation(float* coeffecients)
{
    // In the fragment shader we want to calculate the distance from this
    // line to a point (p), which is given by the formula:
    // (A*p.x + B*p.y + C) / sqrt (a^2 + b^2)
    // We can do a small amount of precalculation here to reduce the
    // amount of math in the shader by scaling the coeffecients now.
    float scale = 1.0 / FloatPoint(coeffecients[0], coeffecients[1]).length();
    coeffecients[0] = coeffecients[0] * scale;
    coeffecients[1] = coeffecients[1] * scale;
    coeffecients[2] = coeffecients[2] * scale;
}

static void getStandardEquationCoeffecientsForLine(const FloatPoint& p1, const FloatPoint& p2, float* coeffecients)
{
    // Given two points, the standard equation of a line (Ax + By + C = 0)
    // can be calculated via the formula:
    // (p1.y – p2.y)x + (p1.x – p2.x)y + ((p1.x*p2.y) – (p2.x*p1.y)) = 0
    coeffecients[0] = p1.y() - p2.y();
    coeffecients[1] = p2.x() - p1.x();
    coeffecients[2] = p1.x() * p2.y() - p2.x() * p1.y();
    scaleLineEquationCoeffecientsToOptimizeDistanceCalculation(coeffecients);
}

static void quadToEdgeArray(const FloatQuad& quad, float* edgeArray)
{
    if (quad.isCounterclockwise()) {
        getStandardEquationCoeffecientsForLine(quad.p4(), quad.p3(), edgeArray);
        getStandardEquationCoeffecientsForLine(quad.p3(), quad.p2(), edgeArray + 3);
        getStandardEquationCoeffecientsForLine(quad.p2(), quad.p1(), edgeArray + 6);
        getStandardEquationCoeffecientsForLine(quad.p1(), quad.p4(), edgeArray + 9);
        return;
    }
    getStandardEquationCoeffecientsForLine(quad.p4(), quad.p1(), edgeArray);
    getStandardEquationCoeffecientsForLine(quad.p1(), quad.p2(), edgeArray + 3);
    getStandardEquationCoeffecientsForLine(quad.p2(), quad.p3(), edgeArray + 6);
    getStandardEquationCoeffecientsForLine(quad.p3(), quad.p4(), edgeArray + 9);
}

static FloatSize scaledVectorDifference(const FloatPoint& point1, const FloatPoint& point2, float scale)
{
    FloatSize vector = point1 - point2;
    if (vector.diagonalLengthSquared())
        vector.scale(1.0 / vector.diagonalLength());

    vector.scale(scale);
    return vector;
}

static FloatQuad inflateQuad(const FloatQuad& quad, float distance)
{
    FloatQuad expandedQuad = quad;
    expandedQuad.setP1(expandedQuad.p1() + scaledVectorDifference(quad.p1(), quad.p2(), distance));
    expandedQuad.setP4(expandedQuad.p4() + scaledVectorDifference(quad.p4(), quad.p3(), distance));

    expandedQuad.setP1(expandedQuad.p1() + scaledVectorDifference(quad.p1(), quad.p4(), distance));
    expandedQuad.setP2(expandedQuad.p2() + scaledVectorDifference(quad.p2(), quad.p3(), distance));

    expandedQuad.setP2(expandedQuad.p2() + scaledVectorDifference(quad.p2(), quad.p1(), distance));
    expandedQuad.setP3(expandedQuad.p3() + scaledVectorDifference(quad.p3(), quad.p4(), distance));

    expandedQuad.setP3(expandedQuad.p3() + scaledVectorDifference(quad.p3(), quad.p2(), distance));
    expandedQuad.setP4(expandedQuad.p4() + scaledVectorDifference(quad.p4(), quad.p1(), distance));

    return expandedQuad;
}

bool TextureMapperGL::drawTextureWithAntialiasing(uint32_t texture, Flags flags, const FloatRect& originalTargetRect, const TransformationMatrix& modelViewMatrix, float opacity, const BitmapTexture* maskTexture, unsigned exposedEdges)
{
    // The antialiasing path does not support mask textures at the moment.
    if (maskTexture)
        return false;

    // For now we punt on rendering tiled layers with antialiasing. It's quite hard
    // to render them without seams.
    if (exposedEdges != AllEdges)
        return false;

    // The goal here is render a slightly larger (0.75 pixels in screen space) quad and to
    // gradually taper off the alpha values to do a simple version of edge distance
    // antialiasing. Note here that we are also including the viewport matrix (which
    // translates from normalized device coordinates to screen coordinates), because these
    // values are consumed in the fragment shader, which works in screen coordinates.
    TransformationMatrix screenSpaceTransform = viewportMatrix(m_context3D.get()).multiply(TransformationMatrix(data().projectionMatrix)).multiply(modelViewMatrix).to2dTransform();
    if (!screenSpaceTransform.isInvertible())
        return false;
    FloatQuad quadInScreenSpace = screenSpaceTransform.mapQuad(originalTargetRect);

    const float inflationDistance = 0.75;
    FloatQuad expandedQuadInScreenSpace = inflateQuad(quadInScreenSpace, inflationDistance);

    // In the non-antialiased case the vertices passed are the unit rectangle and double
    // as the texture coordinates (0,0 1,0, 1,1 and 0,1). Here we map the expanded quad
    // coordinates in screen space back to the original rect's texture coordinates.
    // This has the effect of slightly increasing the size of the original quad's geometry
    // in the vertex shader.
    FloatQuad expandedQuadInTextureCoordinates = screenSpaceTransform.inverse().mapQuad(expandedQuadInScreenSpace);
    expandedQuadInTextureCoordinates.move(-originalTargetRect.x(), -originalTargetRect.y());
    expandedQuadInTextureCoordinates.scale(1 / originalTargetRect.width(), 1 / originalTargetRect.height());

    // We prepare both the expanded quad for the fragment shader as well as the rectangular bounding
    // box of that quad, as that seems necessary to properly antialias backfacing quads.
    float targetQuadEdges[24];
    quadToEdgeArray(expandedQuadInScreenSpace, targetQuadEdges);
    quadToEdgeArray(inflateQuad(quadInScreenSpace.boundingBox(),  inflationDistance), targetQuadEdges + 12);

    RefPtr<TextureMapperShaderProgram> program = data().sharedGLData().textureMapperShaderManager.getShaderProgram(TextureMapperShaderManager::Antialiased);
    m_context3D->useProgram(program->programID());
    m_context3D->uniform3fv(program->expandedQuadEdgesInScreenSpaceLocation(), 8, targetQuadEdges);

    drawTexturedQuadWithProgram(program.get(), texture, flags, DrawQuad(originalTargetRect, expandedQuadInTextureCoordinates), modelViewMatrix, opacity, 0 /* maskTexture */);
    return true;
}

void TextureMapperGL::drawTexturedQuadWithProgram(TextureMapperShaderProgram* program, uint32_t texture, Flags flags, const DrawQuad& quadToDraw, const TransformationMatrix& modelViewMatrix, float opacity, const BitmapTexture* maskTexture)
{
    m_context3D->enableVertexAttribArray(program->vertexLocation());
    m_context3D->activeTexture(GraphicsContext3D::TEXTURE0);
    m_context3D->bindTexture(GraphicsContext3D::TEXTURE_2D, texture);
    m_context3D->uniform1i(program->samplerLocation(), 0);

    m_context3D->uniform1f(program->flipLocation(), !!(flags & ShouldFlipTexture));
    m_context3D->uniform1f(program->opacityLocation(), opacity);

    if (maskTexture && maskTexture->isValid()) {
        const BitmapTextureGL* maskTextureGL = static_cast<const BitmapTextureGL*>(maskTexture);
        m_context3D->activeTexture(GraphicsContext3D::TEXTURE1);
        m_context3D->bindTexture(GraphicsContext3D::TEXTURE_2D, maskTextureGL->id());
        m_context3D->uniform1i(program->maskLocation(), 1);
        m_context3D->activeTexture(GraphicsContext3D::TEXTURE0);
    }

    bool needsBlending = (flags & SupportsBlending) || opacity < 0.99 || maskTexture;
    drawQuad(quadToDraw, modelViewMatrix, program, GraphicsContext3D::TRIANGLE_FAN, needsBlending);
}

BitmapTextureGL::BitmapTextureGL(TextureMapperGL* textureMapper)
    : m_id(0)
    , m_fbo(0)
    , m_rbo(0)
    , m_depthBufferObject(0)
    , m_shouldClear(true)
    , m_context3D(textureMapper->graphicsContext3D())
{
}

bool BitmapTextureGL::canReuseWith(const IntSize& contentsSize, Flags)
{
    return contentsSize == m_textureSize;
}

#if OS(DARWIN)
#define DEFAULT_TEXTURE_PIXEL_TRANSFER_TYPE GL_UNSIGNED_INT_8_8_8_8_REV
#else
#define DEFAULT_TEXTURE_PIXEL_TRANSFER_TYPE GraphicsContext3D::UNSIGNED_BYTE
#endif

static void swizzleBGRAToRGBA(uint32_t* data, const IntRect& rect, int stride = 0)
{
    stride = stride ? stride : rect.width();
    for (int y = rect.y(); y < rect.maxY(); ++y) {
        uint32_t* p = data + y * stride;
        for (int x = rect.x(); x < rect.maxX(); ++x)
            p[x] = ((p[x] << 16) & 0xff0000) | ((p[x] >> 16) & 0xff) | (p[x] & 0xff00ff00);
    }
}

static bool driverSupportsBGRASwizzling()
{
#if defined(TEXMAP_OPENGL_ES_2)
    // FIXME: Implement reliable detection. See also https://bugs.webkit.org/show_bug.cgi?id=81103.
    return false;
#else
    return true;
#endif
}

static bool driverSupportsSubImage()
{
#if defined(TEXMAP_OPENGL_ES_2)
    // FIXME: Implement reliable detection.
    return false;
#else
    return true;
#endif
}

void BitmapTextureGL::didReset()
{
    if (!m_id)
        m_id = m_context3D->createTexture();

    m_shouldClear = true;
    if (m_textureSize == contentSize())
        return;

    Platform3DObject format = driverSupportsBGRASwizzling() ? GraphicsContext3D::BGRA : GraphicsContext3D::RGBA;

    m_textureSize = contentSize();
    m_context3D->bindTexture(GraphicsContext3D::TEXTURE_2D, m_id);
    m_context3D->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::LINEAR);
    m_context3D->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::LINEAR);
    m_context3D->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_S, GraphicsContext3D::CLAMP_TO_EDGE);
    m_context3D->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_T, GraphicsContext3D::CLAMP_TO_EDGE);
    m_context3D->texImage2DDirect(GraphicsContext3D::TEXTURE_2D, 0, GraphicsContext3D::RGBA, m_textureSize.width(), m_textureSize.height(), 0, format, DEFAULT_TEXTURE_PIXEL_TRANSFER_TYPE, 0);
}

void BitmapTextureGL::updateContents(const void* srcData, const IntRect& targetRect, const IntPoint& sourceOffset, int bytesPerLine, UpdateContentsFlag updateContentsFlag)
{
    Platform3DObject glFormat = GraphicsContext3D::RGBA;
    m_context3D->bindTexture(GraphicsContext3D::TEXTURE_2D, m_id);

    const unsigned bytesPerPixel = 4;
    char* data = reinterpret_cast<char*>(const_cast<void*>(srcData));
    Vector<char> temporaryData;
    IntPoint adjustedSourceOffset = sourceOffset;

    // prepare temporaryData if necessary
    if ((!driverSupportsBGRASwizzling() && updateContentsFlag == UpdateCannotModifyOriginalImageData)
        || !driverSupportsSubImage()) {
        temporaryData.resize(targetRect.width() * targetRect.height() * bytesPerPixel);
        data = temporaryData.data();
        const char* bits = static_cast<const char*>(srcData);
        const char* src = bits + sourceOffset.y() * bytesPerLine + sourceOffset.x() * bytesPerPixel;
        char* dst = data;
        const int targetBytesPerLine = targetRect.width() * bytesPerPixel;
        for (int y = 0; y < targetRect.height(); ++y) {
            memcpy(dst, src, targetBytesPerLine);
            src += bytesPerLine;
            dst += targetBytesPerLine;
        }

        bytesPerLine = targetBytesPerLine;
        adjustedSourceOffset = IntPoint(0, 0);
    }

    if (driverSupportsBGRASwizzling())
        glFormat = GraphicsContext3D::BGRA;
    else
        swizzleBGRAToRGBA(reinterpret_cast<uint32_t*>(data), IntRect(adjustedSourceOffset, targetRect.size()), bytesPerLine / bytesPerPixel);

    if (bytesPerLine == static_cast<int>(targetRect.width() * bytesPerPixel) && adjustedSourceOffset == IntPoint::zero()) {
        m_context3D->texSubImage2D(GraphicsContext3D::TEXTURE_2D, 0, targetRect.x(), targetRect.y(), targetRect.width(), targetRect.height(), glFormat, DEFAULT_TEXTURE_PIXEL_TRANSFER_TYPE, data);
        return;
    }

    // For ES drivers that don't support sub-images.
    if (!driverSupportsSubImage()) {
        m_context3D->texSubImage2D(GraphicsContext3D::TEXTURE_2D, 0, targetRect.x(), targetRect.y(), targetRect.width(), targetRect.height(), glFormat, DEFAULT_TEXTURE_PIXEL_TRANSFER_TYPE, data);
        return;
    }

#if !defined(TEXMAP_OPENGL_ES_2)
    // Use the OpenGL sub-image extension, now that we know it's available.
    m_context3D->pixelStorei(GL_UNPACK_ROW_LENGTH, bytesPerLine / bytesPerPixel);
    m_context3D->pixelStorei(GL_UNPACK_SKIP_ROWS, adjustedSourceOffset.y());
    m_context3D->pixelStorei(GL_UNPACK_SKIP_PIXELS, adjustedSourceOffset.x());
    m_context3D->texSubImage2D(GraphicsContext3D::TEXTURE_2D, 0, targetRect.x(), targetRect.y(), targetRect.width(), targetRect.height(), glFormat, DEFAULT_TEXTURE_PIXEL_TRANSFER_TYPE, data);
    m_context3D->pixelStorei(GL_UNPACK_ROW_LENGTH, 0);
    m_context3D->pixelStorei(GL_UNPACK_SKIP_ROWS, 0);
    m_context3D->pixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
#endif
}

void BitmapTextureGL::updateContents(Image* image, const IntRect& targetRect, const IntPoint& offset, UpdateContentsFlag updateContentsFlag)
{
    if (!image)
        return;
    NativeImagePtr frameImage = image->nativeImageForCurrentFrame();
    if (!frameImage)
        return;

    int bytesPerLine;
    const char* imageData;

#if PLATFORM(QT)
    QImage qImage = frameImage->toImage();
    imageData = reinterpret_cast<const char*>(qImage.constBits());
    bytesPerLine = qImage.bytesPerLine();
#elif USE(CAIRO)
    cairo_surface_t* surface = frameImage->surface();
    imageData = reinterpret_cast<const char*>(cairo_image_surface_get_data(surface));
    bytesPerLine = cairo_image_surface_get_stride(surface);
#endif

    updateContents(imageData, targetRect, offset, bytesPerLine, updateContentsFlag);
}

#if ENABLE(CSS_FILTERS)

static TextureMapperShaderManager::ShaderKey keyForFilterType(FilterOperation::OperationType type, unsigned pass)
{
    switch (type) {
    case FilterOperation::GRAYSCALE:
        return TextureMapperShaderManager::GrayscaleFilter;
    case FilterOperation::SEPIA:
        return TextureMapperShaderManager::SepiaFilter;
    case FilterOperation::SATURATE:
        return TextureMapperShaderManager::SaturateFilter;
    case FilterOperation::HUE_ROTATE:
        return TextureMapperShaderManager::HueRotateFilter;
    case FilterOperation::INVERT:
        return TextureMapperShaderManager::InvertFilter;
    case FilterOperation::BRIGHTNESS:
        return TextureMapperShaderManager::BrightnessFilter;
    case FilterOperation::CONTRAST:
        return TextureMapperShaderManager::ContrastFilter;
    case FilterOperation::OPACITY:
        return TextureMapperShaderManager::OpacityFilter;
    case FilterOperation::BLUR:
        return TextureMapperShaderManager::BlurFilter;
    case FilterOperation::DROP_SHADOW:
        return pass ? TextureMapperShaderManager::ShadowFilterPass2 : TextureMapperShaderManager::ShadowFilterPass1;
    default:
        ASSERT_NOT_REACHED();
        return TextureMapperShaderManager::Invalid;
    }
}

static unsigned getPassesRequiredForFilter(FilterOperation::OperationType type)
{
    switch (type) {
    case FilterOperation::GRAYSCALE:
    case FilterOperation::SEPIA:
    case FilterOperation::SATURATE:
    case FilterOperation::HUE_ROTATE:
    case FilterOperation::INVERT:
    case FilterOperation::BRIGHTNESS:
    case FilterOperation::CONTRAST:
    case FilterOperation::OPACITY:
#if ENABLE(CSS_SHADERS)
    case FilterOperation::CUSTOM:
#endif
        return 1;
    case FilterOperation::BLUR:
    case FilterOperation::DROP_SHADOW:
        // We use two-passes (vertical+horizontal) for blur and drop-shadow.
        return 2;
    default:
        return 0;
    }
}

// Create a normal distribution of 21 values between -2 and 2.
static const int GaussianKernelHalfWidth = 11;
static const float GaussianKernelStep = 0.2;

static inline float gauss(float x)
{
    return exp(-(x * x) / 2.);
}

static float* gaussianKernel()
{
    static bool prepared = false;
    static float kernel[GaussianKernelHalfWidth] = {0, };

    if (prepared)
        return kernel;

    kernel[0] = gauss(0);
    float sum = kernel[0];
    for (unsigned i = 1; i < GaussianKernelHalfWidth; ++i) {
        kernel[i] = gauss(i * GaussianKernelStep);
        sum += 2 * kernel[i];
    }

    // Normalize the kernel.
    float scale = 1 / sum;
    for (unsigned i = 0; i < GaussianKernelHalfWidth; ++i)
        kernel[i] *= scale;

    prepared = true;
    return kernel;
}

static void prepareFilterProgram(TextureMapperShaderProgram* program, const FilterOperation& operation, unsigned pass, const IntSize& size, GC3Duint contentTexture)
{
    RefPtr<GraphicsContext3D> context = program->context();
    context->useProgram(program->programID());

    switch (operation.getOperationType()) {
    case FilterOperation::GRAYSCALE:
    case FilterOperation::SEPIA:
    case FilterOperation::SATURATE:
    case FilterOperation::HUE_ROTATE:
        context->uniform1f(program->amountLocation(), static_cast<const BasicColorMatrixFilterOperation&>(operation).amount());
        break;
    case FilterOperation::INVERT:
    case FilterOperation::BRIGHTNESS:
    case FilterOperation::CONTRAST:
    case FilterOperation::OPACITY:
        context->uniform1f(program->amountLocation(), static_cast<const BasicComponentTransferFilterOperation&>(operation).amount());
        break;
    case FilterOperation::BLUR: {
        const BlurFilterOperation& blur = static_cast<const BlurFilterOperation&>(operation);
        FloatSize radius;

        // Blur is done in two passes, first horizontally and then vertically. The same shader is used for both.
        if (pass)
            radius.setHeight(floatValueForLength(blur.stdDeviation(), size.height()) / size.height());
        else
            radius.setWidth(floatValueForLength(blur.stdDeviation(), size.width()) / size.width());

        context->uniform2f(program->blurRadiusLocation(), radius.width(), radius.height());
        context->uniform1fv(program->gaussianKernelLocation(), GaussianKernelHalfWidth, gaussianKernel());
        break;
    }
    case FilterOperation::DROP_SHADOW: {
        const DropShadowFilterOperation& shadow = static_cast<const DropShadowFilterOperation&>(operation);
        context->uniform1fv(program->gaussianKernelLocation(), GaussianKernelHalfWidth, gaussianKernel());
        switch (pass) {
        case 0:
            // First pass: vertical alpha blur.
            context->uniform2f(program->shadowOffsetLocation(), float(shadow.location().x()) / float(size.width()), float(shadow.location().y()) / float(size.height()));
            context->uniform1f(program->blurRadiusLocation(), shadow.stdDeviation() / float(size.width()));
            break;
        case 1:
            // Second pass: we need the shadow color and the content texture for compositing.
            context->uniform1f(program->blurRadiusLocation(), shadow.stdDeviation() / float(size.height()));
            context->activeTexture(GraphicsContext3D::TEXTURE1);
            context->bindTexture(GraphicsContext3D::TEXTURE_2D, contentTexture);
            context->uniform1i(program->contentTextureLocation(), 1);
            float r, g, b, a;
            shadow.color().getRGBA(r, g, b, a);
            context->uniform4f(program->shadowColorLocation(), r, g, b, a);
            break;
        }
        break;
    }
    default:
        break;
    }
}

#if ENABLE(CSS_SHADERS)
bool TextureMapperGL::drawUsingCustomFilter(BitmapTexture& target, const BitmapTexture& source, const FilterOperation& filter)
{
    RefPtr<CustomFilterRenderer> renderer;
    switch (filter.getOperationType()) {
    case FilterOperation::CUSTOM: {
        // WebKit2 pipeline is using the CustomFilterOperation, that's because of the "de-serialization" that
        // happens in CoordinatedGraphicsArgumentCoders.
        const CustomFilterOperation* customFilter = static_cast<const CustomFilterOperation*>(&filter);
        RefPtr<CustomFilterProgram> program = customFilter->program();
        renderer = CustomFilterRenderer::create(m_context3D, program->programType(), customFilter->parameters(), 
            customFilter->meshRows(), customFilter->meshColumns(), customFilter->meshBoxType(), customFilter->meshType());
        // FIXME: Optimize this by keeping a reference to the program across frames.
        // https://bugs.webkit.org/show_bug.cgi?id=101801
        RefPtr<CustomFilterCompiledProgram> compiledProgram = CustomFilterCompiledProgram::create(m_context3D, program->vertexShaderString(), program->fragmentShaderString(), program->programType());
        renderer->setCompiledProgram(compiledProgram.release());
        break;
    }
    case FilterOperation::VALIDATED_CUSTOM: {
        // WebKit1 uses the ValidatedCustomFilterOperation.
        // FIXME: This path is not working yet as GraphicsContext3D fails to initialize.
        // https://bugs.webkit.org/show_bug.cgi?id=101532
        return false;
    }
    default:
        ASSERT_NOT_REACHED();
        return false;
    }
    if (!renderer || !renderer->prepareForDrawing())
        return false;
    static_cast<BitmapTextureGL&>(target).initializeDepthBuffer();
    m_context3D->enable(GraphicsContext3D::BLEND);
    m_context3D->blendFunc(GraphicsContext3D::ONE, GraphicsContext3D::ONE_MINUS_SRC_ALPHA);
    m_context3D->enable(GraphicsContext3D::DEPTH_TEST);
    m_context3D->depthFunc(GraphicsContext3D::LESS);
    m_context3D->clearDepth(1);
    m_context3D->depthMask(1);
    m_context3D->clearColor(0, 0, 0, 0);
    m_context3D->clear(GraphicsContext3D::COLOR_BUFFER_BIT | GraphicsContext3D::DEPTH_BUFFER_BIT);
    renderer->draw(static_cast<const BitmapTextureGL&>(source).id(), source.size());
    m_context3D->disable(GraphicsContext3D::DEPTH_TEST);
    m_context3D->disable(GraphicsContext3D::BLEND);
    m_context3D->depthMask(0);
    return true;
}
#endif

void TextureMapperGL::drawFiltered(const BitmapTexture& sampler, const BitmapTexture& contentTexture, const FilterOperation& filter, int pass)
{
    // For standard filters, we always draw the whole texture without transformations.
    TextureMapperShaderManager::ShaderKey key = keyForFilterType(filter.getOperationType(), pass);
    RefPtr<TextureMapperShaderProgram> program = data().sharedGLData().textureMapperShaderManager.getShaderProgram(key);
    ASSERT(program);

    prepareFilterProgram(program.get(), filter, pass, sampler.contentSize(), static_cast<const BitmapTextureGL&>(contentTexture).id());

    m_context3D->enableVertexAttribArray(program->vertexLocation());
    m_context3D->enableVertexAttribArray(program->texCoordLocation());
    m_context3D->activeTexture(GraphicsContext3D::TEXTURE0);
    m_context3D->bindTexture(GraphicsContext3D::TEXTURE_2D, static_cast<const BitmapTextureGL&>(sampler).id());
    m_context3D->uniform1i(program->samplerLocation(), 0);
    const GC3Dfloat targetVertices[] = {-1, -1, 1, -1, 1, 1, -1, 1};
    const GC3Dfloat sourceVertices[] = {0, 0, 1, 0, 1, 1, 0, 1};
    m_context3D->vertexAttribPointer(program->vertexLocation(), 2, GraphicsContext3D::FLOAT, false, 0, GC3Dintptr(targetVertices));
    m_context3D->vertexAttribPointer(program->texCoordLocation(), 2, GraphicsContext3D::FLOAT, false, 0, GC3Dintptr(sourceVertices));
    m_context3D->disable(GraphicsContext3D::BLEND);
    m_context3D->drawArrays(GraphicsContext3D::TRIANGLE_FAN, 0, 4);
    m_context3D->disableVertexAttribArray(program->vertexLocation());
    m_context3D->disableVertexAttribArray(program->texCoordLocation());
}

PassRefPtr<BitmapTexture> BitmapTextureGL::applyFilters(TextureMapper* textureMapper, const BitmapTexture& contentTexture, const FilterOperations& filters)
{
    TextureMapperGL* textureMapperGL = static_cast<TextureMapperGL*>(textureMapper);
    RefPtr<BitmapTexture> previousSurface = textureMapperGL->data().currentSurface;

    RefPtr<BitmapTexture> source = this;
    RefPtr<BitmapTexture> target = textureMapper->acquireTextureFromPool(m_textureSize);

    bool useContentTexture = true;
    for (size_t i = 0; i < filters.size(); ++i) {
        const FilterOperation* filter = filters.at(i);
        ASSERT(filter);

        int numPasses = getPassesRequiredForFilter(filter->getOperationType());
        for (int j = 0; j < numPasses; ++j) {
            textureMapperGL->bindSurface(target.get());
            const BitmapTexture& sourceTexture = useContentTexture ? contentTexture : *source;
#if ENABLE(CSS_SHADERS)
            if (filter->getOperationType() == FilterOperation::CUSTOM) {
                if (textureMapperGL->drawUsingCustomFilter(*target, sourceTexture, *filter)) {
                    // Only swap if the draw was successful.
                    std::swap(source, target);
                    useContentTexture = false;
                }
                continue;
            }
#endif
            textureMapperGL->drawFiltered(sourceTexture, contentTexture, *filter, j);
            std::swap(source, target);
            useContentTexture = false;
        }
    }

    textureMapperGL->bindSurface(previousSurface.get());
    return source;
}
#endif

static inline TransformationMatrix createProjectionMatrix(const IntSize& size, bool mirrored)
{
    const float nearValue = 9999999;
    const float farValue = -99999;

    return TransformationMatrix(2.0 / float(size.width()), 0, 0, 0,
                                0, (mirrored ? 2.0 : -2.0) / float(size.height()), 0, 0,
                                0, 0, -2.f / (farValue - nearValue), 0,
                                -1, mirrored ? -1 : 1, -(farValue + nearValue) / (farValue - nearValue), 1);
}

void BitmapTextureGL::initializeStencil()
{
    if (m_rbo)
        return;

    m_rbo = m_context3D->createRenderbuffer();
    m_context3D->bindRenderbuffer(GraphicsContext3D::RENDERBUFFER, m_rbo);
#ifdef TEXMAP_OPENGL_ES_2
    m_context3D->renderbufferStorage(GraphicsContext3D::RENDERBUFFER, GraphicsContext3D::STENCIL_INDEX8, m_textureSize.width(), m_textureSize.height());
#else
    m_context3D->renderbufferStorage(GraphicsContext3D::RENDERBUFFER, GraphicsContext3D::DEPTH_STENCIL, m_textureSize.width(), m_textureSize.height());
#endif
    m_context3D->bindRenderbuffer(GraphicsContext3D::RENDERBUFFER, 0);
    m_context3D->framebufferRenderbuffer(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::STENCIL_ATTACHMENT, GraphicsContext3D::RENDERBUFFER, m_rbo);
    m_context3D->clearStencil(0);
    m_context3D->clear(GraphicsContext3D::STENCIL_BUFFER_BIT);
}

void BitmapTextureGL::initializeDepthBuffer()
{
    if (m_depthBufferObject)
        return;

    m_depthBufferObject = m_context3D->createRenderbuffer();
    m_context3D->bindRenderbuffer(GraphicsContext3D::RENDERBUFFER, m_depthBufferObject);
    m_context3D->renderbufferStorage(GraphicsContext3D::RENDERBUFFER, GraphicsContext3D::DEPTH_COMPONENT16, m_textureSize.width(), m_textureSize.height());
    m_context3D->bindRenderbuffer(GraphicsContext3D::RENDERBUFFER, 0);
    m_context3D->framebufferRenderbuffer(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::DEPTH_ATTACHMENT, GraphicsContext3D::RENDERBUFFER, m_depthBufferObject);
}

void BitmapTextureGL::clearIfNeeded()
{
    if (!m_shouldClear)
        return;

    m_clipStack.init(IntRect(IntPoint::zero(), m_textureSize));
    m_clipStack.apply(m_context3D.get());
    m_context3D->clearColor(0, 0, 0, 0);
    m_context3D->clear(GraphicsContext3D::COLOR_BUFFER_BIT);
    m_shouldClear = false;
}

void BitmapTextureGL::createFboIfNeeded()
{
    if (m_fbo)
        return;

    m_fbo = m_context3D->createFramebuffer();
    m_context3D->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_fbo);
    m_context3D->framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::COLOR_ATTACHMENT0, GraphicsContext3D::TEXTURE_2D, id(), 0);
    m_shouldClear = true;
}

void BitmapTextureGL::bind(TextureMapperGL* textureMapper)
{
    m_context3D->bindTexture(GraphicsContext3D::TEXTURE_2D, 0);
    createFboIfNeeded();
    m_context3D->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_fbo);
    m_context3D->viewport(0, 0, m_textureSize.width(), m_textureSize.height());
    clearIfNeeded();
    textureMapper->data().projectionMatrix = createProjectionMatrix(m_textureSize, true /* mirrored */);
    m_clipStack.apply(m_context3D.get());
}

BitmapTextureGL::~BitmapTextureGL()
{
    if (m_id)
        m_context3D->deleteTexture(m_id);

    if (m_fbo)
        m_context3D->deleteFramebuffer(m_fbo);

    if (m_rbo)
        m_context3D->deleteRenderbuffer(m_rbo);

    if (m_depthBufferObject)
        m_context3D->deleteRenderbuffer(m_depthBufferObject);
}

bool BitmapTextureGL::isValid() const
{
    return m_id;
}

IntSize BitmapTextureGL::size() const
{
    return m_textureSize;
}

TextureMapperGL::~TextureMapperGL()
{
    delete m_data;
}

void TextureMapperGL::bindDefaultSurface()
{
    m_context3D->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, data().targetFrameBuffer);
    IntSize viewportSize(data().viewport[2], data().viewport[3]);
    data().projectionMatrix = createProjectionMatrix(viewportSize, data().PaintFlags & PaintingMirrored);
    m_context3D->viewport(data().viewport[0], data().viewport[1], viewportSize.width(), viewportSize.height());
    m_clipStack.apply(m_context3D.get());
    data().currentSurface.clear();
}

void TextureMapperGL::bindSurface(BitmapTexture *surface)
{
    if (!surface) {
        bindDefaultSurface();
        return;
    }

    static_cast<BitmapTextureGL*>(surface)->bind(this);
    data().currentSurface = surface;
}

bool TextureMapperGL::beginScissorClip(const TransformationMatrix& modelViewMatrix, const FloatRect& targetRect)
{
    // 3D transforms are currently not supported in scissor clipping
    // resulting in cropped surfaces when z>0.
    if (!modelViewMatrix.isAffine())
        return false;

    FloatQuad quad = modelViewMatrix.projectQuad(targetRect);
    IntRect rect = quad.enclosingBoundingBox();

    // Only use scissors on rectilinear clips.
    if (!quad.isRectilinear() || rect.isEmpty())
        return false;

    clipStack().current().scissorBox.intersect(rect);
    clipStack().apply(m_context3D.get());
    return true;
}

void TextureMapperGL::beginClip(const TransformationMatrix& modelViewMatrix, const FloatRect& targetRect)
{
    clipStack().push();
    if (beginScissorClip(modelViewMatrix, targetRect))
        return;

    data().initializeStencil();

    RefPtr<TextureMapperShaderProgram> program = data().sharedGLData().textureMapperShaderManager.getShaderProgram(TextureMapperShaderManager::Default);

    m_context3D->useProgram(program->programID());
    m_context3D->enableVertexAttribArray(program->vertexLocation());
    const GC3Dfloat unitRect[] = {0, 0, 1, 0, 1, 1, 0, 1};
    m_context3D->vertexAttribPointer(program->vertexLocation(), 2, GraphicsContext3D::FLOAT, false, 0, GC3Dintptr(unitRect));

    TransformationMatrix matrix = TransformationMatrix(data().projectionMatrix)
            .multiply(modelViewMatrix)
            .multiply(TransformationMatrix(targetRect.width(), 0, 0, 0,
                0, targetRect.height(), 0, 0,
                0, 0, 1, 0,
                targetRect.x(), targetRect.y(), 0, 1));

    const GC3Dfloat m4[] = {
        matrix.m11(), matrix.m12(), matrix.m13(), matrix.m14(),
        matrix.m21(), matrix.m22(), matrix.m23(), matrix.m24(),
        matrix.m31(), matrix.m32(), matrix.m33(), matrix.m34(),
        matrix.m41(), matrix.m42(), matrix.m43(), matrix.m44()
    };

    const GC3Dfloat m4all[] = {
        2, 0, 0, 0,
        0, 2, 0, 0,
        0, 0, 1, 0,
        -1, -1, 0, 1
    };

    int& stencilIndex = clipStack().current().stencilIndex;

    m_context3D->enable(GraphicsContext3D::STENCIL_TEST);

    // Make sure we don't do any actual drawing.
    m_context3D->stencilFunc(GraphicsContext3D::NEVER, stencilIndex, stencilIndex);

    // Operate only on the stencilIndex and above.
    m_context3D->stencilMask(0xff & ~(stencilIndex - 1));

    // First clear the entire buffer at the current index.
    m_context3D->uniformMatrix4fv(program->matrixLocation(), 1, false, const_cast<GC3Dfloat*>(m4all));
    m_context3D->stencilOp(GraphicsContext3D::ZERO, GraphicsContext3D::ZERO, GraphicsContext3D::ZERO);
    m_context3D->drawArrays(GraphicsContext3D::TRIANGLE_FAN, 0, 4);

    // Now apply the current index to the new quad.
    m_context3D->stencilOp(GraphicsContext3D::REPLACE, GraphicsContext3D::REPLACE, GraphicsContext3D::REPLACE);
    m_context3D->uniformMatrix4fv(program->matrixLocation(), 1, false, const_cast<GC3Dfloat*>(m4));
    m_context3D->drawArrays(GraphicsContext3D::TRIANGLE_FAN, 0, 4);

    // Clear the state.
    m_context3D->disableVertexAttribArray(program->vertexLocation());
    m_context3D->stencilMask(0);

    // Increase stencilIndex and apply stencil testing.
    stencilIndex *= 2;
    clipStack().apply(m_context3D.get());
}

void TextureMapperGL::endClip()
{
    clipStack().pop();
    clipStack().apply(m_context3D.get());
}

PassRefPtr<BitmapTexture> TextureMapperGL::createTexture()
{
    BitmapTextureGL* texture = new BitmapTextureGL(this);
    return adoptRef(texture);
}

PassOwnPtr<TextureMapper> TextureMapper::platformCreateAccelerated()
{
    return TextureMapperGL::create();
}

};
