Changeset 86276 in webkit


Ignore:
Timestamp:
May 11, 2011 3:11:13 PM (13 years ago)
Author:
noam.rosenthal@nokia.com
Message:

2011-05-11 Noam Rosenthal <noam.rosenthal@nokia.com>

Reviewed by Kenneth Rohde Christiansen.

[Texmap][Qt] Upstream texture-mapper changes from Qt's WebKit2 branch
https://bugs.webkit.org/show_bug.cgi?id=60439

Patch 10/12: Glue the TextureMapper refactoring into Webkit(1).

  1. Pass a GraphicsLayer* instead of a PlatformLayer* to the QWebPageClient.
  2. Set parameters in TextureMapper/TextureMapperNode instead of passing them in an options argument.
  3. Rename PlatformLayerProxyQt to TextureMapperNodeClient
  • Api/qwebframe.cpp: (QWebFramePrivate::renderCompositedLayers):
  • Api/qwebframe.h:
  • Api/qwebframe_p.h: (QWebFramePrivate::QWebFramePrivate):
  • WebCoreSupport/ChromeClientQt.cpp: (WebCore::ChromeClientQt::attachRootGraphicsLayer):
  • WebCoreSupport/PageClientQt.cpp: (WebCore::TextureMapperNodeClientQt::TextureMapperNodeClientQt): (WebCore::TextureMapperNodeClientQt::scroll): (WebCore::TextureMapperNodeClientQt::setTextureMapper): (WebCore::TextureMapperNodeClientQt::~TextureMapperNodeClientQt): (WebCore::TextureMapperNodeClientQt::computeLastModifiedRect): (WebCore::TextureMapperNodeClientQt::syncRootLayer): (WebCore::TextureMapperNodeClientQt::rootNode): (WebCore::PageClientQWidget::setRootGraphicsLayer): (WebCore::PageClientQWidget::syncLayers): (WebCore::PageClientQWidget::~PageClientQWidget): (WebCore::PageClientQGraphicsWidget::~PageClientQGraphicsWidget): (WebCore::PageClientQGraphicsWidget::update): (WebCore::PageClientQGraphicsWidget::syncLayers): (WebCore::PageClientQGraphicsWidget::setRootGraphicsLayer): (WebCore::PageClientQGraphicsWidget::markForSync):
  • WebCoreSupport/PageClientQt.h: (WebCore::PageClientQWidget::PageClientQWidget): (WebCore::PageClientQGraphicsWidget::PageClientQGraphicsWidget): (WebCore::PageClientQGraphicsWidget::syncLayersTimeout):

2011-05-11 Noam Rosenthal <noam.rosenthal@nokia.com>

Reviewed by Kenneth Rohde Christiansen.

[Texmap][Qt] Upstream texture-mapper changes from Qt's WebKit2 branch
https://bugs.webkit.org/show_bug.cgi?id=60439

Patch 12/12: Enable accelerated animations in texture-mapper. The entire interpolation
mechanism happens inside TextureMapper, and we interpolate right before we paint.

No new tests. Tests in LayoutTests/compositing cover this.

  • platform/graphics/texmap/GraphicsLayerTextureMapper.cpp: (WebCore::GraphicsLayerTextureMapper::GraphicsLayerTextureMapper): (WebCore::GraphicsLayerTextureMapper::syncCompositingState): (WebCore::GraphicsLayerTextureMapper::addAnimation): (WebCore::GraphicsLayerTextureMapper::pauseAnimation): (WebCore::GraphicsLayerTextureMapper::removeAnimation): (WebCore::GraphicsLayerTextureMapper::animationStartedTimerFired):
  • platform/graphics/texmap/TextureMapperNode.cpp: (WebCore::TextureMapperNode::descendantsOrSelfHaveRunningAnimations): (WebCore::normalizedAnimationValue): (WebCore::TextureMapperNode::applyOpacityAnimation): (WebCore::solveEpsilon): (WebCore::solveCubicBezierFunction): (WebCore::solveStepsFunction): (WebCore::applyTimingFunction): (WebCore::TextureMapperNode::applyTransformAnimation): (WebCore::TextureMapperNode::applyAnimationFrame): (WebCore::TextureMapperNode::applyAnimation): (WebCore::TextureMapperNode::hasRunningOpacityAnimation): (WebCore::TextureMapperNode::hasRunningTransformAnimation): (WebCore::TextureMapperNode::syncAnimations): (WebCore::copyTimingFunction): (WebCore::copyAnimationValue): (WebCore::TextureMapperAnimation::TextureMapperAnimation):
  • platform/graphics/texmap/TextureMapperNode.h: (WebCore::TextureMapperAnimation::create):
Location:
trunk/Source
Files:
19 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r86275 r86276  
     12011-05-11  Noam Rosenthal  <noam.rosenthal@nokia.com>
     2
     3        Reviewed by Kenneth Rohde Christiansen.
     4
     5        [Texmap][Qt] Upstream texture-mapper changes from Qt's WebKit2 branch
     6        https://bugs.webkit.org/show_bug.cgi?id=60439
     7
     8        Patch 12/12: Enable accelerated animations in texture-mapper. The entire interpolation
     9        mechanism happens inside TextureMapper, and we interpolate right before we paint.
     10
     11        No new tests. Tests in LayoutTests/compositing cover this.
     12
     13        * platform/graphics/texmap/GraphicsLayerTextureMapper.cpp:
     14        (WebCore::GraphicsLayerTextureMapper::GraphicsLayerTextureMapper):
     15        (WebCore::GraphicsLayerTextureMapper::syncCompositingState):
     16        (WebCore::GraphicsLayerTextureMapper::addAnimation):
     17        (WebCore::GraphicsLayerTextureMapper::pauseAnimation):
     18        (WebCore::GraphicsLayerTextureMapper::removeAnimation):
     19        (WebCore::GraphicsLayerTextureMapper::animationStartedTimerFired):
     20        * platform/graphics/texmap/TextureMapperNode.cpp:
     21        (WebCore::TextureMapperNode::descendantsOrSelfHaveRunningAnimations):
     22        (WebCore::normalizedAnimationValue):
     23        (WebCore::TextureMapperNode::applyOpacityAnimation):
     24        (WebCore::solveEpsilon):
     25        (WebCore::solveCubicBezierFunction):
     26        (WebCore::solveStepsFunction):
     27        (WebCore::applyTimingFunction):
     28        (WebCore::TextureMapperNode::applyTransformAnimation):
     29        (WebCore::TextureMapperNode::applyAnimationFrame):
     30        (WebCore::TextureMapperNode::applyAnimation):
     31        (WebCore::TextureMapperNode::hasRunningOpacityAnimation):
     32        (WebCore::TextureMapperNode::hasRunningTransformAnimation):
     33        (WebCore::TextureMapperNode::syncAnimations):
     34        (WebCore::copyTimingFunction):
     35        (WebCore::copyAnimationValue):
     36        (WebCore::TextureMapperAnimation::TextureMapperAnimation):
     37        * platform/graphics/texmap/TextureMapperNode.h:
     38        (WebCore::TextureMapperAnimation::create):
     39
     402011-05-11  Noam Rosenthal  <noam.rosenthal@nokia.com>
     41
     42        Reviewed by Kenneth Rohde Christiansen.
     43
     44        [Texmap][Qt] Upstream texture-mapper changes from Qt's WebKit2 branch
     45        https://bugs.webkit.org/show_bug.cgi?id=60439
     46
     47        Patch 11/12: Patch PluginView to build with TextureMapper on Linux.
     48
     49        No new tests. This is a build fix.
     50
     51        * platform/qt/QWebPageClient.h:
     52        (QWebPageClient::setRootGraphicsLayer):
     53
     542011-05-11  Noam Rosenthal  <noam.rosenthal@nokia.com>
     55
     56        Reviewed by Kenneth Rohde Christiansen.
     57
     58        [Texmap][Qt] Upstream texture-mapper changes from Qt's WebKit2 branch
     59        https://bugs.webkit.org/show_bug.cgi?id=60439
     60
     61        Patch 10/12: Glue the TextureMapper refactoring into Webkit(1).
     62        Pass a GraphicsLayer* instead of a PlatformLayer* to the QWebPageClient.
     63
     64        No new tests. Tests in LayoutTests/compositing cover this.
     65
     66        * platform/qt/QWebPageClient.h:
     67        (QWebPageClient::setRootGraphicsLayer):
     68
     692011-05-11  Noam Rosenthal  <noam.rosenthal@nokia.com>
     70
     71        Reviewed by Kenneth Rohde Christiansen.
     72
     73        [Texmap][Qt] Upstream texture-mapper changes from Qt's WebKit2 branch
     74        https://bugs.webkit.org/show_bug.cgi?id=60439
     75
     76        Patch 9/12: Refactor TextureMapperNode for performance, readability and accuracy.
     77        Changes include:
     78        1. Support the new TextureMapperPlatformLayer for media & WebGL.
     79        2. Use a pool for intermediate surfaces, to avoid constant allocating/freeing of textures.
     80        3. Divide computation operations to different smaller functions.
     81        4. Get rid of scissor/clip layers, use transformed clip instead.
     82        5. Allow tiling for big layers.
     83
     84        No new tests. Tests in LayoutTests/compositing cover this.
     85
     86        * platform/graphics/texmap/GraphicsLayerTextureMapper.cpp:
     87        (WebCore::GraphicsLayerTextureMapper::GraphicsLayerTextureMapper):
     88        (WebCore::GraphicsLayerTextureMapper::setNeedsDisplayInRect):
     89        (WebCore::GraphicsLayerTextureMapper::setContentsToMedia):
     90        (WebCore::GraphicsLayerTextureMapper::platformLayer):
     91        * platform/graphics/texmap/GraphicsLayerTextureMapper.h:
     92        (WebCore::GraphicsLayerTextureMapper::setContentsNeedsDisplay):
     93        (WebCore::GraphicsLayerTextureMapper::setContentsToCanvas):
     94        (WebCore::GraphicsLayerTextureMapper::node):
     95        * platform/graphics/texmap/TextureMapperNode.cpp:
     96        (WebCore::TextureMapperSurfaceManager::getIntermediateSurface):
     97        (WebCore::TextureMapperSurfaceManager::releaseIntermediateSurface):
     98        (WebCore::toTextureMapperNode):
     99        (WebCore::TextureMapperNode::rootLayer):
     100        (WebCore::TextureMapperNode::setTransform):
     101        (WebCore::TextureMapperNode::computePerspectiveTransformIfNeeded):
     102        (WebCore::TextureMapperNode::countDescendantsWithContent):
     103        (WebCore::TextureMapperNode::computeOverlapsIfNeeded):
     104        (WebCore::TextureMapperNode::computeReplicaTransformIfNeeded):
     105        (WebCore::TextureMapperNode::computeLocalTransformIfNeeded):
     106        (WebCore::TextureMapperNode::needsToComputeBoundingRect):
     107        (WebCore::TextureMapperNode::computeAllTransforms):
     108        (WebCore::TextureMapperNode::computeBoundingRectFromRootIfNeeded):
     109        (WebCore::TextureMapperNode::computeTiles):
     110        (WebCore::TextureMapperNode::computeVisibleRectIfNeeded):
     111        (WebCore::TextureMapperNode::renderContent):
     112        (WebCore::TextureMapperNode::paint):
     113        (WebCore::TextureMapperNode::targetRectForTileRect):
     114        (WebCore::TextureMapperNode::paintSelf):
     115        (WebCore::TextureMapperNode::compareGraphicsLayersZValue):
     116        (WebCore::TextureMapperNode::sortByZOrder):
     117        (WebCore::TextureMapperNode::paintSelfAndChildren):
     118        (WebCore::TextureMapperNode::paintReflection):
     119        (WebCore::TextureMapperNode::paintRecursive):
     120        (WebCore::TextureMapperNode::~TextureMapperNode):
     121        (WebCore::TextureMapperNode::resetDescendants):
     122        (WebCore::TextureMapperNode::setContentScale):
     123        (WebCore::TextureMapperNode::setVisibleRect):
     124        (WebCore::TextureMapperNode::syncCompositingState):
     125        (WebCore::TextureMapperNode::invalidateOverlaps):
     126        (WebCore::TextureMapperNode::syncCompositingStateSelf):
     127        (WebCore::TextureMapperNode::descendantsOrSelfHaveRunningAnimations):
     128        * platform/graphics/texmap/TextureMapperNode.h:
     129        (WebCore::TextureMapperPaintOptions::TextureMapperPaintOptions):
     130        (WebCore::TextureMapperAnimation::create):
     131        (WebCore::TextureMapperNode::TextureMapperNode):
     132        (WebCore::TextureMapperNode::size):
     133        (WebCore::TextureMapperNode::setOpacity):
     134        (WebCore::TextureMapperNode::setTextureMapper):
     135        (WebCore::TextureMapperNode::media):
     136        (WebCore::TextureMapperNode::texture):
     137        (WebCore::TextureMapperNode::targetRect):
     138        (WebCore::TextureMapperNode::entireRect):
     139        (WebCore::TextureMapperNode::contentSize):
     140        (WebCore::TextureMapperNode::State::State):
     141        (WebCore::deleteOwnedPtr):
     142
     1432011-05-07  Noam Rosenthal  <noam.rosenthal@nokia.com>
     144
     145        Reviewed by Kenneth Rohde Christiansen.
     146
     147        [Texmap][Qt] Upstream texture-mapper changes from Qt's WebKit2 branch
     148        https://bugs.webkit.org/show_bug.cgi?id=60439
     149
     150        Patch 8/12: Changes to the GL backend of TextureMapper. The code for these changes is intertwined so it was hard to separate
     151        them to different patches. This is the summary of what the changes do:
     152
     153        1. Use stencil for clipping instead of scissors, refactor beginClip/endClip functions to accomodate that.
     154        2. Get rid of the "Target" program which forced an intermediate framebuffer for any content. Instead,
     155           we upload the texture with BGRA from the start. Ports other than Qt can optimize this for their needs.
     156        3. Use glGetAttribLocation instead of glBindAttribLocation; On some platforms we might be polluting the
     157           GL context otherwise.
     158        4. Use image UIDs (cache-key in Qt) instead of image pointers. This is important for images that change their
     159           internal content.
     160        5. Allow packing and unpacking. This is currently a stub, for future memory optimizations.
     161        6. Put some of the initialization code here (beginPainting/endPainting).
     162        7. Allow painting a texture via an ID instead of a BitmapTexture data type.
     163        8. Get rid of makeContextCurrent / obtainCurrentContext. We only use texture-mapper when the context is current.
     164
     165        No new tests. Tests in LayoutTests/compositing test this.
     166
     167        * platform/graphics/opengl/TextureMapperGL.cpp:
     168        (WebCore::debugGLCommand):
     169        (WebCore::TextureMapperGLData::GlobalGLData::createShaderProgram):
     170        (WebCore::TextureMapperGLData::GlobalGLData::GlobalGLData):
     171        (WebCore::TextureMapperGLData::DirectlyCompositedImageRepository::findOrCreate):
     172        (WebCore::TextureMapperGLData::DirectlyCompositedImageRepository::deref):
     173        (WebCore::TextureMapperGLData::DirectlyCompositedImageRepository::~DirectlyCompositedImageRepository):
     174        (WebCore::TextureMapperGLData::TextureMapperGLData):
     175        (WebCore::BitmapTextureGL::id):
     176        (WebCore::BitmapTextureGL::isOpaque):
     177        (WebCore::BitmapTextureGL::relativeSize):
     178        (WebCore::BitmapTextureGL::setTextureMapper):
     179        (WebCore::BitmapTextureGL::pack):
     180        (WebCore::BitmapTextureGL::unpack):
     181        (WebCore::BitmapTextureGL::isPacked):
     182        (WebCore::BitmapTextureGL::BitmapTextureGL):
     183        (WebCore::TextureMapperGL::TextureMapperGL):
     184        (WebCore::TextureMapperGL::initializeShaders):
     185        (WebCore::TextureMapperGL::beginPainting):
     186        (WebCore::TextureMapperGL::endPainting):
     187        (WebCore::TextureMapperGL::drawTexture):
     188        (WebCore::BitmapTextureGL::reset):
     189        (WebCore::BitmapTextureGL::endPaint):
     190        (WebCore::BitmapTextureGL::setContentsToImage):
     191        (WebCore::createProjectionMatrix):
     192        (WebCore::BitmapTextureGL::bind):
     193        (WebCore::BitmapTextureGL::destroy):
     194        (WebCore::TextureMapperGL::~TextureMapperGL):
     195        (WebCore::TextureMapperGL::bindSurface):
     196        (WebCore::TextureMapperGL::beginClip):
     197        (WebCore::TextureMapperGL::endClip):
     198        (WebCore::TextureMapperGL::createTexture):
     199        * platform/graphics/opengl/TextureMapperGL.h:
     200        (WebCore::TextureMapperGL::allowSurfaceForRoot):
     201        (WebCore::TextureMapperGL::create):
     202        (WebCore::TextureMapperGL::setGraphicsContext):
     203        (WebCore::TextureMapperGL::graphicsContext):
     204        (WebCore::TextureMapperGL::isOpenGLBacked):
     205        * platform/graphics/qt/GraphicsContext3DQt.cpp:
     206        (WebCore::GraphicsContext3DInternal::paintToTextureMapper):
     207        (WebCore::GraphicsContext3DInternal::boundingRect):
     208        (WebCore::GraphicsContext3DInternal::paint):
     209        * platform/graphics/qt/MediaPlayerPrivateQt.cpp:
     210        (WebCore::MediaPlayerPrivateQt::repaint):
     211        (WebCore::MediaPlayerPrivateQt::paintToTextureMapper):
     212        * platform/graphics/qt/MediaPlayerPrivateQt.h:
     213        (WebCore::MediaPlayerPrivateQt::acceleratedRenderingStateChanged):
     214        (WebCore::MediaPlayerPrivateQt::platformLayer):
     215
     2162011-05-11  Noam Rosenthal  <noam.rosenthal@nokia.com>
     217
     218        Reviewed by Kenneth Rohde Christiansen.
     219
     220        [Texmap][Qt] Upstream texture-mapper changes from Qt's WebKit2 branch
     221        https://bugs.webkit.org/show_bug.cgi?id=60439
     222
     223        Patch 7/12: Allow a 3D-context (WebGL) to paint itself into a TextureMapper.
     224        This allows using a WebGL canvas with CSS.
     225
     226        No new tests. Tests in LayoutTests/compositing/webgl cover this.
     227
     228        * platform/graphics/qt/GraphicsContext3DQt.cpp:
     229        (WebCore::GraphicsContext3DInternal::paintToTextureMapper):
     230        (WebCore::GraphicsContext3DInternal::boundingRect):
     231        (WebCore::GraphicsContext3DInternal::paint):
     232        * platform/graphics/qt/MediaPlayerPrivateQt.cpp:
     233        (WebCore::MediaPlayerPrivateQt::repaint):
     234        (WebCore::MediaPlayerPrivateQt::paintToTextureMapper):
     235        * platform/graphics/qt/MediaPlayerPrivateQt.h:
     236        (WebCore::MediaPlayerPrivateQt::acceleratedRenderingStateChanged):
     237        (WebCore::MediaPlayerPrivateQt::platformLayer):
     238
     2392011-05-11  Noam Rosenthal  <noam.rosenthal@nokia.com>
     240
     241        Reviewed by Kenneth Rohde Christiansen.
     242
     243        [Texmap][Qt] Upstream texture-mapper changes from Qt's WebKit2 branch
     244        https://bugs.webkit.org/show_bug.cgi?id=60439
     245
     246        Patch 6/12: Allow the Qt media player implementation to paint into a TextureMapper,
     247        to allow videos to be composited.
     248
     249        No new tests. Tests in LayoutTests/compositing cover this.
     250
     251        * platform/graphics/qt/MediaPlayerPrivateQt.cpp:
     252        (WebCore::MediaPlayerPrivateQt::repaint):
     253        (WebCore::MediaPlayerPrivateQt::paintToTextureMapper):
     254        * platform/graphics/qt/MediaPlayerPrivateQt.h:
     255        (WebCore::MediaPlayerPrivateQt::acceleratedRenderingStateChanged):
     256        (WebCore::MediaPlayerPrivateQt::platformLayer):
     257
    12582011-05-11  John Bauman  <jbauman@chromium.org>
    2259
  • trunk/Source/WebCore/platform/graphics/opengl/TextureMapperGL.cpp

    r85417 r86276  
    1919
    2020#include "config.h"
     21
    2122#include "TextureMapperGL.h"
    2223
     
    3031#if defined(TEXMAP_OPENGL_ES_2)
    3132#include <GLES2/gl2.h>
     33#include <GLES2/gl2ext.h>
    3234#elif OS(MAC_OS_X)
    33 #include <AGL/agl.h>
    3435#include <gl.h>
    3536#else
    36 #if OS(UNIX)
    37 #include <GL/glx.h>
    38 #endif
    3937#include <GL/gl.h>
    4038#endif
     
    6866    void glBufferData(GLenum, GLsizeiptr, const GLvoid*, GLenum);
    6967    void glBufferSubData(GLenum, GLsizeiptr, GLsizeiptr, const GLvoid*);
    70     void glGetProgramInfoLog(GLuint program, GLsizei, GLsizei*, GLchar*);
    71 
     68    void glGetProgramInfoLog(GLuint, GLsizei, GLsizei*, GLchar*);
     69    void glGetShaderInfoLog(GLuint, GLsizei, GLsizei*, GLchar*);
     70    void glGenRenderbuffers(GLsizei n, GLuint* ids);
     71    void glDeleteRenderbuffers(GLsizei n, const GLuint* ids);
     72    void glBindRenderbuffer(GLenum target, GLuint id);
     73    void glRenderbufferStorage(GLenum target, GLenum internalFormat, GLsizei width, GLsizei height);
     74    void glFramebufferRenderbuffer(GLenum target, GLenum attachmentPoint, GLenum renderbufferTarget, GLuint renderbufferId);
     75    GLenum glCheckFramebufferStatus(GLenum target);
     76    GLint glGetAttribLocation(GLuint program, const GLchar* name);
    7277#if !OS(MAC_OS_X)
    7378    GLint glGetUniformLocation(GLuint, const GLchar*);
     
    8590        return;
    8691    WTFReportError(__FILE__, line, WTF_PRETTY_FUNCTION, "[TextureMapper GL] Command failed: %s (%x)\n", command, err);
     92    ASSERT_NOT_REACHED();
    8793}
    8894
     
    95101#endif
    96102
    97 static const GLuint gInVertexAttributeIndex = 0;
    98 
    99103struct TextureMapperGLData {
    100     static struct ShaderInfo {
     104    static struct GlobalGLData {
    101105        enum ShaderProgramIndex {
     106            NoProgram = -1,
    102107            SimpleProgram,
    103108            OpacityAndMaskProgram,
    104             TargetProgram,
     109            ClipProgram,
    105110
    106111            ProgramCount
     
    120125        struct ProgramInfo {
    121126            GLuint id;
     127            GLuint vertexAttrib;
    122128            GLint vars[VariableCount];
    123129        };
     
    139145            GL_CMD(glAttachShader(programID, vertexShader))
    140146            GL_CMD(glAttachShader(programID, fragmentShader))
    141             GL_CMD(glBindAttribLocation(programID, gInVertexAttributeIndex, "InVertex"))
    142147            GL_CMD(glLinkProgram(programID))
     148            programs[index].vertexAttrib = glGetAttribLocation(programID, "InVertex");
    143149            programs[index].id = programID;
    144 #ifdef PRINT_PROGRAM_INFO_LOG
    145             char infoLog[1024];
    146             int len;
    147             GL_CMD(glGetProgramInfoLog(programID, 1024, &len, infoLog));
    148             LOG(Graphics, "Compiled program for texture mapper. Log: %s\n", infoLog);
    149 #endif
    150150        }
    151151
    152152        ProgramInfo programs[ProgramCount];
    153153
    154     } shaderInfo;
     154        int stencilIndex;
     155
     156        GlobalGLData()
     157            : stencilIndex(1)
     158        { }
     159    } globalGLData;
    155160
    156161    struct DirectlyCompositedImageRepository {
     
    159164            int refCount;
    160165        };
    161         HashMap<NativeImagePtr, Entry> imageToTexture;
    162 
    163         GLuint findOrCreate(NativeImagePtr image, bool& found)
     166        typedef HashMap<ImageUID, Entry> ImageTextureMap;
     167        ImageTextureMap imageToTexture;
     168
     169        GLuint findOrCreate(ImageUID image, bool& found)
    164170        {
    165             HashMap<NativeImagePtr, Entry>::iterator it = imageToTexture.find(image);
     171            ImageTextureMap::iterator it = imageToTexture.find(image);
    166172            found = false;
    167173            if (it != imageToTexture.end()) {
     
    177183        }
    178184
    179         bool deref(NativeImagePtr image)
     185        bool deref(ImageUID image)
    180186        {
    181             HashMap<NativeImagePtr, Entry>::iterator it = imageToTexture.find(image);
     187            HashMap<ImageUID, Entry>::iterator it = imageToTexture.find(image);
    182188            if (it != imageToTexture.end()) {
    183189                if (it->second.refCount < 2) {
     
    195201        ~DirectlyCompositedImageRepository()
    196202        {
    197             for (HashMap<NativeImagePtr, Entry>::iterator it = imageToTexture.begin(); it != imageToTexture.end(); ++it) {
     203            for (ImageTextureMap::iterator it = imageToTexture.begin(); it != imageToTexture.end(); ++it) {
    198204                GLuint texture = it->second.texture;
    199205                if (texture)
     
    205211
    206212    TextureMapperGLData()
    207         : currentProgram(TextureMapperGLData::ShaderInfo::TargetProgram)
     213        : currentProgram(TextureMapperGLData::GlobalGLData::NoProgram)
    208214    { }
    209215
    210216    TransformationMatrix projectionMatrix;
    211217    int currentProgram;
    212 
    213 #if OS(MAC_OS_X)
    214     AGLContext aglContext;
    215 #elif OS(UNIX)
    216     Drawable glxDrawable;
    217     GLXContext glxContext;
    218 #endif
     218    int previousProgram;
    219219};
    220220
    221 TextureMapperGLData::ShaderInfo TextureMapperGLData::shaderInfo;
     221TextureMapperGLData::GlobalGLData TextureMapperGLData::globalGLData;
    222222
    223223class BitmapTextureGL : public BitmapTexture {
     
    227227    virtual bool isValid() const;
    228228    virtual void reset(const IntSize&, bool opaque);
     229    void bind();
    229230    virtual PlatformGraphicsContext* beginPaint(const IntRect& dirtyRect);
    230231    virtual void endPaint();
    231232    virtual void setContentsToImage(Image*);
    232233    ~BitmapTextureGL() { destroy(); }
     234    virtual uint32_t id() const { return m_id; }
     235    inline bool isOpaque() const { return m_opaque; }
     236    inline FloatSize relativeSize() const { return m_relativeSize; }
     237    void setTextureMapper(TextureMapperGL* texmap) { m_textureMapper = texmap; }
     238
     239    void pack()
     240    {
     241        // This is currently a stub.
     242        if (isPacked())
     243            return;
     244        m_isPacked = true;
     245    }
     246
     247    void unpack()
     248    {
     249        // This is currently a stub.
     250        if (!isPacked())
     251            return;
     252        m_isPacked = false;
     253    }
     254
     255    bool isPacked() const
     256    {
     257        return m_isPacked;
     258    }
    233259
    234260private:
    235261    GLuint m_id;
    236     NativeImagePtr m_image;
     262    ImageUID m_imageUID;
    237263    FloatSize m_relativeSize;
    238264    bool m_opaque;
     
    241267    IntRect m_dirtyRect;
    242268    GLuint m_fbo;
     269    GLuint m_rbo;
    243270    IntSize m_actualSize;
    244271    bool m_surfaceNeedsReset;
     272    bool m_isPacked;
    245273    TextureMapperGL* m_textureMapper;
    246274    BitmapTextureGL()
    247275        : m_id(0)
    248         , m_image(0)
     276        , m_imageUID(0)
    249277        , m_opaque(false)
    250278        , m_fbo(0)
     279        , m_rbo(0)
    251280        , m_surfaceNeedsReset(true)
    252281        , m_textureMapper(0)
     
    258287
    259288#define TEXMAP_GET_SHADER_VAR_LOCATION(prog, var) \
    260     if (TextureMapperGLData::shaderInfo.getUniformLocation(TextureMapperGLData::shaderInfo.prog##Program, TextureMapperGLData::shaderInfo.var##Variable, #var) < 0) \
     289    if (TextureMapperGLData::globalGLData.getUniformLocation(TextureMapperGLData::globalGLData.prog##Program, TextureMapperGLData::globalGLData.var##Variable, #var) < 0) \
    261290            LOG_ERROR("Couldn't find variable "#var" in program "#prog"\n");
    262291
    263292#define TEXMAP_BUILD_SHADER(program) \
    264     TextureMapperGLData::shaderInfo.createShaderProgram(vertexShaderSource##program, fragmentShaderSource##program, TextureMapperGLData::shaderInfo.program##Program);
     293    TextureMapperGLData::globalGLData.createShaderProgram(vertexShaderSource##program, fragmentShaderSource##program, TextureMapperGLData::globalGLData.program##Program);
    265294
    266295TextureMapperGL::TextureMapperGL()
    267296    : m_data(new TextureMapperGLData)
    268297{
     298}
     299
     300void TextureMapperGL::initializeShaders()
     301{
    269302    static bool shadersCompiled = false;
    270     obtainCurrentContext();
    271303    if (shadersCompiled)
    272304        return;
     
    326358"               }                                                           \n";
    327359
    328     const char* fragmentShaderSourceTarget =
    329             OES2_PRECISION_DEFINITIONS
    330 "               uniform sampler2D SourceTexture;                                            \n"
    331 "               uniform lowp float Opacity;                                                 \n"
    332 "               varying highp vec2 OutTexCoordSource;                                       \n"
    333 "               void main(void)                                                             \n"
    334 "               {                                                                           \n"
    335 "                   lowp vec4 color = texture2D(SourceTexture, OutTexCoordSource);          \n"
    336 "                   gl_FragColor = vec4(color.bgr * Opacity, color.a * Opacity);            \n"
    337 "               }                                                                           \n";
    338 
    339     const char* vertexShaderSourceTarget = vertexShaderSourceSimple;
     360    const char* fragmentShaderSourceClip =
     361"               void main(void) { gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0); }                                ";
     362
     363    const char* vertexShaderSourceClip =
     364"               uniform mat4 InMatrix;                                      \n"
     365"               attribute vec4 InVertex;                                    \n"
     366"               void main(void) { gl_Position = InMatrix * InVertex; }      ";
     367
    340368
    341369    TEXMAP_BUILD_SHADER(Simple)
    342370    TEXMAP_BUILD_SHADER(OpacityAndMask)
    343     TEXMAP_BUILD_SHADER(Target)
     371    TEXMAP_BUILD_SHADER(Clip)
    344372
    345373    TEXMAP_GET_SHADER_VAR_LOCATION(OpacityAndMask, InMatrix)
     
    355383    TEXMAP_GET_SHADER_VAR_LOCATION(Simple, Opacity)
    356384
    357     TEXMAP_GET_SHADER_VAR_LOCATION(Target, InSourceMatrix)
    358     TEXMAP_GET_SHADER_VAR_LOCATION(Target, InMatrix)
    359     TEXMAP_GET_SHADER_VAR_LOCATION(Target, SourceTexture)
    360     TEXMAP_GET_SHADER_VAR_LOCATION(Target, Opacity)
    361 }
    362 
    363 void TextureMapperGL::drawTexture(const BitmapTexture& texture, const IntRect& targetRect, const TransformationMatrix& modelViewMatrix, float opacity, const BitmapTexture* maskTexture)
     385    TEXMAP_GET_SHADER_VAR_LOCATION(Clip, InMatrix)
     386}
     387
     388void TextureMapperGL::beginPainting()
     389{
     390#if PLATFORM(QT)
     391    glGetIntegerv(GL_CURRENT_PROGRAM, &m_data->previousProgram);
     392    QPainter* painter = m_context->platformContext();
     393    painter->save();
     394    painter->beginNativePainting();
     395    glClearStencil(0);
     396    glClear(GL_STENCIL_BUFFER_BIT);
     397    bindSurface(0);
     398#endif
     399    initializeShaders();
     400}
     401
     402void TextureMapperGL::endPainting()
     403{
     404#if PLATFORM(QT)
     405    glClearStencil(1);
     406    glClear(GL_STENCIL_BUFFER_BIT);
     407    QPainter* painter = m_context->platformContext();
     408    glUseProgram(m_data->previousProgram);
     409    painter->endNativePainting();
     410    painter->restore();
     411#endif
     412}
     413
     414
     415void TextureMapperGL::drawTexture(const BitmapTexture& texture, const FloatRect& targetRect, const TransformationMatrix& matrix, float opacity, const BitmapTexture* mask)
    364416{
    365417    if (!texture.isValid())
    366418        return;
    367 
    368419    const BitmapTextureGL& textureGL = static_cast<const BitmapTextureGL&>(texture);
    369 
    370     TextureMapperGLData::ShaderInfo::ShaderProgramIndex program;
     420    drawTexture(textureGL.id(), textureGL.isOpaque(), textureGL.relativeSize(), targetRect, matrix, opacity, mask, false);
     421}
     422
     423void TextureMapperGL::drawTexture(uint32_t texture, bool opaque, const FloatSize& relativeSize, const FloatRect& targetRect, const TransformationMatrix& modelViewMatrix, float opacity, const BitmapTexture* maskTexture, bool flip)
     424{
     425    TextureMapperGLData::GlobalGLData::ShaderProgramIndex program;
    371426    if (maskTexture)
    372         program = TextureMapperGLData::ShaderInfo::OpacityAndMaskProgram;
     427        program = TextureMapperGLData::GlobalGLData::OpacityAndMaskProgram;
    373428    else
    374         program = TextureMapperGLData::ShaderInfo::SimpleProgram;
    375 
    376     const TextureMapperGLData::ShaderInfo::ProgramInfo& programInfo = data().shaderInfo.programs[program];
    377     if (data().currentProgram != program) {
    378         GL_CMD(glUseProgram(programInfo.id))
    379         GL_CMD(glDisableVertexAttribArray(gInVertexAttributeIndex))
    380         data().currentProgram = program;
    381         GL_CMD(glEnableVertexAttribArray(gInVertexAttributeIndex))
    382     }
    383 
    384     GL_CMD(glDisable(GL_DEPTH_TEST))
    385     GL_CMD(glDisable(GL_STENCIL_TEST))
    386 
     429        program = TextureMapperGLData::GlobalGLData::SimpleProgram;
     430
     431    const TextureMapperGLData::GlobalGLData::ProgramInfo& programInfo = data().globalGLData.programs[program];
     432    GL_CMD(glUseProgram(programInfo.id))
     433    data().currentProgram = program;
     434    GL_CMD(glEnableVertexAttribArray(programInfo.vertexAttrib))
    387435    GL_CMD(glActiveTexture(GL_TEXTURE0))
    388     GL_CMD(glBindTexture(GL_TEXTURE_2D, textureGL.m_id))
     436    GL_CMD(glBindTexture(GL_TEXTURE_2D, texture))
    389437    GL_CMD(glBindBuffer(GL_ARRAY_BUFFER, 0))
    390438    const GLfloat unitRect[] = {0, 0, 1, 0, 1, 1, 0, 1};
    391     GL_CMD(glVertexAttribPointer(gInVertexAttributeIndex, 2, GL_FLOAT, GL_FALSE, 0, unitRect))
     439    GL_CMD(glVertexAttribPointer(programInfo.vertexAttrib, 2, GL_FLOAT, GL_FALSE, 0, unitRect))
    392440
    393441    TransformationMatrix matrix = TransformationMatrix(data().projectionMatrix).multiply(modelViewMatrix).multiply(TransformationMatrix(
     
    403451        matrix.m41(), matrix.m42(), matrix.m43(), matrix.m44()
    404452    };
    405     const GLfloat m4src[] = {textureGL.m_relativeSize.width(), 0, 0, 0,
    406                                      0, textureGL.m_relativeSize.height(), 0, 0,
     453    const GLfloat m4src[] = {relativeSize.width(), 0, 0, 0,
     454                                     0, relativeSize.height() * (flip ? -1 : 1), 0, 0,
    407455                                     0, 0, 1, 0,
    408                                      0, 0, 0, 1};
    409     GL_CMD(glUniformMatrix4fv(programInfo.vars[TextureMapperGLData::ShaderInfo::InMatrixVariable], 1, GL_FALSE, m4))
    410     GL_CMD(glUniformMatrix4fv(programInfo.vars[TextureMapperGLData::ShaderInfo::InSourceMatrixVariable], 1, GL_FALSE, m4src))
    411     GL_CMD(glUniform1i(programInfo.vars[TextureMapperGLData::ShaderInfo::SourceTextureVariable], 0))
    412     GL_CMD(glUniform1f(programInfo.vars[TextureMapperGLData::ShaderInfo::OpacityVariable], opacity))
     456                                     0, flip ? relativeSize.height() : 0, 0, 1};
     457
     458    GL_CMD(glUniformMatrix4fv(programInfo.vars[TextureMapperGLData::GlobalGLData::InMatrixVariable], 1, GL_FALSE, m4))
     459    GL_CMD(glUniformMatrix4fv(programInfo.vars[TextureMapperGLData::GlobalGLData::InSourceMatrixVariable], 1, GL_FALSE, m4src))
     460    GL_CMD(glUniform1i(programInfo.vars[TextureMapperGLData::GlobalGLData::SourceTextureVariable], 0))
     461    GL_CMD(glUniform1f(programInfo.vars[TextureMapperGLData::GlobalGLData::OpacityVariable], opacity))
    413462
    414463    if (maskTexture && maskTexture->isValid()) {
    415464        const BitmapTextureGL* maskTextureGL = static_cast<const BitmapTextureGL*>(maskTexture);
    416465        GL_CMD(glActiveTexture(GL_TEXTURE1))
    417         GL_CMD(glBindTexture(GL_TEXTURE_2D, maskTextureGL->m_id))
    418         const GLfloat m4mask[] = {maskTextureGL->m_relativeSize.width(), 0, 0, 0,
    419                                          0, maskTextureGL->m_relativeSize.height(), 0, 0,
     466        GL_CMD(glBindTexture(GL_TEXTURE_2D, maskTextureGL->id()))
     467        const GLfloat m4mask[] = {maskTextureGL->relativeSize().width(), 0, 0, 0,
     468                                         0, maskTextureGL->relativeSize().height(), 0, 0,
    420469                                         0, 0, 1, 0,
    421470                                         0, 0, 0, 1};
    422         GL_CMD(glUniformMatrix4fv(programInfo.vars[TextureMapperGLData::ShaderInfo::InMaskMatrixVariable], 1, GL_FALSE, m4mask));
    423         GL_CMD(glUniform1i(programInfo.vars[TextureMapperGLData::ShaderInfo::MaskTextureVariable], 1))
     471        GL_CMD(glUniformMatrix4fv(programInfo.vars[TextureMapperGLData::GlobalGLData::InMaskMatrixVariable], 1, GL_FALSE, m4mask));
     472        GL_CMD(glUniform1i(programInfo.vars[TextureMapperGLData::GlobalGLData::MaskTextureVariable], 1))
    424473        GL_CMD(glActiveTexture(GL_TEXTURE0))
    425474    }
    426475
    427     if (textureGL.m_opaque && opacity > 0.99 && !maskTexture)
     476    if (opaque && opacity > 0.99 && !maskTexture)
    428477        GL_CMD(glDisable(GL_BLEND))
    429478    else {
     
    432481    }
    433482
     483    GL_CMD(glDisable(GL_DEPTH_TEST))
    434484    GL_CMD(glDrawArrays(GL_TRIANGLE_FAN, 0, 4))
     485    GL_CMD(glDisableVertexAttribArray(programInfo.vertexAttrib))
    435486}
    436487
     
    443494{
    444495    BitmapTexture::reset(newSize, opaque);
    445     m_image = 0;
     496    m_imageUID = 0;
    446497    IntSize newTextureSize = nextPowerOfTwo(newSize);
    447498    bool justCreated = false;
     
    479530    m_buffer->endPaint();
    480531    GL_CMD(glBindTexture(GL_TEXTURE_2D, m_id))
    481     GL_CMD(glTexSubImage2D(GL_TEXTURE_2D, 0, m_dirtyRect.x(), m_dirtyRect.y(), m_dirtyRect.width(), m_dirtyRect.height(), GL_RGBA, GL_UNSIGNED_BYTE, m_buffer->data()))
     532    GL_CMD(glTexSubImage2D(GL_TEXTURE_2D, 0, m_dirtyRect.x(), m_dirtyRect.y(), m_dirtyRect.width(), m_dirtyRect.height(), GL_BGRA, GL_UNSIGNED_BYTE, m_buffer->data()))
    482533    m_buffer.clear();
    483534}
     
    485536void BitmapTextureGL::setContentsToImage(Image* image)
    486537{
    487     NativeImagePtr nativeImage = image ? image->nativeImageForCurrentFrame() : 0;
    488     if (!image || !nativeImage) {
    489         if (m_image)
     538    ImageUID uid = image ? uidForImage(image) : 0;
     539    if (!image || !uid) {
     540        if (m_imageUID)
    490541            destroy();
    491542        return;
    492543    }
    493544
    494     if (nativeImage == m_image)
     545    if (uid == m_imageUID)
    495546        return;
    496547    bool found = false;
    497     GLuint newTextureID = m_textureMapper->data().directlyCompositedImages.findOrCreate(nativeImage, found);
     548    GLuint newTextureID = m_textureMapper->data().directlyCompositedImages.findOrCreate(uid, found);
    498549    if (newTextureID != m_id) {
     550        m_imageUID = uid;
    499551        destroy();
    500552        m_id = newTextureID;
    501553        reset(image->size(), false);
    502         m_image = nativeImage;
    503554        if (!found) {
    504555            GraphicsContext context(beginPaint(IntRect(0, 0, m_textureSize.width(), m_textureSize.height())));
     
    509560}
    510561
     562static inline TransformationMatrix createProjectionMatrix(const IntSize& size, bool flip)
     563{
     564    const float near = 9999999;
     565    const float far = -99999;
     566
     567    return TransformationMatrix(2.0 / float(size.width()), 0, 0, 0,
     568                                0, (flip ? -2.0 : 2.0) / float(size.height()), 0, 0,
     569                                0, 0, -2.f / (far - near), 0,
     570                                -1, flip ? 1 : -1, -(far + near) / (far - near), 1);
     571}
     572
     573void BitmapTextureGL::bind()
     574{
     575    int& stencilIndex = TextureMapperGLData::globalGLData.stencilIndex;
     576    if (m_surfaceNeedsReset || !m_fbo) {
     577        if (!m_fbo)
     578            GL_CMD(glGenFramebuffers(1, &m_fbo))
     579        if (!m_rbo)
     580            GL_CMD(glGenRenderbuffers(1, &m_rbo));
     581        GL_CMD(glBindRenderbuffer(GL_RENDERBUFFER, m_rbo))
     582#ifdef TEXMAP_OPENGL_ES_2
     583        GL_CMD(glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, m_textureSize.width(), m_textureSize.height()))
     584#else
     585        GL_CMD(glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_STENCIL, m_textureSize.width(), m_textureSize.height()))
     586#endif
     587        GL_CMD(glBindFramebuffer(GL_FRAMEBUFFER, m_fbo))
     588        GL_CMD(glBindTexture(GL_TEXTURE_2D, 0))
     589        GL_CMD(glBindRenderbuffer(GL_RENDERBUFFER, 0))
     590        GL_CMD(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, id(), 0))
     591        GL_CMD(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_rbo))
     592#if CPU(X86)
     593        GL_CMD(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_rbo));
     594#endif
     595        GL_CMD(glClearColor(0, 0, 0, 0))
     596        GL_CMD(glClearStencil(stencilIndex - 1))
     597        GL_CMD(glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT))
     598        m_surfaceNeedsReset = false;
     599    } else
     600        GL_CMD(glBindFramebuffer(GL_FRAMEBUFFER, m_fbo))
     601
     602    glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
     603    glStencilFunc(stencilIndex > 1 ? GL_GEQUAL : GL_ALWAYS, stencilIndex - 1, stencilIndex - 1);
     604    GL_CMD(glViewport(0, 0, size().width(), size().height()))
     605    m_textureMapper->data().projectionMatrix = createProjectionMatrix(size(), false);
     606    glDisable(GL_SCISSOR_TEST);
     607}
     608
    511609void BitmapTextureGL::destroy()
    512610{
    513     if (m_id && (!m_image || !m_textureMapper->data().directlyCompositedImages.deref(m_image)))
     611    if (m_id && (!m_imageUID || !m_textureMapper->data().directlyCompositedImages.deref(m_imageUID)))
    514612        GL_CMD(glDeleteTextures(1, &m_id))
     613
    515614    if (m_fbo)
    516615        GL_CMD(glDeleteFramebuffers(1, &m_fbo))
     616
     617    if (m_rbo)
     618        GL_CMD(glDeleteRenderbuffers(1, &m_rbo))
    517619
    518620    m_fbo = 0;
     
    532634}
    533635
    534 static inline TransformationMatrix createProjectionMatrix(const IntSize& size, bool flip)
    535 {
    536     return TransformationMatrix(2.0 / float(size.width()), 0, 0, 0,
    537                                 0, (flip ? -2.0 : 2.0) / float(size.height()), 0, 0,
    538                                 0, 0, -0.000001, 0,
    539                                 -1, flip ? 1 : -1, 0, 1);
    540 }
    541 
    542636TextureMapperGL::~TextureMapperGL()
    543637{
    544     makeContextCurrent();
    545638    delete m_data;
    546639}
    547640
    548 bool TextureMapperGL::makeContextCurrent()
    549 {
    550 #if OS(MAC_OS_X)
    551     return aglSetCurrentContext(data().aglContext);
    552 #elif OS(UNIX)
    553     Display* display = XOpenDisplay(0);
    554     if (!display)
    555         return false;
    556     return glXMakeCurrent(display, data().glxDrawable, data().glxContext);
    557 #endif
    558 }
    559 
    560 void TextureMapperGL::obtainCurrentContext()
    561 {
    562 #if OS(MAC_OS_X)
    563     data().aglContext = aglGetCurrentContext();
    564 #elif OS(UNIX)
    565     data().glxDrawable = glXGetCurrentDrawable();
    566     data().glxContext = glXGetCurrentContext();
    567 #endif
    568 }
    569 
    570641void TextureMapperGL::bindSurface(BitmapTexture *surfacePointer)
    571642{
    572643    BitmapTextureGL* surface = static_cast<BitmapTextureGL*>(surfacePointer);
    573644
    574     if (!surface)
     645    if (!surface) {
     646        GL_CMD(glBindFramebuffer(GL_FRAMEBUFFER, 0))
     647        data().projectionMatrix = createProjectionMatrix(viewportSize(), true).multiply(transform());
     648        GL_CMD(glStencilFunc(data().globalGLData.stencilIndex > 1 ? GL_EQUAL : GL_ALWAYS, data().globalGLData.stencilIndex - 1, data().globalGLData.stencilIndex - 1))
     649        GL_CMD(glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP))
     650        GL_CMD(glViewport(0, 0, viewportSize().width(), viewportSize().height()))
    575651        return;
    576 
    577     TransformationMatrix matrix = createProjectionMatrix(surface->size(), false);
    578     matrix.translate(-surface->offset().x(), -surface->offset().y());
    579 
    580     if (surface->m_surfaceNeedsReset || !surface->m_fbo) {
    581         if (!surface->m_fbo)
    582             GL_CMD(glGenFramebuffers(1, &surface->m_fbo))
    583         GL_CMD(glBindFramebuffer(GL_FRAMEBUFFER, surface->m_fbo))
    584         GL_CMD(glBindTexture(GL_TEXTURE_2D, 0))
    585         GL_CMD(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, surface->m_id, 0))
    586         GL_CMD(glClearColor(0, 0, 0, 0))
    587         GL_CMD(glClear(GL_COLOR_BUFFER_BIT))
    588         surface->m_surfaceNeedsReset = false;
    589     } else {
    590         GL_CMD(glBindFramebuffer(GL_FRAMEBUFFER, surface->m_fbo))
    591     }
    592 
    593     GL_CMD(glViewport(0, 0, surface->size().width(), surface->size().height()))
    594     data().projectionMatrix = matrix;
    595 }
    596 
    597 void TextureMapperGL::setClip(const IntRect& rect)
    598 {
    599     GL_CMD(glScissor(rect.x(), rect.y(), rect.width(), rect.height()))
    600     GL_CMD(glEnable(GL_SCISSOR_TEST))
    601 }
    602 
    603 
    604 void TextureMapperGL::paintToTarget(const BitmapTexture& aSurface, const IntSize& surfaceSize, const TransformationMatrix& transform, float opacity, const IntRect& visibleRect)
    605 {
    606     const BitmapTextureGL& surface = static_cast<const BitmapTextureGL&>(aSurface);
    607 
    608     // Create the model-view-projection matrix to display on screen.
    609     TransformationMatrix matrix = createProjectionMatrix(surfaceSize, true).multiply(transform).multiply(
    610                 TransformationMatrix(
    611                         surface.m_actualSize.width(), 0, 0, 0,
    612                         0, surface.m_actualSize.height(), 0, 0,
    613                         0, 0, 1, 0,
    614                         surface.offset().x(), surface.offset().y(), 0, 1)
    615             );
     652    }
     653
     654    surface->bind();
     655}
     656
     657void TextureMapperGL::beginClip(const TransformationMatrix& modelViewMatrix, const FloatRect& targetRect)
     658{
     659    TextureMapperGLData::GlobalGLData::ShaderProgramIndex program = TextureMapperGLData::GlobalGLData::ClipProgram;
     660    const TextureMapperGLData::GlobalGLData::ProgramInfo& programInfo = data().globalGLData.programs[program];
     661    GL_CMD(glUseProgram(programInfo.id))
     662    GL_CMD(glEnableVertexAttribArray(programInfo.vertexAttrib))
     663    const GLfloat unitRect[] = {0, 0, 1, 0, 1, 1, 0, 1};
     664    GL_CMD(glVertexAttribPointer(programInfo.vertexAttrib, 2, GL_FLOAT, GL_FALSE, 0, unitRect))
     665
     666    TransformationMatrix matrix = TransformationMatrix(data().projectionMatrix)
     667            .multiply(modelViewMatrix)
     668            .multiply(TransformationMatrix(targetRect.width(), 0, 0, 0,
     669                0, targetRect.height(), 0, 0,
     670                0, 0, 1, 0,
     671                targetRect.x(), targetRect.y(), 0, 1));
    616672
    617673    const GLfloat m4[] = {
     
    622678    };
    623679
    624     const GLfloat m4src[] = {surface.m_relativeSize.width(), 0, 0, 0,
    625                                      0, surface.m_relativeSize.height(), 0, 0,
    626                                      0, 0, 1, 0,
    627                                      0, 0, 0, 1};
    628 
    629     // We already blended the alpha in; the result is premultiplied.
    630     GL_CMD(glUseProgram(data().shaderInfo.programs[TextureMapperGLData::ShaderInfo::TargetProgram].id))
    631     GL_CMD(glBindFramebuffer(GL_FRAMEBUFFER, 0))
    632     GL_CMD(glViewport(0, 0, surfaceSize.width(), surfaceSize.height()))
    633     GL_CMD(glDisable(GL_STENCIL_TEST))
    634     const TextureMapperGLData::ShaderInfo::ProgramInfo& programInfo = data().shaderInfo.programs[TextureMapperGLData::ShaderInfo::TargetProgram];
    635     GL_CMD(glUniform1f(programInfo.vars[TextureMapperGLData::ShaderInfo::OpacityVariable], opacity))
    636     GL_CMD(glActiveTexture(GL_TEXTURE0))
    637     GL_CMD(glBindTexture(GL_TEXTURE_2D, surface.m_id))
    638     GL_CMD(glUniform1i(programInfo.vars[TextureMapperGLData::ShaderInfo::SourceTextureVariable], 0))
    639     GL_CMD(glEnableVertexAttribArray(gInVertexAttributeIndex))
    640     GL_CMD(glUniformMatrix4fv(programInfo.vars[TextureMapperGLData::ShaderInfo::InMatrixVariable], 1, GL_FALSE, m4))
    641     GL_CMD(glUniformMatrix4fv(programInfo.vars[TextureMapperGLData::ShaderInfo::InSourceMatrixVariable], 1, GL_FALSE, m4src))
    642     GL_CMD(glBindBuffer(GL_ARRAY_BUFFER, 0))
    643     const GLfloat unitRect[] = {0, 0, 1, 0, 1, 1, 0, 1};
    644     GL_CMD(glVertexAttribPointer(gInVertexAttributeIndex, 2, GL_FLOAT, GL_FALSE, 0, unitRect))
    645     GL_CMD(glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA))
    646     GL_CMD(glEnable(GL_BLEND))
    647     setClip(visibleRect);
    648 
     680    int& stencilIndex = data().globalGLData.stencilIndex;
     681
     682    GL_CMD(glUniformMatrix4fv(programInfo.vars[TextureMapperGLData::GlobalGLData::InMatrixVariable], 1, GL_FALSE, m4))
     683    GL_CMD(glEnable(GL_STENCIL_TEST))
     684    GL_CMD(glStencilFunc(GL_NEVER, stencilIndex, stencilIndex))
     685    GL_CMD(glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE))
     686    GL_CMD(glStencilMask(0xff & ~(stencilIndex - 1)))
    649687    GL_CMD(glDrawArrays(GL_TRIANGLE_FAN, 0, 4))
    650     GL_CMD(glDisableVertexAttribArray(0))
    651     GL_CMD(glUseProgram(0))
    652     GL_CMD(glBindBuffer(GL_ARRAY_BUFFER, 0))
    653     data().currentProgram = TextureMapperGLData::ShaderInfo::TargetProgram;
     688    GL_CMD(glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP))
     689    stencilIndex <<= 1;
     690    glStencilFunc(stencilIndex > 1 ? GL_EQUAL : GL_ALWAYS, stencilIndex - 1, stencilIndex - 1);
     691}
     692
     693void TextureMapperGL::endClip()
     694{
     695    data().globalGLData.stencilIndex >>= 1;
     696    glStencilFunc(data().globalGLData.stencilIndex > 1 ? GL_EQUAL : GL_ALWAYS, data().globalGLData.stencilIndex - 1, data().globalGLData.stencilIndex - 1);
    654697}
    655698
     
    657700{
    658701    BitmapTextureGL* texture = new BitmapTextureGL();
    659     texture->m_textureMapper = this;
     702    texture->setTextureMapper(this);
    660703    return adoptRef(texture);
    661704}
  • trunk/Source/WebCore/platform/graphics/opengl/TextureMapperGL.h

    r81230 r86276  
    3131
    3232class TextureMapperGLData;
     33class GraphicsContext;
    3334
    3435// An OpenGL-ES2 implementation of TextureMapper.
     
    3940
    4041    // reimps from TextureMapper
    41     virtual void drawTexture(const BitmapTexture& texture, const IntRect&, const TransformationMatrix& transform, float opacity, const BitmapTexture* maskTexture);
     42    virtual void drawTexture(const BitmapTexture&, const FloatRect&, const TransformationMatrix&, float opacity, const BitmapTexture* maskTexture);
     43    virtual void drawTexture(uint32_t texture, bool opaque, const FloatSize&, const FloatRect&, const TransformationMatrix&, float opacity, const BitmapTexture* maskTexture, bool flip);
    4244    virtual void bindSurface(BitmapTexture* surface);
    43     virtual void setClip(const IntRect&);
    44     virtual void paintToTarget(const BitmapTexture&, const IntSize&, const TransformationMatrix&, float opacity, const IntRect& visibleRect);
    45     virtual bool allowSurfaceForRoot() const { return true; }
     45    virtual void beginClip(const TransformationMatrix&, const FloatRect&);
     46    virtual void endClip();
     47    virtual bool allowSurfaceForRoot() const { return false; }
    4648    virtual PassRefPtr<BitmapTexture> createTexture();
    4749    virtual const char* type() const;
    48     void obtainCurrentContext();
    49     bool makeContextCurrent();
    50     static PassOwnPtr<TextureMapperGL> create()
    51     {
    52         return new TextureMapperGL;
    53     }
     50    static PassOwnPtr<TextureMapperGL> create() { return adoptPtr(new TextureMapperGL); }
     51    void beginPainting();
     52    void endPainting();
     53    void setGraphicsContext(GraphicsContext* context) { m_context = context; }
     54    GraphicsContext* graphicsContext() { return m_context; }
     55    virtual bool isOpenGLBacked() const { return true; }
    5456
    5557private:
     58    void initializeShaders();
    5659    inline TextureMapperGLData& data() { return *m_data; }
    5760    TextureMapperGLData* m_data;
     61    GraphicsContext* m_context;
    5862    friend class BitmapTextureGL;
    5963};
     
    8589}
    8690
     91typedef uint64_t ImageUID;
     92ImageUID uidForImage(Image*);
     93
    8794};
    8895
  • trunk/Source/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp

    r86275 r86276  
    3939#include <wtf/UnusedParam.h>
    4040#include <wtf/text/CString.h>
     41
     42#if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER)
     43#include <opengl/TextureMapperGL.h>
     44#endif
    4145
    4246#if ENABLE(WEBGL)
     
    155159typedef void (APIENTRY* glVertexAttribPointerType) (GLuint, GLint, GLenum, GLboolean, GLsizei, const GLvoid*);
    156160
    157 class GraphicsContext3DInternal : public QGraphicsObject {
     161class GraphicsContext3DInternal
     162#if USE(ACCELERATED_COMPOSITING)
     163#if USE(TEXTURE_MAPPER)
     164        : public TextureMapperPlatformLayer
     165#else
     166        : public QGraphicsObject
     167#endif
     168#endif
     169{
    158170public:
    159171    GraphicsContext3DInternal(GraphicsContext3D::Attributes attrs, HostWindow* hostWindow);
     
    164176    QGLWidget* getViewportGLWidget();
    165177    void reshape(int width, int height);
     178#if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER)
     179    virtual void paintToTextureMapper(TextureMapper*, const FloatRect& target, const TransformationMatrix&, float opacity, BitmapTexture* mask) const;
     180#endif
     181
    166182    void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*);
    167183    QRectF boundingRect() const;
     
    534550}
    535551
     552#if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER)
     553void GraphicsContext3DInternal::paintToTextureMapper(TextureMapper* textureMapper, const FloatRect& targetRect, const TransformationMatrix& matrix, float opacity, BitmapTexture* mask) const
     554{
     555    if (textureMapper->isOpenGLBacked()) {
     556        TextureMapperGL* texmapGL = static_cast<TextureMapperGL*>(textureMapper);
     557        texmapGL->drawTexture(m_texture, !m_attrs.alpha, FloatSize(1, 1), targetRect, matrix, opacity, mask, true /* flip */);
     558        return;
     559    }
     560
     561    GraphicsContext* context = textureMapper->graphicsContext();
     562    QPainter* painter = context->platformContext();
     563    painter->save();
     564    painter->setTransform(matrix);
     565    painter->setOpacity(opacity);
     566
     567    // Alternatively read pixels to a memory buffer.
     568    QImage offscreenImage(m_boundingRect.width(), m_boundingRect.height(), QImage::Format_ARGB32);
     569    quint32* imagePixels = reinterpret_cast<quint32*>(offscreenImage.bits());
     570
     571    m_glWidget->makeCurrent();
     572    bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_canvasFbo);
     573    glReadPixels(/* x */ 0, /* y */ 0, m_boundingRect.width(), m_boundingRect.height(), GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, imagePixels);
     574
     575    bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_currentFbo);
     576
     577    // OpenGL gives us ABGR on 32 bits, and with the origin at the bottom left
     578    // We need RGB32 or ARGB32_PM, with the origin at the top left.
     579    quint32* pixelsSrc = imagePixels;
     580    const int height = static_cast<int>(m_boundingRect.height());
     581    const int width = static_cast<int>(m_boundingRect.width());
     582    const int halfHeight = height / 2;
     583    for (int row = 0; row < halfHeight; ++row) {
     584        const int targetIdx = (height - 1 - row) * width;
     585        quint32* pixelsDst = imagePixels + targetIdx;
     586        for (int column = 0; column < width; ++column) {
     587            quint32 tempPixel = *pixelsSrc;
     588            *pixelsSrc = swapBgrToRgb(*pixelsDst);
     589            *pixelsDst = swapBgrToRgb(tempPixel);
     590            ++pixelsSrc;
     591            ++pixelsDst;
     592        }
     593    }
     594    if (static_cast<int>(height) % 2) {
     595        for (int column = 0; column < width; ++column) {
     596            *pixelsSrc = swapBgrToRgb(*pixelsSrc);
     597            ++pixelsSrc;
     598        }
     599    }
     600
     601    painter->drawImage(targetRect, offscreenImage);
     602    painter->restore();
     603}
     604#endif // USE(ACCELERATED_COMPOSITING)
     605
     606QRectF GraphicsContext3DInternal::boundingRect() const
     607{
     608    return m_boundingRect;
     609}
     610
    536611void GraphicsContext3DInternal::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
    537612{
     
    581656        }
    582657    }
     658
    583659    painter->drawImage(/* x */ 0, /* y */ 0, offscreenImage);
    584 }
    585 
    586 QRectF GraphicsContext3DInternal::boundingRect() const
    587 {
    588     return m_boundingRect;
    589660}
    590661
     
    636707}
    637708
     709#if USE(ACCELERATED_COMPOSITING)
    638710PlatformLayer* GraphicsContext3D::platformLayer() const
    639711{
    640712    return m_internal.get();
    641713}
     714#endif
    642715
    643716void GraphicsContext3D::makeContextCurrent()
  • trunk/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp

    r83836 r86276  
    2323#include "FrameView.h"
    2424#include "GraphicsContext.h"
     25#include "GraphicsLayer.h"
    2526#include "HTMLMediaElement.h"
    2627#include "HTMLVideoElement.h"
     
    5152#include <wtf/text/CString.h>
    5253
    53 #if USE(ACCELERATED_COMPOSITING)
    54 #include "texmap/TextureMapperPlatformLayer.h"
     54#if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER)
     55#include "texmap/TextureMapper.h"
    5556#endif
    5657
     
    604605{
    605606    m_webCorePlayer->repaint();
     607
    606608}
    607609
    608610#if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER)
    609 
    610 class TextureMapperVideoLayerQt : public virtual TextureMapperMediaLayer {
    611 public:
    612     TextureMapperVideoLayerQt(QGraphicsVideoItem* videoItem)
    613         : m_videoItem(videoItem)
    614     {
    615     }
    616 
    617     virtual void setPlatformLayerClient(TextureMapperLayerClient* client)
    618     {
    619         m_client = client;
    620     }
    621 
    622     virtual void paint(GraphicsContext* context)
    623     {
    624         if (!m_videoItem)
    625             return;
    626 
    627         QStyleOptionGraphicsItem opt;
    628         opt.exposedRect = m_videoItem.data()->sceneBoundingRect();
    629         opt.rect = opt.exposedRect.toRect();
    630         m_videoItem.data()->paint(context->platformContext(), &opt);
    631     }
    632 
    633     virtual IntSize size() const
    634     {
    635         return m_videoItem ? IntSize(m_videoItem.data()->size().width(), m_videoItem.data()->size().height()) : IntSize();
    636     }
    637 
    638     QWeakPointer<QGraphicsVideoItem> m_videoItem;
    639     TextureMapperLayerClient* m_client;
    640 };
    641 
    642 
    643 void MediaPlayerPrivateQt::acceleratedRenderingStateChanged()
    644 {
    645     MediaPlayerClient* client = m_webCorePlayer->mediaPlayerClient();
    646     bool composited = client->mediaPlayerRenderingCanBeAccelerated(m_webCorePlayer);
    647     if (composited == m_composited)
    648         return;
    649 
    650     m_composited = composited;
    651     if (composited)
    652         m_platformLayer = new TextureMapperVideoLayerQt(m_videoItem);
    653 }
    654 
    655 PlatformLayer* MediaPlayerPrivateQt::platformLayer() const
    656 {
    657     return m_composited ? m_platformLayer.get() : 0;
     611void MediaPlayerPrivateQt::paintToTextureMapper(TextureMapper* textureMapper, const FloatRect& targetRect, const TransformationMatrix& matrix, float opacity, BitmapTexture*) const
     612{
     613        GraphicsContext* context = textureMapper->graphicsContext();
     614        QPainter* painter = context->platformContext();
     615        painter->save();
     616        painter->setTransform(matrix);
     617        painter->setOpacity(opacity);
     618        m_videoScene->render(painter, QRectF(targetRect), m_videoItem->sceneBoundingRect());
     619        painter->restore();
    658620}
    659621#endif
  • trunk/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.h

    r82199 r86276  
    3232QT_END_NAMESPACE
    3333
     34#if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER)
     35#include "TextureMapper.h"
     36#endif
     37
    3438namespace WebCore {
    3539
    36 class TextureMapperMediaLayer;
    37 
    38 class MediaPlayerPrivateQt : public QObject, public MediaPlayerPrivateInterface {
     40class MediaPlayerPrivateQt : public QObject, public MediaPlayerPrivateInterface
     41#if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER)
     42        , public TextureMapperPlatformLayer
     43#endif
     44{
    3945
    4046    Q_OBJECT
     
    100106    virtual bool supportsAcceleratedRendering() const { return true; }
    101107    // called when the rendering system flips the into or out of accelerated rendering mode.
    102     virtual void acceleratedRenderingStateChanged();
    103     // returns an object that can be directly composited via GraphicsLayerQt (essentially a QGraphicsItem*)
    104     virtual PlatformLayer* platformLayer() const;
     108    virtual void acceleratedRenderingStateChanged() { }
     109    // Const-casting here is safe, since all of TextureMapperPlatformLayer's functions are const.g
     110    virtual PlatformLayer* platformLayer() const { return const_cast<MediaPlayerPrivateQt*>(this); }
     111    virtual void paintToTextureMapper(TextureMapper*, const FloatRect& targetRect, const TransformationMatrix&, float opacity, BitmapTexture* mask) const;
    105112#else
    106113    virtual bool supportsAcceleratedRendering() const { return false; }
     
    139146    QGraphicsVideoItem* m_videoItem;
    140147    QGraphicsScene* m_videoScene;
    141 #if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER)
    142     OwnPtr<TextureMapperMediaLayer> m_platformLayer;
    143 #endif
    144148
    145149    mutable MediaPlayer::NetworkState m_networkState;
  • trunk/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.cpp

    r85839 r86276  
    2929    , m_node(adoptPtr(new TextureMapperNode()))
    3030    , m_changeMask(0)
     31    , m_animationStartedTimer(this, &GraphicsLayerTextureMapper::animationStartedTimerFired)
    3132{
    3233}
     
    7172    if (m_pendingContent.needsDisplay)
    7273        return;
    73     m_pendingContent.needsDisplayRect.unite(IntRect(rect));
     74    m_pendingContent.needsDisplayRect.unite(rect);
    7475    notifyChange(TextureMapperNode::DisplayChange);
    7576}
     
    320321}
    321322
    322 /* \reimp (GraphicsLayer.h)
    323 */
    324 void GraphicsLayerTextureMapper::setContentsBackgroundColor(const Color& color)
    325 {
    326     notifyChange(TextureMapperNode::ContentChange);
    327     m_pendingContent.contentType = TextureMapperNode::ColorContentType;
    328     m_pendingContent.backgroundColor = color;
    329     GraphicsLayer::setContentsBackgroundColor(color);
    330 }
    331 
    332 
    333 void GraphicsLayerTextureMapper::setContentsToMedia(PlatformLayer* media)
     323void GraphicsLayerTextureMapper::setContentsToMedia(TextureMapperPlatformLayer* media)
    334324{
    335325    GraphicsLayer::setContentsToMedia(media);
    336326    notifyChange(TextureMapperNode::ContentChange);
    337327    m_pendingContent.contentType = media ? TextureMapperNode::MediaContentType : TextureMapperNode::HTMLContentType;
    338     if (media)
    339         m_pendingContent.media = static_cast<TextureMapperMediaLayer*>(media);
    340     else
    341         m_pendingContent.media = 0;
    342 }
    343 
    344 /* \reimp (GraphicsLayer.h)
    345 */
    346 void GraphicsLayerTextureMapper::setContentsOrientation(CompositingCoordinatesOrientation orientation)
    347 {
    348     if (contentsOrientation() == orientation)
    349         return;
    350     notifyChange(TextureMapperNode::ContentsOrientationChange);
    351     GraphicsLayer::setContentsOrientation(orientation);
     328    m_pendingContent.media = media;
    352329}
    353330
     
    356333void GraphicsLayerTextureMapper::syncCompositingStateForThisLayerOnly()
    357334{
    358     m_node->syncCompositingState(this, false);
     335    m_node->syncCompositingState(this);
    359336}
    360337
     
    363340void GraphicsLayerTextureMapper::syncCompositingState()
    364341{
    365     m_node->syncCompositingState(this, true);
     342    m_node->syncCompositingState(this, TextureMapperNode::TraverseDescendants);
    366343}
    367344
     
    370347PlatformLayer* GraphicsLayerTextureMapper::platformLayer() const
    371348{
    372     return m_node.get();
     349    return const_cast<TextureMapperPlatformLayer*>(node()->media());
    373350}
    374351
     
    378355}
    379356
    380 }
     357bool GraphicsLayerTextureMapper::addAnimation(const KeyframeValueList& valueList, const IntSize& boxSize, const Animation* anim, const String& keyframesName, double timeOffset)
     358{
     359    ASSERT(!keyframesName.isEmpty());
     360
     361    if (!anim || anim->isEmptyOrZeroDuration() || valueList.size() < 2 || (valueList.property() != AnimatedPropertyWebkitTransform && valueList.property() != AnimatedPropertyOpacity))
     362        return false;
     363
     364    for (size_t i = 0; i < m_animations.size(); ++i) {
     365        // The same animation name can be used for two animations with different properties.
     366        if (m_animations[i]->name != keyframesName || m_animations[i]->keyframes.property() != valueList.property())
     367            continue;
     368
     369        // We already have a copy of this animation, that means that we're resuming it rather than adding it.
     370        RefPtr<TextureMapperAnimation>& animation = m_animations[i];
     371        animation->animation = Animation::create(anim);
     372        animation->paused = false;
     373        animation->startTime = WTF::currentTime() - timeOffset;
     374        notifyChange(TextureMapperNode::AnimationChange);
     375        m_animationStartedTimer.startOneShot(0);
     376        return true;
     377    }
     378
     379    RefPtr<TextureMapperAnimation> animation = TextureMapperAnimation::create(valueList);
     380    animation->boxSize = boxSize;
     381    animation->name = keyframesName;
     382    animation->animation = Animation::create(anim);
     383    animation->paused = false;
     384    animation->startTime = WTF::currentTime() - timeOffset;
     385
     386    if (valueList.property() == AnimatedPropertyWebkitTransform) {
     387        bool hasBigRotation; // Not used, but required as a pointer parameter for the function.
     388        fetchTransformOperationList(valueList, animation->functionList, animation->listsMatch, hasBigRotation);
     389    }
     390
     391    m_animations.append(animation);
     392    notifyChange(TextureMapperNode::AnimationChange);
     393    m_animationStartedTimer.startOneShot(0);
     394
     395    return true;
     396}
     397
     398void GraphicsLayerTextureMapper::pauseAnimation(const String& animationName, double timeOffset)
     399{
     400    for (size_t i = 0; i < m_animations.size(); ++i) {
     401        if (m_animations[i]->name != animationName)
     402            continue;
     403        m_animations[i]->paused = true;
     404        notifyChange(TextureMapperNode::AnimationChange);
     405    }
     406}
     407
     408void GraphicsLayerTextureMapper::removeAnimation(const String& animationName)
     409{
     410    for (int i = m_animations.size() - 1; i >= 0; --i) {
     411        // The same animation name can be used for two animations with different properties. We should remove both.
     412        if (m_animations[i]->name != animationName)
     413            continue;
     414        m_animations.remove(i);
     415        notifyChange(TextureMapperNode::AnimationChange);
     416    }
     417}
     418
     419void GraphicsLayerTextureMapper::animationStartedTimerFired(Timer<GraphicsLayerTextureMapper>*)
     420{
     421    client()->notifyAnimationStarted(this, /* DOM time */ WTF::currentTime());
     422}
     423
     424}
  • trunk/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.h

    r82044 r86276  
    4646    // reimps from GraphicsLayer.h
    4747    virtual void setNeedsDisplay();
     48    virtual void setContentsNeedsDisplay() { setNeedsDisplay(); };
    4849    virtual void setNeedsDisplayInRect(const FloatRect&);
    4950    virtual void setParent(GraphicsLayer* layer);
     
    7374    virtual void setContentsToImage(Image*);
    7475    virtual void setContentsToMedia(PlatformLayer*);
    75     virtual void setContentsBackgroundColor(const Color&);
    76 #if ENABLE(WEBGL)
    77     virtual void setContentsToGraphicsContext3D(const GraphicsContext3D*);
    78     virtual void setGraphicsContext3DNeedsDisplay();
    79 #endif
    80     virtual void setContentsOrientation(CompositingCoordinatesOrientation orientation);
     76    virtual void setContentsToCanvas(PlatformLayer* canvas) { setContentsToMedia(canvas); }
    8177    virtual void syncCompositingState();
    8278    virtual void syncCompositingStateForThisLayerOnly();
    8379    virtual void setName(const String& name);
    8480    virtual PlatformLayer* platformLayer() const;
    85 
    86     virtual bool addAnimation(const KeyframeValueList&, const IntSize& /*boxSize*/, const Animation*, const String& /*keyframesName*/, double /*timeOffset*/) { return false; }
    8781
    8882    void notifyChange(TextureMapperNode::ChangeMask changeMask);
     
    9185    void didSynchronize();
    9286
     87    virtual bool addAnimation(const KeyframeValueList&, const IntSize&, const Animation*, const String&, double);
     88    virtual void pauseAnimation(const String&, double);
     89    virtual void removeAnimation(const String&);
     90
     91    TextureMapperNode* node() const { return m_node.get(); }
     92
    9393private:
    9494    OwnPtr<TextureMapperNode> m_node;
     
    9696    int m_changeMask;
    9797    TextureMapperNode::ContentData m_pendingContent;
     98    Vector<RefPtr<TextureMapperAnimation> > m_animations;
     99    void animationStartedTimerFired(Timer<GraphicsLayerTextureMapper>*);
     100    Timer<GraphicsLayerTextureMapper> m_animationStartedTimer;
    98101};
    99102
  • trunk/Source/WebCore/platform/graphics/texmap/TextureMapperNode.cpp

    r76537 r86276  
    2121#include "TextureMapperNode.h"
    2222
     23#if USE(ACCELERATED_COMPOSITING)
     24
    2325#include "GraphicsLayerTextureMapper.h"
    2426
     27namespace {
     28    static const float gTileDimension = 1024.0;
     29}
     30
    2531namespace WebCore {
    2632
    27 class TextureMapperCache {
     33class TextureMapperSurfaceManager {
    2834public:
    29     void mark(BitmapTexture* texture);
    30 
    31     class Entry {
    32     public:
    33         RefPtr<BitmapTexture> texture;
    34         Entry() : previousCost(0) { }
    35         inline int computeCost() const
    36         {
    37             if (!texture || !texture->isValid() || texture->isPacked())
    38                 return 0;
    39             const IntSize textureSize = texture->size();
    40             // An image's cost in bytes is width * height * bytes per pixel (4).
    41             return textureSize.width() * textureSize.height() * 4;
    42         }
    43         Entry(BitmapTexture* newTexture)
    44             : texture(newTexture)
    45         {
    46         }
    47         bool operator==(const Entry& other) const { return texture == other.texture; }
    48         int previousCost;
    49     };
    50 
    51     TextureMapperCache()
    52         : m_totalCost(0)
     35    TextureMapper* textureMapper;
     36    Vector<RefPtr<BitmapTexture> > surfaces;
     37    IntSize viewportSize;
     38
     39    PassRefPtr<BitmapTexture> getIntermediateSurface()
    5340    {
    54     }
    55 
    56     void purge();
    57     Vector<Entry> m_data;
    58     int m_totalCost;
    59 #ifndef TEXMAP_TEXTURE_CACHE_KBS
    60 #define TEXMAP_TEXTURE_CACHE_KBS 24 * 1024
    61 #endif
    62     static const int MaxCost = TEXMAP_TEXTURE_CACHE_KBS * 1024;
    63     static const int PurgeAmount = MaxCost / 4;
     41        IntSize newViewportSize = textureMapper->viewportSize();
     42        if (newViewportSize != viewportSize) {
     43            viewportSize = newViewportSize;
     44            surfaces.clear();
     45        }
     46        if (surfaces.isEmpty()) {
     47            RefPtr<BitmapTexture> newSurface = textureMapper->createTexture();
     48            newSurface->reset(viewportSize, false);
     49            return newSurface.get();
     50        }
     51        RefPtr<BitmapTexture> surface = surfaces.last();
     52        surface->reset(viewportSize, false);
     53        surfaces.removeLast();
     54        surface->lock();
     55        return surface.get();
     56    }
     57
     58    void releaseIntermediateSurface(BitmapTexture* surface)
     59    {
     60        if (!surface)
     61            return;
     62        surfaces.append(surface);
     63        surface->unlock();
     64    }
    6465};
    6566
    66 
    67 void TextureMapperCache::purge()
    68 {
    69     const int size = m_data.size();
    70 
    71     if (m_totalCost <= TextureMapperCache::MaxCost)
    72         return;
    73 
    74     // Ensure that we have the right count. It might be inaccurate if content changed size.
    75     // We only do this when we're actually ready to purge.
    76     m_totalCost = 0;
    77     for (int i = 0; i < size; ++i)
    78         m_totalCost += m_data[i].computeCost();
    79 
    80     for (int i = size-1; i >= 0 && m_totalCost > TextureMapperCache::MaxCost - TextureMapperCache::PurgeAmount; --i) {
    81         Entry& entry = m_data[i];
    82         if (entry.texture->isLocked() || !entry.texture->isValid() || entry.texture->isPacked())
    83             continue;
    84         m_totalCost -= entry.previousCost;
    85         entry.texture->pack();
    86         m_data.remove(i);
    87     }
    88 }
    89 
    90 void TextureMapperCache::mark(BitmapTexture* texture)
    91 {
    92     if (!texture || !texture->isValid())
    93         return;
    94 
    95     Entry entry(texture);
    96     size_t index = m_data.find(entry);
    97     if (!index)
    98         return;
    99 
    100     int previousCost = 0;
    101 
    102     if (index < m_data.size()) {
    103         previousCost = m_data[index].previousCost;
    104         m_data.remove(index);
    105     }
    106     const int cost = entry.computeCost();
    107     m_totalCost -= previousCost;
    108     m_totalCost += (entry.previousCost = cost);
    109     m_data.prepend(entry);
    110 }
    111 
    112 class TextureMapperCacheLock {
    113 public:
    114     TextureMapperCacheLock(BitmapTexture* texture) : m_texture(texture)
    115     {
    116         if (m_texture)
    117             m_texture->lock();
    118     }
    119     ~TextureMapperCacheLock()
    120     {
    121         if (m_texture)
    122             m_texture->unlock();
    123     }
    124 
    125 private:
    126     RefPtr<BitmapTexture> m_texture;
    127 };
    128 
    129 
    130 TextureMapperCache* TextureMapperNode::cache()
    131 {
    132     TextureMapperNode* root = rootLayer();
    133     if (!root)
    134         return 0;
    135     if (!root->m_cache)
    136         root->m_cache = new TextureMapperCache;
    137     return root->m_cache;
    138 }
    139 
    140 void TextureMapperNode::setNeedsDisplayInRect(IntRect rect)
    141 {
    142     if (m_platformClient) {
    143         if (m_state.hasSurfaceDescendants) {
    144             m_platformClient->setNeedsDisplay();
    145             return;
    146         }
    147         rect.intersect(IntRect(0, 0, m_size.width(), m_size.height()));
    148         if (rect.isEmpty())
    149             return;
    150         m_platformClient->setNeedsDisplayInRect(rect);
    151         return;
    152     }
    153 
    154     if (!m_parent)
    155         return;
    156 
    157     m_parent->setNeedsDisplayInRect(rect);
    158 }
    159 
    160 void TextureMapperNode::setNeedsDisplay()
    161 {
    162     if (m_effectTarget)
    163         m_effectTarget->setNeedsDisplay();
    164     if (m_transforms.targetBoundingRect.isEmpty())
    165         return;
    166     if (m_state.drawsContent || m_currentContent.contentType != HTMLContentType)
    167         setNeedsDisplayInRect(m_transforms.targetBoundingRect);
    168 }
    169 
    170 void TextureMapperNode::setPlatformLayerClient(TextureMapperLayerClient* client)
    171 {
    172     m_platformClient = client;
    173 }
    174 
    175 int TextureMapperNode::compareGraphicsLayersZValue(const void* a, const void* b)
    176 {
    177     typedef const TextureMapperNode* NodePtr;
    178     const NodePtr* nodeA = static_cast<const NodePtr*>(a);
    179     const NodePtr* nodeB = static_cast<const NodePtr*>(b);
    180     return int(((*nodeA)->m_transforms.centerZ - (*nodeB)->m_transforms.centerZ) * 1000);
    181 }
    182 
    183 void TextureMapperNode::sortByZOrder(Vector<TextureMapperNode* >& array, int first, int last)
    184 {
    185     qsort(array.data(), array.size(), sizeof(TextureMapperNode*), TextureMapperNode::compareGraphicsLayersZValue);
    186 }
    187 
    188 bool TextureMapperNode::hasSurfaceDescendants() const
    189 {
    190     if (m_layerType == ClipLayer || m_layerType == TransparencyLayer || m_state.replicaLayer)
    191         return true;
    192 
    193     const int size = m_children.size();
    194     for (int i = 0; i < size; ++i) {
    195         if (TextureMapperNode* child = m_children[i]) {
    196             if (child->hasSurfaceDescendants())
    197                 return true;
    198         }
    199     }
    200     return false;
    201 }
    202 
    203 int TextureMapperNode::countDescendantsWithContent() const
    204 {
    205     if (!m_state.visible || m_state.opacity < 0.001)
    206         return 0;
    207 
    208     int descendantsWithContent = (m_state.drawsContent || m_currentContent.contentType != HTMLContentType) ? 1 : 0;
    209 
    210     const int size = m_children.size();
    211     for (int i = 0; i < size; ++i) {
    212         if (TextureMapperNode* child = m_children[i])
    213             descendantsWithContent += child->countDescendantsWithContent();
    214     }
    215 
    216     return descendantsWithContent;
    217 }
    218 
    219 TextureMapperNode* TextureMapperNode::toTextureMapperNode(GraphicsLayer* layer)
    220 {
    221     return layer ? static_cast<TextureMapperNode*>(layer->platformLayer()) : 0;
    222 }
    223 
    224 void TextureMapperNode::computeLayerType()
    225 {
    226     const bool selfHasContent = m_state.drawsContent || (m_currentContent.contentType != HTMLContentType);
    227     const bool hasDescendantsWithContent = m_state.descendantsWithContent - (selfHasContent ? 1 : 0);
    228     const bool hasTransparency = m_state.opacity < 0.99 || m_state.maskLayer;
    229     const bool hasReplica = m_state.replicaLayer;
    230 
    231     //  DefaultLayer: draws itself and its children directly to the current framebuffer.
    232     //                any layer that doesn't conform to the other rules is a DefaultLayer.
    233     m_layerType = DefaultLayer;
    234 
    235     //  RootLayer: the top level. Draws to a framebuffer, and the target texture draws into the viewport.
    236     //            only one layer is the root layer.
    237     if (!m_parent && !m_effectTarget) {
    238         m_layerType = RootLayer;
    239         return;
    240     }
    241 
    242     // A layer with no contents is always a default layer.
    243     if (!m_state.descendantsWithContent)
    244         return;
    245 
    246     //  ClipLayer: creates a new framebuffer, the size of the layer, and then paints it to the enclosing BitmapTexture with the layer's transform/opacity.
    247     //              A clip layer is a layer that masks to bounds, doesn't preserve 3D, has children, and has a transparency/mask or a non-rectangular transform.
    248     if (hasDescendantsWithContent && m_state.maskLayer) {
    249         m_layerType = ClipLayer;
    250         return;
    251     }
    252 
    253     //  ScissorLayer: draws to the current framebuffer, and applies an extra scissor before drawing its children.
    254     //                A scissor layer is a layer with children that masks to bounds, is not a transparency layer, and has a rectangular clip.
    255     if (m_state.masksToBounds && hasDescendantsWithContent) {
    256         if (hasTransparency || !m_state.transform.isIdentityOrTranslation() || m_parent->m_state.preserves3D)
    257             m_layerType = ClipLayer;
    258         else
    259             m_layerType = ScissorLayer;
    260         return;
    261     }
    262 
    263     //  TransparencyLayer: creates a new framebuffer idetical in size to the current framebuffer. Then draws the fb's texture to the current framebuffer with identity transform.
    264     //                     Used for layers with children and transparency/mask that preserve 3D or don't mask to bounds.
    265     if ((hasReplica && hasDescendantsWithContent) || (hasReplica && hasTransparency) || (hasTransparency && m_state.descendantsWithContent > 1))
    266         m_layerType = TransparencyLayer;
    267 }
    268 
    269 void TextureMapperNode::initializeTextureMapper(TextureMapper* textureMapper)
    270 {
    271     if (m_texture)
    272         return;
    273     m_surface = textureMapper->createTexture();
    274     m_replicaSurface = textureMapper->createTexture();
    275     m_texture = textureMapper->createTexture();
    276     cache()->mark(m_texture.get());
    277 }
    278 
    279 TextureMapperNode::TextureMapperNode()
    280     : m_layerType(DefaultLayer)
    281     , m_surface(0)
    282     , m_parent(0)
    283     , m_effectTarget(0)
    284     , m_platformClient(0)
    285     , m_cache(0)
    286 {
     67TextureMapperNode* toTextureMapperNode(GraphicsLayer* layer)
     68{
     69    return layer ? toGraphicsLayerTextureMapper(layer)->node() : 0;
    28770}
    28871
     
    29679}
    29780
    298 void TextureMapperNode::invalidateTransform()
    299 {
    300     m_transforms.dirty = true;
    301     if (m_layerType != ClipLayer)
    302         m_state.dirty = true;
    303     if (m_state.replicaLayer)
    304         m_state.replicaLayer->invalidateTransform();
    305     const int size = m_children.size();
    306     for (int i = 0; i < size; ++i) {
    307         if (TextureMapperNode* layer = m_children[i])
    308             layer->invalidateTransform();
    309     }
    310 }
    311 
    312 void TextureMapperNode::computeLocalTransform()
    313 {
    314     if (!m_transforms.localDirty)
    315         return;
    316     const float originX = m_state.anchorPoint.x() * m_size.width();
    317     const float originY = m_state.anchorPoint.y() * m_size.height();
    318     m_transforms.local =
    319         TransformationMatrix()
    320         .translate3d(originX + m_state.pos.x(), originY + m_state.pos.y(), m_state.anchorPoint.z())
    321         .multiply(m_state.transform)
    322         .translate3d(-originX, -originY, -m_state.anchorPoint.z());
    323     m_transforms.localDirty = false;
    324 }
    325 
    326 void TextureMapperNode::flattenTo2DSpaceIfNecessary()
    327 {
    328     if (m_state.preserves3D)
    329         return;
    330 
    331     m_transforms.forDescendants.setM13(0);
    332     m_transforms.forDescendants.setM23(0);
    333     m_transforms.forDescendants.setM31(0);
    334     m_transforms.forDescendants.setM32(0);
    335     m_transforms.forDescendants.setM33(1);
    336     m_transforms.forDescendants.setM34(0);
    337     m_transforms.forDescendants.setM43(0);
    338 }
    339 
    340 IntSize TextureMapperNode::nearestSurfaceSize() const
    341 {
    342     if (m_layerType == ClipLayer || m_layerType == RootLayer)
    343         return m_surface && !m_surface->size().isEmpty() ? m_surface->size() : m_size;
    344     return m_parent->nearestSurfaceSize();
    345 }
    346 
    347 void TextureMapperNode::computeReplicaTransform()
    348 {
    349     if (!m_state.replicaLayer)
    350         return;
    351 
    352     m_nearestSurfaceSize = nearestSurfaceSize();
    353 
    354     if (m_layerType != TransparencyLayer) {
    355         m_transforms.replica = TransformationMatrix(m_transforms.target).multiply(m_state.replicaLayer->m_transforms.local);
    356         return;
    357     }
    358 
    359     const float originX = m_transforms.target.m41();
    360     const float originY = m_transforms.target.m42();
    361     m_transforms.replica =
    362             TransformationMatrix()
    363                 .translate(originX, originY)
    364                 .multiply(m_state.replicaLayer->m_transforms.local)
    365                 .translate(-originX, -originY);
    366 }
    367 
    368 void TextureMapperNode::computeTransformations()
    369 {
    370     if (!m_transforms.dirty)
    371         return;
    372 
    373     m_transforms.dirty = false;
    374     if ((m_size.isEmpty() && m_state.masksToBounds))
    375         return;
    376 
    377     TextureMapperNode* parent = m_parent;
    378     computeLocalTransform();
    379 
    380     m_transforms.target = TransformationMatrix(parent ? parent->m_transforms.forDescendants : TransformationMatrix()).multiply(m_transforms.local);
    381     m_transforms.forDescendants = (m_layerType == ClipLayer ? TransformationMatrix() : m_transforms.target);
    382 
    383     if (m_effectTarget)
    384         return;
    385 
    386     m_transforms.targetBoundingRect = IntRect(m_transforms.target.mapRect(entireRect()));
    387     if (m_state.replicaLayer)
    388         m_state.replicaLayer->computeTransformations();
    389 
    390     flattenTo2DSpaceIfNecessary();
    391 
    392     if (!m_state.backfaceVisibility && m_transforms.target.inverse().m33() < 0) {
    393         m_state.visible = false;
    394         return;
    395     }
    396     m_state.visible = true;
    397 
    398     if (parent && parent->m_state.preserves3D)
    399         m_transforms.centerZ = m_transforms.target.mapPoint(FloatPoint3D(m_size.width() / 2, m_size.height() / 2, 0)).z();
    400 
    401     if (!m_children.size())
    402         return;
    403 
    404     if (m_state.childrenTransform.isIdentity())
     81void TextureMapperNode::setTransform(const TransformationMatrix& matrix)
     82{
     83    if (m_transforms.base == matrix)
     84        return;
     85
     86    m_transforms.base = matrix;
     87}
     88
     89void TextureMapperNode::computePerspectiveTransformIfNeeded()
     90{
     91    if (m_children.isEmpty() || m_state.childrenTransform.isIdentity())
    40592        return;
    40693
    40794    const FloatPoint centerPoint = FloatPoint(m_size.width() / 2, m_size.height() / 2);
    408     if (m_transforms.perspectiveDirty)
    409         m_transforms.perspective = TransformationMatrix()
     95    m_transforms.perspective = TransformationMatrix()
    41096            .translate(centerPoint.x(), centerPoint.y())
    41197            .multiply(m_state.childrenTransform)
    41298            .translate(-centerPoint.x(), -centerPoint.y());
    413     m_transforms.perspectiveDirty = false;
     99}
     100
     101int TextureMapperNode::countDescendantsWithContent() const
     102{
     103    if (!m_state.visible || m_opacity < 0.01 || (!m_size.width() && !m_size.height() && m_state.masksToBounds))
     104        return 0;
     105    int count = (m_size.width() && m_size.height() && (m_state.drawsContent || m_currentContent.contentType != HTMLContentType)) ? 1 : 0;
     106    for (size_t i = 0; i < m_children.size(); ++i)
     107        count += m_children[i]->countDescendantsWithContent();
     108
     109    return count;
     110}
     111
     112void TextureMapperNode::computeOverlapsIfNeeded()
     113{
     114    m_state.mightHaveOverlaps = countDescendantsWithContent() > 1;
     115}
     116
     117void TextureMapperNode::computeReplicaTransformIfNeeded()
     118{
     119    if (!m_state.replicaLayer)
     120        return;
     121
     122    m_transforms.replica =
     123        TransformationMatrix(m_transforms.target)
     124            .multiply(m_state.replicaLayer->m_transforms.local)
     125            .multiply(TransformationMatrix(m_transforms.target).inverse());
     126}
     127
     128void TextureMapperNode::computeLocalTransformIfNeeded()
     129{
     130    float originX = m_state.anchorPoint.x() * m_size.width();
     131    float originY = m_state.anchorPoint.y() * m_size.height();
     132    m_transforms.local =
     133        TransformationMatrix()
     134        .translate3d(originX + m_state.pos.x(), originY + m_state.pos.y(), m_state.anchorPoint.z() )
     135        .multiply(m_transforms.base)
     136        .translate3d(-originX, -originY, -m_state.anchorPoint.z());
     137}
     138
     139bool TextureMapperNode::needsToComputeBoundingRect() const
     140{
     141    if (m_size.width() > gTileDimension || m_size.height() > gTileDimension)
     142        return true;
     143    if (!m_state.masksToBounds)
     144        return false;
     145
     146    for (size_t i = 0; i < m_children.size(); ++i)
     147        if (m_children[i]->needsToComputeBoundingRect())
     148            return true;
     149
     150    return false;
     151}
     152
     153void TextureMapperNode::computeAllTransforms()
     154{
     155    if (m_size.isEmpty() && m_state.masksToBounds)
     156        return;
     157
     158    computeLocalTransformIfNeeded();
     159    computeReplicaTransformIfNeeded();
     160    computePerspectiveTransformIfNeeded();
     161
     162    m_transforms.target = TransformationMatrix(m_parent ? m_parent->m_transforms.forDescendants : TransformationMatrix()).multiply(m_transforms.local);
     163    m_transforms.targetBoundingRect = FloatRect(m_transforms.target.mapRect(targetRect()));
     164
     165    m_state.visible = m_state.backfaceVisibility || m_transforms.target.inverse().m33() >= 0;
     166    if (!m_state.visible)
     167        return;
     168
     169    // This transform is only applied if using a two-pass for the replica, because the transform needs to be adjusted to the size of the intermediate surface, insteaf of the size of the content layer.
     170    if (m_parent && m_parent->m_state.preserves3D)
     171        m_transforms.centerZ = m_transforms.target.mapPoint(FloatPoint3D(m_size.width() / 2, m_size.height() / 2, 0)).z();
     172
     173    if (!m_children.size())
     174        return;
     175
     176    m_transforms.forDescendants = m_transforms.target;
     177
     178    if (!m_state.preserves3D) {
     179        m_transforms.forDescendants = TransformationMatrix(
     180                    m_transforms.forDescendants.m11(), m_transforms.forDescendants.m12(), 0, m_transforms.forDescendants.m14(),
     181                    m_transforms.forDescendants.m21(), m_transforms.forDescendants.m22(), 0, m_transforms.forDescendants.m24(),
     182                    0, 0, 1, 0,
     183                    m_transforms.forDescendants.m41(), m_transforms.forDescendants.m42(), 0, m_transforms.forDescendants.m44());
     184    }
     185
    414186    m_transforms.forDescendants.multiply(m_transforms.perspective);
    415187}
    416188
    417 void TextureMapperNode::uploadTextureFromContent(TextureMapper* textureMapper, const IntRect& visibleRect, GraphicsLayer* layer)
    418 {
    419     if (m_size.isEmpty() || !layer) {
    420         m_texture->destroy();
    421         return;
    422     }
    423 
    424     if (m_currentContent.contentType == DirectImageContentType) {
    425         if (m_currentContent.image)
    426             m_texture->setContentsToImage(m_currentContent.image.get());
    427         return;
    428     }
    429 
    430     if (m_currentContent.contentType == MediaContentType) {
    431         if (!m_currentContent.media)
    432             return;
    433         m_texture->reset(m_size, true);
    434         PlatformGraphicsContext* platformContext = m_texture->beginPaintMedia();
    435         GraphicsContext context(platformContext);
    436         m_currentContent.media->paint(&context);
    437         m_texture->endPaint();
    438         return;
    439     }
    440 
    441     const bool needsReset = (m_texture->contentSize() != m_size) || !m_texture->isValid();
    442     if ((m_currentContent.contentType != HTMLContentType)
    443         || (!m_currentContent.needsDisplay && m_currentContent.needsDisplayRect.isEmpty() && !needsReset))
    444         return;
    445 
    446     IntRect dirtyRect = IntRect(0, 0, m_size.width(), m_size.height());
    447     if (!needsReset && !m_currentContent.needsDisplay)
    448         dirtyRect.intersect(m_currentContent.needsDisplayRect);
    449 
    450     if (needsReset)
    451         m_texture->reset(m_size, m_state.contentsOpaque);
    452 
    453     {
    454         GraphicsContext context(m_texture->beginPaint(dirtyRect));
    455         if (textureMapper) {
     189void TextureMapperNode::computeBoundingRectFromRootIfNeeded()
     190{
     191    if (!needsToComputeBoundingRect())
     192        return;
     193    if (!m_parent) {
     194        m_transforms.boundingRectFromRoot = m_transforms.boundingRectFromRootForDescendants = IntRect(0, 0, -1, -1);
     195        return;
     196    }
     197
     198    const FloatRect targetRectInRootCoordinates = m_transforms.target.mapRect(targetRect());
     199
     200    const FloatRect parentBoundingRect = m_parent->m_transforms.boundingRectFromRootForDescendants;
     201    if (parentBoundingRect.width() < 0)
     202        m_transforms.boundingRectFromRoot = targetRectInRootCoordinates;
     203    else {
     204        m_transforms.boundingRectFromRootForDescendants = m_transforms.boundingRectFromRoot = parentBoundingRect;
     205        m_transforms.boundingRectFromRoot.intersect(targetRectInRootCoordinates);
     206    }
     207    if (m_state.masksToBounds)
     208        m_transforms.boundingRectFromRootForDescendants.intersect(m_transforms.boundingRectFromRoot);
     209}
     210
     211void TextureMapperNode::computeTiles()
     212{
     213    if (m_currentContent.contentType == HTMLContentType && !m_state.drawsContent) {
     214        m_tiles.clear();
     215        return;
     216    }
     217    Vector<FloatRect> tilesToAdd;
     218    Vector<int> tilesToRemove;
     219    const int TileEraseThreshold = 6;
     220    FloatSize size = contentSize();
     221    FloatRect contentRect(0, 0, size.width() * m_state.contentScale, size.height() * m_state.contentScale);
     222
     223    for (float y = 0; y < contentRect.height(); y += gTileDimension) {
     224        for (float x = 0; x < contentRect.width(); x += gTileDimension) {
     225            FloatRect tileRect(x, y, gTileDimension, gTileDimension);
     226            tileRect.intersect(contentRect);
     227            FloatRect tileRectInRootCoordinates = tileRect;
     228            tileRectInRootCoordinates.scale(1.0 / m_state.contentScale);
     229            tileRectInRootCoordinates = m_transforms.target.mapRect(tileRectInRootCoordinates);
     230            static bool sDiscardHiddenTiles = false;
     231            // FIXME: discard hidden tiles.
     232            if (!sDiscardHiddenTiles || !needsToComputeBoundingRect() || tileRectInRootCoordinates.intersects(m_state.visibleRect))
     233                tilesToAdd.append(tileRect);
     234        }
     235    }
     236
     237    for (int i = m_tiles.size() - 1; i >= 0; --i) {
     238        const FloatRect oldTile = m_tiles[i].rect;
     239        bool found = false;
     240
     241        for (int j = tilesToAdd.size() - 1; j >= 0; --j) {
     242            const FloatRect newTile = tilesToAdd[j];
     243            if (oldTile != newTile)
     244                continue;
     245
     246            found = true;
     247            tilesToAdd.remove(j);
     248            break;
     249        }
     250
     251        if (!found)
     252            tilesToRemove.append(i);
     253    }
     254
     255    for (size_t i = 0; i < tilesToAdd.size(); ++i) {
     256        if (!tilesToRemove.isEmpty()) {
     257            Tile& tile = m_tiles[tilesToRemove[0]];
     258            tilesToRemove.remove(0);
     259            tile.rect = tilesToAdd[i];
     260            tile.needsReset = true;
     261            continue;
     262        }
     263
     264        Tile tile;
     265        tile.rect = tilesToAdd[i];
     266        tile.needsReset = true;
     267        m_tiles.append(tile);
     268    }
     269
     270    for (size_t i = 0; i < tilesToRemove.size() && m_tiles.size() > TileEraseThreshold; ++i)
     271        m_tiles.remove(tilesToRemove[i]);
     272}
     273
     274void TextureMapperNode::computeVisibleRectIfNeeded()
     275{
     276    if (!needsToComputeBoundingRect())
     277        return;
     278    FloatRect rootVisibleRect;
     279    if (!m_parent)
     280        rootVisibleRect = m_state.rootVisibleRect;
     281    else if (m_parent)
     282        rootVisibleRect = m_parent->m_state.rootVisibleRect;
     283
     284    m_state.rootVisibleRect = rootVisibleRect;
     285    m_state.visibleRect = m_state.rootVisibleRect;
     286    m_state.visibleRect.intersect(m_transforms.boundingRectFromRoot);
     287}
     288
     289void TextureMapperNode::renderContent(TextureMapper* textureMapper, GraphicsLayer* layer)
     290{
     291    if (m_size.isEmpty() || !layer || (!m_state.drawsContent && m_currentContent.contentType == HTMLContentType)) {
     292        m_tiles.clear();
     293        return;
     294    }
     295
     296    if (!textureMapper)
     297        return;
     298
     299    if (m_currentContent.contentType == MediaContentType)
     300        return;
     301
     302    // FIXME: Add directly composited images.
     303    FloatRect dirtyRect = m_currentContent.needsDisplay ? entireRect() : m_currentContent.needsDisplayRect;
     304    dirtyRect.scale(m_state.contentScale);
     305
     306    for (size_t tileIndex = 0; tileIndex < m_tiles.size(); ++tileIndex) {
     307        Tile& tile = m_tiles[tileIndex];
     308        FloatRect rect = dirtyRect;
     309        if (!tile.texture)
     310            tile.texture = textureMapper->createTexture();
     311        RefPtr<BitmapTexture>& texture = tile.texture;
     312        IntSize tileSize = enclosingIntRect(tile.rect).size();
     313
     314        if (tile.needsReset || texture->contentSize() != tileSize || !texture->isValid()) {
     315            tile.needsReset = false;
     316            texture->reset(tileSize, m_currentContent.contentType == DirectImageContentType ? false : m_state.contentsOpaque);
     317            rect = tile.rect;
     318        }
     319
     320        IntRect contentRect = enclosingIntRect(tile.rect);
     321        contentRect.intersect(enclosingIntRect(rect));
     322        if (contentRect.isEmpty())
     323            continue;
     324
     325        FloatRect contentRectInTileCoordinates = contentRect;
     326        FloatPoint offset(-tile.rect.x(), -tile.rect.y());
     327        contentRectInTileCoordinates.move(offset.x(), offset.y());
     328
     329        {
     330            GraphicsContext context(texture->beginPaint(enclosingIntRect(contentRectInTileCoordinates)));
    456331            context.setImageInterpolationQuality(textureMapper->imageInterpolationQuality());
    457332            context.setTextDrawingMode(textureMapper->textDrawingMode());
    458         }
    459         layer->paintGraphicsLayerContents(context, dirtyRect);
    460     }
    461     m_texture->endPaint();
     333            context.translate(offset.x(), offset.y());
     334            context.scale(FloatSize(m_state.contentScale, m_state.contentScale));
     335            FloatRect scaledContentRect(contentRect);
     336            scaledContentRect.scale(1.0 / m_state.contentScale);
     337            if (m_currentContent.contentType == DirectImageContentType)
     338                context.drawImage(m_currentContent.image.get(), ColorSpaceDeviceRGB, IntPoint(0, 0));
     339            else
     340                layer->paintGraphicsLayerContents(context, enclosingIntRect(scaledContentRect));
     341            texture->endPaint();
     342        }
     343    }
     344
    462345    m_currentContent.needsDisplay = false;
    463 }
    464 
    465 
    466 void TextureMapperNode::paint(TextureMapper* textureMapper, const TextureMapperContentLayer::PaintOptions& options)
    467 {
    468     ASSERT(m_layerType == RootLayer);
     346    m_currentContent.needsDisplayRect = IntRect();
     347}
     348
     349void TextureMapperNode::paint()
     350{
    469351    if (m_size.isEmpty())
    470352        return;
    471353
    472     TexmapPaintOptions opt;
    473     opt.opacity = 1;
    474     opt.rootLayer = this;
    475     opt.scissorRect = options.targetRect;
    476     opt.visibleRect = options.visibleRect;
    477     opt.textureMapper = textureMapper;
    478     opt.surface = 0;
    479     opt.cache = m_cache;
     354    if (!m_surfaceManager)
     355        m_surfaceManager = new TextureMapperSurfaceManager;
     356    m_surfaceManager->textureMapper = m_textureMapper;
     357    TextureMapperPaintOptions opt;
     358    opt.surfaceManager = m_surfaceManager;
     359    opt.textureMapper = m_textureMapper;
     360    opt.textureMapper->bindSurface(0);
    480361    paintRecursive(opt);
    481 
    482     if (textureMapper->allowSurfaceForRoot() || m_state.hasSurfaceDescendants) {
    483         textureMapper->bindSurface(0);
    484         textureMapper->paintToTarget(*m_surface.get(), options.viewportSize, options.transform, options.opacity * m_state.opacity, options.targetRect);
    485     }
    486     m_cache->purge();
    487 }
    488 
    489 void TextureMapperNode::paintSelf(const TexmapPaintOptions& options)
     362}
     363
     364FloatRect TextureMapperNode::targetRectForTileRect(const FloatRect& targetRect, const FloatRect& tileRect) const
     365{
     366    return FloatRect(
     367                targetRect.x() + (tileRect.x() - targetRect.x()) / m_state.contentScale,
     368                targetRect.y() + (tileRect.y() - targetRect.y()) / m_state.contentScale,
     369                tileRect.width() / m_state.contentScale,
     370                tileRect.height() / m_state.contentScale);
     371}
     372
     373void TextureMapperNode::paintSelf(const TextureMapperPaintOptions& options)
    490374{
    491375    if (m_size.isEmpty() || (!m_state.drawsContent && m_currentContent.contentType == HTMLContentType))
    492376        return;
    493377
     378    RefPtr<BitmapTexture> maskTexture;
    494379    RefPtr<BitmapTexture> replicaMaskTexture;
    495     m_texture->unpack();
    496 
    497     RefPtr<BitmapTexture> maskTexture = m_state.maskLayer ? m_state.maskLayer->m_texture : 0;
     380
     381    if (m_state.maskLayer)
     382        maskTexture = m_state.maskLayer->texture();
    498383    if (m_state.replicaLayer && m_state.replicaLayer->m_state.maskLayer)
    499         replicaMaskTexture = m_state.replicaLayer->m_state.maskLayer->m_texture;
    500 
    501     if (maskTexture)
    502         maskTexture->unpack();
    503 
    504     if (replicaMaskTexture)
    505         replicaMaskTexture->unpack();
     384        replicaMaskTexture = m_state.replicaLayer->m_state.maskLayer->texture();
    506385
    507386    const float opacity = options.isSurface ? 1 : options.opacity;
    508387
    509     if (m_state.replicaLayer && !options.isSurface)
    510         options.textureMapper->drawTexture(*m_texture.get(), replicaRect(), m_transforms.replica,
    511                          opacity * m_state.replicaLayer->m_state.opacity,
    512                          replicaMaskTexture ? replicaMaskTexture.get() : maskTexture.get());
    513 
    514     const IntRect rect = m_layerType == ClipLayer ? entireRect() : targetRect();
    515     const TransformationMatrix transform = m_layerType == ClipLayer ? TransformationMatrix() : m_transforms.target;
    516     options.textureMapper->drawTexture(*m_texture.get(), rect, transform, opacity, options.isSurface ? 0 : maskTexture.get());
    517     options.cache->mark(m_texture.get());
    518 }
    519 
    520 bool TextureMapperNode::paintReplica(const TexmapPaintOptions& options)
    521 {
    522     BitmapTexture& texture = *m_surface.get();
    523     TextureMapperNode* replica = m_state.replicaLayer;
     388    const FloatRect targetRect = this->targetRect();
     389
     390    if (m_currentContent.contentType == MediaContentType && m_currentContent.media) {
     391        if (m_state.replicaLayer && !options.isSurface)
     392            m_currentContent.media->paintToTextureMapper(options.textureMapper, targetRect,
     393                                                         TransformationMatrix(m_transforms.target).multiply(m_state.replicaLayer->m_transforms.local),
     394                                                         opacity * m_state.replicaLayer->m_opacity,
     395                                                         replicaMaskTexture ? replicaMaskTexture.get() : maskTexture.get());
     396        m_currentContent.media->paintToTextureMapper(options.textureMapper, targetRect, m_transforms.target, opacity, options.isSurface ? 0 : maskTexture.get());
     397        return;
     398    }
     399
     400    for (size_t i = 0; i < m_tiles.size(); ++i) {
     401        BitmapTexture* texture = m_tiles[i].texture.get();
     402        if (m_state.replicaLayer && !options.isSurface) {
     403            options.textureMapper->drawTexture(*texture, targetRectForTileRect(targetRect, m_tiles[i].rect),
     404                             TransformationMatrix(m_transforms.target).multiply(m_state.replicaLayer->m_transforms.local),
     405                             opacity * m_state.replicaLayer->m_opacity,
     406                             replicaMaskTexture ? replicaMaskTexture.get() : maskTexture.get());
     407        }
     408
     409        const FloatRect rect = targetRectForTileRect(targetRect, m_tiles[i].rect);
     410        options.textureMapper->drawTexture(*texture, rect, m_transforms.target, opacity, options.isSurface ? 0 : maskTexture.get());
     411    }
     412}
     413
     414int TextureMapperNode::compareGraphicsLayersZValue(const void* a, const void* b)
     415{
     416    TextureMapperNode* const* nodeA = static_cast<TextureMapperNode* const*>(a);
     417    TextureMapperNode* const* nodeB = static_cast<TextureMapperNode* const*>(b);
     418    return int(((*nodeA)->m_transforms.centerZ - (*nodeB)->m_transforms.centerZ) * 1000);
     419}
     420
     421void TextureMapperNode::sortByZOrder(Vector<TextureMapperNode* >& array, int first, int last)
     422{
     423    qsort(array.data(), array.size(), sizeof(TextureMapperNode*), compareGraphicsLayersZValue);
     424}
     425
     426void TextureMapperNode::paintSelfAndChildren(const TextureMapperPaintOptions& options, TextureMapperPaintOptions& optionsForDescendants)
     427{
     428    bool hasClip = m_state.masksToBounds && !m_children.isEmpty();
     429    if (hasClip)
     430        options.textureMapper->beginClip(m_transforms.forDescendants, FloatRect(0, 0, m_size.width(), m_size.height()));
     431
     432    paintSelf(options);
     433
     434    for (int i = 0; i < m_children.size(); ++i)
     435        m_children[i]->paintRecursive(optionsForDescendants);
     436
     437    if (hasClip)
     438        options.textureMapper->endClip();
     439}
     440
     441bool TextureMapperNode::paintReflection(const TextureMapperPaintOptions& options, BitmapTexture* contentSurface)
     442{
     443    if (!m_state.replicaLayer)
     444        return false;
     445
     446    RefPtr<BitmapTexture> surface(contentSurface);
     447    RefPtr<BitmapTexture> maskSurface;
     448    RefPtr<BitmapTexture> replicaMaskSurface;
     449    RefPtr<BitmapTexture> replicaMaskTexture;
     450
     451    if (TextureMapperNode* replicaMask = m_state.replicaLayer->m_state.maskLayer)
     452        replicaMaskTexture = replicaMask->texture();
     453
    524454    RefPtr<BitmapTexture> maskTexture;
    525455    if (TextureMapperNode* mask = m_state.maskLayer)
    526         maskTexture = mask->m_texture;
    527     RefPtr<BitmapTexture> replicaMaskTexture;
    528     if (!replica)
    529         return false;
    530 
    531     if (replica && replica->m_state.maskLayer)
    532         replicaMaskTexture = replica->m_state.maskLayer->m_texture;
    533 
    534     if (replicaMaskTexture)
    535         replicaMaskTexture->unpack();
    536     ASSERT(m_replicaSurface);
    537     m_replicaSurface->reset(options.surface->size());
    538     m_replicaSurface->setOffset(options.surface->offset());
    539     options.cache->mark(m_replicaSurface.get());
    540     options.textureMapper->bindSurface(m_replicaSurface.get());
    541     options.textureMapper->drawTexture(texture, replicaRect(), m_transforms.replica, replica->m_state.opacity, replicaMaskTexture ? replicaMaskTexture.get() : maskTexture.get());
    542     options.textureMapper->drawTexture(texture, IntRect(IntPoint(0, 0), options.surface->size()), TransformationMatrix(), 1.0f, maskTexture.get());
     456        maskTexture = mask->texture();
     457
     458    const IntSize viewportSize = options.textureMapper->viewportSize();
     459    const bool useIntermediateBufferForReplica = m_state.replicaLayer && options.opacity < 0.99;
     460    const bool useIntermediateBufferForMask = maskTexture && replicaMaskTexture;
     461    const FloatRect viewportRect(0, 0, viewportSize.width(), viewportSize.height());
     462
     463    // The mask has to be adjusted to target coordinates.
     464    if (maskTexture) {
     465        maskSurface = options.surfaceManager->getIntermediateSurface();
     466        options.textureMapper->bindSurface(maskSurface.get());
     467        options.textureMapper->drawTexture(*maskTexture.get(), entireRect(), m_transforms.target, 1, 0);
     468        maskTexture = maskSurface;
     469    }
     470
     471    // The replica's mask has to be adjusted to target coordinates.
     472    if (replicaMaskTexture) {
     473        replicaMaskSurface = options.surfaceManager->getIntermediateSurface();
     474        options.textureMapper->bindSurface(replicaMaskSurface.get());
     475        options.textureMapper->drawTexture(*replicaMaskTexture.get(), entireRect(), m_transforms.target, 1, 0);
     476        replicaMaskTexture = replicaMaskSurface;
     477    }
     478
     479    // We might need to apply the mask of the content layer before we draw the reflection, as there might be yet another mask for the reflection itself.
     480    if (useIntermediateBufferForMask) {
     481        RefPtr<BitmapTexture> maskSurface = options.surfaceManager->getIntermediateSurface();
     482        options.textureMapper->bindSurface(maskSurface.get());
     483        options.textureMapper->drawTexture(*surface.get(), viewportRect, TransformationMatrix(), 1, maskTexture.get());
     484        options.surfaceManager->releaseIntermediateSurface(surface.get());
     485        surface = maskSurface;
     486        maskTexture.clear();
     487    }
     488
     489    // We blend the layer and its replica in an intermediate buffer before blending into the target surface.
     490    if (useIntermediateBufferForReplica) {
     491        RefPtr<BitmapTexture> replicaSurface = options.surfaceManager->getIntermediateSurface();
     492        options.textureMapper->bindSurface(replicaSurface.get());
     493        options.textureMapper->drawTexture(*surface.get(), viewportRect, m_transforms.replica, m_state.replicaLayer->m_opacity, replicaMaskTexture.get());
     494        options.textureMapper->drawTexture(*surface.get(), viewportRect, TransformationMatrix(), 1, maskTexture.get());
     495        options.surfaceManager->releaseIntermediateSurface(surface.get());
     496        surface = replicaSurface;
     497    }
     498
    543499    options.textureMapper->bindSurface(options.surface);
    544     options.cache->mark(options.surface);
    545     options.textureMapper->drawTexture(*m_replicaSurface.get(), IntRect(IntPoint(0, 0), options.surface->size()), TransformationMatrix(), options.opacity, 0);
     500
     501    // Draw the reflection.
     502    if (!useIntermediateBufferForReplica)
     503        options.textureMapper->drawTexture(*surface.get(), viewportRect, m_transforms.replica, m_state.replicaLayer->m_opacity, replicaMaskTexture.get());
     504
     505    // Draw the original.
     506    options.textureMapper->drawTexture(*surface.get(), viewportRect, TransformationMatrix(), options.opacity, maskTexture.get());
     507
     508    options.surfaceManager->releaseIntermediateSurface(maskSurface.get());
     509    options.surfaceManager->releaseIntermediateSurface(replicaMaskSurface.get());
     510
    546511    return true;
    547512}
    548513
    549 void TextureMapperNode::paintSurface(const TexmapPaintOptions& options)
    550 {
    551     if (m_layerType == RootLayer || m_layerType == DefaultLayer || m_layerType == ScissorLayer)
    552         return;
    553 
    554     RefPtr<BitmapTexture> maskTexture;
    555     if (TextureMapperNode* mask = m_state.maskLayer)
    556         maskTexture = mask->m_texture;
    557 
    558     ASSERT(m_surface);
    559     BitmapTexture& texture = *m_surface.get();
    560     if (maskTexture)
    561         maskTexture->unpack();
    562     texture.unpack();
    563 
    564     if (paintReplica(options))
    565         return;
    566 
    567     options.textureMapper->bindSurface(options.surface);
    568     options.textureMapper->drawTexture(texture,
    569                              m_layerType == TransparencyLayer ? IntRect(IntPoint(0, 0), options.surface->size()) :
    570                              targetRect(),
    571                              m_layerType == TransparencyLayer ? TransformationMatrix() : m_transforms.target,
    572                              options.opacity, maskTexture.get());
    573     options.cache->mark(&texture);
    574 }
    575 
    576 void TextureMapperNode::paintSelfAndChildren(const TexmapPaintOptions& options, TexmapPaintOptions& optionsForDescendants)
    577 {
    578     bool didPaintSelf = false;
    579     if (!m_state.preserves3D || m_children.isEmpty()) {
    580         paintSelf(options);
    581         didPaintSelf = true;
    582     }
    583 
    584     if (m_children.isEmpty() && !options.isSurface)
    585         return;
    586 
    587     if (m_layerType == ScissorLayer)
    588         optionsForDescendants.scissorRect.intersect(m_transforms.target.mapRect(IntRect(0, 0, m_size.width(), m_size.height())));
    589 
    590     for (int i = 0; i < m_children.size(); ++i) {
    591         TextureMapperNode* layer = m_children[i];
    592         if (!layer)
    593             continue;
    594 
    595         if (!didPaintSelf && layer->m_transforms.centerZ >= 0) {
    596             paintSelf(options);
    597             didPaintSelf = true;
    598         }
    599         layer->paintRecursive(optionsForDescendants);
    600         if (options.isSurface) {
    601             ASSERT(m_surface);
    602             options.cache->mark(m_surface.get());
    603             options.textureMapper->bindSurface(m_surface.get());
    604         }
    605     }
    606     if (!didPaintSelf) {
    607         paintSelf(options);
    608         didPaintSelf = true;
    609     }
    610 }
    611 
    612 void TextureMapperNode::paintRecursive(TexmapPaintOptions options)
    613 {
    614     bool isDirty = m_state.dirty;
    615     m_state.dirty = false;
    616 
     514void TextureMapperNode::paintRecursive(TextureMapperPaintOptions options)
     515{
    617516    if ((m_size.isEmpty() && (m_state.masksToBounds
    618         || m_children.isEmpty())) || !m_state.visible || options.opacity < 0.01 || m_state.opacity < 0.01)
    619         return;
    620 
    621     computeReplicaTransform();
    622 
    623     if (m_state.maskLayer)
    624         m_state.maskLayer->m_state.dirty = false;
    625 
    626     if (m_state.replicaLayer) {
    627         m_state.replicaLayer->m_state.dirty = false;
    628         if (m_state.replicaLayer->m_state.maskLayer)
    629             m_state.replicaLayer->m_state.maskLayer->m_state.dirty = false;
    630     }
    631 
    632     const bool isSurface = (m_layerType == ClipLayer
    633                             || m_layerType == TransparencyLayer
    634                             || (m_layerType == RootLayer
    635                                 && (options.textureMapper->allowSurfaceForRoot() || m_state.hasSurfaceDescendants)
    636                                 ));
    637 
    638     const IntRect boundingRectfromNearestSurface = m_transforms.targetBoundingRect;
    639 
    640     options.opacity *= m_state.opacity;
    641 
    642     TexmapPaintOptions optionsForDescendants(options);
    643     optionsForDescendants.opacity = isSurface ? 1 : options.opacity;
    644     options.isSurface = isSurface;
    645 
    646     if (m_layerType == ClipLayer) {
    647         optionsForDescendants.visibleRect = TransformationMatrix().translate(-boundingRectfromNearestSurface.x(), -boundingRectfromNearestSurface.y()).mapRect(options.visibleRect);
    648         optionsForDescendants.scissorRect = IntRect(0, 0, m_size.width(), m_size.height());
    649     }
    650 
    651     if (m_layerType == ScissorLayer)
    652         optionsForDescendants.scissorRect.intersect(m_transforms.targetBoundingRect);
    653     options.textureMapper->setClip(optionsForDescendants.scissorRect);
    654 
    655     TextureMapperCacheLock(m_texture.get());
    656     TextureMapperCacheLock(m_surface.get());
    657     TextureMapperCacheLock(m_replicaSurface.get());
    658 
    659     options.cache->purge();
    660 
    661     if (isSurface) {
    662         ASSERT(m_surface);
    663         if (!m_surface->isValid())
    664             isDirty = true;
    665         if (m_state.tiled) {
    666             m_surface->reset(options.visibleRect.size());
    667             m_surface->setOffset(options.visibleRect.location());
    668         } else if (isDirty)
    669             m_surface->reset(m_layerType == TransparencyLayer ? options.surface->size() : m_size);
    670         options.cache->mark(m_surface.get());
    671         options.textureMapper->bindSurface(m_surface.get());
    672         optionsForDescendants.surface = m_surface.get();
    673     } else if (m_surface)
    674         m_surface->destroy();
    675 
    676     if (isDirty || !isSurface || m_state.tiled || !m_surface->isValid())
     517        || m_children.isEmpty())) || !m_state.visible || options.opacity < 0.01 || m_opacity < 0.01)
     518        return;
     519
     520    options.opacity *= m_opacity;
     521    RefPtr<BitmapTexture> surface;
     522    const bool needsTwoPass = ((m_state.replicaLayer || m_state.maskLayer) && !m_children.isEmpty()) || (m_opacity < 0.99 && m_state.mightHaveOverlaps) || (m_opacity < 0.99 && m_state.replicaLayer);
     523    const IntSize viewportSize = options.textureMapper->viewportSize();
     524    options.isSurface = false;
     525
     526    TextureMapperPaintOptions optionsForDescendants(options);
     527
     528    if (!needsTwoPass) {
    677529        paintSelfAndChildren(options, optionsForDescendants);
    678 
    679     paintSurface(options);
     530        return;
     531    }
     532
     533    FloatRect viewportRect(0, 0, viewportSize.width(), viewportSize.height());
     534
     535    RefPtr<BitmapTexture> maskSurface;
     536
     537    // The mask has to be adjusted to target coordinates.
     538    if (m_state.maskLayer) {
     539        maskSurface = options.surfaceManager->getIntermediateSurface();
     540        options.textureMapper->bindSurface(maskSurface.get());
     541        options.textureMapper->drawTexture(*m_state.maskLayer->texture(), entireRect(), m_transforms.target, 1.0, 0);
     542    }
     543
     544    surface = options.surfaceManager->getIntermediateSurface();
     545    optionsForDescendants.surface = surface.get();
     546    options.isSurface = true;
     547    optionsForDescendants.opacity = 1;
     548    options.textureMapper->bindSurface(surface.get());
     549
     550    paintSelfAndChildren(options, optionsForDescendants);
     551
     552    if (!paintReflection(options, surface.get())) {
     553        options.textureMapper->bindSurface(options.surface);
     554        options.textureMapper->drawTexture(*surface.get(), viewportRect, TransformationMatrix(), options.opacity, 0);
     555    }
     556
     557    options.surfaceManager->releaseIntermediateSurface(surface.get());
     558    options.surfaceManager->releaseIntermediateSurface(maskSurface.get());
    680559}
    681560
    682561TextureMapperNode::~TextureMapperNode()
    683562{
    684     setNeedsDisplay();
    685     {
    686         const int childrenSize = m_children.size();
    687         for (int i = childrenSize-1; i >= 0; --i) {
    688             ASSERT(m_children[i]->m_parent == this);
    689             m_children[i]->m_parent = 0;
    690         }
    691     }
     563    for (int i = m_children.size() - 1; i >= 0; --i)
     564        m_children[i]->m_parent = 0;
     565
    692566    if (m_parent)
    693567        m_parent->m_children.remove(m_parent->m_children.find(this));
    694     if (m_cache)
    695         delete m_cache;
    696 }
    697 
    698 void TextureMapperNode::performPostSyncOperations()
    699 {
    700     const LayerType prevLayerType = m_layerType;
    701     computeLayerType();
    702     if (prevLayerType != m_layerType)
    703         m_state.dirty = true;
    704     if (m_transforms.dirty)
    705         setNeedsDisplay();
    706 
    707     computeTransformations();
    708     if (m_state.maskLayer && !m_state.dirty)
    709         m_state.dirty = m_state.maskLayer->m_state.dirty;
    710     if (m_state.replicaLayer && !m_state.dirty)
    711         m_state.dirty = m_state.replicaLayer->m_state.dirty;
    712 
    713     const int size = m_children.size();
    714 
    715     for (int i = size - 1; i >= 0; --i) {
    716         TextureMapperNode* layer = m_children[i];
    717 
    718         layer->performPostSyncOperations();
    719         if (!m_state.dirty)
    720             m_state.dirty = layer->m_state.dirty;
    721     }
    722     m_state.hasSurfaceDescendants = hasSurfaceDescendants();
    723     if (m_state.dirty)
    724         m_state.descendantsWithContent = countDescendantsWithContent();
    725 
    726     if (m_state.preserves3D)
    727         sortByZOrder(m_children, 0, size);
    728     if (m_state.dirty)
    729         setNeedsDisplay();
    730 }
    731 
    732 void TextureMapperNode::syncCompositingState(GraphicsLayerTextureMapper* graphicsLayer, bool recurse)
    733 {
    734     TextureMapper* textureMapper = rootLayer()->m_platformClient->textureMapper();
    735     syncCompositingStateInternal(graphicsLayer, recurse, textureMapper);
    736     performPostSyncOperations();
     568}
     569
     570void TextureMapperNode::setVisibleRect(const IntRect& rect)
     571{
     572    m_state.rootVisibleRect = m_state.visibleRect = rect;
     573}
     574
     575void TextureMapperNode::syncCompositingState(GraphicsLayerTextureMapper* graphicsLayer, int options)
     576{
     577    syncCompositingState(graphicsLayer, rootLayer()->m_textureMapper, options);
    737578}
    738579
    739580void TextureMapperNode::syncCompositingStateSelf(GraphicsLayerTextureMapper* graphicsLayer, TextureMapper* textureMapper)
    740581{
    741     const int changeMask = graphicsLayer->changeMask();
    742     initializeTextureMapper(textureMapper);
     582    int changeMask = graphicsLayer->changeMask();
    743583    const TextureMapperNode::ContentData& pendingContent = graphicsLayer->pendingContent();
    744     if (changeMask == NoChanges && pendingContent.needsDisplayRect.isEmpty() && !pendingContent.needsDisplay)
    745         return;
    746 
    747     setNeedsDisplay();
    748     if (m_parent)
    749         m_parent->m_state.dirty = true;
     584    if (changeMask == NoChanges && graphicsLayer->m_animations.isEmpty() && pendingContent.needsDisplayRect.isEmpty() && !pendingContent.needsDisplay)
     585        return;
    750586
    751587    if (m_currentContent.contentType == HTMLContentType && (changeMask & ParentChange)) {
    752         // The WebCore compositor manages item ownership. We have to make sure graphicsview doesn't
    753         // try to snatch that ownership.
    754 
    755         if (!graphicsLayer->parent())
    756             m_parent = 0;
    757         else
    758             m_parent = toTextureMapperNode(graphicsLayer->parent());
     588        m_parent = toTextureMapperNode(graphicsLayer->parent());
    759589
    760590        if (!graphicsLayer->parent() && m_parent) {
     
    767597        m_children.clear();
    768598        for (size_t i = 0; i < graphicsLayer->children().size(); ++i) {
    769             if (TextureMapperNode* child = toTextureMapperNode(graphicsLayer->children()[i])) {
    770                 if (!child)
    771                     continue;
    772                 m_children.append(child);
    773                 child->m_parent = this;
    774             }
    775         }
    776         m_state.dirty = true;
     599            TextureMapperNode* child = toTextureMapperNode(graphicsLayer->children()[i]);
     600            if (!child)
     601                continue;
     602            m_children.append(child);
     603            child->m_parent = this;
     604        }
    777605    }
    778606
    779607    if (changeMask & (SizeChange | ContentsRectChange)) {
    780         IntSize wantedSize = IntSize(graphicsLayer->size().width(), graphicsLayer->size().height());
     608        FloatSize wantedSize(graphicsLayer->size().width(), graphicsLayer->size().height());
    781609        if (wantedSize.isEmpty() && pendingContent.contentType == HTMLContentType)
    782             wantedSize = IntSize(graphicsLayer->contentsRect().width(), graphicsLayer->contentsRect().height());
    783 
    784         if (wantedSize != m_size) {
    785             m_size = IntSize(wantedSize.width(), wantedSize.height());
    786             if (m_platformClient)
    787                 m_platformClient->setSizeChanged(m_size);
    788             const bool needsTiling = m_size.width() > 2000 || m_size.height() > 2000;
    789             if (m_state.tiled != needsTiling)
    790                 m_state.tiled = needsTiling;
    791             m_state.dirty = true;
    792         }
     610            wantedSize = FloatSize(graphicsLayer->contentsRect().width(), graphicsLayer->contentsRect().height());
     611
     612        if (wantedSize != m_size)
     613            m_tiles.clear();
     614
     615        m_size = wantedSize;
    793616    }
    794617
     
    803626    }
    804627
    805     if (changeMask & (TransformChange | SizeChange | AnchorPointChange | PositionChange))
    806         m_transforms.localDirty = true;
    807 
    808     if (changeMask & (ChildrenTransformChange | SizeChange))
    809         m_transforms.perspectiveDirty = true;
    810 
    811     if (changeMask & (ChildrenTransformChange | Preserves3DChange | TransformChange | AnchorPointChange | SizeChange | ContentsRectChange | BackfaceVisibilityChange | PositionChange | MaskLayerChange | DrawsContentChange | ContentChange | ReplicaLayerChange))    {
    812         // Due to the differences between the way WebCore handles transforms and the way Qt handles transforms,
    813         // all these elements affect the transforms of all the descendants.
    814         invalidateTransform();
    815     }
    816 
    817     if (changeMask & DisplayChange)
    818         m_state.dirty = true;
     628    if (changeMask & AnimationChange) {
     629        m_animations.clear();
     630        for (size_t i = 0; i < graphicsLayer->m_animations.size(); ++i)
     631            m_animations.append(graphicsLayer->m_animations[i]);
     632    }
    819633
    820634    m_state.maskLayer = toTextureMapperNode(graphicsLayer->maskLayer());
     
    823637    m_state.anchorPoint = graphicsLayer->anchorPoint();
    824638    m_state.size = graphicsLayer->size();
     639    m_state.contentsRect = graphicsLayer->contentsRect();
    825640    m_state.transform = graphicsLayer->transform();
    826     m_state.contentsRect = graphicsLayer->contentsRect();
    827     m_state.opacity = graphicsLayer->opacity();
    828641    m_state.contentsRect = graphicsLayer->contentsRect();
    829642    m_state.preserves3D = graphicsLayer->preserves3D();
     
    833646    m_state.backfaceVisibility = graphicsLayer->backfaceVisibility();
    834647    m_state.childrenTransform = graphicsLayer->childrenTransform();
     648    m_state.opacity = graphicsLayer->opacity();
    835649    m_currentContent.contentType = pendingContent.contentType;
    836650    m_currentContent.image = pendingContent.image;
    837651    m_currentContent.media = pendingContent.media;
    838     m_currentContent.backgroundColor = pendingContent.backgroundColor;
    839652    m_currentContent.needsDisplay = m_currentContent.needsDisplay || pendingContent.needsDisplay;
    840     m_currentContent.needsDisplayRect.unite(pendingContent.needsDisplayRect);
    841 
    842 }
    843 
    844 void TextureMapperNode::syncCompositingStateInternal(GraphicsLayerTextureMapper* graphicsLayer, bool recurse, TextureMapper* textureMapper)
    845 {
    846     syncCompositingStateSelf(graphicsLayer, textureMapper);
    847 
    848     graphicsLayer->didSynchronize();
    849 
    850     if (m_state.maskLayer) {
    851         m_state.maskLayer->syncCompositingStateInternal(toGraphicsLayerTextureMapper(graphicsLayer->maskLayer()), false, textureMapper);
     653    if (!m_currentContent.needsDisplay)
     654        m_currentContent.needsDisplayRect.unite(pendingContent.needsDisplayRect);
     655
     656    if (!hasRunningOpacityAnimation())
     657        m_opacity = m_state.opacity;
     658    if (!hasRunningTransformAnimation())
     659        m_transforms.base = m_state.transform;
     660}
     661
     662bool TextureMapperNode::descendantsOrSelfHaveRunningAnimations() const
     663{
     664    for (size_t i = 0; i < m_animations.size(); ++i) {
     665        if (!m_animations[i]->paused)
     666            return true;
     667    }
     668
     669    for (size_t i = 0; i < m_children.size(); ++i) {
     670        if (m_children[i]->descendantsOrSelfHaveRunningAnimations())
     671            return true;
     672    }
     673
     674    return false;
     675}
     676
     677static double normalizedAnimationValue(double runningTime, double duration, bool alternate)
     678{
     679    if (!duration)
     680        return 0;
     681    const int loopCount = runningTime / duration;
     682    const double lastFullLoop = duration * double(loopCount);
     683    const double remainder = runningTime - lastFullLoop;
     684    const double normalized = remainder / duration;
     685    return (loopCount % 2 && alternate) ? (1 - normalized) : normalized;
     686}
     687
     688void TextureMapperNode::applyOpacityAnimation(float fromOpacity, float toOpacity, double progress)
     689{
     690    // Optimization: special case the edge values (0 and 1).
     691    if (progress == 1.0)
     692        setOpacity(toOpacity);
     693    else if (!progress)
     694        setOpacity(fromOpacity);
     695    else
     696        setOpacity(fromOpacity + progress * (toOpacity - fromOpacity));
     697}
     698
     699static inline double solveEpsilon(double duration)
     700{
     701    return 1.0 / (200.0 * duration);
     702}
     703
     704static inline double solveCubicBezierFunction(qreal p1x, qreal p1y, qreal p2x, qreal p2y, double t, double duration)
     705{
     706    UnitBezier bezier(p1x, p1y, p2x, p2y);
     707    return bezier.solve(t, solveEpsilon(duration));
     708}
     709
     710static inline double solveStepsFunction(int numSteps, bool stepAtStart, double t)
     711{
     712    if (stepAtStart)
     713        return qMin(1.0, (floor(numSteps * t) + 1) / numSteps);
     714    return floor(numSteps * t) / numSteps;
     715}
     716
     717static inline float applyTimingFunction(const TimingFunction* timingFunction, float progress, double duration)
     718{
     719    if (!timingFunction)
     720        return progress;
     721
     722    if (timingFunction->isCubicBezierTimingFunction()) {
     723        const CubicBezierTimingFunction* ctf = static_cast<const CubicBezierTimingFunction*>(timingFunction);
     724        return solveCubicBezierFunction(ctf->x1(),
     725                                        ctf->y1(),
     726                                        ctf->x2(),
     727                                        ctf->y2(),
     728                                        progress, duration);
     729    }
     730
     731    if (timingFunction->isStepsTimingFunction()) {
     732        const StepsTimingFunction* stf = static_cast<const StepsTimingFunction*>(timingFunction);
     733        return solveStepsFunction(stf->numberOfSteps(), stf->stepAtStart(), double(progress));
     734    }
     735
     736    return progress;
     737}
     738
     739void TextureMapperNode::applyTransformAnimation(const TextureMapperAnimation& animation, const TransformOperations* from, const TransformOperations* to, double progress)
     740{
     741    // Optimization: special case the edge values (0 and 1).
     742    if (progress == 1.0 || !progress) {
     743        TransformationMatrix matrix;
     744        const TransformOperations* ops = progress ? to : from;
     745        ops->apply(animation.boxSize, matrix);
     746        setTransform(matrix);
     747    }
     748
     749    if (!animation.listsMatch) {
     750        TransformationMatrix toMatrix, fromMatrix;
     751        to->apply(animation.boxSize, toMatrix);
     752        from->apply(animation.boxSize, fromMatrix);
     753        toMatrix.blend(fromMatrix, progress);
     754        setTransform(toMatrix);
     755        return;
     756    }
     757
     758    TransformationMatrix matrix;
     759
     760    if (!to->size()) {
     761        const TransformOperations* swap = to;
     762        to = from;
     763        from = swap;
     764    } else if (!from->size())
     765        progress = 1.0 - progress;
     766
     767    TransformOperations blended(*to);
     768    for (size_t i = 0; i < animation.functionList.size(); ++i)
     769        blended.operations()[i]->blend(from->at(i), progress, !from->at(i))->apply(matrix, animation.boxSize);
     770
     771    setTransform(matrix);
     772}
     773
     774void TextureMapperNode::applyAnimationFrame(const TextureMapperAnimation& animation, const AnimationValue* from, const AnimationValue* to, float progress)
     775{
     776    switch (animation.keyframes.property()) {
     777    case AnimatedPropertyOpacity:
     778        applyOpacityAnimation((static_cast<const FloatAnimationValue*>(from)->value()), (static_cast<const FloatAnimationValue*>(to)->value()), progress);
     779        return;
     780    case AnimatedPropertyWebkitTransform:
     781        applyTransformAnimation(animation, static_cast<const TransformAnimationValue*>(from)->value(), static_cast<const TransformAnimationValue*>(to)->value(), progress);
     782        return;
     783    default:
     784        ASSERT_NOT_REACHED();
     785    }
     786}
     787
     788void TextureMapperNode::applyAnimation(const TextureMapperAnimation& animation, double normalizedValue)
     789{
     790    // Optimization: special case the edge values (0 and 1).
     791    if (!normalizedValue) {
     792        applyAnimationFrame(animation, animation.keyframes.at(0), animation.keyframes.at(1), 0);
     793        return;
     794    }
     795    if (normalizedValue == 1.0) {
     796        applyAnimationFrame(animation, animation.keyframes.at(animation.keyframes.size() - 2), animation.keyframes.at(animation.keyframes.size() - 1), 1);
     797        return;
     798    }
     799    if (animation.keyframes.size() == 2) {
     800        normalizedValue = applyTimingFunction(animation.animation->timingFunction().get(), normalizedValue, animation.animation->duration());
     801        applyAnimationFrame(animation, animation.keyframes.at(0), animation.keyframes.at(1), normalizedValue);
     802        return;
     803    }
     804
     805    for (size_t i = 0; i < animation.keyframes.size() - 1; ++i) {
     806        const AnimationValue* from = animation.keyframes.at(i);
     807        const AnimationValue* to = animation.keyframes.at(i + 1);
     808        if (from->keyTime() > normalizedValue || to->keyTime() < normalizedValue)
     809            continue;
     810
     811        normalizedValue = (normalizedValue - from->keyTime()) / (to->keyTime() - from->keyTime());
     812        normalizedValue = applyTimingFunction(from->timingFunction(), normalizedValue, animation.animation->duration());
     813        applyAnimationFrame(animation, from, to, normalizedValue);
     814        break;
     815    }
     816}
     817
     818bool TextureMapperNode::hasRunningOpacityAnimation() const
     819{
     820    for (size_t i = 0; i < m_animations.size(); ++i) {
     821        const TextureMapperAnimation& animation = *m_animations[i].get();
     822        if (!animation.paused && animation.keyframes.property() == AnimatedPropertyOpacity)
     823            return true;
     824    }
     825    return false;
     826}
     827
     828bool TextureMapperNode::hasRunningTransformAnimation() const
     829{
     830    for (size_t i = 0; i < m_animations.size(); ++i) {
     831        const TextureMapperAnimation& animation = *m_animations[i].get();
     832        if (!animation.paused && animation.keyframes.property() == AnimatedPropertyWebkitTransform)
     833            return true;
     834    }
     835    return false;
     836}
     837
     838void TextureMapperNode::syncAnimations(GraphicsLayerTextureMapper* layer)
     839{
     840    for (int i = m_animations.size() - 1; i >= 0; --i) {
     841        RefPtr<TextureMapperAnimation> animation = m_animations[i];
     842
     843        double totalRunningTime = WTF::currentTime() - animation->startTime;
     844        RefPtr<Animation> anim = animation->animation;
     845        double normalizedValue = normalizedAnimationValue(totalRunningTime, anim->duration(), true);
     846
     847        if (anim->iterationCount() != Animation::IterationCountInfinite && totalRunningTime >= anim->duration() * anim->iterationCount()) {
     848            // We apply an animation that very close to the edge, so that the final frame is applied, oterwise we might get, for example, an opacity of 0.01 which is still visible.
     849            if (anim->fillsForwards()) {
     850                if (animation->keyframes.property() == AnimatedPropertyWebkitTransform)
     851                    m_state.transform = m_transforms.base;
     852                else if (animation->keyframes.property() == AnimatedPropertyOpacity)
     853                    m_opacity = m_state.opacity;
     854            }
     855
     856            m_animations.remove(i);
     857            continue;
     858        }
     859
     860        if (!animation->paused)
     861            applyAnimation(*animation.get(), normalizedValue);
     862    }
     863}
     864
     865void TextureMapperNode::syncCompositingState(GraphicsLayerTextureMapper* graphicsLayer, TextureMapper* textureMapper, int options)
     866{
     867    if (graphicsLayer) {
     868        syncCompositingStateSelf(graphicsLayer, textureMapper);
     869        graphicsLayer->didSynchronize();
     870    }
     871
     872    if (graphicsLayer && m_state.maskLayer) {
     873        m_state.maskLayer->syncCompositingState(toGraphicsLayerTextureMapper(graphicsLayer->maskLayer()), textureMapper);
     874
     875        // A mask layer has its parent's size by default, in case it's not set specifically.
    852876        if (m_state.maskLayer->m_size.isEmpty())
    853877            m_state.maskLayer->m_size = m_size;
     
    855879
    856880    if (m_state.replicaLayer)
    857         m_state.replicaLayer->syncCompositingStateInternal(toGraphicsLayerTextureMapper(graphicsLayer->replicaLayer()), false, textureMapper);
    858 
    859     if (m_state.dirty)
    860         uploadTextureFromContent(textureMapper, m_state.visibleRect, graphicsLayer);
    861 
    862     m_currentContent.needsDisplayRect = IntRect();
    863     m_currentContent.needsDisplay = false;
    864 
    865     if (!recurse)
    866         return;
    867 
    868     Vector<GraphicsLayer*> children = graphicsLayer->children();
    869     for (int i = children.size() - 1; i >= 0; --i) {
    870         TextureMapperNode* node = toTextureMapperNode(children[i]);
    871         if (!node)
    872             continue;
    873         node->syncCompositingStateInternal(toGraphicsLayerTextureMapper(children[i]), true, textureMapper);
    874     }
    875 }
    876 
    877 }
     881        m_state.replicaLayer->syncCompositingState(toGraphicsLayerTextureMapper(graphicsLayer->replicaLayer()), textureMapper);
     882
     883    syncAnimations(graphicsLayer);
     884
     885    computeAllTransforms();
     886    computeBoundingRectFromRootIfNeeded();
     887    computePerspectiveTransformIfNeeded();
     888    computeTiles();
     889    computeOverlapsIfNeeded();
     890
     891    if (graphicsLayer)
     892        renderContent(textureMapper, graphicsLayer);
     893
     894    if (!(options & TraverseDescendants))
     895        return;
     896
     897    if (graphicsLayer) {
     898        Vector<GraphicsLayer*> children = graphicsLayer->children();
     899        for (int i = children.size() - 1; i >= 0; --i) {
     900            TextureMapperNode* node = toTextureMapperNode(children[i]);
     901            if (!node)
     902                continue;
     903            node->syncCompositingState(toGraphicsLayerTextureMapper(children[i]), textureMapper, options);
     904        }
     905    } else {
     906        for (int i = m_children.size() - 1; i >= 0; --i)
     907            m_children[i]->syncCompositingState(0, textureMapper, options);
     908    }
     909
     910    if (m_state.preserves3D)
     911        sortByZOrder(m_children, 0, m_children.size());
     912}
     913
     914static PassRefPtr<TimingFunction> copyTimingFunction(const TimingFunction* tfunc)
     915{
     916    if (!tfunc)
     917        return 0;
     918
     919    if (tfunc->isLinearTimingFunction())
     920        return LinearTimingFunction::create();
     921
     922    if (tfunc->isCubicBezierTimingFunction()) {
     923        const CubicBezierTimingFunction* btfunc = static_cast<const CubicBezierTimingFunction*>(tfunc);
     924        return CubicBezierTimingFunction::create(btfunc->x1(), btfunc->y1(), btfunc->x2(), btfunc->y2());
     925    }
     926
     927    if (tfunc->isStepsTimingFunction()) {
     928        const StepsTimingFunction* stfunc = static_cast<const StepsTimingFunction*>(tfunc);
     929        return StepsTimingFunction::create(stfunc->numberOfSteps(), stfunc->stepAtStart());
     930    }
     931
     932    return 0;
     933}
     934
     935static const AnimationValue* copyAnimationValue(AnimatedPropertyID property, const AnimationValue* value)
     936{
     937    switch (property) {
     938    case AnimatedPropertyWebkitTransform: {
     939        const TransformAnimationValue* transformValue = static_cast<const TransformAnimationValue*>(value);
     940        return new TransformAnimationValue(transformValue->keyTime(), transformValue->value(), copyTimingFunction(transformValue->timingFunction()));
     941    }
     942    case AnimatedPropertyOpacity: {
     943        const FloatAnimationValue* floatValue = static_cast<const FloatAnimationValue*>(value);
     944        return new FloatAnimationValue(floatValue->keyTime(), floatValue->value(), copyTimingFunction(floatValue->timingFunction()));
     945    }
     946    default:
     947        ASSERT_NOT_REACHED();
     948    }
     949
     950    return 0;
     951}
     952
     953TextureMapperAnimation::TextureMapperAnimation(const KeyframeValueList& values)
     954    : keyframes(values.property())
     955{
     956    for (size_t i = 0; i < values.size(); ++i)
     957        keyframes.insert(copyAnimationValue(values.property(), values.at(i)));
     958}
     959
     960}
     961
     962#endif
  • trunk/Source/WebCore/platform/graphics/texmap/TextureMapperNode.h

    r82199 r86276  
    2626#include "Image.h"
    2727#include "TextureMapper.h"
    28 #include "TextureMapperPlatformLayer.h"
    2928#include "Timer.h"
    3029#include "TransformOperations.h"
     
    3736namespace WebCore {
    3837
     38class TextureMapperPlatformLayer;
    3939class TextureMapperNode;
    40 class TextureMapperCache;
    4140class GraphicsLayerTextureMapper;
    42 
    43 struct TexmapPaintOptions {
     41class TextureMapperSurfaceManager;
     42
     43class TextureMapperPaintOptions {
     44public:
    4445    BitmapTexture* surface;
    4546    TextureMapper* textureMapper;
    46     TextureMapperNode* rootLayer;
     47    TextureMapperSurfaceManager* surfaceManager;
     48
    4749    float opacity;
    48     IntRect scissorRect;
    49     IntRect visibleRect;
    5050    bool isSurface;
    51     TextureMapperCache* cache;
     51    TextureMapperPaintOptions() : surface(0), textureMapper(0), opacity(1.0), isSurface(false) { }
    5252};
    5353
    54 class TextureMapperNode : public TextureMapperContentLayer {
     54class TextureMapperAnimation : public RefCounted<TextureMapperAnimation> {
     55public:
     56    String name;
     57    KeyframeValueList keyframes;
     58    IntSize boxSize;
     59    RefPtr<Animation> animation;
     60    bool paused;
     61    Vector<TransformOperation::OperationType> functionList;
     62    bool listsMatch;
     63    bool hasBigRotation;
     64    double startTime;
     65    TextureMapperAnimation(const KeyframeValueList&);
     66    static PassRefPtr<TextureMapperAnimation> create(const KeyframeValueList& values) { return adoptRef(new TextureMapperAnimation(values)); }
     67};
     68
     69class TextureMapperNode {
    5570
    5671public:
     
    8499        BackgroundColorChange =     (1L << 19),
    85100
    86         ReplicaLayerChange =        (1L << 20)
    87     };
     101        ReplicaLayerChange =        (1L << 20),
     102        AnimationChange =           (1L << 21)
     103    };
     104
     105    enum SyncOptions {
     106        TraverseDescendants = 1
     107    };
     108
    88109    // The compositor lets us special-case images and colors, so we try to do so.
    89110    enum ContentType { HTMLContentType, DirectImageContentType, ColorContentType, MediaContentType, Canvas3DContentType};
    90111    struct ContentData {
    91         IntRect needsDisplayRect;
     112        FloatRect needsDisplayRect;
    92113        bool needsDisplay;
    93114        Color backgroundColor;
     
    95116        ContentType contentType;
    96117        RefPtr<Image> image;
    97         TextureMapperMediaLayer* media;
    98 
     118        const TextureMapperPlatformLayer* media;
    99119        ContentData()
    100120            : needsDisplay(false)
     
    106126    };
    107127
    108 
    109     TextureMapperNode();
     128    TextureMapperNode()
     129        : m_parent(0), m_effectTarget(0), m_opacity(1.0), m_surfaceManager(0), m_textureMapper(0) { }
     130
    110131    virtual ~TextureMapperNode();
    111132
    112     void syncCompositingState(GraphicsLayerTextureMapper*, bool recursive);
    113 
    114 protected:
    115     // Reimps from TextureMapperContentLayer
    116     virtual IntSize size() const { return m_size; }
    117     virtual void setPlatformLayerClient(TextureMapperLayerClient*);
    118     virtual void paint(TextureMapper*, const TextureMapperContentLayer::PaintOptions&);
     133    void syncCompositingState(GraphicsLayerTextureMapper*, int syncOptions = 0);
     134    void syncCompositingState(GraphicsLayerTextureMapper*, TextureMapper*, int syncOptions = 0);
     135    IntSize size() const { return IntSize(m_size.width() + .5, m_size.height() + .5); }
     136    void setTransform(const TransformationMatrix&);
     137    void setOpacity(float value) { m_opacity = value; }
     138    void setVisibleRect(const IntRect&);
     139    void setTextureMapper(TextureMapper* texmap) { m_textureMapper = texmap; }
     140    bool descendantsOrSelfHaveRunningAnimations() const;
     141
     142    void paint();
     143
     144    bool needsToComputeBoundingRect() const;
     145
     146    const TextureMapperPlatformLayer* media() const { return m_currentContent.media; }
    119147
    120148private:
    121149    TextureMapperNode* rootLayer();
    122     void clearDirectImage();
    123     void computeTransformations();
    124     IntSize nearestSurfaceSize() const;
    125     void computeReplicaTransform();
    126     void computeLayerType();
    127     void computeLocalTransform();
    128     void flattenTo2DSpaceIfNecessary();
    129     void initializeTextureMapper(TextureMapper*);
    130     void invalidateTransform();
     150    void computeAllTransforms();
     151    void computeVisibleRectIfNeeded();
     152    void computePerspectiveTransformIfNeeded();
     153    void computeReplicaTransformIfNeeded();
     154    void computeOverlapsIfNeeded();
     155    void computeLocalTransformIfNeeded();
     156    void computeBoundingRectFromRootIfNeeded();
     157    void computeTiles();
     158    int countDescendantsWithContent() const;
     159    FloatRect targetRectForTileRect(const FloatRect& totalTargetRect, const FloatRect& tileRect) const;
     160    void invalidateViewport(const FloatRect&);
    131161    void notifyChange(ChangeMask);
    132     void setNeedsDisplay();
    133     void setNeedsDisplayInRect(IntRect);
    134     void performPostSyncOperations();
    135     void syncCompositingStateInternal(GraphicsLayerTextureMapper*, bool recursive, TextureMapper*);
    136162    void syncCompositingStateSelf(GraphicsLayerTextureMapper* graphicsLayer, TextureMapper* textureMapper);
    137     TextureMapperCache* cache();
    138 
    139     void paintRecursive(TexmapPaintOptions options);
    140     bool paintReplica(const TexmapPaintOptions& options);
    141     void paintSurface(const TexmapPaintOptions& options);
    142     void paintSelf(const TexmapPaintOptions& options);
    143     void paintSelfAndChildren(const TexmapPaintOptions& options, TexmapPaintOptions& optionsForDescendants);
    144     void uploadTextureFromContent(TextureMapper* textureMapper, const IntRect& visibleRect, GraphicsLayer* layer);
    145 
    146     int countDescendantsWithContent() const;
    147     bool hasSurfaceDescendants() const;
    148 
    149     TextureMapper* textureMapper();
    150 
    151 
    152     static TextureMapperNode* toTextureMapperNode(GraphicsLayer*);
     163
    153164    static int compareGraphicsLayersZValue(const void* a, const void* b);
    154165    static void sortByZOrder(Vector<TextureMapperNode* >& array, int first, int last);
     166
     167    BitmapTexture* texture() { return m_tiles.isEmpty() ? 0 : m_tiles[0].texture.get(); }
     168
     169    void paintRecursive(TextureMapperPaintOptions);
     170    bool paintReflection(const TextureMapperPaintOptions&, BitmapTexture* surface);
     171    void paintSelf(const TextureMapperPaintOptions&);
     172    void paintSelfAndChildren(const TextureMapperPaintOptions&, TextureMapperPaintOptions& optionsForDescendants);
     173    void renderContent(TextureMapper*, GraphicsLayer*);
     174
     175    void syncAnimations(GraphicsLayerTextureMapper*);
     176    void applyAnimation(const TextureMapperAnimation&, double runningTime);
     177    void applyAnimationFrame(const TextureMapperAnimation&, const AnimationValue* from, const AnimationValue* to, float progress);
     178    void applyOpacityAnimation(float fromOpacity, float toOpacity, double);
     179    void applyTransformAnimation(const TextureMapperAnimation&, const TransformOperations* start, const TransformOperations* end, double);
     180    bool hasRunningOpacityAnimation() const;
     181    bool hasRunningTransformAnimation() const;
     182
    155183    struct TransformData {
    156         TransformationMatrix base, target, replica, forDescendants, perspective, local;
    157         IntRect targetBoundingRect;
     184        TransformationMatrix target;
     185        TransformationMatrix replica;
     186        TransformationMatrix forDescendants;
     187        TransformationMatrix local;
     188        TransformationMatrix base;
     189        TransformationMatrix perspective;
     190        FloatRect targetBoundingRect;
    158191        float centerZ;
    159         bool dirty, localDirty, perspectiveDirty;
    160         IntRect boundingRectFromRoot;
    161         TransformData() : dirty(true), localDirty(true), perspectiveDirty(true) { }
     192        FloatRect boundingRectFromRoot;
     193        FloatRect boundingRectFromRootForDescendants;
     194        TransformData() { }
    162195    };
    163196
    164197    TransformData m_transforms;
    165198
    166     enum LayerType {
    167         DefaultLayer,
    168         RootLayer,
    169         ScissorLayer,
    170         ClipLayer,
    171         TransparencyLayer
    172     };
    173 
    174     LayerType m_layerType;
    175 
    176     inline IntRect targetRect() const
     199    inline FloatRect targetRect() const
    177200    {
    178201        return m_currentContent.contentType == HTMLContentType ? entireRect() : m_state.contentsRect;
    179202    }
    180203
    181     inline IntRect entireRect() const
     204    inline FloatRect entireRect() const
    182205    {
    183         return IntRect(0, 0, m_size.width(), m_size.height());
     206        return FloatRect(0, 0, m_size.width(), m_size.height());
    184207    }
    185208
    186     inline IntRect replicaRect() const
     209    FloatSize contentSize() const
    187210    {
    188         return m_layerType == TransparencyLayer ? IntRect(0, 0, m_nearestSurfaceSize.width(), m_nearestSurfaceSize.height()) : entireRect();
     211        return m_currentContent.contentType == DirectImageContentType && m_currentContent.image ? m_currentContent.image->size() : m_size;
    189212    }
    190 
    191     RefPtr<BitmapTexture> m_texture;
    192     RefPtr<BitmapTexture> m_surface, m_replicaSurface;
     213    struct Tile {
     214        FloatRect rect;
     215        RefPtr<BitmapTexture> texture;
     216        bool needsReset;
     217    };
     218
     219    Vector<Tile> m_tiles;
    193220
    194221    ContentData m_currentContent;
     
    197224    TextureMapperNode* m_parent;
    198225    TextureMapperNode* m_effectTarget;
    199     IntSize m_size, m_nearestSurfaceSize;
     226    FloatSize m_size;
     227    float m_opacity;
    200228    String m_name;
    201     TextureMapperLayerClient* m_platformClient;
    202229
    203230    struct State {
     
    207234        TransformationMatrix transform;
    208235        TransformationMatrix childrenTransform;
    209         Color backgroundColor;
    210         Color currentColor;
    211         GraphicsLayer::CompositingCoordinatesOrientation geoOrientation;
    212         GraphicsLayer::CompositingCoordinatesOrientation contentsOrientation;
    213236        float opacity;
    214         IntRect contentsRect;
     237        FloatRect contentsRect;
    215238        int descendantsWithContent;
    216239        TextureMapperNode* maskLayer;
    217240        TextureMapperNode* replicaLayer;
    218         bool preserves3D;
    219         bool masksToBounds;
    220         bool drawsContent;
    221         bool contentsOpaque;
    222         bool backfaceVisibility;
    223         bool visible;
    224         bool dirty;
    225         bool tiled;
    226         bool hasSurfaceDescendants;
    227         IntRect visibleRect;
     241        bool preserves3D : 1;
     242        bool masksToBounds : 1;
     243        bool drawsContent : 1;
     244        bool contentsOpaque : 1;
     245        bool backfaceVisibility : 1;
     246        bool visible : 1;
     247        bool needsReset: 1;
     248        bool mightHaveOverlaps : 1;
     249        bool needsRepaint;
     250        FloatRect visibleRect;
     251        FloatRect rootVisibleRect;
     252        float contentScale;
    228253
    229254        State()
    230255            : opacity(1.f)
    231             , descendantsWithContent(0)
    232256            , maskLayer(0)
    233257            , replicaLayer(0)
     
    238262            , backfaceVisibility(false)
    239263            , visible(true)
    240             , dirty(true)
    241             , tiled(false)
    242             , hasSurfaceDescendants(false)
     264            , needsReset(false)
     265            , mightHaveOverlaps(false)
     266            , contentScale(1.0f)
    243267        {
    244268        }
     
    246270
    247271    State m_state;
    248     TextureMapperCache* m_cache;
     272    TextureMapperSurfaceManager* m_surfaceManager;
     273    TextureMapper* m_textureMapper;
     274
     275    Vector<RefPtr<TextureMapperAnimation> > m_animations;
    249276};
     277
     278
     279TextureMapperNode* toTextureMapperNode(GraphicsLayer*);
    250280
    251281}
  • trunk/Source/WebCore/platform/qt/QWebPageClient.h

    r70819 r86276  
    5353    virtual bool inputMethodEnabled() const = 0;
    5454#if USE(ACCELERATED_COMPOSITING)
    55     virtual void setRootGraphicsLayer(WebCore::PlatformLayer* layer) { }
     55    virtual void setRootGraphicsLayer(WebCore::GraphicsLayer* layer) { }
    5656
    5757    // this gets called when the compositor wants us to sync the layers
  • trunk/Source/WebCore/plugins/PluginView.h

    r84979 r86276  
    5959#endif
    6060#if PLATFORM(QT)
     61#if USE(TEXTURE_MAPPER)
     62#include "TextureMapperPlatformLayer.h"
     63#endif
     64
    6165#include <QGraphicsItem>
    6266#include <QImage>
  • trunk/Source/WebKit/qt/Api/qwebframe.cpp

    r85864 r86276  
    9999#if USE(TEXTURE_MAPPER)
    100100#include "texmap/TextureMapper.h"
    101 #include "texmap/TextureMapperPlatformLayer.h"
     101#include "texmap/TextureMapperNode.h"
    102102#endif
    103103#include "wtf/HashMap.h"
     
    322322void QWebFramePrivate::renderCompositedLayers(GraphicsContext* context, const IntRect& clip)
    323323{
    324     if (!rootGraphicsLayer)
     324    if (!rootTextureMapperNode || !textureMapper)
    325325        return;
    326326
     
    328328    textureMapper->setImageInterpolationQuality(context->imageInterpolationQuality());
    329329    textureMapper->setTextDrawingMode(context->textDrawingMode());
     330    textureMapper->setViewportSize(frame->view()->frameRect().size());
    330331    QPainter* painter = context->platformContext();
    331     FrameView* view = frame->view();
    332     painter->save();
    333     painter->beginNativePainting();
    334     TextureMapperContentLayer::PaintOptions options;
    335     options.visibleRect = clip;
    336     options.targetRect = view->frameRect();
    337     options.viewportSize = view->size();
    338     options.opacity = painter->opacity();
    339     rootGraphicsLayer->paint(textureMapper.get(), options);
    340     painter->endNativePainting();
    341     painter->restore();
     332    const QTransform transform = painter->worldTransform();
     333    const TransformationMatrix matrix(
     334                transform.m11(), transform.m12(), 0, transform.m13(),
     335                transform.m21(), transform.m22(), 0, transform.m23(),
     336                0, 0, 1, 0,
     337                transform.m31(), transform.m32(), 0, transform.m33()
     338                );
     339    rootTextureMapperNode->setTransform(matrix);
     340    rootTextureMapperNode->setOpacity(painter->opacity());
     341    textureMapper->beginPainting();
     342    textureMapper->beginClip(matrix, clip);
     343    rootTextureMapperNode->paint();
     344    textureMapper->endClip();
     345    textureMapper->endPainting();
    342346}
    343347#endif
  • trunk/Source/WebKit/qt/Api/qwebframe.h

    r83512 r86276  
    5757    class FrameLoaderClientQt;
    5858    class ChromeClientQt;
    59     class PlatformLayerProxyQt;
     59    class TextureMapperNodeClientQt;
    6060}
    6161class QWebFrameData;
     
    233233    friend class WebCore::FrameLoaderClientQt;
    234234    friend class WebCore::ChromeClientQt;
    235     friend class WebCore::PlatformLayerProxyQt;
     235    friend class WebCore::TextureMapperNodeClientQt;
    236236    QWebFramePrivate *d;
    237237    Q_PRIVATE_SLOT(d, void _q_orientationChanged())
  • trunk/Source/WebKit/qt/Api/qwebframe_p.h

    r83512 r86276  
    4747    class HTMLFrameOwnerElement;
    4848    class Scrollbar;
    49     class TextureMapperContentLayer;
     49    class TextureMapperNode;
    5050}
    5151class QWebPage;
     
    8383        , marginHeight(-1)
    8484#if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER)
    85         , rootGraphicsLayer(0)
     85        , rootTextureMapperNode(0)
    8686#endif
    8787        {}
     
    121121    int marginHeight;
    122122#if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER)
    123     WebCore::TextureMapperContentLayer* rootGraphicsLayer;
     123    WebCore::TextureMapperNode* rootTextureMapperNode;
    124124    OwnPtr<WebCore::TextureMapper> textureMapper;
    125125#endif
  • trunk/Source/WebKit/qt/ChangeLog

    r86268 r86276  
     12011-05-11  Noam Rosenthal  <noam.rosenthal@nokia.com>
     2
     3        Reviewed by Kenneth Rohde Christiansen.
     4
     5        [Texmap][Qt] Upstream texture-mapper changes from Qt's WebKit2 branch
     6        https://bugs.webkit.org/show_bug.cgi?id=60439
     7
     8        Patch 10/12: Glue the TextureMapper refactoring into Webkit(1).
     9        1. Pass a GraphicsLayer* instead of a PlatformLayer* to the QWebPageClient.
     10        2. Set parameters in TextureMapper/TextureMapperNode instead of passing them in an options argument.
     11        3. Rename PlatformLayerProxyQt to TextureMapperNodeClient
     12
     13        * Api/qwebframe.cpp:
     14        (QWebFramePrivate::renderCompositedLayers):
     15        * Api/qwebframe.h:
     16        * Api/qwebframe_p.h:
     17        (QWebFramePrivate::QWebFramePrivate):
     18        * WebCoreSupport/ChromeClientQt.cpp:
     19        (WebCore::ChromeClientQt::attachRootGraphicsLayer):
     20        * WebCoreSupport/PageClientQt.cpp:
     21        (WebCore::TextureMapperNodeClientQt::TextureMapperNodeClientQt):
     22        (WebCore::TextureMapperNodeClientQt::scroll):
     23        (WebCore::TextureMapperNodeClientQt::setTextureMapper):
     24        (WebCore::TextureMapperNodeClientQt::~TextureMapperNodeClientQt):
     25        (WebCore::TextureMapperNodeClientQt::computeLastModifiedRect):
     26        (WebCore::TextureMapperNodeClientQt::syncRootLayer):
     27        (WebCore::TextureMapperNodeClientQt::rootNode):
     28        (WebCore::PageClientQWidget::setRootGraphicsLayer):
     29        (WebCore::PageClientQWidget::syncLayers):
     30        (WebCore::PageClientQWidget::~PageClientQWidget):
     31        (WebCore::PageClientQGraphicsWidget::~PageClientQGraphicsWidget):
     32        (WebCore::PageClientQGraphicsWidget::update):
     33        (WebCore::PageClientQGraphicsWidget::syncLayers):
     34        (WebCore::PageClientQGraphicsWidget::setRootGraphicsLayer):
     35        (WebCore::PageClientQGraphicsWidget::markForSync):
     36        * WebCoreSupport/PageClientQt.h:
     37        (WebCore::PageClientQWidget::PageClientQWidget):
     38        (WebCore::PageClientQGraphicsWidget::PageClientQGraphicsWidget):
     39        (WebCore::PageClientQGraphicsWidget::syncLayersTimeout):
     40
     41
    1422011-05-11  Noam Rosenthal  <noam.rosenthal@nokia.com>
    243
  • trunk/Source/WebKit/qt/WebCoreSupport/ChromeClientQt.cpp

    r83473 r86276  
    622622{
    623623    if (platformPageClient())
    624         platformPageClient()->setRootGraphicsLayer(graphicsLayer ? graphicsLayer->platformLayer() : 0);
     624        platformPageClient()->setRootGraphicsLayer(graphicsLayer);
    625625}
    626626
  • trunk/Source/WebKit/qt/WebCoreSupport/PageClientQt.cpp

    r76196 r86276  
    2020
    2121#include "config.h"
    22 
    2322#include "PageClientQt.h"
    24 #include "TextureMapperQt.h"
    25 #include "texmap/TextureMapperPlatformLayer.h"
     23
    2624#include <QGraphicsScene>
    2725#include <QGraphicsView>
     
    3028#endif
    3129
     30#if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER)
     31#include "TextureMapperQt.h"
     32#include "texmap/TextureMapperNode.h"
     33
    3234#ifdef QT_OPENGL_LIB
    3335#include "opengl/TextureMapperGL.h"
    34 #include <QGLWidget>
     36#endif
    3537#endif
    3638
    3739namespace WebCore {
    3840
    39 #if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER)   
    40 class PlatformLayerProxyQt : public QObject, public virtual TextureMapperLayerClient {
    41 public:
    42     PlatformLayerProxyQt(QWebFrame* frame, TextureMapperContentLayer* layer, QObject* object)
    43         : QObject(object)
    44         , m_frame(frame)
    45         , m_layer(layer)
    46     {
    47         if (m_layer)
    48             m_layer->setPlatformLayerClient(this);
    49         m_frame->d->rootGraphicsLayer = m_layer;
    50     }
    51 
    52     void setTextureMapper(PassOwnPtr<TextureMapper> textureMapper)
    53     {
    54         m_frame->d->textureMapper = textureMapper;
    55     }
    56 
    57     virtual ~PlatformLayerProxyQt()
    58     {
    59         if (m_layer)
    60             m_layer->setPlatformLayerClient(0);
    61         if (m_frame->d)
    62             m_frame->d->rootGraphicsLayer = 0;
    63     }
    64 
    65     virtual TextureMapper* textureMapper()
    66     {
    67         return m_frame->d->textureMapper.get();
    68     }
    69 
    70     // Since we just paint the composited tree and never create a special item for it, we don't have to handle its size changes.
    71     void setSizeChanged(const IntSize&) { }
    72 
    73 private:
    74     QWebFrame* m_frame;
    75     TextureMapperContentLayer* m_layer;
    76 };
    77 
    78 class PlatformLayerProxyQWidget : public PlatformLayerProxyQt {
    79 public:
    80     PlatformLayerProxyQWidget(QWebFrame* frame, TextureMapperContentLayer* layer, QWidget* widget)
    81         : PlatformLayerProxyQt(frame, layer, widget)
    82         , m_widget(widget)
    83     {
    84         if (m_widget)
    85             m_widget->installEventFilter(this);
    86 
    87         if (textureMapper())
    88             return;
    89 
    90         setTextureMapper(TextureMapperQt::create());
    91     }
    92 
    93     // We don't want a huge region-clip on the compositing layers; instead we unite the rectangles together
    94     // and clear them when the paint actually occurs.
    95     bool eventFilter(QObject* object, QEvent* event)
    96     {
    97         if (object == m_widget && event->type() == QEvent::Paint)
    98             m_dirtyRect = QRect();
    99         return QObject::eventFilter(object, event);
    100     }
    101 
    102     void setNeedsDisplay()
    103     {
    104         if (m_widget)
    105             m_widget->update();
    106     }
    107 
    108     void setNeedsDisplayInRect(const IntRect& rect)
    109     {
    110         m_dirtyRect |= rect;
    111         m_widget->update(m_dirtyRect);
    112     }
    113 
    114 private:
    115     QRect m_dirtyRect;
    116     QWidget* m_widget;
    117 };
    118 
    119 #if !defined(QT_NO_GRAPHICSVIEW)
    120 class PlatformLayerProxyQGraphicsObject : public PlatformLayerProxyQt {
    121 public:
    122     PlatformLayerProxyQGraphicsObject(QWebFrame* frame, TextureMapperContentLayer* layer, QGraphicsObject* object)
    123         : PlatformLayerProxyQt(frame, layer, object)
    124         , m_graphicsItem(object)
    125     {
    126         if (textureMapper())
    127             return;
    128 
    129 #ifdef QT_OPENGL_LIB
    130         QGraphicsView* view = object->scene()->views()[0];
    131         if (view && view->viewport() && view->viewport()->inherits("QGLWidget")) {
    132             setTextureMapper(TextureMapperGL::create());
    133             return;
    134         }
    135 #endif
    136         setTextureMapper(TextureMapperQt::create());
    137     }
    138 
    139     void setNeedsDisplay()
    140     {
    141         if (m_graphicsItem)
    142             m_graphicsItem->update();
    143     }
    144 
    145     void setNeedsDisplayInRect(const IntRect& rect)
    146     {
    147         if (m_graphicsItem)
    148             m_graphicsItem->update(QRectF(rect));
    149     }
    150 
    151 private:
    152     QGraphicsItem* m_graphicsItem;
    153 };
    154 #endif // QT_NO_GRAPHICSVIEW
    155 
    156 void PageClientQWidget::setRootGraphicsLayer(TextureMapperPlatformLayer* layer)
     41#if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER)
     42TextureMapperNodeClientQt::TextureMapperNodeClientQt(QWebFrame* frame, GraphicsLayer* layer)
     43    : m_frame(frame)
     44    , m_rootGraphicsLayer(GraphicsLayer::create(0))
     45{
     46    m_frame->d->rootTextureMapperNode = rootNode();
     47    m_rootGraphicsLayer->addChild(layer);
     48    m_rootGraphicsLayer->setDrawsContent(false);
     49    m_rootGraphicsLayer->setMasksToBounds(false);
     50    m_rootGraphicsLayer->setSize(IntSize(1, 1));
     51}
     52
     53void TextureMapperNodeClientQt::setTextureMapper(const PassOwnPtr<TextureMapper>& textureMapper)
     54{
     55    m_frame->d->textureMapper = textureMapper;
     56    m_frame->d->rootTextureMapperNode->setTextureMapper(m_frame->d->textureMapper.get());
     57}
     58
     59TextureMapperNodeClientQt::~TextureMapperNodeClientQt()
     60{
     61    m_frame->d->rootTextureMapperNode = 0;
     62}
     63
     64void TextureMapperNodeClientQt::syncRootLayer()
     65{
     66    m_rootGraphicsLayer->syncCompositingStateForThisLayerOnly();
     67}
     68
     69TextureMapperNode* TextureMapperNodeClientQt::rootNode()
     70{
     71    return toTextureMapperNode(m_rootGraphicsLayer.get());
     72}
     73
     74
     75void PageClientQWidget::setRootGraphicsLayer(GraphicsLayer* layer)
    15776{
    15877    if (layer) {
    159         platformLayerProxy = new PlatformLayerProxyQWidget(page->mainFrame(), static_cast<TextureMapperContentLayer*>(layer), view);
    160         return;
    161     }
    162     delete platformLayerProxy;
    163     platformLayerProxy = 0;
     78        textureMapperNodeClient = adoptPtr(new TextureMapperNodeClientQt(page->mainFrame(), layer));
     79        textureMapperNodeClient->setTextureMapper(new TextureMapperQt);
     80        textureMapperNodeClient->syncRootLayer();
     81        return;
     82    }
     83    textureMapperNodeClient.clear();
    16484}
    16585
     
    17191void PageClientQWidget::syncLayers(Timer<PageClientQWidget>*)
    17292{
     93    if (textureMapperNodeClient)
     94        textureMapperNodeClient->syncRootLayer();
    17395    QWebFramePrivate::core(page->mainFrame())->view()->syncCompositingStateIncludingSubframes();
     96    if (!textureMapperNodeClient)
     97        return;
     98    if (textureMapperNodeClient->rootNode()->descendantsOrSelfHaveRunningAnimations())
     99        syncTimer.startOneShot(1.0 / 60.0);
     100    update(view->rect());
    174101}
    175102#endif
     
    202129PageClientQWidget::~PageClientQWidget()
    203130{
    204 #if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER)
    205     delete platformLayerProxy;
    206 #endif
    207131}
    208132
     
    261185{
    262186    delete overlay;
    263 #if USE(ACCELERATED_COMPOSITING)
    264 #if USE(TEXTURE_MAPPER)
    265     delete platformLayerProxy;
    266 #else
     187#if USE(ACCELERATED_COMPOSITING) && !USE(TEXTURE_MAPPER)
    267188    if (!rootGraphicsLayer)
    268189        return;
     
    271192    view->scene()->removeItem(rootGraphicsLayer.data());
    272193#endif
    273 #endif
    274194}
    275195
     
    286206    if (overlay)
    287207        overlay->update(QRectF(dirtyRect));
    288 #if USE(ACCELERATED_COMPOSITING)
     208#if USE(ACCELERATED_COMPOSITING) && !USE(TEXTURE_MAPPER)
    289209    syncLayers();
    290210#endif
     
    321241void PageClientQGraphicsWidget::syncLayers()
    322242{
    323     if (shouldSync) {
    324         QWebFramePrivate::core(page->mainFrame())->view()->syncCompositingStateIncludingSubframes();
    325         shouldSync = false;
    326     }
    327 }
    328 
    329243#if USE(TEXTURE_MAPPER)
    330 void PageClientQGraphicsWidget::setRootGraphicsLayer(TextureMapperPlatformLayer* layer)
     244    if (textureMapperNodeClient)
     245        textureMapperNodeClient->syncRootLayer();
     246#endif
     247
     248    QWebFramePrivate::core(page->mainFrame())->view()->syncCompositingStateIncludingSubframes();
     249
     250#if USE(TEXTURE_MAPPER)
     251    if (!textureMapperNodeClient)
     252        return;
     253
     254    if (textureMapperNodeClient->rootNode()->descendantsOrSelfHaveRunningAnimations())
     255        syncTimer.startOneShot(1.0 / 60.0);
     256    update(view->boundingRect().toAlignedRect());
     257    if (!shouldSync)
     258        return;
     259    shouldSync = false;
     260#endif
     261}
     262
     263#if USE(TEXTURE_MAPPER)
     264void PageClientQGraphicsWidget::setRootGraphicsLayer(GraphicsLayer* layer)
    331265{
    332266    if (layer) {
    333         platformLayerProxy = new PlatformLayerProxyQGraphicsObject(page->mainFrame(), static_cast<TextureMapperContentLayer*>(layer), view);
    334         return;
    335     }
    336     delete platformLayerProxy;
    337     platformLayerProxy = 0;
     267        textureMapperNodeClient = adoptPtr(new TextureMapperNodeClientQt(page->mainFrame(), layer));
     268#ifdef QT_OPENGL_LIB
     269        QGraphicsView* graphicsView = view->scene()->views()[0];
     270        if (graphicsView && graphicsView->viewport() && graphicsView->viewport()->inherits("QGLWidget")) {
     271            textureMapperNodeClient->setTextureMapper(TextureMapperGL::create());
     272            return;
     273        }
     274#endif
     275        textureMapperNodeClient->setTextureMapper(TextureMapperQt::create());
     276        return;
     277    }
     278    textureMapperNodeClient.clear();
    338279}
    339280#else
    340 void PageClientQGraphicsWidget::setRootGraphicsLayer(QGraphicsObject* layer)
     281void PageClientQGraphicsWidget::setRootGraphicsLayer(GraphicsLayer* layer)
    341282{
    342283    if (rootGraphicsLayer) {
     
    346287    }
    347288
    348     rootGraphicsLayer = layer;
    349 
    350     if (layer) {
    351         layer->setFlag(QGraphicsItem::ItemClipsChildrenToShape, true);
    352         layer->setParentItem(view);
    353         layer->setZValue(RootGraphicsLayerZValue);
     289    rootGraphicsLayer = layer ? layer->platformLayer() : 0;
     290
     291    if (rootGraphicsLayer) {
     292        rootGraphicsLayer.data()->setFlag(QGraphicsItem::ItemClipsChildrenToShape, true);
     293        rootGraphicsLayer.data()->setParentItem(view);
     294        rootGraphicsLayer.data()->setZValue(RootGraphicsLayerZValue);
    354295    }
    355296    createOrDeleteOverlay();
     
    360301{
    361302    shouldSync = true;
    362     if (scheduleSync)
    363         syncMetaMethod.invoke(view, Qt::QueuedConnection);
     303    syncTimer.startOneShot(0);
    364304}
    365305
  • trunk/Source/WebKit/qt/WebCoreSupport/PageClientQt.h

    r75870 r86276  
    4242#include <Settings.h>
    4343
    44 #if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER)
    45 #include "texmap/TextureMapperPlatformLayer.h"
    46 #endif
    47 
    4844namespace WebCore {
     45
     46#if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER)
     47class TextureMapperNodeClientQt {
     48public:
     49    TextureMapperNodeClientQt(QWebFrame*, GraphicsLayer*);
     50    virtual ~TextureMapperNodeClientQt();
     51    void setTextureMapper(const PassOwnPtr<TextureMapper>&);
     52    void syncRootLayer();
     53    TextureMapperNode* rootNode();
     54
     55private:
     56    QWebFrame* m_frame;
     57    OwnPtr<GraphicsLayer> m_rootGraphicsLayer;
     58};
     59#endif
    4960
    5061class PageClientQWidget : public QWebPageClient {
     
    5566#if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER)
    5667        , syncTimer(this, &PageClientQWidget::syncLayers)
    57         , platformLayerProxy(0)
    5868#endif
    5969    {
     
    92102
    93103#if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER)
    94     virtual void setRootGraphicsLayer(TextureMapperPlatformLayer* layer);
     104    virtual void setRootGraphicsLayer(GraphicsLayer*);
    95105    virtual void markForSync(bool scheduleSync);
    96106    void syncLayers(Timer<PageClientQWidget>*);
     
    105115#if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER)
    106116    Timer<PageClientQWidget> syncTimer;
    107     PlatformLayerProxyQt* platformLayerProxy;
     117    OwnPtr<TextureMapperNodeClientQt> textureMapperNodeClient;
    108118#endif
    109119};
     
    151161        , viewResizesToContents(false)
    152162#if USE(ACCELERATED_COMPOSITING)
    153 #if USE(TEXTURE_MAPPER)
    154         , platformLayerProxy(0)
    155 #endif
     163        , syncTimer(this, &PageClientQGraphicsWidget::syncLayersTimeout)
    156164        , shouldSync(false)
    157165#endif
     
    163171        // this QGraphicsWebView as the scrollbars are needed when there's no compositing
    164172        view->setFlag(QGraphicsItem::ItemUsesExtendedStyleOption);
    165         syncMetaMethod = view->metaObject()->method(view->metaObject()->indexOfMethod("syncLayers()"));
    166173#endif
    167174    }
     
    201208
    202209#if USE(ACCELERATED_COMPOSITING)
    203     virtual void setRootGraphicsLayer(PlatformLayer* layer);
     210    virtual void setRootGraphicsLayer(GraphicsLayer*);
    204211    virtual void markForSync(bool scheduleSync);
    205212    void syncLayers();
     213    void syncLayersTimeout(Timer<PageClientQGraphicsWidget>*) { syncLayers(); }
    206214
    207215    // QGraphicsWebView can render composited layers
     
    217225#if USE(ACCELERATED_COMPOSITING)
    218226#if USE(TEXTURE_MAPPER)
    219     PlatformLayerProxyQt* platformLayerProxy;
     227    OwnPtr<TextureMapperNodeClientQt> textureMapperNodeClient;
    220228#else
    221229    QWeakPointer<QGraphicsObject> rootGraphicsLayer;
    222230#endif
    223231    // we have to flush quite often, so we use a meta-method instead of QTimer::singleShot for putting the event in the queue
    224     QMetaMethod syncMetaMethod;
     232    Timer<PageClientQGraphicsWidget> syncTimer;
    225233
    226234    // we need to sync the layers if we get a special call from the WebCore
Note: See TracChangeset for help on using the changeset viewer.