- Revision
- 119867
- Author
- [email protected]
- Date
- 2012-06-08 14:37:33 -0700 (Fri, 08 Jun 2012)
Log Message
[chromium] Skip willDraw() and didDraw() on fully occluded layers
https://bugs.webkit.org/show_bug.cgi?id=88435
Reviewed by Adrienne Walker.
Source/WebCore:
Current willDraw() is called on all layers with non-empty
visibleLayerRect and non-empty scissorRect. This excludes
layers outside the viewport, but does not exclude occluded
layers. We add a check for occlusion to calculateRenderPasses
in order to avoid willDraw() when it will be culled anyway.
We prevent didDraw() from being called for occluded layers, for
which we did not call didDraw() by holding a vector of layers
for which we did call willDraw(). This lets us avoid storing a
flag on the layers, or computing occlusion again in
didDrawAllLayers.
Unit test: CCLayerTreeHostImplTest.willDrawNotCalledOnOccludedLayer
* platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp:
(WebCore::CCLayerTreeHostImpl::calculateRenderPasses):
(WebCore::CCLayerTreeHostImpl::prepareToDraw):
(WebCore::CCLayerTreeHostImpl::didDrawAllLayers):
* platform/graphics/chromium/cc/CCLayerTreeHostImpl.h:
(FrameData):
(CCLayerTreeHostImpl):
Source/WebKit/chromium:
* tests/CCLayerTreeHostImplTest.cpp:
Modified Paths
Diff
Modified: trunk/Source/WebCore/ChangeLog (119866 => 119867)
--- trunk/Source/WebCore/ChangeLog 2012-06-08 21:37:01 UTC (rev 119866)
+++ trunk/Source/WebCore/ChangeLog 2012-06-08 21:37:33 UTC (rev 119867)
@@ -1,3 +1,32 @@
+2012-06-08 Dana Jansens <[email protected]>
+
+ [chromium] Skip willDraw() and didDraw() on fully occluded layers
+ https://bugs.webkit.org/show_bug.cgi?id=88435
+
+ Reviewed by Adrienne Walker.
+
+ Current willDraw() is called on all layers with non-empty
+ visibleLayerRect and non-empty scissorRect. This excludes
+ layers outside the viewport, but does not exclude occluded
+ layers. We add a check for occlusion to calculateRenderPasses
+ in order to avoid willDraw() when it will be culled anyway.
+
+ We prevent didDraw() from being called for occluded layers, for
+ which we did not call didDraw() by holding a vector of layers
+ for which we did call willDraw(). This lets us avoid storing a
+ flag on the layers, or computing occlusion again in
+ didDrawAllLayers.
+
+ Unit test: CCLayerTreeHostImplTest.willDrawNotCalledOnOccludedLayer
+
+ * platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp:
+ (WebCore::CCLayerTreeHostImpl::calculateRenderPasses):
+ (WebCore::CCLayerTreeHostImpl::prepareToDraw):
+ (WebCore::CCLayerTreeHostImpl::didDrawAllLayers):
+ * platform/graphics/chromium/cc/CCLayerTreeHostImpl.h:
+ (FrameData):
+ (CCLayerTreeHostImpl):
+
2012-06-08 Antonio Gomes <[email protected]>
EventHandler shouldn't schedule the fake mousemove event timer when scrolling on devices that don't have a mouse
Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp (119866 => 119867)
--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp 2012-06-08 21:37:01 UTC (rev 119866)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp 2012-06-08 21:37:33 UTC (rev 119867)
@@ -261,13 +261,8 @@
}
}
-static inline bool shouldDrawLayer(CCLayerImpl* layer)
+bool CCLayerTreeHostImpl::calculateRenderPasses(CCRenderPassList& passes, CCLayerList& renderSurfaceLayerList, CCLayerList& willDrawLayers)
{
- return !layer->visibleLayerRect().isEmpty() && !layer->scissorRect().isEmpty();
-}
-
-bool CCLayerTreeHostImpl::calculateRenderPasses(CCRenderPassList& passes, CCLayerList& renderSurfaceLayerList)
-{
ASSERT(passes.isEmpty());
calculateRenderSurfaceLayerList(renderSurfaceLayerList);
@@ -310,8 +305,10 @@
if (it.representsContributingRenderSurface() && !it->renderSurface()->scissorRect().isEmpty()) {
CCRenderPass* contributingRenderPass = surfacePassMap.get(it->renderSurface());
pass->appendQuadsForRenderSurfaceLayer(*it, contributingRenderPass, &occlusionTracker);
- } else if (it.representsItself() && shouldDrawLayer(*it)) {
+ } else if (it.representsItself() && !occlusionTracker.occluded(*it, it->visibleLayerRect()) && !it->visibleLayerRect().isEmpty() && !it->scissorRect().isEmpty()) {
it->willDraw(m_layerRenderer.get(), context());
+ willDrawLayers.append(*it);
+
pass->appendQuadsForLayer(*it, &occlusionTracker, hadMissingTiles);
}
@@ -384,8 +381,9 @@
frame.renderPasses.clear();
frame.renderSurfaceLayerList.clear();
+ frame.willDrawLayers.clear();
- if (!calculateRenderPasses(frame.renderPasses, frame.renderSurfaceLayerList))
+ if (!calculateRenderPasses(frame.renderPasses, frame.renderSurfaceLayerList, frame.willDrawLayers))
return false;
// If we return true, then we expect drawLayers() to be called before this function is called again.
@@ -436,13 +434,8 @@
void CCLayerTreeHostImpl::didDrawAllLayers(const FrameData& frame)
{
- typedef CCLayerIterator<CCLayerImpl, Vector<CCLayerImpl*>, CCRenderSurface, CCLayerIteratorActions::BackToFront> CCLayerIteratorType;
-
- CCLayerIteratorType end = CCLayerIteratorType::end(&frame.renderSurfaceLayerList);
- for (CCLayerIteratorType it = CCLayerIteratorType::begin(&frame.renderSurfaceLayerList); it != end; ++it) {
- if (it.representsItself() && shouldDrawLayer(*it))
- it->didDraw();
- }
+ for (size_t i = 0; i < frame.willDrawLayers.size(); ++i)
+ frame.willDrawLayers[i]->didDraw();
}
void CCLayerTreeHostImpl::finishAllRendering()
Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.h (119866 => 119867)
--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.h 2012-06-08 21:37:01 UTC (rev 119866)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.h 2012-06-08 21:37:33 UTC (rev 119867)
@@ -87,6 +87,7 @@
struct FrameData {
CCRenderPassList renderPasses;
CCLayerList renderSurfaceLayerList;
+ CCLayerList willDrawLayers;
};
// Virtual for testing.
@@ -200,7 +201,7 @@
// Returns false if the frame should not be displayed. This function should
// only be called from prepareToDraw, as didDrawAllLayers must be called
// if this helper function is called.
- bool calculateRenderPasses(CCRenderPassList&, CCLayerList& renderSurfaceLayerList);
+ bool calculateRenderPasses(CCRenderPassList&, CCLayerList& renderSurfaceLayerList, CCLayerList& willDrawLayers);
void animateLayersRecursive(CCLayerImpl*, double monotonicTime, double wallClockTime, CCAnimationEventsVector*, bool& didAnimate, bool& needsAnimateLayers);
void setBackgroundTickingEnabled(bool);
IntSize contentSize() const;
Modified: trunk/Source/WebKit/chromium/ChangeLog (119866 => 119867)
--- trunk/Source/WebKit/chromium/ChangeLog 2012-06-08 21:37:01 UTC (rev 119866)
+++ trunk/Source/WebKit/chromium/ChangeLog 2012-06-08 21:37:33 UTC (rev 119867)
@@ -1,3 +1,12 @@
+2012-06-08 Dana Jansens <[email protected]>
+
+ [chromium] Skip willDraw() and didDraw() on fully occluded layers
+ https://bugs.webkit.org/show_bug.cgi?id=88435
+
+ Reviewed by Adrienne Walker.
+
+ * tests/CCLayerTreeHostImplTest.cpp:
+
2012-06-08 James Robinson <[email protected]>
[chromium] Clean up some unnecessary LayerChromium.h includes
Modified: trunk/Source/WebKit/chromium/tests/CCLayerTreeHostImplTest.cpp (119866 => 119867)
--- trunk/Source/WebKit/chromium/tests/CCLayerTreeHostImplTest.cpp 2012-06-08 21:37:01 UTC (rev 119866)
+++ trunk/Source/WebKit/chromium/tests/CCLayerTreeHostImplTest.cpp 2012-06-08 21:37:33 UTC (rev 119867)
@@ -468,7 +468,12 @@
{
setAnchorPoint(FloatPoint(0, 0));
setBounds(IntSize(10, 10));
+ setContentBounds(IntSize(10, 10));
setDrawsContent(true);
+ setSkipsDraw(false);
+
+ OwnPtr<CCLayerTilingData> tiler = CCLayerTilingData::create(IntSize(100, 100), CCLayerTilingData::HasBorderTexels);
+ setTilingData(*tiler.get());
}
private:
@@ -521,6 +526,42 @@
EXPECT_FALSE(layer->visibleLayerRect().isEmpty());
}
+TEST_F(CCLayerTreeHostImplTest, willDrawNotCalledOnOccludedLayer)
+{
+ // Make the viewport large so that we can have large layers that get considered for occlusion (small layers do not).
+ IntSize bigSize(1000, 1000);
+ m_hostImpl->setViewportSize(bigSize);
+
+ m_hostImpl->setRootLayer(DidDrawCheckLayer::create(0));
+ DidDrawCheckLayer* root = static_cast<DidDrawCheckLayer*>(m_hostImpl->rootLayer());
+
+ root->addChild(DidDrawCheckLayer::create(1));
+ DidDrawCheckLayer* occludedLayer = static_cast<DidDrawCheckLayer*>(root->children()[0].get());
+
+ root->addChild(DidDrawCheckLayer::create(2));
+ DidDrawCheckLayer* topLayer = static_cast<DidDrawCheckLayer*>(root->children()[1].get());
+ // This layer covers the occludedLayer above. Make this layer large so it can occlude.
+ topLayer->setBounds(bigSize);
+ topLayer->setContentBounds(bigSize);
+ topLayer->setOpaque(true);
+
+ CCLayerTreeHostImpl::FrameData frame;
+
+ EXPECT_FALSE(occludedLayer->willDrawCalled());
+ EXPECT_FALSE(occludedLayer->didDrawCalled());
+ EXPECT_FALSE(topLayer->willDrawCalled());
+ EXPECT_FALSE(topLayer->didDrawCalled());
+
+ EXPECT_TRUE(m_hostImpl->prepareToDraw(frame));
+ m_hostImpl->drawLayers(frame);
+ m_hostImpl->didDrawAllLayers(frame);
+
+ EXPECT_FALSE(occludedLayer->willDrawCalled());
+ EXPECT_FALSE(occludedLayer->didDrawCalled());
+ EXPECT_TRUE(topLayer->willDrawCalled());
+ EXPECT_TRUE(topLayer->didDrawCalled());
+}
+
TEST_F(CCLayerTreeHostImplTest, didDrawCalledOnAllLayers)
{
m_hostImpl->setRootLayer(DidDrawCheckLayer::create(0));