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 "cc/occlusion_tracker.h" | 5 #include "cc/occlusion_tracker.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "cc/layer.h" | 9 #include "cc/layer.h" |
10 #include "cc/layer_impl.h" | 10 #include "cc/layer_impl.h" |
11 #include "cc/math_util.h" | 11 #include "cc/math_util.h" |
12 #include "cc/overdraw_metrics.h" | 12 #include "cc/overdraw_metrics.h" |
13 #include "ui/gfx/quad_f.h" | 13 #include "ui/gfx/quad_f.h" |
14 #include "ui/gfx/rect_conversions.h" | 14 #include "ui/gfx/rect_conversions.h" |
15 | 15 |
16 using namespace std; | 16 using namespace std; |
17 using WebKit::WebTransformationMatrix; | 17 using WebKit::WebTransformationMatrix; |
18 | 18 |
19 namespace cc { | 19 namespace cc { |
20 | 20 |
21 template<typename LayerType, typename RenderSurfaceType> | 21 template<typename LayerType, typename RenderSurfaceType> |
22 OcclusionTrackerBase<LayerType, RenderSurfaceType>::OcclusionTrackerBase(gfx::Re
ct rootTargetRect, bool recordMetricsForFrame) | 22 OcclusionTrackerBase<LayerType, RenderSurfaceType>::OcclusionTrackerBase(gfx::Re
ct rootTargetRect, bool recordMetricsForFrame) |
23 : m_rootTargetRect(rootTargetRect) | 23 : m_rootTargetRect(rootTargetRect) |
24 , m_overdrawMetrics(OverdrawMetrics::create(recordMetricsForFrame)) | 24 , m_overdrawMetrics(OverdrawMetrics::create(recordMetricsForFrame)) |
25 , m_occludingScreenSpaceRects(0) | 25 , m_occludingScreenSpaceRects(0) |
| 26 , m_nonOccludingScreenSpaceRects(0) |
26 { | 27 { |
27 } | 28 } |
28 | 29 |
29 template<typename LayerType, typename RenderSurfaceType> | 30 template<typename LayerType, typename RenderSurfaceType> |
30 OcclusionTrackerBase<LayerType, RenderSurfaceType>::~OcclusionTrackerBase() | 31 OcclusionTrackerBase<LayerType, RenderSurfaceType>::~OcclusionTrackerBase() |
31 { | 32 { |
32 } | 33 } |
33 | 34 |
34 template<typename LayerType, typename RenderSurfaceType> | 35 template<typename LayerType, typename RenderSurfaceType> |
35 void OcclusionTrackerBase<LayerType, RenderSurfaceType>::enterLayer(const LayerI
teratorPosition<LayerType>& layerIterator) | 36 void OcclusionTrackerBase<LayerType, RenderSurfaceType>::enterLayer(const LayerI
teratorPosition<LayerType>& layerIterator) |
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
241 | 242 |
242 if (oldTarget->backgroundFilters().hasFilterThatMovesPixels()) { | 243 if (oldTarget->backgroundFilters().hasFilterThatMovesPixels()) { |
243 reduceOcclusionBelowSurface(oldTarget, unoccludedSurfaceRect, oldSurface
->drawTransform(), newTarget, m_stack.back().occlusionInTarget, m_stack.back().o
cclusionInScreen); | 244 reduceOcclusionBelowSurface(oldTarget, unoccludedSurfaceRect, oldSurface
->drawTransform(), newTarget, m_stack.back().occlusionInTarget, m_stack.back().o
cclusionInScreen); |
244 if (oldTarget->hasReplica()) | 245 if (oldTarget->hasReplica()) |
245 reduceOcclusionBelowSurface(oldTarget, unoccludedReplicaRect, oldSur
face->replicaDrawTransform(), newTarget, m_stack.back().occlusionInTarget, m_sta
ck.back().occlusionInScreen); | 246 reduceOcclusionBelowSurface(oldTarget, unoccludedReplicaRect, oldSur
face->replicaDrawTransform(), newTarget, m_stack.back().occlusionInTarget, m_sta
ck.back().occlusionInScreen); |
246 } | 247 } |
247 } | 248 } |
248 | 249 |
249 // FIXME: Remove usePaintTracking when paint tracking is on for paint culling. | 250 // FIXME: Remove usePaintTracking when paint tracking is on for paint culling. |
250 template<typename LayerType> | 251 template<typename LayerType> |
251 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) | 252 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, std::vector<gfx::Rect>* nonOccludingScree
nSpaceRects) |
252 { | 253 { |
253 DCHECK(layer->visibleContentRect().Contains(opaqueContents.bounds())); | 254 DCHECK(layer->visibleContentRect().Contains(opaqueContents.bounds())); |
254 | 255 |
255 bool clipped; | 256 bool clipped; |
256 gfx::QuadF visibleTransformedQuad = MathUtil::mapQuad(transform, gfx::QuadF(
layer->visibleContentRect()), clipped); | 257 gfx::QuadF visibleTransformedQuad = MathUtil::mapQuad(transform, gfx::QuadF(
layer->visibleContentRect()), clipped); |
257 // FIXME: Find a rect interior to each transformed quad. | 258 // FIXME: Find a rect interior to each transformed quad. |
258 if (clipped || !visibleTransformedQuad.IsRectilinear()) | 259 if (clipped || !visibleTransformedQuad.IsRectilinear()) |
259 return; | 260 return; |
260 | 261 |
261 for (Region::Iterator opaqueContentRects(opaqueContents); opaqueContentRects
.has_rect(); opaqueContentRects.next()) { | 262 for (Region::Iterator opaqueContentRects(opaqueContents); opaqueContentRects
.has_rect(); opaqueContentRects.next()) { |
262 // We've already checked for clipping in the mapQuad call above, these c
alls should not clip anything further. | 263 // We've already checked for clipping in the mapQuad call above, these c
alls should not clip anything further. |
263 gfx::Rect transformedRect = gfx::ToEnclosedRect(MathUtil::mapClippedRect
(transform, gfx::RectF(opaqueContentRects.rect()))); | 264 gfx::Rect transformedRect = gfx::ToEnclosedRect(MathUtil::mapClippedRect
(transform, gfx::RectF(opaqueContentRects.rect()))); |
264 transformedRect.Intersect(clipRectInTarget); | 265 transformedRect.Intersect(clipRectInTarget); |
265 if (transformedRect.width() >= minimumTrackingSize.width() || transforme
dRect.height() >= minimumTrackingSize.height()) { | 266 if (transformedRect.width() >= minimumTrackingSize.width() || transforme
dRect.height() >= minimumTrackingSize.height()) { |
266 if (occludingScreenSpaceRects) | 267 if (occludingScreenSpaceRects) |
267 occludingScreenSpaceRects->push_back(transformedRect); | 268 occludingScreenSpaceRects->push_back(transformedRect); |
268 region.Union(transformedRect); | 269 region.Union(transformedRect); |
269 } | 270 } |
270 } | 271 } |
| 272 |
| 273 if (nonOccludingScreenSpaceRects) { |
| 274 Region nonOpaqueContents = SubtractRegions(gfx::Rect(layer->contentBound
s()), opaqueContents); |
| 275 for (Region::Iterator nonOpaqueContentRects(nonOpaqueContents); nonOpaqu
eContentRects.has_rect(); nonOpaqueContentRects.next()) { |
| 276 // We've already checked for clipping in the mapQuad call above, the
se calls should not clip anything further. |
| 277 gfx::Rect transformedRect = gfx::ToEnclosedRect(MathUtil::mapClipped
Rect(transform, gfx::RectF(nonOpaqueContentRects.rect()))); |
| 278 transformedRect.Intersect(clipRectInTarget); |
| 279 if (transformedRect.IsEmpty()) |
| 280 continue; |
| 281 nonOccludingScreenSpaceRects->push_back(transformedRect); |
| 282 } |
| 283 } |
271 } | 284 } |
272 | 285 |
273 template<typename LayerType, typename RenderSurfaceType> | 286 template<typename LayerType, typename RenderSurfaceType> |
274 void OcclusionTrackerBase<LayerType, RenderSurfaceType>::markOccludedBehindLayer
(const LayerType* layer) | 287 void OcclusionTrackerBase<LayerType, RenderSurfaceType>::markOccludedBehindLayer
(const LayerType* layer) |
275 { | 288 { |
276 DCHECK(!m_stack.empty()); | 289 DCHECK(!m_stack.empty()); |
277 DCHECK(layer->renderTarget() == m_stack.back().target); | 290 DCHECK(layer->renderTarget() == m_stack.back().target); |
278 if (m_stack.empty()) | 291 if (m_stack.empty()) |
279 return; | 292 return; |
280 | 293 |
281 if (!layerOpacityKnown(layer) || layer->drawOpacity() < 1) | 294 if (!layerOpacityKnown(layer) || layer->drawOpacity() < 1) |
282 return; | 295 return; |
283 | 296 |
284 if (layerIsInUnsorted3dRenderingContext(layer)) | 297 if (layerIsInUnsorted3dRenderingContext(layer)) |
285 return; | 298 return; |
286 | 299 |
287 Region opaqueContents = layer->visibleContentOpaqueRegion(); | 300 Region opaqueContents = layer->visibleContentOpaqueRegion(); |
288 if (opaqueContents.IsEmpty()) | 301 if (opaqueContents.IsEmpty()) |
289 return; | 302 return; |
290 | 303 |
291 gfx::Rect clipRectInTarget = layerClipRectInTarget(layer); | 304 gfx::Rect clipRectInTarget = layerClipRectInTarget(layer); |
292 if (layerTransformsToTargetKnown(layer)) | 305 if (layerTransformsToTargetKnown(layer)) |
293 addOcclusionBehindLayer<LayerType>(m_stack.back().occlusionInTarget, lay
er, layer->drawTransform(), opaqueContents, clipRectInTarget, m_minimumTrackingS
ize, 0); | 306 addOcclusionBehindLayer<LayerType>(m_stack.back().occlusionInTarget, lay
er, layer->drawTransform(), opaqueContents, clipRectInTarget, m_minimumTrackingS
ize, 0, 0); |
294 | 307 |
295 // 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 | 308 // 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 |
296 // remain rectilinear, then we don't add any occlusion in screen space. | 309 // remain rectilinear, then we don't add any occlusion in screen space. |
297 | 310 |
298 if (layerTransformsToScreenKnown(layer)) { | 311 if (layerTransformsToScreenKnown(layer)) { |
299 WebTransformationMatrix targetToScreenTransform = m_stack.back().target-
>renderSurface()->screenSpaceTransform(); | 312 WebTransformationMatrix targetToScreenTransform = m_stack.back().target-
>renderSurface()->screenSpaceTransform(); |
300 bool clipped; | 313 bool clipped; |
301 gfx::QuadF clipQuadInScreen = MathUtil::mapQuad(targetToScreenTransform,
gfx::QuadF(clipRectInTarget), clipped); | 314 gfx::QuadF clipQuadInScreen = MathUtil::mapQuad(targetToScreenTransform,
gfx::QuadF(clipRectInTarget), clipped); |
302 // FIXME: Find a rect interior to the transformed clip quad. | 315 // FIXME: Find a rect interior to the transformed clip quad. |
303 if (clipped || !clipQuadInScreen.IsRectilinear()) | 316 if (clipped || !clipQuadInScreen.IsRectilinear()) |
304 return; | 317 return; |
305 gfx::Rect clipRectInScreen = gfx::IntersectRects(m_rootTargetRect, gfx::
ToEnclosedRect(clipQuadInScreen.BoundingBox())); | 318 gfx::Rect clipRectInScreen = gfx::IntersectRects(m_rootTargetRect, gfx::
ToEnclosedRect(clipQuadInScreen.BoundingBox())); |
306 addOcclusionBehindLayer<LayerType>(m_stack.back().occlusionInScreen, lay
er, layer->screenSpaceTransform(), opaqueContents, clipRectInScreen, m_minimumTr
ackingSize, m_occludingScreenSpaceRects); | 319 addOcclusionBehindLayer<LayerType>(m_stack.back().occlusionInScreen, lay
er, layer->screenSpaceTransform(), opaqueContents, clipRectInScreen, m_minimumTr
ackingSize, m_occludingScreenSpaceRects, m_nonOccludingScreenSpaceRects); |
307 } | 320 } |
308 } | 321 } |
309 | 322 |
310 static inline bool testContentRectOccluded(const gfx::Rect& contentRect, const W
ebTransformationMatrix& contentSpaceTransform, const gfx::Rect& clipRectInTarget
, const Region& occlusion) | 323 static inline bool testContentRectOccluded(const gfx::Rect& contentRect, const W
ebTransformationMatrix& contentSpaceTransform, const gfx::Rect& clipRectInTarget
, const Region& occlusion) |
311 { | 324 { |
312 gfx::RectF transformedRect = MathUtil::mapClippedRect(contentSpaceTransform,
gfx::RectF(contentRect)); | 325 gfx::RectF transformedRect = MathUtil::mapClippedRect(contentSpaceTransform,
gfx::RectF(contentRect)); |
313 // Take the gfx::ToEnclosingRect, as we want to include partial pixels in th
e test. | 326 // Take the gfx::ToEnclosingRect, as we want to include partial pixels in th
e test. |
314 gfx::Rect targetRect = gfx::IntersectRects(gfx::ToEnclosingRect(transformedR
ect), clipRectInTarget); | 327 gfx::Rect targetRect = gfx::IntersectRects(gfx::ToEnclosingRect(transformedR
ect), clipRectInTarget); |
315 return occlusion.Contains(targetRect); | 328 return occlusion.Contains(targetRect); |
316 } | 329 } |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
459 // FIXME: we could remove this helper function, but unit tests currently ove
rride this | 472 // FIXME: we could remove this helper function, but unit tests currently ove
rride this |
460 // function, and they need to be verified/adjusted before this can be
removed. | 473 // function, and they need to be verified/adjusted before this can be
removed. |
461 return layer->drawableContentRect(); | 474 return layer->drawableContentRect(); |
462 } | 475 } |
463 | 476 |
464 // Instantiate (and export) templates here for the linker. | 477 // Instantiate (and export) templates here for the linker. |
465 template class OcclusionTrackerBase<Layer, RenderSurface>; | 478 template class OcclusionTrackerBase<Layer, RenderSurface>; |
466 template class OcclusionTrackerBase<LayerImpl, RenderSurfaceImpl>; | 479 template class OcclusionTrackerBase<LayerImpl, RenderSurfaceImpl>; |
467 | 480 |
468 } // namespace cc | 481 } // namespace cc |
OLD | NEW |