| 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 |