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 |