Source/WebCore/ChangeLog

 12012-03-26 Dana Jansens <danakj@chromium.org>
 2
 3 [chromium] Cull occluded surface quads
 4 https://bugs.webkit.org/show_bug.cgi?id=81227
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 RenderSurface quads should be culled based on occlusion, but it must
 9 also account to the replica. We take the union of the unoccluded
 10 space in the replica and the original content as the unocclusion
 11 rect in the quad.
 12
 13 In order to compute occlusion for the surface itself, it must not
 14 consider occlusion found in its own subtree. To do this, we reorder
 15 the calls to the occlusion tracker, and add the surface quad
 16 before we "leaveToTargetRenderSurface" which merges occlusion from
 17 the surface's subtree up into its parent.
 18
 19 Unit test: CCOcclusionTrackerTestReplicaOccluded
 20 CCOcclusionTrackerTestSurfaceWithReplicaUnoccluded
 21 CCOcclusionTrackerTestSurfaceAndReplicaOccludedWithSurfaceMore
 22 CCOcclusionTrackerTestSurfaceAndReplicaOccludedWithReplicaMore
 23 CCOcclusionTrackerTestSurfaceChildOfSurface
 24
 25 And added some sanity checks to other CCOcclusionTracker tests that have
 26 render surfaces.
 27
 28 * platform/graphics/chromium/RenderSurfaceChromium.cpp:
 29 (WebCore::RenderSurfaceChromium::hasReplica):
 30 (WebCore):
 31 * platform/graphics/chromium/RenderSurfaceChromium.h:
 32 (RenderSurfaceChromium):
 33 * platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp:
 34 (WebCore::CCLayerTreeHostImpl::calculateRenderPasses):
 35 * platform/graphics/chromium/cc/CCOcclusionTracker.cpp:
 36 (WebCore::::leaveToTargetRenderSurface):
 37 (WebCore::::unoccludedContributingSurfaceContentRect):
 38 (WebCore):
 39 * platform/graphics/chromium/cc/CCOcclusionTracker.h:
 40 (CCOcclusionTrackerBase):
 41 * platform/graphics/chromium/cc/CCQuadCuller.cpp:
 42 (WebCore::CCQuadCuller::append):
 43 * platform/graphics/chromium/cc/CCRenderPass.cpp:
 44 (WebCore::CCRenderPass::appendQuadsForRenderSurfaceLayer):
 45 * platform/graphics/chromium/cc/CCRenderPass.h:
 46 (CCRenderPass):
 47 * platform/graphics/chromium/cc/CCRenderSurface.cpp:
 48 (WebCore::CCRenderSurface::drawableContentRect):
 49 (WebCore::CCRenderSurface::draw):
 50 (WebCore::CCRenderSurface::hasReplica):
 51 * platform/graphics/chromium/cc/CCRenderSurface.h:
 52 (CCRenderSurface):
 53
1542012-04-02 Alexander Pavlov <apavlov@chromium.org>
255
356 Web Inspector: Implement frontend for device metrics emulation

Source/WebKit/chromium/ChangeLog

 12012-03-26 Dana Jansens <danakj@chromium.org>
 2
 3 [chromium] Cull occluded surface quads
 4 https://bugs.webkit.org/show_bug.cgi?id=81227
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 * tests/CCOcclusionTrackerTest.cpp:
 9 (WebCore::CCOcclusionTrackerTest::TearDown):
 10 (WebCore::CCOcclusionTrackerTest::createReplicaLayer):
 11 (CCOcclusionTrackerTest):
 12 (WebCore::CCOcclusionTrackerTest::setReplica):
 13 (WebCore::CCOcclusionTrackerTestOverlappingSurfaceSiblings::runMyTest):
 14 (WebCore::CCOcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms::runMyTest):
 15 (WebCore::CCOcclusionTrackerTestAnimationOpacity1OnMainThread::runMyTest):
 16 (WebCore::CCOcclusionTrackerTestAnimationOpacity0OnMainThread::runMyTest):
 17 (WebCore::CCOcclusionTrackerTestAnimationTranslateOnMainThread::runMyTest):
 18 (WebCore):
 19 (CCOcclusionTrackerTestReplicaOccluded):
 20 (WebCore::CCOcclusionTrackerTestReplicaOccluded::runMyTest):
 21 (CCOcclusionTrackerTestSurfaceWithReplicaUnoccluded):
 22 (WebCore::CCOcclusionTrackerTestSurfaceWithReplicaUnoccluded::runMyTest):
 23 (CCOcclusionTrackerTestSurfaceAndReplicaOccludedWithReplicaMore):
 24 (WebCore::CCOcclusionTrackerTestSurfaceAndReplicaOccludedWithReplicaMore::runMyTest):
 25 (CCOcclusionTrackerTestSurfaceAndReplicaOccludedWithSurfaceMore):
 26 (WebCore::CCOcclusionTrackerTestSurfaceAndReplicaOccludedWithSurfaceMore::runMyTest):
 27
1282012-04-02 Kinuko Yasuda <kinuko@chromium.org>
229
330 Unreviewed, rolling chromium DEPS.

Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.cpp

@@FloatRect RenderSurfaceChromium::drawableContentRect() const
6464 return drawableContentRect;
6565}
6666
 67bool RenderSurfaceChromium::hasReplica() const
 68{
 69 return m_owningLayer->replicaLayer();
 70}
 71
6772}
6873#endif // USE(ACCELERATED_COMPOSITING)

Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.h

@@public:
108108 void setNearestAncestorThatMovesPixels(RenderSurfaceChromium* surface) { m_nearestAncestorThatMovesPixels = surface; }
109109 const RenderSurfaceChromium* nearestAncestorThatMovesPixels() const { return m_nearestAncestorThatMovesPixels; }
110110
 111 bool hasReplica() const;
 112
111113private:
112114 LayerChromium* m_owningLayer;
113115 LayerChromium* m_maskLayer;

Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp

@@bool CCLayerTreeHostImpl::calculateRenderPasses(CCRenderPassList& passes, CCLaye
295295 CCLayerIteratorType end = CCLayerIteratorType::end(&renderSurfaceLayerList);
296296 for (CCLayerIteratorType it = CCLayerIteratorType::begin(&renderSurfaceLayerList); it != end; ++it) {
297297 CCRenderSurface* renderSurface = it.targetRenderSurfaceLayer()->renderSurface();
 298 CCRenderPass* pass = surfacePassMap.get(renderSurface);
298299
299300 if (it.representsItself())
300301 occlusionTracker.enterTargetRenderSurface(renderSurface);
301  else if (it.representsTargetRenderSurface())
 302 else if (it.representsTargetRenderSurface()) {
302303 occlusionTracker.finishedTargetRenderSurface(*it, renderSurface);
303  else
304  occlusionTracker.leaveToTargetRenderSurface(renderSurface);
305 
306  if (it.representsTargetRenderSurface())
307304 continue;
308  if (it->visibleLayerRect().isEmpty())
 305 } else {
 306 pass->appendQuadsForRenderSurfaceLayer(*it, &occlusionTracker);
 307 occlusionTracker.leaveToTargetRenderSurface(renderSurface);
309308 continue;
 309 }
310310
311  CCRenderPass* pass = surfacePassMap.get(renderSurface);
312  if (it.representsContributingRenderSurface()) {
313  pass->appendQuadsForRenderSurfaceLayer(*it);
 311 if (it->visibleLayerRect().isEmpty())
314312 continue;
315  }
316313
317314 it->willDraw(m_layerRenderer.get());
318315

Source/WebCore/platform/graphics/chromium/cc/CCOcclusionTracker.cpp

@@void CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::leaveToTargetRenderSu
137137
138138 const RenderSurfaceType* oldTarget = m_stack[lastIndex].surface;
139139 Region oldTargetOcclusionInNewTarget = transformSurfaceOpaqueRegion<RenderSurfaceType>(oldTarget, m_stack[lastIndex].occlusionInTarget, oldTarget->originTransform());
 140 // FIXME: The replica can occlude things too.
140141
141142 if (surfaceWillBeAtTopAfterPop) {
142143 // Merge the top of the stack down.

@@IntRect CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::unoccludedContentR
336337}
337338
338339template<typename LayerType, typename RenderSurfaceType>
 340IntRect CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::unoccludedContributingSurfaceContentRect(const LayerType* layer, const IntRect& contentRect) const
 341{
 342 ASSERT(!m_stack.isEmpty());
 343 // 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
 344 // found just below the top of the stack (if it exists).
 345 if (m_stack.size() < 2)
 346 return contentRect;
 347 if (contentRect.isEmpty())
 348 return contentRect;
 349
 350 // This should be called while the contributing render surface is still considered the current target in the occlusion tracker.
 351 ASSERT(layer->targetRenderSurface() == m_stack.last().surface);
 352
 353 RenderSurfaceType* surface = layer->renderSurface();
 354 const StackObject& secondLast = m_stack[m_stack.size() - 2];
 355
 356 IntRect unoccludedSurfaceRect = contentRect;
 357 IntRect surfaceClipRect = surface->clipRect();
 358 if (surfaceClipRect.isEmpty()) {
 359 const RenderSurfaceType* targetSurface = m_stack.last().surface;
 360 surfaceClipRect = intersection(targetSurface->contentRect(), enclosingIntRect(surface->drawableContentRect()));
 361 }
 362
 363
 364 IntRect unoccludedInScreen = contentRect;
 365 if (surfaceTransformsToScreenKnown(surface))
 366 unoccludedInScreen = computeUnoccludedContentRect(contentRect, surface->screenSpaceTransform(), m_scissorRectInScreenSpace, secondLast.occlusionInScreen);
 367 unoccludedSurfaceRect.intersect(unoccludedInScreen);
 368
 369 if (!unoccludedSurfaceRect.isEmpty()) {
 370 IntRect unoccludedInTarget = contentRect;
 371 if (surfaceTransformsToTargetKnown(surface))
 372 unoccludedInTarget = computeUnoccludedContentRect(contentRect, surface->originTransform(), surfaceClipRect, secondLast.occlusionInTarget);
 373 unoccludedSurfaceRect.intersect(unoccludedInTarget);
 374 }
 375
 376 IntRect unoccludedReplicaRect;
 377 if (surface->hasReplica()) {
 378 unoccludedReplicaRect = contentRect;
 379
 380 IntRect unoccludedInScreen = contentRect;
 381 if (surfaceTransformsToScreenKnown(surface))
 382 unoccludedInScreen = computeUnoccludedContentRect(contentRect, surface->replicaScreenSpaceTransform(), m_scissorRectInScreenSpace, secondLast.occlusionInScreen);
 383 unoccludedReplicaRect.intersect(unoccludedInScreen);
 384
 385 if (!unoccludedSurfaceRect.isEmpty()) {
 386 IntRect unoccludedInTarget = contentRect;
 387 if (surfaceTransformsToTargetKnown(surface))
 388 unoccludedInTarget = computeUnoccludedContentRect(contentRect, surface->replicaOriginTransform(), surfaceClipRect, secondLast.occlusionInTarget);
 389 unoccludedReplicaRect.intersect(unoccludedInTarget);
 390 }
 391 }
 392
 393 return unionRect(unoccludedSurfaceRect, unoccludedReplicaRect);
 394}
 395
 396template<typename LayerType, typename RenderSurfaceType>
339397IntRect CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::layerScissorRectInTargetSurface(const LayerType* layer) const
340398{
341399 const RenderSurfaceType* targetSurface = m_stack.last().surface;

@@template void CCOcclusionTrackerBase<LayerChromium, RenderSurfaceChromium>::leav
353411template void CCOcclusionTrackerBase<LayerChromium, RenderSurfaceChromium>::markOccludedBehindLayer(const LayerChromium*);
354412template bool CCOcclusionTrackerBase<LayerChromium, RenderSurfaceChromium>::occluded(const LayerChromium*, const IntRect& contentRect) const;
355413template IntRect CCOcclusionTrackerBase<LayerChromium, RenderSurfaceChromium>::unoccludedContentRect(const LayerChromium*, const IntRect& contentRect) const;
 414template IntRect CCOcclusionTrackerBase<LayerChromium, RenderSurfaceChromium>::unoccludedContributingSurfaceContentRect(const LayerChromium*, const IntRect& contentRect) const;
356415template IntRect CCOcclusionTrackerBase<LayerChromium, RenderSurfaceChromium>::layerScissorRectInTargetSurface(const LayerChromium*) const;
357416
358417template CCOcclusionTrackerBase<CCLayerImpl, CCRenderSurface>::CCOcclusionTrackerBase(IntRect scissorRectInScreenSpace, bool recordMetricsForFrame);

@@template void CCOcclusionTrackerBase<CCLayerImpl, CCRenderSurface>::leaveToTarge
362421template void CCOcclusionTrackerBase<CCLayerImpl, CCRenderSurface>::markOccludedBehindLayer(const CCLayerImpl*);
363422template bool CCOcclusionTrackerBase<CCLayerImpl, CCRenderSurface>::occluded(const CCLayerImpl*, const IntRect& contentRect) const;
364423template IntRect CCOcclusionTrackerBase<CCLayerImpl, CCRenderSurface>::unoccludedContentRect(const CCLayerImpl*, const IntRect& contentRect) const;
 424template IntRect CCOcclusionTrackerBase<CCLayerImpl, CCRenderSurface>::unoccludedContributingSurfaceContentRect(const CCLayerImpl*, const IntRect& contentRect) const;
365425template IntRect CCOcclusionTrackerBase<CCLayerImpl, CCRenderSurface>::layerScissorRectInTargetSurface(const CCLayerImpl*) const;
366426
367427

Source/WebCore/platform/graphics/chromium/cc/CCOcclusionTracker.h

@@public:
6767 // Gives an unoccluded sub-rect of |contentRect| in the content space of the layer. Used when considering occlusion for a layer that paints/draws something.
6868 IntRect unoccludedContentRect(const LayerType*, const IntRect& contentRect) const;
6969
 70 // Gives an unoccluded sub-rect of |contentRect| in the content space of the surface owned by |layer|. Used when considering occlusion for a surface
 71 // that is rendering into another target surface.
 72 IntRect unoccludedContributingSurfaceContentRect(const LayerType*, const IntRect& contentRect) const;
 73
7074 // Report operations for recording overdraw metrics.
7175 CCOverdrawMetrics& overdrawMetrics() const { return *m_overdrawMetrics.get(); }
7276

Source/WebCore/platform/graphics/chromium/cc/CCQuadCuller.cpp

@@CCQuadCuller::CCQuadCuller(CCQuadList& quadList, CCLayerImpl* layer, CCOcclusion
5050bool CCQuadCuller::append(PassOwnPtr<CCDrawQuad> passDrawQuad)
5151{
5252 OwnPtr<CCDrawQuad> drawQuad(passDrawQuad);
53  IntRect culledRect = m_occlusionTracker->unoccludedContentRect(m_layer, drawQuad->quadRect());
 53 IntRect culledRect;
 54 if (drawQuad->material() == CCDrawQuad::RenderSurface)
 55 culledRect = m_occlusionTracker->unoccludedContributingSurfaceContentRect(m_layer, drawQuad->quadRect());
 56 else
 57 culledRect = m_occlusionTracker->unoccludedContentRect(m_layer, drawQuad->quadRect());
5458 bool keepQuad = !culledRect.isEmpty();
5559 if (keepQuad)
5660 drawQuad->setQuadVisibleRect(culledRect);

Source/WebCore/platform/graphics/chromium/cc/CCRenderPass.cpp

@@void CCRenderPass::appendQuadsForLayer(CCLayerImpl* layer, CCOcclusionTrackerImp
6666 m_sharedQuadStateList.append(sharedQuadState.release());
6767}
6868
69 void CCRenderPass::appendQuadsForRenderSurfaceLayer(CCLayerImpl* layer)
 69void CCRenderPass::appendQuadsForRenderSurfaceLayer(CCLayerImpl* layer, CCOcclusionTrackerImpl* occlusionTracker)
7070{
7171 // FIXME: render surface layers should be a CCLayerImpl-derived class and
7272 // not be handled specially here.
 73 CCQuadCuller quadCuller(m_quadList, layer, occlusionTracker);
 74
7375 CCRenderSurface* surface = layer->renderSurface();
7476 OwnPtr<CCSharedQuadState> sharedQuadState = surface->createSharedQuadState();
7577
7678 if (layer->hasDebugBorders()) {
7779 Color color(debugSurfaceBorderColorRed, debugSurfaceBorderColorGreen, debugSurfaceBorderColorBlue, debugSurfaceBorderAlpha);
78  m_quadList.append(CCDebugBorderDrawQuad::create(sharedQuadState.get(), surface->contentRect(), color, debugSurfaceBorderWidth));
 80 quadCuller.append(CCDebugBorderDrawQuad::create(sharedQuadState.get(), surface->contentRect(), color, debugSurfaceBorderWidth));
7981 if (surface->hasReplica()) {
8082 OwnPtr<CCSharedQuadState> sharedQuadState = surface->createReplicaSharedQuadState();
8183 Color color(debugReplicaBorderColorRed, debugReplicaBorderColorGreen, debugReplicaBorderColorBlue, debugSurfaceBorderAlpha);
82  m_quadList.append(CCDebugBorderDrawQuad::create(sharedQuadState.get(), surface->contentRect(), color, debugSurfaceBorderWidth));
 84 quadCuller.append(CCDebugBorderDrawQuad::create(sharedQuadState.get(), surface->contentRect(), color, debugSurfaceBorderWidth));
8385 m_sharedQuadStateList.append(sharedQuadState.release());
8486 }
8587 }
8688
87  m_quadList.append(CCRenderSurfaceDrawQuad::create(sharedQuadState.get(), surface->contentRect(), layer, surfaceDamageRect()));
 89 quadCuller.append(CCRenderSurfaceDrawQuad::create(sharedQuadState.get(), surface->contentRect(), layer, surfaceDamageRect()));
8890 m_sharedQuadStateList.append(sharedQuadState.release());
8991}
9092

Source/WebCore/platform/graphics/chromium/cc/CCRenderPass.h

@@public:
5555 static PassOwnPtr<CCRenderPass> create(CCRenderSurface*);
5656
5757 void appendQuadsForLayer(CCLayerImpl*, CCOcclusionTrackerImpl*, bool& usedCheckerboard);
58  void appendQuadsForRenderSurfaceLayer(CCLayerImpl*);
 58 void appendQuadsForRenderSurfaceLayer(CCLayerImpl*, CCOcclusionTrackerImpl*);
5959
6060 const CCQuadList& quadList() const { return m_quadList; }
6161 CCRenderSurface* targetSurface() const { return m_targetSurface; }

Source/WebCore/platform/graphics/chromium/cc/CCRenderSurface.cpp

@@int CCRenderSurface::owningLayerId() const
271271 return m_owningLayer ? m_owningLayer->id() : 0;
272272}
273273
274 bool CCRenderSurface::hasReplica()
 274bool CCRenderSurface::hasReplica() const
275275{
276276 return m_owningLayer->replicaLayer();
277277}

Source/WebCore/platform/graphics/chromium/cc/CCRenderSurface.h

@@public:
127127
128128 int owningLayerId() const;
129129
130  bool hasReplica();
 130 bool hasReplica() const;
131131
132132 void resetPropertyChangedFlag() { m_surfacePropertyChanged = false; }
133133 bool surfacePropertyChanged() const;

Source/WebKit/chromium/tests/CCOcclusionTrackerTest.cpp

@@protected:
135135 m_root.clear();
136136 m_renderSurfaceLayerListChromium.clear();
137137 m_renderSurfaceLayerListImpl.clear();
 138 m_replicaLayers.clear();
138139 CCLayerTreeHost::setNeedsFilterContext(false);
139140 }
140141

@@protected:
187188 return layerPtr;
188189 }
189190
 191 typename Types::LayerType* createReplicaLayer(typename Types::LayerType* owningLayer, const TransformationMatrix& transform, const FloatPoint& position, const IntSize& bounds)
 192 {
 193 typename Types::ContentLayerPtrType layer(Types::createContentLayer());
 194 typename Types::ContentLayerType* layerPtr = layer.get();
 195 setProperties(layerPtr, transform, position, bounds);
 196 setReplica(owningLayer, layer.release());
 197 return layerPtr;
 198 }
 199
190200 typename Types::ContentLayerType* createDrawingSurface(typename Types::LayerType* parent, const TransformationMatrix& transform, const FloatPoint& position, const IntSize& bounds, bool opaque)
191201 {
192202 typename Types::ContentLayerType* layer = createDrawingLayer(parent, transform, position, bounds, opaque);

@@private:
253263 layer->setContentBounds(layer->bounds());
254264 }
255265
 266 void setReplica(LayerChromium* owningLayer, PassRefPtr<LayerChromium> layer)
 267 {
 268 owningLayer->setReplicaLayer(layer.get());
 269 m_replicaLayers.append(layer);
 270 }
 271
 272 void setReplica(CCLayerImpl* owningLayer, PassOwnPtr<CCLayerImpl> layer)
 273 {
 274 owningLayer->setReplicaLayer(layer);
 275 }
 276
256277 // These hold ownership of the layers for the duration of the test.
257278 typename Types::LayerPtrType m_root;
258279 Vector<RefPtr<LayerChromium> > m_renderSurfaceLayerListChromium;
259280 Vector<CCLayerImpl*> m_renderSurfaceLayerListImpl;
 281 Vector<RefPtr<LayerChromium> > m_replicaLayers;
260282};
261283
262284#define RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \

@@protected:
902924
903925 occlusion.markOccludedBehindLayer(child2);
904926 occlusion.finishedTargetRenderSurface(child2, child2->renderSurface());
 927
 928 // There is nothing above child2's surface in the z-order.
 929 EXPECT_EQ_RECT(IntRect(-10, 420, 70, 80), occlusion.unoccludedContributingSurfaceContentRect(child2, IntRect(-10, 420, 70, 80)));
 930
905931 occlusion.leaveToTargetRenderSurface(parent->renderSurface());
906932 occlusion.enterTargetRenderSurface(child1->renderSurface());
907933 occlusion.markOccludedBehindLayer(layer1);

@@protected:
919945
920946 occlusion.markOccludedBehindLayer(child1);
921947 occlusion.finishedTargetRenderSurface(child1, child1->renderSurface());
 948
 949 // child2's contents will occlude child1 below it.
 950 EXPECT_EQ_RECT(IntRect(-10, 430, 10, 70), occlusion.unoccludedContributingSurfaceContentRect(child1, IntRect(-10, 430, 80, 70)));
 951
922952 occlusion.leaveToTargetRenderSurface(parent->renderSurface());
923953
924954 EXPECT_EQ_RECT(IntRect(20, 20, 80, 80), occlusion.occlusionInScreenSpace().bounds());

@@protected:
10061036 occlusion.markOccludedBehindLayer(child2);
10071037 occlusion.finishedTargetRenderSurface(child2, child2->renderSurface());
10081038 occlusion.leaveToTargetRenderSurface(parent->renderSurface());
 1039
 1040 // There is nothing above child2's surface in the z-order.
 1041 EXPECT_EQ_RECT(IntRect(-10, 420, 70, 80), occlusion.unoccludedContributingSurfaceContentRect(child2, IntRect(-10, 420, 70, 80)));
 1042
10091043 occlusion.enterTargetRenderSurface(child1->renderSurface());
10101044 occlusion.markOccludedBehindLayer(layer1);
10111045

@@protected:
10221056
10231057 occlusion.markOccludedBehindLayer(child1);
10241058 occlusion.finishedTargetRenderSurface(child1, child1->renderSurface());
 1059
 1060 // child2's contents will occlude child1 below it.
 1061 EXPECT_EQ_RECT(IntRect(420, -20, 80, 90), occlusion.unoccludedContributingSurfaceContentRect(child1, IntRect(420, -20, 80, 90)));
 1062 EXPECT_EQ_RECT(IntRect(490, -10, 10, 80), occlusion.unoccludedContributingSurfaceContentRect(child1, IntRect(420, -10, 80, 90)));
 1063 EXPECT_EQ_RECT(IntRect(420, -20, 70, 10), occlusion.unoccludedContributingSurfaceContentRect(child1, IntRect(420, -20, 70, 90)));
 1064
10251065 occlusion.leaveToTargetRenderSurface(parent->renderSurface());
10261066
10271067 EXPECT_EQ_RECT(IntRect(10, 20, 90, 80), occlusion.occlusionInScreenSpace().bounds());

@@protected:
16831723 typename Types::ContentLayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300), true);
16841724 typename Types::ContentLayerType* surfaceChild = this->createDrawingLayer(surface, this->identityMatrix, FloatPoint(0, 0), IntSize(200, 300), true);
16851725 typename Types::ContentLayerType* surfaceChild2 = this->createDrawingLayer(surface, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 300), true);
 1726 typename Types::ContentLayerType* topmost = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(250, 0), IntSize(50, 300), true);
16861727
16871728 addOpacityTransitionToController(*layer->layerAnimationController(), 10, 0, 1, false);
16881729 addOpacityTransitionToController(*surface->layerAnimationController(), 10, 0, 1, false);

@@protected:
16941735
16951736 TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
16961737
 1738 occlusion.enterTargetRenderSurface(parent->renderSurface());
 1739 occlusion.markOccludedBehindLayer(topmost);
 1740 // This occlusion will affect all surfaces.
 1741 EXPECT_EQ_RECT(IntRect(0, 0, 250, 300), occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300)));
 1742
16971743 occlusion.enterTargetRenderSurface(surface->renderSurface());
16981744 occlusion.markOccludedBehindLayer(surfaceChild2);
1699  EXPECT_EQ_RECT(IntRect(100, 0, 200, 300), occlusion.unoccludedContentRect(surface, IntRect(0, 0, 300, 300)));
 1745 EXPECT_EQ_RECT(IntRect(100, 0, 150, 300), occlusion.unoccludedContentRect(surface, IntRect(0, 0, 300, 300)));
17001746 occlusion.markOccludedBehindLayer(surfaceChild);
1701  EXPECT_EQ_RECT(IntRect(200, 0, 100, 300), occlusion.unoccludedContentRect(surface, IntRect(0, 0, 300, 300)));
 1747 EXPECT_EQ_RECT(IntRect(200, 0, 50, 300), occlusion.unoccludedContentRect(surface, IntRect(0, 0, 300, 300)));
17021748 occlusion.markOccludedBehindLayer(surface);
17031749 EXPECT_EQ_RECT(IntRect(0, 0, 0, 0), occlusion.unoccludedContentRect(surface, IntRect(0, 0, 300, 300)));
17041750 occlusion.finishedTargetRenderSurface(surface, surface->renderSurface());
1705  occlusion.leaveToTargetRenderSurface(parent->renderSurface());
1706  // Occlusion is lost when leaving the animating surface.
1707  EXPECT_EQ_RECT(IntRect(0, 0, 300, 300), occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300)));
17081751
 1752 // Occlusion within the surface is lost when leaving the animating surface.
 1753 EXPECT_EQ_RECT(IntRect(0, 0, 250, 300), occlusion.unoccludedContributingSurfaceContentRect(surface, IntRect(0, 0, 300, 300)));
 1754
 1755 occlusion.leaveToTargetRenderSurface(parent->renderSurface());
17091756 occlusion.markOccludedBehindLayer(layer);
17101757 // Occlusion is not added for the animating layer.
1711  EXPECT_EQ_RECT(IntRect(0, 0, 300, 300), occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300)));
 1758 EXPECT_EQ_RECT(IntRect(0, 0, 250, 300), occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300)));
17121759 }
17131760};
17141761

@@protected:
17241771 typename Types::ContentLayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300), true);
17251772 typename Types::ContentLayerType* surfaceChild = this->createDrawingLayer(surface, this->identityMatrix, FloatPoint(0, 0), IntSize(200, 300), true);
17261773 typename Types::ContentLayerType* surfaceChild2 = this->createDrawingLayer(surface, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 300), true);
 1774 typename Types::ContentLayerType* topmost = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(250, 0), IntSize(50, 300), true);
17271775
17281776 addOpacityTransitionToController(*layer->layerAnimationController(), 10, 1, 0, false);
17291777 addOpacityTransitionToController(*surface->layerAnimationController(), 10, 1, 0, false);

@@protected:
17351783
17361784 TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
17371785
 1786 occlusion.enterTargetRenderSurface(parent->renderSurface());
 1787 occlusion.markOccludedBehindLayer(topmost);
 1788 // This occlusion will affect all surfaces.
 1789 EXPECT_EQ_RECT(IntRect(0, 0, 250, 300), occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300)));
 1790
17381791 occlusion.enterTargetRenderSurface(surface->renderSurface());
17391792 occlusion.markOccludedBehindLayer(surfaceChild2);
1740  EXPECT_EQ_RECT(IntRect(100, 0, 200, 300), occlusion.unoccludedContentRect(surface, IntRect(0, 0, 300, 300)));
 1793 EXPECT_EQ_RECT(IntRect(100, 0, 150, 300), occlusion.unoccludedContentRect(surface, IntRect(0, 0, 300, 300)));
17411794 occlusion.markOccludedBehindLayer(surfaceChild);
1742  EXPECT_EQ_RECT(IntRect(200, 0, 100, 300), occlusion.unoccludedContentRect(surface, IntRect(0, 0, 300, 300)));
 1795 EXPECT_EQ_RECT(IntRect(200, 0, 50, 300), occlusion.unoccludedContentRect(surface, IntRect(0, 0, 300, 300)));
17431796 occlusion.markOccludedBehindLayer(surface);
17441797 EXPECT_EQ_RECT(IntRect(0, 0, 0, 0), occlusion.unoccludedContentRect(surface, IntRect(0, 0, 300, 300)));
17451798 occlusion.finishedTargetRenderSurface(surface, surface->renderSurface());
1746  occlusion.leaveToTargetRenderSurface(parent->renderSurface());
1747  // Occlusion is lost when leaving the animating surface.
1748  EXPECT_EQ_RECT(IntRect(0, 0, 300, 300), occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300)));
17491799
 1800 // Occlusion within the surface is lost when leaving the animating surface.
 1801 EXPECT_EQ_RECT(IntRect(0, 0, 250, 300), occlusion.unoccludedContributingSurfaceContentRect(surface, IntRect(0, 0, 300, 300)));
 1802
 1803 occlusion.leaveToTargetRenderSurface(parent->renderSurface());
17501804 occlusion.markOccludedBehindLayer(layer);
17511805 // Occlusion is not added for the animating layer.
1752  EXPECT_EQ_RECT(IntRect(0, 0, 300, 300), occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300)));
 1806 EXPECT_EQ_RECT(IntRect(0, 0, 250, 300), occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300)));
17531807 }
17541808};
17551809

@@protected:
18301884
18311885 occlusion.finishedTargetRenderSurface(surface, surface->renderSurface());
18321886 occlusion.leaveToTargetRenderSurface(parent->renderSurface());
1833  // The surface is moving in the screen and in its target, so all occlusion is lost when leaving it.
 1887 // The surface is moving in the screen and in its target, so all occlusion within the surface is lost when leaving it.
18341888 EXPECT_EQ_RECT(IntRect(50, 0, 250, 300), occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300)));
18351889
 1890 // The contributing |surface| is animating so it can't be occluded.
 1891 EXPECT_EQ_RECT(IntRect(0, 0, 300, 300), occlusion.unoccludedContributingSurfaceContentRect(surface, IntRect(0, 0, 300, 300)));
 1892
18361893 occlusion.markOccludedBehindLayer(layer);
18371894 // The layer is animating in the screen and in its target, so no occlusion is added.
18381895 EXPECT_EQ_RECT(IntRect(50, 0, 250, 300), occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300)));

@@protected:
18981955 surface->setOpaqueContentsRect(IntRect(0, 0, 400, 200));
18991956 this->calcDrawEtc(parent);
19001957
1901  TestCCOcclusionTrackerBase<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
 1958 TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
19021959
19031960 occlusion.enterTargetRenderSurface(surface->renderSurface());
19041961 occlusion.markOccludedBehindLayer(surface);

@@protected:
19141971
19151972MAIN_AND_IMPL_THREAD_TEST(CCOcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping);
19161973
 1974template<class Types, bool opaqueLayers>
 1975class CCOcclusionTrackerTestReplicaOccluded : public CCOcclusionTrackerTest<Types, opaqueLayers> {
 1976protected:
 1977 void runMyTest()
 1978 {
 1979 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 200));
 1980 typename Types::LayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100), true);
 1981 this->createReplicaLayer(surface, this->identityMatrix, FloatPoint(0, 100), IntSize(100, 100));
 1982 typename Types::LayerType* topmost = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 100), IntSize(100, 100), true);
 1983 this->calcDrawEtc(parent);
 1984
 1985 TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
 1986 occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
 1987
 1988 // This occludes the replica, but not the surface itself.
 1989 occlusion.enterTargetRenderSurface(parent->renderSurface());
 1990 occlusion.markOccludedBehindLayer(topmost);
 1991
 1992 EXPECT_EQ_RECT(IntRect(0, 100, 100, 100), occlusion.occlusionInScreenSpace().bounds());
 1993 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
 1994 EXPECT_EQ_RECT(IntRect(0, 100, 100, 100), occlusion.occlusionInTargetSurface().bounds());
 1995 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
 1996
 1997 occlusion.enterTargetRenderSurface(surface->renderSurface());
 1998 occlusion.markOccludedBehindLayer(surface);
 1999
 2000 EXPECT_EQ_RECT(IntRect(0, 0, 100, 200), occlusion.occlusionInScreenSpace().bounds());
 2001 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
 2002 EXPECT_EQ_RECT(IntRect(0, 0, 100, 100), occlusion.occlusionInTargetSurface().bounds());
 2003 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
 2004
 2005 occlusion.finishedTargetRenderSurface(surface, surface->renderSurface());
 2006
 2007 // Surface is not occluded so it shouldn't think it is.
 2008 EXPECT_EQ_RECT(IntRect(0, 0, 100, 100), occlusion.unoccludedContributingSurfaceContentRect(surface, IntRect(0, 0, 100, 100)));
 2009 }
 2010};
 2011
 2012ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestReplicaOccluded);
 2013
 2014template<class Types, bool opaqueLayers>
 2015class CCOcclusionTrackerTestSurfaceWithReplicaUnoccluded : public CCOcclusionTrackerTest<Types, opaqueLayers> {
 2016protected:
 2017 void runMyTest()
 2018 {
 2019 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 200));
 2020 typename Types::LayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100), true);
 2021 this->createReplicaLayer(surface, this->identityMatrix, FloatPoint(0, 100), IntSize(100, 100));
 2022 typename Types::LayerType* topmost = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 110), true);
 2023 this->calcDrawEtc(parent);
 2024
 2025 TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
 2026 occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
 2027
 2028 // This occludes the surface, but not the entire surface's replica.
 2029 occlusion.enterTargetRenderSurface(parent->renderSurface());
 2030 occlusion.markOccludedBehindLayer(topmost);
 2031
 2032 EXPECT_EQ_RECT(IntRect(0, 0, 100, 110), occlusion.occlusionInScreenSpace().bounds());
 2033 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
 2034 EXPECT_EQ_RECT(IntRect(0, 0, 100, 110), occlusion.occlusionInTargetSurface().bounds());
 2035 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
 2036
 2037 occlusion.enterTargetRenderSurface(surface->renderSurface());
 2038 occlusion.markOccludedBehindLayer(surface);
 2039
 2040 EXPECT_EQ_RECT(IntRect(0, 0, 100, 110), occlusion.occlusionInScreenSpace().bounds());
 2041 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
 2042 EXPECT_EQ_RECT(IntRect(0, 0, 100, 100), occlusion.occlusionInTargetSurface().bounds());
 2043 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
 2044
 2045 occlusion.finishedTargetRenderSurface(surface, surface->renderSurface());
 2046
 2047 // Surface is occluded, but only the top 10px of the replica, so the rest of the surface should not consider itself occluded.
 2048 EXPECT_EQ_RECT(IntRect(0, 10, 100, 90), occlusion.unoccludedContributingSurfaceContentRect(surface, IntRect(0, 0, 100, 100)));
 2049 }
 2050};
 2051
 2052ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestSurfaceWithReplicaUnoccluded);
 2053
 2054template<class Types, bool opaqueLayers>
 2055class CCOcclusionTrackerTestSurfaceAndReplicaOccludedWithReplicaMore : public CCOcclusionTrackerTest<Types, opaqueLayers> {
 2056protected:
 2057 void runMyTest()
 2058 {
 2059 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 200));
 2060 typename Types::LayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100), true);
 2061 this->createReplicaLayer(surface, this->identityMatrix, FloatPoint(0, 100), IntSize(100, 100));
 2062 typename Types::LayerType* overSurface = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(40, 100), true);
 2063 typename Types::LayerType* overReplica = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 100), IntSize(50, 100), true);
 2064 this->calcDrawEtc(parent);
 2065
 2066 TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
 2067 occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
 2068
 2069 // This occludes the surface, but not the entire surface's replica.
 2070 occlusion.enterTargetRenderSurface(parent->renderSurface());
 2071 occlusion.markOccludedBehindLayer(overReplica);
 2072 occlusion.markOccludedBehindLayer(overSurface);
 2073
 2074 EXPECT_EQ_RECT(IntRect(0, 0, 50, 200), occlusion.occlusionInScreenSpace().bounds());
 2075 EXPECT_EQ(2u, occlusion.occlusionInScreenSpace().rects().size());
 2076 EXPECT_EQ_RECT(IntRect(0, 0, 50, 200), occlusion.occlusionInTargetSurface().bounds());
 2077 EXPECT_EQ(2u, occlusion.occlusionInTargetSurface().rects().size());
 2078
 2079 occlusion.enterTargetRenderSurface(surface->renderSurface());
 2080 occlusion.markOccludedBehindLayer(surface);
 2081
 2082 EXPECT_EQ_RECT(IntRect(0, 0, 100, 200), occlusion.occlusionInScreenSpace().bounds());
 2083 EXPECT_EQ(2u, occlusion.occlusionInScreenSpace().rects().size());
 2084 EXPECT_EQ_RECT(IntRect(0, 0, 100, 100), occlusion.occlusionInTargetSurface().bounds());
 2085 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
 2086
 2087 occlusion.finishedTargetRenderSurface(surface, surface->renderSurface());
 2088
 2089 // Surface is occluded less than replica, so it should dominate what is determined to be unoccluded.
 2090 EXPECT_EQ_RECT(IntRect(40, 0, 60, 100), occlusion.unoccludedContributingSurfaceContentRect(surface, IntRect(0, 0, 100, 100)));
 2091 }
 2092};
 2093
 2094ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestSurfaceAndReplicaOccludedWithReplicaMore);
 2095
 2096template<class Types, bool opaqueLayers>
 2097class CCOcclusionTrackerTestSurfaceAndReplicaOccludedWithSurfaceMore : public CCOcclusionTrackerTest<Types, opaqueLayers> {
 2098protected:
 2099 void runMyTest()
 2100 {
 2101 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 200));
 2102 typename Types::LayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100), true);
 2103 this->createReplicaLayer(surface, this->identityMatrix, FloatPoint(0, 100), IntSize(100, 100));
 2104 typename Types::LayerType* overSurface = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(50, 100), true);
 2105 typename Types::LayerType* overReplica = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 100), IntSize(40, 100), true);
 2106 this->calcDrawEtc(parent);
 2107
 2108 TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
 2109 occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
 2110
 2111 // This occludes the surface, but not the entire surface's replica.
 2112 occlusion.enterTargetRenderSurface(parent->renderSurface());
 2113 occlusion.markOccludedBehindLayer(overReplica);
 2114 occlusion.markOccludedBehindLayer(overSurface);
 2115
 2116 EXPECT_EQ_RECT(IntRect(0, 0, 50, 200), occlusion.occlusionInScreenSpace().bounds());
 2117 EXPECT_EQ(2u, occlusion.occlusionInScreenSpace().rects().size());
 2118 EXPECT_EQ_RECT(IntRect(0, 0, 50, 200), occlusion.occlusionInTargetSurface().bounds());
 2119 EXPECT_EQ(2u, occlusion.occlusionInTargetSurface().rects().size());
 2120
 2121 occlusion.enterTargetRenderSurface(surface->renderSurface());
 2122 occlusion.markOccludedBehindLayer(surface);
 2123
 2124 EXPECT_EQ_RECT(IntRect(0, 0, 100, 200), occlusion.occlusionInScreenSpace().bounds());
 2125 EXPECT_EQ(2u, occlusion.occlusionInScreenSpace().rects().size());
 2126 EXPECT_EQ_RECT(IntRect(0, 0, 100, 100), occlusion.occlusionInTargetSurface().bounds());
 2127 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
 2128
 2129 occlusion.finishedTargetRenderSurface(surface, surface->renderSurface());
 2130
 2131 // Replica is occluded less than the surface, so it should dominate what is determined to be unoccluded.
 2132 EXPECT_EQ_RECT(IntRect(40, 0, 60, 100), occlusion.unoccludedContributingSurfaceContentRect(surface, IntRect(0, 0, 100, 100)));
 2133 }
 2134};
 2135
 2136ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestSurfaceAndReplicaOccludedWithSurfaceMore);
 2137
 2138template<class Types, bool opaqueLayers>
 2139class CCOcclusionTrackerTestSurfaceChildOfSurface : public CCOcclusionTrackerTest<Types, opaqueLayers> {
 2140protected:
 2141 void runMyTest()
 2142 {
 2143 // This test verifies that the surface cliprect does not end up empty and clip away the entire unoccluded rect.
 2144
 2145 typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 200));
 2146 typename Types::LayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100), true);
 2147 typename Types::LayerType* surfaceChild = this->createDrawingSurface(surface, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100), false);
 2148 typename Types::LayerType* topmost = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 50), true);
 2149 this->calcDrawEtc(parent);
 2150
 2151 TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
 2152 occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
 2153
 2154 // This occludes everything partially so we know occlusion is happening at all.
 2155 occlusion.enterTargetRenderSurface(parent->renderSurface());
 2156 occlusion.markOccludedBehindLayer(topmost);
 2157
 2158 EXPECT_EQ_RECT(IntRect(0, 0, 100, 50), occlusion.occlusionInScreenSpace().bounds());
 2159 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
 2160 EXPECT_EQ_RECT(IntRect(0, 0, 100, 50), occlusion.occlusionInTargetSurface().bounds());
 2161 EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
 2162
 2163 occlusion.enterTargetRenderSurface(surfaceChild->renderSurface());
 2164 // surfaceChild is not opaque and does not occlude, so we have a non-empty unoccluded area on surface.
 2165 occlusion.markOccludedBehindLayer(surfaceChild);
 2166
 2167 EXPECT_EQ_RECT(IntRect(0, 0, 100, 50), occlusion.occlusionInScreenSpace().bounds());
 2168 EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
 2169 EXPECT_EQ_RECT(IntRect(0, 0, 0, 0), occlusion.occlusionInTargetSurface().bounds());
 2170 EXPECT_EQ(0u, occlusion.occlusionInTargetSurface().rects().size());
 2171
 2172 // The root layer always has a clipRect. So the parent of |surface| has a clipRect. However, the owning layer for |surface| does not
 2173 // mask to bounds, so it doesn't have a clipRect of its own. Thus the parent of |surfaceChild| exercises different code paths
 2174 // as its parent does not have a clipRect.
 2175
 2176 occlusion.finishedTargetRenderSurface(surfaceChild, surfaceChild->renderSurface());
 2177 // The surfaceChild's parent does not have a clipRect as it owns a render surface.
 2178 EXPECT_EQ_RECT(IntRect(0, 50, 100, 50), occlusion.unoccludedContributingSurfaceContentRect(surfaceChild, IntRect(0, 0, 100, 100)));
 2179
 2180 occlusion.leaveToTargetRenderSurface(surface->renderSurface());
 2181 occlusion.markOccludedBehindLayer(surface);
 2182
 2183 occlusion.finishedTargetRenderSurface(surface, surface->renderSurface());
 2184 // The surface's parent does have a clipRect as it is the root layer.
 2185 EXPECT_EQ_RECT(IntRect(0, 50, 100, 50), occlusion.unoccludedContributingSurfaceContentRect(surface, IntRect(0, 0, 100, 100)));
 2186 }
 2187};
 2188
 2189ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestSurfaceChildOfSurface);
 2190
19172191} // namespace