diff options
author | danakj@chromium.org <danakj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-12-17 03:53:19 +0000 |
---|---|---|
committer | danakj@chromium.org <danakj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-12-17 03:53:19 +0000 |
commit | ccb1c9ae33f51bd314608e34c94466e08e586c37 (patch) | |
tree | 3abe151c81534dfcd4175c49b93c8546b544a6a6 /cc | |
parent | 3cb0a0ebfe3beab46c09f0522166959acf2b86eb (diff) | |
download | chromium_src-ccb1c9ae33f51bd314608e34c94466e08e586c37.zip chromium_src-ccb1c9ae33f51bd314608e34c94466e08e586c37.tar.gz chromium_src-ccb1c9ae33f51bd314608e34c94466e08e586c37.tar.bz2 |
cc: Make occlusion tracker always work in target space.
On desktop this improves LayerTreeHostPerfTestJsonReader.tenTenSingleThread from ~3702.97 runs/s to ~3786.95 runs/s for about 2%. On a phone we observed about 20% reduction in calcRenderPasses in tracing.
Covered by the occlusion tracker tests as well as LayerTreeHost and TiledLayer tests with occlusion.
BUG=163035
NOTRY=true
Review URL: https://chromiumcodereview.appspot.com/11583005
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@173411 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cc')
-rw-r--r-- | cc/layer_tree_host_impl_unittest.cc | 97 | ||||
-rw-r--r-- | cc/layer_tree_host_unittest.cc | 147 | ||||
-rw-r--r-- | cc/occlusion_tracker.cc | 505 | ||||
-rw-r--r-- | cc/occlusion_tracker.h | 13 | ||||
-rw-r--r-- | cc/occlusion_tracker_unittest.cc | 357 | ||||
-rw-r--r-- | cc/test/occlusion_tracker_test_common.h | 8 | ||||
-rw-r--r-- | cc/tiled_layer_unittest.cc | 235 |
7 files changed, 670 insertions, 692 deletions
diff --git a/cc/layer_tree_host_impl_unittest.cc b/cc/layer_tree_host_impl_unittest.cc index 0832426..d439760 100644 --- a/cc/layer_tree_host_impl_unittest.cc +++ b/cc/layer_tree_host_impl_unittest.cc @@ -3140,103 +3140,6 @@ public: using GLRenderer::releaseRenderPassTextures; }; -TEST_P(LayerTreeHostImplTest, textureCachingWithClipping) -{ - LayerTreeSettings settings; - settings.minimumOcclusionTrackingSize = gfx::Size(); - settings.partialSwapEnabled = true; - scoped_ptr<LayerTreeHostImpl> myHostImpl = LayerTreeHostImpl::create(settings, this, &m_proxy); - - LayerImpl* rootPtr; - LayerImpl* surfaceLayerPtr; - - scoped_ptr<OutputSurface> outputSurface = FakeOutputSurface::Create3d(scoped_ptr<WebKit::WebGraphicsContext3D>(new PartialSwapContext)).PassAs<OutputSurface>(); - - gfx::Size rootSize(100, 100); - - myHostImpl->initializeRenderer(outputSurface.Pass()); - myHostImpl->setViewportSize(gfx::Size(rootSize.width(), rootSize.height()), gfx::Size(rootSize.width(), rootSize.height())); - - scoped_ptr<LayerImpl> root = LayerImpl::create(myHostImpl->activeTree(), 1); - rootPtr = root.get(); - - root->setAnchorPoint(gfx::PointF(0, 0)); - root->setPosition(gfx::PointF(0, 0)); - root->setBounds(rootSize); - root->setContentBounds(rootSize); - root->setDrawsContent(true); - root->setMasksToBounds(true); - myHostImpl->setRootLayer(root.Pass()); - - addDrawingLayerTo(rootPtr, 3, gfx::Rect(0, 0, rootSize.width(), rootSize.height()), &surfaceLayerPtr); - surfaceLayerPtr->setDrawsContent(false); - - // Surface layer is the layer that changes its opacity - // It will contain other layers that draw content. - surfaceLayerPtr->setOpacity(0.5f); - surfaceLayerPtr->setForceRenderSurface(true); // This will cause it to have a surface - - addDrawingLayerTo(surfaceLayerPtr, 4, gfx::Rect(0, 0, 100, 3), 0); - addDrawingLayerTo(surfaceLayerPtr, 5, gfx::Rect(0, 97, 100, 3), 0); - - // Rotation will put part of the child ouside the bounds of the root layer. - // Nevertheless, the child layers should be drawn. - gfx::Transform transform = surfaceLayerPtr->transform(); - transform.Translate(50, 50); - transform.Rotate(35); - transform.Translate(-50, -50); - surfaceLayerPtr->setTransform(transform); - - { - LayerTreeHostImpl::FrameData frame; - EXPECT_TRUE(myHostImpl->prepareToDraw(frame)); - - // Must receive two render passes, each with one quad - ASSERT_EQ(2U, frame.renderPasses.size()); - EXPECT_EQ(2U, frame.renderPasses[0]->quad_list.size()); - ASSERT_EQ(1U, frame.renderPasses[1]->quad_list.size()); - - // Verify that the child layers are being clipped. - gfx::Rect quadVisibleRect = frame.renderPasses[0]->quad_list[0]->visible_rect; - EXPECT_LT(quadVisibleRect.width(), 100); - - quadVisibleRect = frame.renderPasses[0]->quad_list[1]->visible_rect; - EXPECT_LT(quadVisibleRect.width(), 100); - - // Verify that the render surface texture is *not* clipped. - EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100), frame.renderPasses[0]->output_rect); - - EXPECT_EQ(DrawQuad::RENDER_PASS, frame.renderPasses[1]->quad_list[0]->material); - const RenderPassDrawQuad* quad = RenderPassDrawQuad::MaterialCast(frame.renderPasses[1]->quad_list[0]); - EXPECT_FALSE(quad->contents_changed_since_last_frame.IsEmpty()); - - myHostImpl->drawLayers(frame); - myHostImpl->didDrawAllLayers(frame); - } - - transform = surfaceLayerPtr->transform(); - transform.Translate(50, 50); - transform.Rotate(-35); - transform.Translate(-50, -50); - surfaceLayerPtr->setTransform(transform); - - // The surface is now aligned again, and the clipped parts are exposed. - // Since the layers were clipped, even though the render surface size - // was not changed, the texture should not be saved. - { - LayerTreeHostImpl::FrameData frame; - EXPECT_TRUE(myHostImpl->prepareToDraw(frame)); - - // Must receive two render passes, each with one quad - ASSERT_EQ(2U, frame.renderPasses.size()); - EXPECT_EQ(2U, frame.renderPasses[0]->quad_list.size()); - ASSERT_EQ(1U, frame.renderPasses[1]->quad_list.size()); - - myHostImpl->drawLayers(frame); - myHostImpl->didDrawAllLayers(frame); - } -} - TEST_P(LayerTreeHostImplTest, textureCachingWithOcclusion) { LayerTreeSettings settings; diff --git a/cc/layer_tree_host_unittest.cc b/cc/layer_tree_host_unittest.cc index a5d9f4d..b8d79d9 100644 --- a/cc/layer_tree_host_unittest.cc +++ b/cc/layer_tree_host_unittest.cc @@ -1643,25 +1643,29 @@ public: { // Gain access to internals of the OcclusionTracker. const TestOcclusionTracker* testOcclusion = static_cast<const TestOcclusionTracker*>(occlusion); - m_occludedScreenSpace = testOcclusion ? testOcclusion->occlusionInScreenSpace() : Region(); + if (!testOcclusion) { + m_occlusion.Clear(); + return; + } + m_occlusion = UnionRegions(testOcclusion->occlusionFromInsideTarget(), testOcclusion->occlusionFromOutsideTarget()); } virtual bool drawsContent() const OVERRIDE { return true; } - const Region& occludedScreenSpace() const { return m_occludedScreenSpace; } - void clearOccludedScreenSpace() { m_occludedScreenSpace.Clear(); } + const Region& occlusion() const { return m_occlusion; } + void clearOcclusion() { m_occlusion.Clear(); } private: TestLayer() : Layer() { } virtual ~TestLayer() { } - Region m_occludedScreenSpace; + Region m_occlusion; }; static void setTestLayerPropertiesForTesting(TestLayer* layer, Layer* parent, const gfx::Transform& transform, const gfx::PointF& anchor, const gfx::PointF& position, const gfx::Size& bounds, bool opaque) { setLayerPropertiesForTesting(layer, parent, transform, anchor, position, bounds, opaque); - layer->clearOccludedScreenSpace(); + layer->clearOcclusion(); } class LayerTreeHostTestLayerOcclusion : public LayerTreeHostTest { @@ -1677,20 +1681,17 @@ public: scoped_refptr<TestLayer> mask = TestLayer::create(); gfx::Transform identityMatrix; - gfx::Transform childTransform; - childTransform.Translate(250, 250); - childTransform.Rotate(90); - childTransform.Translate(-250, -250); child->setMasksToBounds(true); + child->setForceRenderSurface(true); // See LayerTreeHostCommonTest.layerAddsSelfToOccludedRegionWithRotatedSurface for a nice visual of these layers and how they end up // positioned on the screen. - // The child layer is rotated and the grandChild is opaque, but clipped to the child and rootLayer + // The child layer is a surface and the grandChild is opaque, but clipped to the child and rootLayer setTestLayerPropertiesForTesting(rootLayer.get(), 0, identityMatrix, gfx::PointF(0, 0), gfx::PointF(0, 0), gfx::Size(200, 200), true); - setTestLayerPropertiesForTesting(child.get(), rootLayer.get(), childTransform, gfx::PointF(0, 0), gfx::PointF(30, 30), gfx::Size(500, 500), false); - setTestLayerPropertiesForTesting(grandChild.get(), child.get(), identityMatrix, gfx::PointF(0, 0), gfx::PointF(10, 10), gfx::Size(500, 500), true); + setTestLayerPropertiesForTesting(child.get(), rootLayer.get(), identityMatrix, gfx::PointF(0, 0), gfx::PointF(10, 10), gfx::Size(500, 500), false); + setTestLayerPropertiesForTesting(grandChild.get(), child.get(), identityMatrix, gfx::PointF(0, 0), gfx::PointF(-10, -10), gfx::Size(20, 500), true); m_layerTreeHost->setRootLayer(rootLayer); m_layerTreeHost->setViewportSize(rootLayer->bounds(), rootLayer->bounds()); @@ -1699,61 +1700,45 @@ public: m_layerTreeHost->updateLayers(queue, std::numeric_limits<size_t>::max()); m_layerTreeHost->commitComplete(); - EXPECT_EQ(gfx::Rect().ToString(), grandChild->occludedScreenSpace().ToString()); - EXPECT_EQ(gfx::Rect(30, 40, 170, 160).ToString(), child->occludedScreenSpace().ToString()); - EXPECT_EQ(gfx::Rect(30, 40, 170, 160).ToString(), rootLayer->occludedScreenSpace().ToString()); + EXPECT_EQ(gfx::Rect().ToString(), grandChild->occlusion().ToString()); + EXPECT_EQ(gfx::Rect(0, 0, 10, 190).ToString(), child->occlusion().ToString()); + EXPECT_EQ(gfx::Rect(10, 10, 10, 190).ToString(), rootLayer->occlusion().ToString()); // If the child layer is opaque, then it adds to the occlusion seen by the rootLayer. setLayerPropertiesForTesting(rootLayer.get(), 0, identityMatrix, gfx::PointF(0, 0), gfx::PointF(0, 0), gfx::Size(200, 200), true); - setLayerPropertiesForTesting(child.get(), rootLayer.get(), childTransform, gfx::PointF(0, 0), gfx::PointF(30, 30), gfx::Size(500, 500), true); - setLayerPropertiesForTesting(grandChild.get(), child.get(), identityMatrix, gfx::PointF(0, 0), gfx::PointF(10, 10), gfx::Size(500, 500), true); + setLayerPropertiesForTesting(child.get(), rootLayer.get(), identityMatrix, gfx::PointF(0, 0), gfx::PointF(10, 10), gfx::Size(500, 500), true); + setLayerPropertiesForTesting(grandChild.get(), child.get(), identityMatrix, gfx::PointF(0, 0), gfx::PointF(-10, -10), gfx::Size(20, 500), true); m_layerTreeHost->setRootLayer(rootLayer); m_layerTreeHost->setViewportSize(rootLayer->bounds(), rootLayer->bounds()); m_layerTreeHost->updateLayers(queue, std::numeric_limits<size_t>::max()); m_layerTreeHost->commitComplete(); - EXPECT_EQ(gfx::Rect().ToString(), grandChild->occludedScreenSpace().ToString()); - EXPECT_EQ(gfx::Rect(30, 40, 170, 160).ToString(), child->occludedScreenSpace().ToString()); - EXPECT_EQ(gfx::Rect(30, 30, 170, 170).ToString(), rootLayer->occludedScreenSpace().ToString()); + EXPECT_EQ(gfx::Rect().ToString(), grandChild->occlusion().ToString()); + EXPECT_EQ(gfx::Rect(0, 0, 10, 190).ToString(), child->occlusion().ToString()); + EXPECT_EQ(gfx::Rect(10, 10, 190, 190).ToString(), rootLayer->occlusion().ToString()); // Add a second child to the root layer and the regions should merge setTestLayerPropertiesForTesting(rootLayer.get(), 0, identityMatrix, gfx::PointF(0, 0), gfx::PointF(0, 0), gfx::Size(200, 200), true); - setTestLayerPropertiesForTesting(child2.get(), rootLayer.get(), identityMatrix, gfx::PointF(0, 0), gfx::PointF(70, 20), gfx::Size(500, 500), true); - setTestLayerPropertiesForTesting(child.get(), rootLayer.get(), childTransform, gfx::PointF(0, 0), gfx::PointF(30, 30), gfx::Size(500, 500), true); - setTestLayerPropertiesForTesting(grandChild.get(), child.get(), identityMatrix, gfx::PointF(0, 0), gfx::PointF(10, 10), gfx::Size(500, 500), true); - - m_layerTreeHost->setRootLayer(rootLayer); - m_layerTreeHost->setViewportSize(rootLayer->bounds(), rootLayer->bounds()); - m_layerTreeHost->updateLayers(queue, std::numeric_limits<size_t>::max()); - m_layerTreeHost->commitComplete(); - - EXPECT_EQ(gfx::Rect().ToString(), grandChild->occludedScreenSpace().ToString()); - EXPECT_EQ(gfx::Rect(30, 40, 170, 160).ToString(), child->occludedScreenSpace().ToString()); - EXPECT_EQ(gfx::Rect(30, 30, 170, 170).ToString(), child2->occludedScreenSpace().ToString()); - EXPECT_EQ(UnionRegions(gfx::Rect(30, 30, 170, 170), gfx::Rect(70, 20, 130, 180)).ToString(), rootLayer->occludedScreenSpace().ToString()); - - // Move the second child to be sure. - setTestLayerPropertiesForTesting(rootLayer.get(), 0, identityMatrix, gfx::PointF(0, 0), gfx::PointF(0, 0), gfx::Size(200, 200), true); - setTestLayerPropertiesForTesting(child2.get(), rootLayer.get(), identityMatrix, gfx::PointF(0, 0), gfx::PointF(10, 70), gfx::Size(500, 500), true); - setTestLayerPropertiesForTesting(child.get(), rootLayer.get(), childTransform, gfx::PointF(0, 0), gfx::PointF(30, 30), gfx::Size(500, 500), true); - setTestLayerPropertiesForTesting(grandChild.get(), child.get(), identityMatrix, gfx::PointF(0, 0), gfx::PointF(10, 10), gfx::Size(500, 500), true); + setTestLayerPropertiesForTesting(child.get(), rootLayer.get(), identityMatrix, gfx::PointF(0, 0), gfx::PointF(10, 10), gfx::Size(500, 500), false); + setTestLayerPropertiesForTesting(grandChild.get(), child.get(), identityMatrix, gfx::PointF(0, 0), gfx::PointF(-10, -10), gfx::Size(20, 500), true); + setTestLayerPropertiesForTesting(child2.get(), rootLayer.get(), identityMatrix, gfx::PointF(0, 0), gfx::PointF(20, 10), gfx::Size(10, 500), true); m_layerTreeHost->setRootLayer(rootLayer); m_layerTreeHost->setViewportSize(rootLayer->bounds(), rootLayer->bounds()); m_layerTreeHost->updateLayers(queue, std::numeric_limits<size_t>::max()); m_layerTreeHost->commitComplete(); - EXPECT_EQ(gfx::Rect().ToString(), grandChild->occludedScreenSpace().ToString()); - EXPECT_EQ(gfx::Rect(30, 40, 170, 160).ToString(), child->occludedScreenSpace().ToString()); - EXPECT_EQ(gfx::Rect(30, 30, 170, 170).ToString(), child2->occludedScreenSpace().ToString()); - EXPECT_EQ(UnionRegions(gfx::Rect(10, 70, 190, 130), gfx::Rect(30, 30, 170, 170)).ToString(), rootLayer->occludedScreenSpace().ToString()); + EXPECT_EQ(gfx::Rect().ToString(), child2->occlusion().ToString()); + EXPECT_EQ(gfx::Rect(10, 0, 10, 190).ToString(), grandChild->occlusion().ToString()); + EXPECT_EQ(gfx::Rect(0, 0, 20, 190).ToString(), child->occlusion().ToString()); + EXPECT_EQ(gfx::Rect(10, 10, 20, 190).ToString(), rootLayer->occlusion().ToString()); // If the child layer has a mask on it, then it shouldn't contribute to occlusion on stuff below it setLayerPropertiesForTesting(rootLayer.get(), 0, identityMatrix, gfx::PointF(0, 0), gfx::PointF(0, 0), gfx::Size(200, 200), true); - setLayerPropertiesForTesting(child2.get(), rootLayer.get(), identityMatrix, gfx::PointF(0, 0), gfx::PointF(10, 70), gfx::Size(500, 500), true); - setLayerPropertiesForTesting(child.get(), rootLayer.get(), childTransform, gfx::PointF(0, 0), gfx::PointF(30, 30), gfx::Size(500, 500), true); - setLayerPropertiesForTesting(grandChild.get(), child.get(), identityMatrix, gfx::PointF(0, 0), gfx::PointF(10, 10), gfx::Size(500, 500), true); + setLayerPropertiesForTesting(child2.get(), rootLayer.get(), identityMatrix, gfx::PointF(0, 0), gfx::PointF(10, 10), gfx::Size(500, 500), true); + setLayerPropertiesForTesting(child.get(), rootLayer.get(), identityMatrix, gfx::PointF(0, 0), gfx::PointF(20, 20), gfx::Size(500, 500), true); + setLayerPropertiesForTesting(grandChild.get(), child.get(), identityMatrix, gfx::PointF(0, 0), gfx::PointF(-10, -10), gfx::Size(500, 500), true); child->setMaskLayer(mask.get()); @@ -1762,16 +1747,16 @@ public: m_layerTreeHost->updateLayers(queue, std::numeric_limits<size_t>::max()); m_layerTreeHost->commitComplete(); - EXPECT_EQ(gfx::Rect().ToString(), grandChild->occludedScreenSpace().ToString()); - EXPECT_EQ(gfx::Rect(30, 40, 170, 160).ToString(), child->occludedScreenSpace().ToString()); - EXPECT_EQ(gfx::Rect().ToString(), child2->occludedScreenSpace().ToString()); - EXPECT_EQ(gfx::Rect(10, 70, 190, 130).ToString(), rootLayer->occludedScreenSpace().ToString()); + EXPECT_EQ(gfx::Rect().ToString(), grandChild->occlusion().ToString()); + EXPECT_EQ(gfx::Rect(0, 0, 180, 180).ToString(), child->occlusion().ToString()); + EXPECT_EQ(gfx::Rect().ToString(), child2->occlusion().ToString()); + EXPECT_EQ(gfx::Rect(10, 10, 190, 190).ToString(), rootLayer->occlusion().ToString()); // If the child layer with a mask is below child2, then child2 should contribute to occlusion on everything, and child shouldn't contribute to the rootLayer setLayerPropertiesForTesting(rootLayer.get(), 0, identityMatrix, gfx::PointF(0, 0), gfx::PointF(0, 0), gfx::Size(200, 200), true); - setLayerPropertiesForTesting(child.get(), rootLayer.get(), childTransform, gfx::PointF(0, 0), gfx::PointF(30, 30), gfx::Size(500, 500), true); - setLayerPropertiesForTesting(grandChild.get(), child.get(), identityMatrix, gfx::PointF(0, 0), gfx::PointF(10, 10), gfx::Size(500, 500), true); - setLayerPropertiesForTesting(child2.get(), rootLayer.get(), identityMatrix, gfx::PointF(0, 0), gfx::PointF(10, 70), gfx::Size(500, 500), true); + setLayerPropertiesForTesting(child.get(), rootLayer.get(), identityMatrix, gfx::PointF(0, 0), gfx::PointF(10, 10), gfx::Size(500, 500), true); + setLayerPropertiesForTesting(grandChild.get(), child.get(), identityMatrix, gfx::PointF(0, 0), gfx::PointF(-10, -10), gfx::Size(20, 500), true); + setLayerPropertiesForTesting(child2.get(), rootLayer.get(), identityMatrix, gfx::PointF(0, 0), gfx::PointF(20, 10), gfx::Size(10, 500), true); child->setMaskLayer(mask.get()); @@ -1780,16 +1765,16 @@ public: m_layerTreeHost->updateLayers(queue, std::numeric_limits<size_t>::max()); m_layerTreeHost->commitComplete(); - EXPECT_EQ(gfx::Rect().ToString(), child2->occludedScreenSpace().ToString()); - EXPECT_EQ(gfx::Rect(10, 70, 190, 130).ToString(), grandChild->occludedScreenSpace().ToString()); - EXPECT_EQ(UnionRegions(gfx::Rect(30, 40, 170, 160), gfx::Rect(10, 70, 190, 130)).ToString(), child->occludedScreenSpace().ToString()); - EXPECT_EQ(gfx::Rect(10, 70, 190, 130), rootLayer->occludedScreenSpace()); + EXPECT_EQ(gfx::Rect().ToString(), child2->occlusion().ToString()); + EXPECT_EQ(gfx::Rect(10, 0, 10, 190).ToString(), grandChild->occlusion().ToString()); + EXPECT_EQ(gfx::Rect(0, 0, 20, 190).ToString(), child->occlusion().ToString()); + EXPECT_EQ(gfx::Rect(20, 10, 10, 190), rootLayer->occlusion()); // If the child layer has a non-opaque drawOpacity, then it shouldn't contribute to occlusion on stuff below it setTestLayerPropertiesForTesting(rootLayer.get(), 0, identityMatrix, gfx::PointF(0, 0), gfx::PointF(0, 0), gfx::Size(200, 200), true); - setTestLayerPropertiesForTesting(child2.get(), rootLayer.get(), identityMatrix, gfx::PointF(0, 0), gfx::PointF(10, 70), gfx::Size(500, 500), true); - setTestLayerPropertiesForTesting(child.get(), rootLayer.get(), childTransform, gfx::PointF(0, 0), gfx::PointF(30, 30), gfx::Size(500, 500), true); - setTestLayerPropertiesForTesting(grandChild.get(), child.get(), identityMatrix, gfx::PointF(0, 0), gfx::PointF(10, 10), gfx::Size(500, 500), true); + setTestLayerPropertiesForTesting(child2.get(), rootLayer.get(), identityMatrix, gfx::PointF(0, 0), gfx::PointF(20, 10), gfx::Size(10, 500), true); + setTestLayerPropertiesForTesting(child.get(), rootLayer.get(), identityMatrix, gfx::PointF(0, 0), gfx::PointF(10, 10), gfx::Size(500, 500), true); + setTestLayerPropertiesForTesting(grandChild.get(), child.get(), identityMatrix, gfx::PointF(0, 0), gfx::PointF(-10, -10), gfx::Size(20, 500), true); child->setMaskLayer(0); child->setOpacity(0.5); @@ -1799,16 +1784,16 @@ public: m_layerTreeHost->updateLayers(queue, std::numeric_limits<size_t>::max()); m_layerTreeHost->commitComplete(); - EXPECT_EQ(gfx::Rect().ToString(), grandChild->occludedScreenSpace().ToString()); - EXPECT_EQ(gfx::Rect(30, 40, 170, 160).ToString(), child->occludedScreenSpace().ToString()); - EXPECT_EQ(gfx::Rect().ToString(), child2->occludedScreenSpace().ToString()); - EXPECT_EQ(gfx::Rect(10, 70, 190, 130).ToString(), rootLayer->occludedScreenSpace().ToString()); + EXPECT_EQ(gfx::Rect().ToString(), grandChild->occlusion().ToString()); + EXPECT_EQ(gfx::Rect(0, 0, 10, 190).ToString(), child->occlusion().ToString()); + EXPECT_EQ(gfx::Rect().ToString(), child2->occlusion().ToString()); + EXPECT_EQ(gfx::Rect(20, 10, 10, 190).ToString(), rootLayer->occlusion().ToString()); // If the child layer with non-opaque drawOpacity is below child2, then child2 should contribute to occlusion on everything, and child shouldn't contribute to the rootLayer setTestLayerPropertiesForTesting(rootLayer.get(), 0, identityMatrix, gfx::PointF(0, 0), gfx::PointF(0, 0), gfx::Size(200, 200), true); - setTestLayerPropertiesForTesting(child.get(), rootLayer.get(), childTransform, gfx::PointF(0, 0), gfx::PointF(30, 30), gfx::Size(500, 500), true); - setTestLayerPropertiesForTesting(grandChild.get(), child.get(), identityMatrix, gfx::PointF(0, 0), gfx::PointF(10, 10), gfx::Size(500, 500), true); - setTestLayerPropertiesForTesting(child2.get(), rootLayer.get(), identityMatrix, gfx::PointF(0, 0), gfx::PointF(10, 70), gfx::Size(500, 500), true); + setTestLayerPropertiesForTesting(child.get(), rootLayer.get(), identityMatrix, gfx::PointF(0, 0), gfx::PointF(10, 10), gfx::Size(500, 500), true); + setTestLayerPropertiesForTesting(grandChild.get(), child.get(), identityMatrix, gfx::PointF(0, 0), gfx::PointF(-10, -10), gfx::Size(20, 500), true); + setTestLayerPropertiesForTesting(child2.get(), rootLayer.get(), identityMatrix, gfx::PointF(0, 0), gfx::PointF(20, 10), gfx::Size(10, 500), true); child->setMaskLayer(0); child->setOpacity(0.5); @@ -1818,10 +1803,10 @@ public: m_layerTreeHost->updateLayers(queue, std::numeric_limits<size_t>::max()); m_layerTreeHost->commitComplete(); - EXPECT_EQ(gfx::Rect().ToString(), child2->occludedScreenSpace().ToString()); - EXPECT_EQ(gfx::Rect(10, 70, 190, 130).ToString(), grandChild->occludedScreenSpace().ToString()); - EXPECT_EQ(UnionRegions(gfx::Rect(30, 40, 170, 160), gfx::Rect(10, 70, 190, 130)).ToString(), child->occludedScreenSpace().ToString()); - EXPECT_EQ(gfx::Rect(10, 70, 190, 130).ToString(), rootLayer->occludedScreenSpace().ToString()); + EXPECT_EQ(gfx::Rect().ToString(), child2->occlusion().ToString()); + EXPECT_EQ(gfx::Rect(10, 0, 10, 190).ToString(), grandChild->occlusion().ToString()); + EXPECT_EQ(gfx::Rect(0, 0, 20, 190).ToString(), child->occlusion().ToString()); + EXPECT_EQ(gfx::Rect(20, 10, 10, 190).ToString(), rootLayer->occlusion().ToString()); // Kill the layerTreeHost immediately. m_layerTreeHost->setRootLayer(0); @@ -1877,10 +1862,10 @@ public: m_layerTreeHost->updateLayers(queue, std::numeric_limits<size_t>::max()); m_layerTreeHost->commitComplete(); - EXPECT_EQ(gfx::Rect().ToString(), child2->occludedScreenSpace().ToString()); - EXPECT_EQ(gfx::Rect(10, 70, 190, 130).ToString(), grandChild->occludedScreenSpace().ToString()); - EXPECT_EQ(UnionRegions(gfx::Rect(30, 40, 170, 30), gfx::Rect(10, 70, 190, 130)).ToString(), child->occludedScreenSpace().ToString()); - EXPECT_EQ(gfx::Rect(10, 70, 190, 130).ToString(), rootLayer->occludedScreenSpace().ToString()); + EXPECT_EQ(gfx::Rect().ToString(), child2->occlusion().ToString()); + EXPECT_EQ(gfx::Rect(40, 330, 130, 190).ToString(), grandChild->occlusion().ToString()); + EXPECT_EQ(UnionRegions(gfx::Rect(10, 330, 160, 170), gfx::Rect(40, 500, 130, 20)).ToString(), child->occlusion().ToString()); + EXPECT_EQ(gfx::Rect(10, 70, 190, 130).ToString(), rootLayer->occlusion().ToString()); // If the child layer has a filter that moves pixels/changes alpha, and is below child2, then child should not inherit occlusion from outside its subtree, // and should not contribute to the rootLayer @@ -1900,10 +1885,10 @@ public: m_layerTreeHost->updateLayers(queue, std::numeric_limits<size_t>::max()); m_layerTreeHost->commitComplete(); - EXPECT_EQ(gfx::Rect().ToString(), child2->occludedScreenSpace().ToString()); - EXPECT_EQ(gfx::Rect().ToString(), grandChild->occludedScreenSpace().ToString()); - EXPECT_EQ(gfx::Rect(30, 40, 170, 160).ToString(), child->occludedScreenSpace().ToString()); - EXPECT_EQ(gfx::Rect(10, 70, 190, 130).ToString(), rootLayer->occludedScreenSpace().ToString()); + EXPECT_EQ(gfx::Rect().ToString(), child2->occlusion().ToString()); + EXPECT_EQ(gfx::Rect().ToString(), grandChild->occlusion().ToString()); + EXPECT_EQ(gfx::Rect(10, 330, 160, 170).ToString(), child->occlusion().ToString()); + EXPECT_EQ(gfx::Rect(10, 70, 190, 130).ToString(), rootLayer->occlusion().ToString()); // Kill the layerTreeHost immediately. m_layerTreeHost->setRootLayer(0); @@ -1959,8 +1944,8 @@ public: m_layerTreeHost->commitComplete(); for (int i = 0; i < numSurfaces-1; ++i) { - gfx::Rect expectedOcclusion(i+1, i+1, 200-i-1, 200-i-1); - EXPECT_EQ(expectedOcclusion.ToString(), layers[i]->occludedScreenSpace().ToString()); + gfx::Rect expectedOcclusion(1, 1, 200-i-1, 200-i-1); + EXPECT_EQ(expectedOcclusion.ToString(), layers[i]->occlusion().ToString()); } // Kill the layerTreeHost immediately. diff --git a/cc/occlusion_tracker.cc b/cc/occlusion_tracker.cc index 4ea3d3c..406729d 100644 --- a/cc/occlusion_tracker.cc +++ b/cc/occlusion_tracker.cc @@ -18,8 +18,8 @@ using namespace std; namespace cc { template<typename LayerType, typename RenderSurfaceType> -OcclusionTrackerBase<LayerType, RenderSurfaceType>::OcclusionTrackerBase(gfx::Rect rootTargetRect, bool recordMetricsForFrame) - : m_rootTargetRect(rootTargetRect) +OcclusionTrackerBase<LayerType, RenderSurfaceType>::OcclusionTrackerBase(gfx::Rect screenSpaceClipRect, bool recordMetricsForFrame) + : m_screenSpaceClipRect(screenSpaceClipRect) , m_overdrawMetrics(OverdrawMetrics::create(recordMetricsForFrame)) , m_occludingScreenSpaceRects(0) , m_nonOccludingScreenSpaceRects(0) @@ -53,39 +53,47 @@ void OcclusionTrackerBase<LayerType, RenderSurfaceType>::leaveLayer(const LayerI leaveToRenderTarget(renderTarget); } -template<typename LayerType, typename RenderSurfaceType> -void OcclusionTrackerBase<LayerType, RenderSurfaceType>::enterRenderTarget(const LayerType* newTarget) +template<typename RenderSurfaceType> +static gfx::Rect screenSpaceClipRectInTargetSurface(const RenderSurfaceType* targetSurface, gfx::Rect screenSpaceClipRect) { - if (!m_stack.empty() && m_stack.back().target == newTarget) - return; + gfx::Transform inverseScreenSpaceTransform; + if (!targetSurface->screenSpaceTransform().GetInverse(&inverseScreenSpaceTransform)) + return targetSurface->contentRect(); - const LayerType* oldTarget = m_stack.empty() ? 0 : m_stack.back().target; - const RenderSurfaceType* oldAncestorThatMovesPixels = !oldTarget ? 0 : oldTarget->renderSurface()->nearestAncestorThatMovesPixels(); - const RenderSurfaceType* newAncestorThatMovesPixels = newTarget->renderSurface()->nearestAncestorThatMovesPixels(); + return gfx::ToEnclosingRect(MathUtil::projectClippedRect(inverseScreenSpaceTransform, screenSpaceClipRect)); +} - m_stack.push_back(StackObject(newTarget)); +template<typename RenderSurfaceType> +static Region transformSurfaceOpaqueRegion(const Region& region, bool haveClipRect, gfx::Rect clipRectInNewTarget, const gfx::Transform& transform) +{ + if (region.IsEmpty()) + return Region(); - // We copy the screen occlusion into the new RenderSurfaceImpl subtree, but we never copy in the - // target occlusion, since we are looking at a new RenderSurfaceImpl target. + // Verify that rects within the |surface| will remain rects in its target surface after applying |transform|. If this is true, then + // apply |transform| to each rect within |region| in order to transform the entire Region. - // If we are entering a subtree that is going to move pixels around, then the occlusion we've computed - // so far won't apply to the pixels we're drawing here in the same way. We discard the occlusion thus - // far to be safe, and ensure we don't cull any pixels that are moved such that they become visible. - bool enteringSubtreeThatMovesPixels = newAncestorThatMovesPixels && newAncestorThatMovesPixels != oldAncestorThatMovesPixels; + bool clipped; + gfx::QuadF transformedBoundsQuad = MathUtil::mapQuad(transform, gfx::QuadF(region.bounds()), clipped); + // FIXME: Find a rect interior to each transformed quad. + if (clipped || !transformedBoundsQuad.IsRectilinear()) + return Region(); - bool copyScreenOcclusionForward = m_stack.size() > 1 && !enteringSubtreeThatMovesPixels; - if (copyScreenOcclusionForward) { - int lastIndex = m_stack.size() - 1; - m_stack[lastIndex].occlusionInScreen = m_stack[lastIndex - 1].occlusionInScreen; + // TODO(danakj): If the Region is too complex, degrade gracefully here by skipping rects in it. + Region transformedRegion; + for (Region::Iterator rects(region); rects.has_rect(); rects.next()) { + gfx::Rect transformedRect = gfx::ToEnclosedRect(MathUtil::mapQuad(transform, gfx::QuadF(rects.rect()), clipped).BoundingBox()); + DCHECK(!clipped); // We only map if the transform preserves axis alignment. + if (haveClipRect) + transformedRect.Intersect(clipRectInNewTarget); + transformedRegion.Union(transformedRect); } + return transformedRegion; } static inline bool layerOpacityKnown(const Layer* layer) { return !layer->drawOpacityIsAnimating(); } static inline bool layerOpacityKnown(const LayerImpl*) { return true; } static inline bool layerTransformsToTargetKnown(const Layer* layer) { return !layer->drawTransformIsAnimating(); } static inline bool layerTransformsToTargetKnown(const LayerImpl*) { return true; } -static inline bool layerTransformsToScreenKnown(const Layer* layer) { return !layer->screenSpaceTransformIsAnimating(); } -static inline bool layerTransformsToScreenKnown(const LayerImpl*) { return true; } static inline bool surfaceOpacityKnown(const RenderSurface* surface) { return !surface->drawOpacityIsAnimating(); } static inline bool surfaceOpacityKnown(const RenderSurfaceImpl*) { return true; } @@ -98,6 +106,51 @@ static inline bool layerIsInUnsorted3dRenderingContext(const Layer* layer) { ret static inline bool layerIsInUnsorted3dRenderingContext(const LayerImpl*) { return false; } template<typename LayerType, typename RenderSurfaceType> +void OcclusionTrackerBase<LayerType, RenderSurfaceType>::enterRenderTarget(const LayerType* newTarget) +{ + if (!m_stack.empty() && m_stack.back().target == newTarget) + return; + + const LayerType* oldTarget = m_stack.empty() ? 0 : m_stack.back().target; + const RenderSurfaceType* oldAncestorThatMovesPixels = !oldTarget ? 0 : oldTarget->renderSurface()->nearestAncestorThatMovesPixels(); + const RenderSurfaceType* newAncestorThatMovesPixels = newTarget->renderSurface()->nearestAncestorThatMovesPixels(); + + m_stack.push_back(StackObject(newTarget)); + + // We copy the screen occlusion into the new RenderSurface subtree, but we never copy in the + // occlusion from inside the target, since we are looking at a new RenderSurface target. + + // If we are entering a subtree that is going to move pixels around, then the occlusion we've computed + // so far won't apply to the pixels we're drawing here in the same way. We discard the occlusion thus + // far to be safe, and ensure we don't cull any pixels that are moved such that they become visible. + bool enteringSubtreeThatMovesPixels = newAncestorThatMovesPixels && newAncestorThatMovesPixels != oldAncestorThatMovesPixels; + + bool haveTransformFromScreenToNewTarget = false; + gfx::Transform inverseNewTargetScreenSpaceTransform; + if (surfaceTransformsToScreenKnown(newTarget->renderSurface())) + haveTransformFromScreenToNewTarget = newTarget->renderSurface()->screenSpaceTransform().GetInverse(&inverseNewTargetScreenSpaceTransform); + + bool enteringRootTarget = newTarget->parent() == NULL; + + bool copyOutsideOcclusionForward = m_stack.size() > 1 && !enteringSubtreeThatMovesPixels && haveTransformFromScreenToNewTarget && !enteringRootTarget; + if (!copyOutsideOcclusionForward) + return; + + int lastIndex = m_stack.size() - 1; + gfx::Transform oldTargetToNewTargetTransform(inverseNewTargetScreenSpaceTransform, oldTarget->renderSurface()->screenSpaceTransform()); + m_stack[lastIndex].occlusionFromOutsideTarget = transformSurfaceOpaqueRegion<RenderSurfaceType>( + m_stack[lastIndex - 1].occlusionFromOutsideTarget, + false, + gfx::Rect(), + oldTargetToNewTargetTransform); + m_stack[lastIndex].occlusionFromOutsideTarget.Union(transformSurfaceOpaqueRegion<RenderSurfaceType>( + m_stack[lastIndex - 1].occlusionFromInsideTarget, + false, + gfx::Rect(), + oldTargetToNewTargetTransform)); +} + +template<typename LayerType, typename RenderSurfaceType> void OcclusionTrackerBase<LayerType, RenderSurfaceType>::finishedRenderTarget(const LayerType* finishedTarget) { // Make sure we know about the target surface. @@ -109,102 +162,56 @@ void OcclusionTrackerBase<LayerType, RenderSurfaceType>::finishedRenderTarget(co // TODO(senorblanco): Make this smarter for SkImageFilter case: once // SkImageFilters can report affectsOpacity(), call that. if (finishedTarget->maskLayer() || !surfaceOpacityKnown(surface) || surface->drawOpacity() < 1 || finishedTarget->filters().hasFilterThatAffectsOpacity() || finishedTarget->filter()) { - m_stack.back().occlusionInScreen.Clear(); - m_stack.back().occlusionInTarget.Clear(); - } else { - if (!surfaceTransformsToTargetKnown(surface)) - m_stack.back().occlusionInTarget.Clear(); - if (!surfaceTransformsToScreenKnown(surface)) - m_stack.back().occlusionInScreen.Clear(); + m_stack.back().occlusionFromOutsideTarget.Clear(); + m_stack.back().occlusionFromInsideTarget.Clear(); + } else if (!surfaceTransformsToTargetKnown(surface)) { + m_stack.back().occlusionFromInsideTarget.Clear(); + m_stack.back().occlusionFromOutsideTarget.Clear(); } } -template<typename RenderSurfaceType> -static inline Region transformSurfaceOpaqueRegion(const RenderSurfaceType* surface, const Region& region, const gfx::Transform& transform) +template<typename LayerType> +static void reduceOcclusionBelowSurface(LayerType* contributingLayer, const gfx::Rect& surfaceRect, const gfx::Transform& surfaceTransform, LayerType* renderTarget, Region& occlusionFromInsideTarget) { - // Verify that rects within the |surface| will remain rects in its target surface after applying |transform|. If this is true, then - // apply |transform| to each rect within |region| in order to transform the entire Region. + if (surfaceRect.IsEmpty()) + return; - bool clipped; - gfx::QuadF transformedBoundsQuad = MathUtil::mapQuad(transform, gfx::QuadF(region.bounds()), clipped); - // FIXME: Find a rect interior to each transformed quad. - if (clipped || !transformedBoundsQuad.IsRectilinear()) - return Region(); + gfx::Rect affectedAreaInTarget = gfx::ToEnclosingRect(MathUtil::mapClippedRect(surfaceTransform, gfx::RectF(surfaceRect))); + if (contributingLayer->renderSurface()->isClipped()) + affectedAreaInTarget.Intersect(contributingLayer->renderSurface()->clipRect()); + if (affectedAreaInTarget.IsEmpty()) + return; - Region transformedRegion; + int outsetTop, outsetRight, outsetBottom, outsetLeft; + contributingLayer->backgroundFilters().getOutsets(outsetTop, outsetRight, outsetBottom, outsetLeft); - for (Region::Iterator rects(region); rects.has_rect(); rects.next()) { - // We've already checked for clipping in the mapQuad call above, these calls should not clip anything further. - gfx::Rect transformedRect = gfx::ToEnclosedRect(MathUtil::mapClippedRect(transform, gfx::RectF(rects.rect()))); - if (!surface->clipRect().IsEmpty()) - transformedRect.Intersect(surface->clipRect()); - transformedRegion.Union(transformedRect); - } - return transformedRegion; -} + // The filter can move pixels from outside of the clip, so allow affectedArea to expand outside the clip. + affectedAreaInTarget.Inset(-outsetLeft, -outsetTop, -outsetRight, -outsetBottom); -static inline void reduceOcclusion(const gfx::Rect& affectedArea, const gfx::Rect& expandedPixel, Region& occlusion) -{ - if (affectedArea.IsEmpty()) - return; + gfx::Rect filterOutsetsInTarget(-outsetLeft, -outsetTop, outsetLeft + outsetRight, outsetTop + outsetBottom); - Region affectedOcclusion = IntersectRegions(occlusion, affectedArea); + Region affectedOcclusion = IntersectRegions(occlusionFromInsideTarget, affectedAreaInTarget); Region::Iterator affectedOcclusionRects(affectedOcclusion); - occlusion.Subtract(affectedArea); + occlusionFromInsideTarget.Subtract(affectedAreaInTarget); for (; affectedOcclusionRects.has_rect(); affectedOcclusionRects.next()) { gfx::Rect occlusionRect = affectedOcclusionRects.rect(); // Shrink the rect by expanding the non-opaque pixels outside the rect. - // The expandedPixel is the Rect for a single pixel after being - // expanded by filters on the layer. The original pixel would be - // Rect(0, 0, 1, 1), and the expanded pixel is the rect, relative - // to this original rect, that the original pixel can influence after - // being filtered. - // To convert the expandedPixel Rect back to filter outsets: - // x = -leftOutset - // width = leftOutset + rightOutset - // right = x + width = -leftOutset + leftOutset + rightOutset = rightOutset - - // The leftOutset of the filters moves pixels on the right side of + // The left outset of the filters moves pixels on the right side of // the occlusionRect into it, shrinking its right edge. - int shrinkLeft = occlusionRect.x() == affectedArea.x() ? 0 : expandedPixel.right(); - int shrinkTop = occlusionRect.y() == affectedArea.y() ? 0 : expandedPixel.bottom(); - int shrinkRight = occlusionRect.right() == affectedArea.right() ? 0 : -expandedPixel.x(); - int shrinkBottom = occlusionRect.bottom() == affectedArea.bottom() ? 0 : -expandedPixel.y(); + int shrinkLeft = occlusionRect.x() == affectedAreaInTarget.x() ? 0 : outsetRight; + int shrinkTop = occlusionRect.y() == affectedAreaInTarget.y() ? 0 : outsetBottom; + int shrinkRight = occlusionRect.right() == affectedAreaInTarget.right() ? 0 : outsetLeft; + int shrinkBottom = occlusionRect.bottom() == affectedAreaInTarget.bottom() ? 0 : outsetTop; occlusionRect.Inset(shrinkLeft, shrinkTop, shrinkRight, shrinkBottom); - occlusion.Union(occlusionRect); + occlusionFromInsideTarget.Union(occlusionRect); } } -template<typename LayerType> -static void reduceOcclusionBelowSurface(LayerType* contributingLayer, const gfx::Rect& surfaceRect, const gfx::Transform& surfaceTransform, LayerType* renderTarget, Region& occlusionInTarget, Region& occlusionInScreen) -{ - if (surfaceRect.IsEmpty()) - return; - - gfx::Rect boundsInTarget = gfx::ToEnclosingRect(MathUtil::mapClippedRect(surfaceTransform, gfx::RectF(surfaceRect))); - if (!contributingLayer->renderSurface()->clipRect().IsEmpty()) - boundsInTarget.Intersect(contributingLayer->renderSurface()->clipRect()); - - int outsetTop, outsetRight, outsetBottom, outsetLeft; - contributingLayer->backgroundFilters().getOutsets(outsetTop, outsetRight, outsetBottom, outsetLeft); - - // The filter can move pixels from outside of the clip, so allow affectedArea to expand outside the clip. - boundsInTarget.Inset(-outsetLeft, -outsetTop, -outsetRight, -outsetBottom); - - gfx::Rect boundsInScreen = gfx::ToEnclosingRect(MathUtil::mapClippedRect(renderTarget->renderSurface()->screenSpaceTransform(), gfx::RectF(boundsInTarget))); - - gfx::Rect filterOutsetsInTarget(-outsetLeft, -outsetTop, outsetLeft + outsetRight, outsetTop + outsetBottom); - gfx::Rect filterOutsetsInScreen = gfx::ToEnclosingRect(MathUtil::mapClippedRect(renderTarget->renderSurface()->screenSpaceTransform(), gfx::RectF(filterOutsetsInTarget))); - - reduceOcclusion(boundsInTarget, filterOutsetsInTarget, occlusionInTarget); - reduceOcclusion(boundsInScreen, filterOutsetsInScreen, occlusionInScreen); -} - template<typename LayerType, typename RenderSurfaceType> void OcclusionTrackerBase<LayerType, RenderSurfaceType>::leaveToRenderTarget(const LayerType* newTarget) { @@ -216,9 +223,12 @@ void OcclusionTrackerBase<LayerType, RenderSurfaceType>::leaveToRenderTarget(con const LayerType* oldTarget = m_stack[lastIndex].target; const RenderSurfaceType* oldSurface = oldTarget->renderSurface(); - Region oldTargetOcclusionInNewTarget = transformSurfaceOpaqueRegion<RenderSurfaceType>(oldSurface, m_stack[lastIndex].occlusionInTarget, oldSurface->drawTransform()); + + Region oldOcclusionFromInsideTargetInNewTarget = transformSurfaceOpaqueRegion<RenderSurfaceType>(m_stack[lastIndex].occlusionFromInsideTarget, oldSurface->isClipped(), oldSurface->clipRect(), oldSurface->drawTransform()); if (oldTarget->hasReplica() && !oldTarget->replicaHasMask()) - oldTargetOcclusionInNewTarget.Union(transformSurfaceOpaqueRegion<RenderSurfaceType>(oldSurface, m_stack[lastIndex].occlusionInTarget, oldSurface->replicaDrawTransform())); + oldOcclusionFromInsideTargetInNewTarget.Union(transformSurfaceOpaqueRegion<RenderSurfaceType>(m_stack[lastIndex].occlusionFromInsideTarget, oldSurface->isClipped(), oldSurface->clipRect(), oldSurface->replicaDrawTransform())); + + Region oldOcclusionFromOutsideTargetInNewTarget = transformSurfaceOpaqueRegion<RenderSurfaceType>(m_stack[lastIndex].occlusionFromOutsideTarget, false, gfx::Rect(), oldSurface->drawTransform()); gfx::Rect unoccludedSurfaceRect; gfx::Rect unoccludedReplicaRect; @@ -230,56 +240,31 @@ void OcclusionTrackerBase<LayerType, RenderSurfaceType>::leaveToRenderTarget(con if (surfaceWillBeAtTopAfterPop) { // Merge the top of the stack down. - m_stack[lastIndex - 1].occlusionInScreen.Union(m_stack[lastIndex].occlusionInScreen); - m_stack[lastIndex - 1].occlusionInTarget.Union(oldTargetOcclusionInNewTarget); + m_stack[lastIndex - 1].occlusionFromInsideTarget.Union(oldOcclusionFromInsideTargetInNewTarget); + // TODO(danakj): Strictly this should subtract the inside target occlusion before union. + if (newTarget->parent()) + m_stack[lastIndex - 1].occlusionFromOutsideTarget.Union(oldOcclusionFromOutsideTargetInNewTarget); m_stack.pop_back(); } else { - // Replace the top of the stack with the new pushed surface. Copy the occluded screen region to the top. + // Replace the top of the stack with the new pushed surface. m_stack.back().target = newTarget; - m_stack.back().occlusionInTarget = oldTargetOcclusionInNewTarget; - } - - if (oldTarget->backgroundFilters().hasFilterThatMovesPixels()) { - reduceOcclusionBelowSurface(oldTarget, unoccludedSurfaceRect, oldSurface->drawTransform(), newTarget, m_stack.back().occlusionInTarget, m_stack.back().occlusionInScreen); - if (oldTarget->hasReplica()) - reduceOcclusionBelowSurface(oldTarget, unoccludedReplicaRect, oldSurface->replicaDrawTransform(), newTarget, m_stack.back().occlusionInTarget, m_stack.back().occlusionInScreen); + m_stack.back().occlusionFromInsideTarget = oldOcclusionFromInsideTargetInNewTarget; + if (newTarget->parent()) + m_stack.back().occlusionFromOutsideTarget = oldOcclusionFromOutsideTargetInNewTarget; + else + m_stack.back().occlusionFromOutsideTarget.Clear(); } -} -// FIXME: Remove usePaintTracking when paint tracking is on for paint culling. -template<typename LayerType> -static inline void addOcclusionBehindLayer(Region& region, const LayerType* layer, const gfx::Transform& transform, const Region& opaqueContents, const gfx::Rect& clipRectInTarget, const gfx::Size& minimumTrackingSize, std::vector<gfx::Rect>* occludingScreenSpaceRects, std::vector<gfx::Rect>* nonOccludingScreenSpaceRects) -{ - DCHECK(layer->visibleContentRect().Contains(opaqueContents.bounds())); - - bool clipped; - gfx::QuadF visibleTransformedQuad = MathUtil::mapQuad(transform, gfx::QuadF(layer->visibleContentRect()), clipped); - // FIXME: Find a rect interior to each transformed quad. - if (clipped || !visibleTransformedQuad.IsRectilinear()) + if (!oldTarget->backgroundFilters().hasFilterThatMovesPixels()) return; - for (Region::Iterator opaqueContentRects(opaqueContents); opaqueContentRects.has_rect(); opaqueContentRects.next()) { - // We've already checked for clipping in the mapQuad call above, these calls should not clip anything further. - gfx::Rect transformedRect = gfx::ToEnclosedRect(MathUtil::mapClippedRect(transform, gfx::RectF(opaqueContentRects.rect()))); - transformedRect.Intersect(clipRectInTarget); - if (transformedRect.width() >= minimumTrackingSize.width() || transformedRect.height() >= minimumTrackingSize.height()) { - if (occludingScreenSpaceRects) - occludingScreenSpaceRects->push_back(transformedRect); - region.Union(transformedRect); - } - } + reduceOcclusionBelowSurface(oldTarget, unoccludedSurfaceRect, oldSurface->drawTransform(), newTarget, m_stack.back().occlusionFromInsideTarget); + reduceOcclusionBelowSurface(oldTarget, unoccludedSurfaceRect, oldSurface->drawTransform(), newTarget, m_stack.back().occlusionFromOutsideTarget); - if (nonOccludingScreenSpaceRects) { - Region nonOpaqueContents = SubtractRegions(gfx::Rect(layer->contentBounds()), opaqueContents); - for (Region::Iterator nonOpaqueContentRects(nonOpaqueContents); nonOpaqueContentRects.has_rect(); nonOpaqueContentRects.next()) { - // We've already checked for clipping in the mapQuad call above, these calls should not clip anything further. - gfx::Rect transformedRect = gfx::ToEnclosedRect(MathUtil::mapClippedRect(transform, gfx::RectF(nonOpaqueContentRects.rect()))); - transformedRect.Intersect(clipRectInTarget); - if (transformedRect.IsEmpty()) - continue; - nonOccludingScreenSpaceRects->push_back(transformedRect); - } - } + if (!oldTarget->hasReplica()) + return; + reduceOcclusionBelowSurface(oldTarget, unoccludedReplicaRect, oldSurface->replicaDrawTransform(), newTarget, m_stack.back().occlusionFromInsideTarget); + reduceOcclusionBelowSurface(oldTarget, unoccludedReplicaRect, oldSurface->replicaDrawTransform(), newTarget, m_stack.back().occlusionFromOutsideTarget); } template<typename LayerType, typename RenderSurfaceType> @@ -300,84 +285,98 @@ void OcclusionTrackerBase<LayerType, RenderSurfaceType>::markOccludedBehindLayer if (opaqueContents.IsEmpty()) return; - gfx::Rect clipRectInTarget = layerClipRectInTarget(layer); - if (layerTransformsToTargetKnown(layer)) - addOcclusionBehindLayer<LayerType>(m_stack.back().occlusionInTarget, layer, layer->drawTransform(), opaqueContents, clipRectInTarget, m_minimumTrackingSize, 0, 0); - - // We must clip the occlusion within the layer's clipRectInTarget within screen space as well. If the clip rect can't be moved to screen space and - // remain rectilinear, then we don't add any occlusion in screen space. - - if (layerTransformsToScreenKnown(layer)) { - gfx::Transform targetToScreenTransform = m_stack.back().target->renderSurface()->screenSpaceTransform(); - bool clipped; - gfx::QuadF clipQuadInScreen = MathUtil::mapQuad(targetToScreenTransform, gfx::QuadF(clipRectInTarget), clipped); - // FIXME: Find a rect interior to the transformed clip quad. - if (clipped || !clipQuadInScreen.IsRectilinear()) - return; - gfx::Rect clipRectInScreen = gfx::IntersectRects(m_rootTargetRect, gfx::ToEnclosedRect(clipQuadInScreen.BoundingBox())); - addOcclusionBehindLayer<LayerType>(m_stack.back().occlusionInScreen, layer, layer->screenSpaceTransform(), opaqueContents, clipRectInScreen, m_minimumTrackingSize, m_occludingScreenSpaceRects, m_nonOccludingScreenSpaceRects); + DCHECK(layer->visibleContentRect().Contains(opaqueContents.bounds())); + + if (!layerTransformsToTargetKnown(layer)) + return; + + bool clipped; + gfx::QuadF visibleTransformedQuad = MathUtil::mapQuad(layer->drawTransform(), gfx::QuadF(opaqueContents.bounds()), clipped); + // FIXME: Find a rect interior to each transformed quad. + if (clipped || !visibleTransformedQuad.IsRectilinear()) + return; + + gfx::Rect clipRectInTarget = gfx::IntersectRects( + layerClipRectInTarget(layer), + screenSpaceClipRectInTargetSurface(layer->renderTarget()->renderSurface(), m_screenSpaceClipRect)); + + for (Region::Iterator opaqueContentRects(opaqueContents); opaqueContentRects.has_rect(); opaqueContentRects.next()) { + gfx::Rect transformedRect = gfx::ToEnclosedRect(MathUtil::mapQuad(layer->drawTransform(), gfx::QuadF(opaqueContentRects.rect()), clipped).BoundingBox()); + DCHECK(!clipped); // We only map if the transform preserves axis alignment. + transformedRect.Intersect(clipRectInTarget); + if (transformedRect.width() < m_minimumTrackingSize.width() && transformedRect.height() < m_minimumTrackingSize.height()) + continue; + m_stack.back().occlusionFromInsideTarget.Union(transformedRect); + + if (!m_occludingScreenSpaceRects) + continue; + + // Save the occluding area in screen space for debug visualization. + gfx::QuadF screenSpaceQuad = MathUtil::mapQuad(layer->renderTarget()->renderSurface()->screenSpaceTransform(), gfx::QuadF(transformedRect), clipped); + // TODO(danakj): Store the quad in the debug info instead of the bounding box. + gfx::Rect screenSpaceRect = gfx::ToEnclosedRect(screenSpaceQuad.BoundingBox()); + m_occludingScreenSpaceRects->push_back(screenSpaceRect); } -} -static inline bool testContentRectOccluded(const gfx::Rect& contentRect, const gfx::Transform& contentSpaceTransform, const gfx::Rect& clipRectInTarget, const Region& occlusion) -{ - gfx::RectF transformedRect = MathUtil::mapClippedRect(contentSpaceTransform, gfx::RectF(contentRect)); - // Take the gfx::ToEnclosingRect, as we want to include partial pixels in the test. - gfx::Rect targetRect = gfx::IntersectRects(gfx::ToEnclosingRect(transformedRect), clipRectInTarget); - return occlusion.Contains(targetRect); + if (!m_nonOccludingScreenSpaceRects) + return; + + Region nonOpaqueContents = SubtractRegions(gfx::Rect(layer->contentBounds()), opaqueContents); + for (Region::Iterator nonOpaqueContentRects(nonOpaqueContents); nonOpaqueContentRects.has_rect(); nonOpaqueContentRects.next()) { + // We've already checked for clipping in the mapQuad call above, these calls should not clip anything further. + gfx::Rect transformedRect = gfx::ToEnclosedRect(MathUtil::mapClippedRect(layer->drawTransform(), gfx::RectF(nonOpaqueContentRects.rect()))); + transformedRect.Intersect(clipRectInTarget); + if (transformedRect.IsEmpty()) + continue; + + gfx::QuadF screenSpaceQuad = MathUtil::mapQuad(layer->renderTarget()->renderSurface()->screenSpaceTransform(), gfx::QuadF(transformedRect), clipped); + // TODO(danakj): Store the quad in the debug info instead of the bounding box. + gfx::Rect screenSpaceRect = gfx::ToEnclosedRect(screenSpaceQuad.BoundingBox()); + m_nonOccludingScreenSpaceRects->push_back(screenSpaceRect); + } } template<typename LayerType, typename RenderSurfaceType> bool OcclusionTrackerBase<LayerType, RenderSurfaceType>::occluded(const LayerType* renderTarget, const gfx::Rect& contentRect, const gfx::Transform& drawTransform, bool implDrawTransformIsUnknown, const gfx::Rect& clippedRectInTarget, bool* hasOcclusionFromOutsideTargetSurface) const { - if (hasOcclusionFromOutsideTargetSurface) - *hasOcclusionFromOutsideTargetSurface = false; - DCHECK(!m_stack.empty()); if (m_stack.empty()) return false; if (contentRect.IsEmpty()) return true; + if (implDrawTransformIsUnknown) + return false; - DCHECK(renderTarget == m_stack.back().target); + // For tests with no render target. + if (!renderTarget) + return false; - if (!implDrawTransformIsUnknown && testContentRectOccluded(contentRect, drawTransform, clippedRectInTarget, m_stack.back().occlusionInTarget)) - return true; + DCHECK(renderTarget->renderTarget() == renderTarget); + DCHECK(renderTarget->renderSurface()); + DCHECK(renderTarget == m_stack.back().target); - // renderTarget can be NULL in some tests. - bool transformToScreenKnown = renderTarget && !implDrawTransformIsUnknown && layerTransformsToScreenKnown(renderTarget); - if (transformToScreenKnown && testContentRectOccluded(contentRect, renderTarget->renderSurface()->screenSpaceTransform() * drawTransform, m_rootTargetRect, m_stack.back().occlusionInScreen)) { - if (hasOcclusionFromOutsideTargetSurface) - *hasOcclusionFromOutsideTargetSurface = true; - return true; - } + gfx::Transform inverseDrawTransform; + if (!drawTransform.GetInverse(&inverseDrawTransform)) + return false; - return false; -} + // Take the ToEnclosingRect at each step, as we want to contain any unoccluded partial pixels in the resulting Rect. + gfx::Rect contentRectInTargetSurface = gfx::ToEnclosingRect(MathUtil::mapClippedRect(drawTransform, gfx::RectF(contentRect))); + contentRectInTargetSurface.Intersect(clippedRectInTarget); + contentRectInTargetSurface.Intersect(screenSpaceClipRectInTargetSurface(renderTarget->renderSurface(), m_screenSpaceClipRect)); -// Determines what portion of rect, if any, is unoccluded (not occluded by region). If -// the resulting unoccluded region is not rectangular, we return a rect containing it. -static inline gfx::Rect rectSubtractRegion(const gfx::Rect& rect, const Region& region) -{ - if (region.IsEmpty()) - return rect; + Region unoccludedRegionInTargetSurface = contentRectInTargetSurface; + unoccludedRegionInTargetSurface.Subtract(m_stack.back().occlusionFromInsideTarget); + gfx::RectF unoccludedRectInTargetSurfaceWithoutOutsideOcclusion = unoccludedRegionInTargetSurface.bounds(); + unoccludedRegionInTargetSurface.Subtract(m_stack.back().occlusionFromOutsideTarget); - Region rectRegion(rect); - rectRegion.Subtract(region); - return rectRegion.bounds(); -} + gfx::RectF unoccludedRectInTargetSurface = unoccludedRegionInTargetSurface.bounds(); -static inline gfx::Rect computeUnoccludedContentRect(const gfx::Rect& contentRect, const gfx::Transform& contentSpaceTransform, const gfx::Rect& clipRectInTarget, const Region& occlusion) -{ - if (!contentSpaceTransform.IsInvertible()) - return contentRect; + if (hasOcclusionFromOutsideTargetSurface) { + // Check if the unoccluded rect shrank when applying outside occlusion. + *hasOcclusionFromOutsideTargetSurface = !gfx::SubtractRects(unoccludedRectInTargetSurfaceWithoutOutsideOcclusion, unoccludedRectInTargetSurface).IsEmpty(); + } - // Take the ToEnclosingRect at each step, as we want to contain any unoccluded partial pixels in the resulting Rect. - gfx::RectF transformedRect = MathUtil::mapClippedRect(contentSpaceTransform, gfx::RectF(contentRect)); - gfx::Rect shrunkRect = rectSubtractRegion(gfx::IntersectRects(gfx::ToEnclosingRect(transformedRect), clipRectInTarget), occlusion); - gfx::Rect unoccludedRect = gfx::ToEnclosingRect(MathUtil::projectClippedRect(MathUtil::inverse(contentSpaceTransform), gfx::RectF(shrunkRect))); - // The rect back in content space is a bounding box and may extend outside of the original contentRect, so clamp it to the contentRectBounds. - return gfx::IntersectRects(unoccludedRect, contentRect); + return unoccludedRectInTargetSurface.IsEmpty(); } template<typename LayerType, typename RenderSurfaceType> @@ -388,26 +387,41 @@ gfx::Rect OcclusionTrackerBase<LayerType, RenderSurfaceType>::unoccludedContentR return contentRect; if (contentRect.IsEmpty()) return contentRect; + if (implDrawTransformIsUnknown) + return contentRect; + + // For tests with no render target. + if (!renderTarget) + return contentRect; DCHECK(renderTarget->renderTarget() == renderTarget); DCHECK(renderTarget->renderSurface()); DCHECK(renderTarget == m_stack.back().target); - // We want to return a rect that contains all the visible parts of |contentRect| in both screen space and in the target surface. - // So we find the visible parts of |contentRect| in each space, and take the intersection. - - gfx::Rect unoccludedInScreen = contentRect; - if (layerTransformsToScreenKnown(renderTarget) && !implDrawTransformIsUnknown) - unoccludedInScreen = computeUnoccludedContentRect(contentRect, renderTarget->renderSurface()->screenSpaceTransform() * drawTransform, m_rootTargetRect, m_stack.back().occlusionInScreen); - - gfx::Rect unoccludedInTarget = contentRect; - if (!implDrawTransformIsUnknown) - unoccludedInTarget = computeUnoccludedContentRect(contentRect, drawTransform, clippedRectInTarget, m_stack.back().occlusionInTarget); + gfx::Transform inverseDrawTransform; + if (!drawTransform.GetInverse(&inverseDrawTransform)) + return contentRect; - if (hasOcclusionFromOutsideTargetSurface) - *hasOcclusionFromOutsideTargetSurface = (gfx::IntersectRects(unoccludedInScreen, unoccludedInTarget) != unoccludedInTarget); + // Take the ToEnclosingRect at each step, as we want to contain any unoccluded partial pixels in the resulting Rect. + gfx::Rect contentRectInTargetSurface = gfx::ToEnclosingRect(MathUtil::mapClippedRect(drawTransform, gfx::RectF(contentRect))); + contentRectInTargetSurface.Intersect(clippedRectInTarget); + contentRectInTargetSurface.Intersect(screenSpaceClipRectInTargetSurface(renderTarget->renderSurface(), m_screenSpaceClipRect)); + + Region unoccludedRegionInTargetSurface = contentRectInTargetSurface; + unoccludedRegionInTargetSurface.Subtract(m_stack.back().occlusionFromInsideTarget); + gfx::RectF unoccludedRectInTargetSurfaceWithoutOutsideOcclusion = unoccludedRegionInTargetSurface.bounds(); + unoccludedRegionInTargetSurface.Subtract(m_stack.back().occlusionFromOutsideTarget); + + gfx::RectF unoccludedRectInTargetSurface = unoccludedRegionInTargetSurface.bounds(); + gfx::Rect unoccludedRect = gfx::ToEnclosingRect(MathUtil::projectClippedRect(inverseDrawTransform, unoccludedRectInTargetSurface)); + unoccludedRect.Intersect(contentRect); + + if (hasOcclusionFromOutsideTargetSurface) { + // Check if the unoccluded rect shrank when applying outside occlusion. + *hasOcclusionFromOutsideTargetSurface = !gfx::SubtractRects(unoccludedRectInTargetSurfaceWithoutOutsideOcclusion, unoccludedRectInTargetSurface).IsEmpty(); + } - return gfx::IntersectRects(unoccludedInScreen, unoccludedInTarget); + return unoccludedRect; } template<typename LayerType, typename RenderSurfaceType> @@ -426,50 +440,61 @@ gfx::Rect OcclusionTrackerBase<LayerType, RenderSurfaceType>::unoccludedContribu if (contentRect.IsEmpty()) return contentRect; - RenderSurfaceType* surface = layer->renderSurface(); + const RenderSurfaceType* surface = layer->renderSurface(); + const LayerType* contributingSurfaceRenderTarget = layer->parent()->renderTarget(); + + if (!surfaceTransformsToTargetKnown(surface)) + return contentRect; + + gfx::Transform drawTransform = forReplica ? surface->replicaDrawTransform() : surface->drawTransform(); + gfx::Transform inverseDrawTransform; + if (!drawTransform.GetInverse(&inverseDrawTransform)) + return contentRect; - gfx::Rect surfaceClipRect = surface->clipRect(); - if (surfaceClipRect.IsEmpty()) { - const LayerType* contributingSurfaceRenderTarget = layer->parent()->renderTarget(); - surfaceClipRect = gfx::IntersectRects(contributingSurfaceRenderTarget->renderSurface()->contentRect(), gfx::ToEnclosingRect(surface->drawableContentRect())); + // Take the ToEnclosingRect at each step, as we want to contain any unoccluded partial pixels in the resulting Rect. + gfx::Rect contentRectInTargetSurface = gfx::ToEnclosingRect(MathUtil::mapClippedRect(drawTransform, gfx::RectF(contentRect))); + if (surface->isClipped()) { + contentRectInTargetSurface.Intersect(surface->clipRect()); + } else { + contentRectInTargetSurface.Intersect(contributingSurfaceRenderTarget->renderSurface()->contentRect()); + contentRectInTargetSurface.Intersect(gfx::ToEnclosingRect(surface->drawableContentRect())); } + contentRectInTargetSurface.Intersect(screenSpaceClipRectInTargetSurface(contributingSurfaceRenderTarget->renderSurface(), m_screenSpaceClipRect)); + + gfx::RectF unoccludedRectInTargetSurface; // A contributing surface doesn't get occluded by things inside its own surface, so only things outside the surface can occlude it. That occlusion is // found just below the top of the stack (if it exists). bool hasOcclusion = m_stack.size() > 1; - - const gfx::Transform& transformToScreen = forReplica ? surface->replicaScreenSpaceTransform() : surface->screenSpaceTransform(); - const gfx::Transform& transformToTarget = forReplica ? surface->replicaDrawTransform() : surface->drawTransform(); - - gfx::Rect unoccludedInScreen = contentRect; - if (surfaceTransformsToScreenKnown(surface)) { - if (hasOcclusion) { - const StackObject& secondLast = m_stack[m_stack.size() - 2]; - unoccludedInScreen = computeUnoccludedContentRect(contentRect, transformToScreen, m_rootTargetRect, secondLast.occlusionInScreen); - } else - unoccludedInScreen = computeUnoccludedContentRect(contentRect, transformToScreen, m_rootTargetRect, Region()); - } - - gfx::Rect unoccludedInTarget = contentRect; - if (surfaceTransformsToTargetKnown(surface)) { - if (hasOcclusion) { - const StackObject& secondLast = m_stack[m_stack.size() - 2]; - unoccludedInTarget = computeUnoccludedContentRect(contentRect, transformToTarget, surfaceClipRect, secondLast.occlusionInTarget); - } else - unoccludedInTarget = computeUnoccludedContentRect(contentRect, transformToTarget, surfaceClipRect, Region()); + if (hasOcclusion) { + const StackObject& secondLast = m_stack[m_stack.size() - 2]; + Region unoccludedRegionInTargetSurface = contentRectInTargetSurface; + unoccludedRegionInTargetSurface.Subtract(secondLast.occlusionFromInsideTarget); + gfx::RectF unoccludedRectInTargetSurfaceWithoutOutsideOcclusion = unoccludedRegionInTargetSurface.bounds(); + unoccludedRegionInTargetSurface.Subtract(secondLast.occlusionFromOutsideTarget); + + unoccludedRectInTargetSurface = unoccludedRegionInTargetSurface.bounds(); + + if (hasOcclusionFromOutsideTargetSurface) { + // Check if the unoccluded rect shrank when applying outside occlusion. + *hasOcclusionFromOutsideTargetSurface = !gfx::SubtractRects(unoccludedRectInTargetSurfaceWithoutOutsideOcclusion, unoccludedRectInTargetSurface).IsEmpty(); + } + } else { + unoccludedRectInTargetSurface = contentRectInTargetSurface; + if (hasOcclusionFromOutsideTargetSurface) + *hasOcclusionFromOutsideTargetSurface = false; } - if (hasOcclusionFromOutsideTargetSurface) - *hasOcclusionFromOutsideTargetSurface = (gfx::IntersectRects(unoccludedInScreen, unoccludedInTarget) != unoccludedInTarget); + gfx::Rect unoccludedRect = gfx::ToEnclosingRect(MathUtil::projectClippedRect(inverseDrawTransform, unoccludedRectInTargetSurface)); + unoccludedRect.Intersect(contentRect); - return gfx::IntersectRects(unoccludedInScreen, unoccludedInTarget); + return unoccludedRect; } template<typename LayerType, typename RenderSurfaceType> gfx::Rect OcclusionTrackerBase<LayerType, RenderSurfaceType>::layerClipRectInTarget(const LayerType* layer) const { - // FIXME: we could remove this helper function, but unit tests currently override this - // function, and they need to be verified/adjusted before this can be removed. + // TODO(danakj): Can we remove this use of drawableContentRect and just use the clipRect() and target surface contentRect? return layer->drawableContentRect(); } diff --git a/cc/occlusion_tracker.h b/cc/occlusion_tracker.h index 96df92e..260dddb 100644 --- a/cc/occlusion_tracker.h +++ b/cc/occlusion_tracker.h @@ -26,7 +26,7 @@ class RenderSurface; template<typename LayerType, typename RenderSurfaceType> class CC_EXPORT OcclusionTrackerBase { public: - OcclusionTrackerBase(gfx::Rect rootTargetRect, bool recordMetricsForFrame); + OcclusionTrackerBase(gfx::Rect screenSpaceClipRect, bool recordMetricsForFrame); ~OcclusionTrackerBase(); // Called at the beginning of each step in the LayerIterator's front-to-back traversal. @@ -47,7 +47,10 @@ public: OverdrawMetrics& overdrawMetrics() const { return *m_overdrawMetrics.get(); } // Gives the region of the screen that is not occluded by something opaque. - Region computeVisibleRegionInScreen() const { return SubtractRegions(m_rootTargetRect, m_stack.back().occlusionInScreen); } + Region computeVisibleRegionInScreen() const { + DCHECK(!m_stack.back().target->parent()); + return SubtractRegions(m_screenSpaceClipRect, m_stack.back().occlusionFromInsideTarget); + } void setMinimumTrackingSize(const gfx::Size& size) { m_minimumTrackingSize = size; } @@ -60,8 +63,8 @@ protected: StackObject() : target(0) { } StackObject(const LayerType* target) : target(target) { } const LayerType* target; - Region occlusionInScreen; - Region occlusionInTarget; + Region occlusionFromOutsideTarget; + Region occlusionFromInsideTarget; }; // The stack holds occluded regions for subtrees in the RenderSurfaceImpl-Layer tree, so that when we leave a subtree we may @@ -91,7 +94,7 @@ private: // Add the layer's occlusion to the tracked state. void markOccludedBehindLayer(const LayerType*); - gfx::Rect m_rootTargetRect; + gfx::Rect m_screenSpaceClipRect; scoped_ptr<OverdrawMetrics> m_overdrawMetrics; gfx::Size m_minimumTrackingSize; diff --git a/cc/occlusion_tracker_unittest.cc b/cc/occlusion_tracker_unittest.cc index 447945c..3aacde0 100644 --- a/cc/occlusion_tracker_unittest.cc +++ b/cc/occlusion_tracker_unittest.cc @@ -489,8 +489,8 @@ protected: this->visitLayer(layer, occlusion); this->enterLayer(parent, occlusion); - EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(), occlusion.occlusionInScreenSpace().ToString()); - EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(), occlusion.occlusionInTargetSurface().ToString()); + EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString()); + EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(), occlusion.occlusionFromInsideTarget().ToString()); EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(30, 30, 70, 70))); EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(29, 30, 70, 70))); @@ -539,8 +539,8 @@ protected: this->visitLayer(layer2, occlusion); this->enterLayer(layer1, occlusion); - EXPECT_EQ(gfx::Rect(20, 20, 50, 50).ToString(), occlusion.occlusionInScreenSpace().ToString()); - EXPECT_EQ(gfx::Rect(20, 20, 50, 50).ToString(), occlusion.occlusionInTargetSurface().ToString()); + EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString()); + EXPECT_EQ(gfx::Rect(20, 20, 50, 50).ToString(), occlusion.occlusionFromInsideTarget().ToString()); // This checks cases where the quads don't match their "containing" // layers, e.g. in terms of transforms or clip rect. This is typical for @@ -581,8 +581,8 @@ protected: this->visitLayer(layer, occlusion); this->enterLayer(parent, occlusion); - EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(), occlusion.occlusionInScreenSpace().ToString()); - EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(), occlusion.occlusionInTargetSurface().ToString()); + EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString()); + EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(), occlusion.occlusionFromInsideTarget().ToString()); EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(30, 30, 70, 70))); EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(29, 30, 70, 70))); @@ -631,8 +631,8 @@ protected: this->visitLayer(layer, occlusion); this->enterLayer(parent, occlusion); - EXPECT_EQ(gfx::Rect(50, 50, 50, 50).ToString(), occlusion.occlusionInScreenSpace().ToString()); - EXPECT_EQ(gfx::Rect(50, 50, 50, 50).ToString(), occlusion.occlusionInTargetSurface().ToString()); + EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString()); + EXPECT_EQ(gfx::Rect(50, 50, 50, 50).ToString(), occlusion.occlusionFromInsideTarget().ToString()); EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(50, 50, 50, 50))); EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(49, 50, 50, 50))); @@ -698,14 +698,14 @@ protected: this->visitLayer(layer, occlusion); this->enterContributingSurface(child, occlusion); - EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(), occlusion.occlusionInScreenSpace().ToString()); - EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(), occlusion.occlusionInTargetSurface().ToString()); + EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString()); + EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(), occlusion.occlusionFromInsideTarget().ToString()); this->leaveContributingSurface(child, occlusion); this->enterLayer(parent, occlusion); - EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(), occlusion.occlusionInScreenSpace().ToString()); - EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(), occlusion.occlusionInTargetSurface().ToString()); + EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString()); + EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(), occlusion.occlusionFromInsideTarget().ToString()); EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(30, 40, 70, 60))); EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(29, 40, 70, 60))); @@ -776,8 +776,8 @@ protected: this->visitLayer(occluder, occlusion); this->enterLayer(layer2, occlusion); - EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(), occlusion.occlusionInScreenSpace().ToString()); - EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionInTargetSurface().ToString()); + EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(), occlusion.occlusionFromOutsideTarget().ToString()); + EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromInsideTarget().ToString()); EXPECT_RECT_EQ(gfx::Rect(0, 0, 25, 25), occlusion.unoccludedLayerContentRect(layer2, gfx::Rect(0, 0, 25, 25))); EXPECT_RECT_EQ(gfx::Rect(10, 25, 15, 25), occlusion.unoccludedLayerContentRect(layer2, gfx::Rect(10, 25, 25, 25))); @@ -814,25 +814,25 @@ protected: this->visitLayer(child2, occlusion); - EXPECT_EQ(gfx::Rect(30, 30, 60, 20).ToString(), occlusion.occlusionInScreenSpace().ToString()); - EXPECT_EQ(gfx::Rect(30, 30, 60, 20).ToString(), occlusion.occlusionInTargetSurface().ToString()); + EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString()); + EXPECT_EQ(gfx::Rect(30, 30, 60, 20).ToString(), occlusion.occlusionFromInsideTarget().ToString()); this->visitLayer(layer, occlusion); - EXPECT_EQ(UnionRegions(gfx::Rect(30, 30, 60, 10), gfx::Rect(30, 40, 70, 60)).ToString(), occlusion.occlusionInScreenSpace().ToString()); - EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(), occlusion.occlusionInTargetSurface().ToString()); + EXPECT_EQ(gfx::Rect(0, 440, 20, 60).ToString(), occlusion.occlusionFromOutsideTarget().ToString()); + EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(), occlusion.occlusionFromInsideTarget().ToString()); this->enterContributingSurface(child, occlusion); - EXPECT_EQ(UnionRegions(gfx::Rect(30, 30, 60, 10), gfx::Rect(30, 40, 70, 60)).ToString(), occlusion.occlusionInScreenSpace().ToString()); - EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(), occlusion.occlusionInTargetSurface().ToString()); + EXPECT_EQ(gfx::Rect(0, 440, 20, 60).ToString(), occlusion.occlusionFromOutsideTarget().ToString()); + EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(), occlusion.occlusionFromInsideTarget().ToString()); // Occlusion in |child2| should get merged with the |child| surface we are leaving now. this->leaveContributingSurface(child, occlusion); this->enterLayer(parent, occlusion); - EXPECT_EQ(UnionRegions(gfx::Rect(30, 30, 60, 10), gfx::Rect(30, 40, 70, 60)).ToString(), occlusion.occlusionInScreenSpace().ToString()); - EXPECT_EQ(UnionRegions(gfx::Rect(30, 30, 60, 10), gfx::Rect(30, 40, 70, 60)).ToString(), occlusion.occlusionInTargetSurface().ToString()); + EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString()); + EXPECT_EQ(UnionRegions(gfx::Rect(30, 30, 60, 10), gfx::Rect(30, 40, 70, 60)).ToString(), occlusion.occlusionFromInsideTarget().ToString()); EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(30, 30, 70, 70))); EXPECT_RECT_EQ(gfx::Rect(90, 30, 10, 10), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(30, 30, 70, 70))); @@ -921,8 +921,8 @@ protected: this->visitLayer(layer, occlusion); this->enterContributingSurface(child, occlusion); - EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionInScreenSpace().ToString()); - EXPECT_EQ(clippedLayerInChild.ToString(), occlusion.occlusionInTargetSurface().ToString()); + EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString()); + EXPECT_EQ(clippedLayerInChild.ToString(), occlusion.occlusionFromInsideTarget().ToString()); EXPECT_TRUE(occlusion.occludedLayer(child, clippedLayerInChild)); EXPECT_TRUE(occlusion.unoccludedLayerContentRect(child, clippedLayerInChild).IsEmpty()); @@ -946,8 +946,8 @@ protected: this->leaveContributingSurface(child, occlusion); this->enterLayer(parent, occlusion); - EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionInScreenSpace().ToString()); - EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionInTargetSurface().ToString()); + EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString()); + EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromInsideTarget().ToString()); EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(75, 55, 1, 1))); EXPECT_RECT_EQ(gfx::Rect(75, 55, 1, 1), occlusion.unoccludedLayerContentRect(parent, gfx::Rect(75, 55, 1, 1))); @@ -982,8 +982,8 @@ protected: this->visitLayer(layer1, occlusion); this->enterContributingSurface(child, occlusion); - EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(), occlusion.occlusionInScreenSpace().ToString()); - EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(), occlusion.occlusionInTargetSurface().ToString()); + EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString()); + EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(), occlusion.occlusionFromInsideTarget().ToString()); EXPECT_TRUE(occlusion.occludedLayer(child, gfx::Rect(10, 430, 60, 70))); EXPECT_FALSE(occlusion.occludedLayer(child, gfx::Rect(9, 430, 60, 70))); @@ -1000,8 +1000,8 @@ protected: this->leaveContributingSurface(child, occlusion); this->enterLayer(parent, occlusion); - EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(), occlusion.occlusionInScreenSpace().ToString()); - EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(), occlusion.occlusionInTargetSurface().ToString()); + EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString()); + EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(), occlusion.occlusionFromInsideTarget().ToString()); EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(30, 40, 70, 60))); EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(29, 40, 70, 60))); @@ -1067,8 +1067,8 @@ protected: this->visitLayer(layer2, occlusion); this->enterContributingSurface(child2, occlusion); - EXPECT_EQ(gfx::Rect(20, 30, 80, 70).ToString(), occlusion.occlusionInScreenSpace().ToString()); - EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(), occlusion.occlusionInTargetSurface().ToString()); + EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString()); + EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(), occlusion.occlusionFromInsideTarget().ToString()); EXPECT_TRUE(occlusion.occludedLayer(child2, gfx::Rect(-10, 420, 70, 80))); EXPECT_FALSE(occlusion.occludedLayer(child2, gfx::Rect(-11, 420, 70, 80))); @@ -1091,8 +1091,8 @@ protected: this->visitLayer(layer1, occlusion); this->enterContributingSurface(child1, occlusion); - EXPECT_EQ(UnionRegions(gfx::Rect(30, 20, 70, 10), gfx::Rect(20, 30, 80, 70)).ToString(), occlusion.occlusionInScreenSpace().ToString()); - EXPECT_EQ(gfx::Rect(-10, 430, 80, 70).ToString(), occlusion.occlusionInTargetSurface().ToString()); + EXPECT_EQ(gfx::Rect(0, 430, 70, 80).ToString(), occlusion.occlusionFromOutsideTarget().ToString()); + EXPECT_EQ(gfx::Rect(-10, 430, 80, 70).ToString(), occlusion.occlusionFromInsideTarget().ToString()); EXPECT_TRUE(occlusion.occludedLayer(child1, gfx::Rect(-10, 430, 80, 70))); EXPECT_FALSE(occlusion.occludedLayer(child1, gfx::Rect(-11, 430, 80, 70))); @@ -1106,8 +1106,8 @@ protected: this->leaveContributingSurface(child1, occlusion); this->enterLayer(parent, occlusion); - EXPECT_EQ(UnionRegions(gfx::Rect(30, 20, 70, 10), gfx::Rect(20, 30, 80, 70)).ToString(), occlusion.occlusionInScreenSpace().ToString()); - EXPECT_EQ(UnionRegions(gfx::Rect(30, 20, 70, 10), gfx::Rect(20, 30, 80, 70)).ToString(), occlusion.occlusionInTargetSurface().ToString()); + EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString()); + EXPECT_EQ(UnionRegions(gfx::Rect(30, 20, 70, 10), gfx::Rect(20, 30, 80, 70)).ToString(), occlusion.occlusionFromInsideTarget().ToString()); EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(20, 20, 80, 80))); @@ -1177,8 +1177,8 @@ protected: this->visitLayer(layer2, occlusion); this->enterLayer(child2, occlusion); - EXPECT_EQ(gfx::Rect(20, 30, 80, 70).ToString(), occlusion.occlusionInScreenSpace().ToString()); - EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(), occlusion.occlusionInTargetSurface().ToString()); + EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString()); + EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(), occlusion.occlusionFromInsideTarget().ToString()); EXPECT_TRUE(occlusion.occludedLayer(child2, gfx::Rect(-10, 420, 70, 80))); EXPECT_FALSE(occlusion.occludedLayer(child2, gfx::Rect(-11, 420, 70, 80))); @@ -1196,8 +1196,8 @@ protected: this->visitLayer(layer1, occlusion); this->enterContributingSurface(child1, occlusion); - EXPECT_EQ(gfx::Rect(10, 20, 90, 80).ToString(), occlusion.occlusionInScreenSpace().ToString()); - EXPECT_EQ(gfx::Rect(420, -20, 80, 90).ToString(), occlusion.occlusionInTargetSurface().ToString()); + EXPECT_EQ(gfx::Rect(420, -10, 70, 80).ToString(), occlusion.occlusionFromOutsideTarget().ToString()); + EXPECT_EQ(gfx::Rect(420, -20, 80, 90).ToString(), occlusion.occlusionFromInsideTarget().ToString()); EXPECT_TRUE(occlusion.occludedLayer(child1, gfx::Rect(420, -20, 80, 90))); EXPECT_FALSE(occlusion.occludedLayer(child1, gfx::Rect(419, -20, 80, 90))); @@ -1213,8 +1213,8 @@ protected: this->leaveContributingSurface(child1, occlusion); this->enterLayer(parent, occlusion); - EXPECT_EQ(gfx::Rect(10, 20, 90, 80).ToString(), occlusion.occlusionInScreenSpace().ToString()); - EXPECT_EQ(gfx::Rect(10, 20, 90, 80).ToString(), occlusion.occlusionInTargetSurface().ToString()); + EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString()); + EXPECT_EQ(gfx::Rect(10, 20, 90, 80).ToString(), occlusion.occlusionFromInsideTarget().ToString()); EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(10, 20, 90, 80))); EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(9, 20, 90, 80))); @@ -1288,42 +1288,42 @@ protected: this->visitLayer(opacityLayer, occlusion); this->enterContributingSurface(opacityLayer, occlusion); - EXPECT_TRUE(occlusion.occlusionInScreenSpace().IsEmpty()); - EXPECT_TRUE(occlusion.occlusionInTargetSurface().IsEmpty()); + EXPECT_TRUE(occlusion.occlusionFromOutsideTarget().IsEmpty()); + EXPECT_TRUE(occlusion.occlusionFromInsideTarget().IsEmpty()); // And has nothing to contribute to its parent surface. this->leaveContributingSurface(opacityLayer, occlusion); - EXPECT_TRUE(occlusion.occlusionInScreenSpace().IsEmpty()); - EXPECT_TRUE(occlusion.occlusionInTargetSurface().IsEmpty()); + EXPECT_TRUE(occlusion.occlusionFromOutsideTarget().IsEmpty()); + EXPECT_TRUE(occlusion.occlusionFromInsideTarget().IsEmpty()); // Opaque layer will contribute to occlusion. this->visitLayer(opaqueLayer, occlusion); this->enterContributingSurface(opaqueLayer, occlusion); - EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(), occlusion.occlusionInScreenSpace().ToString()); - EXPECT_EQ(gfx::Rect(0, 430, 70, 70).ToString(), occlusion.occlusionInTargetSurface().ToString()); + EXPECT_TRUE(occlusion.occlusionFromOutsideTarget().IsEmpty()); + EXPECT_EQ(gfx::Rect(0, 430, 70, 70).ToString(), occlusion.occlusionFromInsideTarget().ToString()); // And it gets translated to the parent surface. this->leaveContributingSurface(opaqueLayer, occlusion); - EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(), occlusion.occlusionInScreenSpace().ToString()); - EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(), occlusion.occlusionInTargetSurface().ToString()); + EXPECT_TRUE(occlusion.occlusionFromOutsideTarget().IsEmpty()); + EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(), occlusion.occlusionFromInsideTarget().ToString()); // The blur layer needs to throw away any occlusion from outside its subtree. this->enterLayer(blurLayer, occlusion); - EXPECT_TRUE(occlusion.occlusionInScreenSpace().IsEmpty()); - EXPECT_TRUE(occlusion.occlusionInTargetSurface().IsEmpty()); + EXPECT_TRUE(occlusion.occlusionFromOutsideTarget().IsEmpty()); + EXPECT_TRUE(occlusion.occlusionFromInsideTarget().IsEmpty()); // And it won't contribute to occlusion. this->leaveLayer(blurLayer, occlusion); this->enterContributingSurface(blurLayer, occlusion); - EXPECT_TRUE(occlusion.occlusionInScreenSpace().IsEmpty()); - EXPECT_TRUE(occlusion.occlusionInTargetSurface().IsEmpty()); + EXPECT_TRUE(occlusion.occlusionFromOutsideTarget().IsEmpty()); + EXPECT_TRUE(occlusion.occlusionFromInsideTarget().IsEmpty()); // But the opaque layer's occlusion is preserved on the parent. this->leaveContributingSurface(blurLayer, occlusion); this->enterLayer(parent, occlusion); - EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(), occlusion.occlusionInScreenSpace().ToString()); - EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(), occlusion.occlusionInTargetSurface().ToString()); + EXPECT_TRUE(occlusion.occlusionFromOutsideTarget().IsEmpty()); + EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(), occlusion.occlusionFromInsideTarget().ToString()); } }; @@ -1345,14 +1345,13 @@ protected: this->visitLayer(surface, occlusion); - EXPECT_EQ(gfx::Rect(0, 100, 50, 50).ToString(), occlusion.occlusionInScreenSpace().ToString()); - EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(), occlusion.occlusionInTargetSurface().ToString()); + EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(), occlusion.occlusionFromInsideTarget().ToString()); this->visitContributingSurface(surface, occlusion); this->enterLayer(parent, occlusion); // The surface and replica should both be occluding the parent. - EXPECT_EQ(UnionRegions(gfx::Rect(0, 100, 50, 50), gfx::Rect(50, 150, 50, 50)).ToString(), occlusion.occlusionInTargetSurface().ToString()); + EXPECT_EQ(UnionRegions(gfx::Rect(0, 100, 50, 50), gfx::Rect(50, 150, 50, 50)).ToString(), occlusion.occlusionFromInsideTarget().ToString()); } }; @@ -1375,14 +1374,13 @@ protected: this->visitLayer(surface, occlusion); - EXPECT_EQ(gfx::Rect(0, 100, 50, 50).ToString(), occlusion.occlusionInScreenSpace().ToString()); - EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(), occlusion.occlusionInTargetSurface().ToString()); + EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(), occlusion.occlusionFromInsideTarget().ToString()); this->visitContributingSurface(surface, occlusion); this->enterLayer(parent, occlusion); // The surface and replica should both be occluding the parent. - EXPECT_EQ(UnionRegions(gfx::Rect(0, 100, 50, 50), gfx::Rect(50, 150, 50, 20)).ToString(), occlusion.occlusionInTargetSurface().ToString()); + EXPECT_EQ(UnionRegions(gfx::Rect(0, 100, 50, 50), gfx::Rect(50, 150, 50, 20)).ToString(), occlusion.occlusionFromInsideTarget().ToString()); } }; @@ -1405,14 +1403,13 @@ protected: this->visitLayer(surface, occlusion); - EXPECT_EQ(gfx::Rect(0, 100, 50, 50).ToString(), occlusion.occlusionInScreenSpace().ToString()); - EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(), occlusion.occlusionInTargetSurface().ToString()); + EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(), occlusion.occlusionFromInsideTarget().ToString()); this->visitContributingSurface(surface, occlusion); this->enterLayer(parent, occlusion); // The replica should not be occluding the parent, since it has a mask applied to it. - EXPECT_EQ(gfx::Rect(0, 100, 50, 50).ToString(), occlusion.occlusionInTargetSurface().ToString()); + EXPECT_EQ(gfx::Rect(0, 100, 50, 50).ToString(), occlusion.occlusionFromInsideTarget().ToString()); } }; @@ -1819,7 +1816,7 @@ protected: this->visitContributingSurface(layer, occlusion); this->enterLayer(parent, occlusion); - EXPECT_TRUE(occlusion.occlusionInScreenSpace().IsEmpty()); + EXPECT_TRUE(occlusion.occlusionFromOutsideTarget().IsEmpty()); } }; @@ -1843,7 +1840,7 @@ protected: this->visitLayer(layer, occlusion); this->enterLayer(parent, occlusion); - EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(), occlusion.occlusionInScreenSpace().ToString()); + EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(), occlusion.occlusionFromInsideTarget().ToString()); EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(0, 100, 100, 100))); EXPECT_TRUE(occlusion.occludedLayer(parent, gfx::Rect(100, 100, 100, 100))); @@ -1858,7 +1855,7 @@ protected: this->visitLayer(layer, occlusion); this->enterLayer(parent, occlusion); - EXPECT_EQ(gfx::Rect(120, 120, 180, 180).ToString(), occlusion.occlusionInScreenSpace().ToString()); + EXPECT_EQ(gfx::Rect(120, 120, 180, 180).ToString(), occlusion.occlusionFromInsideTarget().ToString()); EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(0, 100, 100, 100))); EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(100, 100, 100, 100))); @@ -1873,7 +1870,7 @@ protected: this->visitLayer(layer, occlusion); this->enterLayer(parent, occlusion); - EXPECT_EQ(gfx::Rect(250, 250, 50, 50).ToString(), occlusion.occlusionInScreenSpace().ToString()); + EXPECT_EQ(gfx::Rect(250, 250, 50, 50).ToString(), occlusion.occlusionFromInsideTarget().ToString()); EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(0, 100, 100, 100))); EXPECT_FALSE(occlusion.occludedLayer(parent, gfx::Rect(100, 100, 100, 100))); @@ -1935,12 +1932,12 @@ protected: TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000)); this->visitLayer(child2, occlusion); - EXPECT_TRUE(occlusion.occlusionInScreenSpace().IsEmpty()); - EXPECT_TRUE(occlusion.occlusionInTargetSurface().IsEmpty()); + EXPECT_TRUE(occlusion.occlusionFromOutsideTarget().IsEmpty()); + EXPECT_TRUE(occlusion.occlusionFromInsideTarget().IsEmpty()); this->visitLayer(child1, occlusion); - EXPECT_TRUE(occlusion.occlusionInScreenSpace().IsEmpty()); - EXPECT_TRUE(occlusion.occlusionInTargetSurface().IsEmpty()); + EXPECT_TRUE(occlusion.occlusionFromOutsideTarget().IsEmpty()); + EXPECT_TRUE(occlusion.occlusionFromInsideTarget().IsEmpty()); } }; @@ -2033,8 +2030,8 @@ protected: // The |layer| is entirely behind the camera and should not occlude. this->visitLayer(layer, occlusion); this->enterLayer(parent, occlusion); - EXPECT_TRUE(occlusion.occlusionInTargetSurface().IsEmpty()); - EXPECT_TRUE(occlusion.occlusionInScreenSpace().IsEmpty()); + EXPECT_TRUE(occlusion.occlusionFromInsideTarget().IsEmpty()); + EXPECT_TRUE(occlusion.occlusionFromOutsideTarget().IsEmpty()); } }; @@ -2066,8 +2063,8 @@ protected: // Ensure that those pixels don't occlude things outside the clipRect. this->visitLayer(layer, occlusion); this->enterLayer(parent, occlusion); - EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), occlusion.occlusionInTargetSurface().ToString()); - EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), occlusion.occlusionInScreenSpace().ToString()); + EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), occlusion.occlusionFromInsideTarget().ToString()); + EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString()); } }; @@ -2213,39 +2210,40 @@ protected: this->visitLayer(surface2, occlusion); this->enterContributingSurface(surface2, occlusion); - EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(), occlusion.occlusionInScreenSpace().ToString()); + EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(), occlusion.occlusionFromInsideTarget().ToString()); this->leaveContributingSurface(surface2, occlusion); this->enterLayer(surfaceChild2, occlusion); // surfaceChild2 is moving in screen space but not relative to its target, so occlusion should happen in its target space only. - // It also means that things occluding in screen space (e.g. surface2) cannot occlude this layer. + // It also means that things occluding from outside the target (e.g. surface2) cannot occlude this layer. + EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString()); + EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 300), occlusion.unoccludedLayerContentRect(surfaceChild2, gfx::Rect(0, 0, 100, 300))); EXPECT_FALSE(occlusion.occludedLayer(surfaceChild, gfx::Rect(0, 0, 50, 300))); this->leaveLayer(surfaceChild2, occlusion); this->enterLayer(surfaceChild, occlusion); EXPECT_FALSE(occlusion.occludedLayer(surfaceChild, gfx::Rect(0, 0, 100, 300))); - EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(), occlusion.occlusionInScreenSpace().ToString()); - EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(), occlusion.occlusionInTargetSurface().ToString()); + EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString()); + EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(), occlusion.occlusionFromInsideTarget().ToString()); EXPECT_RECT_EQ(gfx::Rect(100, 0, 200, 300), occlusion.unoccludedLayerContentRect(surface, gfx::Rect(0, 0, 300, 300))); - // The surfaceChild is occluded by the surfaceChild2, but is moving relative its target and the screen, so it - // can't be occluded. + // The surfaceChild is occluded by the surfaceChild2, but is moving relative its target, so it can't be occluded. EXPECT_RECT_EQ(gfx::Rect(0, 0, 200, 300), occlusion.unoccludedLayerContentRect(surfaceChild, gfx::Rect(0, 0, 200, 300))); EXPECT_FALSE(occlusion.occludedLayer(surfaceChild, gfx::Rect(0, 0, 50, 300))); this->leaveLayer(surfaceChild, occlusion); this->enterLayer(surface, occlusion); - // The surfaceChild is moving in screen space but not relative to its target, so occlusion should happen in its target space only. - EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(), occlusion.occlusionInScreenSpace().ToString()); - EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(), occlusion.occlusionInTargetSurface().ToString()); + // The surfaceChild is moving in screen space but not relative to its target, so occlusion should happen from within the target only. + EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString()); + EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(), occlusion.occlusionFromInsideTarget().ToString()); EXPECT_RECT_EQ(gfx::Rect(100, 0, 200, 300), occlusion.unoccludedLayerContentRect(surface, gfx::Rect(0, 0, 300, 300))); this->leaveLayer(surface, occlusion); - // The surface's owning layer is moving in screen space but not relative to its target, so occlusion should happen in its target space only. - EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(), occlusion.occlusionInScreenSpace().ToString()); - EXPECT_EQ(gfx::Rect(0, 0, 300, 300).ToString(), occlusion.occlusionInTargetSurface().ToString()); + // The surface's owning layer is moving in screen space but not relative to its target, so occlusion should happen within the target only. + EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString()); + EXPECT_EQ(gfx::Rect(0, 0, 300, 300).ToString(), occlusion.occlusionFromInsideTarget().ToString()); EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0), occlusion.unoccludedLayerContentRect(surface, gfx::Rect(0, 0, 300, 300))); this->enterContributingSurface(surface, occlusion); @@ -2289,18 +2287,18 @@ protected: this->visitLayer(surface2, occlusion); this->visitContributingSurface(surface2, occlusion); - EXPECT_EQ(gfx::Rect(50, 50, 200, 200).ToString(), occlusion.occlusionInScreenSpace().ToString()); - EXPECT_EQ(gfx::Rect(50, 50, 200, 200).ToString(), occlusion.occlusionInTargetSurface().ToString()); + EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString()); + EXPECT_EQ(gfx::Rect(50, 50, 200, 200).ToString(), occlusion.occlusionFromInsideTarget().ToString()); // Clear any stored occlusion. - occlusion.setOcclusionInScreenSpace(Region()); - occlusion.setOcclusionInTargetSurface(Region()); + occlusion.setOcclusionFromOutsideTarget(Region()); + occlusion.setOcclusionFromInsideTarget(Region()); this->visitLayer(surface, occlusion); this->visitContributingSurface(surface, occlusion); - EXPECT_EQ(gfx::Rect(0, 0, 400, 400).ToString(), occlusion.occlusionInScreenSpace().ToString()); - EXPECT_EQ(gfx::Rect(0, 0, 400, 400).ToString(), occlusion.occlusionInTargetSurface().ToString()); + EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString()); + EXPECT_EQ(gfx::Rect(0, 0, 400, 400).ToString(), occlusion.occlusionFromInsideTarget().ToString()); } }; @@ -2323,8 +2321,8 @@ protected: this->visitLayer(surface, occlusion); this->visitContributingSurface(surface, occlusion); - EXPECT_EQ(gfx::Rect(0, 0, 300, 200).ToString(), occlusion.occlusionInScreenSpace().ToString()); - EXPECT_EQ(gfx::Rect(0, 0, 300, 200).ToString(), occlusion.occlusionInTargetSurface().ToString()); + EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString()); + EXPECT_EQ(gfx::Rect(0, 0, 300, 200).ToString(), occlusion.occlusionFromInsideTarget().ToString()); } }; @@ -2348,13 +2346,13 @@ protected: // |topmost| occludes the replica, but not the surface itself. this->visitLayer(topmost, occlusion); - EXPECT_EQ(gfx::Rect(0, 100, 100, 100).ToString(), occlusion.occlusionInScreenSpace().ToString()); - EXPECT_EQ(gfx::Rect(0, 100, 100, 100).ToString(), occlusion.occlusionInTargetSurface().ToString()); + EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString()); + EXPECT_EQ(gfx::Rect(0, 100, 100, 100).ToString(), occlusion.occlusionFromInsideTarget().ToString()); this->visitLayer(surface, occlusion); - EXPECT_EQ(gfx::Rect(0, 0, 100, 200).ToString(), occlusion.occlusionInScreenSpace().ToString()); - EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), occlusion.occlusionInTargetSurface().ToString()); + EXPECT_EQ(gfx::Rect(0, 100, 100, 100).ToString(), occlusion.occlusionFromOutsideTarget().ToString()); + EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), occlusion.occlusionFromInsideTarget().ToString()); this->enterContributingSurface(surface, occlusion); @@ -2383,13 +2381,13 @@ protected: // |topmost| occludes the surface, but not the entire surface's replica. this->visitLayer(topmost, occlusion); - EXPECT_EQ(gfx::Rect(0, 0, 100, 110).ToString(), occlusion.occlusionInScreenSpace().ToString()); - EXPECT_EQ(gfx::Rect(0, 0, 100, 110).ToString(), occlusion.occlusionInTargetSurface().ToString()); + EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString()); + EXPECT_EQ(gfx::Rect(0, 0, 100, 110).ToString(), occlusion.occlusionFromInsideTarget().ToString()); this->visitLayer(surface, occlusion); - EXPECT_EQ(gfx::Rect(0, 0, 100, 110).ToString(), occlusion.occlusionInScreenSpace().ToString()); - EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), occlusion.occlusionInTargetSurface().ToString()); + EXPECT_EQ(gfx::Rect(0, 0, 100, 110).ToString(), occlusion.occlusionFromOutsideTarget().ToString()); + EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), occlusion.occlusionFromInsideTarget().ToString()); this->enterContributingSurface(surface, occlusion); @@ -2421,13 +2419,13 @@ protected: this->visitLayer(overReplica, occlusion); this->visitLayer(overSurface, occlusion); - EXPECT_EQ(UnionRegions(gfx::Rect(0, 0, 40, 100), gfx::Rect(0, 100, 50, 100)).ToString(), occlusion.occlusionInScreenSpace().ToString()); - EXPECT_EQ(UnionRegions(gfx::Rect(0, 0, 40, 100), gfx::Rect(0, 100, 50, 100)).ToString(), occlusion.occlusionInTargetSurface().ToString()); + EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString()); + EXPECT_EQ(UnionRegions(gfx::Rect(0, 0, 40, 100), gfx::Rect(0, 100, 50, 100)).ToString(), occlusion.occlusionFromInsideTarget().ToString()); this->visitLayer(surface, occlusion); - EXPECT_EQ(UnionRegions(gfx::Rect(0, 0, 100, 100), gfx::Rect(0, 100, 50, 100)).ToString(), occlusion.occlusionInScreenSpace().ToString()); - EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), occlusion.occlusionInTargetSurface().ToString()); + EXPECT_EQ(UnionRegions(gfx::Rect(0, 0, 40, 100), gfx::Rect(0, 100, 50, 100)).ToString(), occlusion.occlusionFromOutsideTarget().ToString()); + EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), occlusion.occlusionFromInsideTarget().ToString()); this->enterContributingSurface(surface, occlusion); @@ -2458,15 +2456,15 @@ protected: // |topmost| occludes everything partially so we know occlusion is happening at all. this->visitLayer(topmost, occlusion); - EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(), occlusion.occlusionInScreenSpace().ToString()); - EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(), occlusion.occlusionInTargetSurface().ToString()); + EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString()); + EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(), occlusion.occlusionFromInsideTarget().ToString()); this->visitLayer(surfaceChild, occlusion); // surfaceChild increases the occlusion in the screen by a narrow sliver. - EXPECT_EQ(gfx::Rect(0, 0, 100, 60).ToString(), occlusion.occlusionInScreenSpace().ToString()); + EXPECT_EQ(gfx::Rect(0, -10, 100, 50).ToString(), occlusion.occlusionFromOutsideTarget().ToString()); // In its own surface, surfaceChild is at 0,0 as is its occlusion. - EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(), occlusion.occlusionInTargetSurface().ToString()); + EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(), occlusion.occlusionFromInsideTarget().ToString()); // The root layer always has a clipRect. So the parent of |surface| has a clipRect. However, the owning layer for |surface| does not // mask to bounds, so it doesn't have a clipRect of its own. Thus the parent of |surfaceChild| exercises different code paths @@ -2480,8 +2478,8 @@ protected: // When the surfaceChild's occlusion is transformed up to its parent, make sure it is not clipped away inappropriately also. this->enterLayer(surface, occlusion); - EXPECT_EQ(gfx::Rect(0, 0, 100, 60).ToString(), occlusion.occlusionInScreenSpace().ToString()); - EXPECT_EQ(gfx::Rect(0, 10, 100, 50).ToString(), occlusion.occlusionInTargetSurface().ToString()); + EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(), occlusion.occlusionFromOutsideTarget().ToString()); + EXPECT_EQ(gfx::Rect(0, 10, 100, 50).ToString(), occlusion.occlusionFromInsideTarget().ToString()); this->leaveLayer(surface, occlusion); this->enterContributingSurface(surface, occlusion); @@ -2553,14 +2551,14 @@ protected: // |topmost| occludes everything partially so we know occlusion is happening at all. this->visitLayer(topmost, occlusion); - EXPECT_EQ(gfx::Rect(0, 0, 80, 50).ToString(), occlusion.occlusionInScreenSpace().ToString()); - EXPECT_EQ(gfx::Rect(0, 0, 80, 50).ToString(), occlusion.occlusionInTargetSurface().ToString()); + EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString()); + EXPECT_EQ(gfx::Rect(0, 0, 80, 50).ToString(), occlusion.occlusionFromInsideTarget().ToString()); // surfaceChild is not opaque and does not occlude, so we have a non-empty unoccluded area on surface. this->visitLayer(surfaceChild, occlusion); - EXPECT_EQ(gfx::Rect(0, 0, 80, 50).ToString(), occlusion.occlusionInScreenSpace().ToString()); - EXPECT_EQ(gfx::Rect(0, 0, 0, 0).ToString(), occlusion.occlusionInTargetSurface().ToString()); + EXPECT_EQ(gfx::Rect(0, 0, 80, 50).ToString(), occlusion.occlusionFromOutsideTarget().ToString()); + EXPECT_EQ(gfx::Rect(0, 0, 0, 0).ToString(), occlusion.occlusionFromInsideTarget().ToString()); // The root layer always has a clipRect. So the parent of |surface| has a clipRect. However, the owning layer for |surface| does not // mask to bounds, so it doesn't have a clipRect of its own. Thus the parent of |surfaceChild| exercises different code paths @@ -2568,13 +2566,13 @@ protected: this->enterContributingSurface(surfaceChild, occlusion); // The surfaceChild's parent does not have a clipRect as it owns a render surface. - EXPECT_RECT_EQ(gfx::Rect(0, 50, 80, 50), occlusion.unoccludedContributingSurfaceContentRect(surfaceChild, false, gfx::Rect(0, 0, 100, 100))); + EXPECT_EQ(gfx::Rect(0, 50, 80, 50).ToString(), occlusion.unoccludedContributingSurfaceContentRect(surfaceChild, false, gfx::Rect(0, 0, 100, 100)).ToString()); this->leaveContributingSurface(surfaceChild, occlusion); this->visitLayer(surface, occlusion); this->enterContributingSurface(surface, occlusion); // The surface's parent does have a clipRect as it is the root layer. - EXPECT_RECT_EQ(gfx::Rect(0, 50, 80, 50), occlusion.unoccludedContributingSurfaceContentRect(surface, false, gfx::Rect(0, 0, 100, 100))); + EXPECT_EQ(gfx::Rect(0, 50, 80, 50).ToString(), occlusion.unoccludedContributingSurfaceContentRect(surface, false, gfx::Rect(0, 0, 100, 100)).ToString()); } }; @@ -2630,8 +2628,8 @@ protected: expectedOcclusion.Union(gfx::Rect(250, 50, 50, 50)); expectedOcclusion.Union(gfx::Rect(0, 100, 300, 50)); - EXPECT_EQ(expectedOcclusion.ToString(), occlusion.occlusionInScreenSpace().ToString()); - EXPECT_EQ(expectedOcclusion.ToString(), occlusion.occlusionInTargetSurface().ToString()); + EXPECT_EQ(expectedOcclusion.ToString(), occlusion.occlusionFromInsideTarget().ToString()); + EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString()); // Everything outside the surface/replica is occluded but the surface/replica itself is not. this->enterLayer(filteredSurface, occlusion); @@ -2647,8 +2645,15 @@ protected: this->leaveLayer(filteredSurface, occlusion); // The filtered layer/replica does not occlude. - EXPECT_EQ(expectedOcclusion.ToString(), occlusion.occlusionInScreenSpace().ToString()); - EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionInTargetSurface().ToString()); + Region expectedOcclusionOutsideSurface; + expectedOcclusionOutsideSurface.Union(gfx::Rect(-50, -50, 300, 50)); + expectedOcclusionOutsideSurface.Union(gfx::Rect(-50, 0, 50, 50)); + expectedOcclusionOutsideSurface.Union(gfx::Rect(50, 0, 100, 50)); + expectedOcclusionOutsideSurface.Union(gfx::Rect(200, 0, 50, 50)); + expectedOcclusionOutsideSurface.Union(gfx::Rect(-50, 50, 300, 50)); + + EXPECT_EQ(expectedOcclusionOutsideSurface.ToString(), occlusion.occlusionFromOutsideTarget().ToString()); + EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromInsideTarget().ToString()); // The surface has a background blur, so it needs pixels that are currently considered occluded in order to be drawn. So the pixels // it needs should be removed some the occluded area so that when we get to the parent they are drawn. @@ -2663,8 +2668,8 @@ protected: expectedBlurredOcclusion.Union(gfx::Rect(250 + outsetRight, 50 - outsetTop, 50 - outsetRight, 50 + outsetTop + outsetBottom)); expectedBlurredOcclusion.Union(gfx::Rect(0, 100 + outsetBottom, 300, 50 - outsetBottom)); - EXPECT_EQ(expectedBlurredOcclusion.ToString(), occlusion.occlusionInScreenSpace().ToString()); - EXPECT_EQ(expectedBlurredOcclusion.ToString(), occlusion.occlusionInTargetSurface().ToString()); + EXPECT_EQ(expectedBlurredOcclusion.ToString(), occlusion.occlusionFromInsideTarget().ToString()); + EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString()); gfx::Rect outsetRect; gfx::Rect testRect; @@ -2672,40 +2677,40 @@ protected: // Nothing in the blur outsets for the filteredSurface is occluded. outsetRect = gfx::Rect(50 - outsetLeft, 50 - outsetTop, 50 + outsetLeft + outsetRight, 50 + outsetTop + outsetBottom); testRect = outsetRect; - EXPECT_RECT_EQ(outsetRect, occlusion.unoccludedLayerContentRect(parent, testRect)); + EXPECT_EQ(outsetRect.ToString(), occlusion.unoccludedLayerContentRect(parent, testRect).ToString()); // Stuff outside the blur outsets is still occluded though. testRect = outsetRect; testRect.Inset(0, 0, -1, 0); - EXPECT_RECT_EQ(outsetRect, occlusion.unoccludedLayerContentRect(parent, testRect)); + EXPECT_EQ(outsetRect.ToString(), occlusion.unoccludedLayerContentRect(parent, testRect).ToString()); testRect = outsetRect; testRect.Inset(0, 0, 0, -1); - EXPECT_RECT_EQ(outsetRect, occlusion.unoccludedLayerContentRect(parent, testRect)); + EXPECT_EQ(outsetRect.ToString(), occlusion.unoccludedLayerContentRect(parent, testRect).ToString()); testRect = outsetRect; testRect.Inset(-1, 0, 0, 0); - EXPECT_RECT_EQ(outsetRect, occlusion.unoccludedLayerContentRect(parent, testRect)); + EXPECT_EQ(outsetRect.ToString(), occlusion.unoccludedLayerContentRect(parent, testRect).ToString()); testRect = outsetRect; testRect.Inset(0, -1, 0, 0); - EXPECT_RECT_EQ(outsetRect, occlusion.unoccludedLayerContentRect(parent, testRect)); + EXPECT_EQ(outsetRect.ToString(), occlusion.unoccludedLayerContentRect(parent, testRect).ToString()); // Nothing in the blur outsets for the filteredSurface's replica is occluded. outsetRect = gfx::Rect(200 - outsetLeft, 50 - outsetTop, 50 + outsetLeft + outsetRight, 50 + outsetTop + outsetBottom); testRect = outsetRect; - EXPECT_RECT_EQ(outsetRect, occlusion.unoccludedLayerContentRect(parent, testRect)); + EXPECT_EQ(outsetRect.ToString(), occlusion.unoccludedLayerContentRect(parent, testRect).ToString()); // Stuff outside the blur outsets is still occluded though. testRect = outsetRect; testRect.Inset(0, 0, -1, 0); - EXPECT_RECT_EQ(outsetRect, occlusion.unoccludedLayerContentRect(parent, testRect)); + EXPECT_EQ(outsetRect.ToString(), occlusion.unoccludedLayerContentRect(parent, testRect).ToString()); testRect = outsetRect; testRect.Inset(0, 0, 0, -1); - EXPECT_RECT_EQ(outsetRect, occlusion.unoccludedLayerContentRect(parent, testRect)); + EXPECT_EQ(outsetRect.ToString(), occlusion.unoccludedLayerContentRect(parent, testRect).ToString()); testRect = outsetRect; testRect.Inset(-1, 0, 0, 0); - EXPECT_RECT_EQ(outsetRect, occlusion.unoccludedLayerContentRect(parent, testRect)); + EXPECT_EQ(outsetRect.ToString(), occlusion.unoccludedLayerContentRect(parent, testRect).ToString()); testRect = outsetRect; testRect.Inset(0, -1, 0, 0); - EXPECT_RECT_EQ(outsetRect, occlusion.unoccludedLayerContentRect(parent, testRect)); + EXPECT_EQ(outsetRect.ToString(), occlusion.unoccludedLayerContentRect(parent, testRect).ToString()); } }; @@ -2744,8 +2749,8 @@ protected: occlusion.setLayerClipRect(gfx::Rect(0, 0, 1000, 1000)); this->visitLayer(occludingLayerAbove, occlusion); - EXPECT_EQ(gfx::Rect(100 / 2, 100 / 2, 50 / 2, 50 / 2).ToString(), occlusion.occlusionInScreenSpace().ToString()); - EXPECT_EQ(gfx::Rect(100 / 2, 100 / 2, 50 / 2, 50 / 2).ToString(), occlusion.occlusionInTargetSurface().ToString()); + EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString()); + EXPECT_EQ(gfx::Rect(100 / 2, 100 / 2, 50 / 2, 50 / 2).ToString(), occlusion.occlusionFromInsideTarget().ToString()); this->visitLayer(filteredSurface2, occlusion); this->visitContributingSurface(filteredSurface2, occlusion); @@ -2754,10 +2759,10 @@ protected: // Test expectations in the target. gfx::Rect expectedOcclusion = gfx::Rect(100 / 2 + outsetRight * 2, 100 / 2 + outsetBottom * 2, 50 / 2 - (outsetLeft + outsetRight) * 2, 50 / 2 - (outsetTop + outsetBottom) * 2); - EXPECT_EQ(expectedOcclusion.ToString(), occlusion.occlusionInTargetSurface().ToString()); + EXPECT_EQ(expectedOcclusion.ToString(), occlusion.occlusionFromInsideTarget().ToString()); // Test expectations in the screen are the same as in the target, as the render surface is 1:1 with the screen. - EXPECT_EQ(expectedOcclusion.ToString(), occlusion.occlusionInScreenSpace().ToString()); + EXPECT_EQ(expectedOcclusion.ToString(), occlusion.occlusionFromOutsideTarget().ToString()); } }; @@ -2812,8 +2817,8 @@ protected: expectedOcclusion.Union(gfx::Rect(250, 50, 50, 50)); expectedOcclusion.Union(gfx::Rect(0, 100, 300, 50)); - EXPECT_EQ(expectedOcclusion.ToString(), occlusion.occlusionInScreenSpace().ToString()); - EXPECT_EQ(expectedOcclusion.ToString(), occlusion.occlusionInTargetSurface().ToString()); + EXPECT_EQ(expectedOcclusion.ToString(), occlusion.occlusionFromInsideTarget().ToString()); + EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString()); // Everything outside the surface/replica is occluded but the surface/replica itself is not. this->enterLayer(filteredSurface, occlusion); @@ -2829,8 +2834,15 @@ protected: this->leaveLayer(filteredSurface, occlusion); // The filtered layer/replica does not occlude. - EXPECT_EQ(expectedOcclusion.ToString(), occlusion.occlusionInScreenSpace().ToString()); - EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionInTargetSurface().ToString()); + Region expectedOcclusionOutsideSurface; + expectedOcclusionOutsideSurface.Union(gfx::Rect(-50, -50, 300, 50)); + expectedOcclusionOutsideSurface.Union(gfx::Rect(-50, 0, 50, 50)); + expectedOcclusionOutsideSurface.Union(gfx::Rect(50, 0, 100, 50)); + expectedOcclusionOutsideSurface.Union(gfx::Rect(200, 0, 50, 50)); + expectedOcclusionOutsideSurface.Union(gfx::Rect(-50, 50, 300, 50)); + + EXPECT_EQ(expectedOcclusionOutsideSurface.ToString(), occlusion.occlusionFromOutsideTarget().ToString()); + EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromInsideTarget().ToString()); // The surface has a background blur, so it needs pixels that are currently considered occluded in order to be drawn. So the pixels // it needs should be removed some the occluded area so that when we get to the parent they are drawn. @@ -2845,8 +2857,8 @@ protected: expectedBlurredOcclusion.Union(gfx::Rect(250 + outsetRight, 50 - outsetTop, 50 - outsetRight, 20 + outsetTop + outsetBottom)); expectedBlurredOcclusion.Union(gfx::Rect(0, 100 + 5, 300, 50 - 5)); - EXPECT_EQ(expectedBlurredOcclusion.ToString(), occlusion.occlusionInScreenSpace().ToString()); - EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionInTargetSurface().ToString()); + EXPECT_EQ(expectedBlurredOcclusion.ToString(), occlusion.occlusionFromOutsideTarget().ToString()); + EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromInsideTarget().ToString()); gfx::Rect outsetRect; gfx::Rect clippedOutsetRect; @@ -2937,8 +2949,9 @@ protected: gfx::Rect occlusionBehindReplica = gfx::Rect(210, 60, 30, 30); Region expectedOpaqueBounds = UnionRegions(occlusionBehindSurface, occlusionBehindReplica); - EXPECT_EQ(expectedOpaqueBounds.ToString(), occlusion.occlusionInScreenSpace().ToString()); - EXPECT_EQ(expectedOpaqueBounds.ToString(), occlusion.occlusionInTargetSurface().ToString()); + EXPECT_EQ(expectedOpaqueBounds.ToString(), occlusion.occlusionFromInsideTarget().ToString()); + + EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString()); } }; @@ -2975,17 +2988,30 @@ protected: this->visitLayer(aboveReplicaLayer, occlusion); this->visitLayer(aboveSurfaceLayer, occlusion); - // The surface has a background blur, so it blurs non-opaque pixels below it. this->visitLayer(filteredSurface, occlusion); + + { + // The layers above the filtered surface occlude from outside. + gfx::Rect occlusionAboveSurface = gfx::Rect(0, 0, 50, 50); + gfx::Rect occlusionAboveReplica = gfx::Rect(150, 0, 50, 50); + Region expectedOpaqueRegion = UnionRegions(occlusionAboveSurface, occlusionAboveReplica); + + EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromInsideTarget().ToString()); + EXPECT_EQ(expectedOpaqueRegion.ToString(), occlusion.occlusionFromOutsideTarget().ToString()); + } + + // The surface has a background blur, so it blurs non-opaque pixels below it. this->visitContributingSurface(filteredSurface, occlusion); - // The filter is completely occluded, so it should not blur anything and reduce any occlusion. - gfx::Rect occlusionAboveSurface = gfx::Rect(50, 50, 50, 50); - gfx::Rect occlusionAboveReplica = gfx::Rect(200, 50, 50, 50); + { + // The filter is completely occluded, so it should not blur anything and reduce any occlusion. + gfx::Rect occlusionAboveSurface = gfx::Rect(50, 50, 50, 50); + gfx::Rect occlusionAboveReplica = gfx::Rect(200, 50, 50, 50); + Region expectedOpaqueRegion = UnionRegions(occlusionAboveSurface, occlusionAboveReplica); - Region expectedOpaqueRegion = UnionRegions(occlusionAboveSurface, occlusionAboveReplica); - EXPECT_EQ(expectedOpaqueRegion, occlusion.occlusionInScreenSpace()); - EXPECT_EQ(expectedOpaqueRegion, occlusion.occlusionInTargetSurface()); + EXPECT_EQ(expectedOpaqueRegion.ToString(), occlusion.occlusionFromInsideTarget().ToString()); + EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString()); + } } }; @@ -3049,16 +3075,13 @@ protected: expectedOcclusion.Union(occlusionBesideSurface); expectedOcclusion.Union(occlusionBesideReplica); - ASSERT_EQ(expectedOcclusion, occlusion.occlusionInTargetSurface()); - ASSERT_EQ(expectedOcclusion, occlusion.occlusionInScreenSpace()); + ASSERT_EQ(expectedOcclusion.ToString(), occlusion.occlusionFromInsideTarget().ToString()); + EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString()); Region::Iterator expectedRects(expectedOcclusion); - Region::Iterator screenSpaceRects(occlusion.occlusionInScreenSpace()); - Region::Iterator targetSurfaceRects(occlusion.occlusionInTargetSurface()); - for (; expectedRects.has_rect(); expectedRects.next(), screenSpaceRects.next(), targetSurfaceRects.next()) { - ASSERT_TRUE(screenSpaceRects.has_rect()); + Region::Iterator targetSurfaceRects(occlusion.occlusionFromInsideTarget()); + for (; expectedRects.has_rect(); expectedRects.next(), targetSurfaceRects.next()) { ASSERT_TRUE(targetSurfaceRects.has_rect()); - EXPECT_EQ(expectedRects.rect(), screenSpaceRects.rect()); EXPECT_EQ(expectedRects.rect(), targetSurfaceRects.rect()); } } @@ -3087,14 +3110,14 @@ protected: // The small layer is not tracked because it is too small. this->visitLayer(small, occlusion); - EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionInScreenSpace().ToString()); - EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionInTargetSurface().ToString()); + EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString()); + EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromInsideTarget().ToString()); // The large layer is tracked as it is large enough. this->visitLayer(large, occlusion); - EXPECT_EQ(gfx::Rect(gfx::Point(), trackingSize).ToString(), occlusion.occlusionInScreenSpace().ToString()); - EXPECT_EQ(gfx::Rect(gfx::Point(), trackingSize).ToString(), occlusion.occlusionInTargetSurface().ToString()); + EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusionFromOutsideTarget().ToString()); + EXPECT_EQ(gfx::Rect(gfx::Point(), trackingSize).ToString(), occlusion.occlusionFromInsideTarget().ToString()); } }; diff --git a/cc/test/occlusion_tracker_test_common.h b/cc/test/occlusion_tracker_test_common.h index 5a67ee5..866f2ae 100644 --- a/cc/test/occlusion_tracker_test_common.h +++ b/cc/test/occlusion_tracker_test_common.h @@ -20,11 +20,11 @@ public: { } - cc::Region occlusionInScreenSpace() const { return cc::OcclusionTrackerBase<LayerType, RenderSurfaceType>::m_stack.back().occlusionInScreen; } - cc::Region occlusionInTargetSurface() const { return cc::OcclusionTrackerBase<LayerType, RenderSurfaceType>::m_stack.back().occlusionInTarget; } + cc::Region occlusionFromInsideTarget() const { return cc::OcclusionTrackerBase<LayerType, RenderSurfaceType>::m_stack.back().occlusionFromInsideTarget; } + cc::Region occlusionFromOutsideTarget() const { return cc::OcclusionTrackerBase<LayerType, RenderSurfaceType>::m_stack.back().occlusionFromOutsideTarget; } - void setOcclusionInScreenSpace(const cc::Region& region) { cc::OcclusionTrackerBase<LayerType, RenderSurfaceType>::m_stack.back().occlusionInScreen = region; } - void setOcclusionInTargetSurface(const cc::Region& region) { cc::OcclusionTrackerBase<LayerType, RenderSurfaceType>::m_stack.back().occlusionInTarget = region; } + void setOcclusionFromOutsideTarget(const cc::Region& region) { cc::OcclusionTrackerBase<LayerType, RenderSurfaceType>::m_stack.back().occlusionFromOutsideTarget = region; } + void setOcclusionFromInsideTarget(const cc::Region& region) { cc::OcclusionTrackerBase<LayerType, RenderSurfaceType>::m_stack.back().occlusionFromInsideTarget = region; } }; typedef TestOcclusionTrackerBase<cc::Layer, cc::RenderSurface> TestOcclusionTracker; diff --git a/cc/tiled_layer_unittest.cc b/cc/tiled_layer_unittest.cc index 056127a..f6404e7 100644 --- a/cc/tiled_layer_unittest.cc +++ b/cc/tiled_layer_unittest.cc @@ -30,11 +30,15 @@ public: : OcclusionTracker(gfx::Rect(0, 0, 1000, 1000), true) , m_layerClipRectInTarget(gfx::Rect(0, 0, 1000, 1000)) { - // Pretend we have visited a render surface. m_stack.push_back(StackObject()); } - void setOcclusion(const Region& occlusion) { m_stack.back().occlusionInTarget = occlusion; } + void setRenderTarget(Layer* renderTarget) + { + m_stack.back().target = renderTarget; + } + + void setOcclusion(const Region& occlusion) { m_stack.back().occlusionFromInsideTarget = occlusion; } protected: virtual gfx::Rect layerClipRectInTarget(const Layer* layer) const OVERRIDE { return m_layerClipRectInTarget; } @@ -59,6 +63,8 @@ public: m_proxy = m_layerTreeHost->proxy(); m_resourceManager = PrioritizedResourceManager::create(m_proxy); m_layerTreeHost->initializeRendererIfNeeded(); + m_layerTreeHost->setRootLayer(Layer::create()); + DebugScopedSetImplThreadAndMainThreadBlocked implThreadAndMainThreadBlocked(m_proxy); m_resourceProvider = ResourceProvider::create(m_outputSurface.get()); m_hostImpl = make_scoped_ptr(new FakeLayerTreeHostImpl(m_proxy)); @@ -67,32 +73,12 @@ public: virtual ~TiledLayerTest() { resourceManagerClearAllMemory(m_resourceManager.get(), m_resourceProvider.get()); + DebugScopedSetImplThreadAndMainThreadBlocked implThreadAndMainThreadBlocked(m_proxy); m_resourceProvider.reset(); m_hostImpl.reset(); } - class ScopedFakeTiledLayerImpl { - public: - ScopedFakeTiledLayerImpl(LayerTreeImpl* treeImpl, int id) - { - m_layerImpl = new FakeTiledLayerImpl(treeImpl, id); - } - ~ScopedFakeTiledLayerImpl() - { - delete m_layerImpl; - } - FakeTiledLayerImpl* get() - { - return m_layerImpl; - } - FakeTiledLayerImpl* operator->() - { - return m_layerImpl; - } - private: - FakeTiledLayerImpl* m_layerImpl; - }; void resourceManagerClearAllMemory(PrioritizedResourceManager* resourceManager, ResourceProvider* resourceProvider) { { @@ -127,17 +113,52 @@ public: layer->update(*m_queue.get(), occluded, m_stats); } - bool updateAndPush(FakeTiledLayer* layer1, - FakeTiledLayerImpl* layerImpl1, - FakeTiledLayer* layer2 = 0, - FakeTiledLayerImpl* layerImpl2 = 0) + void calcDrawProps(const scoped_refptr<FakeTiledLayer>& layer1) + { + scoped_refptr<FakeTiledLayer> layer2; + calcDrawProps(layer1, layer2); + } + + void calcDrawProps(const scoped_refptr<FakeTiledLayer>& layer1, + const scoped_refptr<FakeTiledLayer>& layer2) + { + if (layer1 && !layer1->parent()) + m_layerTreeHost->rootLayer()->addChild(layer1); + if (layer2 && !layer1->parent()) + m_layerTreeHost->rootLayer()->addChild(layer2); + if (m_occlusion) + m_occlusion->setRenderTarget(m_layerTreeHost->rootLayer()); + + std::vector<scoped_refptr<Layer> > renderSurfaceLayerList; + LayerTreeHostCommon::calculateDrawProperties( + m_layerTreeHost->rootLayer(), + m_layerTreeHost->deviceViewportSize(), + m_layerTreeHost->deviceScaleFactor(), + 1, // page_scale_factor + m_layerTreeHost->rendererCapabilities().maxTextureSize, + false, // can_use_lcd_text + renderSurfaceLayerList); + } + + bool updateAndPush(const scoped_refptr<FakeTiledLayer>& layer1, + const scoped_ptr<FakeTiledLayerImpl>& layerImpl1) + { + scoped_refptr<FakeTiledLayer> layer2; + scoped_ptr<FakeTiledLayerImpl> layerImpl2; + return updateAndPush(layer1, layerImpl1, layer2, layerImpl2); + } + + bool updateAndPush(const scoped_refptr<FakeTiledLayer>& layer1, + const scoped_ptr<FakeTiledLayerImpl>& layerImpl1, + const scoped_refptr<FakeTiledLayer>& layer2, + const scoped_ptr<FakeTiledLayerImpl>& layerImpl2) { // Get textures m_resourceManager->clearPriorities(); if (layer1) layer1->setTexturePriorities(m_priorityCalculator); if (layer2) - layer2->setTexturePriorities(m_priorityCalculator); + layer2->setTexturePriorities(m_priorityCalculator); m_resourceManager->prioritizeTextures(); // Update content @@ -155,9 +176,9 @@ public: // Update textures and push. updateTextures(); if (layer1) - layerPushPropertiesTo(layer1, layerImpl1); + layerPushPropertiesTo(layer1.get(), layerImpl1.get()); if (layer2) - layerPushPropertiesTo(layer2, layerImpl2); + layerPushPropertiesTo(layer2.get(), layerImpl2.get()); return needsUpdate; } @@ -180,13 +201,13 @@ public: TEST_F(TiledLayerTest, pushDirtyTiles) { scoped_refptr<FakeTiledLayer> layer = make_scoped_refptr(new FakeTiledLayer(m_resourceManager.get())); - ScopedFakeTiledLayerImpl layerImpl(m_hostImpl->activeTree(), 1); + scoped_ptr<FakeTiledLayerImpl> layerImpl = make_scoped_ptr(new FakeTiledLayerImpl(m_hostImpl->activeTree(), 1)); // The tile size is 100x100, so this invalidates and then paints two tiles. layer->setBounds(gfx::Size(100, 200)); layer->drawProperties().visible_content_rect = gfx::Rect(0, 0, 100, 200); layer->invalidateContentRect(gfx::Rect(0, 0, 100, 200)); - updateAndPush(layer.get(), layerImpl.get()); + updateAndPush(layer, layerImpl); // We should have both tiles on the impl side. EXPECT_TRUE(layerImpl->hasResourceIdForTileAt(0, 0)); @@ -196,7 +217,7 @@ TEST_F(TiledLayerTest, pushDirtyTiles) layer->setBounds(gfx::Size(100, 200)); layer->drawProperties().visible_content_rect = gfx::Rect(0, 0, 100, 100); layer->invalidateContentRect(gfx::Rect(0, 0, 100, 200)); - updateAndPush(layer.get(), layerImpl.get()); + updateAndPush(layer, layerImpl); // We should only have the first tile since the other tile was invalidated but not painted. EXPECT_TRUE(layerImpl->hasResourceIdForTileAt(0, 0)); @@ -206,7 +227,7 @@ TEST_F(TiledLayerTest, pushDirtyTiles) TEST_F(TiledLayerTest, pushOccludedDirtyTiles) { scoped_refptr<FakeTiledLayer> layer = make_scoped_refptr(new FakeTiledLayer(m_resourceManager.get())); - ScopedFakeTiledLayerImpl layerImpl(m_hostImpl->activeTree(), 1); + scoped_ptr<FakeTiledLayerImpl> layerImpl = make_scoped_ptr(new FakeTiledLayerImpl(m_hostImpl->activeTree(), 1)); TestOcclusionTracker occluded; m_occlusion = &occluded; @@ -215,7 +236,7 @@ TEST_F(TiledLayerTest, pushOccludedDirtyTiles) layer->drawProperties().visible_content_rect = gfx::Rect(0, 0, 100, 200); layer->drawProperties().drawable_content_rect = gfx::Rect(0, 0, 100, 200); layer->invalidateContentRect(gfx::Rect(0, 0, 100, 200)); - updateAndPush(layer.get(), layerImpl.get()); + updateAndPush(layer, layerImpl); EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1); EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 20000, 1); @@ -229,7 +250,7 @@ TEST_F(TiledLayerTest, pushOccludedDirtyTiles) layer->invalidateContentRect(gfx::Rect(0, 0, 50, 50)); // ....but the area is occluded. occluded.setOcclusion(gfx::Rect(0, 0, 50, 50)); - updateAndPush(layer.get(), layerImpl.get()); + updateAndPush(layer, layerImpl); EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1); EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 20000 + 2500, 1); @@ -243,13 +264,13 @@ TEST_F(TiledLayerTest, pushOccludedDirtyTiles) TEST_F(TiledLayerTest, pushDeletedTiles) { scoped_refptr<FakeTiledLayer> layer = make_scoped_refptr(new FakeTiledLayer(m_resourceManager.get())); - ScopedFakeTiledLayerImpl layerImpl(m_hostImpl->activeTree(), 1); + scoped_ptr<FakeTiledLayerImpl> layerImpl = make_scoped_ptr(new FakeTiledLayerImpl(m_hostImpl->activeTree(), 1)); // The tile size is 100x100, so this invalidates and then paints two tiles. layer->setBounds(gfx::Size(100, 200)); layer->drawProperties().visible_content_rect = gfx::Rect(0, 0, 100, 200); layer->invalidateContentRect(gfx::Rect(0, 0, 100, 200)); - updateAndPush(layer.get(), layerImpl.get()); + updateAndPush(layer, layerImpl); // We should have both tiles on the impl side. EXPECT_TRUE(layerImpl->hasResourceIdForTileAt(0, 0)); @@ -268,7 +289,7 @@ TEST_F(TiledLayerTest, pushDeletedTiles) // This should recreate and update one of the deleted textures. layer->drawProperties().visible_content_rect = gfx::Rect(0, 0, 100, 100); - updateAndPush(layer.get(), layerImpl.get()); + updateAndPush(layer, layerImpl); // We should have one tiles on the impl side. EXPECT_TRUE(layerImpl->hasResourceIdForTileAt(0, 0)); @@ -278,14 +299,14 @@ TEST_F(TiledLayerTest, pushDeletedTiles) TEST_F(TiledLayerTest, pushIdlePaintTiles) { scoped_refptr<FakeTiledLayer> layer = make_scoped_refptr(new FakeTiledLayer(m_resourceManager.get())); - ScopedFakeTiledLayerImpl layerImpl(m_hostImpl->activeTree(), 1); + scoped_ptr<FakeTiledLayerImpl> layerImpl = make_scoped_ptr(new FakeTiledLayerImpl(m_hostImpl->activeTree(), 1)); // The tile size is 100x100. Setup 5x5 tiles with one visible tile in the center. // This paints 1 visible of the 25 invalid tiles. layer->setBounds(gfx::Size(500, 500)); layer->drawProperties().visible_content_rect = gfx::Rect(200, 200, 100, 100); layer->invalidateContentRect(gfx::Rect(0, 0, 500, 500)); - bool needsUpdate = updateAndPush(layer.get(), layerImpl.get()); + bool needsUpdate = updateAndPush(layer, layerImpl); // We should need idle-painting for surrounding tiles. EXPECT_TRUE(needsUpdate); @@ -294,13 +315,13 @@ TEST_F(TiledLayerTest, pushIdlePaintTiles) // For the next four updates, we should detect we still need idle painting. for (int i = 0; i < 4; i++) { - needsUpdate = updateAndPush(layer.get(), layerImpl.get()); + needsUpdate = updateAndPush(layer, layerImpl); EXPECT_TRUE(needsUpdate); } // We should always finish painting eventually. for (int i = 0; i < 20; i++) - needsUpdate = updateAndPush(layer.get(), layerImpl.get()); + needsUpdate = updateAndPush(layer, layerImpl); // We should have pre-painted all of the surrounding tiles. for (int i = 0; i < 5; i++) { @@ -314,7 +335,7 @@ TEST_F(TiledLayerTest, pushIdlePaintTiles) TEST_F(TiledLayerTest, predictivePainting) { scoped_refptr<FakeTiledLayer> layer = make_scoped_refptr(new FakeTiledLayer(m_resourceManager.get())); - ScopedFakeTiledLayerImpl layerImpl(m_hostImpl->activeTree(), 1); + scoped_ptr<FakeTiledLayerImpl> layerImpl = make_scoped_ptr(new FakeTiledLayerImpl(m_hostImpl->activeTree(), 1)); // Prepainting should occur in the scroll direction first, and the // visible rect should be extruded only along the dominant axis. @@ -352,13 +373,13 @@ TEST_F(TiledLayerTest, predictivePainting) layer->setBounds(contentBounds); layer->drawProperties().visible_content_rect = previousVisibleRect; layer->invalidateContentRect(contentRect); - bool needsUpdate = updateAndPush(layer.get(), layerImpl.get()); + bool needsUpdate = updateAndPush(layer, layerImpl); // Invalidate and move the visibleRect in the scroll direction. // Check that the correct tiles have been painted in the visible pass. layer->invalidateContentRect(contentRect); layer->drawProperties().visible_content_rect = visibleRect; - needsUpdate = updateAndPush(layer.get(), layerImpl.get()); + needsUpdate = updateAndPush(layer, layerImpl); for (int i = 0; i < 5; i++) { for (int j = 0; j < 5; j++) EXPECT_EQ(layerImpl->hasResourceIdForTileAt(i, j), pushedVisibleTiles[k].Contains(i, j)); @@ -369,7 +390,7 @@ TEST_F(TiledLayerTest, predictivePainting) // Ignore diagonal scrolls here (k > 3) as these have new visible content now. if (k <= 3) { layer->drawProperties().visible_content_rect = nextVisibleRect; - needsUpdate = updateAndPush(layer.get(), layerImpl.get()); + needsUpdate = updateAndPush(layer, layerImpl); for (int i = 0; i < 5; i++) { for (int j = 0; j < 5; j++) EXPECT_EQ(layerImpl->hasResourceIdForTileAt(i, j), pushedPrepaintTiles[k].Contains(i, j)); @@ -378,7 +399,7 @@ TEST_F(TiledLayerTest, predictivePainting) // We should always finish painting eventually. for (int i = 0; i < 20; i++) - needsUpdate = updateAndPush(layer.get(), layerImpl.get()); + needsUpdate = updateAndPush(layer, layerImpl); EXPECT_FALSE(needsUpdate); } } @@ -388,9 +409,9 @@ TEST_F(TiledLayerTest, pushTilesAfterIdlePaintFailed) // Start with 2mb of memory, but the test is going to try to use just more than 1mb, so we reduce to 1mb later. m_resourceManager->setMaxMemoryLimitBytes(2 * 1024 * 1024); scoped_refptr<FakeTiledLayer> layer1 = make_scoped_refptr(new FakeTiledLayer(m_resourceManager.get())); - ScopedFakeTiledLayerImpl layerImpl1(m_hostImpl->activeTree(), 1); + scoped_ptr<FakeTiledLayerImpl> layerImpl1 = make_scoped_ptr(new FakeTiledLayerImpl(m_hostImpl->activeTree(), 1)); scoped_refptr<FakeTiledLayer> layer2 = make_scoped_refptr(new FakeTiledLayer(m_resourceManager.get())); - ScopedFakeTiledLayerImpl layerImpl2(m_hostImpl->activeTree(), 2); + scoped_ptr<FakeTiledLayerImpl> layerImpl2 = make_scoped_ptr(new FakeTiledLayerImpl(m_hostImpl->activeTree(), 2)); // For this test we have two layers. layer1 exhausts most texture memory, leaving room for 2 more tiles from // layer2, but not all three tiles. First we paint layer1, and one tile from layer2. Then when we idle paint @@ -407,8 +428,8 @@ TEST_F(TiledLayerTest, pushTilesAfterIdlePaintFailed) layer1->drawProperties().visible_content_rect = layer1Rect; layer2->setBounds(layer2Rect.size()); layer2->drawProperties().visible_content_rect = gfx::Rect(0, 0, 100, 100); - bool needsUpdate = updateAndPush(layer1.get(), layerImpl1.get(), - layer2.get(), layerImpl2.get()); + bool needsUpdate = updateAndPush(layer1, layerImpl1, + layer2, layerImpl2); // We should need idle-painting for both remaining tiles in layer2. EXPECT_TRUE(needsUpdate); @@ -418,8 +439,8 @@ TEST_F(TiledLayerTest, pushTilesAfterIdlePaintFailed) // Now idle paint layer2. We are going to run out of memory though! // Oh well, commit the frame and push. for (int i = 0; i < 4; i++) { - needsUpdate = updateAndPush(layer1.get(), layerImpl1.get(), - layer2.get(), layerImpl2.get()); + needsUpdate = updateAndPush(layer1, layerImpl1, + layer2, layerImpl2); } // Sanity check, we should have textures for the big layer. @@ -440,7 +461,7 @@ TEST_F(TiledLayerTest, pushTilesAfterIdlePaintFailed) TEST_F(TiledLayerTest, pushIdlePaintedOccludedTiles) { scoped_refptr<FakeTiledLayer> layer = make_scoped_refptr(new FakeTiledLayer(m_resourceManager.get())); - ScopedFakeTiledLayerImpl layerImpl(m_hostImpl->activeTree(), 1); + scoped_ptr<FakeTiledLayerImpl> layerImpl = make_scoped_ptr(new FakeTiledLayerImpl(m_hostImpl->activeTree(), 1)); TestOcclusionTracker occluded; m_occlusion = &occluded; @@ -448,8 +469,9 @@ TEST_F(TiledLayerTest, pushIdlePaintedOccludedTiles) occluded.setOcclusion(gfx::Rect(0, 0, 100, 100)); layer->setBounds(gfx::Size(100, 100)); + calcDrawProps(layer); layer->drawProperties().visible_content_rect = gfx::Rect(0, 0, 100, 100); - updateAndPush(layer.get(), layerImpl.get()); + updateAndPush(layer, layerImpl); // We should have the prepainted tile on the impl side, but culled it during paint. EXPECT_TRUE(layerImpl->hasResourceIdForTileAt(0, 0)); @@ -459,15 +481,16 @@ TEST_F(TiledLayerTest, pushIdlePaintedOccludedTiles) TEST_F(TiledLayerTest, pushTilesMarkedDirtyDuringPaint) { scoped_refptr<FakeTiledLayer> layer = make_scoped_refptr(new FakeTiledLayer(m_resourceManager.get())); - ScopedFakeTiledLayerImpl layerImpl(m_hostImpl->activeTree(), 1); + scoped_ptr<FakeTiledLayerImpl> layerImpl = make_scoped_ptr(new FakeTiledLayerImpl(m_hostImpl->activeTree(), 1)); // 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->fakeLayerUpdater()->setRectToInvalidate(gfx::Rect(0, 50, 100, 50), layer.get()); layer->setBounds(gfx::Size(100, 200)); + calcDrawProps(layer); layer->drawProperties().visible_content_rect = gfx::Rect(0, 0, 100, 200); - updateAndPush(layer.get(), layerImpl.get()); + updateAndPush(layer, layerImpl); // We should have both tiles on the impl side. EXPECT_TRUE(layerImpl->hasResourceIdForTileAt(0, 0)); @@ -478,17 +501,18 @@ TEST_F(TiledLayerTest, pushTilesLayerMarkedDirtyDuringPaintOnNextLayer) { scoped_refptr<FakeTiledLayer> layer1 = make_scoped_refptr(new FakeTiledLayer(m_resourceManager.get())); scoped_refptr<FakeTiledLayer> layer2 = make_scoped_refptr(new FakeTiledLayer(m_resourceManager.get())); - ScopedFakeTiledLayerImpl layer1Impl(m_hostImpl->activeTree(), 1); - ScopedFakeTiledLayerImpl layer2Impl(m_hostImpl->activeTree(), 2); + scoped_ptr<FakeTiledLayerImpl> layer1Impl = make_scoped_ptr(new FakeTiledLayerImpl(m_hostImpl->activeTree(), 1)); + scoped_ptr<FakeTiledLayerImpl> layer2Impl = make_scoped_ptr(new FakeTiledLayerImpl(m_hostImpl->activeTree(), 2)); // Invalidate a tile on layer1, during update of layer 2. layer2->fakeLayerUpdater()->setRectToInvalidate(gfx::Rect(0, 50, 100, 50), layer1.get()); layer1->setBounds(gfx::Size(100, 200)); - layer1->drawProperties().visible_content_rect = gfx::Rect(0, 0, 100, 200); layer2->setBounds(gfx::Size(100, 200)); + calcDrawProps(layer1, layer2); + layer1->drawProperties().visible_content_rect = gfx::Rect(0, 0, 100, 200); layer2->drawProperties().visible_content_rect = gfx::Rect(0, 0, 100, 200); - updateAndPush(layer1.get(), layer1Impl.get(), - layer2.get(), layer2Impl.get()); + updateAndPush(layer1, layer1Impl, + layer2, layer2Impl); // We should have both tiles on the impl side for all layers. EXPECT_TRUE(layer1Impl->hasResourceIdForTileAt(0, 0)); @@ -501,16 +525,17 @@ TEST_F(TiledLayerTest, pushTilesLayerMarkedDirtyDuringPaintOnPreviousLayer) { scoped_refptr<FakeTiledLayer> layer1 = make_scoped_refptr(new FakeTiledLayer(m_resourceManager.get())); scoped_refptr<FakeTiledLayer> layer2 = make_scoped_refptr(new FakeTiledLayer(m_resourceManager.get())); - ScopedFakeTiledLayerImpl layer1Impl(m_hostImpl->activeTree(), 1); - ScopedFakeTiledLayerImpl layer2Impl(m_hostImpl->activeTree(), 2); + scoped_ptr<FakeTiledLayerImpl> layer1Impl = make_scoped_ptr(new FakeTiledLayerImpl(m_hostImpl->activeTree(), 1)); + scoped_ptr<FakeTiledLayerImpl> layer2Impl = make_scoped_ptr(new FakeTiledLayerImpl(m_hostImpl->activeTree(), 2)); layer1->fakeLayerUpdater()->setRectToInvalidate(gfx::Rect(0, 50, 100, 50), layer2.get()); layer1->setBounds(gfx::Size(100, 200)); - layer1->drawProperties().visible_content_rect = gfx::Rect(0, 0, 100, 200); layer2->setBounds(gfx::Size(100, 200)); + calcDrawProps(layer1, layer2); + layer1->drawProperties().visible_content_rect = gfx::Rect(0, 0, 100, 200); layer2->drawProperties().visible_content_rect = gfx::Rect(0, 0, 100, 200); - updateAndPush(layer1.get(), layer1Impl.get(), - layer2.get(), layer2Impl.get()); + updateAndPush(layer1, layer1Impl, + layer2, layer2Impl); // We should have both tiles on the impl side for all layers. EXPECT_TRUE(layer1Impl->hasResourceIdForTileAt(0, 0)); @@ -543,7 +568,7 @@ TEST_F(TiledLayerTest, paintSmallAnimatedLayersImmediately) m_resourceManager->setMaxMemoryLimitBytes(memoryForLayer); scoped_refptr<FakeTiledLayer> layer = make_scoped_refptr(new FakeTiledLayer(m_resourceManager.get())); - ScopedFakeTiledLayerImpl layerImpl(m_hostImpl->activeTree(), 1); + scoped_ptr<FakeTiledLayerImpl> layerImpl = make_scoped_ptr(new FakeTiledLayerImpl(m_hostImpl->activeTree(), 1)); // Full size layer with half being visible. gfx::Size contentBounds(layerWidth, layerHeight); @@ -585,7 +610,7 @@ TEST_F(TiledLayerTest, paintSmallAnimatedLayersImmediately) TEST_F(TiledLayerTest, idlePaintOutOfMemory) { scoped_refptr<FakeTiledLayer> layer = make_scoped_refptr(new FakeTiledLayer(m_resourceManager.get())); - ScopedFakeTiledLayerImpl layerImpl(m_hostImpl->activeTree(), 1); + scoped_ptr<FakeTiledLayerImpl> layerImpl = make_scoped_ptr(new FakeTiledLayerImpl(m_hostImpl->activeTree(), 1)); // We have enough memory for only the visible rect, so we will run out of memory in first idle paint. int memoryLimit = 4 * 100 * 100; // 1 tiles, 4 bytes per pixel. @@ -594,9 +619,10 @@ TEST_F(TiledLayerTest, idlePaintOutOfMemory) // The tile size is 100x100, so this invalidates and then paints two tiles. bool needsUpdate = false; layer->setBounds(gfx::Size(300, 300)); + calcDrawProps(layer); layer->drawProperties().visible_content_rect = gfx::Rect(100, 100, 100, 100); for (int i = 0; i < 2; i++) - needsUpdate = updateAndPush(layer.get(), layerImpl.get()); + needsUpdate = updateAndPush(layer, layerImpl); // Idle-painting should see no more priority tiles for painting. EXPECT_FALSE(needsUpdate); @@ -608,7 +634,7 @@ TEST_F(TiledLayerTest, idlePaintOutOfMemory) TEST_F(TiledLayerTest, idlePaintZeroSizedLayer) { scoped_refptr<FakeTiledLayer> layer = make_scoped_refptr(new FakeTiledLayer(m_resourceManager.get())); - ScopedFakeTiledLayerImpl layerImpl(m_hostImpl->activeTree(), 1); + scoped_ptr<FakeTiledLayerImpl> layerImpl = make_scoped_ptr(new FakeTiledLayerImpl(m_hostImpl->activeTree(), 1)); bool animating[2] = {false, true}; for (int i = 0; i < 2; i++) { @@ -618,8 +644,9 @@ TEST_F(TiledLayerTest, idlePaintZeroSizedLayer) // The layer's bounds are empty. // Empty layers don't paint or idle-paint. layer->setBounds(gfx::Size()); + calcDrawProps(layer); layer->drawProperties().visible_content_rect = gfx::Rect(); - bool needsUpdate = updateAndPush(layer.get(), layerImpl.get()); + bool needsUpdate = updateAndPush(layer, layerImpl); // Empty layers don't have tiles. EXPECT_EQ(0u, layer->numPaintedTiles()); @@ -635,7 +662,7 @@ TEST_F(TiledLayerTest, idlePaintZeroSizedLayer) TEST_F(TiledLayerTest, idlePaintNonVisibleLayers) { scoped_refptr<FakeTiledLayer> layer = make_scoped_refptr(new FakeTiledLayer(m_resourceManager.get())); - ScopedFakeTiledLayerImpl layerImpl(m_hostImpl->activeTree(), 1); + scoped_ptr<FakeTiledLayerImpl> layerImpl = make_scoped_ptr(new FakeTiledLayerImpl(m_hostImpl->activeTree(), 1)); // Alternate between not visible and visible. gfx::Rect v(0, 0, 100, 100); @@ -649,11 +676,12 @@ TEST_F(TiledLayerTest, idlePaintNonVisibleLayers) for (int i = 0; i < 10; i++) { layer->setBounds(gfx::Size(100, 100)); + calcDrawProps(layer); layer->drawProperties().visible_content_rect = visibleRect[i]; if (invalidate[i]) layer->invalidateContentRect(gfx::Rect(0, 0, 100, 100)); - bool needsUpdate = updateAndPush(layer.get(), layerImpl.get()); + bool needsUpdate = updateAndPush(layer, layerImpl); // We should never signal idle paint, as we painted the entire layer // or the layer was not visible. @@ -665,12 +693,13 @@ TEST_F(TiledLayerTest, idlePaintNonVisibleLayers) TEST_F(TiledLayerTest, invalidateFromPrepare) { scoped_refptr<FakeTiledLayer> layer = make_scoped_refptr(new FakeTiledLayer(m_resourceManager.get())); - ScopedFakeTiledLayerImpl layerImpl(m_hostImpl->activeTree(), 1); + scoped_ptr<FakeTiledLayerImpl> layerImpl = make_scoped_ptr(new FakeTiledLayerImpl(m_hostImpl->activeTree(), 1)); // The tile size is 100x100, so this invalidates and then paints two tiles. layer->setBounds(gfx::Size(100, 200)); + calcDrawProps(layer); layer->drawProperties().visible_content_rect = gfx::Rect(0, 0, 100, 200); - updateAndPush(layer.get(), layerImpl.get()); + updateAndPush(layer, layerImpl); // We should have both tiles on the impl side. EXPECT_TRUE(layerImpl->hasResourceIdForTileAt(0, 0)); @@ -679,19 +708,19 @@ TEST_F(TiledLayerTest, invalidateFromPrepare) layer->fakeLayerUpdater()->clearPrepareCount(); // Invoke update again. As the layer is valid update shouldn't be invoked on // the LayerUpdater. - updateAndPush(layer.get(), layerImpl.get()); + updateAndPush(layer, layerImpl); EXPECT_EQ(0, layer->fakeLayerUpdater()->prepareCount()); // setRectToInvalidate triggers invalidateContentRect() being invoked from update. layer->fakeLayerUpdater()->setRectToInvalidate(gfx::Rect(25, 25, 50, 50), layer.get()); layer->fakeLayerUpdater()->clearPrepareCount(); layer->invalidateContentRect(gfx::Rect(0, 0, 50, 50)); - updateAndPush(layer.get(), layerImpl.get()); + updateAndPush(layer, layerImpl); EXPECT_EQ(1, layer->fakeLayerUpdater()->prepareCount()); layer->fakeLayerUpdater()->clearPrepareCount(); // The layer should still be invalid as update invoked invalidate. - updateAndPush(layer.get(), layerImpl.get()); // visible + updateAndPush(layer, layerImpl); // visible EXPECT_EQ(1, layer->fakeLayerUpdater()->prepareCount()); } @@ -738,7 +767,7 @@ TEST_F(TiledLayerTest, verifyUpdateRectWhenContentBoundsAreScaled) TEST_F(TiledLayerTest, verifyInvalidationWhenContentsScaleChanges) { scoped_refptr<FakeTiledLayer> layer = make_scoped_refptr(new FakeTiledLayer(m_resourceManager.get())); - ScopedFakeTiledLayerImpl layerImpl(m_hostImpl->activeTree(), 1); + scoped_ptr<FakeTiledLayerImpl> layerImpl = make_scoped_ptr(new FakeTiledLayerImpl(m_hostImpl->activeTree(), 1)); // Create a layer with one tile. layer->setBounds(gfx::Size(100, 100)); @@ -890,7 +919,7 @@ TEST_F(TiledLayerPartialUpdateTest, partialUpdates) m_layerTreeHost->updateLayers( *m_queue.get(), std::numeric_limits<size_t>::max()); { - ScopedFakeTiledLayerImpl layerImpl(m_hostImpl->activeTree(), 1); + scoped_ptr<FakeTiledLayerImpl> layerImpl = make_scoped_ptr(new FakeTiledLayerImpl(m_hostImpl->activeTree(), 1)); EXPECT_EQ(6, m_queue->fullUploadSize()); EXPECT_EQ(0, m_queue->partialUploadSize()); updateTextures(); @@ -905,7 +934,7 @@ TEST_F(TiledLayerPartialUpdateTest, partialUpdates) layer->invalidateContentRect(gfx::Rect(0, 0, 300, 150)); m_layerTreeHost->updateLayers(*m_queue.get(), std::numeric_limits<size_t>::max()); { - ScopedFakeTiledLayerImpl layerImpl(m_hostImpl->activeTree(), 1); + scoped_ptr<FakeTiledLayerImpl> layerImpl = make_scoped_ptr(new FakeTiledLayerImpl(m_hostImpl->activeTree(), 1)); EXPECT_EQ(3, m_queue->fullUploadSize()); EXPECT_EQ(3, m_queue->partialUploadSize()); updateTextures(); @@ -919,7 +948,7 @@ TEST_F(TiledLayerPartialUpdateTest, partialUpdates) // Partial update of 6 tiles. layer->invalidateContentRect(gfx::Rect(50, 50, 200, 100)); { - ScopedFakeTiledLayerImpl layerImpl(m_hostImpl->activeTree(), 1); + scoped_ptr<FakeTiledLayerImpl> layerImpl = make_scoped_ptr(new FakeTiledLayerImpl(m_hostImpl->activeTree(), 1)); m_layerTreeHost->updateLayers(*m_queue.get(), std::numeric_limits<size_t>::max()); EXPECT_EQ(2, m_queue->fullUploadSize()); EXPECT_EQ(4, m_queue->partialUploadSize()); @@ -934,7 +963,7 @@ TEST_F(TiledLayerPartialUpdateTest, partialUpdates) // Checkerboard all tiles. layer->invalidateContentRect(gfx::Rect(0, 0, 300, 200)); { - ScopedFakeTiledLayerImpl layerImpl(m_hostImpl->activeTree(), 1); + scoped_ptr<FakeTiledLayerImpl> layerImpl = make_scoped_ptr(new FakeTiledLayerImpl(m_hostImpl->activeTree(), 1)); layerPushPropertiesTo(layer.get(), layerImpl.get()); } m_layerTreeHost->commitComplete(); @@ -942,7 +971,7 @@ TEST_F(TiledLayerPartialUpdateTest, partialUpdates) // Partial update of 6 checkerboard tiles. layer->invalidateContentRect(gfx::Rect(50, 50, 200, 100)); { - ScopedFakeTiledLayerImpl layerImpl(m_hostImpl->activeTree(), 1); + scoped_ptr<FakeTiledLayerImpl> layerImpl = make_scoped_ptr(new FakeTiledLayerImpl(m_hostImpl->activeTree(), 1)); m_layerTreeHost->updateLayers(*m_queue.get(), std::numeric_limits<size_t>::max()); EXPECT_EQ(6, m_queue->fullUploadSize()); EXPECT_EQ(0, m_queue->partialUploadSize()); @@ -957,7 +986,7 @@ TEST_F(TiledLayerPartialUpdateTest, partialUpdates) // Partial update of 4 tiles. layer->invalidateContentRect(gfx::Rect(50, 50, 100, 100)); { - ScopedFakeTiledLayerImpl layerImpl(m_hostImpl->activeTree(), 1); + scoped_ptr<FakeTiledLayerImpl> layerImpl = make_scoped_ptr(new FakeTiledLayerImpl(m_hostImpl->activeTree(), 1)); m_layerTreeHost->updateLayers(*m_queue.get(), std::numeric_limits<size_t>::max()); EXPECT_EQ(0, m_queue->fullUploadSize()); EXPECT_EQ(4, m_queue->partialUploadSize()); @@ -993,10 +1022,12 @@ TEST_F(TiledLayerTest, tilesPaintedWithOcclusion) { scoped_refptr<FakeTiledLayer> layer = make_scoped_refptr(new FakeTiledLayer(m_resourceManager.get())); TestOcclusionTracker occluded; + m_occlusion = &occluded; // The tile size is 100x100. layer->setBounds(gfx::Size(600, 600)); + calcDrawProps(layer); occluded.setOcclusion(gfx::Rect(200, 200, 300, 100)); layer->drawProperties().drawable_content_rect = gfx::Rect(gfx::Point(), layer->contentBounds()); @@ -1043,10 +1074,12 @@ TEST_F(TiledLayerTest, tilesPaintedWithOcclusionAndVisiblityConstraints) { scoped_refptr<FakeTiledLayer> layer = make_scoped_refptr(new FakeTiledLayer(m_resourceManager.get())); TestOcclusionTracker occluded; + m_occlusion = &occluded; // The tile size is 100x100. layer->setBounds(gfx::Size(600, 600)); + calcDrawProps(layer); // The partially occluded tiles (by the 150 occlusion height) are visible beyond the occlusion, so not culled. occluded.setOcclusion(gfx::Rect(200, 200, 300, 150)); @@ -1101,10 +1134,12 @@ TEST_F(TiledLayerTest, tilesNotPaintedWithoutInvalidation) { scoped_refptr<FakeTiledLayer> layer = make_scoped_refptr(new FakeTiledLayer(m_resourceManager.get())); TestOcclusionTracker occluded; + m_occlusion = &occluded; // The tile size is 100x100. layer->setBounds(gfx::Size(600, 600)); + calcDrawProps(layer); occluded.setOcclusion(gfx::Rect(200, 200, 300, 100)); layer->drawProperties().drawable_content_rect = gfx::Rect(0, 0, 600, 600); @@ -1139,12 +1174,14 @@ TEST_F(TiledLayerTest, tilesPaintedWithOcclusionAndTransforms) { scoped_refptr<FakeTiledLayer> layer = make_scoped_refptr(new FakeTiledLayer(m_resourceManager.get())); TestOcclusionTracker occluded; + m_occlusion = &occluded; // The tile size is 100x100. // This makes sure the painting works when the occluded region (in screen space) // is transformed differently than the layer. layer->setBounds(gfx::Size(600, 600)); + calcDrawProps(layer); gfx::Transform screenTransform; screenTransform.Scale(0.5, 0.5); layer->drawProperties().screen_space_transform = screenTransform; @@ -1168,15 +1205,17 @@ TEST_F(TiledLayerTest, tilesPaintedWithOcclusionAndScaling) { scoped_refptr<FakeTiledLayer> layer = make_scoped_refptr(new FakeTiledLayer(m_resourceManager.get())); TestOcclusionTracker occluded; + m_occlusion = &occluded; // The tile size is 100x100. // This makes sure the painting works when the content space is scaled to // a different layer space. In this case tiles are scaled to be 200x200 // pixels, which means none should be occluded. - layer->updateContentsScale(0.5); - EXPECT_FLOAT_EQ(layer->contentsScaleX(), layer->contentsScaleY()); layer->setBounds(gfx::Size(600, 600)); + layer->setRasterScale(0.5); + calcDrawProps(layer); + EXPECT_FLOAT_EQ(layer->contentsScaleX(), layer->contentsScaleY()); gfx::Transform drawTransform; double invScaleFactor = 1 / layer->contentsScaleX(); drawTransform.Scale(invScaleFactor, invScaleFactor); @@ -1437,9 +1476,9 @@ TEST_F(TiledLayerTest, dontAllocateContentsWhenTargetSurfaceCantBeAllocated) child->fakeLayerUpdater()->clearUpdateCount(); child2->fakeLayerUpdater()->clearUpdateCount(); - ScopedFakeTiledLayerImpl rootImpl(m_hostImpl->activeTree(), root->id()); - ScopedFakeTiledLayerImpl childImpl(m_hostImpl->activeTree(), child->id()); - ScopedFakeTiledLayerImpl child2Impl(m_hostImpl->activeTree(), child2->id()); + scoped_ptr<FakeTiledLayerImpl> rootImpl = make_scoped_ptr(new FakeTiledLayerImpl(m_hostImpl->activeTree(), root->id())); + scoped_ptr<FakeTiledLayerImpl> childImpl = make_scoped_ptr(new FakeTiledLayerImpl(m_hostImpl->activeTree(), child->id())); + scoped_ptr<FakeTiledLayerImpl> child2Impl = make_scoped_ptr(new FakeTiledLayerImpl(m_hostImpl->activeTree(), child2->id())); layerPushPropertiesTo(root.get(), rootImpl.get()); layerPushPropertiesTo(child.get(), childImpl.get()); layerPushPropertiesTo(child2.get(), child2Impl.get()); @@ -1472,9 +1511,9 @@ TEST_F(TiledLayerTest, dontAllocateContentsWhenTargetSurfaceCantBeAllocated) child->fakeLayerUpdater()->clearUpdateCount(); child2->fakeLayerUpdater()->clearUpdateCount(); - ScopedFakeTiledLayerImpl rootImpl(m_hostImpl->activeTree(), root->id()); - ScopedFakeTiledLayerImpl childImpl(m_hostImpl->activeTree(), child->id()); - ScopedFakeTiledLayerImpl child2Impl(m_hostImpl->activeTree(), child2->id()); + scoped_ptr<FakeTiledLayerImpl> rootImpl = make_scoped_ptr(new FakeTiledLayerImpl(m_hostImpl->activeTree(), root->id())); + scoped_ptr<FakeTiledLayerImpl> childImpl = make_scoped_ptr(new FakeTiledLayerImpl(m_hostImpl->activeTree(), child->id())); + scoped_ptr<FakeTiledLayerImpl> child2Impl = make_scoped_ptr(new FakeTiledLayerImpl(m_hostImpl->activeTree(), child2->id())); layerPushPropertiesTo(root.get(), rootImpl.get()); layerPushPropertiesTo(child.get(), childImpl.get()); layerPushPropertiesTo(child2.get(), child2Impl.get()); @@ -1508,9 +1547,9 @@ TEST_F(TiledLayerTest, dontAllocateContentsWhenTargetSurfaceCantBeAllocated) child->fakeLayerUpdater()->clearUpdateCount(); child2->fakeLayerUpdater()->clearUpdateCount(); - ScopedFakeTiledLayerImpl rootImpl(m_hostImpl->activeTree(), root->id()); - ScopedFakeTiledLayerImpl childImpl(m_hostImpl->activeTree(), child->id()); - ScopedFakeTiledLayerImpl child2Impl(m_hostImpl->activeTree(), child2->id()); + scoped_ptr<FakeTiledLayerImpl> rootImpl = make_scoped_ptr(new FakeTiledLayerImpl(m_hostImpl->activeTree(), root->id())); + scoped_ptr<FakeTiledLayerImpl> childImpl = make_scoped_ptr(new FakeTiledLayerImpl(m_hostImpl->activeTree(), child->id())); + scoped_ptr<FakeTiledLayerImpl> child2Impl = make_scoped_ptr(new FakeTiledLayerImpl(m_hostImpl->activeTree(), child2->id())); layerPushPropertiesTo(root.get(), rootImpl.get()); layerPushPropertiesTo(child.get(), childImpl.get()); layerPushPropertiesTo(child2.get(), child2Impl.get()); |