Changeset 71538 in webkit


Ignore:
Timestamp:
Nov 8, 2010 10:04:58 AM (13 years ago)
Author:
noam.rosenthal@nokia.com
Message:

[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.
Location:
trunk
Files:
4 added
14 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r71537 r71538  
     12010-11-08  Noam Rosenthal  <noam.rosenthal@nokia.com>
     2
     3        Reviewed by Kenneth Rohde Christiansen.
     4
     5        [Texmap] [Qt] Texture mapper initial implementation
     6        https://bugs.webkit.org/show_bug.cgi?id=47070
     7
     8        Added a test that includes several composited layers, containing pixel data that's larger
     9        than 24MB, which is the default value for TextureMapper's cache. This tests the video memory
     10        ceiling functionality of TextureMapper, as purging that cache would kick in whe running this test.
     11
     12        * compositing/layer-creation/many-layers.html: Added.
     13
    1142010-11-08  Tony Chang  <tony@chromium.org>
    215
  • trunk/WebCore/ChangeLog

    r71536 r71538  
     12010-11-08  Noam Rosenthal  <noam.rosenthal@nokia.com>
     2
     3        Reviewed by Kenneth Rohde Christiansen.
     4
     5        [Texmap] [Qt] Texture mapper initial implementation
     6        https://bugs.webkit.org/show_bug.cgi?id=47070
     7
     8        Make the necessary changes in TextureMapperNode in preparation of making it possible to paint it
     9        from a different thread.
     10        The main problematic part was the cache, which made it so that textures can become invalid and have to
     11        be rerendered from content during paint. This is solved here by creating a pack/unpack function for
     12        textures, which lets a texture archive its data away from video memory, or do whatever the platform
     13        thinks is right for freeing memory without needing to re-render again from content (which cannot be
     14        made thread safe).
     15
     16        After this change, TextureMapperNode moved to its own file, and has 2 entry points: paint and syncCompositingState.
     17        The idea is that syncCompositingState has to be called in the UI thread, paint can be called from a different
     18        thread, and they should block each other.
     19
     20        The new test tests the cache code-path, to show that the pack/unpack technique works for cases where it
     21        kicks in.
     22
     23        Test: compositing/layer-creation/many-layers.html
     24
     25        * WebCore.pro:
     26        * platform/graphics/opengl/TextureMapperGL.cpp:
     27        (WebCore::BitmapTextureGL::~BitmapTextureGL):
     28        (WebCore::BitmapTextureGL::BitmapTextureGL):
     29        (WebCore::TextureMapperGL::TextureMapperGL):
     30        (WebCore::TextureMapperGL::drawTexture):
     31        * platform/graphics/opengl/TextureMapperGL.h:
     32        (WebCore::TextureMapperGL::create):
     33        * platform/graphics/qt/TextureMapperQt.cpp:
     34        (WebCore::BitmapTextureQt::pack):
     35        (WebCore::BitmapTextureQt::unpack):
     36        (WebCore::TextureMapper::create):
     37        (WebCore::BitmapTextureQt::BitmapTextureQt):
     38        * platform/graphics/qt/TextureMapperQt.h: Added.
     39
    1402010-11-08  Simon Fraser  <simon.fraser@apple.com>
    241
  • trunk/WebCore/WebCore.pro

    r71515 r71538  
    38583858    DEFINES += WTF_USE_TEXTURE_MAPPER=1
    38593859    HEADERS += \
     3860        platform/graphics/qt/TextureMapperQt.h \
     3861        platform/graphics/texmap/GraphicsLayerTextureMapper.h \
    38603862        platform/graphics/texmap/TextureMapper.h \
     3863        platform/graphics/texmap/TextureMapperNode.h \
    38613864        platform/graphics/texmap/TextureMapperPlatformLayer.h
    38623865
    38633866    SOURCES += \
    38643867        platform/graphics/qt/TextureMapperQt.cpp \
     3868        platform/graphics/texmap/TextureMapperNode.cpp \
    38653869        platform/graphics/texmap/GraphicsLayerTextureMapper.cpp
    38663870
  • trunk/WebCore/platform/graphics/opengl/TextureMapperGL.cpp

    r71213 r71538  
    230230    virtual void endPaint();
    231231    virtual void setContentsToImage(Image*);
     232    ~BitmapTextureGL() { destroy(); }
    232233
    233234private:
     
    242243    IntSize m_actualSize;
    243244    bool m_surfaceNeedsReset;
    244     RefPtr<TextureMapperGL> m_textureMapper;
     245    TextureMapperGL* m_textureMapper;
    245246    BitmapTextureGL()
    246247        : m_id(0)
     
    249250        , m_fbo(0)
    250251        , m_surfaceNeedsReset(true)
     252        , m_textureMapper(0)
    251253    {
    252254    }
     
    266268{
    267269    static bool shadersCompiled = false;
     270    obtainCurrentContext();
    268271    if (shadersCompiled)
    269272        return;
     
    417420                                         0, 0, 1, 0,
    418421                                         0, 0, 0, 1};
    419         glUniformMatrix4fv(programInfo.vars[TextureMapperGLData::ShaderInfo::InMaskMatrixVariable], 1, GL_FALSE, m4mask);
     422        GL_CMD(glUniformMatrix4fv(programInfo.vars[TextureMapperGLData::ShaderInfo::InMaskMatrixVariable], 1, GL_FALSE, m4mask));
    420423        GL_CMD(glUniform1i(programInfo.vars[TextureMapperGLData::ShaderInfo::MaskTextureVariable], 1))
    421424        GL_CMD(glActiveTexture(GL_TEXTURE0))
    422425    }
    423 
    424426
    425427    if (textureGL.m_opaque && opacity > 0.99 && !maskTexture)
     
    432434    GL_CMD(glDrawArrays(GL_TRIANGLE_FAN, 0, 4))
    433435}
    434 
    435436
    436437const char* TextureMapperGL::type() const
  • trunk/WebCore/platform/graphics/opengl/TextureMapperGL.h

    r71213 r71538  
    4848    void obtainCurrentContext();
    4949    bool makeContextCurrent();
     50    static PassOwnPtr<TextureMapperGL> create()
     51    {
     52        return new TextureMapperGL;
     53    }
    5054
    5155private:
  • trunk/WebCore/platform/graphics/qt/TextureMapperQt.cpp

    r71213 r71538  
    1919
    2020#include "config.h"
    21 #include "texmap/TextureMapper.h"
     21#include "TextureMapperQt.h"
    2222
    2323#include <QtCore/qdebug.h>
     
    3030
    3131namespace WebCore {
    32 
    33 class BitmapTextureQt : public BitmapTexture {
    34     friend class TextureMapperQt;
    35 public:
    36     BitmapTextureQt() {}
    37     virtual void destroy();
    38     virtual IntSize size() const { return IntSize(m_pixmap.width(), m_pixmap.height()); }
    39     virtual void reset(const IntSize&, bool opaque);
    40     virtual PlatformGraphicsContext* beginPaint(const IntRect& dirtyRect);
    41     virtual void endPaint();
    42     virtual void setContentsToImage(Image*);
    43     virtual bool save(const String& path);
    44     virtual bool isValid() const { return !m_pixmap.isNull(); }
    45     virtual bool allowOfflineTextureUpload() const { return true; }
    46     IntRect sourceRect() const { return IntRect(0, 0, contentSize().width(), contentSize().height()); }
    47 private:
    48     QPainter m_painter;
    49     QPixmap m_pixmap;
    50 };
    51 
    52 class TextureMapperQt : public TextureMapper {
    53 public:
    54     virtual void drawTexture(const BitmapTexture& texture, const IntRect& targetRect, const TransformationMatrix& matrix, float opacity, const BitmapTexture* maskTexture);
    55     virtual void bindSurface(BitmapTexture* surface);
    56     virtual void setClip(const IntRect&);
    57     virtual void setGraphicsContext(GraphicsContext*);
    58     virtual bool allowSurfaceForRoot() const { return false; }
    59     TextureMapperQt();
    60     virtual const char* type() const { return "TextureMapperQt"; }
    61     virtual PassRefPtr<BitmapTexture> createTexture();
    62 
    63     static void initialize(QPainter* painter)
    64     {
    65         painter->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform, false);
    66     }
    67 
    68 private:
    69     QPainter* m_painter;
    70     RefPtr<BitmapTextureQt> m_currentSurface;
    71 };
    7232
    7333void BitmapTextureQt::destroy()
     
    11777    BitmapTexture::reset(pixmap->size(), !pixmap->hasAlphaChannel());
    11878    m_pixmap = *pixmap;
     79}
     80
     81void BitmapTextureQt::pack()
     82{
     83    if (m_pixmap.isNull())
     84        return;
     85
     86    m_image = m_pixmap.toImage();
     87    m_pixmap = QPixmap();
     88    m_isPacked = true;
     89}
     90
     91void BitmapTextureQt::unpack()
     92{
     93    m_isPacked = false;
     94    if (m_image.isNull())
     95        return;
     96
     97    m_pixmap = QPixmap::fromImage(m_image);
     98    m_image = QImage();
    11999}
    120100
     
    183163}
    184164
    185 PassRefPtr<TextureMapper> TextureMapper::create(GraphicsContext* context)
     165PassOwnPtr<TextureMapper> TextureMapper::create(GraphicsContext* context)
    186166{
    187167#ifdef QT_OPENGL_LIB
    188     if (context->platformContext()->paintEngine()->type() == QPaintEngine::OpenGL2) {
    189         TextureMapperGL* texmapGL = new TextureMapperGL;
    190         return adoptRef(texmapGL);
    191     }
     168    if (context && context->platformContext()->paintEngine()->type() == QPaintEngine::OpenGL2)
     169        return new TextureMapperGL;
    192170#endif
    193     return adoptRef(new TextureMapperQt);
    194 }
    195 
     171    return new TextureMapperQt;
     172}
    196173
    197174PassRefPtr<BitmapTexture> TextureMapperQt::createTexture()
    198175{
    199176    return adoptRef(new BitmapTextureQt());
     177}
     178
     179BitmapTextureQt::BitmapTextureQt()
     180    : m_isPacked(false)
     181{
     182
    200183}
    201184
  • trunk/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.cpp

    r71213 r71538  
    2121#include "GraphicsLayerTextureMapper.h"
    2222
    23 #include "CurrentTime.h"
    24 #include "FloatRect.h"
    25 #include "GraphicsContext.h"
    26 #include "HashMap.h"
    27 #include "Image.h"
    28 #include "RefCounted.h"
    29 #include "TextureMapper.h"
    30 #include "TextureMapperPlatformLayer.h"
    31 #include "Timer.h"
    32 #include "TransformOperations.h"
    33 #include "TranslateTransformOperation.h"
    34 #include "UnitBezier.h"
    35 
    36 #define DEBUG_TEXMAP_FPS 0
     23#include "TextureMapperNode.h"
    3724
    3825namespace WebCore {
    3926
    40 struct TexmapPaintOptions {
    41     BitmapTexture* surface;
    42     TextureMapper* textureMapper;
    43     TextureMapperNode* rootLayer;
    44     float opacity;
    45     IntRect scissorRect;
    46     IntRect visibleRect;
    47     bool isSurface;
    48 };
    49 class TextureMapperCache {
    50 public:
    51     void mark(BitmapTexture* texture);
    52 
    53     class Entry {
    54     public:
    55         RefPtr<BitmapTexture> texture;
    56         Entry() : previousCost(0) { }
    57         inline int calculateCost() const
    58         {
    59             if (!texture || !texture->isValid())
    60                 return 0;
    61             const IntSize textureSize = texture->size();
    62             // an image's cost in bytes is width * height * bytes per pixel (4).
    63             return textureSize.width() * textureSize.height() * 4;
    64         }
    65         Entry(BitmapTexture* newTexture)
    66             : texture(newTexture)
    67         {
    68         }
    69         bool operator==(const Entry& other) const { return texture == other.texture; }
    70         int previousCost;
    71     };
    72 
    73     TextureMapperCache() : m_totalCost(0) {}
    74 
    75     void purge();
    76     Vector<Entry> m_data;
    77     int m_totalCost;
    78 #ifndef TEXMAP_TEXTURE_CACHE_KBS
    79 #define TEXMAP_TEXTURE_CACHE_KBS 24 * 1024
    80 #endif
    81     static const int MaxCost = TEXMAP_TEXTURE_CACHE_KBS * 1024;
    82     static const int PurgeAmount = MaxCost / 4;
    83 };
    84 
    85 
    86 void TextureMapperCache::purge()
    87 {
    88     // If this is in the GL implementation, we need an active GL context, because we might call glDeleteTextures.
    89     const int size = m_data.size();
    90 
    91     if (m_totalCost <= TextureMapperCache::MaxCost)
    92         return;
    93 
    94     // Ensure that we have the right count. It might be inaccurate if content changed size.
    95     // We only do this when we're actually ready to purge.
    96     m_totalCost = 0;
    97     for (int i = 0; i < size; ++i)
    98         m_totalCost += m_data[i].calculateCost();
    99 
    100     for (int i = size-1; i >= 0 && m_totalCost > TextureMapperCache::MaxCost - TextureMapperCache::PurgeAmount; --i) {
    101         Entry& entry = m_data[i];
    102         if (entry.texture->isLocked() || !entry.texture->isValid())
    103             continue;
    104         m_totalCost -= entry.previousCost;
    105         entry.texture->destroy();
    106         m_data.remove(i);
    107     }
    108 }
    109 
    110 void TextureMapperCache::mark(BitmapTexture* texture)
    111 {
    112     if (!texture || !texture->isValid())
    113         return;
    114 
    115     Entry entry(texture);
    116     size_t index = m_data.find(entry);
    117     if (!index)
    118         return;
    119 
    120     if (index < m_data.size())
    121         m_data.remove(index);
    122     const int cost = entry.calculateCost();
    123     m_totalCost -= entry.previousCost;
    124     m_totalCost += (entry.previousCost = cost);
    125     m_data.prepend(entry);
    126 }
    127 
    128 TextureMapperCache gTextureMapperCache;
    129 
    130 class TextureMapperCacheLock {
    131 public:
    132     TextureMapperCacheLock(BitmapTexture* texture) : m_texture(texture)
    133     {
    134         if (m_texture)
    135             m_texture->lock();
    136     }
    137     ~TextureMapperCacheLock()
    138     {
    139         if (m_texture)
    140             m_texture->unlock();
    141     }
    142 
    143 private:
    144     RefPtr<BitmapTexture> m_texture;
    145 };
    146 
    147 class TextureMapperNode : public TextureMapperContentLayer {
    148 
    149 public:
    150     // This set of flags help us defer which properties of the layer have been
    151     // modified by the compositor, so we can know what to look for in the next flush.
    152     enum ChangeMask {
    153         NoChanges =                 0,
    154 
    155         ParentChange =              (1L << 0),
    156         ChildrenChange =            (1L << 1),
    157         MaskLayerChange =           (1L << 2),
    158         PositionChange =            (1L << 3),
    159 
    160         AnchorPointChange =         (1L << 4),
    161         SizeChange  =               (1L << 5),
    162         TransformChange =           (1L << 6),
    163         ContentChange =             (1L << 7),
    164 
    165         ContentsOrientationChange = (1L << 9),
    166         OpacityChange =             (1L << 10),
    167         ContentsRectChange =        (1L << 11),
    168 
    169         Preserves3DChange =         (1L << 12),
    170         MasksToBoundsChange =       (1L << 13),
    171         DrawsContentChange =        (1L << 14),
    172         ContentsOpaqueChange =      (1L << 15),
    173 
    174         BackfaceVisibilityChange =  (1L << 16),
    175         ChildrenTransformChange =   (1L << 17),
    176         DisplayChange =             (1L << 18),
    177         BackgroundColorChange =     (1L << 19),
    178 
    179         ReplicaLayerChange =        (1L << 20)
    180     };
    181 
    182     // The compositor lets us special-case images and colors, so we try to do so.
    183     enum StaticContentType { HTMLContentType, DirectImageContentType, ColorContentType, MediaContentType, Canvas3DContentType};
    184 
    185     TextureMapperNode* rootLayer();
    186 
    187     TextureMapperNode(GraphicsLayerTextureMapper* newLayer);
    188     virtual ~TextureMapperNode();
    189 
    190     void clearDirectImage();
    191     void computeTransformations();
    192     IntSize nearestSurfaceSize() const;
    193     void computeReplicaTransform();
    194     void computeLayerType();
    195     void computeLocalTransform();
    196     void flattenTo2DSpaceIfNecessary();
    197     void initializeTextureMapper(TextureMapper*);
    198     void invalidateTransform();
    199     void notifyChange(ChangeMask);
    200     void syncCompositingState(bool recurse);
    201     void performPostSyncOperations();
    202     void setNeedsDisplay();
    203     void setNeedsDisplayInRect(IntRect);
    204     virtual void cleanupTextureMapper();
    205 
    206     void paintRecursive(TexmapPaintOptions options);
    207     void paintSelf(const TexmapPaintOptions& options);
    208     void uploadTextureFromContent(TextureMapper* textureMapper, const IntRect& visibleRect);
    209 
    210     int countDescendantsWithContent() const;
    211     bool hasSurfaceDescendants() const;
    212 
    213     IntSize size() const { return m_size; }
    214 
    215     virtual void setPlatformLayerClient(TextureMapperLayerClient*);
    216     virtual void paint(TextureMapper*, const TextureMapperContentLayer::PaintOptions&);
    217 
    218     static TextureMapperNode* toTextureMapperNode(GraphicsLayer*);
    219 public:
    220     GraphicsLayerTextureMapper* m_layer;
    221     const char* m_lastTextureMapperType;
    222     RefPtr<TextureMapper> m_lastTextureMapper;
    223     struct TransformData {
    224         TransformationMatrix base, target, replica, forDescendants, perspective, local;
    225         IntRect targetBoundingRect;
    226         float centerZ;
    227         bool dirty, localDirty, perspectiveDirty;
    228         IntRect boundingRectFromRoot;
    229         TransformData() : dirty(true), localDirty(true), perspectiveDirty(true) { }
    230     };
    231 
    232     TransformData m_transforms;
    233 
    234     enum LayerType {
    235         DefaultLayer,
    236         RootLayer,
    237         ScissorLayer,
    238         ClipLayer,
    239         TransparencyLayer
    240     };
    241 
    242     LayerType m_layerType;
    243 
    244     struct ContentData {
    245         IntRect needsDisplayRect;
    246         bool needsDisplay;
    247         Color backgroundColor;
    248 
    249         StaticContentType contentType;
    250         RefPtr<Image> image;
    251         TextureMapperVideoLayer* media;
    252 
    253         ContentData()
    254             : needsDisplay(false)
    255             , contentType(HTMLContentType)
    256             , image(0)
    257             , media(0)
    258         {
    259         }
    260 
    261     };
    262 
    263     inline IntRect targetRect() const
    264     {
    265         return m_currentContent.contentType == HTMLContentType ? entireRect() : m_state.contentsRect;
    266     }
    267 
    268     inline IntRect entireRect() const
    269     {
    270         return IntRect(0, 0, m_size.width(), m_size.height());
    271     }
    272 
    273     inline IntRect replicaRect() const
    274     {
    275         return m_layerType == TransparencyLayer ? IntRect(0, 0, m_nearestSurfaceSize.width(), m_nearestSurfaceSize.height()) : entireRect();
    276     }
    277 
    278     RefPtr<BitmapTexture> m_texture;
    279     RefPtr<BitmapTexture> m_surface, m_replicaSurface;
    280 
    281     ContentData m_pendingContent;
    282     ContentData m_currentContent;
    283 
    284     Vector<TextureMapperNode*> m_children;
    285     TextureMapperNode* m_parent;
    286     TextureMapperNode* m_effectTarget;
    287     int m_changeMask;
    288     IntSize m_size, m_nearestSurfaceSize;
    289     String m_name;
    290     TextureMapperLayerClient* m_platformClient;
    291 
    292     struct State {
    293         FloatPoint pos;
    294         FloatPoint3D anchorPoint;
    295         FloatSize size;
    296         TransformationMatrix transform;
    297         TransformationMatrix childrenTransform;
    298         Color backgroundColor;
    299         Color currentColor;
    300         GraphicsLayer::CompositingCoordinatesOrientation geoOrientation;
    301         GraphicsLayer::CompositingCoordinatesOrientation contentsOrientation;
    302         float opacity;
    303         IntRect contentsRect;
    304         int descendantsWithContent;
    305         TextureMapperNode* maskLayer;
    306         TextureMapperNode* replicaLayer;
    307         bool preserves3D;
    308         bool masksToBounds;
    309         bool drawsContent;
    310         bool contentsOpaque;
    311         bool backfaceVisibility;
    312         bool visible;
    313         bool dirty;
    314         bool tiled;
    315         bool hasSurfaceDescendants;
    316 
    317         State()
    318             : opacity(1.f)
    319             , descendantsWithContent(0)
    320             , maskLayer(0)
    321             , replicaLayer(0)
    322             , preserves3D(false)
    323             , masksToBounds(false)
    324             , drawsContent(false)
    325             , contentsOpaque(false)
    326             , backfaceVisibility(false)
    327             , visible(true)
    328             , dirty(true)
    329             , tiled(false)
    330             , hasSurfaceDescendants(false)
    331         {
    332         }
    333     };
    334     State m_state;
    335 };
    336 
    337 void TextureMapperNode::setNeedsDisplayInRect(IntRect rect)
    338 {
    339     if (m_platformClient) {
    340         if (m_state.hasSurfaceDescendants) {
    341             m_platformClient->setNeedsDisplay();
    342             return;
    343         }
    344         rect.intersect(IntRect(0, 0, m_size.width(), m_size.height()));
    345         if (rect.isEmpty())
    346             return;
    347         m_platformClient->setNeedsDisplayInRect(rect);
    348         return;
    349     }
    350 
    351     if (!m_parent)
    352         return;
    353 
    354     m_parent->setNeedsDisplayInRect(rect);
    355 }
    356 
    357 void TextureMapperNode::setNeedsDisplay()
    358 {
    359     if (m_effectTarget)
    360         m_effectTarget->setNeedsDisplay();
    361     if (m_transforms.targetBoundingRect.isEmpty())
    362         return;
    363     if (m_state.drawsContent || m_currentContent.contentType != HTMLContentType)
    364         setNeedsDisplayInRect(m_transforms.targetBoundingRect);
    365 }
    366 
    367 
    368 void TextureMapperNode::setPlatformLayerClient(TextureMapperLayerClient* client)
    369 {
    370     m_platformClient = client;
    371 }
    372 
    373 static int compareGraphicsLayersZValue(const void* a, const void* b)
    374 {
    375     typedef const TextureMapperNode* NodePtr;
    376     const NodePtr* nodeA = static_cast<const NodePtr*>(a);
    377     const NodePtr* nodeB = static_cast<const NodePtr*>(b);
    378     return int(((*nodeA)->m_transforms.centerZ - (*nodeB)->m_transforms.centerZ) * 1000);
    379 }
    380 inline static void sortByZOrder(Vector<TextureMapperNode* >& array, int first, int last)
    381 {
    382     qsort(array.data(), array.size(), sizeof(TextureMapperNode*), compareGraphicsLayersZValue);
    383 }
    384 
    385 bool TextureMapperNode::hasSurfaceDescendants() const
    386 {
    387     if (m_layerType == ClipLayer || m_layerType == TransparencyLayer || m_state.replicaLayer)
     27GraphicsLayerTextureMapper::GraphicsLayerTextureMapper(GraphicsLayerClient* client)
     28    : GraphicsLayer(client)
     29    , m_node(new TextureMapperNode())
     30    , m_changeMask(0)
     31{
     32}
     33
     34void GraphicsLayerTextureMapper::notifyChange(TextureMapperNode::ChangeMask changeMask)
     35{
     36    m_changeMask |= changeMask;
     37    if (!client())
     38        return;
     39    client()->notifySyncRequired(this);
     40}
     41
     42void GraphicsLayerTextureMapper::didSynchronize()
     43{
     44    m_syncQueued = false;
     45    m_changeMask = 0;
     46    m_pendingContent.needsDisplay = false;
     47    m_pendingContent.needsDisplayRect = IntRect();
     48}
     49
     50void GraphicsLayerTextureMapper::setName(const String& name)
     51{
     52    GraphicsLayer::setName(name);
     53}
     54
     55GraphicsLayerTextureMapper::~GraphicsLayerTextureMapper()
     56{
     57}
     58
     59/* \reimp (GraphicsLayer.h): The current size might change, thus we need to update the whole display.
     60*/
     61void GraphicsLayerTextureMapper::setNeedsDisplay()
     62{
     63    m_pendingContent.needsDisplay = true;
     64    notifyChange(TextureMapperNode::DisplayChange);
     65}
     66
     67/* \reimp (GraphicsLayer.h)
     68*/
     69void GraphicsLayerTextureMapper::setNeedsDisplayInRect(const FloatRect& rect)
     70{
     71    if (m_pendingContent.needsDisplay)
     72        return;
     73    m_pendingContent.needsDisplayRect.unite(IntRect(rect));
     74    notifyChange(TextureMapperNode::DisplayChange);
     75}
     76
     77/* \reimp (GraphicsLayer.h)
     78*/
     79void GraphicsLayerTextureMapper::setParent(GraphicsLayer* layer)
     80{
     81    notifyChange(TextureMapperNode::ParentChange);
     82    GraphicsLayer::setParent(layer);
     83}
     84
     85/* \reimp (GraphicsLayer.h)
     86*/
     87bool GraphicsLayerTextureMapper::setChildren(const Vector<GraphicsLayer*>& children)
     88{
     89    notifyChange(TextureMapperNode::ChildrenChange);
     90    return GraphicsLayer::setChildren(children);
     91}
     92
     93/* \reimp (GraphicsLayer.h)
     94*/
     95void GraphicsLayerTextureMapper::addChild(GraphicsLayer* layer)
     96{
     97    notifyChange(TextureMapperNode::ChildrenChange);
     98    GraphicsLayer::addChild(layer);
     99}
     100
     101/* \reimp (GraphicsLayer.h)
     102*/
     103void GraphicsLayerTextureMapper::addChildAtIndex(GraphicsLayer* layer, int index)
     104{
     105    GraphicsLayer::addChildAtIndex(layer, index);
     106    notifyChange(TextureMapperNode::ChildrenChange);
     107}
     108
     109/* \reimp (GraphicsLayer.h)
     110*/
     111void GraphicsLayerTextureMapper::addChildAbove(GraphicsLayer* layer, GraphicsLayer* sibling)
     112{
     113     GraphicsLayer::addChildAbove(layer, sibling);
     114     notifyChange(TextureMapperNode::ChildrenChange);
     115}
     116
     117/* \reimp (GraphicsLayer.h)
     118*/
     119void GraphicsLayerTextureMapper::addChildBelow(GraphicsLayer* layer, GraphicsLayer* sibling)
     120{
     121
     122    GraphicsLayer::addChildBelow(layer, sibling);
     123    notifyChange(TextureMapperNode::ChildrenChange);
     124}
     125
     126/* \reimp (GraphicsLayer.h)
     127*/
     128bool GraphicsLayerTextureMapper::replaceChild(GraphicsLayer* oldChild, GraphicsLayer* newChild)
     129{
     130    if (GraphicsLayer::replaceChild(oldChild, newChild)) {
     131        notifyChange(TextureMapperNode::ChildrenChange);
    388132        return true;
    389     const int size = m_children.size();
    390     for (int i = 0; i < size; ++i) {
    391         if (TextureMapperNode* child = m_children[i]) {
    392             if (child->hasSurfaceDescendants())
    393                 return true;
    394         }
    395133    }
    396134    return false;
    397 
    398 }
    399 
    400 void TextureMapperNode::paint(TextureMapper* textureMapper, const TextureMapperContentLayer::PaintOptions& options)
    401 {
    402     ASSERT(m_layerType == RootLayer);
    403     if (m_size.isEmpty())
    404         return;
    405 
    406 #if 0
    407     WTF::StopWatch stopWatch;
    408     ("[TextureMapper] RootPaint!!\n");
    409 #endif
    410 
    411     if (textureMapper->type() != m_lastTextureMapperType)
    412         gTextureMapperCache.m_data.clear();
    413 
    414     m_lastTextureMapper = textureMapper;
    415     TexmapPaintOptions opt;
    416     opt.opacity = 1;
    417     opt.rootLayer = this;
    418     opt.scissorRect = options.targetRect;
    419     opt.visibleRect = options.visibleRect;
    420     opt.textureMapper = textureMapper;
    421     opt.surface = 0;
    422     paintRecursive(opt);
    423 
    424     if (textureMapper->allowSurfaceForRoot() || m_state.hasSurfaceDescendants) {
    425         textureMapper->bindSurface(0);
    426         textureMapper->paintToTarget(*m_surface.get(), options.viewportSize, options.transform, options.opacity * m_state.opacity, options.targetRect);
    427     }
    428     gTextureMapperCache.purge();
    429 }
    430 
    431 int TextureMapperNode::countDescendantsWithContent() const
    432 {
    433     if (!m_state.visible || m_state.opacity < 0.001)
    434         return 0;
    435     int descendantsWithContent = (m_state.drawsContent || m_currentContent.contentType != HTMLContentType) ? 1 : 0;
    436 
    437     const int size = m_children.size();
    438     for (int i = 0; i < size; ++i) {
    439         if (TextureMapperNode* child = m_children[i])
    440             descendantsWithContent += child->countDescendantsWithContent();
    441     }
    442 
    443     return descendantsWithContent;
    444 }
    445 
    446 inline TextureMapperNode* TextureMapperNode::toTextureMapperNode(GraphicsLayer* layer)
    447 {
    448     return layer ? static_cast<GraphicsLayerTextureMapper*>(layer)->m_node.get() : 0;
    449 }
    450 
    451 void TextureMapperNode::computeLayerType()
    452 {
    453     // calculate layer type. A layer can be one of the following:
    454     //  RootLayer: the top level. Draws to a framebuffer, and the target texture draws into the viewport.
    455     //            only one layer is the root layer.
    456     //  ScissorLayer: draws to the current framebuffer, and applies an extra scissor before drawing its children.
    457     //                A scissor layer is a layer with children that masks to bounds, is not a transparency layer, and has a rectangular clip.
    458     //  ClipLayer: creates a new framebuffer, the size of the layer, and then paints it to the enclosing BitmapTexture with the layer's transform/opacity.
    459     //              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.
    460     //  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.
    461     //                     Used for layers with children and transparency/mask that preserve 3D or don't mask to bounds.
    462     //  DefaultLayer: draws itself and its children directly to the current framebuffer.
    463     //                any layer that doesn't conform to the other rules is a DefaultLayer.
    464 
    465     const bool selfHasContent = m_state.drawsContent || (m_currentContent.contentType != HTMLContentType);
    466     const bool hasDescendantsWithContent = m_state.descendantsWithContent - (selfHasContent ? 1 : 0);
    467     const bool hasTransparency = m_state.opacity < 0.99 || m_state.maskLayer;
    468     const bool hasReplica = m_state.replicaLayer;
    469     m_layerType = DefaultLayer;
    470 
    471     // Layer has no parent, it must be a root layer.
    472     if (!m_parent && !m_effectTarget) {
    473         m_layerType = RootLayer;
    474         return;
    475     }
    476 
    477     // A layer with no contents is always a default layer.
    478     if (!m_state.descendantsWithContent)
    479         return;
    480 
    481     // A layer with content-descendants and a mask is always a clip layer.
    482     if (hasDescendantsWithContent && m_state.maskLayer) {
    483         m_layerType = ClipLayer;
    484         return;
    485     }
    486 
    487     // 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.
    488     // 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.
    489     if (m_state.masksToBounds && hasDescendantsWithContent) {
    490         if (hasTransparency || !m_state.transform.isIdentityOrTranslation() || m_parent->m_state.preserves3D)
    491             m_layerType = ClipLayer;
    492         else
    493             m_layerType = ScissorLayer;
    494         return;
    495     }
    496 
    497     // We use a transparency layer when we have two of the following 3: replica, transparency, descendants with contents.
    498     if ((hasReplica && hasDescendantsWithContent) || (hasReplica && hasTransparency) || (hasTransparency && m_state.descendantsWithContent > 1))
    499         m_layerType = TransparencyLayer;
    500 }
    501 void TextureMapperNode::initializeTextureMapper(TextureMapper* textureMapper)
    502 {
    503     if (textureMapper->type() == m_lastTextureMapperType)
    504         return;
    505     m_surface = textureMapper->createTexture();
    506     m_replicaSurface = textureMapper->createTexture();
    507     m_texture = textureMapper->createTexture();
    508     gTextureMapperCache.mark(m_texture.get());
    509     m_lastTextureMapperType = textureMapper->type();
    510 }
    511 
    512 TextureMapperNode::TextureMapperNode(GraphicsLayerTextureMapper* newLayer)
    513     : m_layer(newLayer)
    514     , m_lastTextureMapperType(0)
    515     , m_lastTextureMapper(0)
    516     , m_layerType(DefaultLayer)
    517     , m_surface(0)
    518     , m_parent(0)
    519     , m_effectTarget(0)
    520     , m_changeMask(NoChanges)
    521     , m_platformClient(0)
    522 {
    523 
    524 }
    525 
    526 TextureMapperNode* TextureMapperNode::rootLayer()
    527 {
    528     if (m_effectTarget)
    529         return m_effectTarget->rootLayer();
    530     if (m_parent)
    531         return m_parent->rootLayer();
    532     return this;
    533 }
    534 
    535 void TextureMapperNode::invalidateTransform()
    536 {
    537     m_transforms.dirty = true;
    538     if (m_layerType != ClipLayer)
    539         m_state.dirty = true;
    540     if (m_state.replicaLayer)
    541         m_state.replicaLayer->invalidateTransform();
    542     const int size = m_children.size();
    543     for (int i = 0; i < size; ++i) {
    544         if (TextureMapperNode* layer = m_children[i])
    545             layer->invalidateTransform();
    546     }
    547 }
    548 
    549 void TextureMapperNode::computeLocalTransform()
    550 {
    551     if (!m_transforms.localDirty)
    552         return;
    553     const float originX = m_state.anchorPoint.x() * m_size.width();
    554     const float originY = m_state.anchorPoint.y() * m_size.height();
    555     m_transforms.local =
    556         TransformationMatrix()
    557         .translate3d(originX + m_state.pos.x(), originY + m_state.pos.y(), m_state.anchorPoint.z())
    558         .multLeft(m_state.transform)
    559         .translate3d(-originX, -originY, -m_state.anchorPoint.z());
    560     m_transforms.localDirty = false;
    561 }
    562 
    563 void TextureMapperNode::flattenTo2DSpaceIfNecessary()
    564 {
    565     if (m_state.preserves3D)
    566         return;
    567     m_transforms.forDescendants.setM13(0);
    568     m_transforms.forDescendants.setM23(0);
    569     m_transforms.forDescendants.setM31(0);
    570     m_transforms.forDescendants.setM32(0);
    571     m_transforms.forDescendants.setM33(1);
    572     m_transforms.forDescendants.setM34(0);
    573     m_transforms.forDescendants.setM43(0);
    574 }
    575 
    576 IntSize TextureMapperNode::nearestSurfaceSize() const
    577 {
    578     if (m_layerType == ClipLayer || m_layerType == RootLayer)
    579         return m_surface && !m_surface->size().isEmpty() ? m_surface->size() : m_size;
    580     return m_parent->nearestSurfaceSize();
    581 }
    582 
    583 void TextureMapperNode::computeReplicaTransform()
    584 {
    585     if (!m_state.replicaLayer)
    586         return;
    587 
    588     m_nearestSurfaceSize = nearestSurfaceSize();
    589 
    590     if (m_layerType != TransparencyLayer) {
    591         m_transforms.replica = TransformationMatrix(m_transforms.target).multLeft(m_state.replicaLayer->m_transforms.local);
    592         return;
    593     }
    594 
    595     const float originX = m_transforms.target.m41();
    596     const float originY = m_transforms.target.m42();
    597     m_transforms.replica =
    598             TransformationMatrix()
    599                 .translate(originX, originY)
    600                 .multLeft(m_state.replicaLayer->m_transforms.local)
    601                 .translate(-originX, -originY);
    602 }
    603 
    604 void TextureMapperNode::computeTransformations()
    605 {
    606     if (!m_transforms.dirty)
    607         return;
    608 
    609     m_transforms.dirty = false;
    610     if ((m_size.isEmpty() && m_state.masksToBounds))
    611         return;
    612 
    613     TextureMapperNode* parent = m_parent;
    614     computeLocalTransform();
    615 
    616     m_transforms.target = TransformationMatrix(parent ? parent->m_transforms.forDescendants : TransformationMatrix()).multLeft(m_transforms.local);
    617     m_transforms.forDescendants = (m_layerType == ClipLayer ? TransformationMatrix() : m_transforms.target);
    618 
    619     if (m_effectTarget)
    620         return;
    621 
    622     m_transforms.targetBoundingRect = IntRect(m_transforms.target.mapRect(entireRect()));
    623     if (m_state.replicaLayer)
    624         m_state.replicaLayer->computeTransformations();
    625 
    626     flattenTo2DSpaceIfNecessary();
    627 
    628     if (!m_state.backfaceVisibility && m_transforms.target.inverse().m33() < 0) {
    629         m_state.visible = false;
    630         return;
    631     }
    632     m_state.visible = true;
    633 
    634     if (parent && parent->m_state.preserves3D)
    635         m_transforms.centerZ = m_transforms.target.mapPoint(FloatPoint3D(m_size.width() / 2, m_size.height() / 2, 0)).z();
    636 
    637     if (!m_children.size())
    638         return;
    639 
    640     if (m_state.childrenTransform.isIdentity())
    641         return;
    642 
    643     const FloatPoint centerPoint = FloatPoint(m_size.width() / 2, m_size.height() / 2);
    644     if (m_transforms.perspectiveDirty)
    645         m_transforms.perspective = TransformationMatrix()
    646             .translate(centerPoint.x(), centerPoint.y())
    647             .multLeft(m_state.childrenTransform)
    648             .translate(-centerPoint.x(), -centerPoint.y());
    649     m_transforms.perspectiveDirty = false;
    650     m_transforms.forDescendants.multLeft(m_transforms.perspective);
    651 }
    652 
    653 void TextureMapperNode::uploadTextureFromContent(TextureMapper* textureMapper, const IntRect& visibleRect)
    654 {
    655     if (m_size.isEmpty() || !m_layer) {
    656         m_texture->destroy();
    657         return;
    658     }
    659 
    660     if (m_currentContent.contentType == DirectImageContentType) {
    661         if (m_currentContent.image)
    662             m_texture->setContentsToImage(m_currentContent.image.get());
    663         return;
    664     }
    665 
    666     if (m_currentContent.contentType == MediaContentType) {
    667         if (!m_currentContent.media)
    668             return;
    669         m_texture->reset(m_size, true);
    670         PlatformGraphicsContext* platformContext = m_texture->beginPaintMedia();
    671         GraphicsContext context(platformContext);
    672         m_currentContent.media->paint(&context);
    673         m_texture->endPaint();
    674         return;
    675     }
    676 
    677     const bool needsReset = (m_texture->contentSize() != m_size) || !m_texture->isValid();
    678     if ((m_currentContent.contentType != HTMLContentType)
    679         || (!m_currentContent.needsDisplay && m_currentContent.needsDisplayRect.isEmpty() && !needsReset))
    680         return;
    681 
    682     IntRect dirtyRect = IntRect(0, 0, m_size.width(), m_size.height());
    683     if (!needsReset && !m_currentContent.needsDisplay)
    684         dirtyRect.intersect(m_currentContent.needsDisplayRect);
    685     if (needsReset)
    686         m_texture->reset(m_size, m_state.contentsOpaque);
    687     m_pendingContent.needsDisplayRect = IntRect();
    688 
    689     {
    690         GraphicsContext context(m_texture->beginPaint(dirtyRect));
    691         if (textureMapper) {
    692             context.setImageInterpolationQuality(textureMapper->imageInterpolationQuality());
    693             context.setTextDrawingMode(textureMapper->textDrawingMode());
    694         }
    695         m_layer->paintGraphicsLayerContents(context, dirtyRect);
    696     }
    697     m_texture->endPaint();
    698     m_currentContent.needsDisplay = false;
    699 
    700 }
    701 
    702 void TextureMapperNode::paintSelf(const TexmapPaintOptions& options)
    703 {
    704     if (!m_layer || m_size.isEmpty() || (!m_state.drawsContent && m_currentContent.contentType == HTMLContentType))
    705         return;
    706 
    707     RefPtr<BitmapTexture> maskTexture = m_state.maskLayer ? m_state.maskLayer->m_texture : 0;
    708     RefPtr<BitmapTexture> replicaMaskTexture = 0;
    709     if (m_state.replicaLayer && m_state.replicaLayer->m_state.maskLayer)
    710         replicaMaskTexture = m_state.replicaLayer->m_state.maskLayer->m_texture;
    711 
    712     const float opacity = options.isSurface ? 1 : options.opacity;
    713 
    714     uploadTextureFromContent(options.textureMapper, options.visibleRect);
    715     if (m_state.replicaLayer && !options.isSurface)
    716         options.textureMapper->drawTexture(*m_texture.get(), replicaRect(), m_transforms.replica,
    717                          opacity * m_state.replicaLayer->m_state.opacity,
    718                          replicaMaskTexture ? replicaMaskTexture.get() : maskTexture.get());
    719 
    720     const IntRect rect = m_layerType == ClipLayer ? entireRect() : targetRect();
    721     const TransformationMatrix transform = m_layerType == ClipLayer ? TransformationMatrix() : m_transforms.target;
    722     options.textureMapper->drawTexture(*m_texture.get(), rect, transform, opacity, options.isSurface ? 0 : maskTexture.get());
    723 }
    724 
    725 void TextureMapperNode::paintRecursive(TexmapPaintOptions options)
    726 {
    727     bool isDirty = m_state.dirty;
    728     m_state.dirty = false;
    729 
    730     if ((m_size.isEmpty() && (m_state.masksToBounds
    731         || m_children.isEmpty())) || !m_state.visible || options.opacity < 0.01 || m_state.opacity < 0.01)
    732         return;
    733 
    734     initializeTextureMapper(options.textureMapper);
    735     computeReplicaTransform();
    736 
    737     if (m_state.maskLayer) {
    738         m_state.maskLayer->initializeTextureMapper(options.textureMapper);
    739         m_state.maskLayer->m_state.dirty = false;
    740     }
    741 
    742     if (m_state.replicaLayer) {
    743         m_state.replicaLayer->initializeTextureMapper(options.textureMapper);
    744         m_state.replicaLayer->m_state.dirty = false;
    745         if (m_state.replicaLayer->m_state.maskLayer) {
    746             m_state.replicaLayer->m_state.maskLayer->initializeTextureMapper(options.textureMapper);
    747             m_state.replicaLayer->m_state.maskLayer->m_state.dirty = false;
    748         }
    749     }
    750 
    751     TextureMapperNode* replica = m_state.replicaLayer;
    752     const bool isSurface = (m_layerType == ClipLayer
    753                             || m_layerType == TransparencyLayer
    754                             || (m_layerType == RootLayer
    755                                 && (options.textureMapper->allowSurfaceForRoot() || m_state.hasSurfaceDescendants)
    756                                 ));
    757     if (isSurface)
    758         uploadTextureFromContent(options.textureMapper, options.visibleRect);
    759     const IntRect boundingRectfromNearestSurface = m_transforms.targetBoundingRect;
    760 
    761     options.opacity *= m_state.opacity;
    762 
    763     TexmapPaintOptions optionsForDescendants(options);
    764     optionsForDescendants.opacity = isSurface ? 1 : options.opacity;
    765     options.isSurface = isSurface;
    766 
    767     if (m_layerType == ClipLayer) {
    768         optionsForDescendants.visibleRect = TransformationMatrix().translate(-boundingRectfromNearestSurface.x(), -boundingRectfromNearestSurface.y()).mapRect(options.visibleRect);
    769         optionsForDescendants.scissorRect = IntRect(0, 0, m_size.width(), m_size.height());
    770     }
    771 
    772     if (m_layerType == ScissorLayer)
    773         optionsForDescendants.scissorRect.intersect(m_transforms.targetBoundingRect);
    774     options.textureMapper->setClip(optionsForDescendants.scissorRect);
    775 
    776     TextureMapperCacheLock(m_texture.get());
    777     TextureMapperCacheLock(m_surface.get());
    778     TextureMapperCacheLock(m_replicaSurface.get());
    779 
    780     gTextureMapperCache.purge();
    781 
    782     if (isSurface) {
    783         ASSERT(m_surface);
    784         if (!m_surface->isValid())
    785             isDirty = true;
    786         if (m_state.tiled) {
    787             m_surface->reset(options.visibleRect.size());
    788             m_surface->setOffset(options.visibleRect.location());
    789         } else if (isDirty)
    790             m_surface->reset(m_layerType == TransparencyLayer ? options.surface->size() : m_size);
    791         gTextureMapperCache.mark(m_surface.get());
    792         options.textureMapper->bindSurface(m_surface.get());
    793 
    794         optionsForDescendants.surface = m_surface.get();
    795     } else if (m_surface)
    796         m_surface->destroy();
    797 
    798     RefPtr<BitmapTexture> maskTexture;
    799     RefPtr<BitmapTexture> replicaMaskTexture;
    800     if (TextureMapperNode* mask = m_state.maskLayer) {
    801         mask->uploadTextureFromContent(options.textureMapper, options.visibleRect);
    802         maskTexture = mask->m_texture;
    803     }
    804 
    805     if (replica && replica->m_state.maskLayer) {
    806         replica->m_state.maskLayer->uploadTextureFromContent(options.textureMapper, options.visibleRect);
    807         replicaMaskTexture = replica->m_state.maskLayer->m_texture;
    808     }
    809 
    810     int childrenSize = m_children.size();
    811     if (isDirty || !isSurface || m_state.tiled || !m_surface->isValid()) {
    812         bool didPaintSelf = false;
    813         if (!m_state.preserves3D || m_children.isEmpty()) {
    814             paintSelf(options);
    815             didPaintSelf = true;
    816         }
    817 
    818         if (m_children.isEmpty() && !isSurface)
    819             return;
    820 
    821         if (m_layerType == ScissorLayer)
    822             optionsForDescendants.scissorRect.intersect(m_transforms.target.mapRect(IntRect(0, 0, m_size.width(), m_size.height())));
    823 
    824         for (int i = 0; i < childrenSize; ++i) {
    825             TextureMapperNode* layer = m_children[i];
    826             if (!layer)
    827                 continue;
    828 
    829             if (!didPaintSelf && layer->m_transforms.centerZ >= 0) {
    830                 paintSelf(options);
    831                 didPaintSelf = true;
    832             }
    833             layer->paintRecursive(optionsForDescendants);
    834             if (isSurface) {
    835                 ASSERT(m_surface);
    836                 gTextureMapperCache.mark(m_surface.get());
    837                 options.textureMapper->bindSurface(m_surface.get());
    838             }
    839         }
    840         if (!didPaintSelf) {
    841             paintSelf(options);
    842             didPaintSelf = true;
    843         }
    844     }
    845 
    846     if (m_layerType == RootLayer || m_layerType == DefaultLayer || m_layerType == ScissorLayer)
    847         return;
    848 
    849     ASSERT(m_surface);
    850     BitmapTexture& texture = *m_surface.get();
    851     if (replica) {
    852         ASSERT(m_replicaSurface);
    853         m_replicaSurface->reset(options.surface->size());
    854         m_replicaSurface->setOffset(options.surface->offset());
    855         gTextureMapperCache.mark(m_replicaSurface.get());
    856         options.textureMapper->bindSurface(m_replicaSurface.get());
    857         options.textureMapper->drawTexture(texture, replicaRect(), m_transforms.replica, replica->m_state.opacity, replicaMaskTexture ? replicaMaskTexture.get() : maskTexture.get());
    858         options.textureMapper->drawTexture(texture, IntRect(IntPoint(0, 0), options.surface->size()), TransformationMatrix(), 1.0f, maskTexture.get());
    859         options.textureMapper->bindSurface(options.surface);
    860         gTextureMapperCache.mark(options.surface);
    861         options.textureMapper->drawTexture(*m_replicaSurface.get(), IntRect(IntPoint(0, 0), options.surface->size()), TransformationMatrix(), options.opacity, 0);
    862         return;
    863     }
    864 
    865     options.textureMapper->bindSurface(options.surface);
    866     options.textureMapper->drawTexture(texture,
    867                              m_layerType == TransparencyLayer ? IntRect(IntPoint(0, 0), options.surface->size()) :
    868                              targetRect(),
    869                              m_layerType == TransparencyLayer ? TransformationMatrix() : m_transforms.target,
    870                              options.opacity, maskTexture.get());
    871     gTextureMapperCache.mark(&texture);
    872 }
    873 
    874 void TextureMapperNode::cleanupTextureMapper()
    875 {
    876     if (m_texture)
    877         m_texture->destroy();
    878     if (m_surface)
    879         m_surface->destroy();
    880     if (m_replicaSurface)
    881         m_replicaSurface->destroy();
    882     for (int i = 0; i < m_children.size(); ++i) {
    883         if (m_children[i])
    884             m_children[i]->cleanupTextureMapper();
    885     }
    886     if (m_lastTextureMapper)
    887         m_lastTextureMapper->cleanup();
    888 }
    889 
    890 TextureMapperNode::~TextureMapperNode()
    891 {
    892     setNeedsDisplay();
    893     {
    894         const int childrenSize = m_children.size();
    895         for (int i = childrenSize-1; i >= 0; --i) {
    896             ASSERT(m_children[i]->m_parent == this);
    897             m_children[i]->m_parent = 0;
    898         }
    899     }
    900     if (m_parent)
    901         m_parent->m_children.remove(m_parent->m_children.find(this));
    902 }
    903 
    904 void TextureMapperNode::notifyChange(ChangeMask changeMask)
    905 {
    906     m_changeMask |= changeMask;
    907     if (!m_layer->client())
    908         return;
    909     m_layer->client()->notifySyncRequired(m_layer);
    910 }
    911 
    912 void TextureMapperNode::performPostSyncOperations()
    913 {
    914     const LayerType prevLayerType = m_layerType;
    915     computeLayerType();
    916     if (prevLayerType != m_layerType)
    917         m_state.dirty = true;
    918     if (m_transforms.dirty)
    919         setNeedsDisplay();
    920 
    921     computeTransformations();
    922     if (m_state.maskLayer && !m_state.dirty)
    923         m_state.dirty = m_state.maskLayer->m_state.dirty;
    924     if (m_state.replicaLayer && !m_state.dirty)
    925         m_state.dirty = m_state.replicaLayer->m_state.dirty;
    926 
    927     const int size = m_children.size();
    928 
    929     for (int i = size - 1; i >= 0; --i) {
    930         TextureMapperNode* layer = m_children[i];
    931 
    932         layer->performPostSyncOperations();
    933         if (!m_state.dirty)
    934             m_state.dirty = layer->m_state.dirty;
    935     }
    936     m_state.hasSurfaceDescendants = hasSurfaceDescendants();
    937     if (m_state.dirty)
    938         m_state.descendantsWithContent = countDescendantsWithContent();
    939 
    940     if (m_state.preserves3D)
    941         sortByZOrder(m_children, 0, size);
    942     if (m_state.dirty)
    943         setNeedsDisplay();
    944 }
    945 
    946 void TextureMapperNode::syncCompositingState(bool recurse)
    947 {
    948     bool needsToInvalidateTransform = false;
    949 
    950     if (!m_layer)
    951         return;
    952 
    953     if (m_changeMask == NoChanges)
    954         goto afterCurrentLayerSync;
    955 
    956     setNeedsDisplay();
    957     if (m_parent)
    958         m_parent->m_state.dirty = true;
    959 
    960     if (m_currentContent.contentType == HTMLContentType && (m_changeMask & ParentChange)) {
    961         // The WebCore compositor manages item ownership. We have to make sure graphicsview doesn't
    962         // try to snatch that ownership.
    963 
    964         if (!m_layer->parent())
    965             m_parent = 0;
    966         else
    967             m_parent = toTextureMapperNode(m_layer->parent());
    968 
    969         if (!m_layer->parent() && m_parent) {
    970             size_t index = m_parent->m_children.find(this);
    971             m_parent->m_children.remove(index);
    972         }
    973 
    974     }
    975 
    976     if (m_changeMask & ChildrenChange) {
    977         m_children.clear();
    978         for (size_t i = 0; i < m_layer->children().size(); ++i) {
    979             if (TextureMapperNode* child = toTextureMapperNode(m_layer->children()[i])) {
    980                 if (!child)
    981                     continue;
    982                 m_children.append(child);
    983                 child->m_parent = this;
    984             }
    985         }
    986         m_state.dirty = true;
    987     }
    988 
    989     if (m_changeMask & (SizeChange | ContentsRectChange)) {
    990         IntSize wantedSize = IntSize(m_layer->size().width(), m_layer->size().height());
    991         if (wantedSize.isEmpty() && m_pendingContent.contentType == HTMLContentType)
    992             wantedSize = IntSize(m_layer->contentsRect().width(), m_layer->contentsRect().height());
    993 
    994         if (wantedSize != m_size) {
    995             m_size = IntSize(wantedSize.width(), wantedSize.height());
    996             if (m_platformClient)
    997                 m_platformClient->setSizeChanged(m_size);
    998             const bool needsTiling = m_size.width() > 2000 || m_size.height() > 2000;
    999             if (m_state.tiled != needsTiling)
    1000                 m_state.tiled = needsTiling;
    1001             m_state.dirty = true;
    1002         }
    1003     }
    1004 
    1005     if (m_changeMask & MaskLayerChange) {
    1006        if (TextureMapperNode* layer = toTextureMapperNode(m_layer->maskLayer()))
    1007            layer->m_effectTarget = this;
    1008     }
    1009 
    1010     if (m_changeMask & ReplicaLayerChange) {
    1011        if (TextureMapperNode* layer = toTextureMapperNode(m_layer->replicaLayer()))
    1012            layer->m_effectTarget = this;
    1013     }
    1014 
    1015     if (m_changeMask & (TransformChange | SizeChange | AnchorPointChange | PositionChange))
    1016         m_transforms.localDirty = true;
    1017 
    1018     if (m_changeMask & (ChildrenTransformChange | SizeChange))
    1019         m_transforms.perspectiveDirty = true;
    1020 
    1021     if (m_changeMask & (ChildrenTransformChange | Preserves3DChange | TransformChange | AnchorPointChange | SizeChange | ContentsRectChange | BackfaceVisibilityChange | PositionChange | MaskLayerChange | DrawsContentChange | ContentChange | ReplicaLayerChange))    {
    1022         // Due to the differences between the way WebCore handles transforms and the way Qt handles transforms,
    1023         // all these elements affect the transforms of all the descendants.
    1024         needsToInvalidateTransform = true;
    1025     }
    1026 
    1027     if (m_changeMask & DisplayChange)
    1028         m_state.dirty = true;
    1029 
    1030     m_state.maskLayer = toTextureMapperNode(m_layer->maskLayer());
    1031     m_state.replicaLayer = toTextureMapperNode(m_layer->replicaLayer());
    1032     m_state.pos = m_layer->position();
    1033     m_state.anchorPoint = m_layer->anchorPoint();
    1034     m_state.size = m_layer->size();
    1035     m_state.transform = m_layer->transform();
    1036     m_state.contentsRect = m_layer->contentsRect();
    1037     m_state.opacity = m_layer->opacity();
    1038     m_state.contentsRect = m_layer->contentsRect();
    1039     m_state.preserves3D = m_layer->preserves3D();
    1040     m_state.masksToBounds = m_layer->masksToBounds();
    1041     m_state.drawsContent = m_layer->drawsContent();
    1042     m_state.contentsOpaque = m_layer->contentsOpaque();
    1043     m_state.backfaceVisibility = m_layer->backfaceVisibility();
    1044     m_state.childrenTransform = m_layer->childrenTransform();
    1045     m_currentContent.contentType = m_pendingContent.contentType;
    1046     m_currentContent.image = m_pendingContent.image;
    1047     m_currentContent.media = m_pendingContent.media;
    1048     m_currentContent.backgroundColor = m_pendingContent.backgroundColor;
    1049     m_currentContent.needsDisplay = m_currentContent.needsDisplay || m_pendingContent.needsDisplay;
    1050     m_currentContent.needsDisplayRect.unite(m_pendingContent.needsDisplayRect);
    1051     m_pendingContent.needsDisplay = false;
    1052     m_pendingContent.needsDisplayRect = IntRect();
    1053     m_changeMask = NoChanges;
    1054     afterCurrentLayerSync:
    1055     if (needsToInvalidateTransform)
    1056         invalidateTransform();
    1057 
    1058     if (m_state.maskLayer) {
    1059         m_state.maskLayer->syncCompositingState(false);
    1060         if (m_state.maskLayer->m_size.isEmpty())
    1061             m_state.maskLayer->m_size = m_size;
    1062     }
    1063 
    1064     if (m_state.replicaLayer)
    1065         m_state.replicaLayer->syncCompositingState(false);
    1066 
    1067 #if 0
    1068     if (m_state.dirty && m_texture && m_texture->allowOfflineTextureUpload())
    1069         uploadTextureFromContent(0);
    1070 #endif
    1071 
    1072     if (!recurse)
    1073         return;
    1074 
    1075     const int childrenSize = m_children.size();
    1076     for (int i = childrenSize-1; i >= 0; --i)
    1077         m_children[i]->syncCompositingState(true);
    1078 }
    1079 
    1080 GraphicsLayerTextureMapper::GraphicsLayerTextureMapper(GraphicsLayerClient* client)
    1081     : GraphicsLayer(client)
    1082     , m_node(new TextureMapperNode(this))
    1083 {
    1084 }
    1085 
    1086 void GraphicsLayerTextureMapper::setName(const String& name)
    1087 {
    1088     m_node->m_name = name;
    1089 }
    1090 
    1091 GraphicsLayerTextureMapper::~GraphicsLayerTextureMapper()
    1092 {
    1093 }
    1094 
    1095 /* \reimp (GraphicsLayer.h): The current size might change, thus we need to update the whole display.
    1096 */
    1097 void GraphicsLayerTextureMapper::setNeedsDisplay()
    1098 {
    1099     m_node->m_pendingContent.needsDisplay = true;
    1100     m_node->notifyChange(TextureMapperNode::DisplayChange);
    1101 }
    1102 
    1103 /* \reimp (GraphicsLayer.h)
    1104 */
    1105 void GraphicsLayerTextureMapper::setNeedsDisplayInRect(const FloatRect& rect)
    1106 {
    1107     if (m_node->m_pendingContent.needsDisplay)
    1108         return;
    1109     m_node->m_pendingContent.needsDisplayRect.unite(IntRect(rect));
    1110     m_node->notifyChange(TextureMapperNode::DisplayChange);
    1111 }
    1112 
    1113 /* \reimp (GraphicsLayer.h)
    1114 */
    1115 void GraphicsLayerTextureMapper::setParent(GraphicsLayer* layer)
    1116 {
    1117     m_node->notifyChange(TextureMapperNode::ParentChange);
    1118     GraphicsLayer::setParent(layer);
    1119 }
    1120 
    1121 /* \reimp (GraphicsLayer.h)
    1122 */
    1123 bool GraphicsLayerTextureMapper::setChildren(const Vector<GraphicsLayer*>& children)
    1124 {
    1125     m_node->notifyChange(TextureMapperNode::ChildrenChange);
    1126     return GraphicsLayer::setChildren(children);
    1127 }
    1128 
    1129 /* \reimp (GraphicsLayer.h)
    1130 */
    1131 void GraphicsLayerTextureMapper::addChild(GraphicsLayer* layer)
    1132 {
    1133     m_node->notifyChange(TextureMapperNode::ChildrenChange);
    1134     GraphicsLayer::addChild(layer);
    1135 }
    1136 
    1137 /* \reimp (GraphicsLayer.h)
    1138 */
    1139 void GraphicsLayerTextureMapper::addChildAtIndex(GraphicsLayer* layer, int index)
    1140 {
    1141     GraphicsLayer::addChildAtIndex(layer, index);
    1142     m_node->notifyChange(TextureMapperNode::ChildrenChange);
    1143 }
    1144 
    1145 /* \reimp (GraphicsLayer.h)
    1146 */
    1147 void GraphicsLayerTextureMapper::addChildAbove(GraphicsLayer* layer, GraphicsLayer* sibling)
    1148 {
    1149      GraphicsLayer::addChildAbove(layer, sibling);
    1150      m_node->notifyChange(TextureMapperNode::ChildrenChange);
    1151 }
    1152 
    1153 /* \reimp (GraphicsLayer.h)
    1154 */
    1155 void GraphicsLayerTextureMapper::addChildBelow(GraphicsLayer* layer, GraphicsLayer* sibling)
    1156 {
    1157 
    1158     GraphicsLayer::addChildBelow(layer, sibling);
    1159     m_node->notifyChange(TextureMapperNode::ChildrenChange);
    1160 }
    1161 
    1162 /* \reimp (GraphicsLayer.h)
    1163 */
    1164 bool GraphicsLayerTextureMapper::replaceChild(GraphicsLayer* oldChild, GraphicsLayer* newChild)
    1165 {
    1166     if (GraphicsLayer::replaceChild(oldChild, newChild)) {
    1167         m_node->notifyChange(TextureMapperNode::ChildrenChange);
    1168         return true;
    1169     }
    1170 
    1171     return false;
    1172135}
    1173136
     
    1178141    if (!parent())
    1179142        return;
    1180     m_node->notifyChange(TextureMapperNode::ParentChange);
     143    notifyChange(TextureMapperNode::ParentChange);
    1181144    GraphicsLayer::removeFromParent();
    1182145}
     
    1189152        return;
    1190153    GraphicsLayer::setMaskLayer(value);
    1191     m_node->notifyChange(TextureMapperNode::MaskLayerChange);
     154    notifyChange(TextureMapperNode::MaskLayerChange);
    1192155}
    1193156
     
    1200163        return;
    1201164    GraphicsLayer::setReplicatedByLayer(value);
    1202     m_node->notifyChange(TextureMapperNode::ReplicaLayerChange);
     165    notifyChange(TextureMapperNode::ReplicaLayerChange);
    1203166}
    1204167
     
    1210173        return;
    1211174    GraphicsLayer::setPosition(value);
    1212     m_node->notifyChange(TextureMapperNode::PositionChange);
     175    notifyChange(TextureMapperNode::PositionChange);
    1213176}
    1214177
     
    1220183        return;
    1221184    GraphicsLayer::setAnchorPoint(value);
    1222     m_node->notifyChange(TextureMapperNode::AnchorPointChange);
     185    notifyChange(TextureMapperNode::AnchorPointChange);
    1223186}
    1224187
     
    1231194
    1232195    GraphicsLayer::setSize(value);
    1233     m_node->notifyChange(TextureMapperNode::SizeChange);
     196    notifyChange(TextureMapperNode::SizeChange);
    1234197}
    1235198
     
    1242205
    1243206    GraphicsLayer::setTransform(value);
    1244     m_node->notifyChange(TextureMapperNode::TransformChange);
     207    notifyChange(TextureMapperNode::TransformChange);
    1245208}
    1246209
     
    1252215        return;
    1253216    GraphicsLayer::setChildrenTransform(value);
    1254     m_node->notifyChange(TextureMapperNode::ChildrenTransformChange);
     217    notifyChange(TextureMapperNode::ChildrenTransformChange);
    1255218}
    1256219
     
    1262225        return;
    1263226    GraphicsLayer::setPreserves3D(value);
    1264     m_node->notifyChange(TextureMapperNode::Preserves3DChange);
     227    notifyChange(TextureMapperNode::Preserves3DChange);
    1265228}
    1266229
     
    1272235        return;
    1273236    GraphicsLayer::setMasksToBounds(value);
    1274     m_node->notifyChange(TextureMapperNode::MasksToBoundsChange);
     237    notifyChange(TextureMapperNode::MasksToBoundsChange);
    1275238}
    1276239
     
    1281244    if (value == drawsContent())
    1282245        return;
    1283     m_node->notifyChange(TextureMapperNode::DrawsContentChange);
     246    notifyChange(TextureMapperNode::DrawsContentChange);
    1284247    GraphicsLayer::setDrawsContent(value);
    1285248}
     
    1289252void GraphicsLayerTextureMapper::setBackgroundColor(const Color& value)
    1290253{
    1291     if (value == m_node->m_pendingContent.backgroundColor)
    1292         return;
    1293     m_node->m_pendingContent.backgroundColor = value;
     254    if (value == m_pendingContent.backgroundColor)
     255        return;
     256    m_pendingContent.backgroundColor = value;
    1294257    GraphicsLayer::setBackgroundColor(value);
    1295     m_node->notifyChange(TextureMapperNode::BackgroundColorChange);
     258    notifyChange(TextureMapperNode::BackgroundColorChange);
    1296259}
    1297260
     
    1300263void GraphicsLayerTextureMapper::clearBackgroundColor()
    1301264{
    1302     if (!m_node->m_pendingContent.backgroundColor.isValid())
    1303         return;
    1304     m_node->m_pendingContent.backgroundColor = Color();
     265    if (!m_pendingContent.backgroundColor.isValid())
     266        return;
     267    m_pendingContent.backgroundColor = Color();
    1305268    GraphicsLayer::clearBackgroundColor();
    1306     m_node->notifyChange(TextureMapperNode::BackgroundColorChange);
     269    notifyChange(TextureMapperNode::BackgroundColorChange);
    1307270}
    1308271
     
    1313276    if (value == contentsOpaque())
    1314277        return;
    1315     m_node->notifyChange(TextureMapperNode::ContentsOpaqueChange);
     278    notifyChange(TextureMapperNode::ContentsOpaqueChange);
    1316279    GraphicsLayer::setContentsOpaque(value);
    1317280}
     
    1324287        return;
    1325288    GraphicsLayer::setBackfaceVisibility(value);
    1326     m_node->notifyChange(TextureMapperNode::BackfaceVisibilityChange);
     289    notifyChange(TextureMapperNode::BackfaceVisibilityChange);
    1327290}
    1328291
     
    1334297        return;
    1335298    GraphicsLayer::setOpacity(value);
    1336     m_node->notifyChange(TextureMapperNode::OpacityChange);
     299    notifyChange(TextureMapperNode::OpacityChange);
    1337300}
    1338301
     
    1344307        return;
    1345308    GraphicsLayer::setContentsRect(value);
    1346     m_node->notifyChange(TextureMapperNode::ContentsRectChange);
     309    notifyChange(TextureMapperNode::ContentsRectChange);
    1347310}
    1348311
     
    1351314void GraphicsLayerTextureMapper::setContentsToImage(Image* image)
    1352315{
    1353     m_node->notifyChange(TextureMapperNode::ContentChange);
    1354     m_node->m_pendingContent.contentType = image ? TextureMapperNode::DirectImageContentType : TextureMapperNode::HTMLContentType;
    1355     m_node->m_pendingContent.image = image;
     316    notifyChange(TextureMapperNode::ContentChange);
     317    m_pendingContent.contentType = image ? TextureMapperNode::DirectImageContentType : TextureMapperNode::HTMLContentType;
     318    m_pendingContent.image = image;
    1356319    GraphicsLayer::setContentsToImage(image);
    1357320}
     
    1361324void GraphicsLayerTextureMapper::setContentsBackgroundColor(const Color& color)
    1362325{
    1363     m_node->notifyChange(TextureMapperNode::ContentChange);
    1364     m_node->m_pendingContent.contentType = TextureMapperNode::ColorContentType;
    1365     m_node->m_pendingContent.backgroundColor = color;
     326    notifyChange(TextureMapperNode::ContentChange);
     327    m_pendingContent.contentType = TextureMapperNode::ColorContentType;
     328    m_pendingContent.backgroundColor = color;
    1366329    GraphicsLayer::setContentsBackgroundColor(color);
    1367330}
     
    1371334{
    1372335    GraphicsLayer::setContentsToMedia(media);
    1373     m_node->notifyChange(TextureMapperNode::ContentChange);
    1374     m_node->m_pendingContent.contentType = media ? TextureMapperNode::MediaContentType : TextureMapperNode::HTMLContentType;
     336    notifyChange(TextureMapperNode::ContentChange);
     337    m_pendingContent.contentType = media ? TextureMapperNode::MediaContentType : TextureMapperNode::HTMLContentType;
    1375338    if (media)
    1376         m_node->m_pendingContent.media = static_cast<TextureMapperVideoLayer*>(media);
     339        m_pendingContent.media = static_cast<TextureMapperVideoLayer*>(media);
    1377340    else
    1378         m_node->m_pendingContent.media = 0;
     341        m_pendingContent.media = 0;
    1379342}
    1380343
     
    1385348    if (contentsOrientation() == orientation)
    1386349        return;
    1387     m_node->notifyChange(TextureMapperNode::ContentsOrientationChange);
     350    notifyChange(TextureMapperNode::ContentsOrientationChange);
    1388351    GraphicsLayer::setContentsOrientation(orientation);
    1389352}
     
    1393356void GraphicsLayerTextureMapper::syncCompositingStateForThisLayerOnly()
    1394357{
    1395     m_node->syncCompositingState(false);
    1396     m_node->performPostSyncOperations();
     358    m_node->syncCompositingState(this, false);
    1397359}
    1398360
     
    1401363void GraphicsLayerTextureMapper::syncCompositingState()
    1402364{
    1403     GraphicsLayer::syncCompositingState();
    1404     m_node->syncCompositingState(true);
    1405     m_node->performPostSyncOperations();
     365    m_node->syncCompositingState(this, true);
    1406366}
    1407367
  • trunk/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.h

    r69374 r71538  
    2525#include "GraphicsLayerClient.h"
    2626#include "Image.h"
     27#include "TextureMapperNode.h"
    2728
    2829#if ENABLE(3D_CANVAS)
    2930#include "GraphicsContext3D.h"
    3031#endif
    31 
    32 #define ENABLE_TEXMAP_ANIMATION 0
    3332
    3433namespace WebCore {
     
    8685    virtual PlatformLayer* platformLayer() const;
    8786
    88     virtual bool addAnimation(const KeyframeValueList&, const IntSize& /*boxSize*/, const Animation*,
    89                               const String& /*keyframesName*/, double /*timeOffset*/) { return false; }
     87    virtual bool addAnimation(const KeyframeValueList&, const IntSize& /*boxSize*/, const Animation*, const String& /*keyframesName*/, double /*timeOffset*/) { return false; }
     88
     89    void notifyChange(TextureMapperNode::ChangeMask changeMask);
     90    inline TextureMapperNode::ContentData& pendingContent() { return m_pendingContent; }
     91    inline int changeMask() const { return m_changeMask; }
     92    void didSynchronize();
    9093
    9194private:
    9295    OwnPtr<TextureMapperNode> m_node;
     96    bool m_syncQueued;
     97    int m_changeMask;
     98    TextureMapperNode::ContentData m_pendingContent;
    9399};
     100
     101inline static GraphicsLayerTextureMapper* toGraphicsLayerTextureMapper(GraphicsLayer* layer)
     102{
     103    return static_cast<GraphicsLayerTextureMapper*>(layer);
     104}
    94105
    95106}
  • trunk/WebCore/platform/graphics/texmap/TextureMapper.h

    r71213 r71538  
    5858    }
    5959
     60    virtual void pack() { }
     61    virtual void unpack() { }
     62    virtual bool isPacked() const { return false; }
     63
    6064    virtual PlatformGraphicsContext* beginPaint(const IntRect& dirtyRect) = 0;
    6165    virtual void endPaint() = 0;
     
    7377    inline void setOffset(const IntPoint& o) { m_offset = o; }
    7478    inline IntPoint offset() const { return m_offset; }
     79
     80protected:
     81
    7582private:
    7683    int m_lockCount;
     
    8289// A "context" class used to encapsulate accelerated texture mapping functions: i.e. drawing a texture
    8390// onto the screen or into another texture with a specified transform, opacity and mask.
    84 class TextureMapper : public RefCounted<TextureMapper> {
     91class TextureMapper {
    8592    friend class BitmapTexture;
    8693
    8794public:
    88     static PassRefPtr<TextureMapper> create(GraphicsContext*);
     95    static PassOwnPtr<TextureMapper> create(GraphicsContext* graphicsContext = 0);
    8996    virtual ~TextureMapper() { }
    9097
     
    102109    virtual bool allowSurfaceForRoot() const = 0;
    103110    virtual PassRefPtr<BitmapTexture> createTexture() = 0;
    104     virtual const char* type() const = 0;
    105     virtual void cleanup() {}
    106111
    107112    void setImageInterpolationQuality(InterpolationQuality quality) { m_interpolationQuality = quality; }
  • trunk/WebCore/platform/graphics/texmap/TextureMapperPlatformLayer.h

    r71213 r71538  
    3737    virtual void setNeedsDisplayInRect(const IntRect& rect) = 0;
    3838    virtual void setSizeChanged(const IntSize&) = 0;
     39    virtual TextureMapper* textureMapper() = 0;
    3940};
    4041
  • trunk/WebKit/qt/Api/qwebframe.cpp

    r71217 r71538  
    310310        return;
    311311
    312     if (!textureMapper)
    313         textureMapper = TextureMapper::create(context);
    314 
    315312    textureMapper->setGraphicsContext(context);
    316313    textureMapper->setImageInterpolationQuality(context->imageInterpolationQuality());
  • trunk/WebKit/qt/Api/qwebframe_p.h

    r71213 r71538  
    114114#if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER)
    115115    WebCore::TextureMapperContentLayer* rootGraphicsLayer;
    116     RefPtr<WebCore::TextureMapper> textureMapper;
     116    OwnPtr<WebCore::TextureMapper> textureMapper;
    117117#endif
    118118    bool zoomTextOnly;
  • trunk/WebKit/qt/ChangeLog

    r71499 r71538  
     12010-11-08  Noam Rosenthal  <noam.rosenthal@nokia.com>
     2
     3        Reviewed by Kenneth Rohde Christiansen.
     4
     5        [Texmap] [Qt] Texture mapper initial implementation
     6        https://bugs.webkit.org/show_bug.cgi?id=47070
     7
     8        Reorganized the textureMapper to be a member of QWebFramePrivate, to help with making
     9        TextureMapper thread-safe.
     10
     11        * Api/qwebframe.cpp:
     12        (QWebFramePrivate::renderCompositedLayers):
     13        * Api/qwebframe_p.h:
     14        * WebCoreSupport/PageClientQt.cpp:
     15        (WebCore::PlatformLayerProxyQt::setTextureMapper):
     16        (WebCore::PlatformLayerProxyQt::textureMapper):
     17        (WebCore::PlatformLayerProxyQWidget::PlatformLayerProxyQWidget):
     18        (WebCore::PlatformLayerProxyQGraphicsObject::PlatformLayerProxyQGraphicsObject):
     19
    1202010-11-07  Adam Barth  <abarth@webkit.org>
    221
  • trunk/WebKit/qt/WebCoreSupport/PageClientQt.cpp

    r70819 r71538  
    2222
    2323#include "PageClientQt.h"
     24#include "TextureMapperQt.h"
    2425#include "texmap/TextureMapperPlatformLayer.h"
    25 
     26#include <QGraphicsScene>
     27#include <QGraphicsView>
    2628#if defined(Q_WS_X11)
    2729#include <QX11Info>
     
    2931
    3032#ifdef QT_OPENGL_LIB
     33#include "opengl/TextureMapperGL.h"
    3134#include <QGLWidget>
    3235#endif
     36
    3337namespace WebCore {
    3438
     
    4650    }
    4751
     52    void setTextureMapper(PassOwnPtr<TextureMapper> textureMapper)
     53    {
     54        m_frame->d->textureMapper = textureMapper;
     55    }
     56
    4857    virtual ~PlatformLayerProxyQt()
    4958    {
     
    5261        if (m_frame->d)
    5362            m_frame->d->rootGraphicsLayer = 0;
     63    }
     64
     65    virtual TextureMapper* textureMapper()
     66    {
     67        return m_frame->d->textureMapper.get();
    5468    }
    5569
     
    7084        if (m_widget)
    7185            m_widget->installEventFilter(this);
     86
     87        if (textureMapper())
     88            return;
     89
     90        setTextureMapper(TextureMapperQt::create());
    7291    }
    7392
     
    104123        , m_graphicsItem(object)
    105124    {
     125        if (textureMapper())
     126            return;
     127
     128#ifdef QT_OPENGL_LIB
     129        QGraphicsView* view = object->scene()->views()[0];
     130        if (view && view->viewport() && view->viewport()->inherits("QGLWidget")) {
     131            setTextureMapper(TextureMapperGL::create());
     132            return;
     133        }
     134#endif
     135        setTextureMapper(TextureMapperQt::create());
    106136    }
    107137
Note: See TracChangeset for help on using the changeset viewer.