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