Title: [90492] trunk/Source/WebCore
Revision
90492
Author
[email protected]
Date
2011-07-06 13:56:28 -0700 (Wed, 06 Jul 2011)

Log Message

2011-07-01  James Robinson  <[email protected]>

        Reviewed by Stephen White.

        [chromium] Externalize layer visibility calculation
        https://bugs.webkit.org/show_bug.cgi?id=63847

        This moves the layer visibility calculation from the layer itself out to LayerRendererChromium, like the other
        calculated properties.  Previously, we were doing this calculating at paint time and again at draw time and
        relying on the fact that this produced the same value.  This avoids the redundant calculation.

        Covered by existing compositing/ layout tests.

        * platform/graphics/chromium/ContentLayerChromium.cpp:
        (WebCore::ContentLayerChromium::ContentLayerChromium):
        (WebCore::ContentLayerChromium::paintContentsIfDirty):
        (WebCore::ContentLayerChromium::tilingTransform):
        (WebCore::ContentLayerChromium::contentBounds):
        (WebCore::ContentLayerChromium::updateLayerSize):
        (WebCore::ContentLayerChromium::draw):
        (WebCore::ContentLayerChromium::setTilingOption):
        (WebCore::ContentLayerChromium::setIsMask):
        * platform/graphics/chromium/ContentLayerChromium.h:
        * platform/graphics/chromium/ImageLayerChromium.cpp:
        (WebCore::ImageLayerChromium::paintContentsIfDirty):
        (WebCore::ImageLayerChromium::contentBounds):
        * platform/graphics/chromium/ImageLayerChromium.h:
        * platform/graphics/chromium/LayerChromium.cpp:
        (WebCore::LayerChromium::pushPropertiesTo):
        * platform/graphics/chromium/LayerChromium.h:
        (WebCore::LayerChromium::contentBounds):
        (WebCore::LayerChromium::visibleLayerRect):
        (WebCore::LayerChromium::setVisibleLayerRect):
        (WebCore::LayerChromium::draw):
        * platform/graphics/chromium/LayerRendererChromium.cpp:
        (WebCore::calculateVisibleLayerRect):
        (WebCore::LayerRendererChromium::paintLayerContents):
        (WebCore::LayerRendererChromium::drawLayer):
        * platform/graphics/chromium/RenderSurfaceChromium.cpp:
        (WebCore::RenderSurfaceChromium::draw):
        * platform/graphics/chromium/cc/CCCanvasLayerImpl.cpp:
        (WebCore::CCCanvasLayerImpl::draw):
        * platform/graphics/chromium/cc/CCCanvasLayerImpl.h:
        * platform/graphics/chromium/cc/CCLayerImpl.cpp:
        (WebCore::CCLayerImpl::draw):
        * platform/graphics/chromium/cc/CCLayerImpl.h:
        (WebCore::CCLayerImpl::contentBounds):
        (WebCore::CCLayerImpl::setContentBounds):
        (WebCore::CCLayerImpl::visibleLayerRect):
        (WebCore::CCLayerImpl::setVisibleLayerRect):
        (WebCore::CCLayerImpl::doubleSided):
        (WebCore::CCLayerImpl::setDoubleSided):
        * platform/graphics/chromium/cc/CCPluginLayerImpl.cpp:
        (WebCore::CCPluginLayerImpl::draw):
        * platform/graphics/chromium/cc/CCPluginLayerImpl.h:
        * platform/graphics/chromium/cc/CCVideoLayerImpl.cpp:
        (WebCore::CCVideoLayerImpl::draw):
        * platform/graphics/chromium/cc/CCVideoLayerImpl.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (90491 => 90492)


--- trunk/Source/WebCore/ChangeLog	2011-07-06 20:50:46 UTC (rev 90491)
+++ trunk/Source/WebCore/ChangeLog	2011-07-06 20:56:28 UTC (rev 90492)
@@ -1,3 +1,62 @@
+2011-07-01  James Robinson  <[email protected]>
+
+        Reviewed by Stephen White.
+
+        [chromium] Externalize layer visibility calculation
+        https://bugs.webkit.org/show_bug.cgi?id=63847
+
+        This moves the layer visibility calculation from the layer itself out to LayerRendererChromium, like the other
+        calculated properties.  Previously, we were doing this calculating at paint time and again at draw time and
+        relying on the fact that this produced the same value.  This avoids the redundant calculation.
+
+        Covered by existing compositing/ layout tests.
+
+        * platform/graphics/chromium/ContentLayerChromium.cpp:
+        (WebCore::ContentLayerChromium::ContentLayerChromium):
+        (WebCore::ContentLayerChromium::paintContentsIfDirty):
+        (WebCore::ContentLayerChromium::tilingTransform):
+        (WebCore::ContentLayerChromium::contentBounds):
+        (WebCore::ContentLayerChromium::updateLayerSize):
+        (WebCore::ContentLayerChromium::draw):
+        (WebCore::ContentLayerChromium::setTilingOption):
+        (WebCore::ContentLayerChromium::setIsMask):
+        * platform/graphics/chromium/ContentLayerChromium.h:
+        * platform/graphics/chromium/ImageLayerChromium.cpp:
+        (WebCore::ImageLayerChromium::paintContentsIfDirty):
+        (WebCore::ImageLayerChromium::contentBounds):
+        * platform/graphics/chromium/ImageLayerChromium.h:
+        * platform/graphics/chromium/LayerChromium.cpp:
+        (WebCore::LayerChromium::pushPropertiesTo):
+        * platform/graphics/chromium/LayerChromium.h:
+        (WebCore::LayerChromium::contentBounds):
+        (WebCore::LayerChromium::visibleLayerRect):
+        (WebCore::LayerChromium::setVisibleLayerRect):
+        (WebCore::LayerChromium::draw):
+        * platform/graphics/chromium/LayerRendererChromium.cpp:
+        (WebCore::calculateVisibleLayerRect):
+        (WebCore::LayerRendererChromium::paintLayerContents):
+        (WebCore::LayerRendererChromium::drawLayer):
+        * platform/graphics/chromium/RenderSurfaceChromium.cpp:
+        (WebCore::RenderSurfaceChromium::draw):
+        * platform/graphics/chromium/cc/CCCanvasLayerImpl.cpp:
+        (WebCore::CCCanvasLayerImpl::draw):
+        * platform/graphics/chromium/cc/CCCanvasLayerImpl.h:
+        * platform/graphics/chromium/cc/CCLayerImpl.cpp:
+        (WebCore::CCLayerImpl::draw):
+        * platform/graphics/chromium/cc/CCLayerImpl.h:
+        (WebCore::CCLayerImpl::contentBounds):
+        (WebCore::CCLayerImpl::setContentBounds):
+        (WebCore::CCLayerImpl::visibleLayerRect):
+        (WebCore::CCLayerImpl::setVisibleLayerRect):
+        (WebCore::CCLayerImpl::doubleSided):
+        (WebCore::CCLayerImpl::setDoubleSided):
+        * platform/graphics/chromium/cc/CCPluginLayerImpl.cpp:
+        (WebCore::CCPluginLayerImpl::draw):
+        * platform/graphics/chromium/cc/CCPluginLayerImpl.h:
+        * platform/graphics/chromium/cc/CCVideoLayerImpl.cpp:
+        (WebCore::CCVideoLayerImpl::draw):
+        * platform/graphics/chromium/cc/CCVideoLayerImpl.h:
+
 2011-07-06  John Sullivan  <[email protected]>
 
         IconDatabase::synchronousIconForPageURL() has inconsistent API when no custom icon is available

Modified: trunk/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp (90491 => 90492)


--- trunk/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp	2011-07-06 20:50:46 UTC (rev 90491)
+++ trunk/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp	2011-07-06 20:56:28 UTC (rev 90492)
@@ -92,7 +92,6 @@
 ContentLayerChromium::ContentLayerChromium(GraphicsLayerChromium* owner)
     : LayerChromium(owner)
     , m_tilingOption(ContentLayerChromium::AutoTile)
-    , m_isMask(false)
 {
 }
 
@@ -101,19 +100,19 @@
     cleanupResources();
 }
 
-void ContentLayerChromium::paintContentsIfDirty(const IntRect& targetSurfaceRect)
+void ContentLayerChromium::paintContentsIfDirty()
 {
     ASSERT(drawsContent());
     ASSERT(layerRenderer());
 
-    updateLayerSize(layerBounds().size());
+    updateLayerSize();
 
-    IntRect layerRect = visibleLayerRect(targetSurfaceRect);
+    const IntRect& layerRect = visibleLayerRect();
     if (layerRect.isEmpty())
         return;
 
     IntRect dirty = enclosingIntRect(m_dirtyRect);
-    dirty.intersect(layerBounds());
+    dirty.intersect(IntRect(IntPoint(), contentBounds()));
     m_tiler->invalidateRect(dirty);
 
     if (!drawsContent())
@@ -152,66 +151,36 @@
 TransformationMatrix ContentLayerChromium::tilingTransform()
 {
     TransformationMatrix transform = ccLayerImpl()->drawTransform();
-    // Tiler draws from the upper left corner. The draw transform
-    // specifies the middle of the layer.
-    IntSize size = bounds();
-    transform.translate(-size.width() / 2.0, -size.height() / 2.0);
 
-    return transform;
-}
+    if (contentBounds().isEmpty())
+        return transform;
 
-IntRect ContentLayerChromium::visibleLayerRect(const IntRect& targetSurfaceRect)
-{
-    if (targetSurfaceRect.isEmpty())
-        return targetSurfaceRect;
+    transform.scaleNonUniform(bounds().width() / static_cast<double>(contentBounds().width()),
+                              bounds().height() / static_cast<double>(contentBounds().height()));
 
-    const IntRect layerBoundRect = layerBounds();
+    // Tiler draws with a different origin from other layers.
+    transform.translate(-contentBounds().width() / 2.0, -contentBounds().height() / 2.0);
 
-    // Mask layers don't have their own draw transform so we return the entire
-    // layer bounds as the visible rect.
-    if (m_isMask)
-        return layerBoundRect;
-
-    const TransformationMatrix transform = tilingTransform();
-
-    // Is this layer fully contained within the target surface?
-    IntRect layerInSurfaceSpace = transform.mapRect(layerBoundRect);
-    if (targetSurfaceRect.contains(layerInSurfaceSpace))
-        return layerBoundRect;
-
-    // If the layer doesn't fill up the entire surface, then find the part of
-    // the surface rect where the layer could be visible. This avoids trying to
-    // project surface rect points that are behind the projection point.
-    IntRect minimalSurfaceRect = targetSurfaceRect;
-    minimalSurfaceRect.intersect(layerInSurfaceSpace);
-
-    // Project the corners of the target surface rect into the layer space.
-    // This bounding rectangle may be larger than it needs to be (being
-    // axis-aligned), but is a reasonable filter on the space to consider.
-    // Non-invertible transforms will create an empty rect here.
-    const TransformationMatrix surfaceToLayer = transform.inverse();
-    IntRect layerRect = surfaceToLayer.projectQuad(FloatQuad(FloatRect(minimalSurfaceRect))).enclosingBoundingBox();
-    layerRect.intersect(layerBoundRect);
-    return layerRect;
+    return transform;
 }
 
-IntRect ContentLayerChromium::layerBounds() const
+IntSize ContentLayerChromium::contentBounds() const
 {
-    return IntRect(IntPoint(0, 0), bounds());
+    return bounds();
 }
 
-void ContentLayerChromium::updateLayerSize(const IntSize& layerSize)
+void ContentLayerChromium::updateLayerSize()
 {
     if (!m_tiler)
         return;
 
-    const IntSize tileSize(min(defaultTileSize, layerSize.width()), min(defaultTileSize, layerSize.height()));
+    const IntSize tileSize(min(defaultTileSize, contentBounds().width()), min(defaultTileSize, contentBounds().height()));
 
     // Tile if both dimensions large, or any one dimension large and the other
     // extends into a second tile. This heuristic allows for long skinny layers
     // (e.g. scrollbars) that are Nx1 tiles to minimize wasted texture space.
-    const bool anyDimensionLarge = layerSize.width() > maxUntiledSize || layerSize.height() > maxUntiledSize;
-    const bool anyDimensionOneTile = layerSize.width() <= defaultTileSize || layerSize.height() <= defaultTileSize;
+    const bool anyDimensionLarge = contentBounds().width() > maxUntiledSize || contentBounds().height() > maxUntiledSize;
+    const bool anyDimensionOneTile = contentBounds().width() <= defaultTileSize || contentBounds().height() <= defaultTileSize;
     const bool autoTiled = anyDimensionLarge && !anyDimensionOneTile;
 
     bool isTiled;
@@ -222,18 +191,17 @@
     else
         isTiled = autoTiled;
 
-    IntSize requestedSize = isTiled ? tileSize : layerSize;
+    IntSize requestedSize = isTiled ? tileSize : contentBounds();
     const int maxSize = layerRenderer()->maxTextureSize();
     IntSize clampedSize = requestedSize.shrunkTo(IntSize(maxSize, maxSize));
     m_tiler->setTileSize(clampedSize);
 }
 
-void ContentLayerChromium::draw(const IntRect& targetSurfaceRect)
+void ContentLayerChromium::draw()
 {
-    const TransformationMatrix transform = tilingTransform();
-    IntRect layerRect = visibleLayerRect(targetSurfaceRect);
+    const IntRect& layerRect = visibleLayerRect();
     if (!layerRect.isEmpty())
-        m_tiler->draw(layerRect, transform, ccLayerImpl()->drawOpacity(), m_textureUpdater.get());
+        m_tiler->draw(layerRect, tilingTransform(), ccLayerImpl()->drawOpacity(), m_textureUpdater.get());
 }
 
 bool ContentLayerChromium::drawsContent() const
@@ -271,7 +239,7 @@
 void ContentLayerChromium::setTilingOption(TilingOption option)
 {
     m_tilingOption = option;
-    updateLayerSize(bounds());
+    updateLayerSize();
 }
 
 void ContentLayerChromium::bindContentsTexture()
@@ -289,7 +257,6 @@
 void ContentLayerChromium::setIsMask(bool isMask)
 {
     setTilingOption(isMask ? NeverTile : AutoTile);
-    m_isMask = isMask;
 }
 
 static void writeIndent(TextStream& ts, int indent)

Modified: trunk/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.h (90491 => 90492)


--- trunk/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.h	2011-07-06 20:50:46 UTC (rev 90491)
+++ trunk/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.h	2011-07-06 20:56:28 UTC (rev 90492)
@@ -52,12 +52,12 @@
 
     virtual ~ContentLayerChromium();
 
-    virtual void paintContentsIfDirty(const IntRect& targetSurfaceRect);
+    virtual void paintContentsIfDirty();
     virtual void updateCompositorResources();
     virtual void setIsMask(bool);
     virtual void bindContentsTexture();
 
-    virtual void draw(const IntRect& targetSurfaceRect);
+    virtual void draw();
     virtual bool drawsContent() const;
 
 protected:
@@ -69,15 +69,11 @@
     virtual void cleanupResources();
     virtual void setLayerRenderer(LayerRendererChromium*);
 
-    virtual IntRect layerBounds() const;
+    virtual IntSize contentBounds() const;
 
-    virtual TransformationMatrix tilingTransform();
+    TransformationMatrix tilingTransform();
 
-    // For a given render surface rect that this layer will be transformed and
-    // drawn into, return the layer space rect that is visible in that surface.
-    IntRect visibleLayerRect(const IntRect&);
-
-    void updateLayerSize(const IntSize&);
+    void updateLayerSize();
     void createTilerIfNeeded();
     virtual void createTextureUpdaterIfNeeded();
     void setTilingOption(TilingOption);
@@ -85,7 +81,6 @@
     OwnPtr<LayerTextureUpdater> m_textureUpdater;
     OwnPtr<LayerTilerChromium> m_tiler;
     TilingOption m_tilingOption;
-    bool m_isMask;
 };
 
 }

Modified: trunk/Source/WebCore/platform/graphics/chromium/ImageLayerChromium.cpp (90491 => 90492)


--- trunk/Source/WebCore/platform/graphics/chromium/ImageLayerChromium.cpp	2011-07-06 20:50:46 UTC (rev 90491)
+++ trunk/Source/WebCore/platform/graphics/chromium/ImageLayerChromium.cpp	2011-07-06 20:56:28 UTC (rev 90492)
@@ -140,7 +140,7 @@
     setNeedsDisplay();
 }
 
-void ImageLayerChromium::paintContentsIfDirty(const IntRect& targetSurfaceRect)
+void ImageLayerChromium::paintContentsIfDirty()
 {
     ASSERT(layerRenderer());
 
@@ -148,18 +148,15 @@
         // FIXME: This downcast is bad. The fix is to make ImageLayerChromium not derive from ContentLayerChromium.
         ImageLayerTextureUpdater* imageTextureUpdater = static_cast<ImageLayerTextureUpdater*>(m_textureUpdater.get());
         imageTextureUpdater->updateFromImage(m_contents->nativeImageForCurrentFrame());
-        updateLayerSize(imageTextureUpdater->imageSize());
-        IntRect paintRect(IntPoint(0, 0), imageTextureUpdater->imageSize());
+        updateLayerSize();
+        IntRect paintRect(IntPoint(), contentBounds());
         if (!m_dirtyRect.isEmpty()) {
             m_tiler->invalidateRect(paintRect);
             m_dirtyRect = IntRect();
         }
     }
-    IntRect layerRect = visibleLayerRect(targetSurfaceRect);
-    if (layerRect.isEmpty())
-        return;
 
-    m_tiler->prepareToUpdate(layerRect, m_textureUpdater.get());
+    m_tiler->prepareToUpdate(visibleLayerRect(), m_textureUpdater.get());
 }
 
 void ImageLayerChromium::updateCompositorResources()
@@ -167,45 +164,16 @@
     m_tiler->updateRect(m_textureUpdater.get());
 }
 
-void ImageLayerChromium::setLayerRenderer(LayerRendererChromium* newLayerRenderer)
-{
-    if (newLayerRenderer != layerRenderer())
-        m_textureUpdater.clear();
-    ContentLayerChromium::setLayerRenderer(newLayerRenderer);
-}
-
 void ImageLayerChromium::createTextureUpdaterIfNeeded()
 {
     if (!m_textureUpdater)
         m_textureUpdater = ImageLayerTextureUpdater::create(layerRendererContext(), layerRenderer()->contextSupportsMapSub());
 }
 
-IntRect ImageLayerChromium::layerBounds() const
+IntSize ImageLayerChromium::contentBounds() const
 {
-    if (!m_textureUpdater)
-        return IntRect();
-    ImageLayerTextureUpdater* imageTextureUpdater = static_cast<ImageLayerTextureUpdater*>(m_textureUpdater.get());
-    return IntRect(IntPoint(), imageTextureUpdater->imageSize());
+    return m_contents->size();
 }
 
-TransformationMatrix ImageLayerChromium::tilingTransform()
-{
-    // Tiler draws from the upper left corner. The draw transform
-    // specifies the middle of the layer.
-    TransformationMatrix transform = ccLayerImpl()->drawTransform();
-    const IntRect sourceRect = layerBounds();
-    const IntSize destSize = bounds();
-
-    transform.translate(-destSize.width() / 2.0, -destSize.height() / 2.0);
-
-    // Tiler also draws at the original content size, so rescale the original
-    // image dimensions to the bounds that it is meant to be drawn at.
-    float scaleX = destSize.width() / static_cast<float>(sourceRect.size().width());
-    float scaleY = destSize.height() / static_cast<float>(sourceRect.size().height());
-    transform.scale3d(scaleX, scaleY, 1.0f);
-
-    return transform;
 }
-
-}
 #endif // USE(ACCELERATED_COMPOSITING)

Modified: trunk/Source/WebCore/platform/graphics/chromium/ImageLayerChromium.h (90491 => 90492)


--- trunk/Source/WebCore/platform/graphics/chromium/ImageLayerChromium.h	2011-07-06 20:50:46 UTC (rev 90491)
+++ trunk/Source/WebCore/platform/graphics/chromium/ImageLayerChromium.h	2011-07-06 20:56:28 UTC (rev 90492)
@@ -51,7 +51,7 @@
     static PassRefPtr<ImageLayerChromium> create(GraphicsLayerChromium* owner = 0);
     virtual ~ImageLayerChromium();
 
-    virtual void paintContentsIfDirty(const IntRect& targetSurfaceRect);
+    virtual void paintContentsIfDirty();
     virtual void updateCompositorResources();
     virtual bool drawsContent() const { return m_contents; }
 
@@ -60,11 +60,8 @@
 protected:
     virtual const char* layerTypeAsString() const { return "ImageLayer"; }
 
-    virtual void setLayerRenderer(LayerRendererChromium*);
+    virtual IntSize contentBounds() const;
 
-    virtual TransformationMatrix tilingTransform();
-    virtual IntRect layerBounds() const;
-
 private:
     ImageLayerChromium(GraphicsLayerChromium* owner);
 

Modified: trunk/Source/WebCore/platform/graphics/chromium/LayerChromium.cpp (90491 => 90492)


--- trunk/Source/WebCore/platform/graphics/chromium/LayerChromium.cpp	2011-07-06 20:50:46 UTC (rev 90491)
+++ trunk/Source/WebCore/platform/graphics/chromium/LayerChromium.cpp	2011-07-06 20:56:28 UTC (rev 90492)
@@ -291,6 +291,7 @@
     layer->setAnchorPoint(m_anchorPoint);
     layer->setAnchorPointZ(m_anchorPointZ);
     layer->setBounds(m_bounds);
+    layer->setContentBounds(contentBounds());
     layer->setDebugBorderColor(m_debugBorderColor);
     layer->setDebugBorderWidth(m_debugBorderWidth);
     layer->setDoubleSided(m_doubleSided);
@@ -302,6 +303,7 @@
     layer->setPreserves3D(preserves3D());
     layer->setSublayerTransform(m_sublayerTransform);
     layer->setTransform(m_transform);
+    layer->setVisibleLayerRect(m_visibleLayerRect);
 
     if (maskLayer())
         maskLayer()->pushPropertiesTo(layer->maskLayer());

Modified: trunk/Source/WebCore/platform/graphics/chromium/LayerChromium.h (90491 => 90492)


--- trunk/Source/WebCore/platform/graphics/chromium/LayerChromium.h	2011-07-06 20:50:46 UTC (rev 90491)
+++ trunk/Source/WebCore/platform/graphics/chromium/LayerChromium.h	2011-07-06 20:56:28 UTC (rev 90492)
@@ -86,6 +86,7 @@
 
     void setBounds(const IntSize&);
     const IntSize& bounds() const { return m_bounds; }
+    virtual IntSize contentBounds() const { return bounds(); }
 
     void setClearsContext(bool clears) { m_clearsContext = clears; setNeedsCommit(); }
     bool clearsContext() const { return m_clearsContext; }
@@ -132,6 +133,9 @@
     void setTransform(const TransformationMatrix& transform) { m_transform = transform; setNeedsCommit(); }
     const TransformationMatrix& transform() const { return m_transform; }
 
+    const IntRect& visibleLayerRect() const { return m_visibleLayerRect; }
+    void setVisibleLayerRect(const IntRect& visibleLayerRect) { m_visibleLayerRect = visibleLayerRect; }
+
     bool doubleSided() const { return m_doubleSided; }
     void setDoubleSided(bool doubleSided) { m_doubleSided = doubleSided; setNeedsCommit(); }
 
@@ -152,13 +156,12 @@
 
     // These methods typically need to be overwritten by derived classes.
     virtual bool drawsContent() const { return false; }
-    virtual void paintContentsIfDirty(const IntRect&) { }
     virtual void paintContentsIfDirty() { }
     virtual void updateCompositorResources() { }
     virtual void setIsMask(bool) {}
     virtual void unreserveContentsTexture() { }
     virtual void bindContentsTexture() { }
-    virtual void draw(const IntRect&) { }
+    virtual void draw() { }
 
     // These exists just for debugging (via drawDebugBorder()).
     void setBorderColor(const Color&);
@@ -249,6 +252,7 @@
 
     // Layer properties.
     IntSize m_bounds;
+    IntRect m_visibleLayerRect;
     FloatPoint m_position;
     FloatPoint m_anchorPoint;
     Color m_backgroundColor;

Modified: trunk/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp (90491 => 90492)


--- trunk/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp	2011-07-06 20:50:46 UTC (rev 90491)
+++ trunk/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp	2011-07-06 20:56:28 UTC (rev 90492)
@@ -358,6 +358,47 @@
     updateCompositorResources(renderSurfaceLayerList);
 }
 
+static IntRect calculateVisibleLayerRect(const IntRect& targetSurfaceRect, const IntSize& bounds, const IntSize& contentBounds, const TransformationMatrix& tilingTransform)
+{
+    if (targetSurfaceRect.isEmpty() || contentBounds.isEmpty())
+        return targetSurfaceRect;
+
+    const IntRect layerBoundRect = IntRect(IntPoint(), contentBounds);
+    TransformationMatrix transform = tilingTransform;
+
+    transform.scaleNonUniform(bounds.width() / static_cast<double>(contentBounds.width()),
+                              bounds.height() / static_cast<double>(contentBounds.height()));
+    transform.translate(-contentBounds.width() / 2.0, -contentBounds.height() / 2.0);
+
+    // Is this layer fully contained within the target surface?
+    IntRect layerInSurfaceSpace = transform.mapRect(layerBoundRect);
+    if (targetSurfaceRect.contains(layerInSurfaceSpace))
+        return layerBoundRect;
+
+    // If the layer doesn't fill up the entire surface, then find the part of
+    // the surface rect where the layer could be visible. This avoids trying to
+    // project surface rect points that are behind the projection point.
+    IntRect minimalSurfaceRect = targetSurfaceRect;
+    minimalSurfaceRect.intersect(layerInSurfaceSpace);
+
+    // Project the corners of the target surface rect into the layer space.
+    // This bounding rectangle may be larger than it needs to be (being
+    // axis-aligned), but is a reasonable filter on the space to consider.
+    // Non-invertible transforms will create an empty rect here.
+    const TransformationMatrix surfaceToLayer = transform.inverse();
+    IntRect layerRect = surfaceToLayer.projectQuad(FloatQuad(FloatRect(minimalSurfaceRect))).enclosingBoundingBox();
+    layerRect.intersect(layerBoundRect);
+    return layerRect;
+}
+
+static void paintContentsIfDirty(LayerChromium* layer, const IntRect& visibleLayerRect)
+{
+    if (layer->drawsContent()) {
+        layer->setVisibleLayerRect(visibleLayerRect);
+        layer->paintContentsIfDirty();
+    }
+}
+
 void LayerRendererChromium::paintLayerContents(const LayerList& renderSurfaceLayerList)
 {
     for (int surfaceIndex = renderSurfaceLayerList.size() - 1; surfaceIndex >= 0 ; --surfaceIndex) {
@@ -398,20 +439,26 @@
             }
 
             if (layer->bounds().isEmpty())
-              continue;
+                continue;
 
             IntRect targetSurfaceRect = ccLayerImpl->targetRenderSurface() ? ccLayerImpl->targetRenderSurface()->contentRect() : m_defaultRenderSurface->contentRect();
             if (layer->ccLayerImpl()->usesLayerScissor())
                 targetSurfaceRect.intersect(layer->ccLayerImpl()->scissorRect());
+            IntRect visibleLayerRect = calculateVisibleLayerRect(targetSurfaceRect, layer->bounds(), layer->contentBounds(), ccLayerImpl->drawTransform());
 
-            if (layer->drawsContent())
-                layer->paintContentsIfDirty(targetSurfaceRect);
-            if (layer->maskLayer() && layer->maskLayer()->drawsContent())
-                layer->maskLayer()->paintContentsIfDirty(targetSurfaceRect);
-            if (layer->replicaLayer() && layer->replicaLayer()->drawsContent())
-                layer->replicaLayer()->paintContentsIfDirty(targetSurfaceRect);
-            if (layer->replicaLayer() && layer->replicaLayer()->maskLayer() && layer->replicaLayer()->maskLayer()->drawsContent())
-                layer->replicaLayer()->maskLayer()->paintContentsIfDirty(targetSurfaceRect);
+            paintContentsIfDirty(layer, visibleLayerRect);
+
+            if (LayerChromium* maskLayer = layer->maskLayer()) {
+                paintContentsIfDirty(maskLayer, IntRect(IntPoint(), maskLayer->contentBounds()));
+            }
+
+            if (LayerChromium* replicaLayer = layer->replicaLayer()) {
+                paintContentsIfDirty(replicaLayer, visibleLayerRect);
+
+                if (LayerChromium* replicaMaskLayer = replicaLayer->maskLayer()) {
+                    paintContentsIfDirty(replicaMaskLayer, IntRect(IntPoint(), replicaMaskLayer->contentBounds()));
+                }
+            }
         }
     }
 }
@@ -985,7 +1032,7 @@
             return;
     }
 
-    layer->draw(targetSurfaceRect);
+    layer->draw();
 
     // Draw the debug border if there is one.
     layer->drawDebugBorder();

Modified: trunk/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.cpp (90491 => 90492)


--- trunk/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.cpp	2011-07-06 20:50:46 UTC (rev 90491)
+++ trunk/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.cpp	2011-07-06 20:56:28 UTC (rev 90492)
@@ -166,7 +166,7 @@
 
 
     // Reflection draws before the layer.
-    if (m_owningLayer->replicaLayer()) 
+    if (m_owningLayer->replicaLayer())
         drawSurface(replicaMaskLayer, m_replicaDrawTransform);
 
     drawSurface(m_maskLayer, m_drawTransform);

Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCCanvasLayerImpl.cpp (90491 => 90492)


--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCCanvasLayerImpl.cpp	2011-07-06 20:50:46 UTC (rev 90491)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCCanvasLayerImpl.cpp	2011-07-06 20:56:28 UTC (rev 90492)
@@ -48,7 +48,7 @@
 {
 }
 
-void CCCanvasLayerImpl::draw(const IntRect&)
+void CCCanvasLayerImpl::draw()
 {
     ASSERT(layerRenderer());
     const CCCanvasLayerImpl::Program* program = layerRenderer()->canvasLayerProgram();

Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCCanvasLayerImpl.h (90491 => 90492)


--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCCanvasLayerImpl.h	2011-07-06 20:50:46 UTC (rev 90491)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCCanvasLayerImpl.h	2011-07-06 20:56:28 UTC (rev 90492)
@@ -42,7 +42,7 @@
 
     typedef ProgramBinding<VertexShaderPosTex, FragmentShaderRGBATexFlipAlpha> Program;
 
-    virtual void draw(const IntRect&);
+    virtual void draw();
 
     virtual void dumpLayerProperties(TextStream&, int indent) const;
 

Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.cpp (90491 => 90492)


--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.cpp	2011-07-06 20:50:46 UTC (rev 90491)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.cpp	2011-07-06 20:56:28 UTC (rev 90492)
@@ -142,9 +142,9 @@
     return m_owner->drawsContent();
 }
 
-void CCLayerImpl::draw(const IntRect& targetSurfaceRect)
+void CCLayerImpl::draw()
 {
-    return m_owner->draw(targetSurfaceRect);
+    return m_owner->draw();
 }
 
 void CCLayerImpl::updateCompositorResources()

Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.h (90491 => 90492)


--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.h	2011-07-06 20:50:46 UTC (rev 90491)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.h	2011-07-06 20:56:28 UTC (rev 90492)
@@ -69,7 +69,7 @@
     int debugID() const { return m_debugID; }
 #endif
 
-    virtual void draw(const IntRect& contentRect);
+    virtual void draw();
     virtual void updateCompositorResources();
     void unreserveContentsTexture();
     void bindContentsTexture();
@@ -127,18 +127,28 @@
 
     RenderSurfaceChromium* renderSurface() const { return m_renderSurface.get(); }
     void clearRenderSurface() { m_renderSurface.clear(); }
+
     float drawOpacity() const { return m_drawOpacity; }
     void setDrawOpacity(float opacity) { m_drawOpacity = opacity; }
+
     const IntRect& scissorRect() const { return m_scissorRect; }
     void setScissorRect(const IntRect& rect) { m_scissorRect = rect; }
+
     RenderSurfaceChromium* targetRenderSurface() const { return m_targetRenderSurface; }
     void setTargetRenderSurface(RenderSurfaceChromium* surface) { m_targetRenderSurface = surface; }
 
-    bool doubleSided() const { return m_doubleSided; }
-    void setDoubleSided(bool doubleSided) { m_doubleSided = doubleSided; }
     const IntSize& bounds() const { return m_bounds; }
     void setBounds(const IntSize& bounds) { m_bounds = bounds; }
 
+    const IntSize& contentBounds() const { return m_contentBounds; }
+    void setContentBounds(const IntSize& contentBounds) { m_contentBounds = contentBounds; }
+
+    const IntRect& visibleLayerRect() const { return m_visibleLayerRect; }
+    void setVisibleLayerRect(const IntRect& visibleLayerRect) { m_visibleLayerRect = visibleLayerRect; }
+
+    bool doubleSided() const { return m_doubleSided; }
+    void setDoubleSided(bool doubleSided) { m_doubleSided = doubleSided; }
+
     // Returns the rect containtaining this layer in the current view's coordinate system.
     const IntRect getDrawRect() const;
 
@@ -152,6 +162,7 @@
     // HACK TODO fix this
     LayerChromium* owner() const { return m_owner; }
     void clearOwner() { m_owner = 0; }
+
 protected:
     // For now, CCLayerImpls have a back pointer to their LayerChromium.
     // FIXME: remove this after https://bugs.webkit.org/show_bug.cgi?id=58833 is fixed.
@@ -176,6 +187,8 @@
     FloatPoint m_anchorPoint;
     float m_anchorPointZ;
     IntSize m_bounds;
+    IntSize m_contentBounds;
+    IntRect m_visibleLayerRect;
 
     // Whether the "back" of this layer should draw.
     bool m_doubleSided;

Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCPluginLayerImpl.cpp (90491 => 90492)


--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCPluginLayerImpl.cpp	2011-07-06 20:50:46 UTC (rev 90491)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCPluginLayerImpl.cpp	2011-07-06 20:56:28 UTC (rev 90492)
@@ -46,7 +46,7 @@
 {
 }
 
-void CCPluginLayerImpl::draw(const IntRect&)
+void CCPluginLayerImpl::draw()
 {
     ASSERT(layerRenderer());
     const CCPluginLayerImpl::Program* program = layerRenderer()->pluginLayerProgram();

Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCPluginLayerImpl.h (90491 => 90492)


--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCPluginLayerImpl.h	2011-07-06 20:50:46 UTC (rev 90491)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCPluginLayerImpl.h	2011-07-06 20:56:28 UTC (rev 90492)
@@ -42,7 +42,7 @@
 
     typedef ProgramBinding<VertexShaderPosTex, FragmentShaderRGBATexFlipAlpha> Program;
 
-    virtual void draw(const IntRect&);
+    virtual void draw();
 
     virtual void dumpLayerProperties(TextStream&, int indent) const;
 

Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCVideoLayerImpl.cpp (90491 => 90492)


--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCVideoLayerImpl.cpp	2011-07-06 20:50:46 UTC (rev 90491)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCVideoLayerImpl.cpp	2011-07-06 20:56:28 UTC (rev 90492)
@@ -75,7 +75,7 @@
     m_textures[i] = texture;
 }
 
-void CCVideoLayerImpl::draw(const IntRect&)
+void CCVideoLayerImpl::draw()
 {
     if (m_skipsDraw)
         return;

Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCVideoLayerImpl.h (90491 => 90492)


--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCVideoLayerImpl.h	2011-07-06 20:50:46 UTC (rev 90491)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCVideoLayerImpl.h	2011-07-06 20:56:28 UTC (rev 90492)
@@ -47,7 +47,7 @@
     typedef ProgramBinding<VertexShaderPosTexTransform, FragmentShaderRGBATexFlipAlpha> RGBAProgram;
     typedef ProgramBinding<VertexShaderPosTexYUVStretch, FragmentShaderYUVVideo> YUVProgram;
 
-    virtual void draw(const IntRect&);
+    virtual void draw();
 
     virtual void dumpLayerProperties(TextStream&, int indent) const;
 
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to