Title: [120904] trunk/Source
Revision
120904
Author
[email protected]
Date
2012-06-20 22:39:56 -0700 (Wed, 20 Jun 2012)

Log Message

[Chromium] Damage tracker is not used without partial swap, causing valid render passes to be removed
https://bugs.webkit.org/show_bug.cgi?id=89589

Patch by Zeev Lieber <[email protected]> on 2012-06-20
Reviewed by Adrienne Walker.

Source/WebCore:

When not using partial swap, the CCDamageTracker was not used, and
its m_currentDamageRect was always empty. As a result,
CCLayerTreeHostImpl was thinking no content was changed and was
removing more textures than needed. Fixed this by turning on
CCDamageTracker usage even if not using partial swap, but
overwriting the rootScissorRect with viewport rect if required.

Added unit tests to exercise this scenario.

* platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp:
(WebCore::CCLayerTreeHostImpl::calculateRenderSurfaceLayerList):

Source/WebKit/chromium:

Added unit tests to check surface texture caching when partial
swap is not used.

* tests/CCLayerTreeHostImplTest.cpp:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (120903 => 120904)


--- trunk/Source/WebCore/ChangeLog	2012-06-21 05:11:25 UTC (rev 120903)
+++ trunk/Source/WebCore/ChangeLog	2012-06-21 05:39:56 UTC (rev 120904)
@@ -1,3 +1,22 @@
+2012-06-20  Zeev Lieber  <[email protected]>
+
+        [Chromium] Damage tracker is not used without partial swap, causing valid render passes to be removed
+        https://bugs.webkit.org/show_bug.cgi?id=89589
+
+        Reviewed by Adrienne Walker.
+
+        When not using partial swap, the CCDamageTracker was not used, and
+        its m_currentDamageRect was always empty. As a result,
+        CCLayerTreeHostImpl was thinking no content was changed and was
+        removing more textures than needed. Fixed this by turning on
+        CCDamageTracker usage even if not using partial swap, but
+        overwriting the rootScissorRect with viewport rect if required.
+
+        Added unit tests to exercise this scenario.
+
+        * platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp:
+        (WebCore::CCLayerTreeHostImpl::calculateRenderSurfaceLayerList):
+
 2012-06-20  Yoshifumi Inoue  <[email protected]>
 
         [Forms] Make step action of SpinButtonElement replaceable

Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp (120903 => 120904)


--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp	2012-06-21 05:11:25 UTC (rev 120903)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp	2012-06-21 05:39:56 UTC (rev 120904)
@@ -255,11 +255,11 @@
         deviceScaleTransform.scale(m_deviceScaleFactor);
         CCLayerTreeHostCommon::calculateDrawTransforms(m_rootLayerImpl.get(), m_rootLayerImpl.get(), deviceScaleTransform, identityMatrix, renderSurfaceLayerList, m_rootLayerImpl->renderSurface()->layerList(), &m_layerSorter, layerRendererCapabilities().maxTextureSize);
 
-        if (layerRendererCapabilities().usingPartialSwap || settings().showSurfaceDamageRects)
-            trackDamageForAllSurfaces(m_rootLayerImpl.get(), renderSurfaceLayerList);
-        m_rootScissorRect = m_rootLayerImpl->renderSurface()->damageTracker()->currentDamageRect();
+        trackDamageForAllSurfaces(m_rootLayerImpl.get(), renderSurfaceLayerList);
 
-        if (!layerRendererCapabilities().usingPartialSwap)
+        if (layerRendererCapabilities().usingPartialSwap)
+            m_rootScissorRect = m_rootLayerImpl->renderSurface()->damageTracker()->currentDamageRect();
+        else
             m_rootScissorRect = FloatRect(FloatPoint(0, 0), deviceViewportSize());
 
         CCLayerTreeHostCommon::calculateVisibleAndScissorRects(renderSurfaceLayerList, m_rootScissorRect);

Modified: trunk/Source/WebKit/chromium/ChangeLog (120903 => 120904)


--- trunk/Source/WebKit/chromium/ChangeLog	2012-06-21 05:11:25 UTC (rev 120903)
+++ trunk/Source/WebKit/chromium/ChangeLog	2012-06-21 05:39:56 UTC (rev 120904)
@@ -1,3 +1,15 @@
+2012-06-20  Zeev Lieber  <[email protected]>
+
+        [Chromium] Damage tracker is not used without partial swap, causing valid render passes to be removed
+        https://bugs.webkit.org/show_bug.cgi?id=89589
+
+        Reviewed by Adrienne Walker.
+
+        Added unit tests to check surface texture caching when partial
+        swap is not used.
+
+        * tests/CCLayerTreeHostImplTest.cpp:
+
 2012-06-20  Sheriff Bot  <[email protected]>
 
         Unreviewed, rolling out r120889.

Modified: trunk/Source/WebKit/chromium/tests/CCLayerTreeHostImplTest.cpp (120903 => 120904)


--- trunk/Source/WebKit/chromium/tests/CCLayerTreeHostImplTest.cpp	2012-06-21 05:11:25 UTC (rev 120903)
+++ trunk/Source/WebKit/chromium/tests/CCLayerTreeHostImplTest.cpp	2012-06-21 05:39:56 UTC (rev 120904)
@@ -2410,20 +2410,15 @@
     Mock::VerifyAndClearExpectations(&mockContext);
 }
 
-TEST_F(CCLayerTreeHostImplTest, surfaceTextureCaching)
+static void setupLayersForTextureCaching(CCLayerTreeHostImpl* layerTreeHostImpl, CCLayerImpl*& rootPtr, CCLayerImpl*& intermediateLayerPtr, CCLayerImpl*& surfaceLayerPtr, CCLayerImpl*& childPtr)
 {
-    CCSettings::setPartialSwapEnabled(true);
-    
-    CCLayerTreeSettings settings;
-    OwnPtr<CCLayerTreeHostImpl> myHostImpl = CCLayerTreeHostImpl::create(settings, this);
-    
     RefPtr<CCGraphicsContext> context = CCGraphicsContext::create3D(GraphicsContext3DPrivate::createGraphicsContextFromWebContext(adoptPtr(new PartialSwapContext()), GraphicsContext3D::RenderDirectlyToHostWindow));
 
-    myHostImpl->initializeLayerRenderer(context.release(), UnthrottledUploader);
-    myHostImpl->setViewportSize(IntSize(100, 100));
+    layerTreeHostImpl->initializeLayerRenderer(context.release(), UnthrottledUploader);
+    layerTreeHostImpl->setViewportSize(IntSize(100, 100));
 
     OwnPtr<CCLayerImpl> root = CCLayerImpl::create(1);
-    CCLayerImpl* rootPtr = root.get();
+    rootPtr = root.get();
 
     root->setAnchorPoint(FloatPoint(0, 0));
     root->setPosition(FloatPoint(0, 0));
@@ -2431,11 +2426,11 @@
     root->setContentBounds(IntSize(100, 100));
     root->setVisibleLayerRect(IntRect(0, 0, 100, 100));
     root->setDrawsContent(true);
-    myHostImpl->setRootLayer(root.release());
+    layerTreeHostImpl->setRootLayer(root.release());
 
     // Intermediate layer does not own a surface, and does not draw content.
     OwnPtr<CCLayerImpl> intermediateLayer = CCLayerImpl::create(2);
-    CCLayerImpl* intermediateLayerPtr = intermediateLayer.get();
+    intermediateLayerPtr = intermediateLayer.get();
 
     intermediateLayerPtr->setAnchorPoint(FloatPoint(0, 0));
     intermediateLayerPtr->setPosition(FloatPoint(10, 10));
@@ -2446,7 +2441,7 @@
     rootPtr->addChild(intermediateLayer.release());
 
     OwnPtr<CCLayerImpl> surfaceLayer = CCLayerImpl::create(3);
-    CCLayerImpl* surfaceLayerPtr = surfaceLayer.get();
+    surfaceLayerPtr = surfaceLayer.get();
 
     // Surface layer is the layer that changes its opacity
     // It will contain other layers that draw content.
@@ -2461,7 +2456,7 @@
 
     // Child of the surface layer will produce some quads
     OwnPtr<FakeLayerWithQuads> child = FakeLayerWithQuads::create(4);
-    FakeLayerWithQuads* childPtr = child.get();
+    childPtr = child.get();
 
     childPtr->setAnchorPoint(FloatPoint(0, 0));
     childPtr->setPosition(FloatPoint(5, 5));
@@ -2471,7 +2466,22 @@
     childPtr->setDrawsContent(true);
 
     surfaceLayerPtr->addChild(child.release());
+}
 
+TEST_F(CCLayerTreeHostImplTest, surfaceTextureCaching)
+{
+    CCSettings::setPartialSwapEnabled(true);
+
+    CCLayerTreeSettings settings;
+    OwnPtr<CCLayerTreeHostImpl> myHostImpl = CCLayerTreeHostImpl::create(settings, this);
+
+    CCLayerImpl* rootPtr;
+    CCLayerImpl* intermediateLayerPtr;
+    CCLayerImpl* surfaceLayerPtr;
+    CCLayerImpl* childPtr;
+
+    setupLayersForTextureCaching(myHostImpl.get(), rootPtr, intermediateLayerPtr, surfaceLayerPtr, childPtr);
+
     {
         CCLayerTreeHostImpl::FrameData frame;
         EXPECT_TRUE(myHostImpl->prepareToDraw(frame));
@@ -2615,6 +2625,165 @@
     }
 }
 
+TEST_F(CCLayerTreeHostImplTest, surfaceTextureCachingNoPartialSwap)
+{
+    CCSettings::setPartialSwapEnabled(false);
+
+    CCLayerTreeSettings settings;
+    OwnPtr<CCLayerTreeHostImpl> myHostImpl = CCLayerTreeHostImpl::create(settings, this);
+
+    CCLayerImpl* rootPtr;
+    CCLayerImpl* intermediateLayerPtr;
+    CCLayerImpl* surfaceLayerPtr;
+    CCLayerImpl* childPtr;
+
+    setupLayersForTextureCaching(myHostImpl.get(), rootPtr, intermediateLayerPtr, surfaceLayerPtr, childPtr);
+
+    {
+        CCLayerTreeHostImpl::FrameData frame;
+        EXPECT_TRUE(myHostImpl->prepareToDraw(frame));
+
+        // Must receive two render passes, each with one quad
+        ASSERT_EQ(2U, frame.renderPasses.size());
+        EXPECT_EQ(1U, frame.renderPasses[0]->quadList().size());
+        EXPECT_EQ(1U, frame.renderPasses[1]->quadList().size());
+
+        EXPECT_EQ(CCDrawQuad::RenderPass, frame.renderPasses[1]->quadList()[0]->material());
+        CCRenderPassDrawQuad* quad = static_cast<CCRenderPassDrawQuad*>(frame.renderPasses[1]->quadList()[0].get());
+        EXPECT_TRUE(quad->renderPass()->targetSurface()->contentsChanged());
+
+        myHostImpl->drawLayers(frame);
+        myHostImpl->didDrawAllLayers(frame);
+    }
+
+    // Draw without any change
+    {
+        CCLayerTreeHostImpl::FrameData frame;
+        EXPECT_TRUE(myHostImpl->prepareToDraw(frame));
+
+        // Even though there was no change, we set the damage to entire viewport.
+        // One of the passes should be culled as a result, since contents didn't change
+        // and we have cached texture.
+        ASSERT_EQ(1U, frame.renderPasses.size());
+        EXPECT_EQ(1U, frame.renderPasses[0]->quadList().size());
+
+        myHostImpl->drawLayers(frame);
+        myHostImpl->didDrawAllLayers(frame);
+    }
+
+    // Change opacity and draw
+    surfaceLayerPtr->setOpacity(0.6f);
+    {
+        CCLayerTreeHostImpl::FrameData frame;
+        EXPECT_TRUE(myHostImpl->prepareToDraw(frame));
+
+        // Must receive one render pass, as the other one should be culled
+        ASSERT_EQ(1U, frame.renderPasses.size());
+
+        EXPECT_EQ(1U, frame.renderPasses[0]->quadList().size());
+        EXPECT_EQ(CCDrawQuad::RenderPass, frame.renderPasses[0]->quadList()[0]->material());
+        CCRenderPassDrawQuad* quad = static_cast<CCRenderPassDrawQuad*>(frame.renderPasses[0]->quadList()[0].get());
+        EXPECT_FALSE(quad->renderPass()->targetSurface()->contentsChanged());
+
+        myHostImpl->drawLayers(frame);
+        myHostImpl->didDrawAllLayers(frame);
+    }
+
+    // Change less benign property and draw - should have contents changed flag
+    surfaceLayerPtr->setStackingOrderChanged(true);
+    {
+        CCLayerTreeHostImpl::FrameData frame;
+        EXPECT_TRUE(myHostImpl->prepareToDraw(frame));
+
+        // Must receive two render passes, each with one quad
+        ASSERT_EQ(2U, frame.renderPasses.size());
+
+        EXPECT_EQ(1U, frame.renderPasses[0]->quadList().size());
+        EXPECT_EQ(CCDrawQuad::SolidColor, frame.renderPasses[0]->quadList()[0]->material());
+
+        EXPECT_EQ(CCDrawQuad::RenderPass, frame.renderPasses[1]->quadList()[0]->material());
+        CCRenderPassDrawQuad* quad = static_cast<CCRenderPassDrawQuad*>(frame.renderPasses[1]->quadList()[0].get());
+        EXPECT_TRUE(quad->renderPass()->targetSurface()->contentsChanged());
+
+        myHostImpl->drawLayers(frame);
+        myHostImpl->didDrawAllLayers(frame);
+    }
+
+    // Change opacity again, but evict the cached surface texture
+    surfaceLayerPtr->setOpacity(0.5f);
+    ManagedTexture* contentsTexture = surfaceLayerPtr->renderSurface()->contentsTexture();
+    ASSERT_TRUE(contentsTexture->isValid(contentsTexture->size(), contentsTexture->format()));
+    CCRenderer* renderer = myHostImpl->layerRenderer();
+    TextureManager* textureManager = renderer->implTextureManager();
+    size_t maxMemoryLimit = textureManager->maxMemoryLimitBytes();
+
+    // This should evice all cached surfaces
+    textureManager->setMaxMemoryLimitBytes(0);
+
+    // Restore original limit
+    textureManager->setMaxMemoryLimitBytes(maxMemoryLimit);
+
+    // Was our surface evicted?
+    ASSERT_FALSE(contentsTexture->isValid(contentsTexture->size(), contentsTexture->format()));
+
+    // Change opacity and draw
+    surfaceLayerPtr->setOpacity(0.6f);
+    {
+        CCLayerTreeHostImpl::FrameData frame;
+        EXPECT_TRUE(myHostImpl->prepareToDraw(frame));
+
+        // Must receive two render passes
+        ASSERT_EQ(2U, frame.renderPasses.size());
+
+        // Even though not enough properties changed, the entire thing must be
+        // redrawn as we don't have cached textures
+        EXPECT_EQ(1U, frame.renderPasses[0]->quadList().size());
+        EXPECT_EQ(1U, frame.renderPasses[1]->quadList().size());
+
+        EXPECT_EQ(CCDrawQuad::RenderPass, frame.renderPasses[1]->quadList()[0]->material());
+        CCRenderPassDrawQuad* quad = static_cast<CCRenderPassDrawQuad*>(frame.renderPasses[1]->quadList()[0].get());
+        EXPECT_FALSE(quad->renderPass()->targetSurface()->contentsChanged());
+
+        myHostImpl->drawLayers(frame);
+        myHostImpl->didDrawAllLayers(frame);
+    }
+
+    // Draw without any change, to make sure the state is clear
+    {
+        CCLayerTreeHostImpl::FrameData frame;
+        EXPECT_TRUE(myHostImpl->prepareToDraw(frame));
+
+        // Even though there was no change, we set the damage to entire viewport.
+        // One of the passes should be culled as a result, since contents didn't change
+        // and we have cached texture.
+        ASSERT_EQ(1U, frame.renderPasses.size());
+        EXPECT_EQ(1U, frame.renderPasses[0]->quadList().size());
+
+        myHostImpl->drawLayers(frame);
+        myHostImpl->didDrawAllLayers(frame);
+    }
+
+    // Change opacity on the intermediate layer
+    WebTransformationMatrix transform = intermediateLayerPtr->transform();
+    transform.setM11(1.0001);
+    intermediateLayerPtr->setTransform(transform);
+    {
+        CCLayerTreeHostImpl::FrameData frame;
+        EXPECT_TRUE(myHostImpl->prepareToDraw(frame));
+
+        // Must receive one render pass, as the other one should be culled.
+        ASSERT_EQ(1U, frame.renderPasses.size());
+        EXPECT_EQ(1U, frame.renderPasses[0]->quadList().size());
+
+        EXPECT_EQ(CCDrawQuad::RenderPass, frame.renderPasses[0]->quadList()[0]->material());
+        CCRenderPassDrawQuad* quad = static_cast<CCRenderPassDrawQuad*>(frame.renderPasses[0]->quadList()[0].get());
+        EXPECT_FALSE(quad->renderPass()->targetSurface()->contentsChanged());
+
+        myHostImpl->drawLayers(frame);
+        myHostImpl->didDrawAllLayers(frame);
+    }
+}
+
 struct RenderPassCacheEntry {
     mutable OwnPtr<CCRenderPass> renderPassPtr;
     CCRenderPass* renderPass;
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to