Unreviewed, rolling out r105366.
[WebKit-https.git] / Source / WebCore / platform / graphics / chromium / TiledLayerChromium.cpp
index 22580de..713b4e0 100644 (file)
@@ -33,6 +33,7 @@
 #include "LayerRendererChromium.h"
 #include "ManagedTexture.h"
 #include "MathExtras.h"
+#include "Region.h"
 #include "TextStream.h"
 #include "cc/CCLayerImpl.h"
 #include "cc/CCTextureUpdater.h"
@@ -57,12 +58,14 @@ public:
     LayerTextureUpdater::Texture* texture() { return m_texture.get(); }
     ManagedTexture* managedTexture() { return m_texture->texture(); }
 
-    bool isDirty() const { return !m_dirtyLayerRect.isEmpty(); }
-    void clearDirty() { m_dirtyLayerRect = IntRect(); }
+    bool isDirty() const { return !m_dirtyRect.isEmpty(); }
+    void copyAndClearDirty()
+    {
+        m_updateRect = m_dirtyRect;
+        m_dirtyRect = IntRect();
+    }
 
-    // Layer-space dirty rectangle that needs to be repainted.
-    IntRect m_dirtyLayerRect;
-    // Content-space rectangle that needs to be updated.
+    IntRect m_dirtyRect;
     IntRect m_updateRect;
 private:
     OwnPtr<LayerTextureUpdater::Texture> m_texture;
@@ -122,6 +125,23 @@ void TiledLayerChromium::updateTileSizeAndTilingOption()
     setTileSize(clampedSize);
 }
 
+void TiledLayerChromium::updateBounds()
+{
+    IntSize oldBounds = m_tiler->bounds();
+    IntSize newBounds = contentBounds();
+    if (oldBounds == newBounds)
+        return;
+    m_tiler->setBounds(newBounds);
+
+    // Invalidate any areas that the new bounds exposes.
+    Region oldRegion(IntRect(IntPoint(), oldBounds));
+    Region newRegion(IntRect(IntPoint(), newBounds));
+    newRegion.subtract(oldRegion);
+    Vector<IntRect> rects = newRegion.rects();
+    for (size_t i = 0; i < rects.size(); ++i)
+        invalidateRect(rects[i]);
+}
+
 void TiledLayerChromium::setTileSize(const IntSize& size)
 {
     m_tiler->setTileSize(size);
@@ -134,7 +154,7 @@ void TiledLayerChromium::setBorderTexelOption(CCLayerTilingData::BorderTexelOpti
 
 bool TiledLayerChromium::drawsContent() const
 {
-    if (!m_delegate)
+    if (!LayerChromium::drawsContent() || !m_delegate)
         return false;
 
     if (m_tilingOption == NeverTile && m_tiler->numTiles() > 1)
@@ -196,7 +216,7 @@ void TiledLayerChromium::updateCompositorResources(GraphicsContext3D*, CCTexture
                 continue;
 
             ASSERT(tile->managedTexture()->isReserved());
-            const IntPoint anchor = m_tiler->tileContentRect(tile).location();
+            const IntPoint anchor = m_tiler->tileRect(tile).location();
 
             // Calculate tile-space rectangle to upload into.
             IntRect destRect(IntPoint(sourceRect.x() - anchor.x(), sourceRect.y() - anchor.y()), sourceRect.size());
@@ -220,7 +240,7 @@ void TiledLayerChromium::updateCompositorResources(GraphicsContext3D*, CCTexture
         }
     }
 
-    m_updateRect = FloatRect(m_tiler->contentRectToLayerRect(m_paintRect));
+    m_updateRect = FloatRect(m_paintRect);
 }
 
 void TiledLayerChromium::setTilingOption(TilingOption tilingOption)
@@ -272,7 +292,7 @@ UpdatableTile* TiledLayerChromium::createTile(int i, int j)
 {
     RefPtr<UpdatableTile> tile = adoptRef(new UpdatableTile(textureUpdater()->createTexture(textureManager())));
     m_tiler->addTile(tile, i, j);
-    tile->m_dirtyLayerRect = m_tiler->tileLayerRect(tile.get());
+    tile->m_dirtyRect = m_tiler->tileRect(tile.get());
 
     return tile.get();
 }
@@ -298,25 +318,21 @@ void TiledLayerChromium::setIsNonCompositedContent(bool isNonCompositedContent)
     setBorderTexelOption(borderTexelOption);
 }
 
-void TiledLayerChromium::invalidateRect(const IntRect& contentRect)
+void TiledLayerChromium::invalidateRect(const IntRect& layerRect)
 {
-    if (m_tiler->isEmpty() || contentRect.isEmpty() || m_skipsDraw)
+    if (m_tiler->isEmpty() || layerRect.isEmpty() || m_skipsDraw)
         return;
 
-    // Dirty rects are always in layer space, as the layer could be repositioned
-    // after invalidation.
-    const IntRect layerRect = m_tiler->contentRectToLayerRect(contentRect);
-
     int left, top, right, bottom;
-    m_tiler->contentRectToTileIndices(contentRect, left, top, right, bottom);
+    m_tiler->layerRectToTileIndices(layerRect, left, top, right, bottom);
     for (int j = top; j <= bottom; ++j) {
         for (int i = left; i <= right; ++i) {
             UpdatableTile* tile = tileAt(i, j);
             if (!tile)
                 continue;
-            IntRect bound = m_tiler->tileLayerRect(tile);
+            IntRect bound = m_tiler->tileRect(tile);
             bound.intersect(layerRect);
-            tile->m_dirtyLayerRect.unite(bound);
+            tile->m_dirtyRect.unite(bound);
         }
     }
 }
@@ -326,13 +342,13 @@ void TiledLayerChromium::protectVisibleTileTextures()
     protectTileTextures(IntRect(IntPoint::zero(), contentBounds()));
 }
 
-void TiledLayerChromium::protectTileTextures(const IntRect& contentRect)
+void TiledLayerChromium::protectTileTextures(const IntRect& layerRect)
 {
-    if (m_tiler->isEmpty() || contentRect.isEmpty())
+    if (m_tiler->isEmpty() || layerRect.isEmpty())
         return;
 
     int left, top, right, bottom;
-    m_tiler->contentRectToTileIndices(contentRect, left, top, right, bottom);
+    m_tiler->layerRectToTileIndices(layerRect, left, top, right, bottom);
 
     for (int j = top; j <= bottom; ++j) {
         for (int i = left; i <= right; ++i) {
@@ -354,7 +370,9 @@ void TiledLayerChromium::prepareToUpdateTiles(bool idle, int left, int top, int
     }
 
     // Create tiles as needed, expanding a dirty rect to contain all
-    // the dirty regions currently being drawn.
+    // the dirty regions currently being drawn. All dirty tiles that are to be painted
+    // get their m_updateRect set to m_dirtyRect and m_dirtyRect cleared. This way if
+    // invalidateRect is invoked during prepareToUpdate we don't lose the request.
     IntRect dirtyLayerRect;
     for (int j = top; j <= bottom; ++j) {
         for (int i = left; i <= right; ++i) {
@@ -363,7 +381,7 @@ void TiledLayerChromium::prepareToUpdateTiles(bool idle, int left, int top, int
                 tile = createTile(i, j);
 
             if (!tile->managedTexture()->isValid(m_tiler->tileSize(), m_textureFormat))
-                tile->m_dirtyLayerRect = m_tiler->tileLayerRect(tile);
+                tile->m_dirtyRect = m_tiler->tileRect(tile);
 
             if (!tile->managedTexture()->reserve(m_tiler->tileSize(), m_textureFormat)) {
                 m_skipsIdlePaint = true;
@@ -374,11 +392,12 @@ void TiledLayerChromium::prepareToUpdateTiles(bool idle, int left, int top, int
                 return;
             }
 
-            dirtyLayerRect.unite(tile->m_dirtyLayerRect);
+            dirtyLayerRect.unite(tile->m_dirtyRect);
+            tile->copyAndClearDirty();
         }
     }
 
-    m_paintRect = m_tiler->layerRectToContentRect(dirtyLayerRect);
+    m_paintRect = dirtyLayerRect;
     if (dirtyLayerRect.isEmpty())
         return;
 
@@ -393,7 +412,8 @@ void TiledLayerChromium::prepareToUpdateTiles(bool idle, int left, int top, int
     // However, we can't free the memory backing the GraphicsContext until the paint finishes,
     // so we grab a local reference here to hold the updater alive until the paint completes.
     RefPtr<LayerTextureUpdater> protector(textureUpdater());
-    textureUpdater()->prepareToUpdate(m_paintRect, m_tiler->tileSize(), m_tiler->hasBorderTexels(), contentsScale());
+    IntRect opaqueRect; // FIXME: unused. remove this and store in the layer to pass to impl for draw culling
+    textureUpdater()->prepareToUpdate(m_paintRect, m_tiler->tileSize(), m_tiler->hasBorderTexels(), contentsScale(), &opaqueRect);
     for (int j = top; j <= bottom; ++j) {
         for (int i = left; i <= right; ++i) {
             UpdatableTile* tile = tileAt(i, j);
@@ -402,20 +422,17 @@ void TiledLayerChromium::prepareToUpdateTiles(bool idle, int left, int top, int
             if (!tile)
                 CRASH();
 
-            if (!tile->isDirty())
+            // Use m_updateRect as copyAndClearDirty above moved the existing dirty rect to m_updateRect.
+            const IntRect& dirtyRect = tile->m_updateRect;
+            if (dirtyRect.isEmpty())
                 continue;
 
-            // Calculate content-space rectangle to copy from.
-            IntRect sourceRect = m_tiler->tileContentRect(tile);
-            sourceRect.intersect(m_tiler->layerRectToContentRect(tile->m_dirtyLayerRect));
+            IntRect sourceRect = m_tiler->tileRect(tile);
+            sourceRect.intersect(dirtyRect);
             // Paint rect not guaranteed to line up on tile boundaries, so
             // make sure that sourceRect doesn't extend outside of it.
             sourceRect.intersect(m_paintRect);
 
-            // updateCompositorResources() uses m_updateRect to determine
-            // the tiles to update so we can clear the dirty rectangle here.
-            tile->clearDirty();
-
             tile->m_updateRect = sourceRect;
             if (sourceRect.isEmpty())
                 continue;
@@ -426,25 +443,25 @@ void TiledLayerChromium::prepareToUpdateTiles(bool idle, int left, int top, int
 }
 
 
-void TiledLayerChromium::prepareToUpdate(const IntRect& contentRect)
+void TiledLayerChromium::prepareToUpdate(const IntRect& layerRect)
 {
     m_skipsDraw = false;
     m_skipsIdlePaint = false;
     m_requestedUpdateTilesRect = IntRect();
     m_paintRect = IntRect();
 
-    m_tiler->growLayerToContain(IntRect(IntPoint::zero(), contentBounds()));
+    updateBounds();
 
-    if (contentRect.isEmpty() || !m_tiler->numTiles())
+    if (layerRect.isEmpty() || !m_tiler->numTiles())
         return;
 
     int left, top, right, bottom;
-    m_tiler->contentRectToTileIndices(contentRect, left, top, right, bottom);
+    m_tiler->layerRectToTileIndices(layerRect, left, top, right, bottom);
 
     prepareToUpdateTiles(false, left, top, right, bottom);
 }
 
-void TiledLayerChromium::prepareToUpdateIdle(const IntRect& contentRect)
+void TiledLayerChromium::prepareToUpdateIdle(const IntRect& layerRect)
 {
     // Abort if we have already prepared a paint or run out of memory.
     if (m_skipsIdlePaint || !m_paintRect.isEmpty())
@@ -452,21 +469,21 @@ void TiledLayerChromium::prepareToUpdateIdle(const IntRect& contentRect)
 
     ASSERT(m_tiler);
 
-    m_tiler->growLayerToContain(IntRect(IntPoint::zero(), contentBounds()));
+    updateBounds();
 
     if (m_tiler->isEmpty())
         return;
 
     // Protect any textures in the pre-paint area so we don't end up just
     // reclaiming them below.
-    IntRect idlePaintContentRect = idlePaintRect(contentRect);
-    protectTileTextures(idlePaintContentRect);
+    IntRect idlePaintLayerRect = idlePaintRect(layerRect);
+    protectTileTextures(idlePaintLayerRect);
 
     // Expand outwards until we find a dirty row or column to update.
     int left, top, right, bottom;
-    m_tiler->contentRectToTileIndices(contentRect, left, top, right, bottom);
+    m_tiler->layerRectToTileIndices(layerRect, left, top, right, bottom);
     int prepaintLeft, prepaintTop, prepaintRight, prepaintBottom;
-    m_tiler->contentRectToTileIndices(idlePaintContentRect, prepaintLeft, prepaintTop, prepaintRight, prepaintBottom);
+    m_tiler->layerRectToTileIndices(idlePaintLayerRect, prepaintLeft, prepaintTop, prepaintRight, prepaintBottom);
     while (!m_skipsIdlePaint && (left > prepaintLeft || top > prepaintTop || right < prepaintRight || bottom < prepaintBottom)) {
         if (bottom < prepaintBottom) {
             ++bottom;
@@ -495,15 +512,15 @@ void TiledLayerChromium::prepareToUpdateIdle(const IntRect& contentRect)
     }
 }
 
-bool TiledLayerChromium::needsIdlePaint(const IntRect& contentRect)
+bool TiledLayerChromium::needsIdlePaint(const IntRect& layerRect)
 {
     if (m_skipsIdlePaint)
         return false;
 
-    IntRect idlePaintContentRect = idlePaintRect(contentRect);
+    IntRect idlePaintLayerRect = idlePaintRect(layerRect);
 
     int left, top, right, bottom;
-    m_tiler->contentRectToTileIndices(idlePaintContentRect, left, top, right, bottom);
+    m_tiler->layerRectToTileIndices(idlePaintLayerRect, left, top, right, bottom);
     for (int j = top; j <= bottom; ++j) {
         for (int i = left; i <= right; ++i) {
             if (m_requestedUpdateTilesRect.contains(IntPoint(i, j)))
@@ -516,9 +533,9 @@ bool TiledLayerChromium::needsIdlePaint(const IntRect& contentRect)
     return false;
 }
 
-IntRect TiledLayerChromium::idlePaintRect(const IntRect& visibleContentRect)
+IntRect TiledLayerChromium::idlePaintRect(const IntRect& visibleLayerRect)
 {
-    IntRect prepaintRect = visibleContentRect;
+    IntRect prepaintRect = visibleLayerRect;
     // FIXME: This can be made a lot larger if we can:
     // - reserve memory at a lower priority than for visible content
     // - only reserve idle paint tiles up to a memory reclaim threshold and