[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc

noam.rosenthal at nokia.com noam.rosenthal at nokia.com
Wed Dec 22 15:34:34 UTC 2010


The following commit has been merged in the debian/experimental branch:
commit 3a8def298f180d932d20ea0e8af9b3ea0b262ab4
Author: noam.rosenthal at nokia.com <noam.rosenthal at nokia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Mon Nov 8 18:04:58 2010 +0000

    [Texmap] [Qt] Texture mapper initial implementation
    https://bugs.webkit.org/show_bug.cgi?id=47070
    
    Reviewed by Kenneth Rohde Christiansen.
    
    WebCore:
    
    Make the necessary changes in TextureMapperNode in preparation of making it possible to paint it
    from a different thread.
    The main problematic part was the cache, which made it so that textures can become invalid and have to
    be rerendered from content during paint. This is solved here by creating a pack/unpack function for
    textures, which lets a texture archive its data away from video memory, or do whatever the platform
    thinks is right for freeing memory without needing to re-render again from content (which cannot be
    made thread safe).
    
    After this change, TextureMapperNode moved to its own file, and has 2 entry points: paint and syncCompositingState.
    The idea is that syncCompositingState has to be called in the UI thread, paint can be called from a different
    thread, and they should block each other.
    
    The new test tests the cache code-path, to show that the pack/unpack technique works for cases where it
    kicks in.
    
    Test: compositing/layer-creation/many-layers.html
    
    * WebCore.pro:
    * platform/graphics/opengl/TextureMapperGL.cpp:
    (WebCore::BitmapTextureGL::~BitmapTextureGL):
    (WebCore::BitmapTextureGL::BitmapTextureGL):
    (WebCore::TextureMapperGL::TextureMapperGL):
    (WebCore::TextureMapperGL::drawTexture):
    * platform/graphics/opengl/TextureMapperGL.h:
    (WebCore::TextureMapperGL::create):
    * platform/graphics/qt/TextureMapperQt.cpp:
    (WebCore::BitmapTextureQt::pack):
    (WebCore::BitmapTextureQt::unpack):
    (WebCore::TextureMapper::create):
    (WebCore::BitmapTextureQt::BitmapTextureQt):
    * platform/graphics/qt/TextureMapperQt.h: Added.
    
    WebKit/qt:
    
    Reorganized the textureMapper to be a member of QWebFramePrivate, to help with making
    TextureMapper thread-safe.
    
    * Api/qwebframe.cpp:
    (QWebFramePrivate::renderCompositedLayers):
    * Api/qwebframe_p.h:
    * WebCoreSupport/PageClientQt.cpp:
    (WebCore::PlatformLayerProxyQt::setTextureMapper):
    (WebCore::PlatformLayerProxyQt::textureMapper):
    (WebCore::PlatformLayerProxyQWidget::PlatformLayerProxyQWidget):
    (WebCore::PlatformLayerProxyQGraphicsObject::PlatformLayerProxyQGraphicsObject):
    
    LayoutTests:
    
    Added a test that includes several composited layers, containing pixel data that's larger
    than 24MB, which is the default value for TextureMapper's cache. This tests the video memory
    ceiling functionality of TextureMapper, as purging that cache would kick in whe running this test.
    
    * compositing/layer-creation/many-layers.html: Added.
    
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@71538 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 216d83c..bedd91a 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,16 @@
+2010-11-08  Noam Rosenthal  <noam.rosenthal at nokia.com>
+
+        Reviewed by Kenneth Rohde Christiansen.
+
+        [Texmap] [Qt] Texture mapper initial implementation
+        https://bugs.webkit.org/show_bug.cgi?id=47070
+
+        Added a test that includes several composited layers, containing pixel data that's larger
+        than 24MB, which is the default value for TextureMapper's cache. This tests the video memory
+        ceiling functionality of TextureMapper, as purging that cache would kick in whe running this test.
+
+        * compositing/layer-creation/many-layers.html: Added.
+
 2010-11-08  Tony Chang  <tony at chromium.org>
 
         Reviewed by Adam Barth.
diff --git a/LayoutTests/compositing/layer-creation/many-layers.html b/LayoutTests/compositing/layer-creation/many-layers.html
new file mode 100644
index 0000000..782e8d6
--- /dev/null
+++ b/LayoutTests/compositing/layer-creation/many-layers.html
@@ -0,0 +1,81 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+   "http://www.w3.org/TR/html4/loose.dtd">
+
+<html lang="en">
+<head>
+  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+  <title>untitled</title>
+  <style type="text/css" media="screen">
+
+    .tile {
+        -webkit-transform: translateZ(0);
+        width: 1024px;
+        height: 1024px;
+        background-color: green;
+        position: absolute;
+        opacity: 0.1;
+    }
+    
+    #red { 
+        background-color: red;
+        position: absolute;
+        left: 0px;
+        top: 0px;
+        width: 800px;
+        height: 600px;
+    }
+
+    #container td {
+        width: 50px;
+    }
+    
+  </style>
+</head>
+<body>
+    <div id="tester">
+    </div>
+    <table id="container">
+        <tr>
+            <td>
+                <div class="tile">
+            </td>
+            <td>
+                <div class="tile">
+            </td>
+            <td>
+                <div class="tile">
+            </td>
+            <td>
+                <div class="tile">
+            </td>
+            <td>
+                <div class="tile">
+            </td>
+            <td>
+                <div class="tile">
+            </td>
+            <td>
+                <div class="tile">
+            </td>
+            <td>
+                <div class="tile">
+            </td>
+            <td>
+                <div class="tile">
+            </td>
+            <td>
+                <div class="tile">
+            </td>
+            <td>
+                <div class="tile">
+            </td>
+            <td>
+                <div class="tile">
+            </td>
+            <td>
+                <div class="tile">
+            </td>
+        </tr>
+    </table>
+</body>
+</html>
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 129ce69..9c4dab4 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,42 @@
+2010-11-08  Noam Rosenthal  <noam.rosenthal at nokia.com>
+
+        Reviewed by Kenneth Rohde Christiansen.
+
+        [Texmap] [Qt] Texture mapper initial implementation
+        https://bugs.webkit.org/show_bug.cgi?id=47070
+
+        Make the necessary changes in TextureMapperNode in preparation of making it possible to paint it
+        from a different thread.
+        The main problematic part was the cache, which made it so that textures can become invalid and have to
+        be rerendered from content during paint. This is solved here by creating a pack/unpack function for
+        textures, which lets a texture archive its data away from video memory, or do whatever the platform
+        thinks is right for freeing memory without needing to re-render again from content (which cannot be
+        made thread safe).
+
+        After this change, TextureMapperNode moved to its own file, and has 2 entry points: paint and syncCompositingState.
+        The idea is that syncCompositingState has to be called in the UI thread, paint can be called from a different
+        thread, and they should block each other.
+
+        The new test tests the cache code-path, to show that the pack/unpack technique works for cases where it
+        kicks in.
+
+        Test: compositing/layer-creation/many-layers.html
+
+        * WebCore.pro:
+        * platform/graphics/opengl/TextureMapperGL.cpp:
+        (WebCore::BitmapTextureGL::~BitmapTextureGL):
+        (WebCore::BitmapTextureGL::BitmapTextureGL):
+        (WebCore::TextureMapperGL::TextureMapperGL):
+        (WebCore::TextureMapperGL::drawTexture):
+        * platform/graphics/opengl/TextureMapperGL.h:
+        (WebCore::TextureMapperGL::create):
+        * platform/graphics/qt/TextureMapperQt.cpp:
+        (WebCore::BitmapTextureQt::pack):
+        (WebCore::BitmapTextureQt::unpack):
+        (WebCore::TextureMapper::create):
+        (WebCore::BitmapTextureQt::BitmapTextureQt):
+        * platform/graphics/qt/TextureMapperQt.h: Added.
+
 2010-11-08  Simon Fraser  <simon.fraser at apple.com>
 
         Reviewed by Sam Weinig.
diff --git a/WebCore/WebCore.pro b/WebCore/WebCore.pro
index 3d30aa6..7a98a1f 100644
--- a/WebCore/WebCore.pro
+++ b/WebCore/WebCore.pro
@@ -3857,11 +3857,15 @@ win32:!win32-g++*:contains(QMAKE_HOST.arch, x86_64):{
 contains(CONFIG, texmap) {
     DEFINES += WTF_USE_TEXTURE_MAPPER=1
     HEADERS += \
+        platform/graphics/qt/TextureMapperQt.h \
+        platform/graphics/texmap/GraphicsLayerTextureMapper.h \
         platform/graphics/texmap/TextureMapper.h \
+        platform/graphics/texmap/TextureMapperNode.h \
         platform/graphics/texmap/TextureMapperPlatformLayer.h
 
     SOURCES += \
         platform/graphics/qt/TextureMapperQt.cpp \
+        platform/graphics/texmap/TextureMapperNode.cpp \
         platform/graphics/texmap/GraphicsLayerTextureMapper.cpp
 
     contains(QT_CONFIG, opengl) {
diff --git a/WebCore/platform/graphics/opengl/TextureMapperGL.cpp b/WebCore/platform/graphics/opengl/TextureMapperGL.cpp
index 41bcfc4..03f9b7c 100644
--- a/WebCore/platform/graphics/opengl/TextureMapperGL.cpp
+++ b/WebCore/platform/graphics/opengl/TextureMapperGL.cpp
@@ -229,6 +229,7 @@ public:
     virtual PlatformGraphicsContext* beginPaint(const IntRect& dirtyRect);
     virtual void endPaint();
     virtual void setContentsToImage(Image*);
+    ~BitmapTextureGL() { destroy(); }
 
 private:
     GLuint m_id;
@@ -241,13 +242,14 @@ private:
     GLuint m_fbo;
     IntSize m_actualSize;
     bool m_surfaceNeedsReset;
-    RefPtr<TextureMapperGL> m_textureMapper;
+    TextureMapperGL* m_textureMapper;
     BitmapTextureGL()
         : m_id(0)
         , m_image(0)
         , m_opaque(false)
         , m_fbo(0)
         , m_surfaceNeedsReset(true)
+        , m_textureMapper(0)
     {
     }
 
@@ -265,6 +267,7 @@ TextureMapperGL::TextureMapperGL()
     : m_data(new TextureMapperGLData)
 {
     static bool shadersCompiled = false;
+    obtainCurrentContext();
     if (shadersCompiled)
         return;
     shadersCompiled = true;
@@ -416,12 +419,11 @@ void TextureMapperGL::drawTexture(const BitmapTexture& texture, const IntRect& t
                                          0, maskTextureGL->m_relativeSize.height(), 0, 0,
                                          0, 0, 1, 0,
                                          0, 0, 0, 1};
-        glUniformMatrix4fv(programInfo.vars[TextureMapperGLData::ShaderInfo::InMaskMatrixVariable], 1, GL_FALSE, m4mask);
+        GL_CMD(glUniformMatrix4fv(programInfo.vars[TextureMapperGLData::ShaderInfo::InMaskMatrixVariable], 1, GL_FALSE, m4mask));
         GL_CMD(glUniform1i(programInfo.vars[TextureMapperGLData::ShaderInfo::MaskTextureVariable], 1))
         GL_CMD(glActiveTexture(GL_TEXTURE0))
     }
 
-
     if (textureGL.m_opaque && opacity > 0.99 && !maskTexture)
         GL_CMD(glDisable(GL_BLEND))
     else {
@@ -432,7 +434,6 @@ void TextureMapperGL::drawTexture(const BitmapTexture& texture, const IntRect& t
     GL_CMD(glDrawArrays(GL_TRIANGLE_FAN, 0, 4))
 }
 
-
 const char* TextureMapperGL::type() const
 {
     return "OpenGL";
diff --git a/WebCore/platform/graphics/opengl/TextureMapperGL.h b/WebCore/platform/graphics/opengl/TextureMapperGL.h
index d05601d..8035abf 100644
--- a/WebCore/platform/graphics/opengl/TextureMapperGL.h
+++ b/WebCore/platform/graphics/opengl/TextureMapperGL.h
@@ -47,6 +47,10 @@ public:
     virtual const char* type() const;
     void obtainCurrentContext();
     bool makeContextCurrent();
+    static PassOwnPtr<TextureMapperGL> create()
+    {
+        return new TextureMapperGL;
+    }
 
 private:
     inline TextureMapperGLData& data() { return *m_data; }
diff --git a/WebCore/platform/graphics/qt/TextureMapperQt.cpp b/WebCore/platform/graphics/qt/TextureMapperQt.cpp
index 1c3a1c7..6fdd7df 100644
--- a/WebCore/platform/graphics/qt/TextureMapperQt.cpp
+++ b/WebCore/platform/graphics/qt/TextureMapperQt.cpp
@@ -18,7 +18,7 @@
  */
 
 #include "config.h"
-#include "texmap/TextureMapper.h"
+#include "TextureMapperQt.h"
 
 #include <QtCore/qdebug.h>
 #include <QtGui/qpaintengine.h>
@@ -30,46 +30,6 @@
 
 namespace WebCore {
 
-class BitmapTextureQt : public BitmapTexture {
-    friend class TextureMapperQt;
-public:
-    BitmapTextureQt() {}
-    virtual void destroy();
-    virtual IntSize size() const { return IntSize(m_pixmap.width(), m_pixmap.height()); }
-    virtual void reset(const IntSize&, bool opaque);
-    virtual PlatformGraphicsContext* beginPaint(const IntRect& dirtyRect);
-    virtual void endPaint();
-    virtual void setContentsToImage(Image*);
-    virtual bool save(const String& path);
-    virtual bool isValid() const { return !m_pixmap.isNull(); }
-    virtual bool allowOfflineTextureUpload() const { return true; }
-    IntRect sourceRect() const { return IntRect(0, 0, contentSize().width(), contentSize().height()); }
-private:
-    QPainter m_painter;
-    QPixmap m_pixmap;
-};
-
-class TextureMapperQt : public TextureMapper {
-public:
-    virtual void drawTexture(const BitmapTexture& texture, const IntRect& targetRect, const TransformationMatrix& matrix, float opacity, const BitmapTexture* maskTexture);
-    virtual void bindSurface(BitmapTexture* surface);
-    virtual void setClip(const IntRect&);
-    virtual void setGraphicsContext(GraphicsContext*);
-    virtual bool allowSurfaceForRoot() const { return false; }
-    TextureMapperQt();
-    virtual const char* type() const { return "TextureMapperQt"; }
-    virtual PassRefPtr<BitmapTexture> createTexture();
-
-    static void initialize(QPainter* painter)
-    {
-        painter->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform, false);
-    }
-
-private:
-    QPainter* m_painter;
-    RefPtr<BitmapTextureQt> m_currentSurface;
-};
-
 void BitmapTextureQt::destroy()
 {
     if (m_pixmap.paintingActive())
@@ -118,6 +78,26 @@ void BitmapTextureQt::setContentsToImage(Image* image)
     m_pixmap = *pixmap;
 }
 
+void BitmapTextureQt::pack()
+{
+    if (m_pixmap.isNull())
+        return;
+
+    m_image = m_pixmap.toImage();
+    m_pixmap = QPixmap();
+    m_isPacked = true;
+}
+
+void BitmapTextureQt::unpack()
+{
+    m_isPacked = false;
+    if (m_image.isNull())
+        return;
+
+    m_pixmap = QPixmap::fromImage(m_image);
+    m_image = QImage();
+}
+
 void TextureMapperQt::setClip(const IntRect& rect)
 {
      QPainter* painter = m_currentSurface ? &m_currentSurface->m_painter : m_painter;
@@ -182,23 +162,26 @@ void TextureMapperQt::drawTexture(const BitmapTexture& texture, const IntRect& t
     painter->setOpacity(prevOpacity);
 }
 
-PassRefPtr<TextureMapper> TextureMapper::create(GraphicsContext* context)
+PassOwnPtr<TextureMapper> TextureMapper::create(GraphicsContext* context)
 {
 #ifdef QT_OPENGL_LIB
-    if (context->platformContext()->paintEngine()->type() == QPaintEngine::OpenGL2) {
-        TextureMapperGL* texmapGL = new TextureMapperGL;
-        return adoptRef(texmapGL);
-    }
+    if (context && context->platformContext()->paintEngine()->type() == QPaintEngine::OpenGL2)
+        return new TextureMapperGL;
 #endif
-    return adoptRef(new TextureMapperQt);
+    return new TextureMapperQt;
 }
 
-
 PassRefPtr<BitmapTexture> TextureMapperQt::createTexture()
 {
     return adoptRef(new BitmapTextureQt());
 }
 
+BitmapTextureQt::BitmapTextureQt()
+    : m_isPacked(false)
+{
+
+}
+
 #ifdef QT_OPENGL_LIB
 class RGBA32PremultimpliedBufferQt : public RGBA32PremultimpliedBuffer {
 public:
diff --git a/WebCore/platform/graphics/qt/TextureMapperQt.h b/WebCore/platform/graphics/qt/TextureMapperQt.h
new file mode 100644
index 0000000..e17b968
--- /dev/null
+++ b/WebCore/platform/graphics/qt/TextureMapperQt.h
@@ -0,0 +1,76 @@
+/*
+ Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB.  If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+ */
+
+#include "texmap/TextureMapper.h"
+
+#ifndef TextureMapperQt_h
+#define TextureMapperQt_h
+
+namespace WebCore {
+
+class BitmapTextureQt : public BitmapTexture {
+    friend class TextureMapperQt;
+public:
+    BitmapTextureQt();
+    ~BitmapTextureQt() { destroy(); }
+    virtual void destroy();
+    virtual IntSize size() const { return IntSize(m_pixmap.width(), m_pixmap.height()); }
+    virtual void reset(const IntSize&, bool opaque);
+    virtual PlatformGraphicsContext* beginPaint(const IntRect& dirtyRect);
+    virtual void endPaint();
+    virtual void setContentsToImage(Image*);
+    virtual bool save(const String& path);
+    virtual bool isValid() const { return !m_pixmap.isNull() || !m_image.isNull(); }
+    IntRect sourceRect() const { return IntRect(0, 0, contentSize().width(), contentSize().height()); }
+    virtual void pack();
+    virtual void unpack();
+    virtual bool isPacked() const { return m_isPacked; }
+
+private:
+    QPainter m_painter;
+    QPixmap m_pixmap;
+    QImage m_image;
+    bool m_isPacked;
+};
+
+class TextureMapperQt : public TextureMapper {
+public:
+    TextureMapperQt();
+
+    virtual void drawTexture(const BitmapTexture& texture, const IntRect& targetRect, const TransformationMatrix& matrix, float opacity, const BitmapTexture* maskTexture);
+    virtual void bindSurface(BitmapTexture* surface);
+    virtual void setClip(const IntRect&);
+    virtual void setGraphicsContext(GraphicsContext*);
+    virtual bool allowSurfaceForRoot() const { return false; }
+    virtual PassRefPtr<BitmapTexture> createTexture();
+
+    static void initialize(QPainter* painter)
+    {
+        painter->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform, false);
+    }
+
+    static PassOwnPtr<TextureMapper> create() { return new TextureMapperQt; }
+
+private:
+    QPainter* m_painter;
+    RefPtr<BitmapTextureQt> m_currentSurface;
+};
+
+}
+#endif
diff --git a/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.cpp b/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.cpp
index 54e6c7a..4698239 100644
--- a/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.cpp
+++ b/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.cpp
@@ -20,1072 +20,36 @@
 #include "config.h"
 #include "GraphicsLayerTextureMapper.h"
 
-#include "CurrentTime.h"
-#include "FloatRect.h"
-#include "GraphicsContext.h"
-#include "HashMap.h"
-#include "Image.h"
-#include "RefCounted.h"
-#include "TextureMapper.h"
-#include "TextureMapperPlatformLayer.h"
-#include "Timer.h"
-#include "TransformOperations.h"
-#include "TranslateTransformOperation.h"
-#include "UnitBezier.h"
-
-#define DEBUG_TEXMAP_FPS 0
+#include "TextureMapperNode.h"
 
 namespace WebCore {
 
-struct TexmapPaintOptions {
-    BitmapTexture* surface;
-    TextureMapper* textureMapper;
-    TextureMapperNode* rootLayer;
-    float opacity;
-    IntRect scissorRect;
-    IntRect visibleRect;
-    bool isSurface;
-};
-class TextureMapperCache {
-public:
-    void mark(BitmapTexture* texture);
-
-    class Entry {
-    public:
-        RefPtr<BitmapTexture> texture;
-        Entry() : previousCost(0) { }
-        inline int calculateCost() const
-        {
-            if (!texture || !texture->isValid())
-                return 0;
-            const IntSize textureSize = texture->size();
-            // an image's cost in bytes is width * height * bytes per pixel (4).
-            return textureSize.width() * textureSize.height() * 4;
-        }
-        Entry(BitmapTexture* newTexture)
-            : texture(newTexture)
-        {
-        }
-        bool operator==(const Entry& other) const { return texture == other.texture; }
-        int previousCost;
-    };
-
-    TextureMapperCache() : m_totalCost(0) {}
-
-    void purge();
-    Vector<Entry> m_data;
-    int m_totalCost;
-#ifndef TEXMAP_TEXTURE_CACHE_KBS
-#define TEXMAP_TEXTURE_CACHE_KBS 24 * 1024
-#endif
-    static const int MaxCost = TEXMAP_TEXTURE_CACHE_KBS * 1024;
-    static const int PurgeAmount = MaxCost / 4;
-};
-
-
-void TextureMapperCache::purge()
-{
-    // If this is in the GL implementation, we need an active GL context, because we might call glDeleteTextures.
-    const int size = m_data.size();
-
-    if (m_totalCost <= TextureMapperCache::MaxCost)
-        return;
-
-    // Ensure that we have the right count. It might be inaccurate if content changed size.
-    // We only do this when we're actually ready to purge.
-    m_totalCost = 0;
-    for (int i = 0; i < size; ++i)
-        m_totalCost += m_data[i].calculateCost();
-
-    for (int i = size-1; i >= 0 && m_totalCost > TextureMapperCache::MaxCost - TextureMapperCache::PurgeAmount; --i) {
-        Entry& entry = m_data[i];
-        if (entry.texture->isLocked() || !entry.texture->isValid())
-            continue;
-        m_totalCost -= entry.previousCost;
-        entry.texture->destroy();
-        m_data.remove(i);
-    }
-}
-
-void TextureMapperCache::mark(BitmapTexture* texture)
-{
-    if (!texture || !texture->isValid())
-        return;
-
-    Entry entry(texture);
-    size_t index = m_data.find(entry);
-    if (!index)
-        return;
-
-    if (index < m_data.size()) 
-        m_data.remove(index);
-    const int cost = entry.calculateCost();
-    m_totalCost -= entry.previousCost;
-    m_totalCost += (entry.previousCost = cost);
-    m_data.prepend(entry);
-}
-
-TextureMapperCache gTextureMapperCache;
-
-class TextureMapperCacheLock {
-public:
-    TextureMapperCacheLock(BitmapTexture* texture) : m_texture(texture)
-    {
-        if (m_texture)
-            m_texture->lock();
-    }
-    ~TextureMapperCacheLock()
-    {
-        if (m_texture)
-            m_texture->unlock();
-    }
-
-private:
-    RefPtr<BitmapTexture> m_texture;
-};
-
-class TextureMapperNode : public TextureMapperContentLayer {
-
-public:
-    // This set of flags help us defer which properties of the layer have been
-    // modified by the compositor, so we can know what to look for in the next flush.
-    enum ChangeMask {
-        NoChanges =                 0,
-
-        ParentChange =              (1L << 0),
-        ChildrenChange =            (1L << 1),
-        MaskLayerChange =           (1L << 2),
-        PositionChange =            (1L << 3),
-
-        AnchorPointChange =         (1L << 4),
-        SizeChange  =               (1L << 5),
-        TransformChange =           (1L << 6),
-        ContentChange =             (1L << 7),
-
-        ContentsOrientationChange = (1L << 9),
-        OpacityChange =             (1L << 10),
-        ContentsRectChange =        (1L << 11),
-
-        Preserves3DChange =         (1L << 12),
-        MasksToBoundsChange =       (1L << 13),
-        DrawsContentChange =        (1L << 14),
-        ContentsOpaqueChange =      (1L << 15),
-
-        BackfaceVisibilityChange =  (1L << 16),
-        ChildrenTransformChange =   (1L << 17),
-        DisplayChange =             (1L << 18),
-        BackgroundColorChange =     (1L << 19),
-
-        ReplicaLayerChange =        (1L << 20)
-    };
-
-    // The compositor lets us special-case images and colors, so we try to do so.
-    enum StaticContentType { HTMLContentType, DirectImageContentType, ColorContentType, MediaContentType, Canvas3DContentType};
-
-    TextureMapperNode* rootLayer();
-
-    TextureMapperNode(GraphicsLayerTextureMapper* newLayer);
-    virtual ~TextureMapperNode();
-
-    void clearDirectImage();
-    void computeTransformations();
-    IntSize nearestSurfaceSize() const;
-    void computeReplicaTransform();
-    void computeLayerType();
-    void computeLocalTransform();
-    void flattenTo2DSpaceIfNecessary();
-    void initializeTextureMapper(TextureMapper*);
-    void invalidateTransform();
-    void notifyChange(ChangeMask);
-    void syncCompositingState(bool recurse);
-    void performPostSyncOperations();
-    void setNeedsDisplay();
-    void setNeedsDisplayInRect(IntRect);
-    virtual void cleanupTextureMapper();
-
-    void paintRecursive(TexmapPaintOptions options);
-    void paintSelf(const TexmapPaintOptions& options);
-    void uploadTextureFromContent(TextureMapper* textureMapper, const IntRect& visibleRect);
-
-    int countDescendantsWithContent() const;
-    bool hasSurfaceDescendants() const;
-
-    IntSize size() const { return m_size; }
-
-    virtual void setPlatformLayerClient(TextureMapperLayerClient*);
-    virtual void paint(TextureMapper*, const TextureMapperContentLayer::PaintOptions&);
-
-    static TextureMapperNode* toTextureMapperNode(GraphicsLayer*);
-public:
-    GraphicsLayerTextureMapper* m_layer;
-    const char* m_lastTextureMapperType;
-    RefPtr<TextureMapper> m_lastTextureMapper;
-    struct TransformData {
-        TransformationMatrix base, target, replica, forDescendants, perspective, local;
-        IntRect targetBoundingRect;
-        float centerZ;
-        bool dirty, localDirty, perspectiveDirty;
-        IntRect boundingRectFromRoot;
-        TransformData() : dirty(true), localDirty(true), perspectiveDirty(true) { }
-    };
-
-    TransformData m_transforms;
-
-    enum LayerType {
-        DefaultLayer,
-        RootLayer,
-        ScissorLayer,
-        ClipLayer,
-        TransparencyLayer
-    };
-
-    LayerType m_layerType;
-
-    struct ContentData {
-        IntRect needsDisplayRect;
-        bool needsDisplay;
-        Color backgroundColor;
-
-        StaticContentType contentType;
-        RefPtr<Image> image;
-        TextureMapperVideoLayer* media;
-
-        ContentData()
-            : needsDisplay(false)
-            , contentType(HTMLContentType)
-            , image(0)
-            , media(0)
-        {
-        }
-
-    };
-
-    inline IntRect targetRect() const
-    {
-        return m_currentContent.contentType == HTMLContentType ? entireRect() : m_state.contentsRect;
-    }
-
-    inline IntRect entireRect() const
-    {
-        return IntRect(0, 0, m_size.width(), m_size.height());
-    }
-
-    inline IntRect replicaRect() const
-    {
-        return m_layerType == TransparencyLayer ? IntRect(0, 0, m_nearestSurfaceSize.width(), m_nearestSurfaceSize.height()) : entireRect();
-    }
-
-    RefPtr<BitmapTexture> m_texture;
-    RefPtr<BitmapTexture> m_surface, m_replicaSurface;
-
-    ContentData m_pendingContent;
-    ContentData m_currentContent;
-
-    Vector<TextureMapperNode*> m_children;
-    TextureMapperNode* m_parent;
-    TextureMapperNode* m_effectTarget;
-    int m_changeMask;
-    IntSize m_size, m_nearestSurfaceSize;
-    String m_name;
-    TextureMapperLayerClient* m_platformClient;
-
-    struct State {
-        FloatPoint pos;
-        FloatPoint3D anchorPoint;
-        FloatSize size;
-        TransformationMatrix transform;
-        TransformationMatrix childrenTransform;
-        Color backgroundColor;
-        Color currentColor;
-        GraphicsLayer::CompositingCoordinatesOrientation geoOrientation;
-        GraphicsLayer::CompositingCoordinatesOrientation contentsOrientation;
-        float opacity;
-        IntRect contentsRect;
-        int descendantsWithContent;
-        TextureMapperNode* maskLayer;
-        TextureMapperNode* replicaLayer;
-        bool preserves3D;
-        bool masksToBounds;
-        bool drawsContent;
-        bool contentsOpaque;
-        bool backfaceVisibility;
-        bool visible;
-        bool dirty;
-        bool tiled;
-        bool hasSurfaceDescendants;
-
-        State()
-            : opacity(1.f)
-            , descendantsWithContent(0)
-            , maskLayer(0)
-            , replicaLayer(0)
-            , preserves3D(false)
-            , masksToBounds(false)
-            , drawsContent(false)
-            , contentsOpaque(false)
-            , backfaceVisibility(false)
-            , visible(true)
-            , dirty(true)
-            , tiled(false)
-            , hasSurfaceDescendants(false)
-        {
-        }
-    };
-    State m_state;
-};
-
-void TextureMapperNode::setNeedsDisplayInRect(IntRect rect)
-{
-    if (m_platformClient) {
-        if (m_state.hasSurfaceDescendants) {
-            m_platformClient->setNeedsDisplay();
-            return;
-        }
-        rect.intersect(IntRect(0, 0, m_size.width(), m_size.height()));
-        if (rect.isEmpty())
-            return;
-        m_platformClient->setNeedsDisplayInRect(rect);
-        return;
-    }
-
-    if (!m_parent)
-        return;
-
-    m_parent->setNeedsDisplayInRect(rect);
-}
-
-void TextureMapperNode::setNeedsDisplay()
-{
-    if (m_effectTarget)
-        m_effectTarget->setNeedsDisplay();
-    if (m_transforms.targetBoundingRect.isEmpty())
-        return;
-    if (m_state.drawsContent || m_currentContent.contentType != HTMLContentType)
-        setNeedsDisplayInRect(m_transforms.targetBoundingRect);
-}
-
-
-void TextureMapperNode::setPlatformLayerClient(TextureMapperLayerClient* client)
-{
-    m_platformClient = client;
-}
-
-static int compareGraphicsLayersZValue(const void* a, const void* b)
-{
-    typedef const TextureMapperNode* NodePtr;
-    const NodePtr* nodeA = static_cast<const NodePtr*>(a);
-    const NodePtr* nodeB = static_cast<const NodePtr*>(b);
-    return int(((*nodeA)->m_transforms.centerZ - (*nodeB)->m_transforms.centerZ) * 1000);
-}
-inline static void sortByZOrder(Vector<TextureMapperNode* >& array, int first, int last)
-{
-    qsort(array.data(), array.size(), sizeof(TextureMapperNode*), compareGraphicsLayersZValue);
-}
-
-bool TextureMapperNode::hasSurfaceDescendants() const
-{
-    if (m_layerType == ClipLayer || m_layerType == TransparencyLayer || m_state.replicaLayer)
-        return true;
-    const int size = m_children.size();
-    for (int i = 0; i < size; ++i) {
-        if (TextureMapperNode* child = m_children[i]) {
-            if (child->hasSurfaceDescendants())
-                return true;
-        }
-    }
-    return false;
-
-}
-
-void TextureMapperNode::paint(TextureMapper* textureMapper, const TextureMapperContentLayer::PaintOptions& options)
-{
-    ASSERT(m_layerType == RootLayer);
-    if (m_size.isEmpty())
-        return;
-
-#if 0
-    WTF::StopWatch stopWatch;
-    ("[TextureMapper] RootPaint!!\n");
-#endif
-
-    if (textureMapper->type() != m_lastTextureMapperType)
-        gTextureMapperCache.m_data.clear();
-
-    m_lastTextureMapper = textureMapper;
-    TexmapPaintOptions opt;
-    opt.opacity = 1;
-    opt.rootLayer = this;
-    opt.scissorRect = options.targetRect;
-    opt.visibleRect = options.visibleRect;
-    opt.textureMapper = textureMapper;
-    opt.surface = 0;
-    paintRecursive(opt);
-
-    if (textureMapper->allowSurfaceForRoot() || m_state.hasSurfaceDescendants) {
-        textureMapper->bindSurface(0);
-        textureMapper->paintToTarget(*m_surface.get(), options.viewportSize, options.transform, options.opacity * m_state.opacity, options.targetRect);
-    }
-    gTextureMapperCache.purge();
-}
-
-int TextureMapperNode::countDescendantsWithContent() const
-{
-    if (!m_state.visible || m_state.opacity < 0.001)
-        return 0;
-    int descendantsWithContent = (m_state.drawsContent || m_currentContent.contentType != HTMLContentType) ? 1 : 0;
-
-    const int size = m_children.size();
-    for (int i = 0; i < size; ++i) {
-        if (TextureMapperNode* child = m_children[i])
-            descendantsWithContent += child->countDescendantsWithContent();
-    }
-
-    return descendantsWithContent;
-}
-
-inline TextureMapperNode* TextureMapperNode::toTextureMapperNode(GraphicsLayer* layer)
-{
-    return layer ? static_cast<GraphicsLayerTextureMapper*>(layer)->m_node.get() : 0;
-}
-
-void TextureMapperNode::computeLayerType()
-{
-    // calculate layer type. A layer can be one of the following:
-    //  RootLayer: the top level. Draws to a framebuffer, and the target texture draws into the viewport.
-    //            only one layer is the root layer.
-    //  ScissorLayer: draws to the current framebuffer, and applies an extra scissor before drawing its children.
-    //                A scissor layer is a layer with children that masks to bounds, is not a transparency layer, and has a rectangular clip.
-    //  ClipLayer: creates a new framebuffer, the size of the layer, and then paints it to the enclosing BitmapTexture with the layer's transform/opacity.
-    //              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.
-    //  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.
-    //                     Used for layers with children and transparency/mask that preserve 3D or don't mask to bounds.
-    //  DefaultLayer: draws itself and its children directly to the current framebuffer.
-    //                any layer that doesn't conform to the other rules is a DefaultLayer.
-
-    const bool selfHasContent = m_state.drawsContent || (m_currentContent.contentType != HTMLContentType);
-    const bool hasDescendantsWithContent = m_state.descendantsWithContent - (selfHasContent ? 1 : 0);
-    const bool hasTransparency = m_state.opacity < 0.99 || m_state.maskLayer;
-    const bool hasReplica = m_state.replicaLayer;
-    m_layerType = DefaultLayer;
-
-    // Layer has no parent, it must be a root layer.
-    if (!m_parent && !m_effectTarget) {
-        m_layerType = RootLayer;
-        return;
-    }
-
-    // A layer with no contents is always a default layer.
-    if (!m_state.descendantsWithContent)
-        return;
-
-    // A layer with content-descendants and a mask is always a clip layer.
-    if (hasDescendantsWithContent && m_state.maskLayer) {
-        m_layerType = ClipLayer;
-        return;
-    }
-
-    // A masks-to bounds layer can be a clip or a scissor layer. It's a scissor layer only if it has a trivial clip (identity or translation), or if it has transparency.
-    // That's because a ClipLayer would create an intermediate drawing surface (FB) - we want to limit it to when it's actually necessary, i.e. transparency or non-trivial clip.
-    if (m_state.masksToBounds && hasDescendantsWithContent) {
-        if (hasTransparency || !m_state.transform.isIdentityOrTranslation() || m_parent->m_state.preserves3D)
-            m_layerType = ClipLayer;
-        else
-            m_layerType = ScissorLayer;
-        return;
-    }
-
-    // We use a transparency layer when we have two of the following 3: replica, transparency, descendants with contents.
-    if ((hasReplica && hasDescendantsWithContent) || (hasReplica && hasTransparency) || (hasTransparency && m_state.descendantsWithContent > 1))
-        m_layerType = TransparencyLayer;
-}
-void TextureMapperNode::initializeTextureMapper(TextureMapper* textureMapper)
-{
-    if (textureMapper->type() == m_lastTextureMapperType)
-        return;
-    m_surface = textureMapper->createTexture();
-    m_replicaSurface = textureMapper->createTexture();
-    m_texture = textureMapper->createTexture();
-    gTextureMapperCache.mark(m_texture.get());
-    m_lastTextureMapperType = textureMapper->type();
-}
-
-TextureMapperNode::TextureMapperNode(GraphicsLayerTextureMapper* newLayer)
-    : m_layer(newLayer)
-    , m_lastTextureMapperType(0)
-    , m_lastTextureMapper(0)
-    , m_layerType(DefaultLayer)
-    , m_surface(0)
-    , m_parent(0)
-    , m_effectTarget(0)
-    , m_changeMask(NoChanges)
-    , m_platformClient(0)
-{
-
-}
-
-TextureMapperNode* TextureMapperNode::rootLayer()
-{
-    if (m_effectTarget)
-        return m_effectTarget->rootLayer();
-    if (m_parent)
-        return m_parent->rootLayer();
-    return this;
-}
-
-void TextureMapperNode::invalidateTransform()
-{
-    m_transforms.dirty = true;
-    if (m_layerType != ClipLayer)
-        m_state.dirty = true;
-    if (m_state.replicaLayer)
-        m_state.replicaLayer->invalidateTransform();
-    const int size = m_children.size();
-    for (int i = 0; i < size; ++i) {
-        if (TextureMapperNode* layer = m_children[i])
-            layer->invalidateTransform();
-    }
-}
-
-void TextureMapperNode::computeLocalTransform()
-{
-    if (!m_transforms.localDirty)
-        return;
-    const float originX = m_state.anchorPoint.x() * m_size.width();
-    const float originY = m_state.anchorPoint.y() * m_size.height();
-    m_transforms.local =
-        TransformationMatrix()
-        .translate3d(originX + m_state.pos.x(), originY + m_state.pos.y(), m_state.anchorPoint.z())
-        .multLeft(m_state.transform)
-        .translate3d(-originX, -originY, -m_state.anchorPoint.z());
-    m_transforms.localDirty = false;
-}
-
-void TextureMapperNode::flattenTo2DSpaceIfNecessary()
-{
-    if (m_state.preserves3D)
-        return;
-    m_transforms.forDescendants.setM13(0);
-    m_transforms.forDescendants.setM23(0);
-    m_transforms.forDescendants.setM31(0);
-    m_transforms.forDescendants.setM32(0);
-    m_transforms.forDescendants.setM33(1);
-    m_transforms.forDescendants.setM34(0);
-    m_transforms.forDescendants.setM43(0);
-}
-
-IntSize TextureMapperNode::nearestSurfaceSize() const
-{
-    if (m_layerType == ClipLayer || m_layerType == RootLayer)
-        return m_surface && !m_surface->size().isEmpty() ? m_surface->size() : m_size;
-    return m_parent->nearestSurfaceSize();
-}
-
-void TextureMapperNode::computeReplicaTransform()
-{
-    if (!m_state.replicaLayer)
-        return;
-
-    m_nearestSurfaceSize = nearestSurfaceSize();
-
-    if (m_layerType != TransparencyLayer) {
-        m_transforms.replica = TransformationMatrix(m_transforms.target).multLeft(m_state.replicaLayer->m_transforms.local);
-        return;
-    }
-
-    const float originX = m_transforms.target.m41();
-    const float originY = m_transforms.target.m42();
-    m_transforms.replica =
-            TransformationMatrix()
-                .translate(originX, originY)
-                .multLeft(m_state.replicaLayer->m_transforms.local)
-                .translate(-originX, -originY);
-}
-
-void TextureMapperNode::computeTransformations()
-{
-    if (!m_transforms.dirty)
-        return;
-
-    m_transforms.dirty = false;
-    if ((m_size.isEmpty() && m_state.masksToBounds))
-        return;
-
-    TextureMapperNode* parent = m_parent;
-    computeLocalTransform();
-
-    m_transforms.target = TransformationMatrix(parent ? parent->m_transforms.forDescendants : TransformationMatrix()).multLeft(m_transforms.local);
-    m_transforms.forDescendants = (m_layerType == ClipLayer ? TransformationMatrix() : m_transforms.target);
-
-    if (m_effectTarget)
-        return;
-
-    m_transforms.targetBoundingRect = IntRect(m_transforms.target.mapRect(entireRect()));
-    if (m_state.replicaLayer)
-        m_state.replicaLayer->computeTransformations();
-
-    flattenTo2DSpaceIfNecessary();
-
-    if (!m_state.backfaceVisibility && m_transforms.target.inverse().m33() < 0) {
-        m_state.visible = false;
-        return;
-    }
-    m_state.visible = true;
-
-    if (parent && parent->m_state.preserves3D)
-        m_transforms.centerZ = m_transforms.target.mapPoint(FloatPoint3D(m_size.width() / 2, m_size.height() / 2, 0)).z();
-
-    if (!m_children.size())
-        return;
-
-    if (m_state.childrenTransform.isIdentity())
-        return;
-
-    const FloatPoint centerPoint = FloatPoint(m_size.width() / 2, m_size.height() / 2);
-    if (m_transforms.perspectiveDirty)
-        m_transforms.perspective = TransformationMatrix()
-            .translate(centerPoint.x(), centerPoint.y())
-            .multLeft(m_state.childrenTransform)
-            .translate(-centerPoint.x(), -centerPoint.y());
-    m_transforms.perspectiveDirty = false;
-    m_transforms.forDescendants.multLeft(m_transforms.perspective);
-}
-
-void TextureMapperNode::uploadTextureFromContent(TextureMapper* textureMapper, const IntRect& visibleRect)
-{
-    if (m_size.isEmpty() || !m_layer) {
-        m_texture->destroy();
-        return;
-    }
-
-    if (m_currentContent.contentType == DirectImageContentType) {
-        if (m_currentContent.image)
-            m_texture->setContentsToImage(m_currentContent.image.get());
-        return;
-    }
-
-    if (m_currentContent.contentType == MediaContentType) {
-        if (!m_currentContent.media)
-            return;
-        m_texture->reset(m_size, true);
-        PlatformGraphicsContext* platformContext = m_texture->beginPaintMedia();
-        GraphicsContext context(platformContext);
-        m_currentContent.media->paint(&context);
-        m_texture->endPaint();
-        return;
-    }
-
-    const bool needsReset = (m_texture->contentSize() != m_size) || !m_texture->isValid();
-    if ((m_currentContent.contentType != HTMLContentType)
-        || (!m_currentContent.needsDisplay && m_currentContent.needsDisplayRect.isEmpty() && !needsReset))
-        return;
-
-    IntRect dirtyRect = IntRect(0, 0, m_size.width(), m_size.height());
-    if (!needsReset && !m_currentContent.needsDisplay)
-        dirtyRect.intersect(m_currentContent.needsDisplayRect);
-    if (needsReset)
-        m_texture->reset(m_size, m_state.contentsOpaque);
-    m_pendingContent.needsDisplayRect = IntRect();
-
-    {
-        GraphicsContext context(m_texture->beginPaint(dirtyRect));
-        if (textureMapper) {
-            context.setImageInterpolationQuality(textureMapper->imageInterpolationQuality());
-            context.setTextDrawingMode(textureMapper->textDrawingMode());
-        }
-        m_layer->paintGraphicsLayerContents(context, dirtyRect);
-    }
-    m_texture->endPaint();
-    m_currentContent.needsDisplay = false;
-
-}
-
-void TextureMapperNode::paintSelf(const TexmapPaintOptions& options)
-{
-    if (!m_layer || m_size.isEmpty() || (!m_state.drawsContent && m_currentContent.contentType == HTMLContentType))
-        return;
-
-    RefPtr<BitmapTexture> maskTexture = m_state.maskLayer ? m_state.maskLayer->m_texture : 0;
-    RefPtr<BitmapTexture> replicaMaskTexture = 0;
-    if (m_state.replicaLayer && m_state.replicaLayer->m_state.maskLayer)
-        replicaMaskTexture = m_state.replicaLayer->m_state.maskLayer->m_texture;
-
-    const float opacity = options.isSurface ? 1 : options.opacity;
-
-    uploadTextureFromContent(options.textureMapper, options.visibleRect);
-    if (m_state.replicaLayer && !options.isSurface)
-        options.textureMapper->drawTexture(*m_texture.get(), replicaRect(), m_transforms.replica,
-                         opacity * m_state.replicaLayer->m_state.opacity,
-                         replicaMaskTexture ? replicaMaskTexture.get() : maskTexture.get());
-
-    const IntRect rect = m_layerType == ClipLayer ? entireRect() : targetRect();
-    const TransformationMatrix transform = m_layerType == ClipLayer ? TransformationMatrix() : m_transforms.target;
-    options.textureMapper->drawTexture(*m_texture.get(), rect, transform, opacity, options.isSurface ? 0 : maskTexture.get());
-}
-
-void TextureMapperNode::paintRecursive(TexmapPaintOptions options)
-{
-    bool isDirty = m_state.dirty;
-    m_state.dirty = false;
-
-    if ((m_size.isEmpty() && (m_state.masksToBounds
-        || m_children.isEmpty())) || !m_state.visible || options.opacity < 0.01 || m_state.opacity < 0.01)
-        return;
-
-    initializeTextureMapper(options.textureMapper);
-    computeReplicaTransform();
-
-    if (m_state.maskLayer) {
-        m_state.maskLayer->initializeTextureMapper(options.textureMapper);
-        m_state.maskLayer->m_state.dirty = false;
-    }
-
-    if (m_state.replicaLayer) {
-        m_state.replicaLayer->initializeTextureMapper(options.textureMapper);
-        m_state.replicaLayer->m_state.dirty = false;
-        if (m_state.replicaLayer->m_state.maskLayer) {
-            m_state.replicaLayer->m_state.maskLayer->initializeTextureMapper(options.textureMapper);
-            m_state.replicaLayer->m_state.maskLayer->m_state.dirty = false;
-        }
-    }
-
-    TextureMapperNode* replica = m_state.replicaLayer;
-    const bool isSurface = (m_layerType == ClipLayer
-                            || m_layerType == TransparencyLayer
-                            || (m_layerType == RootLayer
-                                && (options.textureMapper->allowSurfaceForRoot() || m_state.hasSurfaceDescendants)
-                                ));
-    if (isSurface)
-        uploadTextureFromContent(options.textureMapper, options.visibleRect);
-    const IntRect boundingRectfromNearestSurface = m_transforms.targetBoundingRect;
-
-    options.opacity *= m_state.opacity;
-
-    TexmapPaintOptions optionsForDescendants(options);
-    optionsForDescendants.opacity = isSurface ? 1 : options.opacity;
-    options.isSurface = isSurface;
-
-    if (m_layerType == ClipLayer) {
-        optionsForDescendants.visibleRect = TransformationMatrix().translate(-boundingRectfromNearestSurface.x(), -boundingRectfromNearestSurface.y()).mapRect(options.visibleRect);
-        optionsForDescendants.scissorRect = IntRect(0, 0, m_size.width(), m_size.height());
-    }
-
-    if (m_layerType == ScissorLayer)
-        optionsForDescendants.scissorRect.intersect(m_transforms.targetBoundingRect);
-    options.textureMapper->setClip(optionsForDescendants.scissorRect);
-
-    TextureMapperCacheLock(m_texture.get());
-    TextureMapperCacheLock(m_surface.get());
-    TextureMapperCacheLock(m_replicaSurface.get());
-
-    gTextureMapperCache.purge();
-
-    if (isSurface) {
-        ASSERT(m_surface);
-        if (!m_surface->isValid())
-            isDirty = true;
-        if (m_state.tiled) {
-            m_surface->reset(options.visibleRect.size());
-            m_surface->setOffset(options.visibleRect.location());
-        } else if (isDirty)
-            m_surface->reset(m_layerType == TransparencyLayer ? options.surface->size() : m_size);
-        gTextureMapperCache.mark(m_surface.get());
-        options.textureMapper->bindSurface(m_surface.get());
-
-        optionsForDescendants.surface = m_surface.get();
-    } else if (m_surface)
-        m_surface->destroy();
-
-    RefPtr<BitmapTexture> maskTexture;
-    RefPtr<BitmapTexture> replicaMaskTexture;
-    if (TextureMapperNode* mask = m_state.maskLayer) {
-        mask->uploadTextureFromContent(options.textureMapper, options.visibleRect);
-        maskTexture = mask->m_texture;
-    }
-
-    if (replica && replica->m_state.maskLayer) {
-        replica->m_state.maskLayer->uploadTextureFromContent(options.textureMapper, options.visibleRect);
-        replicaMaskTexture = replica->m_state.maskLayer->m_texture;
-    }
-
-    int childrenSize = m_children.size();
-    if (isDirty || !isSurface || m_state.tiled || !m_surface->isValid()) {
-        bool didPaintSelf = false;
-        if (!m_state.preserves3D || m_children.isEmpty()) {
-            paintSelf(options);
-            didPaintSelf = true;
-        }
-
-        if (m_children.isEmpty() && !isSurface)
-            return;
-
-        if (m_layerType == ScissorLayer)
-            optionsForDescendants.scissorRect.intersect(m_transforms.target.mapRect(IntRect(0, 0, m_size.width(), m_size.height())));
-
-        for (int i = 0; i < childrenSize; ++i) {
-            TextureMapperNode* layer = m_children[i];
-            if (!layer)
-                continue;
-
-            if (!didPaintSelf && layer->m_transforms.centerZ >= 0) {
-                paintSelf(options);
-                didPaintSelf = true;
-            }
-            layer->paintRecursive(optionsForDescendants);
-            if (isSurface) {
-                ASSERT(m_surface);
-                gTextureMapperCache.mark(m_surface.get());
-                options.textureMapper->bindSurface(m_surface.get());
-            }
-        }
-        if (!didPaintSelf) {
-            paintSelf(options);
-            didPaintSelf = true;
-        }
-    }
-
-    if (m_layerType == RootLayer || m_layerType == DefaultLayer || m_layerType == ScissorLayer)
-        return;
-
-    ASSERT(m_surface);
-    BitmapTexture& texture = *m_surface.get();
-    if (replica) {
-        ASSERT(m_replicaSurface);
-        m_replicaSurface->reset(options.surface->size());
-        m_replicaSurface->setOffset(options.surface->offset());
-        gTextureMapperCache.mark(m_replicaSurface.get());
-        options.textureMapper->bindSurface(m_replicaSurface.get());
-        options.textureMapper->drawTexture(texture, replicaRect(), m_transforms.replica, replica->m_state.opacity, replicaMaskTexture ? replicaMaskTexture.get() : maskTexture.get());
-        options.textureMapper->drawTexture(texture, IntRect(IntPoint(0, 0), options.surface->size()), TransformationMatrix(), 1.0f, maskTexture.get());
-        options.textureMapper->bindSurface(options.surface);
-        gTextureMapperCache.mark(options.surface);
-        options.textureMapper->drawTexture(*m_replicaSurface.get(), IntRect(IntPoint(0, 0), options.surface->size()), TransformationMatrix(), options.opacity, 0);
-        return;
-    }
-
-    options.textureMapper->bindSurface(options.surface);
-    options.textureMapper->drawTexture(texture,
-                             m_layerType == TransparencyLayer ? IntRect(IntPoint(0, 0), options.surface->size()) :
-                             targetRect(),
-                             m_layerType == TransparencyLayer ? TransformationMatrix() : m_transforms.target,
-                             options.opacity, maskTexture.get());
-    gTextureMapperCache.mark(&texture);
-}
-
-void TextureMapperNode::cleanupTextureMapper()
-{
-    if (m_texture)
-        m_texture->destroy();
-    if (m_surface)
-        m_surface->destroy();
-    if (m_replicaSurface)
-        m_replicaSurface->destroy();
-    for (int i = 0; i < m_children.size(); ++i) {
-        if (m_children[i])
-            m_children[i]->cleanupTextureMapper();
-    }
-    if (m_lastTextureMapper)
-        m_lastTextureMapper->cleanup();
-}
-
-TextureMapperNode::~TextureMapperNode()
+GraphicsLayerTextureMapper::GraphicsLayerTextureMapper(GraphicsLayerClient* client)
+    : GraphicsLayer(client)
+    , m_node(new TextureMapperNode())
+    , m_changeMask(0)
 {
-    setNeedsDisplay();
-    {
-        const int childrenSize = m_children.size();
-        for (int i = childrenSize-1; i >= 0; --i) {
-            ASSERT(m_children[i]->m_parent == this);
-            m_children[i]->m_parent = 0;
-        }
-    }
-    if (m_parent)
-        m_parent->m_children.remove(m_parent->m_children.find(this));
 }
 
-void TextureMapperNode::notifyChange(ChangeMask changeMask)
+void GraphicsLayerTextureMapper::notifyChange(TextureMapperNode::ChangeMask changeMask)
 {
     m_changeMask |= changeMask;
-    if (!m_layer->client())
+    if (!client())
         return;
-    m_layer->client()->notifySyncRequired(m_layer);
-}
-
-void TextureMapperNode::performPostSyncOperations()
-{
-    const LayerType prevLayerType = m_layerType;
-    computeLayerType();
-    if (prevLayerType != m_layerType)
-        m_state.dirty = true;
-    if (m_transforms.dirty)
-        setNeedsDisplay();
-
-    computeTransformations();
-    if (m_state.maskLayer && !m_state.dirty)
-        m_state.dirty = m_state.maskLayer->m_state.dirty;
-    if (m_state.replicaLayer && !m_state.dirty)
-        m_state.dirty = m_state.replicaLayer->m_state.dirty;
-
-    const int size = m_children.size();
-
-    for (int i = size - 1; i >= 0; --i) {
-        TextureMapperNode* layer = m_children[i];
-
-        layer->performPostSyncOperations();
-        if (!m_state.dirty)
-            m_state.dirty = layer->m_state.dirty;
-    }
-    m_state.hasSurfaceDescendants = hasSurfaceDescendants();
-    if (m_state.dirty)
-        m_state.descendantsWithContent = countDescendantsWithContent();
-
-    if (m_state.preserves3D)
-        sortByZOrder(m_children, 0, size);
-    if (m_state.dirty) 
-        setNeedsDisplay();
+    client()->notifySyncRequired(this);
 }
 
-void TextureMapperNode::syncCompositingState(bool recurse)
+void GraphicsLayerTextureMapper::didSynchronize()
 {
-    bool needsToInvalidateTransform = false;
-
-    if (!m_layer)
-        return;
-
-    if (m_changeMask == NoChanges)
-        goto afterCurrentLayerSync;
-
-    setNeedsDisplay();
-    if (m_parent)
-        m_parent->m_state.dirty = true;
-
-    if (m_currentContent.contentType == HTMLContentType && (m_changeMask & ParentChange)) {
-        // The WebCore compositor manages item ownership. We have to make sure graphicsview doesn't
-        // try to snatch that ownership.
-
-        if (!m_layer->parent())
-            m_parent = 0;
-        else
-            m_parent = toTextureMapperNode(m_layer->parent());
-
-        if (!m_layer->parent() && m_parent) {
-            size_t index = m_parent->m_children.find(this);
-            m_parent->m_children.remove(index);
-        }
-
-    }
-
-    if (m_changeMask & ChildrenChange) {
-        m_children.clear();
-        for (size_t i = 0; i < m_layer->children().size(); ++i) {
-            if (TextureMapperNode* child = toTextureMapperNode(m_layer->children()[i])) {
-                if (!child)
-                    continue;
-                m_children.append(child);
-                child->m_parent = this;
-            }
-        }
-        m_state.dirty = true;
-    }
-
-    if (m_changeMask & (SizeChange | ContentsRectChange)) {
-        IntSize wantedSize = IntSize(m_layer->size().width(), m_layer->size().height());
-        if (wantedSize.isEmpty() && m_pendingContent.contentType == HTMLContentType)
-            wantedSize = IntSize(m_layer->contentsRect().width(), m_layer->contentsRect().height());
-
-        if (wantedSize != m_size) {
-            m_size = IntSize(wantedSize.width(), wantedSize.height());
-            if (m_platformClient)
-                m_platformClient->setSizeChanged(m_size);
-            const bool needsTiling = m_size.width() > 2000 || m_size.height() > 2000;
-            if (m_state.tiled != needsTiling)
-                m_state.tiled = needsTiling;
-            m_state.dirty = true;
-        }
-    }
-
-    if (m_changeMask & MaskLayerChange) {
-       if (TextureMapperNode* layer = toTextureMapperNode(m_layer->maskLayer()))
-           layer->m_effectTarget = this;
-    }
-
-    if (m_changeMask & ReplicaLayerChange) {
-       if (TextureMapperNode* layer = toTextureMapperNode(m_layer->replicaLayer()))
-           layer->m_effectTarget = this;
-    }
-
-    if (m_changeMask & (TransformChange | SizeChange | AnchorPointChange | PositionChange))
-        m_transforms.localDirty = true;
-
-    if (m_changeMask & (ChildrenTransformChange | SizeChange))
-        m_transforms.perspectiveDirty = true;
-
-    if (m_changeMask & (ChildrenTransformChange | Preserves3DChange | TransformChange | AnchorPointChange | SizeChange | ContentsRectChange | BackfaceVisibilityChange | PositionChange | MaskLayerChange | DrawsContentChange | ContentChange | ReplicaLayerChange))    {
-        // Due to the differences between the way WebCore handles transforms and the way Qt handles transforms,
-        // all these elements affect the transforms of all the descendants.
-        needsToInvalidateTransform = true;
-    }
-
-    if (m_changeMask & DisplayChange) 
-        m_state.dirty = true;
-
-    m_state.maskLayer = toTextureMapperNode(m_layer->maskLayer());
-    m_state.replicaLayer = toTextureMapperNode(m_layer->replicaLayer());
-    m_state.pos = m_layer->position();
-    m_state.anchorPoint = m_layer->anchorPoint();
-    m_state.size = m_layer->size();
-    m_state.transform = m_layer->transform();
-    m_state.contentsRect = m_layer->contentsRect();
-    m_state.opacity = m_layer->opacity();
-    m_state.contentsRect = m_layer->contentsRect();
-    m_state.preserves3D = m_layer->preserves3D();
-    m_state.masksToBounds = m_layer->masksToBounds();
-    m_state.drawsContent = m_layer->drawsContent();
-    m_state.contentsOpaque = m_layer->contentsOpaque();
-    m_state.backfaceVisibility = m_layer->backfaceVisibility();
-    m_state.childrenTransform = m_layer->childrenTransform();
-    m_currentContent.contentType = m_pendingContent.contentType;
-    m_currentContent.image = m_pendingContent.image;
-    m_currentContent.media = m_pendingContent.media;
-    m_currentContent.backgroundColor = m_pendingContent.backgroundColor;
-    m_currentContent.needsDisplay = m_currentContent.needsDisplay || m_pendingContent.needsDisplay;
-    m_currentContent.needsDisplayRect.unite(m_pendingContent.needsDisplayRect);
+    m_syncQueued = false;
+    m_changeMask = 0;
     m_pendingContent.needsDisplay = false;
     m_pendingContent.needsDisplayRect = IntRect();
-    m_changeMask = NoChanges;
-    afterCurrentLayerSync:
-    if (needsToInvalidateTransform)
-        invalidateTransform();
-
-    if (m_state.maskLayer) {
-        m_state.maskLayer->syncCompositingState(false);
-        if (m_state.maskLayer->m_size.isEmpty())
-            m_state.maskLayer->m_size = m_size;
-    }
-
-    if (m_state.replicaLayer)
-        m_state.replicaLayer->syncCompositingState(false);
-
-#if 0
-    if (m_state.dirty && m_texture && m_texture->allowOfflineTextureUpload())
-        uploadTextureFromContent(0);
-#endif
-
-    if (!recurse)
-        return;
-
-    const int childrenSize = m_children.size();
-    for (int i = childrenSize-1; i >= 0; --i)
-        m_children[i]->syncCompositingState(true);
-}
-
-GraphicsLayerTextureMapper::GraphicsLayerTextureMapper(GraphicsLayerClient* client)
-    : GraphicsLayer(client)
-    , m_node(new TextureMapperNode(this))
-{
 }
 
 void GraphicsLayerTextureMapper::setName(const String& name)
 {
-    m_node->m_name = name;
+    GraphicsLayer::setName(name);
 }
 
 GraphicsLayerTextureMapper::~GraphicsLayerTextureMapper()
@@ -1096,25 +60,25 @@ GraphicsLayerTextureMapper::~GraphicsLayerTextureMapper()
 */
 void GraphicsLayerTextureMapper::setNeedsDisplay()
 {
-    m_node->m_pendingContent.needsDisplay = true;
-    m_node->notifyChange(TextureMapperNode::DisplayChange);
+    m_pendingContent.needsDisplay = true;
+    notifyChange(TextureMapperNode::DisplayChange);
 }
 
 /* \reimp (GraphicsLayer.h)
 */
 void GraphicsLayerTextureMapper::setNeedsDisplayInRect(const FloatRect& rect)
 {
-    if (m_node->m_pendingContent.needsDisplay)
+    if (m_pendingContent.needsDisplay)
         return;
-    m_node->m_pendingContent.needsDisplayRect.unite(IntRect(rect));
-    m_node->notifyChange(TextureMapperNode::DisplayChange);
+    m_pendingContent.needsDisplayRect.unite(IntRect(rect));
+    notifyChange(TextureMapperNode::DisplayChange);
 }
 
 /* \reimp (GraphicsLayer.h)
 */
 void GraphicsLayerTextureMapper::setParent(GraphicsLayer* layer)
 {
-    m_node->notifyChange(TextureMapperNode::ParentChange);
+    notifyChange(TextureMapperNode::ParentChange);
     GraphicsLayer::setParent(layer);
 }
 
@@ -1122,7 +86,7 @@ void GraphicsLayerTextureMapper::setParent(GraphicsLayer* layer)
 */
 bool GraphicsLayerTextureMapper::setChildren(const Vector<GraphicsLayer*>& children)
 {
-    m_node->notifyChange(TextureMapperNode::ChildrenChange);
+    notifyChange(TextureMapperNode::ChildrenChange);
     return GraphicsLayer::setChildren(children);
 }
 
@@ -1130,7 +94,7 @@ bool GraphicsLayerTextureMapper::setChildren(const Vector<GraphicsLayer*>& child
 */
 void GraphicsLayerTextureMapper::addChild(GraphicsLayer* layer)
 {
-    m_node->notifyChange(TextureMapperNode::ChildrenChange);
+    notifyChange(TextureMapperNode::ChildrenChange);
     GraphicsLayer::addChild(layer);
 }
 
@@ -1139,7 +103,7 @@ void GraphicsLayerTextureMapper::addChild(GraphicsLayer* layer)
 void GraphicsLayerTextureMapper::addChildAtIndex(GraphicsLayer* layer, int index)
 {
     GraphicsLayer::addChildAtIndex(layer, index);
-    m_node->notifyChange(TextureMapperNode::ChildrenChange);
+    notifyChange(TextureMapperNode::ChildrenChange);
 }
 
 /* \reimp (GraphicsLayer.h)
@@ -1147,7 +111,7 @@ void GraphicsLayerTextureMapper::addChildAtIndex(GraphicsLayer* layer, int index
 void GraphicsLayerTextureMapper::addChildAbove(GraphicsLayer* layer, GraphicsLayer* sibling)
 {
      GraphicsLayer::addChildAbove(layer, sibling);
-     m_node->notifyChange(TextureMapperNode::ChildrenChange);
+     notifyChange(TextureMapperNode::ChildrenChange);
 }
 
 /* \reimp (GraphicsLayer.h)
@@ -1156,7 +120,7 @@ void GraphicsLayerTextureMapper::addChildBelow(GraphicsLayer* layer, GraphicsLay
 {
 
     GraphicsLayer::addChildBelow(layer, sibling);
-    m_node->notifyChange(TextureMapperNode::ChildrenChange);
+    notifyChange(TextureMapperNode::ChildrenChange);
 }
 
 /* \reimp (GraphicsLayer.h)
@@ -1164,10 +128,9 @@ void GraphicsLayerTextureMapper::addChildBelow(GraphicsLayer* layer, GraphicsLay
 bool GraphicsLayerTextureMapper::replaceChild(GraphicsLayer* oldChild, GraphicsLayer* newChild)
 {
     if (GraphicsLayer::replaceChild(oldChild, newChild)) {
-        m_node->notifyChange(TextureMapperNode::ChildrenChange);
+        notifyChange(TextureMapperNode::ChildrenChange);
         return true;
     }
-
     return false;
 }
 
@@ -1177,7 +140,7 @@ void GraphicsLayerTextureMapper::removeFromParent()
 {
     if (!parent())
         return;
-    m_node->notifyChange(TextureMapperNode::ParentChange);
+    notifyChange(TextureMapperNode::ParentChange);
     GraphicsLayer::removeFromParent();
 }
 
@@ -1188,7 +151,7 @@ void GraphicsLayerTextureMapper::setMaskLayer(GraphicsLayer* value)
     if (value == maskLayer())
         return;
     GraphicsLayer::setMaskLayer(value);
-    m_node->notifyChange(TextureMapperNode::MaskLayerChange);
+    notifyChange(TextureMapperNode::MaskLayerChange);
 }
 
 
@@ -1199,7 +162,7 @@ void GraphicsLayerTextureMapper::setReplicatedByLayer(GraphicsLayer* value)
     if (value == replicaLayer())
         return;
     GraphicsLayer::setReplicatedByLayer(value);
-    m_node->notifyChange(TextureMapperNode::ReplicaLayerChange);
+    notifyChange(TextureMapperNode::ReplicaLayerChange);
 }
 
 /* \reimp (GraphicsLayer.h)
@@ -1209,7 +172,7 @@ void GraphicsLayerTextureMapper::setPosition(const FloatPoint& value)
     if (value == position())
         return;
     GraphicsLayer::setPosition(value);
-    m_node->notifyChange(TextureMapperNode::PositionChange);
+    notifyChange(TextureMapperNode::PositionChange);
 }
 
 /* \reimp (GraphicsLayer.h)
@@ -1219,7 +182,7 @@ void GraphicsLayerTextureMapper::setAnchorPoint(const FloatPoint3D& value)
     if (value == anchorPoint())
         return;
     GraphicsLayer::setAnchorPoint(value);
-    m_node->notifyChange(TextureMapperNode::AnchorPointChange);
+    notifyChange(TextureMapperNode::AnchorPointChange);
 }
 
 /* \reimp (GraphicsLayer.h)
@@ -1230,7 +193,7 @@ void GraphicsLayerTextureMapper::setSize(const FloatSize& value)
         return;
 
     GraphicsLayer::setSize(value);
-    m_node->notifyChange(TextureMapperNode::SizeChange);
+    notifyChange(TextureMapperNode::SizeChange);
 }
 
 /* \reimp (GraphicsLayer.h)
@@ -1241,7 +204,7 @@ void GraphicsLayerTextureMapper::setTransform(const TransformationMatrix& value)
         return;
 
     GraphicsLayer::setTransform(value);
-    m_node->notifyChange(TextureMapperNode::TransformChange);
+    notifyChange(TextureMapperNode::TransformChange);
 }
 
 /* \reimp (GraphicsLayer.h)
@@ -1251,7 +214,7 @@ void GraphicsLayerTextureMapper::setChildrenTransform(const TransformationMatrix
     if (value == childrenTransform())
         return;
     GraphicsLayer::setChildrenTransform(value);
-    m_node->notifyChange(TextureMapperNode::ChildrenTransformChange);
+    notifyChange(TextureMapperNode::ChildrenTransformChange);
 }
 
 /* \reimp (GraphicsLayer.h)
@@ -1261,7 +224,7 @@ void GraphicsLayerTextureMapper::setPreserves3D(bool value)
     if (value == preserves3D())
         return;
     GraphicsLayer::setPreserves3D(value);
-    m_node->notifyChange(TextureMapperNode::Preserves3DChange);
+    notifyChange(TextureMapperNode::Preserves3DChange);
 }
 
 /* \reimp (GraphicsLayer.h)
@@ -1271,7 +234,7 @@ void GraphicsLayerTextureMapper::setMasksToBounds(bool value)
     if (value == masksToBounds())
         return;
     GraphicsLayer::setMasksToBounds(value);
-    m_node->notifyChange(TextureMapperNode::MasksToBoundsChange);
+    notifyChange(TextureMapperNode::MasksToBoundsChange);
 }
 
 /* \reimp (GraphicsLayer.h)
@@ -1280,7 +243,7 @@ void GraphicsLayerTextureMapper::setDrawsContent(bool value)
 {
     if (value == drawsContent())
         return;
-    m_node->notifyChange(TextureMapperNode::DrawsContentChange);
+    notifyChange(TextureMapperNode::DrawsContentChange);
     GraphicsLayer::setDrawsContent(value);
 }
 
@@ -1288,22 +251,22 @@ void GraphicsLayerTextureMapper::setDrawsContent(bool value)
 */
 void GraphicsLayerTextureMapper::setBackgroundColor(const Color& value)
 {
-    if (value == m_node->m_pendingContent.backgroundColor)
+    if (value == m_pendingContent.backgroundColor)
         return;
-    m_node->m_pendingContent.backgroundColor = value;
+    m_pendingContent.backgroundColor = value;
     GraphicsLayer::setBackgroundColor(value);
-    m_node->notifyChange(TextureMapperNode::BackgroundColorChange);
+    notifyChange(TextureMapperNode::BackgroundColorChange);
 }
 
 /* \reimp (GraphicsLayer.h)
 */
 void GraphicsLayerTextureMapper::clearBackgroundColor()
 {
-    if (!m_node->m_pendingContent.backgroundColor.isValid())
+    if (!m_pendingContent.backgroundColor.isValid())
         return;
-    m_node->m_pendingContent.backgroundColor = Color();
+    m_pendingContent.backgroundColor = Color();
     GraphicsLayer::clearBackgroundColor();
-    m_node->notifyChange(TextureMapperNode::BackgroundColorChange);
+    notifyChange(TextureMapperNode::BackgroundColorChange);
 }
 
 /* \reimp (GraphicsLayer.h)
@@ -1312,7 +275,7 @@ void GraphicsLayerTextureMapper::setContentsOpaque(bool value)
 {
     if (value == contentsOpaque())
         return;
-    m_node->notifyChange(TextureMapperNode::ContentsOpaqueChange);
+    notifyChange(TextureMapperNode::ContentsOpaqueChange);
     GraphicsLayer::setContentsOpaque(value);
 }
 
@@ -1323,7 +286,7 @@ void GraphicsLayerTextureMapper::setBackfaceVisibility(bool value)
     if (value == backfaceVisibility())
         return;
     GraphicsLayer::setBackfaceVisibility(value);
-    m_node->notifyChange(TextureMapperNode::BackfaceVisibilityChange);
+    notifyChange(TextureMapperNode::BackfaceVisibilityChange);
 }
 
 /* \reimp (GraphicsLayer.h)
@@ -1333,7 +296,7 @@ void GraphicsLayerTextureMapper::setOpacity(float value)
     if (value == opacity())
         return;
     GraphicsLayer::setOpacity(value);
-    m_node->notifyChange(TextureMapperNode::OpacityChange);
+    notifyChange(TextureMapperNode::OpacityChange);
 }
 
 /* \reimp (GraphicsLayer.h)
@@ -1343,16 +306,16 @@ void GraphicsLayerTextureMapper::setContentsRect(const IntRect& value)
     if (value == contentsRect())
         return;
     GraphicsLayer::setContentsRect(value);
-    m_node->notifyChange(TextureMapperNode::ContentsRectChange);
+    notifyChange(TextureMapperNode::ContentsRectChange);
 }
 
 /* \reimp (GraphicsLayer.h)
 */
 void GraphicsLayerTextureMapper::setContentsToImage(Image* image)
 {
-    m_node->notifyChange(TextureMapperNode::ContentChange);
-    m_node->m_pendingContent.contentType = image ? TextureMapperNode::DirectImageContentType : TextureMapperNode::HTMLContentType;
-    m_node->m_pendingContent.image = image;
+    notifyChange(TextureMapperNode::ContentChange);
+    m_pendingContent.contentType = image ? TextureMapperNode::DirectImageContentType : TextureMapperNode::HTMLContentType;
+    m_pendingContent.image = image;
     GraphicsLayer::setContentsToImage(image);
 }
 
@@ -1360,9 +323,9 @@ void GraphicsLayerTextureMapper::setContentsToImage(Image* image)
 */
 void GraphicsLayerTextureMapper::setContentsBackgroundColor(const Color& color)
 {
-    m_node->notifyChange(TextureMapperNode::ContentChange);
-    m_node->m_pendingContent.contentType = TextureMapperNode::ColorContentType;
-    m_node->m_pendingContent.backgroundColor = color;
+    notifyChange(TextureMapperNode::ContentChange);
+    m_pendingContent.contentType = TextureMapperNode::ColorContentType;
+    m_pendingContent.backgroundColor = color;
     GraphicsLayer::setContentsBackgroundColor(color);
 }
 
@@ -1370,12 +333,12 @@ void GraphicsLayerTextureMapper::setContentsBackgroundColor(const Color& color)
 void GraphicsLayerTextureMapper::setContentsToMedia(PlatformLayer* media)
 {
     GraphicsLayer::setContentsToMedia(media);
-    m_node->notifyChange(TextureMapperNode::ContentChange);
-    m_node->m_pendingContent.contentType = media ? TextureMapperNode::MediaContentType : TextureMapperNode::HTMLContentType;
+    notifyChange(TextureMapperNode::ContentChange);
+    m_pendingContent.contentType = media ? TextureMapperNode::MediaContentType : TextureMapperNode::HTMLContentType;
     if (media)
-        m_node->m_pendingContent.media = static_cast<TextureMapperVideoLayer*>(media);
+        m_pendingContent.media = static_cast<TextureMapperVideoLayer*>(media);
     else
-        m_node->m_pendingContent.media = 0;
+        m_pendingContent.media = 0;
 }
 
 /* \reimp (GraphicsLayer.h)
@@ -1384,7 +347,7 @@ void GraphicsLayerTextureMapper::setContentsOrientation(CompositingCoordinatesOr
 {
     if (contentsOrientation() == orientation)
         return;
-    m_node->notifyChange(TextureMapperNode::ContentsOrientationChange);
+    notifyChange(TextureMapperNode::ContentsOrientationChange);
     GraphicsLayer::setContentsOrientation(orientation);
 }
 
@@ -1392,17 +355,14 @@ void GraphicsLayerTextureMapper::setContentsOrientation(CompositingCoordinatesOr
 */
 void GraphicsLayerTextureMapper::syncCompositingStateForThisLayerOnly()
 {
-    m_node->syncCompositingState(false);
-    m_node->performPostSyncOperations();
+    m_node->syncCompositingState(this, false);
 }
 
 /* \reimp (GraphicsLayer.h)
 */
 void GraphicsLayerTextureMapper::syncCompositingState()
 {
-    GraphicsLayer::syncCompositingState();
-    m_node->syncCompositingState(true);
-    m_node->performPostSyncOperations();
+    m_node->syncCompositingState(this, true);
 }
 
 /* \reimp (GraphicsLayer.h)
diff --git a/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.h b/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.h
index 36ebd74..85fa3ee 100644
--- a/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.h
+++ b/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.h
@@ -24,13 +24,12 @@
 #include "GraphicsLayer.h"
 #include "GraphicsLayerClient.h"
 #include "Image.h"
+#include "TextureMapperNode.h"
 
 #if ENABLE(3D_CANVAS)
 #include "GraphicsContext3D.h"
 #endif
 
-#define ENABLE_TEXMAP_ANIMATION 0
-
 namespace WebCore {
 
 class TextureMapperNode;
@@ -85,12 +84,24 @@ public:
     virtual NativeLayer nativeLayer() const;
     virtual PlatformLayer* platformLayer() const;
 
-    virtual bool addAnimation(const KeyframeValueList&, const IntSize& /*boxSize*/, const Animation*,
-                              const String& /*keyframesName*/, double /*timeOffset*/) { return false; }
+    virtual bool addAnimation(const KeyframeValueList&, const IntSize& /*boxSize*/, const Animation*, const String& /*keyframesName*/, double /*timeOffset*/) { return false; }
+
+    void notifyChange(TextureMapperNode::ChangeMask changeMask);
+    inline TextureMapperNode::ContentData& pendingContent() { return m_pendingContent; }
+    inline int changeMask() const { return m_changeMask; }
+    void didSynchronize();
 
 private:
     OwnPtr<TextureMapperNode> m_node;
+    bool m_syncQueued;
+    int m_changeMask;
+    TextureMapperNode::ContentData m_pendingContent;
 };
 
+inline static GraphicsLayerTextureMapper* toGraphicsLayerTextureMapper(GraphicsLayer* layer)
+{
+    return static_cast<GraphicsLayerTextureMapper*>(layer);
+}
+
 }
 #endif // GraphicsLayerTextureMapper_h
diff --git a/WebCore/platform/graphics/texmap/TextureMapper.h b/WebCore/platform/graphics/texmap/TextureMapper.h
index 89899c0..250125b 100644
--- a/WebCore/platform/graphics/texmap/TextureMapper.h
+++ b/WebCore/platform/graphics/texmap/TextureMapper.h
@@ -57,6 +57,10 @@ public:
         m_contentSize = size;
     }
 
+    virtual void pack() { }
+    virtual void unpack() { }
+    virtual bool isPacked() const { return false; }
+
     virtual PlatformGraphicsContext* beginPaint(const IntRect& dirtyRect) = 0;
     virtual void endPaint() = 0;
     virtual PlatformGraphicsContext* beginPaintMedia()
@@ -72,6 +76,9 @@ public:
     inline IntSize contentSize() const { return m_contentSize; }
     inline void setOffset(const IntPoint& o) { m_offset = o; }
     inline IntPoint offset() const { return m_offset; }
+
+protected:
+
 private:
     int m_lockCount;
     IntSize m_contentSize;
@@ -81,11 +88,11 @@ private:
 
 // A "context" class used to encapsulate accelerated texture mapping functions: i.e. drawing a texture
 // onto the screen or into another texture with a specified transform, opacity and mask.
-class TextureMapper : public RefCounted<TextureMapper> {
+class TextureMapper {
     friend class BitmapTexture;
 
 public:
-    static PassRefPtr<TextureMapper> create(GraphicsContext*);
+    static PassOwnPtr<TextureMapper> create(GraphicsContext* graphicsContext = 0);
     virtual ~TextureMapper() { }
 
     virtual void drawTexture(const BitmapTexture& texture, const IntRect& target, const TransformationMatrix& matrix = TransformationMatrix(), float opacity = 1.0f, const BitmapTexture* maskTexture = 0) = 0;
@@ -101,8 +108,6 @@ public:
     virtual void setClip(const IntRect&) = 0;
     virtual bool allowSurfaceForRoot() const = 0;
     virtual PassRefPtr<BitmapTexture> createTexture() = 0;
-    virtual const char* type() const = 0;
-    virtual void cleanup() {}
 
     void setImageInterpolationQuality(InterpolationQuality quality) { m_interpolationQuality = quality; }
     void setTextDrawingMode(int mode) { m_textDrawingMode = mode; }
diff --git a/WebCore/platform/graphics/texmap/TextureMapperNode.cpp b/WebCore/platform/graphics/texmap/TextureMapperNode.cpp
new file mode 100644
index 0000000..09051f9
--- /dev/null
+++ b/WebCore/platform/graphics/texmap/TextureMapperNode.cpp
@@ -0,0 +1,877 @@
+/*
+ Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB.  If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "TextureMapperNode.h"
+
+#include "GraphicsLayerTextureMapper.h"
+
+namespace WebCore {
+
+class TextureMapperCache {
+public:
+    void mark(BitmapTexture* texture);
+
+    class Entry {
+    public:
+        RefPtr<BitmapTexture> texture;
+        Entry() : previousCost(0) { }
+        inline int computeCost() const
+        {
+            if (!texture || !texture->isValid() || texture->isPacked())
+                return 0;
+            const IntSize textureSize = texture->size();
+            // An image's cost in bytes is width * height * bytes per pixel (4).
+            return textureSize.width() * textureSize.height() * 4;
+        }
+        Entry(BitmapTexture* newTexture)
+            : texture(newTexture)
+        {
+        }
+        bool operator==(const Entry& other) const { return texture == other.texture; }
+        int previousCost;
+    };
+
+    TextureMapperCache()
+        : m_totalCost(0)
+    {
+    }
+
+    void purge();
+    Vector<Entry> m_data;
+    int m_totalCost;
+#ifndef TEXMAP_TEXTURE_CACHE_KBS
+#define TEXMAP_TEXTURE_CACHE_KBS 24 * 1024
+#endif
+    static const int MaxCost = TEXMAP_TEXTURE_CACHE_KBS * 1024;
+    static const int PurgeAmount = MaxCost / 4;
+};
+
+
+void TextureMapperCache::purge()
+{
+    const int size = m_data.size();
+
+    if (m_totalCost <= TextureMapperCache::MaxCost)
+        return;
+
+    // Ensure that we have the right count. It might be inaccurate if content changed size.
+    // We only do this when we're actually ready to purge.
+    m_totalCost = 0;
+    for (int i = 0; i < size; ++i)
+        m_totalCost += m_data[i].computeCost();
+
+    for (int i = size-1; i >= 0 && m_totalCost > TextureMapperCache::MaxCost - TextureMapperCache::PurgeAmount; --i) {
+        Entry& entry = m_data[i];
+        if (entry.texture->isLocked() || !entry.texture->isValid() || entry.texture->isPacked())
+            continue;
+        m_totalCost -= entry.previousCost;
+        entry.texture->pack();
+        m_data.remove(i);
+    }
+}
+
+void TextureMapperCache::mark(BitmapTexture* texture)
+{
+    if (!texture || !texture->isValid())
+        return;
+
+    Entry entry(texture);
+    size_t index = m_data.find(entry);
+    if (!index)
+        return;
+
+    int previousCost = 0;
+
+    if (index < m_data.size()) {
+        previousCost = m_data[index].previousCost;
+        m_data.remove(index);
+    }
+    const int cost = entry.computeCost();
+    m_totalCost -= previousCost;
+    m_totalCost += (entry.previousCost = cost);
+    m_data.prepend(entry);
+}
+
+class TextureMapperCacheLock {
+public:
+    TextureMapperCacheLock(BitmapTexture* texture) : m_texture(texture)
+    {
+        if (m_texture)
+            m_texture->lock();
+    }
+    ~TextureMapperCacheLock()
+    {
+        if (m_texture)
+            m_texture->unlock();
+    }
+
+private:
+    RefPtr<BitmapTexture> m_texture;
+};
+
+
+TextureMapperCache* TextureMapperNode::cache()
+{
+    TextureMapperNode* root = rootLayer();
+    if (!root)
+        return 0;
+    if (!root->m_cache)
+        root->m_cache = new TextureMapperCache;
+    return root->m_cache;
+}
+
+void TextureMapperNode::setNeedsDisplayInRect(IntRect rect)
+{
+    if (m_platformClient) {
+        if (m_state.hasSurfaceDescendants) {
+            m_platformClient->setNeedsDisplay();
+            return;
+        }
+        rect.intersect(IntRect(0, 0, m_size.width(), m_size.height()));
+        if (rect.isEmpty())
+            return;
+        m_platformClient->setNeedsDisplayInRect(rect);
+        return;
+    }
+
+    if (!m_parent)
+        return;
+
+    m_parent->setNeedsDisplayInRect(rect);
+}
+
+void TextureMapperNode::setNeedsDisplay()
+{
+    if (m_effectTarget)
+        m_effectTarget->setNeedsDisplay();
+    if (m_transforms.targetBoundingRect.isEmpty())
+        return;
+    if (m_state.drawsContent || m_currentContent.contentType != HTMLContentType)
+        setNeedsDisplayInRect(m_transforms.targetBoundingRect);
+}
+
+void TextureMapperNode::setPlatformLayerClient(TextureMapperLayerClient* client)
+{
+    m_platformClient = client;
+}
+
+int TextureMapperNode::compareGraphicsLayersZValue(const void* a, const void* b)
+{
+    typedef const TextureMapperNode* NodePtr;
+    const NodePtr* nodeA = static_cast<const NodePtr*>(a);
+    const NodePtr* nodeB = static_cast<const NodePtr*>(b);
+    return int(((*nodeA)->m_transforms.centerZ - (*nodeB)->m_transforms.centerZ) * 1000);
+}
+
+void TextureMapperNode::sortByZOrder(Vector<TextureMapperNode* >& array, int first, int last)
+{
+    qsort(array.data(), array.size(), sizeof(TextureMapperNode*), TextureMapperNode::compareGraphicsLayersZValue);
+}
+
+bool TextureMapperNode::hasSurfaceDescendants() const
+{
+    if (m_layerType == ClipLayer || m_layerType == TransparencyLayer || m_state.replicaLayer)
+        return true;
+
+    const int size = m_children.size();
+    for (int i = 0; i < size; ++i) {
+        if (TextureMapperNode* child = m_children[i]) {
+            if (child->hasSurfaceDescendants())
+                return true;
+        }
+    }
+    return false;
+}
+
+int TextureMapperNode::countDescendantsWithContent() const
+{
+    if (!m_state.visible || m_state.opacity < 0.001)
+        return 0;
+
+    int descendantsWithContent = (m_state.drawsContent || m_currentContent.contentType != HTMLContentType) ? 1 : 0;
+
+    const int size = m_children.size();
+    for (int i = 0; i < size; ++i) {
+        if (TextureMapperNode* child = m_children[i])
+            descendantsWithContent += child->countDescendantsWithContent();
+    }
+
+    return descendantsWithContent;
+}
+
+TextureMapperNode* TextureMapperNode::toTextureMapperNode(GraphicsLayer* layer)
+{
+    return layer ? static_cast<TextureMapperNode*>(layer->platformLayer()) : 0;
+}
+
+void TextureMapperNode::computeLayerType()
+{
+    const bool selfHasContent = m_state.drawsContent || (m_currentContent.contentType != HTMLContentType);
+    const bool hasDescendantsWithContent = m_state.descendantsWithContent - (selfHasContent ? 1 : 0);
+    const bool hasTransparency = m_state.opacity < 0.99 || m_state.maskLayer;
+    const bool hasReplica = m_state.replicaLayer;
+
+    //  DefaultLayer: draws itself and its children directly to the current framebuffer.
+    //                any layer that doesn't conform to the other rules is a DefaultLayer.
+    m_layerType = DefaultLayer;
+
+    //  RootLayer: the top level. Draws to a framebuffer, and the target texture draws into the viewport.
+    //            only one layer is the root layer.
+    if (!m_parent && !m_effectTarget) {
+        m_layerType = RootLayer;
+        return;
+    }
+
+    // A layer with no contents is always a default layer.
+    if (!m_state.descendantsWithContent)
+        return;
+
+    //  ClipLayer: creates a new framebuffer, the size of the layer, and then paints it to the enclosing BitmapTexture with the layer's transform/opacity.
+    //              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.
+    if (hasDescendantsWithContent && m_state.maskLayer) {
+        m_layerType = ClipLayer;
+        return;
+    }
+
+    //  ScissorLayer: draws to the current framebuffer, and applies an extra scissor before drawing its children.
+    //                A scissor layer is a layer with children that masks to bounds, is not a transparency layer, and has a rectangular clip.
+    if (m_state.masksToBounds && hasDescendantsWithContent) {
+        if (hasTransparency || !m_state.transform.isIdentityOrTranslation() || m_parent->m_state.preserves3D)
+            m_layerType = ClipLayer;
+        else
+            m_layerType = ScissorLayer;
+        return;
+    }
+
+    //  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.
+    //                     Used for layers with children and transparency/mask that preserve 3D or don't mask to bounds.
+    if ((hasReplica && hasDescendantsWithContent) || (hasReplica && hasTransparency) || (hasTransparency && m_state.descendantsWithContent > 1))
+        m_layerType = TransparencyLayer;
+}
+
+void TextureMapperNode::initializeTextureMapper(TextureMapper* textureMapper)
+{
+    if (m_texture)
+        return;
+    m_surface = textureMapper->createTexture();
+    m_replicaSurface = textureMapper->createTexture();
+    m_texture = textureMapper->createTexture();
+    cache()->mark(m_texture.get());
+}
+
+TextureMapperNode::TextureMapperNode()
+    : m_layerType(DefaultLayer)
+    , m_surface(0)
+    , m_parent(0)
+    , m_effectTarget(0)
+    , m_platformClient(0)
+    , m_cache(0)
+{
+}
+
+TextureMapperNode* TextureMapperNode::rootLayer()
+{
+    if (m_effectTarget)
+        return m_effectTarget->rootLayer();
+    if (m_parent)
+        return m_parent->rootLayer();
+    return this;
+}
+
+void TextureMapperNode::invalidateTransform()
+{
+    m_transforms.dirty = true;
+    if (m_layerType != ClipLayer)
+        m_state.dirty = true;
+    if (m_state.replicaLayer)
+        m_state.replicaLayer->invalidateTransform();
+    const int size = m_children.size();
+    for (int i = 0; i < size; ++i) {
+        if (TextureMapperNode* layer = m_children[i])
+            layer->invalidateTransform();
+    }
+}
+
+void TextureMapperNode::computeLocalTransform()
+{
+    if (!m_transforms.localDirty)
+        return;
+    const float originX = m_state.anchorPoint.x() * m_size.width();
+    const float originY = m_state.anchorPoint.y() * m_size.height();
+    m_transforms.local =
+        TransformationMatrix()
+        .translate3d(originX + m_state.pos.x(), originY + m_state.pos.y(), m_state.anchorPoint.z())
+        .multLeft(m_state.transform)
+        .translate3d(-originX, -originY, -m_state.anchorPoint.z());
+    m_transforms.localDirty = false;
+}
+
+void TextureMapperNode::flattenTo2DSpaceIfNecessary()
+{
+    if (m_state.preserves3D)
+        return;
+
+    m_transforms.forDescendants.setM13(0);
+    m_transforms.forDescendants.setM23(0);
+    m_transforms.forDescendants.setM31(0);
+    m_transforms.forDescendants.setM32(0);
+    m_transforms.forDescendants.setM33(1);
+    m_transforms.forDescendants.setM34(0);
+    m_transforms.forDescendants.setM43(0);
+}
+
+IntSize TextureMapperNode::nearestSurfaceSize() const
+{
+    if (m_layerType == ClipLayer || m_layerType == RootLayer)
+        return m_surface && !m_surface->size().isEmpty() ? m_surface->size() : m_size;
+    return m_parent->nearestSurfaceSize();
+}
+
+void TextureMapperNode::computeReplicaTransform()
+{
+    if (!m_state.replicaLayer)
+        return;
+
+    m_nearestSurfaceSize = nearestSurfaceSize();
+
+    if (m_layerType != TransparencyLayer) {
+        m_transforms.replica = TransformationMatrix(m_transforms.target).multLeft(m_state.replicaLayer->m_transforms.local);
+        return;
+    }
+
+    const float originX = m_transforms.target.m41();
+    const float originY = m_transforms.target.m42();
+    m_transforms.replica =
+            TransformationMatrix()
+                .translate(originX, originY)
+                .multLeft(m_state.replicaLayer->m_transforms.local)
+                .translate(-originX, -originY);
+}
+
+void TextureMapperNode::computeTransformations()
+{
+    if (!m_transforms.dirty)
+        return;
+
+    m_transforms.dirty = false;
+    if ((m_size.isEmpty() && m_state.masksToBounds))
+        return;
+
+    TextureMapperNode* parent = m_parent;
+    computeLocalTransform();
+
+    m_transforms.target = TransformationMatrix(parent ? parent->m_transforms.forDescendants : TransformationMatrix()).multLeft(m_transforms.local);
+    m_transforms.forDescendants = (m_layerType == ClipLayer ? TransformationMatrix() : m_transforms.target);
+
+    if (m_effectTarget)
+        return;
+
+    m_transforms.targetBoundingRect = IntRect(m_transforms.target.mapRect(entireRect()));
+    if (m_state.replicaLayer)
+        m_state.replicaLayer->computeTransformations();
+
+    flattenTo2DSpaceIfNecessary();
+
+    if (!m_state.backfaceVisibility && m_transforms.target.inverse().m33() < 0) {
+        m_state.visible = false;
+        return;
+    }
+    m_state.visible = true;
+
+    if (parent && parent->m_state.preserves3D)
+        m_transforms.centerZ = m_transforms.target.mapPoint(FloatPoint3D(m_size.width() / 2, m_size.height() / 2, 0)).z();
+
+    if (!m_children.size())
+        return;
+
+    if (m_state.childrenTransform.isIdentity())
+        return;
+
+    const FloatPoint centerPoint = FloatPoint(m_size.width() / 2, m_size.height() / 2);
+    if (m_transforms.perspectiveDirty)
+        m_transforms.perspective = TransformationMatrix()
+            .translate(centerPoint.x(), centerPoint.y())
+            .multLeft(m_state.childrenTransform)
+            .translate(-centerPoint.x(), -centerPoint.y());
+    m_transforms.perspectiveDirty = false;
+    m_transforms.forDescendants.multLeft(m_transforms.perspective);
+}
+
+void TextureMapperNode::uploadTextureFromContent(TextureMapper* textureMapper, const IntRect& visibleRect, GraphicsLayer* layer)
+{
+    if (m_size.isEmpty() || !layer) {
+        m_texture->destroy();
+        return;
+    }
+
+    if (m_currentContent.contentType == DirectImageContentType) {
+        if (m_currentContent.image)
+            m_texture->setContentsToImage(m_currentContent.image.get());
+        return;
+    }
+
+    if (m_currentContent.contentType == MediaContentType) {
+        if (!m_currentContent.media)
+            return;
+        m_texture->reset(m_size, true);
+        PlatformGraphicsContext* platformContext = m_texture->beginPaintMedia();
+        GraphicsContext context(platformContext);
+        m_currentContent.media->paint(&context);
+        m_texture->endPaint();
+        return;
+    }
+
+    const bool needsReset = (m_texture->contentSize() != m_size) || !m_texture->isValid();
+    if ((m_currentContent.contentType != HTMLContentType)
+        || (!m_currentContent.needsDisplay && m_currentContent.needsDisplayRect.isEmpty() && !needsReset))
+        return;
+
+    IntRect dirtyRect = IntRect(0, 0, m_size.width(), m_size.height());
+    if (!needsReset && !m_currentContent.needsDisplay)
+        dirtyRect.intersect(m_currentContent.needsDisplayRect);
+
+    if (needsReset)
+        m_texture->reset(m_size, m_state.contentsOpaque);
+
+    {
+        GraphicsContext context(m_texture->beginPaint(dirtyRect));
+        if (textureMapper) {
+            context.setImageInterpolationQuality(textureMapper->imageInterpolationQuality());
+            context.setTextDrawingMode(textureMapper->textDrawingMode());
+        }
+        layer->paintGraphicsLayerContents(context, dirtyRect);
+    }
+    m_texture->endPaint();
+    m_currentContent.needsDisplay = false;
+}
+
+
+void TextureMapperNode::paint(TextureMapper* textureMapper, const TextureMapperContentLayer::PaintOptions& options)
+{
+    ASSERT(m_layerType == RootLayer);
+    if (m_size.isEmpty())
+        return;
+
+    TexmapPaintOptions opt;
+    opt.opacity = 1;
+    opt.rootLayer = this;
+    opt.scissorRect = options.targetRect;
+    opt.visibleRect = options.visibleRect;
+    opt.textureMapper = textureMapper;
+    opt.surface = 0;
+    opt.cache = m_cache;
+    paintRecursive(opt);
+
+    if (textureMapper->allowSurfaceForRoot() || m_state.hasSurfaceDescendants) {
+        textureMapper->bindSurface(0);
+        textureMapper->paintToTarget(*m_surface.get(), options.viewportSize, options.transform, options.opacity * m_state.opacity, options.targetRect);
+    }
+    m_cache->purge();
+}
+
+void TextureMapperNode::paintSelf(const TexmapPaintOptions& options)
+{
+    if (m_size.isEmpty() || (!m_state.drawsContent && m_currentContent.contentType == HTMLContentType))
+        return;
+
+    RefPtr<BitmapTexture> replicaMaskTexture;
+    m_texture->unpack();
+
+    RefPtr<BitmapTexture> maskTexture = m_state.maskLayer ? m_state.maskLayer->m_texture : 0;
+    if (m_state.replicaLayer && m_state.replicaLayer->m_state.maskLayer)
+        replicaMaskTexture = m_state.replicaLayer->m_state.maskLayer->m_texture;
+
+    if (maskTexture)
+        maskTexture->unpack();
+
+    if (replicaMaskTexture)
+        replicaMaskTexture->unpack();
+
+    const float opacity = options.isSurface ? 1 : options.opacity;
+
+    if (m_state.replicaLayer && !options.isSurface)
+        options.textureMapper->drawTexture(*m_texture.get(), replicaRect(), m_transforms.replica,
+                         opacity * m_state.replicaLayer->m_state.opacity,
+                         replicaMaskTexture ? replicaMaskTexture.get() : maskTexture.get());
+
+    const IntRect rect = m_layerType == ClipLayer ? entireRect() : targetRect();
+    const TransformationMatrix transform = m_layerType == ClipLayer ? TransformationMatrix() : m_transforms.target;
+    options.textureMapper->drawTexture(*m_texture.get(), rect, transform, opacity, options.isSurface ? 0 : maskTexture.get());
+    options.cache->mark(m_texture.get());
+}
+
+bool TextureMapperNode::paintReplica(const TexmapPaintOptions& options)
+{
+    BitmapTexture& texture = *m_surface.get();
+    TextureMapperNode* replica = m_state.replicaLayer;
+    RefPtr<BitmapTexture> maskTexture;
+    if (TextureMapperNode* mask = m_state.maskLayer)
+        maskTexture = mask->m_texture;
+    RefPtr<BitmapTexture> replicaMaskTexture;
+    if (!replica)
+        return false;
+
+    if (replica && replica->m_state.maskLayer)
+        replicaMaskTexture = replica->m_state.maskLayer->m_texture;
+
+    if (replicaMaskTexture)
+        replicaMaskTexture->unpack();
+    ASSERT(m_replicaSurface);
+    m_replicaSurface->reset(options.surface->size());
+    m_replicaSurface->setOffset(options.surface->offset());
+    options.cache->mark(m_replicaSurface.get());
+    options.textureMapper->bindSurface(m_replicaSurface.get());
+    options.textureMapper->drawTexture(texture, replicaRect(), m_transforms.replica, replica->m_state.opacity, replicaMaskTexture ? replicaMaskTexture.get() : maskTexture.get());
+    options.textureMapper->drawTexture(texture, IntRect(IntPoint(0, 0), options.surface->size()), TransformationMatrix(), 1.0f, maskTexture.get());
+    options.textureMapper->bindSurface(options.surface);
+    options.cache->mark(options.surface);
+    options.textureMapper->drawTexture(*m_replicaSurface.get(), IntRect(IntPoint(0, 0), options.surface->size()), TransformationMatrix(), options.opacity, 0);
+    return true;
+}
+
+void TextureMapperNode::paintSurface(const TexmapPaintOptions& options)
+{
+    if (m_layerType == RootLayer || m_layerType == DefaultLayer || m_layerType == ScissorLayer)
+        return;
+
+    RefPtr<BitmapTexture> maskTexture;
+    if (TextureMapperNode* mask = m_state.maskLayer)
+        maskTexture = mask->m_texture;
+
+    ASSERT(m_surface);
+    BitmapTexture& texture = *m_surface.get();
+    if (maskTexture)
+        maskTexture->unpack();
+    texture.unpack();
+
+    if (paintReplica(options))
+        return;
+
+    options.textureMapper->bindSurface(options.surface);
+    options.textureMapper->drawTexture(texture,
+                             m_layerType == TransparencyLayer ? IntRect(IntPoint(0, 0), options.surface->size()) :
+                             targetRect(),
+                             m_layerType == TransparencyLayer ? TransformationMatrix() : m_transforms.target,
+                             options.opacity, maskTexture.get());
+    options.cache->mark(&texture);
+}
+
+void TextureMapperNode::paintSelfAndChildren(const TexmapPaintOptions& options, TexmapPaintOptions& optionsForDescendants)
+{
+    bool didPaintSelf = false;
+    if (!m_state.preserves3D || m_children.isEmpty()) {
+        paintSelf(options);
+        didPaintSelf = true;
+    }
+
+    if (m_children.isEmpty() && !options.isSurface)
+        return;
+
+    if (m_layerType == ScissorLayer)
+        optionsForDescendants.scissorRect.intersect(m_transforms.target.mapRect(IntRect(0, 0, m_size.width(), m_size.height())));
+
+    for (int i = 0; i < m_children.size(); ++i) {
+        TextureMapperNode* layer = m_children[i];
+        if (!layer)
+            continue;
+
+        if (!didPaintSelf && layer->m_transforms.centerZ >= 0) {
+            paintSelf(options);
+            didPaintSelf = true;
+        }
+        layer->paintRecursive(optionsForDescendants);
+        if (options.isSurface) {
+            ASSERT(m_surface);
+            options.cache->mark(m_surface.get());
+            options.textureMapper->bindSurface(m_surface.get());
+        }
+    }
+    if (!didPaintSelf) {
+        paintSelf(options);
+        didPaintSelf = true;
+    }
+}
+
+void TextureMapperNode::paintRecursive(TexmapPaintOptions options)
+{
+    bool isDirty = m_state.dirty;
+    m_state.dirty = false;
+
+    if ((m_size.isEmpty() && (m_state.masksToBounds
+        || m_children.isEmpty())) || !m_state.visible || options.opacity < 0.01 || m_state.opacity < 0.01)
+        return;
+
+    computeReplicaTransform();
+
+    if (m_state.maskLayer)
+        m_state.maskLayer->m_state.dirty = false;
+
+    if (m_state.replicaLayer) {
+        m_state.replicaLayer->m_state.dirty = false;
+        if (m_state.replicaLayer->m_state.maskLayer)
+            m_state.replicaLayer->m_state.maskLayer->m_state.dirty = false;
+    }
+
+    const bool isSurface = (m_layerType == ClipLayer
+                            || m_layerType == TransparencyLayer
+                            || (m_layerType == RootLayer
+                                && (options.textureMapper->allowSurfaceForRoot() || m_state.hasSurfaceDescendants)
+                                ));
+
+    const IntRect boundingRectfromNearestSurface = m_transforms.targetBoundingRect;
+
+    options.opacity *= m_state.opacity;
+
+    TexmapPaintOptions optionsForDescendants(options);
+    optionsForDescendants.opacity = isSurface ? 1 : options.opacity;
+    options.isSurface = isSurface;
+
+    if (m_layerType == ClipLayer) {
+        optionsForDescendants.visibleRect = TransformationMatrix().translate(-boundingRectfromNearestSurface.x(), -boundingRectfromNearestSurface.y()).mapRect(options.visibleRect);
+        optionsForDescendants.scissorRect = IntRect(0, 0, m_size.width(), m_size.height());
+    }
+
+    if (m_layerType == ScissorLayer)
+        optionsForDescendants.scissorRect.intersect(m_transforms.targetBoundingRect);
+    options.textureMapper->setClip(optionsForDescendants.scissorRect);
+
+    TextureMapperCacheLock(m_texture.get());
+    TextureMapperCacheLock(m_surface.get());
+    TextureMapperCacheLock(m_replicaSurface.get());
+
+    options.cache->purge();
+
+    if (isSurface) {
+        ASSERT(m_surface);
+        if (!m_surface->isValid())
+            isDirty = true;
+        if (m_state.tiled) {
+            m_surface->reset(options.visibleRect.size());
+            m_surface->setOffset(options.visibleRect.location());
+        } else if (isDirty)
+            m_surface->reset(m_layerType == TransparencyLayer ? options.surface->size() : m_size);
+        options.cache->mark(m_surface.get());
+        options.textureMapper->bindSurface(m_surface.get());
+        optionsForDescendants.surface = m_surface.get();
+    } else if (m_surface)
+        m_surface->destroy();
+
+    if (isDirty || !isSurface || m_state.tiled || !m_surface->isValid())
+        paintSelfAndChildren(options, optionsForDescendants);
+
+    paintSurface(options);
+}
+
+TextureMapperNode::~TextureMapperNode()
+{
+    setNeedsDisplay();
+    {
+        const int childrenSize = m_children.size();
+        for (int i = childrenSize-1; i >= 0; --i) {
+            ASSERT(m_children[i]->m_parent == this);
+            m_children[i]->m_parent = 0;
+        }
+    }
+    if (m_parent)
+        m_parent->m_children.remove(m_parent->m_children.find(this));
+    if (m_cache)
+        delete m_cache;
+}
+
+void TextureMapperNode::performPostSyncOperations()
+{
+    const LayerType prevLayerType = m_layerType;
+    computeLayerType();
+    if (prevLayerType != m_layerType)
+        m_state.dirty = true;
+    if (m_transforms.dirty)
+        setNeedsDisplay();
+
+    computeTransformations();
+    if (m_state.maskLayer && !m_state.dirty)
+        m_state.dirty = m_state.maskLayer->m_state.dirty;
+    if (m_state.replicaLayer && !m_state.dirty)
+        m_state.dirty = m_state.replicaLayer->m_state.dirty;
+
+    const int size = m_children.size();
+
+    for (int i = size - 1; i >= 0; --i) {
+        TextureMapperNode* layer = m_children[i];
+
+        layer->performPostSyncOperations();
+        if (!m_state.dirty)
+            m_state.dirty = layer->m_state.dirty;
+    }
+    m_state.hasSurfaceDescendants = hasSurfaceDescendants();
+    if (m_state.dirty)
+        m_state.descendantsWithContent = countDescendantsWithContent();
+
+    if (m_state.preserves3D)
+        sortByZOrder(m_children, 0, size);
+    if (m_state.dirty)
+        setNeedsDisplay();
+}
+
+void TextureMapperNode::syncCompositingState(GraphicsLayerTextureMapper* graphicsLayer, bool recurse)
+{
+    TextureMapper* textureMapper = rootLayer()->m_platformClient->textureMapper();
+    syncCompositingStateInternal(graphicsLayer, recurse, textureMapper);
+    performPostSyncOperations();
+}
+
+void TextureMapperNode::syncCompositingStateSelf(GraphicsLayerTextureMapper* graphicsLayer, TextureMapper* textureMapper)
+{
+    const int changeMask = graphicsLayer->changeMask();
+    initializeTextureMapper(textureMapper);
+    const TextureMapperNode::ContentData& pendingContent = graphicsLayer->pendingContent();
+    if (changeMask == NoChanges && pendingContent.needsDisplayRect.isEmpty() && !pendingContent.needsDisplay)
+        return;
+
+    setNeedsDisplay();
+    if (m_parent)
+        m_parent->m_state.dirty = true;
+
+    if (m_currentContent.contentType == HTMLContentType && (changeMask & ParentChange)) {
+        // The WebCore compositor manages item ownership. We have to make sure graphicsview doesn't
+        // try to snatch that ownership.
+
+        if (!graphicsLayer->parent())
+            m_parent = 0;
+        else
+            m_parent = toTextureMapperNode(graphicsLayer->parent());
+
+        if (!graphicsLayer->parent() && m_parent) {
+            size_t index = m_parent->m_children.find(this);
+            m_parent->m_children.remove(index);
+        }
+    }
+
+    if (changeMask & ChildrenChange) {
+        m_children.clear();
+        for (size_t i = 0; i < graphicsLayer->children().size(); ++i) {
+            if (TextureMapperNode* child = toTextureMapperNode(graphicsLayer->children()[i])) {
+                if (!child)
+                    continue;
+                m_children.append(child);
+                child->m_parent = this;
+            }
+        }
+        m_state.dirty = true;
+    }
+
+    if (changeMask & (SizeChange | ContentsRectChange)) {
+        IntSize wantedSize = IntSize(graphicsLayer->size().width(), graphicsLayer->size().height());
+        if (wantedSize.isEmpty() && pendingContent.contentType == HTMLContentType)
+            wantedSize = IntSize(graphicsLayer->contentsRect().width(), graphicsLayer->contentsRect().height());
+
+        if (wantedSize != m_size) {
+            m_size = IntSize(wantedSize.width(), wantedSize.height());
+            if (m_platformClient)
+                m_platformClient->setSizeChanged(m_size);
+            const bool needsTiling = m_size.width() > 2000 || m_size.height() > 2000;
+            if (m_state.tiled != needsTiling)
+                m_state.tiled = needsTiling;
+            m_state.dirty = true;
+        }
+    }
+
+    if (changeMask & MaskLayerChange) {
+       if (TextureMapperNode* layer = toTextureMapperNode(graphicsLayer->maskLayer()))
+           layer->m_effectTarget = this;
+    }
+
+    if (changeMask & ReplicaLayerChange) {
+       if (TextureMapperNode* layer = toTextureMapperNode(graphicsLayer->replicaLayer()))
+           layer->m_effectTarget = this;
+    }
+
+    if (changeMask & (TransformChange | SizeChange | AnchorPointChange | PositionChange))
+        m_transforms.localDirty = true;
+
+    if (changeMask & (ChildrenTransformChange | SizeChange))
+        m_transforms.perspectiveDirty = true;
+
+    if (changeMask & (ChildrenTransformChange | Preserves3DChange | TransformChange | AnchorPointChange | SizeChange | ContentsRectChange | BackfaceVisibilityChange | PositionChange | MaskLayerChange | DrawsContentChange | ContentChange | ReplicaLayerChange))    {
+        // Due to the differences between the way WebCore handles transforms and the way Qt handles transforms,
+        // all these elements affect the transforms of all the descendants.
+        invalidateTransform();
+    }
+
+    if (changeMask & DisplayChange)
+        m_state.dirty = true;
+
+    m_state.maskLayer = toTextureMapperNode(graphicsLayer->maskLayer());
+    m_state.replicaLayer = toTextureMapperNode(graphicsLayer->replicaLayer());
+    m_state.pos = graphicsLayer->position();
+    m_state.anchorPoint = graphicsLayer->anchorPoint();
+    m_state.size = graphicsLayer->size();
+    m_state.transform = graphicsLayer->transform();
+    m_state.contentsRect = graphicsLayer->contentsRect();
+    m_state.opacity = graphicsLayer->opacity();
+    m_state.contentsRect = graphicsLayer->contentsRect();
+    m_state.preserves3D = graphicsLayer->preserves3D();
+    m_state.masksToBounds = graphicsLayer->masksToBounds();
+    m_state.drawsContent = graphicsLayer->drawsContent();
+    m_state.contentsOpaque = graphicsLayer->contentsOpaque();
+    m_state.backfaceVisibility = graphicsLayer->backfaceVisibility();
+    m_state.childrenTransform = graphicsLayer->childrenTransform();
+    m_currentContent.contentType = pendingContent.contentType;
+    m_currentContent.image = pendingContent.image;
+    m_currentContent.media = pendingContent.media;
+    m_currentContent.backgroundColor = pendingContent.backgroundColor;
+    m_currentContent.needsDisplay = m_currentContent.needsDisplay || pendingContent.needsDisplay;
+    m_currentContent.needsDisplayRect.unite(pendingContent.needsDisplayRect);
+
+}
+
+void TextureMapperNode::syncCompositingStateInternal(GraphicsLayerTextureMapper* graphicsLayer, bool recurse, TextureMapper* textureMapper)
+{
+    syncCompositingStateSelf(graphicsLayer, textureMapper);
+
+    graphicsLayer->didSynchronize();
+
+    if (m_state.maskLayer) {
+        m_state.maskLayer->syncCompositingStateInternal(toGraphicsLayerTextureMapper(graphicsLayer->maskLayer()), false, textureMapper);
+        if (m_state.maskLayer->m_size.isEmpty())
+            m_state.maskLayer->m_size = m_size;
+    }
+
+    if (m_state.replicaLayer)
+        m_state.replicaLayer->syncCompositingStateInternal(toGraphicsLayerTextureMapper(graphicsLayer->replicaLayer()), false, textureMapper);
+
+    if (m_state.dirty)
+        uploadTextureFromContent(textureMapper, m_state.visibleRect, graphicsLayer);
+
+    m_currentContent.needsDisplayRect = IntRect();
+    m_currentContent.needsDisplay = false;
+
+    if (!recurse)
+        return;
+
+    Vector<GraphicsLayer*> children = graphicsLayer->children();
+    for (int i = children.size() - 1; i >= 0; --i) {
+        TextureMapperNode* node = toTextureMapperNode(children[i]);
+        if (!node)
+            continue;
+        node->syncCompositingStateInternal(toGraphicsLayerTextureMapper(children[i]), true, textureMapper);
+    }
+}
+
+}
diff --git a/WebCore/platform/graphics/texmap/TextureMapperNode.h b/WebCore/platform/graphics/texmap/TextureMapperNode.h
new file mode 100644
index 0000000..9694043
--- /dev/null
+++ b/WebCore/platform/graphics/texmap/TextureMapperNode.h
@@ -0,0 +1,252 @@
+/*
+ Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB.  If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+ */
+
+#ifndef TextureMapperNode_h
+#define TextureMapperNode_h
+
+#include "CurrentTime.h"
+#include "FloatRect.h"
+#include "GraphicsContext.h"
+#include "GraphicsLayer.h"
+#include "HashMap.h"
+#include "Image.h"
+#include "RefCounted.h"
+#include "TextureMapper.h"
+#include "TextureMapperPlatformLayer.h"
+#include "Timer.h"
+#include "TransformOperations.h"
+#include "TranslateTransformOperation.h"
+#include "UnitBezier.h"
+
+namespace WebCore {
+
+class TextureMapperNode;
+class TextureMapperCache;
+class GraphicsLayerTextureMapper;
+
+struct TexmapPaintOptions {
+    BitmapTexture* surface;
+    TextureMapper* textureMapper;
+    TextureMapperNode* rootLayer;
+    float opacity;
+    IntRect scissorRect;
+    IntRect visibleRect;
+    bool isSurface;
+    TextureMapperCache* cache;
+};
+
+class TextureMapperNode : public TextureMapperContentLayer {
+
+public:
+    // This set of flags help us defer which properties of the layer have been
+    // modified by the compositor, so we can know what to look for in the next flush.
+    enum ChangeMask {
+        NoChanges =                 0,
+
+        ParentChange =              (1L << 0),
+        ChildrenChange =            (1L << 1),
+        MaskLayerChange =           (1L << 2),
+        PositionChange =            (1L << 3),
+
+        AnchorPointChange =         (1L << 4),
+        SizeChange  =               (1L << 5),
+        TransformChange =           (1L << 6),
+        ContentChange =             (1L << 7),
+
+        ContentsOrientationChange = (1L << 9),
+        OpacityChange =             (1L << 10),
+        ContentsRectChange =        (1L << 11),
+
+        Preserves3DChange =         (1L << 12),
+        MasksToBoundsChange =       (1L << 13),
+        DrawsContentChange =        (1L << 14),
+        ContentsOpaqueChange =      (1L << 15),
+
+        BackfaceVisibilityChange =  (1L << 16),
+        ChildrenTransformChange =   (1L << 17),
+        DisplayChange =             (1L << 18),
+        BackgroundColorChange =     (1L << 19),
+
+        ReplicaLayerChange =        (1L << 20)
+    };
+    // The compositor lets us special-case images and colors, so we try to do so.
+    enum ContentType { HTMLContentType, DirectImageContentType, ColorContentType, MediaContentType, Canvas3DContentType};
+    struct ContentData {
+        IntRect needsDisplayRect;
+        bool needsDisplay;
+        Color backgroundColor;
+
+        ContentType contentType;
+        RefPtr<Image> image;
+        TextureMapperVideoLayer* media;
+
+        ContentData()
+            : needsDisplay(false)
+            , contentType(HTMLContentType)
+            , image(0)
+            , media(0)
+        {
+        }
+    };
+
+
+    TextureMapperNode();
+    virtual ~TextureMapperNode();
+
+    void syncCompositingState(GraphicsLayerTextureMapper*, bool recursive);
+
+protected:
+    // Reimps from TextureMapperContentLayer
+    virtual IntSize size() const { return m_size; }
+    virtual void setPlatformLayerClient(TextureMapperLayerClient*);
+    virtual void paint(TextureMapper*, const TextureMapperContentLayer::PaintOptions&);
+
+private:
+    TextureMapperNode* rootLayer();
+    void clearDirectImage();
+    void computeTransformations();
+    IntSize nearestSurfaceSize() const;
+    void computeReplicaTransform();
+    void computeLayerType();
+    void computeLocalTransform();
+    void flattenTo2DSpaceIfNecessary();
+    void initializeTextureMapper(TextureMapper*);
+    void invalidateTransform();
+    void notifyChange(ChangeMask);
+    void setNeedsDisplay();
+    void setNeedsDisplayInRect(IntRect);
+    void performPostSyncOperations();
+    void syncCompositingStateInternal(GraphicsLayerTextureMapper*, bool recursive, TextureMapper*);
+    void syncCompositingStateSelf(GraphicsLayerTextureMapper* graphicsLayer, TextureMapper* textureMapper);
+    TextureMapperCache* cache();
+
+    void paintRecursive(TexmapPaintOptions options);
+    bool paintReplica(const TexmapPaintOptions& options);
+    void paintSurface(const TexmapPaintOptions& options);
+    void paintSelf(const TexmapPaintOptions& options);
+    void paintSelfAndChildren(const TexmapPaintOptions& options, TexmapPaintOptions& optionsForDescendants);
+    void uploadTextureFromContent(TextureMapper* textureMapper, const IntRect& visibleRect, GraphicsLayer* layer);
+
+    int countDescendantsWithContent() const;
+    bool hasSurfaceDescendants() const;
+
+    TextureMapper* textureMapper();
+
+
+    static TextureMapperNode* toTextureMapperNode(GraphicsLayer*);
+    static int compareGraphicsLayersZValue(const void* a, const void* b);
+    static void sortByZOrder(Vector<TextureMapperNode* >& array, int first, int last);
+    struct TransformData {
+        TransformationMatrix base, target, replica, forDescendants, perspective, local;
+        IntRect targetBoundingRect;
+        float centerZ;
+        bool dirty, localDirty, perspectiveDirty;
+        IntRect boundingRectFromRoot;
+        TransformData() : dirty(true), localDirty(true), perspectiveDirty(true) { }
+    };
+
+    TransformData m_transforms;
+
+    enum LayerType {
+        DefaultLayer,
+        RootLayer,
+        ScissorLayer,
+        ClipLayer,
+        TransparencyLayer
+    };
+
+    LayerType m_layerType;
+
+    inline IntRect targetRect() const
+    {
+        return m_currentContent.contentType == HTMLContentType ? entireRect() : m_state.contentsRect;
+    }
+
+    inline IntRect entireRect() const
+    {
+        return IntRect(0, 0, m_size.width(), m_size.height());
+    }
+
+    inline IntRect replicaRect() const
+    {
+        return m_layerType == TransparencyLayer ? IntRect(0, 0, m_nearestSurfaceSize.width(), m_nearestSurfaceSize.height()) : entireRect();
+    }
+
+    RefPtr<BitmapTexture> m_texture;
+    RefPtr<BitmapTexture> m_surface, m_replicaSurface;
+
+    ContentData m_currentContent;
+
+    Vector<TextureMapperNode*> m_children;
+    TextureMapperNode* m_parent;
+    TextureMapperNode* m_effectTarget;
+    IntSize m_size, m_nearestSurfaceSize;
+    String m_name;
+    TextureMapperLayerClient* m_platformClient;
+
+    struct State {
+        FloatPoint pos;
+        FloatPoint3D anchorPoint;
+        FloatSize size;
+        TransformationMatrix transform;
+        TransformationMatrix childrenTransform;
+        Color backgroundColor;
+        Color currentColor;
+        GraphicsLayer::CompositingCoordinatesOrientation geoOrientation;
+        GraphicsLayer::CompositingCoordinatesOrientation contentsOrientation;
+        float opacity;
+        IntRect contentsRect;
+        int descendantsWithContent;
+        TextureMapperNode* maskLayer;
+        TextureMapperNode* replicaLayer;
+        bool preserves3D;
+        bool masksToBounds;
+        bool drawsContent;
+        bool contentsOpaque;
+        bool backfaceVisibility;
+        bool visible;
+        bool dirty;
+        bool tiled;
+        bool hasSurfaceDescendants;
+        IntRect visibleRect;
+
+        State()
+            : opacity(1.f)
+            , descendantsWithContent(0)
+            , maskLayer(0)
+            , replicaLayer(0)
+            , preserves3D(false)
+            , masksToBounds(false)
+            , drawsContent(false)
+            , contentsOpaque(false)
+            , backfaceVisibility(false)
+            , visible(true)
+            , dirty(true)
+            , tiled(false)
+            , hasSurfaceDescendants(false)
+        {
+        }
+    };
+
+    State m_state;
+    TextureMapperCache* m_cache;
+};
+
+}
+#endif // TextureMapperNode_h
diff --git a/WebCore/platform/graphics/texmap/TextureMapperPlatformLayer.h b/WebCore/platform/graphics/texmap/TextureMapperPlatformLayer.h
index a15681c..2a38b90 100644
--- a/WebCore/platform/graphics/texmap/TextureMapperPlatformLayer.h
+++ b/WebCore/platform/graphics/texmap/TextureMapperPlatformLayer.h
@@ -36,6 +36,7 @@ public:
     virtual void setNeedsDisplay() = 0;
     virtual void setNeedsDisplayInRect(const IntRect& rect) = 0;
     virtual void setSizeChanged(const IntSize&) = 0;
+    virtual TextureMapper* textureMapper() = 0;
 };
 
 class TextureMapperPlatformLayer {
diff --git a/WebKit/qt/Api/qwebframe.cpp b/WebKit/qt/Api/qwebframe.cpp
index 63cd7f7..7d423d5 100644
--- a/WebKit/qt/Api/qwebframe.cpp
+++ b/WebKit/qt/Api/qwebframe.cpp
@@ -309,9 +309,6 @@ void QWebFramePrivate::renderCompositedLayers(GraphicsContext* context, const In
     if (!rootGraphicsLayer)
         return;
 
-    if (!textureMapper)
-        textureMapper = TextureMapper::create(context);
-
     textureMapper->setGraphicsContext(context);
     textureMapper->setImageInterpolationQuality(context->imageInterpolationQuality());
     textureMapper->setTextDrawingMode(context->textDrawingMode());
diff --git a/WebKit/qt/Api/qwebframe_p.h b/WebKit/qt/Api/qwebframe_p.h
index 634e21b..7c0d235 100644
--- a/WebKit/qt/Api/qwebframe_p.h
+++ b/WebKit/qt/Api/qwebframe_p.h
@@ -113,7 +113,7 @@ public:
     int marginHeight;
 #if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER)
     WebCore::TextureMapperContentLayer* rootGraphicsLayer;
-    RefPtr<WebCore::TextureMapper> textureMapper;
+    OwnPtr<WebCore::TextureMapper> textureMapper;
 #endif
     bool zoomTextOnly;
 };
diff --git a/WebKit/qt/ChangeLog b/WebKit/qt/ChangeLog
index 872ead1..8ba9a5c 100644
--- a/WebKit/qt/ChangeLog
+++ b/WebKit/qt/ChangeLog
@@ -1,3 +1,22 @@
+2010-11-08  Noam Rosenthal  <noam.rosenthal at nokia.com>
+
+        Reviewed by Kenneth Rohde Christiansen.
+
+        [Texmap] [Qt] Texture mapper initial implementation
+        https://bugs.webkit.org/show_bug.cgi?id=47070
+
+        Reorganized the textureMapper to be a member of QWebFramePrivate, to help with making
+        TextureMapper thread-safe.
+
+        * Api/qwebframe.cpp:
+        (QWebFramePrivate::renderCompositedLayers):
+        * Api/qwebframe_p.h:
+        * WebCoreSupport/PageClientQt.cpp:
+        (WebCore::PlatformLayerProxyQt::setTextureMapper):
+        (WebCore::PlatformLayerProxyQt::textureMapper):
+        (WebCore::PlatformLayerProxyQWidget::PlatformLayerProxyQWidget):
+        (WebCore::PlatformLayerProxyQGraphicsObject::PlatformLayerProxyQGraphicsObject):
+
 2010-11-07  Adam Barth  <abarth at webkit.org>
 
         Reviewed by Eric Seidel.
diff --git a/WebKit/qt/WebCoreSupport/PageClientQt.cpp b/WebKit/qt/WebCoreSupport/PageClientQt.cpp
index 4d42c39..9fa5bf7 100644
--- a/WebKit/qt/WebCoreSupport/PageClientQt.cpp
+++ b/WebKit/qt/WebCoreSupport/PageClientQt.cpp
@@ -21,15 +21,19 @@
 #include "config.h"
 
 #include "PageClientQt.h"
+#include "TextureMapperQt.h"
 #include "texmap/TextureMapperPlatformLayer.h"
-
+#include <QGraphicsScene>
+#include <QGraphicsView>
 #if defined(Q_WS_X11)
 #include <QX11Info>
 #endif
 
 #ifdef QT_OPENGL_LIB
+#include "opengl/TextureMapperGL.h"
 #include <QGLWidget>
 #endif
+
 namespace WebCore {
 
 #if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER)    
@@ -45,6 +49,11 @@ public:
         m_frame->d->rootGraphicsLayer = m_layer;
     }
 
+    void setTextureMapper(PassOwnPtr<TextureMapper> textureMapper)
+    {
+        m_frame->d->textureMapper = textureMapper;
+    }
+
     virtual ~PlatformLayerProxyQt()
     {
         if (m_layer)
@@ -53,6 +62,11 @@ public:
             m_frame->d->rootGraphicsLayer = 0;
     }
 
+    virtual TextureMapper* textureMapper()
+    {
+        return m_frame->d->textureMapper.get();
+    }
+
     // Since we just paint the composited tree and never create a special item for it, we don't have to handle its size changes.
     void setSizeChanged(const IntSize&) { }
 
@@ -69,6 +83,11 @@ public:
     {
         if (m_widget)
             m_widget->installEventFilter(this);
+
+        if (textureMapper())
+            return;
+
+        setTextureMapper(TextureMapperQt::create());
     }
 
     // We don't want a huge region-clip on the compositing layers; instead we unite the rectangles together
@@ -103,6 +122,17 @@ public:
         : PlatformLayerProxyQt(frame, layer, object)
         , m_graphicsItem(object)
     {
+        if (textureMapper())
+            return;
+
+#ifdef QT_OPENGL_LIB
+        QGraphicsView* view = object->scene()->views()[0];
+        if (view && view->viewport() && view->viewport()->inherits("QGLWidget")) {
+            setTextureMapper(TextureMapperGL::create());
+            return;
+        }
+#endif
+        setTextureMapper(TextureMapperQt::create());
     }
 
     void setNeedsDisplay()

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list