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-83217-20120406184559.patch (text/plain), 13.96 KB, created by
Dana Jansens
on 2012-04-06 15:46:01 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Dana Jansens
Created:
2012-04-06 15:46:01 PDT
Size:
13.96 KB
patch
obsolete
>Subversion Revision: 113431 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index 1004038ed7d991bcef428acdef9aac676facca16..00cccab2b6fe7f59d9c1558da828e53b2b8088c9 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,34 @@ >+2012-04-06 Dana Jansens <danakj@chromium.org> >+ >+ [chromium] Make culling work with clipped rects >+ https://bugs.webkit.org/show_bug.cgi?id=83217 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Use new CCMathUtil transformation methods to deal with rects that clip >+ the camera plane. This fixes three things: >+ >+ 1. A layer completely behind the camera is not visible and should not >+ occlude. >+ 2. A layer that is clipped by the camera is treated like a >+ non-axis-aligned transform, as the result of a mapClippedRect() is a >+ bounding box and may contain pixels not in the original rect. This guards >+ our use of mapRect() when transforming occluded regions. >+ 3. A layer's occlusion must be clipped by its scissor rect. This scissor >+ rect exists in its target space, so occlusion in screen space is only >+ possible if its target also is axis aligned in the screen, such that >+ the layer's scissor rect remains a rect in screen space. >+ >+ Unit tests: CCOcclusionTrackerTestLayerBehindCameraDoesNotOcclude >+ CCOcclusionTrackerTestLargePixelsOccludeInsideClipRect >+ >+ * platform/graphics/chromium/cc/CCOcclusionTracker.cpp: >+ (WebCore::transformSurfaceOpaqueRegion): >+ (WebCore::computeOcclusionBehindLayer): >+ (WebCore::::markOccludedBehindLayer): >+ (WebCore::testContentRectOccluded): >+ (WebCore::computeUnoccludedContentRect): >+ > 2012-04-06 Levi Weintraub <leviw@chromium.org> > > Update LayoutUnit usage in RenderView >diff --git a/Source/WebKit/chromium/ChangeLog b/Source/WebKit/chromium/ChangeLog >index c81a39da609be4d80973511226400b3811e3e54f..df2183d98be4c596d8f49b72b9a42b7c4a156f13 100644 >--- a/Source/WebKit/chromium/ChangeLog >+++ b/Source/WebKit/chromium/ChangeLog >@@ -1,3 +1,19 @@ >+2012-04-06 Dana Jansens <danakj@chromium.org> >+ >+ [chromium] Make culling work with clipped rects >+ https://bugs.webkit.org/show_bug.cgi?id=83217 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * tests/CCOcclusionTrackerTest.cpp: >+ (CCOcclusionTrackerTestLayerBehindCameraDoesNotOcclude): >+ (WebKitTests::CCOcclusionTrackerTestLayerBehindCameraDoesNotOcclude::runMyTest): >+ (WebKitTests): >+ (CCOcclusionTrackerTestLargePixelsOccludeInsideClipRect): >+ (WebKitTests::CCOcclusionTrackerTestLargePixelsOccludeInsideClipRect::runMyTest): >+ * tests/CCQuadCullerTest.cpp: >+ (WebCore::TestCCOcclusionTrackerImpl::TestCCOcclusionTrackerImpl): >+ > 2012-04-06 Kent Tamura <tkent@chromium.org> > > Calendar Picker: Add code to open/close the calendar picker >diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCOcclusionTracker.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCOcclusionTracker.cpp >index e04adfa3136a4f09eea28d8b2051a3fb46c6773e..cf76bdf63bcfc2b83a954d7ef7bbb96f7d2c9c14 100644 >--- a/Source/WebCore/platform/graphics/chromium/cc/CCOcclusionTracker.cpp >+++ b/Source/WebCore/platform/graphics/chromium/cc/CCOcclusionTracker.cpp >@@ -115,13 +115,16 @@ static inline Region transformSurfaceOpaqueRegion(const RenderSurfaceType* surfa > // Verify that rects within the |surface| will remain rects in its target surface after applying |transform|. If this is true, then > // apply |transform| to each rect within |region| in order to transform the entire Region. > >- FloatQuad transformedBoundsQuad = transform.mapQuad(FloatQuad(region.bounds())); >- if (!transformedBoundsQuad.isRectilinear()) >+ bool clipped; >+ FloatQuad transformedBoundsQuad = CCMathUtil::mapQuad(transform, FloatQuad(region.bounds()), clipped); >+ // FIXME: Find a rect interior to each transformed quad. >+ if (clipped || !transformedBoundsQuad.isRectilinear()) > return Region(); > > Region transformedRegion; > > Vector<IntRect> rects = region.rects(); >+ // Clipping has been verified above, so mapRect will give correct results. > for (size_t i = 0; i < rects.size(); ++i) > transformedRegion.unite(enclosedIntRect(transform.mapRect(FloatRect(rects[i])))); > return transformedRegion; >@@ -195,13 +198,15 @@ static inline TransformationMatrix contentToTargetSurfaceTransform(const LayerTy > > // FIXME: Remove usePaintTracking when paint tracking is on for paint culling. > template<typename LayerType> >-static inline Region computeOcclusionBehindLayer(const LayerType* layer, const TransformationMatrix& transform, bool usePaintTracking) >+static inline Region computeOcclusionBehindLayer(const LayerType* layer, const TransformationMatrix& transform, const IntRect& scissorRect, bool usePaintTracking) > { > Region opaqueRegion; > >- FloatQuad unoccludedQuad = transform.mapQuad(FloatQuad(layer->visibleLayerRect())); >+ bool clipped; >+ FloatQuad unoccludedQuad = CCMathUtil::mapQuad(transform, FloatQuad(layer->visibleLayerRect()), clipped); > bool isPaintedAxisAligned = unoccludedQuad.isRectilinear(); >- if (!isPaintedAxisAligned) >+ // FIXME: Find a rect interior to each transformed quad. >+ if (clipped || !isPaintedAxisAligned) > return opaqueRegion; > > if (layer->opaque()) >@@ -211,9 +216,11 @@ static inline Region computeOcclusionBehindLayer(const LayerType* layer, const T > else if (usePaintTracking) { > Region contentRegion = layer->visibleContentOpaqueRegion(); > Vector<IntRect> contentRects = contentRegion.rects(); >+ // We verify that the possible bounds of this region are not clipped above, so we can use mapRect() safely here. > for (size_t i = 0; i < contentRects.size(); ++i) > opaqueRegion.unite(enclosedIntRect(transform.mapRect(FloatRect(contentRects[i])))); > } >+ opaqueRegion.intersect(scissorRect); > return opaqueRegion; > } > >@@ -228,16 +235,26 @@ void CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::markOccludedBehindLay > if (!layerOpacityKnown(layer) || layer->drawOpacity() < 1) > return; > >- // FIXME: Remove m_usePaintTracking when paint tracking is on for paint culling. >- if (layerTransformsToScreenKnown(layer)) >- m_stack.last().occlusionInScreen.unite(computeOcclusionBehindLayer<LayerType>(layer, contentToScreenSpaceTransform<LayerType>(layer), m_usePaintTracking)); >+ IntRect scissorInTarget = layerScissorRectInTargetSurface(layer); > if (layerTransformsToTargetKnown(layer)) >- m_stack.last().occlusionInTarget.unite(computeOcclusionBehindLayer<LayerType>(layer, contentToTargetSurfaceTransform<LayerType>(layer), m_usePaintTracking)); >+ m_stack.last().occlusionInTarget.unite(computeOcclusionBehindLayer<LayerType>(layer, contentToTargetSurfaceTransform<LayerType>(layer), scissorInTarget, m_usePaintTracking)); >+ >+ // We must clip the occlusion within the layer's scissorInTarget within screen space as well. If the scissor rect can't be moved to screen space and >+ // remain rectilinear, then we don't add any occlusion in screen space. >+ >+ if (layerTransformsToScreenKnown(layer)) { >+ TransformationMatrix targetToScreenTransform = m_stack.last().surface->screenSpaceTransform(); >+ FloatQuad scissorInScreenQuad = targetToScreenTransform.mapQuad(FloatQuad(FloatRect(scissorInTarget))); >+ if (!scissorInScreenQuad.isRectilinear()) >+ return; >+ IntRect scissorInScreenRect = intersection(m_scissorRectInScreenSpace, enclosedIntRect(CCMathUtil::mapClippedRect(targetToScreenTransform, FloatRect(scissorInTarget)))); >+ m_stack.last().occlusionInScreen.unite(computeOcclusionBehindLayer<LayerType>(layer, contentToScreenSpaceTransform<LayerType>(layer), scissorInScreenRect, m_usePaintTracking)); >+ } > } > > static inline bool testContentRectOccluded(const IntRect& contentRect, const TransformationMatrix& contentSpaceTransform, const IntRect& scissorRect, const Region& occlusion) > { >- FloatRect transformedRect = contentSpaceTransform.mapRect(FloatRect(contentRect)); >+ FloatRect transformedRect = CCMathUtil::mapClippedRect(contentSpaceTransform, FloatRect(contentRect)); > // Take the enclosingIntRect, as we want to include partial pixels in the test. > IntRect targetRect = intersection(enclosingIntRect(transformedRect), scissorRect); > return targetRect.isEmpty() || occlusion.contains(targetRect); >@@ -281,13 +298,10 @@ static inline IntRect computeUnoccludedContentRect(const IntRect& contentRect, c > if (!contentSpaceTransform.isInvertible()) > return contentRect; > >- FloatRect transformedRect = contentSpaceTransform.mapRect(FloatRect(contentRect)); > // Take the enclosingIntRect at each step, as we want to contain any unoccluded partial pixels in the resulting IntRect. >+ FloatRect transformedRect = CCMathUtil::mapClippedRect(contentSpaceTransform, FloatRect(contentRect)); > IntRect shrunkRect = rectSubtractRegion(intersection(enclosingIntRect(transformedRect), scissorRect), occlusion); >- bool clipped; // FIXME: We should be able to use projectClippedQuad instead of forcing everything to be unoccluded. https://bugs.webkit.org/show_bug.cgi?id=83217. >- IntRect unoccludedRect = enclosingIntRect(CCMathUtil::projectQuad(contentSpaceTransform.inverse(), FloatQuad(FloatRect(shrunkRect)), clipped).boundingBox()); >- if (clipped) >- return contentRect; >+ IntRect unoccludedRect = enclosingIntRect(CCMathUtil::projectClippedRect(contentSpaceTransform.inverse(), FloatRect(shrunkRect))); > // The rect back in content space is a bounding box and may extend outside of the original contentRect, so clamp it to the contentRectBounds. > return intersection(unoccludedRect, contentRect); > } >diff --git a/Source/WebKit/chromium/tests/CCOcclusionTrackerTest.cpp b/Source/WebKit/chromium/tests/CCOcclusionTrackerTest.cpp >index ccbb0c2b75cd5bd6efe2253b40a263096369af41..b1a6f3a9e3a5059ca1dac7c85f82eccadcb7f921 100644 >--- a/Source/WebKit/chromium/tests/CCOcclusionTrackerTest.cpp >+++ b/Source/WebKit/chromium/tests/CCOcclusionTrackerTest.cpp >@@ -1674,6 +1674,65 @@ protected: > MAIN_THREAD_TEST(CCOcclusionTrackerTestPerspectiveTransformBehindCamera); > > template<class Types, bool opaqueLayers> >+class CCOcclusionTrackerTestLayerBehindCameraDoesNotOcclude : public CCOcclusionTrackerTest<Types, opaqueLayers> { >+protected: >+ void runMyTest() >+ { >+ TransformationMatrix transform; >+ transform.translate(50, 50); >+ transform.applyPerspective(100); >+ transform.translate3d(0, 0, 110); >+ transform.translate(-50, -50); >+ >+ typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100)); >+ typename Types::ContentLayerType* layer = this->createDrawingLayer(parent, transform, FloatPoint(0, 0), IntSize(100, 100), true); >+ parent->setPreserves3D(true); >+ this->calcDrawEtc(parent); >+ >+ TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000)); >+ occlusion.enterTargetRenderSurface(parent->renderSurface()); >+ >+ // This layer is entirely behind the camera and should not occlude. >+ occlusion.markOccludedBehindLayer(layer); >+ EXPECT_EQ(0u, occlusion.occlusionInTargetSurface().rects().size()); >+ EXPECT_EQ(0u, occlusion.occlusionInScreenSpace().rects().size()); >+ } >+}; >+ >+MAIN_THREAD_TEST(CCOcclusionTrackerTestLayerBehindCameraDoesNotOcclude); >+ >+template<class Types, bool opaqueLayers> >+class CCOcclusionTrackerTestLargePixelsOccludeInsideClipRect : public CCOcclusionTrackerTest<Types, opaqueLayers> { >+protected: >+ void runMyTest() >+ { >+ TransformationMatrix transform; >+ transform.translate(50, 50); >+ transform.applyPerspective(100); >+ transform.translate3d(0, 0, 99); >+ transform.translate(-50, -50); >+ >+ typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(100, 100)); >+ typename Types::ContentLayerType* layer = this->createDrawingLayer(parent, transform, FloatPoint(0, 0), IntSize(100, 100), true); >+ parent->setPreserves3D(true); >+ this->calcDrawEtc(parent); >+ >+ TestCCOcclusionTrackerWithScissor<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000)); >+ occlusion.enterTargetRenderSurface(parent->renderSurface()); >+ >+ // This is very close to the camera, so pixels in its visibleLayerRect will actually go outside of the layer's clipRect. >+ // Ensure that those pixels don't occlude things outside the clipRect. >+ occlusion.markOccludedBehindLayer(layer); >+ EXPECT_EQ(IntRect(0, 0, 100, 100), occlusion.occlusionInTargetSurface().bounds()); >+ EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size()); >+ EXPECT_EQ(IntRect(0, 0, 100, 100), occlusion.occlusionInScreenSpace().bounds()); >+ EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size()); >+ } >+}; >+ >+MAIN_THREAD_TEST(CCOcclusionTrackerTestLargePixelsOccludeInsideClipRect); >+ >+template<class Types, bool opaqueLayers> > class CCOcclusionTrackerTestAnimationOpacity1OnMainThread : public CCOcclusionTrackerTest<Types, opaqueLayers> { > protected: > void runMyTest() >diff --git a/Source/WebKit/chromium/tests/CCQuadCullerTest.cpp b/Source/WebKit/chromium/tests/CCQuadCullerTest.cpp >index 4562a3a75c2cbb9580933c323abd050de5411d73..51cbc8bbe4957b856927c7aafc6f6bbb7f9af7ce 100644 >--- a/Source/WebKit/chromium/tests/CCQuadCullerTest.cpp >+++ b/Source/WebKit/chromium/tests/CCQuadCullerTest.cpp >@@ -44,8 +44,9 @@ public: > : CCOcclusionTrackerImpl(scissorRectInScreen, recordMetricsForFrame) > , m_scissorRectInScreen(scissorRectInScreen) > { >- // Pretend we have visited a render surface. >+ // Pretend we have visited the root render surface. > m_stack.append(StackObject()); >+ m_stack.last().surface = new CCRenderSurface(0); > } > > protected:
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 83217
:
135867
| 136079