diff options
Diffstat (limited to 'Source/WebCore/platform/graphics/chromium/cc/CCOcclusionTracker.cpp')
-rw-r--r-- | Source/WebCore/platform/graphics/chromium/cc/CCOcclusionTracker.cpp | 60 |
1 files changed, 36 insertions, 24 deletions
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCOcclusionTracker.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCOcclusionTracker.cpp index 792f8629a..68ccdc9c0 100644 --- a/Source/WebCore/platform/graphics/chromium/cc/CCOcclusionTracker.cpp +++ b/Source/WebCore/platform/graphics/chromium/cc/CCOcclusionTracker.cpp @@ -36,6 +36,7 @@ #include <algorithm> using namespace std; +using WebKit::WebTransformationMatrix; namespace WebCore { @@ -131,7 +132,7 @@ void CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::finishedTargetRenderS } template<typename RenderSurfaceType> -static inline Region transformSurfaceOpaqueRegion(const RenderSurfaceType* surface, const Region& region, const TransformationMatrix& transform) +static inline Region transformSurfaceOpaqueRegion(const RenderSurfaceType* surface, const Region& region, const WebTransformationMatrix& transform) { // 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. @@ -194,7 +195,7 @@ static inline void reduceOcclusion(const IntRect& affectedArea, const IntRect& e } template<typename RenderSurfaceType> -static void reduceOcclusionBelowSurface(RenderSurfaceType* surface, const IntRect& surfaceRect, const TransformationMatrix& surfaceTransform, RenderSurfaceType* surfaceTarget, Region& occlusionInTarget, Region& occlusionInScreen) +static void reduceOcclusionBelowSurface(RenderSurfaceType* surface, const IntRect& surfaceRect, const WebTransformationMatrix& surfaceTransform, RenderSurfaceType* surfaceTarget, Region& occlusionInTarget, Region& occlusionInScreen) { if (surfaceRect.isEmpty()) return; @@ -260,13 +261,13 @@ void CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::leaveToTargetRenderSu } template<typename LayerType> -static inline TransformationMatrix contentToScreenSpaceTransform(const LayerType* layer) +static inline WebTransformationMatrix contentToScreenSpaceTransform(const LayerType* layer) { ASSERT(layerTransformsToScreenKnown(layer)); IntSize boundsInLayerSpace = layer->bounds(); IntSize boundsInContentSpace = layer->contentBounds(); - TransformationMatrix transform = layer->screenSpaceTransform(); + WebTransformationMatrix transform = layer->screenSpaceTransform(); if (boundsInContentSpace.isEmpty()) return transform; @@ -279,13 +280,13 @@ static inline TransformationMatrix contentToScreenSpaceTransform(const LayerType } template<typename LayerType> -static inline TransformationMatrix contentToTargetSurfaceTransform(const LayerType* layer) +static inline WebTransformationMatrix contentToTargetSurfaceTransform(const LayerType* layer) { ASSERT(layerTransformsToTargetKnown(layer)); IntSize boundsInLayerSpace = layer->bounds(); IntSize boundsInContentSpace = layer->contentBounds(); - TransformationMatrix transform = layer->drawTransform(); + WebTransformationMatrix transform = layer->drawTransform(); if (boundsInContentSpace.isEmpty()) return transform; @@ -302,7 +303,7 @@ static inline TransformationMatrix contentToTargetSurfaceTransform(const LayerTy // FIXME: Remove usePaintTracking when paint tracking is on for paint culling. template<typename LayerType> -static inline void addOcclusionBehindLayer(Region& region, const LayerType* layer, const TransformationMatrix& transform, const Region& opaqueContents, const IntRect& scissorRect, const IntSize& minimumTrackingSize) +static inline void addOcclusionBehindLayer(Region& region, const LayerType* layer, const WebTransformationMatrix& transform, const Region& opaqueContents, const IntRect& scissorRect, const IntSize& minimumTrackingSize) { ASSERT(layer->visibleLayerRect().contains(opaqueContents.bounds())); @@ -345,7 +346,7 @@ void CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::markOccludedBehindLay // remain rectilinear, then we don't add any occlusion in screen space. if (layerTransformsToScreenKnown(layer)) { - TransformationMatrix targetToScreenTransform = m_stack.last().surface->screenSpaceTransform(); + WebTransformationMatrix targetToScreenTransform = m_stack.last().surface->screenSpaceTransform(); bool clipped; FloatQuad scissorInScreenQuad = CCMathUtil::mapQuad(targetToScreenTransform, FloatQuad(FloatRect(scissorInTarget)), clipped); // FIXME: Find a rect interior to the transformed scissor quad. @@ -356,7 +357,7 @@ void CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::markOccludedBehindLay } } -static inline bool testContentRectOccluded(const IntRect& contentRect, const TransformationMatrix& contentSpaceTransform, const IntRect& scissorRect, const Region& occlusion) +static inline bool testContentRectOccluded(const IntRect& contentRect, const WebTransformationMatrix& contentSpaceTransform, const IntRect& scissorRect, const Region& occlusion) { FloatRect transformedRect = CCMathUtil::mapClippedRect(contentSpaceTransform, FloatRect(contentRect)); // Take the enclosingIntRect, as we want to include partial pixels in the test. @@ -391,7 +392,7 @@ static inline IntRect rectSubtractRegion(const IntRect& rect, const Region& regi return rectRegion.bounds(); } -static inline IntRect computeUnoccludedContentRect(const IntRect& contentRect, const TransformationMatrix& contentSpaceTransform, const IntRect& scissorRect, const Region& occlusion) +static inline IntRect computeUnoccludedContentRect(const IntRect& contentRect, const WebTransformationMatrix& contentSpaceTransform, const IntRect& scissorRect, const Region& occlusion) { if (!contentSpaceTransform.isInvertible()) return contentRect; @@ -439,34 +440,45 @@ IntRect CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::unoccludedContribu // This should be called while the contributing render surface is still considered the current target in the occlusion tracker. ASSERT(surface == m_stack.last().surface); - // 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; - const StackObject& secondLast = m_stack[m_stack.size() - 2]; - IntRect surfaceClipRect = surface->clipRect(); if (surfaceClipRect.isEmpty()) { - const RenderSurfaceType* targetSurface = secondLast.surface; - surfaceClipRect = intersection(targetSurface->contentRect(), enclosingIntRect(surface->drawableContentRect())); + const RenderSurfaceType* targetSurface = surface->targetRenderSurface(); + if (targetSurface) + surfaceClipRect = intersection(targetSurface->contentRect(), enclosingIntRect(surface->drawableContentRect())); + else + surfaceClipRect = m_scissorRectInScreenSpace; } - const TransformationMatrix& transformToScreen = forReplica ? surface->replicaScreenSpaceTransform() : surface->screenSpaceTransform(); - const TransformationMatrix& transformToTarget = forReplica ? surface->replicaOriginTransform() : surface->originTransform(); + // A contributing surface doesn't get occluded by things inside its own surface, so only things outside the surface can occlude it. That occlusion is + // found just below the top of the stack (if it exists). + bool hasOcclusion = m_stack.size() > 1; + + const WebTransformationMatrix& transformToScreen = forReplica ? surface->replicaScreenSpaceTransform() : surface->screenSpaceTransform(); + const WebTransformationMatrix& transformToTarget = forReplica ? surface->replicaOriginTransform() : surface->originTransform(); IntRect unoccludedInScreen = contentRect; - if (surfaceTransformsToScreenKnown(surface)) - unoccludedInScreen = computeUnoccludedContentRect(contentRect, transformToScreen, m_scissorRectInScreenSpace, secondLast.occlusionInScreen); + if (surfaceTransformsToScreenKnown(surface)) { + if (hasOcclusion) { + const StackObject& secondLast = m_stack[m_stack.size() - 2]; + unoccludedInScreen = computeUnoccludedContentRect(contentRect, transformToScreen, m_scissorRectInScreenSpace, secondLast.occlusionInScreen); + } else + unoccludedInScreen = computeUnoccludedContentRect(contentRect, transformToScreen, m_scissorRectInScreenSpace, Region()); + } if (unoccludedInScreen.isEmpty()) return unoccludedInScreen; IntRect unoccludedInTarget = contentRect; - if (surfaceTransformsToTargetKnown(surface)) - unoccludedInTarget = computeUnoccludedContentRect(contentRect, transformToTarget, surfaceClipRect, secondLast.occlusionInTarget); + if (surfaceTransformsToTargetKnown(surface)) { + if (hasOcclusion) { + const StackObject& secondLast = m_stack[m_stack.size() - 2]; + unoccludedInTarget = computeUnoccludedContentRect(contentRect, transformToTarget, surfaceClipRect, secondLast.occlusionInTarget); + } else + unoccludedInTarget = computeUnoccludedContentRect(contentRect, transformToTarget, surfaceClipRect, Region()); + } return intersection(unoccludedInScreen, unoccludedInTarget); } |