WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
[patch]
Patch
bug-81227-20120402134707.patch (text/plain), 46.07 KB, created by
Dana Jansens
on 2012-04-02 10:47:08 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Dana Jansens
Created:
2012-04-02 10:47:08 PDT
Size:
46.07 KB
patch
obsolete
>Subversion Revision: 112886 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index fcc3ca69622d459407c6a93c6efb7d05665376ab..ea11f417b3fb5af326821d66c25f9d5ae93e5a98 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,56 @@ >+2012-03-26 Dana Jansens <danakj@chromium.org> >+ >+ [chromium] Cull occluded surface quads >+ https://bugs.webkit.org/show_bug.cgi?id=81227 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ RenderSurface quads should be culled based on occlusion, but it must >+ also account to the replica. We take the union of the unoccluded >+ space in the replica and the original content as the unocclusion >+ rect in the quad. >+ >+ In order to compute occlusion for the surface itself, it must not >+ consider occlusion found in its own subtree. To do this, we reorder >+ the calls to the occlusion tracker, and add the surface quad >+ before we "leaveToTargetRenderSurface" which merges occlusion from >+ the surface's subtree up into its parent. >+ >+ Unit test: CCOcclusionTrackerTestReplicaOccluded >+ CCOcclusionTrackerTestSurfaceWithReplicaUnoccluded >+ CCOcclusionTrackerTestSurfaceAndReplicaOccludedWithSurfaceMore >+ CCOcclusionTrackerTestSurfaceAndReplicaOccludedWithReplicaMore >+ CCOcclusionTrackerTestSurfaceChildOfSurface >+ >+ And added some sanity checks to other CCOcclusionTracker tests that have >+ render surfaces. >+ >+ * platform/graphics/chromium/RenderSurfaceChromium.cpp: >+ (WebCore::RenderSurfaceChromium::hasReplica): >+ (WebCore): >+ * platform/graphics/chromium/RenderSurfaceChromium.h: >+ (RenderSurfaceChromium): >+ * platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp: >+ (WebCore::CCLayerTreeHostImpl::calculateRenderPasses): >+ * platform/graphics/chromium/cc/CCOcclusionTracker.cpp: >+ (WebCore::::leaveToTargetRenderSurface): >+ (WebCore::::unoccludedContributingSurfaceContentRect): >+ (WebCore): >+ * platform/graphics/chromium/cc/CCOcclusionTracker.h: >+ (CCOcclusionTrackerBase): >+ * platform/graphics/chromium/cc/CCQuadCuller.cpp: >+ (WebCore::CCQuadCuller::append): >+ * platform/graphics/chromium/cc/CCRenderPass.cpp: >+ (WebCore::CCRenderPass::appendQuadsForRenderSurfaceLayer): >+ * platform/graphics/chromium/cc/CCRenderPass.h: >+ (CCRenderPass): >+ * platform/graphics/chromium/cc/CCRenderSurface.cpp: >+ (WebCore::CCRenderSurface::drawableContentRect): >+ (WebCore::CCRenderSurface::draw): >+ (WebCore::CCRenderSurface::hasReplica): >+ * platform/graphics/chromium/cc/CCRenderSurface.h: >+ (CCRenderSurface): >+ > 2012-04-02 Alexander Pavlov <apavlov@chromium.org> > > Web Inspector: Implement frontend for device metrics emulation >diff --git a/Source/WebKit/chromium/ChangeLog b/Source/WebKit/chromium/ChangeLog >index 6a787232c79640f1cdd41ef1a3438751411347ae..f25a9c57d70480216ddc436e36e816f661f3bd9d 100644 >--- a/Source/WebKit/chromium/ChangeLog >+++ b/Source/WebKit/chromium/ChangeLog >@@ -1,3 +1,30 @@ >+2012-03-26 Dana Jansens <danakj@chromium.org> >+ >+ [chromium] Cull occluded surface quads >+ https://bugs.webkit.org/show_bug.cgi?id=81227 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * tests/CCOcclusionTrackerTest.cpp: >+ (WebCore::CCOcclusionTrackerTest::TearDown): >+ (WebCore::CCOcclusionTrackerTest::createReplicaLayer): >+ (CCOcclusionTrackerTest): >+ (WebCore::CCOcclusionTrackerTest::setReplica): >+ (WebCore::CCOcclusionTrackerTestOverlappingSurfaceSiblings::runMyTest): >+ (WebCore::CCOcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms::runMyTest): >+ (WebCore::CCOcclusionTrackerTestAnimationOpacity1OnMainThread::runMyTest): >+ (WebCore::CCOcclusionTrackerTestAnimationOpacity0OnMainThread::runMyTest): >+ (WebCore::CCOcclusionTrackerTestAnimationTranslateOnMainThread::runMyTest): >+ (WebCore): >+ (CCOcclusionTrackerTestReplicaOccluded): >+ (WebCore::CCOcclusionTrackerTestReplicaOccluded::runMyTest): >+ (CCOcclusionTrackerTestSurfaceWithReplicaUnoccluded): >+ (WebCore::CCOcclusionTrackerTestSurfaceWithReplicaUnoccluded::runMyTest): >+ (CCOcclusionTrackerTestSurfaceAndReplicaOccludedWithReplicaMore): >+ (WebCore::CCOcclusionTrackerTestSurfaceAndReplicaOccludedWithReplicaMore::runMyTest): >+ (CCOcclusionTrackerTestSurfaceAndReplicaOccludedWithSurfaceMore): >+ (WebCore::CCOcclusionTrackerTestSurfaceAndReplicaOccludedWithSurfaceMore::runMyTest): >+ > 2012-04-02 Kinuko Yasuda <kinuko@chromium.org> > > Unreviewed, rolling chromium DEPS. >diff --git a/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.cpp b/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.cpp >index fbef7a7682a812c530545a617c52f90e2e08a589..4e5528ec83a0ef9949ba112ed2c13bad7082f021 100644 >--- a/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.cpp >+++ b/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.cpp >@@ -64,5 +64,10 @@ FloatRect RenderSurfaceChromium::drawableContentRect() const > return drawableContentRect; > } > >+bool RenderSurfaceChromium::hasReplica() const >+{ >+ return m_owningLayer->replicaLayer(); >+} >+ > } > #endif // USE(ACCELERATED_COMPOSITING) >diff --git a/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.h b/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.h >index 59e5d961dc81d70b6689836232cf9a9cd43687c9..338dd640e13d0137a4bc323ec55e148bf40f5c4a 100644 >--- a/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.h >+++ b/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.h >@@ -108,6 +108,8 @@ public: > void setNearestAncestorThatMovesPixels(RenderSurfaceChromium* surface) { m_nearestAncestorThatMovesPixels = surface; } > const RenderSurfaceChromium* nearestAncestorThatMovesPixels() const { return m_nearestAncestorThatMovesPixels; } > >+ bool hasReplica() const; >+ > private: > LayerChromium* m_owningLayer; > LayerChromium* m_maskLayer; >diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp >index f2e20cf01412220ed116c02214d03e1be45959ed..4297e28c6a66b706105c75fdf2554572e7143cde 100644 >--- a/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp >+++ b/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp >@@ -295,24 +295,21 @@ bool CCLayerTreeHostImpl::calculateRenderPasses(CCRenderPassList& passes, CCLaye > CCLayerIteratorType end = CCLayerIteratorType::end(&renderSurfaceLayerList); > for (CCLayerIteratorType it = CCLayerIteratorType::begin(&renderSurfaceLayerList); it != end; ++it) { > CCRenderSurface* renderSurface = it.targetRenderSurfaceLayer()->renderSurface(); >+ CCRenderPass* pass = surfacePassMap.get(renderSurface); > > if (it.representsItself()) > occlusionTracker.enterTargetRenderSurface(renderSurface); >- else if (it.representsTargetRenderSurface()) >+ else if (it.representsTargetRenderSurface()) { > occlusionTracker.finishedTargetRenderSurface(*it, renderSurface); >- else >- occlusionTracker.leaveToTargetRenderSurface(renderSurface); >- >- if (it.representsTargetRenderSurface()) > continue; >- if (it->visibleLayerRect().isEmpty()) >+ } else { >+ pass->appendQuadsForRenderSurfaceLayer(*it, &occlusionTracker); >+ occlusionTracker.leaveToTargetRenderSurface(renderSurface); > continue; >+ } > >- CCRenderPass* pass = surfacePassMap.get(renderSurface); >- if (it.representsContributingRenderSurface()) { >- pass->appendQuadsForRenderSurfaceLayer(*it); >+ if (it->visibleLayerRect().isEmpty()) > continue; >- } > > it->willDraw(m_layerRenderer.get()); > >diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCOcclusionTracker.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCOcclusionTracker.cpp >index a5411eccf76151ea3bf0035cf998d0bcbdb327bb..d0bc0a9efe74dbd7b20c8a6d7dafbb01ac0a40a0 100644 >--- a/Source/WebCore/platform/graphics/chromium/cc/CCOcclusionTracker.cpp >+++ b/Source/WebCore/platform/graphics/chromium/cc/CCOcclusionTracker.cpp >@@ -137,6 +137,7 @@ void CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::leaveToTargetRenderSu > > const RenderSurfaceType* oldTarget = m_stack[lastIndex].surface; > Region oldTargetOcclusionInNewTarget = transformSurfaceOpaqueRegion<RenderSurfaceType>(oldTarget, m_stack[lastIndex].occlusionInTarget, oldTarget->originTransform()); >+ // FIXME: The replica can occlude things too. > > if (surfaceWillBeAtTopAfterPop) { > // Merge the top of the stack down. >@@ -336,6 +337,63 @@ IntRect CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::unoccludedContentR > } > > template<typename LayerType, typename RenderSurfaceType> >+IntRect CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::unoccludedContributingSurfaceContentRect(const LayerType* layer, const IntRect& contentRect) const >+{ >+ ASSERT(!m_stack.isEmpty()); >+ // 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). >+ if (m_stack.size() < 2) >+ return contentRect; >+ if (contentRect.isEmpty()) >+ return contentRect; >+ >+ // This should be called while the contributing render surface is still considered the current target in the occlusion tracker. >+ ASSERT(layer->targetRenderSurface() == m_stack.last().surface); >+ >+ RenderSurfaceType* surface = layer->renderSurface(); >+ const StackObject& secondLast = m_stack[m_stack.size() - 2]; >+ >+ IntRect unoccludedSurfaceRect = contentRect; >+ IntRect surfaceClipRect = surface->clipRect(); >+ if (surfaceClipRect.isEmpty()) { >+ const RenderSurfaceType* targetSurface = m_stack.last().surface; >+ surfaceClipRect = intersection(targetSurface->contentRect(), enclosingIntRect(surface->drawableContentRect())); >+ } >+ >+ >+ IntRect unoccludedInScreen = contentRect; >+ if (surfaceTransformsToScreenKnown(surface)) >+ unoccludedInScreen = computeUnoccludedContentRect(contentRect, surface->screenSpaceTransform(), m_scissorRectInScreenSpace, secondLast.occlusionInScreen); >+ unoccludedSurfaceRect.intersect(unoccludedInScreen); >+ >+ if (!unoccludedSurfaceRect.isEmpty()) { >+ IntRect unoccludedInTarget = contentRect; >+ if (surfaceTransformsToTargetKnown(surface)) >+ unoccludedInTarget = computeUnoccludedContentRect(contentRect, surface->originTransform(), surfaceClipRect, secondLast.occlusionInTarget); >+ unoccludedSurfaceRect.intersect(unoccludedInTarget); >+ } >+ >+ IntRect unoccludedReplicaRect; >+ if (surface->hasReplica()) { >+ unoccludedReplicaRect = contentRect; >+ >+ IntRect unoccludedInScreen = contentRect; >+ if (surfaceTransformsToScreenKnown(surface)) >+ unoccludedInScreen = computeUnoccludedContentRect(contentRect, surface->replicaScreenSpaceTransform(), m_scissorRectInScreenSpace, secondLast.occlusionInScreen); >+ unoccludedReplicaRect.intersect(unoccludedInScreen); >+ >+ if (!unoccludedSurfaceRect.isEmpty()) { >+ IntRect unoccludedInTarget = contentRect; >+ if (surfaceTransformsToTargetKnown(surface)) >+ unoccludedInTarget = computeUnoccludedContentRect(contentRect, surface->replicaOriginTransform(), surfaceClipRect, secondLast.occlusionInTarget); >+ unoccludedReplicaRect.intersect(unoccludedInTarget); >+ } >+ } >+ >+ return unionRect(unoccludedSurfaceRect, unoccludedReplicaRect); >+} >+ >+template<typename LayerType, typename RenderSurfaceType> > IntRect CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::layerScissorRectInTargetSurface(const LayerType* layer) const > { > const RenderSurfaceType* targetSurface = m_stack.last().surface; >@@ -353,6 +411,7 @@ template void CCOcclusionTrackerBase<LayerChromium, RenderSurfaceChromium>::leav > template void CCOcclusionTrackerBase<LayerChromium, RenderSurfaceChromium>::markOccludedBehindLayer(const LayerChromium*); > template bool CCOcclusionTrackerBase<LayerChromium, RenderSurfaceChromium>::occluded(const LayerChromium*, const IntRect& contentRect) const; > template IntRect CCOcclusionTrackerBase<LayerChromium, RenderSurfaceChromium>::unoccludedContentRect(const LayerChromium*, const IntRect& contentRect) const; >+template IntRect CCOcclusionTrackerBase<LayerChromium, RenderSurfaceChromium>::unoccludedContributingSurfaceContentRect(const LayerChromium*, const IntRect& contentRect) const; > template IntRect CCOcclusionTrackerBase<LayerChromium, RenderSurfaceChromium>::layerScissorRectInTargetSurface(const LayerChromium*) const; > > template CCOcclusionTrackerBase<CCLayerImpl, CCRenderSurface>::CCOcclusionTrackerBase(IntRect scissorRectInScreenSpace, bool recordMetricsForFrame); >@@ -362,6 +421,7 @@ template void CCOcclusionTrackerBase<CCLayerImpl, CCRenderSurface>::leaveToTarge > template void CCOcclusionTrackerBase<CCLayerImpl, CCRenderSurface>::markOccludedBehindLayer(const CCLayerImpl*); > template bool CCOcclusionTrackerBase<CCLayerImpl, CCRenderSurface>::occluded(const CCLayerImpl*, const IntRect& contentRect) const; > template IntRect CCOcclusionTrackerBase<CCLayerImpl, CCRenderSurface>::unoccludedContentRect(const CCLayerImpl*, const IntRect& contentRect) const; >+template IntRect CCOcclusionTrackerBase<CCLayerImpl, CCRenderSurface>::unoccludedContributingSurfaceContentRect(const CCLayerImpl*, const IntRect& contentRect) const; > template IntRect CCOcclusionTrackerBase<CCLayerImpl, CCRenderSurface>::layerScissorRectInTargetSurface(const CCLayerImpl*) const; > > >diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCOcclusionTracker.h b/Source/WebCore/platform/graphics/chromium/cc/CCOcclusionTracker.h >index 6b2b6e1668b57959c138204572332f9cf7a9344f..043b0cad3efcee521ce2bf0c7130fc1daff38a39 100644 >--- a/Source/WebCore/platform/graphics/chromium/cc/CCOcclusionTracker.h >+++ b/Source/WebCore/platform/graphics/chromium/cc/CCOcclusionTracker.h >@@ -67,6 +67,10 @@ public: > // 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. > IntRect unoccludedContentRect(const LayerType*, const IntRect& contentRect) const; > >+ // Gives an unoccluded sub-rect of |contentRect| in the content space of the surface owned by |layer|. Used when considering occlusion for a surface >+ // that is rendering into another target surface. >+ IntRect unoccludedContributingSurfaceContentRect(const LayerType*, const IntRect& contentRect) const; >+ > // Report operations for recording overdraw metrics. > CCOverdrawMetrics& overdrawMetrics() const { return *m_overdrawMetrics.get(); } > >diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCQuadCuller.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCQuadCuller.cpp >index 35d19461779592feb4ef8471b38fe0d5ef9c8440..920b4e74d712b9e1300c8c4d175759293ccf8c6a 100644 >--- a/Source/WebCore/platform/graphics/chromium/cc/CCQuadCuller.cpp >+++ b/Source/WebCore/platform/graphics/chromium/cc/CCQuadCuller.cpp >@@ -50,7 +50,11 @@ CCQuadCuller::CCQuadCuller(CCQuadList& quadList, CCLayerImpl* layer, CCOcclusion > bool CCQuadCuller::append(PassOwnPtr<CCDrawQuad> passDrawQuad) > { > OwnPtr<CCDrawQuad> drawQuad(passDrawQuad); >- IntRect culledRect = m_occlusionTracker->unoccludedContentRect(m_layer, drawQuad->quadRect()); >+ IntRect culledRect; >+ if (drawQuad->material() == CCDrawQuad::RenderSurface) >+ culledRect = m_occlusionTracker->unoccludedContributingSurfaceContentRect(m_layer, drawQuad->quadRect()); >+ else >+ culledRect = m_occlusionTracker->unoccludedContentRect(m_layer, drawQuad->quadRect()); > bool keepQuad = !culledRect.isEmpty(); > if (keepQuad) > drawQuad->setQuadVisibleRect(culledRect); >diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCRenderPass.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCRenderPass.cpp >index 1704a616d5b3134c9ac9a8461da8a4db2ff10eb7..6ed3985841e4e9cad4d2672c87113de88f582cdd 100644 >--- a/Source/WebCore/platform/graphics/chromium/cc/CCRenderPass.cpp >+++ b/Source/WebCore/platform/graphics/chromium/cc/CCRenderPass.cpp >@@ -66,25 +66,27 @@ void CCRenderPass::appendQuadsForLayer(CCLayerImpl* layer, CCOcclusionTrackerImp > m_sharedQuadStateList.append(sharedQuadState.release()); > } > >-void CCRenderPass::appendQuadsForRenderSurfaceLayer(CCLayerImpl* layer) >+void CCRenderPass::appendQuadsForRenderSurfaceLayer(CCLayerImpl* layer, CCOcclusionTrackerImpl* occlusionTracker) > { > // FIXME: render surface layers should be a CCLayerImpl-derived class and > // not be handled specially here. >+ CCQuadCuller quadCuller(m_quadList, layer, occlusionTracker); >+ > CCRenderSurface* surface = layer->renderSurface(); > OwnPtr<CCSharedQuadState> sharedQuadState = surface->createSharedQuadState(); > > if (layer->hasDebugBorders()) { > Color color(debugSurfaceBorderColorRed, debugSurfaceBorderColorGreen, debugSurfaceBorderColorBlue, debugSurfaceBorderAlpha); >- m_quadList.append(CCDebugBorderDrawQuad::create(sharedQuadState.get(), surface->contentRect(), color, debugSurfaceBorderWidth)); >+ quadCuller.append(CCDebugBorderDrawQuad::create(sharedQuadState.get(), surface->contentRect(), color, debugSurfaceBorderWidth)); > if (surface->hasReplica()) { > OwnPtr<CCSharedQuadState> sharedQuadState = surface->createReplicaSharedQuadState(); > Color color(debugReplicaBorderColorRed, debugReplicaBorderColorGreen, debugReplicaBorderColorBlue, debugSurfaceBorderAlpha); >- m_quadList.append(CCDebugBorderDrawQuad::create(sharedQuadState.get(), surface->contentRect(), color, debugSurfaceBorderWidth)); >+ quadCuller.append(CCDebugBorderDrawQuad::create(sharedQuadState.get(), surface->contentRect(), color, debugSurfaceBorderWidth)); > m_sharedQuadStateList.append(sharedQuadState.release()); > } > } > >- m_quadList.append(CCRenderSurfaceDrawQuad::create(sharedQuadState.get(), surface->contentRect(), layer, surfaceDamageRect())); >+ quadCuller.append(CCRenderSurfaceDrawQuad::create(sharedQuadState.get(), surface->contentRect(), layer, surfaceDamageRect())); > m_sharedQuadStateList.append(sharedQuadState.release()); > } > >diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCRenderPass.h b/Source/WebCore/platform/graphics/chromium/cc/CCRenderPass.h >index 59901c8c58cf376a0c1f0cc09c578ee04d3162e3..9f3a7e79d58d373b4e7fd1daf84873ad62e2ca5c 100644 >--- a/Source/WebCore/platform/graphics/chromium/cc/CCRenderPass.h >+++ b/Source/WebCore/platform/graphics/chromium/cc/CCRenderPass.h >@@ -55,7 +55,7 @@ public: > static PassOwnPtr<CCRenderPass> create(CCRenderSurface*); > > void appendQuadsForLayer(CCLayerImpl*, CCOcclusionTrackerImpl*, bool& usedCheckerboard); >- void appendQuadsForRenderSurfaceLayer(CCLayerImpl*); >+ void appendQuadsForRenderSurfaceLayer(CCLayerImpl*, CCOcclusionTrackerImpl*); > > const CCQuadList& quadList() const { return m_quadList; } > CCRenderSurface* targetSurface() const { return m_targetSurface; } >diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCRenderSurface.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCRenderSurface.cpp >index 815f1efeb32f6266f93d60686be84dc00fdb05a5..bc108e8aa9a47f7cc4c09e860ccaa12e6c3228aa 100644 >--- a/Source/WebCore/platform/graphics/chromium/cc/CCRenderSurface.cpp >+++ b/Source/WebCore/platform/graphics/chromium/cc/CCRenderSurface.cpp >@@ -271,7 +271,7 @@ int CCRenderSurface::owningLayerId() const > return m_owningLayer ? m_owningLayer->id() : 0; > } > >-bool CCRenderSurface::hasReplica() >+bool CCRenderSurface::hasReplica() const > { > return m_owningLayer->replicaLayer(); > } >diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCRenderSurface.h b/Source/WebCore/platform/graphics/chromium/cc/CCRenderSurface.h >index ac48655a3962e67a4ce7dbf4c922117a3234e239..f7dbcf5aa730312815b71dc7a8de8990398966d5 100644 >--- a/Source/WebCore/platform/graphics/chromium/cc/CCRenderSurface.h >+++ b/Source/WebCore/platform/graphics/chromium/cc/CCRenderSurface.h >@@ -127,7 +127,7 @@ public: > > int owningLayerId() const; > >- bool hasReplica(); >+ bool hasReplica() const; > > void resetPropertyChangedFlag() { m_surfacePropertyChanged = false; } > bool surfacePropertyChanged() const; >diff --git a/Source/WebKit/chromium/tests/CCOcclusionTrackerTest.cpp b/Source/WebKit/chromium/tests/CCOcclusionTrackerTest.cpp >index ccbb0c2b75cd5bd6efe2253b40a263096369af41..a5cfda62322817098efa0a47ccf987621ec7fb1c 100644 >--- a/Source/WebKit/chromium/tests/CCOcclusionTrackerTest.cpp >+++ b/Source/WebKit/chromium/tests/CCOcclusionTrackerTest.cpp >@@ -135,6 +135,7 @@ protected: > m_root.clear(); > m_renderSurfaceLayerListChromium.clear(); > m_renderSurfaceLayerListImpl.clear(); >+ m_replicaLayers.clear(); > CCLayerTreeHost::setNeedsFilterContext(false); > } > >@@ -187,6 +188,15 @@ protected: > return layerPtr; > } > >+ typename Types::LayerType* createReplicaLayer(typename Types::LayerType* owningLayer, const TransformationMatrix& transform, const FloatPoint& position, const IntSize& bounds) >+ { >+ typename Types::ContentLayerPtrType layer(Types::createContentLayer()); >+ typename Types::ContentLayerType* layerPtr = layer.get(); >+ setProperties(layerPtr, transform, position, bounds); >+ setReplica(owningLayer, layer.release()); >+ return layerPtr; >+ } >+ > typename Types::ContentLayerType* createDrawingSurface(typename Types::LayerType* parent, const TransformationMatrix& transform, const FloatPoint& position, const IntSize& bounds, bool opaque) > { > typename Types::ContentLayerType* layer = createDrawingLayer(parent, transform, position, bounds, opaque); >@@ -253,10 +263,22 @@ private: > layer->setContentBounds(layer->bounds()); > } > >+ void setReplica(LayerChromium* owningLayer, PassRefPtr<LayerChromium> layer) >+ { >+ owningLayer->setReplicaLayer(layer.get()); >+ m_replicaLayers.append(layer); >+ } >+ >+ void setReplica(CCLayerImpl* owningLayer, PassOwnPtr<CCLayerImpl> layer) >+ { >+ owningLayer->setReplicaLayer(layer); >+ } >+ > // These hold ownership of the layers for the duration of the test. > typename Types::LayerPtrType m_root; > Vector<RefPtr<LayerChromium> > m_renderSurfaceLayerListChromium; > Vector<CCLayerImpl*> m_renderSurfaceLayerListImpl; >+ Vector<RefPtr<LayerChromium> > m_replicaLayers; > }; > > #define RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \ >@@ -902,6 +924,10 @@ protected: > > occlusion.markOccludedBehindLayer(child2); > occlusion.finishedTargetRenderSurface(child2, child2->renderSurface()); >+ >+ // There is nothing above child2's surface in the z-order. >+ EXPECT_EQ_RECT(IntRect(-10, 420, 70, 80), occlusion.unoccludedContributingSurfaceContentRect(child2, IntRect(-10, 420, 70, 80))); >+ > occlusion.leaveToTargetRenderSurface(parent->renderSurface()); > occlusion.enterTargetRenderSurface(child1->renderSurface()); > occlusion.markOccludedBehindLayer(layer1); >@@ -919,6 +945,10 @@ protected: > > occlusion.markOccludedBehindLayer(child1); > occlusion.finishedTargetRenderSurface(child1, child1->renderSurface()); >+ >+ // child2's contents will occlude child1 below it. >+ EXPECT_EQ_RECT(IntRect(-10, 430, 10, 70), occlusion.unoccludedContributingSurfaceContentRect(child1, IntRect(-10, 430, 80, 70))); >+ > occlusion.leaveToTargetRenderSurface(parent->renderSurface()); > > EXPECT_EQ_RECT(IntRect(20, 20, 80, 80), occlusion.occlusionInScreenSpace().bounds()); >@@ -1006,6 +1036,10 @@ protected: > occlusion.markOccludedBehindLayer(child2); > occlusion.finishedTargetRenderSurface(child2, child2->renderSurface()); > occlusion.leaveToTargetRenderSurface(parent->renderSurface()); >+ >+ // There is nothing above child2's surface in the z-order. >+ EXPECT_EQ_RECT(IntRect(-10, 420, 70, 80), occlusion.unoccludedContributingSurfaceContentRect(child2, IntRect(-10, 420, 70, 80))); >+ > occlusion.enterTargetRenderSurface(child1->renderSurface()); > occlusion.markOccludedBehindLayer(layer1); > >@@ -1022,6 +1056,12 @@ protected: > > occlusion.markOccludedBehindLayer(child1); > occlusion.finishedTargetRenderSurface(child1, child1->renderSurface()); >+ >+ // child2's contents will occlude child1 below it. >+ EXPECT_EQ_RECT(IntRect(420, -20, 80, 90), occlusion.unoccludedContributingSurfaceContentRect(child1, IntRect(420, -20, 80, 90))); >+ EXPECT_EQ_RECT(IntRect(490, -10, 10, 80), occlusion.unoccludedContributingSurfaceContentRect(child1, IntRect(420, -10, 80, 90))); >+ EXPECT_EQ_RECT(IntRect(420, -20, 70, 10), occlusion.unoccludedContributingSurfaceContentRect(child1, IntRect(420, -20, 70, 90))); >+ > occlusion.leaveToTargetRenderSurface(parent->renderSurface()); > > EXPECT_EQ_RECT(IntRect(10, 20, 90, 80), occlusion.occlusionInScreenSpace().bounds()); >@@ -1683,6 +1723,7 @@ protected: > typename Types::ContentLayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300), true); > typename Types::ContentLayerType* surfaceChild = this->createDrawingLayer(surface, this->identityMatrix, FloatPoint(0, 0), IntSize(200, 300), true); > typename Types::ContentLayerType* surfaceChild2 = this->createDrawingLayer(surface, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 300), true); >+ typename Types::ContentLayerType* topmost = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(250, 0), IntSize(50, 300), true); > > addOpacityTransitionToController(*layer->layerAnimationController(), 10, 0, 1, false); > addOpacityTransitionToController(*surface->layerAnimationController(), 10, 0, 1, false); >@@ -1694,21 +1735,27 @@ protected: > > TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000)); > >+ occlusion.enterTargetRenderSurface(parent->renderSurface()); >+ occlusion.markOccludedBehindLayer(topmost); >+ // This occlusion will affect all surfaces. >+ EXPECT_EQ_RECT(IntRect(0, 0, 250, 300), occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300))); >+ > occlusion.enterTargetRenderSurface(surface->renderSurface()); > occlusion.markOccludedBehindLayer(surfaceChild2); >- EXPECT_EQ_RECT(IntRect(100, 0, 200, 300), occlusion.unoccludedContentRect(surface, IntRect(0, 0, 300, 300))); >+ EXPECT_EQ_RECT(IntRect(100, 0, 150, 300), occlusion.unoccludedContentRect(surface, IntRect(0, 0, 300, 300))); > occlusion.markOccludedBehindLayer(surfaceChild); >- EXPECT_EQ_RECT(IntRect(200, 0, 100, 300), occlusion.unoccludedContentRect(surface, IntRect(0, 0, 300, 300))); >+ EXPECT_EQ_RECT(IntRect(200, 0, 50, 300), occlusion.unoccludedContentRect(surface, IntRect(0, 0, 300, 300))); > occlusion.markOccludedBehindLayer(surface); > EXPECT_EQ_RECT(IntRect(0, 0, 0, 0), occlusion.unoccludedContentRect(surface, IntRect(0, 0, 300, 300))); > occlusion.finishedTargetRenderSurface(surface, surface->renderSurface()); >- occlusion.leaveToTargetRenderSurface(parent->renderSurface()); >- // Occlusion is lost when leaving the animating surface. >- EXPECT_EQ_RECT(IntRect(0, 0, 300, 300), occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300))); > >+ // Occlusion within the surface is lost when leaving the animating surface. >+ EXPECT_EQ_RECT(IntRect(0, 0, 250, 300), occlusion.unoccludedContributingSurfaceContentRect(surface, IntRect(0, 0, 300, 300))); >+ >+ occlusion.leaveToTargetRenderSurface(parent->renderSurface()); > occlusion.markOccludedBehindLayer(layer); > // Occlusion is not added for the animating layer. >- EXPECT_EQ_RECT(IntRect(0, 0, 300, 300), occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300))); >+ EXPECT_EQ_RECT(IntRect(0, 0, 250, 300), occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300))); > } > }; > >@@ -1724,6 +1771,7 @@ protected: > typename Types::ContentLayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300), true); > typename Types::ContentLayerType* surfaceChild = this->createDrawingLayer(surface, this->identityMatrix, FloatPoint(0, 0), IntSize(200, 300), true); > typename Types::ContentLayerType* surfaceChild2 = this->createDrawingLayer(surface, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 300), true); >+ typename Types::ContentLayerType* topmost = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(250, 0), IntSize(50, 300), true); > > addOpacityTransitionToController(*layer->layerAnimationController(), 10, 1, 0, false); > addOpacityTransitionToController(*surface->layerAnimationController(), 10, 1, 0, false); >@@ -1735,21 +1783,27 @@ protected: > > TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000)); > >+ occlusion.enterTargetRenderSurface(parent->renderSurface()); >+ occlusion.markOccludedBehindLayer(topmost); >+ // This occlusion will affect all surfaces. >+ EXPECT_EQ_RECT(IntRect(0, 0, 250, 300), occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300))); >+ > occlusion.enterTargetRenderSurface(surface->renderSurface()); > occlusion.markOccludedBehindLayer(surfaceChild2); >- EXPECT_EQ_RECT(IntRect(100, 0, 200, 300), occlusion.unoccludedContentRect(surface, IntRect(0, 0, 300, 300))); >+ EXPECT_EQ_RECT(IntRect(100, 0, 150, 300), occlusion.unoccludedContentRect(surface, IntRect(0, 0, 300, 300))); > occlusion.markOccludedBehindLayer(surfaceChild); >- EXPECT_EQ_RECT(IntRect(200, 0, 100, 300), occlusion.unoccludedContentRect(surface, IntRect(0, 0, 300, 300))); >+ EXPECT_EQ_RECT(IntRect(200, 0, 50, 300), occlusion.unoccludedContentRect(surface, IntRect(0, 0, 300, 300))); > occlusion.markOccludedBehindLayer(surface); > EXPECT_EQ_RECT(IntRect(0, 0, 0, 0), occlusion.unoccludedContentRect(surface, IntRect(0, 0, 300, 300))); > occlusion.finishedTargetRenderSurface(surface, surface->renderSurface()); >- occlusion.leaveToTargetRenderSurface(parent->renderSurface()); >- // Occlusion is lost when leaving the animating surface. >- EXPECT_EQ_RECT(IntRect(0, 0, 300, 300), occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300))); > >+ // Occlusion within the surface is lost when leaving the animating surface. >+ EXPECT_EQ_RECT(IntRect(0, 0, 250, 300), occlusion.unoccludedContributingSurfaceContentRect(surface, IntRect(0, 0, 300, 300))); >+ >+ occlusion.leaveToTargetRenderSurface(parent->renderSurface()); > occlusion.markOccludedBehindLayer(layer); > // Occlusion is not added for the animating layer. >- EXPECT_EQ_RECT(IntRect(0, 0, 300, 300), occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300))); >+ EXPECT_EQ_RECT(IntRect(0, 0, 250, 300), occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300))); > } > }; > >@@ -1830,9 +1884,12 @@ protected: > > occlusion.finishedTargetRenderSurface(surface, surface->renderSurface()); > occlusion.leaveToTargetRenderSurface(parent->renderSurface()); >- // The surface is moving in the screen and in its target, so all occlusion is lost when leaving it. >+ // The surface is moving in the screen and in its target, so all occlusion within the surface is lost when leaving it. > EXPECT_EQ_RECT(IntRect(50, 0, 250, 300), occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300))); > >+ // The contributing |surface| is animating so it can't be occluded. >+ EXPECT_EQ_RECT(IntRect(0, 0, 300, 300), occlusion.unoccludedContributingSurfaceContentRect(surface, IntRect(0, 0, 300, 300))); >+ > occlusion.markOccludedBehindLayer(layer); > // The layer is animating in the screen and in its target, so no occlusion is added. > EXPECT_EQ_RECT(IntRect(50, 0, 250, 300), occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300))); >@@ -1898,7 +1955,7 @@ protected: > surface->setOpaqueContentsRect(IntRect(0, 0, 400, 200)); > this->calcDrawEtc(parent); > >- TestCCOcclusionTrackerBase<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000)); >+ TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000)); > > occlusion.enterTargetRenderSurface(surface->renderSurface()); > occlusion.markOccludedBehindLayer(surface); >@@ -1914,4 +1971,221 @@ protected: > > MAIN_AND_IMPL_THREAD_TEST(CCOcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping); > >+template<class Types, bool opaqueLayers> >+class CCOcclusionTrackerTestReplicaOccluded : public CCOcclusionTrackerTest<Types, opaqueLayers> { >+protected: >+ void runMyTest() >+ { >+ typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 200)); >+ typename Types::LayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100), true); >+ this->createReplicaLayer(surface, this->identityMatrix, FloatPoint(0, 100), IntSize(100, 100)); >+ typename Types::LayerType* topmost = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 100), IntSize(100, 100), true); >+ this->calcDrawEtc(parent); >+ >+ TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000)); >+ occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000)); >+ >+ // This occludes the replica, but not the surface itself. >+ occlusion.enterTargetRenderSurface(parent->renderSurface()); >+ occlusion.markOccludedBehindLayer(topmost); >+ >+ EXPECT_EQ_RECT(IntRect(0, 100, 100, 100), occlusion.occlusionInScreenSpace().bounds()); >+ EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size()); >+ EXPECT_EQ_RECT(IntRect(0, 100, 100, 100), occlusion.occlusionInTargetSurface().bounds()); >+ EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size()); >+ >+ occlusion.enterTargetRenderSurface(surface->renderSurface()); >+ occlusion.markOccludedBehindLayer(surface); >+ >+ EXPECT_EQ_RECT(IntRect(0, 0, 100, 200), occlusion.occlusionInScreenSpace().bounds()); >+ EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size()); >+ EXPECT_EQ_RECT(IntRect(0, 0, 100, 100), occlusion.occlusionInTargetSurface().bounds()); >+ EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size()); >+ >+ occlusion.finishedTargetRenderSurface(surface, surface->renderSurface()); >+ >+ // Surface is not occluded so it shouldn't think it is. >+ EXPECT_EQ_RECT(IntRect(0, 0, 100, 100), occlusion.unoccludedContributingSurfaceContentRect(surface, IntRect(0, 0, 100, 100))); >+ } >+}; >+ >+ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestReplicaOccluded); >+ >+template<class Types, bool opaqueLayers> >+class CCOcclusionTrackerTestSurfaceWithReplicaUnoccluded : public CCOcclusionTrackerTest<Types, opaqueLayers> { >+protected: >+ void runMyTest() >+ { >+ typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 200)); >+ typename Types::LayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100), true); >+ this->createReplicaLayer(surface, this->identityMatrix, FloatPoint(0, 100), IntSize(100, 100)); >+ typename Types::LayerType* topmost = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 110), true); >+ this->calcDrawEtc(parent); >+ >+ TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000)); >+ occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000)); >+ >+ // This occludes the surface, but not the entire surface's replica. >+ occlusion.enterTargetRenderSurface(parent->renderSurface()); >+ occlusion.markOccludedBehindLayer(topmost); >+ >+ EXPECT_EQ_RECT(IntRect(0, 0, 100, 110), occlusion.occlusionInScreenSpace().bounds()); >+ EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size()); >+ EXPECT_EQ_RECT(IntRect(0, 0, 100, 110), occlusion.occlusionInTargetSurface().bounds()); >+ EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size()); >+ >+ occlusion.enterTargetRenderSurface(surface->renderSurface()); >+ occlusion.markOccludedBehindLayer(surface); >+ >+ EXPECT_EQ_RECT(IntRect(0, 0, 100, 110), occlusion.occlusionInScreenSpace().bounds()); >+ EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size()); >+ EXPECT_EQ_RECT(IntRect(0, 0, 100, 100), occlusion.occlusionInTargetSurface().bounds()); >+ EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size()); >+ >+ occlusion.finishedTargetRenderSurface(surface, surface->renderSurface()); >+ >+ // Surface is occluded, but only the top 10px of the replica, so the rest of the surface should not consider itself occluded. >+ EXPECT_EQ_RECT(IntRect(0, 10, 100, 90), occlusion.unoccludedContributingSurfaceContentRect(surface, IntRect(0, 0, 100, 100))); >+ } >+}; >+ >+ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestSurfaceWithReplicaUnoccluded); >+ >+template<class Types, bool opaqueLayers> >+class CCOcclusionTrackerTestSurfaceAndReplicaOccludedWithReplicaMore : public CCOcclusionTrackerTest<Types, opaqueLayers> { >+protected: >+ void runMyTest() >+ { >+ typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 200)); >+ typename Types::LayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100), true); >+ this->createReplicaLayer(surface, this->identityMatrix, FloatPoint(0, 100), IntSize(100, 100)); >+ typename Types::LayerType* overSurface = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(40, 100), true); >+ typename Types::LayerType* overReplica = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 100), IntSize(50, 100), true); >+ this->calcDrawEtc(parent); >+ >+ TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000)); >+ occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000)); >+ >+ // This occludes the surface, but not the entire surface's replica. >+ occlusion.enterTargetRenderSurface(parent->renderSurface()); >+ occlusion.markOccludedBehindLayer(overReplica); >+ occlusion.markOccludedBehindLayer(overSurface); >+ >+ EXPECT_EQ_RECT(IntRect(0, 0, 50, 200), occlusion.occlusionInScreenSpace().bounds()); >+ EXPECT_EQ(2u, occlusion.occlusionInScreenSpace().rects().size()); >+ EXPECT_EQ_RECT(IntRect(0, 0, 50, 200), occlusion.occlusionInTargetSurface().bounds()); >+ EXPECT_EQ(2u, occlusion.occlusionInTargetSurface().rects().size()); >+ >+ occlusion.enterTargetRenderSurface(surface->renderSurface()); >+ occlusion.markOccludedBehindLayer(surface); >+ >+ EXPECT_EQ_RECT(IntRect(0, 0, 100, 200), occlusion.occlusionInScreenSpace().bounds()); >+ EXPECT_EQ(2u, occlusion.occlusionInScreenSpace().rects().size()); >+ EXPECT_EQ_RECT(IntRect(0, 0, 100, 100), occlusion.occlusionInTargetSurface().bounds()); >+ EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size()); >+ >+ occlusion.finishedTargetRenderSurface(surface, surface->renderSurface()); >+ >+ // Surface is occluded less than replica, so it should dominate what is determined to be unoccluded. >+ EXPECT_EQ_RECT(IntRect(40, 0, 60, 100), occlusion.unoccludedContributingSurfaceContentRect(surface, IntRect(0, 0, 100, 100))); >+ } >+}; >+ >+ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestSurfaceAndReplicaOccludedWithReplicaMore); >+ >+template<class Types, bool opaqueLayers> >+class CCOcclusionTrackerTestSurfaceAndReplicaOccludedWithSurfaceMore : public CCOcclusionTrackerTest<Types, opaqueLayers> { >+protected: >+ void runMyTest() >+ { >+ typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 200)); >+ typename Types::LayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100), true); >+ this->createReplicaLayer(surface, this->identityMatrix, FloatPoint(0, 100), IntSize(100, 100)); >+ typename Types::LayerType* overSurface = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(50, 100), true); >+ typename Types::LayerType* overReplica = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 100), IntSize(40, 100), true); >+ this->calcDrawEtc(parent); >+ >+ TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000)); >+ occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000)); >+ >+ // This occludes the surface, but not the entire surface's replica. >+ occlusion.enterTargetRenderSurface(parent->renderSurface()); >+ occlusion.markOccludedBehindLayer(overReplica); >+ occlusion.markOccludedBehindLayer(overSurface); >+ >+ EXPECT_EQ_RECT(IntRect(0, 0, 50, 200), occlusion.occlusionInScreenSpace().bounds()); >+ EXPECT_EQ(2u, occlusion.occlusionInScreenSpace().rects().size()); >+ EXPECT_EQ_RECT(IntRect(0, 0, 50, 200), occlusion.occlusionInTargetSurface().bounds()); >+ EXPECT_EQ(2u, occlusion.occlusionInTargetSurface().rects().size()); >+ >+ occlusion.enterTargetRenderSurface(surface->renderSurface()); >+ occlusion.markOccludedBehindLayer(surface); >+ >+ EXPECT_EQ_RECT(IntRect(0, 0, 100, 200), occlusion.occlusionInScreenSpace().bounds()); >+ EXPECT_EQ(2u, occlusion.occlusionInScreenSpace().rects().size()); >+ EXPECT_EQ_RECT(IntRect(0, 0, 100, 100), occlusion.occlusionInTargetSurface().bounds()); >+ EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size()); >+ >+ occlusion.finishedTargetRenderSurface(surface, surface->renderSurface()); >+ >+ // Replica is occluded less than the surface, so it should dominate what is determined to be unoccluded. >+ EXPECT_EQ_RECT(IntRect(40, 0, 60, 100), occlusion.unoccludedContributingSurfaceContentRect(surface, IntRect(0, 0, 100, 100))); >+ } >+}; >+ >+ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestSurfaceAndReplicaOccludedWithSurfaceMore); >+ >+template<class Types, bool opaqueLayers> >+class CCOcclusionTrackerTestSurfaceChildOfSurface : public CCOcclusionTrackerTest<Types, opaqueLayers> { >+protected: >+ void runMyTest() >+ { >+ // This test verifies that the surface cliprect does not end up empty and clip away the entire unoccluded rect. >+ >+ typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 200)); >+ typename Types::LayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100), true); >+ typename Types::LayerType* surfaceChild = this->createDrawingSurface(surface, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100), false); >+ typename Types::LayerType* topmost = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 50), true); >+ this->calcDrawEtc(parent); >+ >+ TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000)); >+ occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000)); >+ >+ // This occludes everything partially so we know occlusion is happening at all. >+ occlusion.enterTargetRenderSurface(parent->renderSurface()); >+ occlusion.markOccludedBehindLayer(topmost); >+ >+ EXPECT_EQ_RECT(IntRect(0, 0, 100, 50), occlusion.occlusionInScreenSpace().bounds()); >+ EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size()); >+ EXPECT_EQ_RECT(IntRect(0, 0, 100, 50), occlusion.occlusionInTargetSurface().bounds()); >+ EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size()); >+ >+ occlusion.enterTargetRenderSurface(surfaceChild->renderSurface()); >+ // surfaceChild is not opaque and does not occlude, so we have a non-empty unoccluded area on surface. >+ occlusion.markOccludedBehindLayer(surfaceChild); >+ >+ EXPECT_EQ_RECT(IntRect(0, 0, 100, 50), occlusion.occlusionInScreenSpace().bounds()); >+ EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size()); >+ EXPECT_EQ_RECT(IntRect(0, 0, 0, 0), occlusion.occlusionInTargetSurface().bounds()); >+ EXPECT_EQ(0u, occlusion.occlusionInTargetSurface().rects().size()); >+ >+ // 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 >+ // as its parent does not have a clipRect. >+ >+ occlusion.finishedTargetRenderSurface(surfaceChild, surfaceChild->renderSurface()); >+ // The surfaceChild's parent does not have a clipRect as it owns a render surface. >+ EXPECT_EQ_RECT(IntRect(0, 50, 100, 50), occlusion.unoccludedContributingSurfaceContentRect(surfaceChild, IntRect(0, 0, 100, 100))); >+ >+ occlusion.leaveToTargetRenderSurface(surface->renderSurface()); >+ occlusion.markOccludedBehindLayer(surface); >+ >+ occlusion.finishedTargetRenderSurface(surface, surface->renderSurface()); >+ // The surface's parent does have a clipRect as it is the root layer. >+ EXPECT_EQ_RECT(IntRect(0, 50, 100, 50), occlusion.unoccludedContributingSurfaceContentRect(surface, IntRect(0, 0, 100, 100))); >+ } >+}; >+ >+ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestSurfaceChildOfSurface); >+ > } // namespace
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 81227
:
133942
|
133969
|
135131
|
135862
|
136107
|
136205
|
136212
|
136283