diff options
author | danakj@chromium.org <danakj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-01-18 12:14:31 +0000 |
---|---|---|
committer | danakj@chromium.org <danakj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-01-18 12:14:31 +0000 |
commit | bae49f2c697eb35b62c6503b051db728ebb8044e (patch) | |
tree | baa76626d8fff59584ec2f9d16bbe047959ef3b1 /cc/occlusion_tracker_unittest.cc | |
parent | 164e62828afdd0df8a608a67395d9203e32babe0 (diff) | |
download | chromium_src-bae49f2c697eb35b62c6503b051db728ebb8044e.zip chromium_src-bae49f2c697eb35b62c6503b051db728ebb8044e.tar.gz chromium_src-bae49f2c697eb35b62c6503b051db728ebb8044e.tar.bz2 |
cc: Fix clipped render surface caching.
Fix this by considering clipping from outside of the target surface as
occlusion from outside the target surface. We clip quads by the various
rects including the device viewport. When we do this, it should count as
occlusion from outside of the target surface so that surfaces do not
consider themselves complete when they are not fully drawn because they
extend outside the viewport.
The OcclusionTrackerTestLayerClipIsExternalOcclusion test will pass
without this CL as clipping does not cross surface boundaries in the
occlusion tracker right now, except for the screen space (viewport) clip
rect. I've added some TODOs where we could change this behaviour and
clip more aggressively things that will not be seen.
Tests:
cc_unittests:OcclusionTrackerTestViewportClipIsExternalOcclusion*
cc_unittests:OcclusionTrackerTestLayerClipIsExternalOcclusion*
BUG=167681
R=enne
Review URL: https://chromiumcodereview.appspot.com/11971030
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@177645 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cc/occlusion_tracker_unittest.cc')
-rw-r--r-- | cc/occlusion_tracker_unittest.cc | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/cc/occlusion_tracker_unittest.cc b/cc/occlusion_tracker_unittest.cc index ea4993a..32de23b 100644 --- a/cc/occlusion_tracker_unittest.cc +++ b/cc/occlusion_tracker_unittest.cc @@ -3122,5 +3122,112 @@ protected: ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestMinimumTrackingSize); +template<class Types> +class OcclusionTrackerTestViewportClipIsExternalOcclusion : public OcclusionTrackerTest<Types> { +protected: + OcclusionTrackerTestViewportClipIsExternalOcclusion(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {} + void runMyTest() + { + typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(400, 400)); + typename Types::LayerType* small = this->createDrawingSurface(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(200, 200), false); + typename Types::LayerType* large = this->createDrawingLayer(small, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(400, 400), false); + small->setMasksToBounds(true); + this->calcDrawEtc(parent); + + TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 100, 100)); + + this->enterLayer(large, occlusion); + + bool hasOcclusionFromOutsideTargetSurface = false; + EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100), occlusion.unoccludedLayerContentRect(large, gfx::Rect(0, 0, 400, 400), &hasOcclusionFromOutsideTargetSurface)); + EXPECT_TRUE(hasOcclusionFromOutsideTargetSurface); + + hasOcclusionFromOutsideTargetSurface = false; + EXPECT_FALSE(occlusion.occludedLayer(large, gfx::Rect(0, 0, 400, 400), &hasOcclusionFromOutsideTargetSurface)); + EXPECT_TRUE(hasOcclusionFromOutsideTargetSurface); + + this->leaveLayer(large, occlusion); + this->visitLayer(small, occlusion); + + hasOcclusionFromOutsideTargetSurface = false; + EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100), occlusion.unoccludedLayerContentRect(small, gfx::Rect(0, 0, 200, 200), &hasOcclusionFromOutsideTargetSurface)); + EXPECT_TRUE(hasOcclusionFromOutsideTargetSurface); + + hasOcclusionFromOutsideTargetSurface = false; + EXPECT_FALSE(occlusion.occludedLayer(small, gfx::Rect(0, 0, 200, 200), &hasOcclusionFromOutsideTargetSurface)); + EXPECT_TRUE(hasOcclusionFromOutsideTargetSurface); + + this->enterContributingSurface(small, occlusion); + + hasOcclusionFromOutsideTargetSurface = false; + EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100), occlusion.unoccludedContributingSurfaceContentRect(small, false, gfx::Rect(0, 0, 200, 200), &hasOcclusionFromOutsideTargetSurface)); + EXPECT_TRUE(hasOcclusionFromOutsideTargetSurface); + } +}; + +ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestViewportClipIsExternalOcclusion) + +template<class Types> +class OcclusionTrackerTestLayerClipIsExternalOcclusion : public OcclusionTrackerTest<Types> { +protected: + OcclusionTrackerTestLayerClipIsExternalOcclusion(bool opaqueLayers) : OcclusionTrackerTest<Types>(opaqueLayers) {} + void runMyTest() + { + typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, gfx::PointF(0, 0), gfx::Size(400, 400)); + typename Types::LayerType* smallest = this->createDrawingLayer(parent, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(50, 50), false); + typename Types::LayerType* smaller = this->createDrawingSurface(smallest, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(100, 100), false); + typename Types::LayerType* small = this->createDrawingSurface(smaller, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(200, 200), false); + typename Types::LayerType* large = this->createDrawingLayer(small, this->identityMatrix, gfx::PointF(0, 0), gfx::Size(400, 400), false); + smallest->setMasksToBounds(true); + smaller->setMasksToBounds(true); + small->setMasksToBounds(true); + this->calcDrawEtc(parent); + + TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(gfx::Rect(0, 0, 1000, 1000)); + + this->enterLayer(large, occlusion); + + // Clipping from the smaller layer doesn't cross the surface boundary. The layer is clipped by its target surface which is not outside its target. + // TODO(danakj): This will change if we clip the layer to its target surface's contentRect. + bool hasOcclusionFromOutsideTargetSurface = false; + EXPECT_RECT_EQ(gfx::Rect(0, 0, 200, 200), occlusion.unoccludedLayerContentRect(large, gfx::Rect(0, 0, 400, 400), &hasOcclusionFromOutsideTargetSurface)); + EXPECT_FALSE(hasOcclusionFromOutsideTargetSurface); + + hasOcclusionFromOutsideTargetSurface = false; + EXPECT_FALSE(occlusion.occludedLayer(large, gfx::Rect(0, 0, 400, 400), &hasOcclusionFromOutsideTargetSurface)); + EXPECT_FALSE(hasOcclusionFromOutsideTargetSurface); + + this->leaveLayer(large, occlusion); + this->visitLayer(small, occlusion); + + // Clipping from the smaller layer doesn't cross the surface boundary. + hasOcclusionFromOutsideTargetSurface = false; + EXPECT_RECT_EQ(gfx::Rect(0, 0, 200, 200), occlusion.unoccludedLayerContentRect(small, gfx::Rect(0, 0, 200, 200), &hasOcclusionFromOutsideTargetSurface)); + EXPECT_FALSE(hasOcclusionFromOutsideTargetSurface); + + hasOcclusionFromOutsideTargetSurface = false; + EXPECT_FALSE(occlusion.occludedLayer(small, gfx::Rect(0, 0, 200, 200), &hasOcclusionFromOutsideTargetSurface)); + EXPECT_FALSE(hasOcclusionFromOutsideTargetSurface); + + this->enterContributingSurface(small, occlusion); + + // The |small| surface is clipped from outside its target by |smallest|. + hasOcclusionFromOutsideTargetSurface = false; + EXPECT_RECT_EQ(gfx::Rect(0, 0, 50, 50), occlusion.unoccludedContributingSurfaceContentRect(small, false, gfx::Rect(0, 0, 200, 200), &hasOcclusionFromOutsideTargetSurface)); + EXPECT_TRUE(hasOcclusionFromOutsideTargetSurface); + + this->leaveContributingSurface(small, occlusion); + this->visitLayer(smaller, occlusion); + this->enterContributingSurface(smaller, occlusion); + + // The |smaller| surface is clipped from inside its target by |smallest|. + hasOcclusionFromOutsideTargetSurface = false; + EXPECT_RECT_EQ(gfx::Rect(0, 0, 50, 50), occlusion.unoccludedContributingSurfaceContentRect(smaller, false, gfx::Rect(0, 0, 100, 100), &hasOcclusionFromOutsideTargetSurface)); + EXPECT_FALSE(hasOcclusionFromOutsideTargetSurface); + } +}; + +ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestLayerClipIsExternalOcclusion) + } // namespace } // namespace cc |