Title: [109263] trunk/Source
Revision
109263
Author
commit-qu...@webkit.org
Date
2012-02-29 14:35:01 -0800 (Wed, 29 Feb 2012)

Log Message

[chromium] Don't let invalidation for next frame prevent tile upload
https://bugs.webkit.org/show_bug.cgi?id=79841

Patch by Dana Jansens <dan...@chromium.org> on 2012-02-29
Reviewed by James Robinson.

Source/WebCore:

We currently don't push dirty tiles to the impl thread so there are no
tiles with garbage data on the impl thread. However, this judgement is
overzealous and blocks tiles that get invalidated by WebKit for the
next frame during the paint of the current frame.

Instead, check if a tile is dirty and was not painted for the current
frame when deciding to push the tile to the impl thread. This requires
that we know if a tile was painted during the current frame, which we
can do if we always reset m_updateRect to be empty each frame.

New unit tests: TiledLayerChromiumTest.pushTilesMarkedDirtyDuringPaint
                TiledLayerChromiumTest.pushTilesLayerMarkedDirtyDuringPaintOnNextLayer
                TiledLayerChromiumTest.pushTilesLayerMarkedDirtyDuringPaintOnPreviousLayer

* platform/graphics/chromium/TiledLayerChromium.cpp:
(WebCore::UpdatableTile::isDirtyForCurrentFrame):
(WebCore::TiledLayerChromium::pushPropertiesTo):
(WebCore::TiledLayerChromium::prepareToUpdateTiles):
(WebCore::TiledLayerChromium::resetUpdateState):
(WebCore):
(WebCore::TiledLayerChromium::prepareToUpdate):
* platform/graphics/chromium/TiledLayerChromium.h:
(TiledLayerChromium):

Source/WebKit/chromium:

* tests/TiledLayerChromiumTest.cpp:
(WTF::TEST):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (109262 => 109263)


--- trunk/Source/WebCore/ChangeLog	2012-02-29 22:30:33 UTC (rev 109262)
+++ trunk/Source/WebCore/ChangeLog	2012-02-29 22:35:01 UTC (rev 109263)
@@ -1,3 +1,34 @@
+2012-02-29  Dana Jansens  <dan...@chromium.org>
+
+        [chromium] Don't let invalidation for next frame prevent tile upload
+        https://bugs.webkit.org/show_bug.cgi?id=79841
+
+        Reviewed by James Robinson.
+
+        We currently don't push dirty tiles to the impl thread so there are no
+        tiles with garbage data on the impl thread. However, this judgement is
+        overzealous and blocks tiles that get invalidated by WebKit for the
+        next frame during the paint of the current frame.
+
+        Instead, check if a tile is dirty and was not painted for the current
+        frame when deciding to push the tile to the impl thread. This requires
+        that we know if a tile was painted during the current frame, which we
+        can do if we always reset m_updateRect to be empty each frame.
+
+        New unit tests: TiledLayerChromiumTest.pushTilesMarkedDirtyDuringPaint
+                        TiledLayerChromiumTest.pushTilesLayerMarkedDirtyDuringPaintOnNextLayer
+                        TiledLayerChromiumTest.pushTilesLayerMarkedDirtyDuringPaintOnPreviousLayer
+
+        * platform/graphics/chromium/TiledLayerChromium.cpp:
+        (WebCore::UpdatableTile::isDirtyForCurrentFrame):
+        (WebCore::TiledLayerChromium::pushPropertiesTo):
+        (WebCore::TiledLayerChromium::prepareToUpdateTiles):
+        (WebCore::TiledLayerChromium::resetUpdateState):
+        (WebCore):
+        (WebCore::TiledLayerChromium::prepareToUpdate):
+        * platform/graphics/chromium/TiledLayerChromium.h:
+        (TiledLayerChromium):
+
 2012-02-29  Tommy Widenflycht  <tom...@google.com>
 
         MediaStream API: MediaStreamTrackList out-of-bounds access fix

Modified: trunk/Source/WebCore/platform/graphics/chromium/TiledLayerChromium.cpp (109262 => 109263)


--- trunk/Source/WebCore/platform/graphics/chromium/TiledLayerChromium.cpp	2012-02-29 22:30:33 UTC (rev 109262)
+++ trunk/Source/WebCore/platform/graphics/chromium/TiledLayerChromium.cpp	2012-02-29 22:35:01 UTC (rev 109263)
@@ -67,6 +67,7 @@
         m_updateRect = m_dirtyRect;
         m_dirtyRect = IntRect();
     }
+    bool isDirtyForCurrentFrame() { return !m_dirtyRect.isEmpty() && m_updateRect.isEmpty(); }
 
     IntRect m_dirtyRect;
     IntRect m_updateRect;
@@ -263,7 +264,7 @@
             invalidTiles.append(tile);
             continue;
         }
-        if (tile->isDirty())
+        if (tile->isDirtyForCurrentFrame())
             continue;
 
         tiledLayer->pushTileProperties(i, j, tile->managedTexture()->textureId(), tile->m_opaqueRect);
@@ -398,13 +399,6 @@
 
 void TiledLayerChromium::prepareToUpdateTiles(bool idle, int left, int top, int right, int bottom)
 {
-    // Reset m_updateRect for all tiles.
-    for (CCLayerTilingData::TileMap::const_iterator iter = m_tiler->tiles().begin(); iter != m_tiler->tiles().end(); ++iter) {
-        UpdatableTile* tile = static_cast<UpdatableTile*>(iter->second.get());
-        tile->m_updateRect = IntRect();
-        tile->m_partialUpdate = false;
-    }
-
     createTextureUpdaterIfNeeded();
 
     // Create tiles as needed, expanding a dirty rect to contain all
@@ -566,6 +560,17 @@
     }
 }
 
+void TiledLayerChromium::resetUpdateState()
+{
+    // Reset m_updateRect for all tiles.
+    CCLayerTilingData::TileMap::const_iterator end = m_tiler->tiles().end();
+    for (CCLayerTilingData::TileMap::const_iterator iter = m_tiler->tiles().begin(); iter != end; ++iter) {
+        UpdatableTile* tile = static_cast<UpdatableTile*>(iter->second.get());
+        tile->m_updateRect = IntRect();
+        tile->m_partialUpdate = false;
+    }
+}
+
 void TiledLayerChromium::prepareToUpdate(const IntRect& layerRect)
 {
     m_skipsDraw = false;
@@ -575,6 +580,8 @@
 
     updateBounds();
 
+    resetUpdateState();
+
     if (layerRect.isEmpty() || !m_tiler->numTiles())
         return;
 

Modified: trunk/Source/WebCore/platform/graphics/chromium/TiledLayerChromium.h (109262 => 109263)


--- trunk/Source/WebCore/platform/graphics/chromium/TiledLayerChromium.h	2012-02-29 22:30:33 UTC (rev 109262)
+++ trunk/Source/WebCore/platform/graphics/chromium/TiledLayerChromium.h	2012-02-29 22:35:01 UTC (rev 109263)
@@ -86,6 +86,9 @@
     // Set invalidations to be potentially repainted during update().
     void invalidateRect(const IntRect& layerRect);
 
+    // Reset state on tiles that will be used for updating the layer.
+    void resetUpdateState();
+
     // Prepare data needed to update textures that intersect with layerRect.
     void prepareToUpdate(const IntRect& layerRect);
 

Modified: trunk/Source/WebKit/chromium/ChangeLog (109262 => 109263)


--- trunk/Source/WebKit/chromium/ChangeLog	2012-02-29 22:30:33 UTC (rev 109262)
+++ trunk/Source/WebKit/chromium/ChangeLog	2012-02-29 22:35:01 UTC (rev 109263)
@@ -1,3 +1,13 @@
+2012-02-29  Dana Jansens  <dan...@chromium.org>
+
+        [chromium] Don't let invalidation for next frame prevent tile upload
+        https://bugs.webkit.org/show_bug.cgi?id=79841
+
+        Reviewed by James Robinson.
+
+        * tests/TiledLayerChromiumTest.cpp:
+        (WTF::TEST):
+
 2012-02-28  Sheriff Bot  <webkit.review....@gmail.com>
 
         Unreviewed, rolling out r107917 and r109188.

Modified: trunk/Source/WebKit/chromium/tests/TiledLayerChromiumTest.cpp (109262 => 109263)


--- trunk/Source/WebKit/chromium/tests/TiledLayerChromiumTest.cpp	2012-02-29 22:30:33 UTC (rev 109262)
+++ trunk/Source/WebKit/chromium/tests/TiledLayerChromiumTest.cpp	2012-02-29 22:35:01 UTC (rev 109263)
@@ -318,7 +318,103 @@
     }
 }
 
+TEST(TiledLayerChromiumTest, pushTilesMarkedDirtyDuringPaint)
+{
+    OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024);
+    RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
+    DebugScopedSetImplThread implThread;
+    OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
 
+    FakeTextureAllocator textureAllocator;
+    CCTextureUpdater updater(&textureAllocator);
+
+    // The tile size is 100x100, so this invalidates and then paints two tiles.
+    // However, during the paint, we invalidate one of the tiles. This should
+    // not prevent the tile from being pushed.
+    layer->setBounds(IntSize(100, 200));
+    layer->invalidateRect(IntRect(0, 0, 100, 200));
+    layer->fakeLayerTextureUpdater()->setRectToInvalidate(IntRect(0, 50, 100, 50), layer.get());
+    layer->prepareToUpdate(IntRect(0, 0, 100, 200));
+    layer->updateCompositorResources(0, updater);
+    layer->pushPropertiesTo(layerImpl.get());
+
+    // We should have both tiles on the impl side.
+    EXPECT_TRUE(layerImpl->hasTileAt(0, 0));
+    EXPECT_TRUE(layerImpl->hasTileAt(0, 1));
+}
+
+TEST(TiledLayerChromiumTest, pushTilesLayerMarkedDirtyDuringPaintOnNextLayer)
+{
+    OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024);
+    RefPtr<FakeTiledLayerChromium> layer1 = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
+    RefPtr<FakeTiledLayerChromium> layer2 = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
+    DebugScopedSetImplThread implThread;
+    OwnPtr<FakeCCTiledLayerImpl> layer1Impl(adoptPtr(new FakeCCTiledLayerImpl(0)));
+    OwnPtr<FakeCCTiledLayerImpl> layer2Impl(adoptPtr(new FakeCCTiledLayerImpl(0)));
+
+    FakeTextureAllocator textureAllocator;
+    CCTextureUpdater updater(&textureAllocator);
+
+    layer1->setBounds(IntSize(100, 200));
+    layer1->invalidateRect(IntRect(0, 0, 100, 200));
+    layer2->setBounds(IntSize(100, 200));
+    layer2->invalidateRect(IntRect(0, 0, 100, 200));
+
+    layer1->prepareToUpdate(IntRect(0, 0, 100, 200));
+
+    // Invalidate a tile on layer1
+    layer2->fakeLayerTextureUpdater()->setRectToInvalidate(IntRect(0, 50, 100, 50), layer1.get());
+    layer2->prepareToUpdate(IntRect(0, 0, 100, 200));
+
+    layer1->updateCompositorResources(0, updater);
+    layer2->updateCompositorResources(0, updater);
+
+    layer1->pushPropertiesTo(layer1Impl.get());
+    layer2->pushPropertiesTo(layer2Impl.get());
+
+    // We should have both tiles on the impl side for all layers.
+    EXPECT_TRUE(layer1Impl->hasTileAt(0, 0));
+    EXPECT_TRUE(layer1Impl->hasTileAt(0, 1));
+    EXPECT_TRUE(layer2Impl->hasTileAt(0, 0));
+    EXPECT_TRUE(layer2Impl->hasTileAt(0, 1));
+}
+
+TEST(TiledLayerChromiumTest, pushTilesLayerMarkedDirtyDuringPaintOnPreviousLayer)
+{
+    OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024);
+    RefPtr<FakeTiledLayerChromium> layer1 = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
+    RefPtr<FakeTiledLayerChromium> layer2 = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
+    DebugScopedSetImplThread implThread;
+    OwnPtr<FakeCCTiledLayerImpl> layer1Impl(adoptPtr(new FakeCCTiledLayerImpl(0)));
+    OwnPtr<FakeCCTiledLayerImpl> layer2Impl(adoptPtr(new FakeCCTiledLayerImpl(0)));
+
+    FakeTextureAllocator textureAllocator;
+    CCTextureUpdater updater(&textureAllocator);
+
+    layer1->setBounds(IntSize(100, 200));
+    layer1->invalidateRect(IntRect(0, 0, 100, 200));
+    layer2->setBounds(IntSize(100, 200));
+    layer2->invalidateRect(IntRect(0, 0, 100, 200));
+
+    // Invalidate a tile on layer2
+    layer1->fakeLayerTextureUpdater()->setRectToInvalidate(IntRect(0, 50, 100, 50), layer2.get());
+    layer1->prepareToUpdate(IntRect(0, 0, 100, 200));
+
+    layer2->prepareToUpdate(IntRect(0, 0, 100, 200));
+
+    layer1->updateCompositorResources(0, updater);
+    layer2->updateCompositorResources(0, updater);
+
+    layer1->pushPropertiesTo(layer1Impl.get());
+    layer2->pushPropertiesTo(layer2Impl.get());
+
+    // We should have both tiles on the impl side for all layers.
+    EXPECT_TRUE(layer1Impl->hasTileAt(0, 0));
+    EXPECT_TRUE(layer1Impl->hasTileAt(0, 1));
+    EXPECT_TRUE(layer2Impl->hasTileAt(0, 0));
+    EXPECT_TRUE(layer2Impl->hasTileAt(0, 1));
+}
+
 TEST(TiledLayerChromiumTest, idlePaintOutOfMemory)
 {
     // The tile size is 100x100. Setup 5x5 tiles with one 1x1 visible tile in the center.
@@ -486,6 +582,7 @@
     // Invalidate the entire layer again, but do not paint. All tiles should be gone now from the
     // impl side.
     layer->setNeedsDisplay();
+    layer->prepareToUpdate(IntRect(0, 0, 0, 0));
     layer->updateCompositorResources(0, updater);
     layer->pushPropertiesTo(layerImpl.get());
     EXPECT_FALSE(layerImpl->hasTileAt(0, 0));
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to