| OLD | NEW |
| 1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "config.h" | 5 #include "config.h" |
| 6 | 6 |
| 7 #include "cc/occlusion_tracker.h" | 7 #include "cc/occlusion_tracker.h" |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 | 10 |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 51 | 51 |
| 52 if (layerIterator.representsItself) | 52 if (layerIterator.representsItself) |
| 53 markOccludedBehindLayer(layerIterator.currentLayer); | 53 markOccludedBehindLayer(layerIterator.currentLayer); |
| 54 else if (layerIterator.representsContributingRenderSurface) | 54 else if (layerIterator.representsContributingRenderSurface) |
| 55 leaveToRenderTarget(renderTarget); | 55 leaveToRenderTarget(renderTarget); |
| 56 } | 56 } |
| 57 | 57 |
| 58 template<typename LayerType, typename RenderSurfaceType> | 58 template<typename LayerType, typename RenderSurfaceType> |
| 59 void OcclusionTrackerBase<LayerType, RenderSurfaceType>::enterRenderTarget(const
LayerType* newTarget) | 59 void OcclusionTrackerBase<LayerType, RenderSurfaceType>::enterRenderTarget(const
LayerType* newTarget) |
| 60 { | 60 { |
| 61 if (!m_stack.isEmpty() && m_stack.last().target == newTarget) | 61 if (!m_stack.empty() && m_stack.back().target == newTarget) |
| 62 return; | 62 return; |
| 63 | 63 |
| 64 const LayerType* oldTarget = m_stack.isEmpty() ? 0 : m_stack.last().target; | 64 const LayerType* oldTarget = m_stack.empty() ? 0 : m_stack.back().target; |
| 65 const RenderSurfaceType* oldAncestorThatMovesPixels = !oldTarget ? 0 : oldTa
rget->renderSurface()->nearestAncestorThatMovesPixels(); | 65 const RenderSurfaceType* oldAncestorThatMovesPixels = !oldTarget ? 0 : oldTa
rget->renderSurface()->nearestAncestorThatMovesPixels(); |
| 66 const RenderSurfaceType* newAncestorThatMovesPixels = newTarget->renderSurfa
ce()->nearestAncestorThatMovesPixels(); | 66 const RenderSurfaceType* newAncestorThatMovesPixels = newTarget->renderSurfa
ce()->nearestAncestorThatMovesPixels(); |
| 67 | 67 |
| 68 m_stack.append(StackObject(newTarget)); | 68 m_stack.push_back(StackObject(newTarget)); |
| 69 | 69 |
| 70 // We copy the screen occlusion into the new RenderSurfaceImpl subtree, but
we never copy in the | 70 // We copy the screen occlusion into the new RenderSurfaceImpl subtree, but
we never copy in the |
| 71 // target occlusion, since we are looking at a new RenderSurfaceImpl target. | 71 // target occlusion, since we are looking at a new RenderSurfaceImpl target. |
| 72 | 72 |
| 73 // If we are entering a subtree that is going to move pixels around, then th
e occlusion we've computed | 73 // If we are entering a subtree that is going to move pixels around, then th
e occlusion we've computed |
| 74 // so far won't apply to the pixels we're drawing here in the same way. We d
iscard the occlusion thus | 74 // so far won't apply to the pixels we're drawing here in the same way. We d
iscard the occlusion thus |
| 75 // far to be safe, and ensure we don't cull any pixels that are moved such t
hat they become visible. | 75 // far to be safe, and ensure we don't cull any pixels that are moved such t
hat they become visible. |
| 76 bool enteringSubtreeThatMovesPixels = newAncestorThatMovesPixels && newAnces
torThatMovesPixels != oldAncestorThatMovesPixels; | 76 bool enteringSubtreeThatMovesPixels = newAncestorThatMovesPixels && newAnces
torThatMovesPixels != oldAncestorThatMovesPixels; |
| 77 | 77 |
| 78 bool copyScreenOcclusionForward = m_stack.size() > 1 && !enteringSubtreeThat
MovesPixels; | 78 bool copyScreenOcclusionForward = m_stack.size() > 1 && !enteringSubtreeThat
MovesPixels; |
| (...skipping 25 matching lines...) Expand all Loading... |
| 104 { | 104 { |
| 105 // Make sure we know about the target surface. | 105 // Make sure we know about the target surface. |
| 106 enterRenderTarget(finishedTarget); | 106 enterRenderTarget(finishedTarget); |
| 107 | 107 |
| 108 RenderSurfaceType* surface = finishedTarget->renderSurface(); | 108 RenderSurfaceType* surface = finishedTarget->renderSurface(); |
| 109 | 109 |
| 110 // If the occlusion within the surface can not be applied to things outside
of the surface's subtree, then clear the occlusion here so it won't be used. | 110 // If the occlusion within the surface can not be applied to things outside
of the surface's subtree, then clear the occlusion here so it won't be used. |
| 111 // TODO(senorblanco): Make this smarter for SkImageFilter case: once | 111 // TODO(senorblanco): Make this smarter for SkImageFilter case: once |
| 112 // SkImageFilters can report affectsOpacity(), call that. | 112 // SkImageFilters can report affectsOpacity(), call that. |
| 113 if (finishedTarget->maskLayer() || !surfaceOpacityKnown(surface) || surface-
>drawOpacity() < 1 || finishedTarget->filters().hasFilterThatAffectsOpacity() ||
finishedTarget->filter()) { | 113 if (finishedTarget->maskLayer() || !surfaceOpacityKnown(surface) || surface-
>drawOpacity() < 1 || finishedTarget->filters().hasFilterThatAffectsOpacity() ||
finishedTarget->filter()) { |
| 114 m_stack.last().occlusionInScreen = Region(); | 114 m_stack.back().occlusionInScreen = Region(); |
| 115 m_stack.last().occlusionInTarget = Region(); | 115 m_stack.back().occlusionInTarget = Region(); |
| 116 } else { | 116 } else { |
| 117 if (!surfaceTransformsToTargetKnown(surface)) | 117 if (!surfaceTransformsToTargetKnown(surface)) |
| 118 m_stack.last().occlusionInTarget = Region(); | 118 m_stack.back().occlusionInTarget = Region(); |
| 119 if (!surfaceTransformsToScreenKnown(surface)) | 119 if (!surfaceTransformsToScreenKnown(surface)) |
| 120 m_stack.last().occlusionInScreen = Region(); | 120 m_stack.back().occlusionInScreen = Region(); |
| 121 } | 121 } |
| 122 } | 122 } |
| 123 | 123 |
| 124 template<typename RenderSurfaceType> | 124 template<typename RenderSurfaceType> |
| 125 static inline Region transformSurfaceOpaqueRegion(const RenderSurfaceType* surfa
ce, const Region& region, const WebTransformationMatrix& transform) | 125 static inline Region transformSurfaceOpaqueRegion(const RenderSurfaceType* surfa
ce, const Region& region, const WebTransformationMatrix& transform) |
| 126 { | 126 { |
| 127 // Verify that rects within the |surface| will remain rects in its target su
rface after applying |transform|. If this is true, then | 127 // Verify that rects within the |surface| will remain rects in its target su
rface after applying |transform|. If this is true, then |
| 128 // apply |transform| to each rect within |region| in order to transform the
entire Region. | 128 // apply |transform| to each rect within |region| in order to transform the
entire Region. |
| 129 | 129 |
| 130 bool clipped; | 130 bool clipped; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 143 transformedRegion.Union(transformedRect); | 143 transformedRegion.Union(transformedRect); |
| 144 } | 144 } |
| 145 return transformedRegion; | 145 return transformedRegion; |
| 146 } | 146 } |
| 147 | 147 |
| 148 static inline void reduceOcclusion(const gfx::Rect& affectedArea, const gfx::Rec
t& expandedPixel, Region& occlusion) | 148 static inline void reduceOcclusion(const gfx::Rect& affectedArea, const gfx::Rec
t& expandedPixel, Region& occlusion) |
| 149 { | 149 { |
| 150 if (affectedArea.IsEmpty()) | 150 if (affectedArea.IsEmpty()) |
| 151 return; | 151 return; |
| 152 | 152 |
| 153 Region affectedOcclusion = intersect(occlusion, affectedArea); | 153 Region affectedOcclusion = IntersectRegions(occlusion, affectedArea); |
| 154 Region::Iterator affectedOcclusionRects(affectedOcclusion); | 154 Region::Iterator affectedOcclusionRects(affectedOcclusion); |
| 155 | 155 |
| 156 occlusion.Subtract(affectedArea); | 156 occlusion.Subtract(affectedArea); |
| 157 for (; affectedOcclusionRects.has_rect(); affectedOcclusionRects.next()) { | 157 for (; affectedOcclusionRects.has_rect(); affectedOcclusionRects.next()) { |
| 158 gfx::Rect occlusionRect = affectedOcclusionRects.rect(); | 158 gfx::Rect occlusionRect = affectedOcclusionRects.rect(); |
| 159 | 159 |
| 160 // Shrink the rect by expanding the non-opaque pixels outside the rect. | 160 // Shrink the rect by expanding the non-opaque pixels outside the rect. |
| 161 | 161 |
| 162 // The expandedPixel is the Rect for a single pixel after being | 162 // The expandedPixel is the Rect for a single pixel after being |
| 163 // expanded by filters on the layer. The original pixel would be | 163 // expanded by filters on the layer. The original pixel would be |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 227 if (oldTarget->backgroundFilters().hasFilterThatMovesPixels()) { | 227 if (oldTarget->backgroundFilters().hasFilterThatMovesPixels()) { |
| 228 unoccludedSurfaceRect = unoccludedContributingSurfaceContentRect(oldTarg
et, false, oldSurface->contentRect()); | 228 unoccludedSurfaceRect = unoccludedContributingSurfaceContentRect(oldTarg
et, false, oldSurface->contentRect()); |
| 229 if (oldTarget->hasReplica()) | 229 if (oldTarget->hasReplica()) |
| 230 unoccludedReplicaRect = unoccludedContributingSurfaceContentRect(old
Target, true, oldSurface->contentRect()); | 230 unoccludedReplicaRect = unoccludedContributingSurfaceContentRect(old
Target, true, oldSurface->contentRect()); |
| 231 } | 231 } |
| 232 | 232 |
| 233 if (surfaceWillBeAtTopAfterPop) { | 233 if (surfaceWillBeAtTopAfterPop) { |
| 234 // Merge the top of the stack down. | 234 // Merge the top of the stack down. |
| 235 m_stack[lastIndex - 1].occlusionInScreen.Union(m_stack[lastIndex].occlus
ionInScreen); | 235 m_stack[lastIndex - 1].occlusionInScreen.Union(m_stack[lastIndex].occlus
ionInScreen); |
| 236 m_stack[lastIndex - 1].occlusionInTarget.Union(oldTargetOcclusionInNewTa
rget); | 236 m_stack[lastIndex - 1].occlusionInTarget.Union(oldTargetOcclusionInNewTa
rget); |
| 237 m_stack.removeLast(); | 237 m_stack.pop_back(); |
| 238 } else { | 238 } else { |
| 239 // Replace the top of the stack with the new pushed surface. Copy the oc
cluded screen region to the top. | 239 // Replace the top of the stack with the new pushed surface. Copy the oc
cluded screen region to the top. |
| 240 m_stack.last().target = newTarget; | 240 m_stack.back().target = newTarget; |
| 241 m_stack.last().occlusionInTarget = oldTargetOcclusionInNewTarget; | 241 m_stack.back().occlusionInTarget = oldTargetOcclusionInNewTarget; |
| 242 } | 242 } |
| 243 | 243 |
| 244 if (oldTarget->backgroundFilters().hasFilterThatMovesPixels()) { | 244 if (oldTarget->backgroundFilters().hasFilterThatMovesPixels()) { |
| 245 reduceOcclusionBelowSurface(oldTarget, unoccludedSurfaceRect, oldSurface
->drawTransform(), newTarget, m_stack.last().occlusionInTarget, m_stack.last().o
cclusionInScreen); | 245 reduceOcclusionBelowSurface(oldTarget, unoccludedSurfaceRect, oldSurface
->drawTransform(), newTarget, m_stack.back().occlusionInTarget, m_stack.back().o
cclusionInScreen); |
| 246 if (oldTarget->hasReplica()) | 246 if (oldTarget->hasReplica()) |
| 247 reduceOcclusionBelowSurface(oldTarget, unoccludedReplicaRect, oldSur
face->replicaDrawTransform(), newTarget, m_stack.last().occlusionInTarget, m_sta
ck.last().occlusionInScreen); | 247 reduceOcclusionBelowSurface(oldTarget, unoccludedReplicaRect, oldSur
face->replicaDrawTransform(), newTarget, m_stack.back().occlusionInTarget, m_sta
ck.back().occlusionInScreen); |
| 248 } | 248 } |
| 249 } | 249 } |
| 250 | 250 |
| 251 // FIXME: Remove usePaintTracking when paint tracking is on for paint culling. | 251 // FIXME: Remove usePaintTracking when paint tracking is on for paint culling. |
| 252 template<typename LayerType> | 252 template<typename LayerType> |
| 253 static inline void addOcclusionBehindLayer(Region& region, const LayerType* laye
r, const WebTransformationMatrix& transform, const Region& opaqueContents, const
gfx::Rect& clipRectInTarget, const gfx::Size& minimumTrackingSize, std::vector<
gfx::Rect>* occludingScreenSpaceRects) | 253 static inline void addOcclusionBehindLayer(Region& region, const LayerType* laye
r, const WebTransformationMatrix& transform, const Region& opaqueContents, const
gfx::Rect& clipRectInTarget, const gfx::Size& minimumTrackingSize, std::vector<
gfx::Rect>* occludingScreenSpaceRects) |
| 254 { | 254 { |
| 255 DCHECK(layer->visibleContentRect().Contains(opaqueContents.bounds())); | 255 DCHECK(layer->visibleContentRect().Contains(opaqueContents.bounds())); |
| 256 | 256 |
| 257 bool clipped; | 257 bool clipped; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 268 if (occludingScreenSpaceRects) | 268 if (occludingScreenSpaceRects) |
| 269 occludingScreenSpaceRects->push_back(transformedRect); | 269 occludingScreenSpaceRects->push_back(transformedRect); |
| 270 region.Union(transformedRect); | 270 region.Union(transformedRect); |
| 271 } | 271 } |
| 272 } | 272 } |
| 273 } | 273 } |
| 274 | 274 |
| 275 template<typename LayerType, typename RenderSurfaceType> | 275 template<typename LayerType, typename RenderSurfaceType> |
| 276 void OcclusionTrackerBase<LayerType, RenderSurfaceType>::markOccludedBehindLayer
(const LayerType* layer) | 276 void OcclusionTrackerBase<LayerType, RenderSurfaceType>::markOccludedBehindLayer
(const LayerType* layer) |
| 277 { | 277 { |
| 278 DCHECK(!m_stack.isEmpty()); | 278 DCHECK(!m_stack.empty()); |
| 279 DCHECK(layer->renderTarget() == m_stack.last().target); | 279 DCHECK(layer->renderTarget() == m_stack.back().target); |
| 280 if (m_stack.isEmpty()) | 280 if (m_stack.empty()) |
| 281 return; | 281 return; |
| 282 | 282 |
| 283 if (!layerOpacityKnown(layer) || layer->drawOpacity() < 1) | 283 if (!layerOpacityKnown(layer) || layer->drawOpacity() < 1) |
| 284 return; | 284 return; |
| 285 | 285 |
| 286 if (layerIsInUnsorted3dRenderingContext(layer)) | 286 if (layerIsInUnsorted3dRenderingContext(layer)) |
| 287 return; | 287 return; |
| 288 | 288 |
| 289 Region opaqueContents = layer->visibleContentOpaqueRegion(); | 289 Region opaqueContents = layer->visibleContentOpaqueRegion(); |
| 290 if (opaqueContents.IsEmpty()) | 290 if (opaqueContents.IsEmpty()) |
| 291 return; | 291 return; |
| 292 | 292 |
| 293 gfx::Rect clipRectInTarget = layerClipRectInTarget(layer); | 293 gfx::Rect clipRectInTarget = layerClipRectInTarget(layer); |
| 294 if (layerTransformsToTargetKnown(layer)) | 294 if (layerTransformsToTargetKnown(layer)) |
| 295 addOcclusionBehindLayer<LayerType>(m_stack.last().occlusionInTarget, lay
er, layer->drawTransform(), opaqueContents, clipRectInTarget, m_minimumTrackingS
ize, 0); | 295 addOcclusionBehindLayer<LayerType>(m_stack.back().occlusionInTarget, lay
er, layer->drawTransform(), opaqueContents, clipRectInTarget, m_minimumTrackingS
ize, 0); |
| 296 | 296 |
| 297 // We must clip the occlusion within the layer's clipRectInTarget within scr
een space as well. If the clip rect can't be moved to screen space and | 297 // We must clip the occlusion within the layer's clipRectInTarget within scr
een space as well. If the clip rect can't be moved to screen space and |
| 298 // remain rectilinear, then we don't add any occlusion in screen space. | 298 // remain rectilinear, then we don't add any occlusion in screen space. |
| 299 | 299 |
| 300 if (layerTransformsToScreenKnown(layer)) { | 300 if (layerTransformsToScreenKnown(layer)) { |
| 301 WebTransformationMatrix targetToScreenTransform = m_stack.last().target-
>renderSurface()->screenSpaceTransform(); | 301 WebTransformationMatrix targetToScreenTransform = m_stack.back().target-
>renderSurface()->screenSpaceTransform(); |
| 302 bool clipped; | 302 bool clipped; |
| 303 gfx::QuadF clipQuadInScreen = MathUtil::mapQuad(targetToScreenTransform,
gfx::QuadF(clipRectInTarget), clipped); | 303 gfx::QuadF clipQuadInScreen = MathUtil::mapQuad(targetToScreenTransform,
gfx::QuadF(clipRectInTarget), clipped); |
| 304 // FIXME: Find a rect interior to the transformed clip quad. | 304 // FIXME: Find a rect interior to the transformed clip quad. |
| 305 if (clipped || !clipQuadInScreen.IsRectilinear()) | 305 if (clipped || !clipQuadInScreen.IsRectilinear()) |
| 306 return; | 306 return; |
| 307 gfx::Rect clipRectInScreen = gfx::IntersectRects(m_rootTargetRect, gfx::
ToEnclosedRect(clipQuadInScreen.BoundingBox())); | 307 gfx::Rect clipRectInScreen = gfx::IntersectRects(m_rootTargetRect, gfx::
ToEnclosedRect(clipQuadInScreen.BoundingBox())); |
| 308 addOcclusionBehindLayer<LayerType>(m_stack.last().occlusionInScreen, lay
er, layer->screenSpaceTransform(), opaqueContents, clipRectInScreen, m_minimumTr
ackingSize, m_occludingScreenSpaceRects); | 308 addOcclusionBehindLayer<LayerType>(m_stack.back().occlusionInScreen, lay
er, layer->screenSpaceTransform(), opaqueContents, clipRectInScreen, m_minimumTr
ackingSize, m_occludingScreenSpaceRects); |
| 309 } | 309 } |
| 310 } | 310 } |
| 311 | 311 |
| 312 static inline bool testContentRectOccluded(const gfx::Rect& contentRect, const W
ebTransformationMatrix& contentSpaceTransform, const gfx::Rect& clipRectInTarget
, const Region& occlusion) | 312 static inline bool testContentRectOccluded(const gfx::Rect& contentRect, const W
ebTransformationMatrix& contentSpaceTransform, const gfx::Rect& clipRectInTarget
, const Region& occlusion) |
| 313 { | 313 { |
| 314 gfx::RectF transformedRect = MathUtil::mapClippedRect(contentSpaceTransform,
gfx::RectF(contentRect)); | 314 gfx::RectF transformedRect = MathUtil::mapClippedRect(contentSpaceTransform,
gfx::RectF(contentRect)); |
| 315 // Take the gfx::ToEnclosingRect, as we want to include partial pixels in th
e test. | 315 // Take the gfx::ToEnclosingRect, as we want to include partial pixels in th
e test. |
| 316 gfx::Rect targetRect = gfx::IntersectRects(gfx::ToEnclosingRect(transformedR
ect), clipRectInTarget); | 316 gfx::Rect targetRect = gfx::IntersectRects(gfx::ToEnclosingRect(transformedR
ect), clipRectInTarget); |
| 317 return targetRect.IsEmpty() || occlusion.Contains(targetRect); | 317 return targetRect.IsEmpty() || occlusion.Contains(targetRect); |
| 318 } | 318 } |
| 319 | 319 |
| 320 template<typename LayerType, typename RenderSurfaceType> | 320 template<typename LayerType, typename RenderSurfaceType> |
| 321 bool OcclusionTrackerBase<LayerType, RenderSurfaceType>::occluded(const LayerTyp
e* renderTarget, const gfx::Rect& contentRect, const WebKit::WebTransformationMa
trix& drawTransform, bool implDrawTransformIsUnknown, const gfx::Rect& clippedRe
ctInTarget, bool* hasOcclusionFromOutsideTargetSurface) const | 321 bool OcclusionTrackerBase<LayerType, RenderSurfaceType>::occluded(const LayerTyp
e* renderTarget, const gfx::Rect& contentRect, const WebKit::WebTransformationMa
trix& drawTransform, bool implDrawTransformIsUnknown, const gfx::Rect& clippedRe
ctInTarget, bool* hasOcclusionFromOutsideTargetSurface) const |
| 322 { | 322 { |
| 323 if (hasOcclusionFromOutsideTargetSurface) | 323 if (hasOcclusionFromOutsideTargetSurface) |
| 324 *hasOcclusionFromOutsideTargetSurface = false; | 324 *hasOcclusionFromOutsideTargetSurface = false; |
| 325 | 325 |
| 326 DCHECK(!m_stack.isEmpty()); | 326 DCHECK(!m_stack.empty()); |
| 327 if (m_stack.isEmpty()) | 327 if (m_stack.empty()) |
| 328 return false; | 328 return false; |
| 329 if (contentRect.IsEmpty()) | 329 if (contentRect.IsEmpty()) |
| 330 return true; | 330 return true; |
| 331 | 331 |
| 332 DCHECK(renderTarget == m_stack.last().target); | 332 DCHECK(renderTarget == m_stack.back().target); |
| 333 | 333 |
| 334 if (!implDrawTransformIsUnknown && testContentRectOccluded(contentRect, draw
Transform, clippedRectInTarget, m_stack.last().occlusionInTarget)) | 334 if (!implDrawTransformIsUnknown && testContentRectOccluded(contentRect, draw
Transform, clippedRectInTarget, m_stack.back().occlusionInTarget)) |
| 335 return true; | 335 return true; |
| 336 | 336 |
| 337 // renderTarget can be NULL in some tests. | 337 // renderTarget can be NULL in some tests. |
| 338 bool transformToScreenKnown = renderTarget && !implDrawTransformIsUnknown &&
layerTransformsToScreenKnown(renderTarget); | 338 bool transformToScreenKnown = renderTarget && !implDrawTransformIsUnknown &&
layerTransformsToScreenKnown(renderTarget); |
| 339 if (transformToScreenKnown && testContentRectOccluded(contentRect, renderTar
get->renderSurface()->screenSpaceTransform() * drawTransform, m_rootTargetRect,
m_stack.last().occlusionInScreen)) { | 339 if (transformToScreenKnown && testContentRectOccluded(contentRect, renderTar
get->renderSurface()->screenSpaceTransform() * drawTransform, m_rootTargetRect,
m_stack.back().occlusionInScreen)) { |
| 340 if (hasOcclusionFromOutsideTargetSurface) | 340 if (hasOcclusionFromOutsideTargetSurface) |
| 341 *hasOcclusionFromOutsideTargetSurface = true; | 341 *hasOcclusionFromOutsideTargetSurface = true; |
| 342 return true; | 342 return true; |
| 343 } | 343 } |
| 344 | 344 |
| 345 return false; | 345 return false; |
| 346 } | 346 } |
| 347 | 347 |
| 348 // Determines what portion of rect, if any, is unoccluded (not occluded by regio
n). If | 348 // Determines what portion of rect, if any, is unoccluded (not occluded by regio
n). If |
| 349 // the resulting unoccluded region is not rectangular, we return a rect containi
ng it. | 349 // the resulting unoccluded region is not rectangular, we return a rect containi
ng it. |
| (...skipping 13 matching lines...) Expand all Loading... |
| 363 gfx::RectF transformedRect = MathUtil::mapClippedRect(contentSpaceTransform,
gfx::RectF(contentRect)); | 363 gfx::RectF transformedRect = MathUtil::mapClippedRect(contentSpaceTransform,
gfx::RectF(contentRect)); |
| 364 gfx::Rect shrunkRect = rectSubtractRegion(gfx::IntersectRects(gfx::ToEnclosi
ngRect(transformedRect), clipRectInTarget), occlusion); | 364 gfx::Rect shrunkRect = rectSubtractRegion(gfx::IntersectRects(gfx::ToEnclosi
ngRect(transformedRect), clipRectInTarget), occlusion); |
| 365 gfx::Rect unoccludedRect = gfx::ToEnclosingRect(MathUtil::projectClippedRect
(contentSpaceTransform.inverse(), gfx::RectF(shrunkRect))); | 365 gfx::Rect unoccludedRect = gfx::ToEnclosingRect(MathUtil::projectClippedRect
(contentSpaceTransform.inverse(), gfx::RectF(shrunkRect))); |
| 366 // The rect back in content space is a bounding box and may extend outside o
f the original contentRect, so clamp it to the contentRectBounds. | 366 // The rect back in content space is a bounding box and may extend outside o
f the original contentRect, so clamp it to the contentRectBounds. |
| 367 return gfx::IntersectRects(unoccludedRect, contentRect); | 367 return gfx::IntersectRects(unoccludedRect, contentRect); |
| 368 } | 368 } |
| 369 | 369 |
| 370 template<typename LayerType, typename RenderSurfaceType> | 370 template<typename LayerType, typename RenderSurfaceType> |
| 371 gfx::Rect OcclusionTrackerBase<LayerType, RenderSurfaceType>::unoccludedContentR
ect(const LayerType* renderTarget, const gfx::Rect& contentRect, const WebKit::W
ebTransformationMatrix& drawTransform, bool implDrawTransformIsUnknown, const gf
x::Rect& clippedRectInTarget, bool* hasOcclusionFromOutsideTargetSurface) const | 371 gfx::Rect OcclusionTrackerBase<LayerType, RenderSurfaceType>::unoccludedContentR
ect(const LayerType* renderTarget, const gfx::Rect& contentRect, const WebKit::W
ebTransformationMatrix& drawTransform, bool implDrawTransformIsUnknown, const gf
x::Rect& clippedRectInTarget, bool* hasOcclusionFromOutsideTargetSurface) const |
| 372 { | 372 { |
| 373 DCHECK(!m_stack.isEmpty()); | 373 DCHECK(!m_stack.empty()); |
| 374 if (m_stack.isEmpty()) | 374 if (m_stack.empty()) |
| 375 return contentRect; | 375 return contentRect; |
| 376 if (contentRect.IsEmpty()) | 376 if (contentRect.IsEmpty()) |
| 377 return contentRect; | 377 return contentRect; |
| 378 | 378 |
| 379 DCHECK(renderTarget->renderTarget() == renderTarget); | 379 DCHECK(renderTarget->renderTarget() == renderTarget); |
| 380 DCHECK(renderTarget->renderSurface()); | 380 DCHECK(renderTarget->renderSurface()); |
| 381 DCHECK(renderTarget == m_stack.last().target); | 381 DCHECK(renderTarget == m_stack.back().target); |
| 382 | 382 |
| 383 // We want to return a rect that contains all the visible parts of |contentR
ect| in both screen space and in the target surface. | 383 // We want to return a rect that contains all the visible parts of |contentR
ect| in both screen space and in the target surface. |
| 384 // So we find the visible parts of |contentRect| in each space, and take the
intersection. | 384 // So we find the visible parts of |contentRect| in each space, and take the
intersection. |
| 385 | 385 |
| 386 gfx::Rect unoccludedInScreen = contentRect; | 386 gfx::Rect unoccludedInScreen = contentRect; |
| 387 if (layerTransformsToScreenKnown(renderTarget) && !implDrawTransformIsUnknow
n) | 387 if (layerTransformsToScreenKnown(renderTarget) && !implDrawTransformIsUnknow
n) |
| 388 unoccludedInScreen = computeUnoccludedContentRect(contentRect, renderTar
get->renderSurface()->screenSpaceTransform() * drawTransform, m_rootTargetRect,
m_stack.last().occlusionInScreen); | 388 unoccludedInScreen = computeUnoccludedContentRect(contentRect, renderTar
get->renderSurface()->screenSpaceTransform() * drawTransform, m_rootTargetRect,
m_stack.back().occlusionInScreen); |
| 389 | 389 |
| 390 gfx::Rect unoccludedInTarget = contentRect; | 390 gfx::Rect unoccludedInTarget = contentRect; |
| 391 if (!implDrawTransformIsUnknown) | 391 if (!implDrawTransformIsUnknown) |
| 392 unoccludedInTarget = computeUnoccludedContentRect(contentRect, drawTrans
form, clippedRectInTarget, m_stack.last().occlusionInTarget); | 392 unoccludedInTarget = computeUnoccludedContentRect(contentRect, drawTrans
form, clippedRectInTarget, m_stack.back().occlusionInTarget); |
| 393 | 393 |
| 394 if (hasOcclusionFromOutsideTargetSurface) | 394 if (hasOcclusionFromOutsideTargetSurface) |
| 395 *hasOcclusionFromOutsideTargetSurface = (gfx::IntersectRects(unoccludedI
nScreen, unoccludedInTarget) != unoccludedInTarget); | 395 *hasOcclusionFromOutsideTargetSurface = (gfx::IntersectRects(unoccludedI
nScreen, unoccludedInTarget) != unoccludedInTarget); |
| 396 | 396 |
| 397 return gfx::IntersectRects(unoccludedInScreen, unoccludedInTarget); | 397 return gfx::IntersectRects(unoccludedInScreen, unoccludedInTarget); |
| 398 } | 398 } |
| 399 | 399 |
| 400 template<typename LayerType, typename RenderSurfaceType> | 400 template<typename LayerType, typename RenderSurfaceType> |
| 401 gfx::Rect OcclusionTrackerBase<LayerType, RenderSurfaceType>::unoccludedContribu
tingSurfaceContentRect(const LayerType* layer, bool forReplica, const gfx::Rect&
contentRect, bool* hasOcclusionFromOutsideTargetSurface) const | 401 gfx::Rect OcclusionTrackerBase<LayerType, RenderSurfaceType>::unoccludedContribu
tingSurfaceContentRect(const LayerType* layer, bool forReplica, const gfx::Rect&
contentRect, bool* hasOcclusionFromOutsideTargetSurface) const |
| 402 { | 402 { |
| 403 DCHECK(!m_stack.isEmpty()); | 403 DCHECK(!m_stack.empty()); |
| 404 // The layer is a contributing renderTarget so it should have a surface. | 404 // The layer is a contributing renderTarget so it should have a surface. |
| 405 DCHECK(layer->renderSurface()); | 405 DCHECK(layer->renderSurface()); |
| 406 // The layer is a contributing renderTarget so its target should be itself. | 406 // The layer is a contributing renderTarget so its target should be itself. |
| 407 DCHECK(layer->renderTarget() == layer); | 407 DCHECK(layer->renderTarget() == layer); |
| 408 // The layer should not be the root, else what is is contributing to? | 408 // The layer should not be the root, else what is is contributing to? |
| 409 DCHECK(layer->parent()); | 409 DCHECK(layer->parent()); |
| 410 // This should be called while the layer is still considered the current tar
get in the occlusion tracker. | 410 // This should be called while the layer is still considered the current tar
get in the occlusion tracker. |
| 411 DCHECK(layer == m_stack.last().target); | 411 DCHECK(layer == m_stack.back().target); |
| 412 | 412 |
| 413 if (contentRect.IsEmpty()) | 413 if (contentRect.IsEmpty()) |
| 414 return contentRect; | 414 return contentRect; |
| 415 | 415 |
| 416 RenderSurfaceType* surface = layer->renderSurface(); | 416 RenderSurfaceType* surface = layer->renderSurface(); |
| 417 | 417 |
| 418 gfx::Rect surfaceClipRect = surface->clipRect(); | 418 gfx::Rect surfaceClipRect = surface->clipRect(); |
| 419 if (surfaceClipRect.IsEmpty()) { | 419 if (surfaceClipRect.IsEmpty()) { |
| 420 LayerType* contributingSurfaceRenderTarget = layer->parent()->renderTarg
et(); | 420 LayerType* contributingSurfaceRenderTarget = layer->parent()->renderTarg
et(); |
| 421 surfaceClipRect = gfx::IntersectRects(contributingSurfaceRenderTarget->r
enderSurface()->contentRect(), gfx::ToEnclosingRect(surface->drawableContentRect
())); | 421 surfaceClipRect = gfx::IntersectRects(contributingSurfaceRenderTarget->r
enderSurface()->contentRect(), gfx::ToEnclosingRect(surface->drawableContentRect
())); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 458 // FIXME: we could remove this helper function, but unit tests currently ove
rride this | 458 // FIXME: we could remove this helper function, but unit tests currently ove
rride this |
| 459 // function, and they need to be verified/adjusted before this can be
removed. | 459 // function, and they need to be verified/adjusted before this can be
removed. |
| 460 return layer->drawableContentRect(); | 460 return layer->drawableContentRect(); |
| 461 } | 461 } |
| 462 | 462 |
| 463 // Instantiate (and export) templates here for the linker. | 463 // Instantiate (and export) templates here for the linker. |
| 464 template class OcclusionTrackerBase<Layer, RenderSurface>; | 464 template class OcclusionTrackerBase<Layer, RenderSurface>; |
| 465 template class OcclusionTrackerBase<LayerImpl, RenderSurfaceImpl>; | 465 template class OcclusionTrackerBase<LayerImpl, RenderSurfaceImpl>; |
| 466 | 466 |
| 467 } // namespace cc | 467 } // namespace cc |
| OLD | NEW |