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/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));