| 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" |
| (...skipping 29 matching lines...) Expand all Loading... |
| 40 finishedRenderTarget(renderTarget); | 40 finishedRenderTarget(renderTarget); |
| 41 } | 41 } |
| 42 | 42 |
| 43 template<typename LayerType, typename RenderSurfaceType> | 43 template<typename LayerType, typename RenderSurfaceType> |
| 44 void OcclusionTrackerBase<LayerType, RenderSurfaceType>::leaveLayer(const LayerI
teratorPosition<LayerType>& layerIterator) | 44 void OcclusionTrackerBase<LayerType, RenderSurfaceType>::leaveLayer(const LayerI
teratorPosition<LayerType>& layerIterator) |
| 45 { | 45 { |
| 46 LayerType* renderTarget = layerIterator.targetRenderSurfaceLayer; | 46 LayerType* renderTarget = layerIterator.targetRenderSurfaceLayer; |
| 47 | 47 |
| 48 if (layerIterator.representsItself) | 48 if (layerIterator.representsItself) |
| 49 markOccludedBehindLayer(layerIterator.currentLayer); | 49 markOccludedBehindLayer(layerIterator.currentLayer); |
| 50 // TODO(danakj): This should be done when entering the contributing surface,
but in a way that the surface's own occlusion won't occlude itself. |
| 50 else if (layerIterator.representsContributingRenderSurface) | 51 else if (layerIterator.representsContributingRenderSurface) |
| 51 leaveToRenderTarget(renderTarget); | 52 leaveToRenderTarget(renderTarget); |
| 52 } | 53 } |
| 53 | 54 |
| 54 template<typename RenderSurfaceType> | 55 template<typename RenderSurfaceType> |
| 55 static gfx::Rect screenSpaceClipRectInTargetSurface(const RenderSurfaceType* tar
getSurface, gfx::Rect screenSpaceClipRect) | 56 static gfx::Rect screenSpaceClipRectInTargetSurface(const RenderSurfaceType* tar
getSurface, gfx::Rect screenSpaceClipRect) |
| 56 { | 57 { |
| 57 gfx::Transform inverseScreenSpaceTransform(gfx::Transform::kSkipInitializati
on); | 58 gfx::Transform inverseScreenSpaceTransform(gfx::Transform::kSkipInitializati
on); |
| 58 if (!targetSurface->screenSpaceTransform().GetInverse(&inverseScreenSpaceTra
nsform)) | 59 if (!targetSurface->screenSpaceTransform().GetInverse(&inverseScreenSpaceTra
nsform)) |
| 59 return targetSurface->contentRect(); | 60 return targetSurface->contentRect(); |
| (...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 272 DCHECK(layer->renderTarget() == m_stack.back().target); | 273 DCHECK(layer->renderTarget() == m_stack.back().target); |
| 273 if (m_stack.empty()) | 274 if (m_stack.empty()) |
| 274 return; | 275 return; |
| 275 | 276 |
| 276 if (!layerOpacityKnown(layer) || layer->drawOpacity() < 1) | 277 if (!layerOpacityKnown(layer) || layer->drawOpacity() < 1) |
| 277 return; | 278 return; |
| 278 | 279 |
| 279 if (layerIsInUnsorted3dRenderingContext(layer)) | 280 if (layerIsInUnsorted3dRenderingContext(layer)) |
| 280 return; | 281 return; |
| 281 | 282 |
| 283 if (!layerTransformsToTargetKnown(layer)) |
| 284 return; |
| 285 |
| 282 Region opaqueContents = layer->visibleContentOpaqueRegion(); | 286 Region opaqueContents = layer->visibleContentOpaqueRegion(); |
| 283 if (opaqueContents.IsEmpty()) | 287 if (opaqueContents.IsEmpty()) |
| 284 return; | 288 return; |
| 285 | 289 |
| 286 DCHECK(layer->visibleContentRect().Contains(opaqueContents.bounds())); | 290 DCHECK(layer->visibleContentRect().Contains(opaqueContents.bounds())); |
| 287 | 291 |
| 288 if (!layerTransformsToTargetKnown(layer)) | |
| 289 return; | |
| 290 | |
| 291 bool clipped; | 292 bool clipped; |
| 292 gfx::QuadF visibleTransformedQuad = MathUtil::mapQuad(layer->drawTransform()
, gfx::QuadF(opaqueContents.bounds()), clipped); | 293 gfx::QuadF visibleTransformedQuad = MathUtil::mapQuad(layer->drawTransform()
, gfx::QuadF(opaqueContents.bounds()), clipped); |
| 293 // FIXME: Find a rect interior to each transformed quad. | 294 // FIXME: Find a rect interior to each transformed quad. |
| 294 if (clipped || !visibleTransformedQuad.IsRectilinear()) | 295 if (clipped || !visibleTransformedQuad.IsRectilinear()) |
| 295 return; | 296 return; |
| 296 | 297 |
| 297 gfx::Rect clipRectInTarget = gfx::IntersectRects( | 298 gfx::Rect clipRectInTarget = gfx::IntersectRects( |
| 298 layerClipRectInTarget(layer), | 299 layer->renderTarget()->renderSurface()->contentRect(), |
| 299 screenSpaceClipRectInTargetSurface(layer->renderTarget()->renderSurface(
), m_screenSpaceClipRect)); | 300 screenSpaceClipRectInTargetSurface(layer->renderTarget()->renderSurface(
), m_screenSpaceClipRect)); |
| 300 | 301 |
| 301 for (Region::Iterator opaqueContentRects(opaqueContents); opaqueContentRects
.has_rect(); opaqueContentRects.next()) { | 302 for (Region::Iterator opaqueContentRects(opaqueContents); opaqueContentRects
.has_rect(); opaqueContentRects.next()) { |
| 302 gfx::Rect transformedRect = gfx::ToEnclosedRect(MathUtil::mapQuad(layer-
>drawTransform(), gfx::QuadF(opaqueContentRects.rect()), clipped).BoundingBox())
; | 303 gfx::Rect transformedRect = gfx::ToEnclosedRect(MathUtil::mapQuad(layer-
>drawTransform(), gfx::QuadF(opaqueContentRects.rect()), clipped).BoundingBox())
; |
| 303 DCHECK(!clipped); // We only map if the transform preserves axis alignme
nt. | 304 DCHECK(!clipped); // We only map if the transform preserves axis alignme
nt. |
| 304 transformedRect.Intersect(clipRectInTarget); | 305 transformedRect.Intersect(clipRectInTarget); |
| 305 if (transformedRect.width() < m_minimumTrackingSize.width() && transform
edRect.height() < m_minimumTrackingSize.height()) | 306 if (transformedRect.width() < m_minimumTrackingSize.width() && transform
edRect.height() < m_minimumTrackingSize.height()) |
| 306 continue; | 307 continue; |
| 307 m_stack.back().occlusionFromInsideTarget.Union(transformedRect); | 308 m_stack.back().occlusionFromInsideTarget.Union(transformedRect); |
| 308 | 309 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 328 continue; | 329 continue; |
| 329 | 330 |
| 330 gfx::QuadF screenSpaceQuad = MathUtil::mapQuad(layer->renderTarget()->re
nderSurface()->screenSpaceTransform(), gfx::QuadF(transformedRect), clipped); | 331 gfx::QuadF screenSpaceQuad = MathUtil::mapQuad(layer->renderTarget()->re
nderSurface()->screenSpaceTransform(), gfx::QuadF(transformedRect), clipped); |
| 331 // TODO(danakj): Store the quad in the debug info instead of the boundin
g box. | 332 // TODO(danakj): Store the quad in the debug info instead of the boundin
g box. |
| 332 gfx::Rect screenSpaceRect = gfx::ToEnclosedRect(screenSpaceQuad.Bounding
Box()); | 333 gfx::Rect screenSpaceRect = gfx::ToEnclosedRect(screenSpaceQuad.Bounding
Box()); |
| 333 m_nonOccludingScreenSpaceRects->push_back(screenSpaceRect); | 334 m_nonOccludingScreenSpaceRects->push_back(screenSpaceRect); |
| 334 } | 335 } |
| 335 } | 336 } |
| 336 | 337 |
| 337 template<typename LayerType, typename RenderSurfaceType> | 338 template<typename LayerType, typename RenderSurfaceType> |
| 338 bool OcclusionTrackerBase<LayerType, RenderSurfaceType>::occluded(const LayerTyp
e* renderTarget, const gfx::Rect& contentRect, const gfx::Transform& drawTransfo
rm, bool implDrawTransformIsUnknown, const gfx::Rect& clippedRectInTarget, bool*
hasOcclusionFromOutsideTargetSurface) const | 339 bool OcclusionTrackerBase<LayerType, RenderSurfaceType>::occluded(const LayerTyp
e* renderTarget, gfx::Rect contentRect, const gfx::Transform& drawTransform, boo
l implDrawTransformIsUnknown, bool isClipped, gfx::Rect clipRectInTarget, bool*
hasOcclusionFromOutsideTargetSurface) const |
| 339 { | 340 { |
| 340 if (hasOcclusionFromOutsideTargetSurface) | 341 if (hasOcclusionFromOutsideTargetSurface) |
| 341 *hasOcclusionFromOutsideTargetSurface = false; | 342 *hasOcclusionFromOutsideTargetSurface = false; |
| 342 | 343 |
| 343 DCHECK(!m_stack.empty()); | 344 DCHECK(!m_stack.empty()); |
| 344 if (m_stack.empty()) | 345 if (m_stack.empty()) |
| 345 return false; | 346 return false; |
| 346 if (contentRect.IsEmpty()) | 347 if (contentRect.IsEmpty()) |
| 347 return true; | 348 return true; |
| 348 if (implDrawTransformIsUnknown) | 349 if (implDrawTransformIsUnknown) |
| 349 return false; | 350 return false; |
| 350 | 351 |
| 351 // For tests with no render target. | 352 // For tests with no render target. |
| 352 if (!renderTarget) | 353 if (!renderTarget) |
| 353 return false; | 354 return false; |
| 354 | 355 |
| 355 DCHECK(renderTarget->renderTarget() == renderTarget); | 356 DCHECK(renderTarget->renderTarget() == renderTarget); |
| 356 DCHECK(renderTarget->renderSurface()); | 357 DCHECK(renderTarget->renderSurface()); |
| 357 DCHECK(renderTarget == m_stack.back().target); | 358 DCHECK(renderTarget == m_stack.back().target); |
| 358 | 359 |
| 359 gfx::Transform inverseDrawTransform(gfx::Transform::kSkipInitialization); | 360 gfx::Transform inverseDrawTransform(gfx::Transform::kSkipInitialization); |
| 360 if (!drawTransform.GetInverse(&inverseDrawTransform)) | 361 if (!drawTransform.GetInverse(&inverseDrawTransform)) |
| 361 return false; | 362 return false; |
| 362 | 363 |
| 363 // Take the ToEnclosingRect at each step, as we want to contain any unocclud
ed partial pixels in the resulting Rect. | 364 // Take the ToEnclosingRect at each step, as we want to contain any unocclud
ed partial pixels in the resulting Rect. |
| 364 Region unoccludedRegionInTargetSurface = gfx::ToEnclosingRect(MathUtil::mapC
lippedRect(drawTransform, gfx::RectF(contentRect))); | 365 Region unoccludedRegionInTargetSurface = gfx::ToEnclosingRect(MathUtil::mapC
lippedRect(drawTransform, gfx::RectF(contentRect))); |
| 365 // Layers can't clip across surfaces, so count this as internal occlusion. | 366 // Layers can't clip across surfaces, so count this as internal occlusion. |
| 366 // TODO(danakj): This would change if we clipped to the visibleContentRect()
. | 367 if (isClipped) |
| 367 unoccludedRegionInTargetSurface.Intersect(clippedRectInTarget); | 368 unoccludedRegionInTargetSurface.Intersect(clipRectInTarget); |
| 368 unoccludedRegionInTargetSurface.Subtract(m_stack.back().occlusionFromInsideT
arget); | 369 unoccludedRegionInTargetSurface.Subtract(m_stack.back().occlusionFromInsideT
arget); |
| 369 gfx::RectF unoccludedRectInTargetSurfaceWithoutOutsideOcclusion = unoccluded
RegionInTargetSurface.bounds(); | 370 gfx::RectF unoccludedRectInTargetSurfaceWithoutOutsideOcclusion = unoccluded
RegionInTargetSurface.bounds(); |
| 370 unoccludedRegionInTargetSurface.Subtract(m_stack.back().occlusionFromOutside
Target); | 371 unoccludedRegionInTargetSurface.Subtract(m_stack.back().occlusionFromOutside
Target); |
| 371 | 372 |
| 372 // Treat other clipping as occlusion from outside the surface. | 373 // Treat other clipping as occlusion from outside the surface. |
| 374 // TODO(danakj): Clip to visibleContentRect? |
| 373 unoccludedRegionInTargetSurface.Intersect(renderTarget->renderSurface()->con
tentRect()); | 375 unoccludedRegionInTargetSurface.Intersect(renderTarget->renderSurface()->con
tentRect()); |
| 374 unoccludedRegionInTargetSurface.Intersect(screenSpaceClipRectInTargetSurface
(renderTarget->renderSurface(), m_screenSpaceClipRect)); | 376 unoccludedRegionInTargetSurface.Intersect(screenSpaceClipRectInTargetSurface
(renderTarget->renderSurface(), m_screenSpaceClipRect)); |
| 375 | 377 |
| 376 gfx::RectF unoccludedRectInTargetSurface = unoccludedRegionInTargetSurface.b
ounds(); | 378 gfx::RectF unoccludedRectInTargetSurface = unoccludedRegionInTargetSurface.b
ounds(); |
| 377 | 379 |
| 378 if (hasOcclusionFromOutsideTargetSurface) { | 380 if (hasOcclusionFromOutsideTargetSurface) { |
| 379 // Check if the unoccluded rect shrank when applying outside occlusion. | 381 // Check if the unoccluded rect shrank when applying outside occlusion. |
| 380 *hasOcclusionFromOutsideTargetSurface = !gfx::SubtractRects(unoccludedRe
ctInTargetSurfaceWithoutOutsideOcclusion, unoccludedRectInTargetSurface).IsEmpty
(); | 382 *hasOcclusionFromOutsideTargetSurface = !gfx::SubtractRects(unoccludedRe
ctInTargetSurfaceWithoutOutsideOcclusion, unoccludedRectInTargetSurface).IsEmpty
(); |
| 381 } | 383 } |
| 382 | 384 |
| 383 return unoccludedRectInTargetSurface.IsEmpty(); | 385 return unoccludedRectInTargetSurface.IsEmpty(); |
| 384 } | 386 } |
| 385 | 387 |
| 386 template<typename LayerType, typename RenderSurfaceType> | 388 template<typename LayerType, typename RenderSurfaceType> |
| 387 gfx::Rect OcclusionTrackerBase<LayerType, RenderSurfaceType>::unoccludedContentR
ect(const LayerType* renderTarget, const gfx::Rect& contentRect, const gfx::Tran
sform& drawTransform, bool implDrawTransformIsUnknown, const gfx::Rect& clippedR
ectInTarget, bool* hasOcclusionFromOutsideTargetSurface) const | 389 gfx::Rect OcclusionTrackerBase<LayerType, RenderSurfaceType>::unoccludedContentR
ect(const LayerType* renderTarget, gfx::Rect contentRect, const gfx::Transform&
drawTransform, bool implDrawTransformIsUnknown, bool isClipped, gfx::Rect clipRe
ctInTarget, bool* hasOcclusionFromOutsideTargetSurface) const |
| 388 { | 390 { |
| 389 if (hasOcclusionFromOutsideTargetSurface) | 391 if (hasOcclusionFromOutsideTargetSurface) |
| 390 *hasOcclusionFromOutsideTargetSurface = false; | 392 *hasOcclusionFromOutsideTargetSurface = false; |
| 391 | 393 |
| 392 DCHECK(!m_stack.empty()); | 394 DCHECK(!m_stack.empty()); |
| 393 if (m_stack.empty()) | 395 if (m_stack.empty()) |
| 394 return contentRect; | 396 return contentRect; |
| 395 if (contentRect.IsEmpty()) | 397 if (contentRect.IsEmpty()) |
| 396 return contentRect; | 398 return contentRect; |
| 397 if (implDrawTransformIsUnknown) | 399 if (implDrawTransformIsUnknown) |
| 398 return contentRect; | 400 return contentRect; |
| 399 | 401 |
| 400 // For tests with no render target. | 402 // For tests with no render target. |
| 401 if (!renderTarget) | 403 if (!renderTarget) |
| 402 return contentRect; | 404 return contentRect; |
| 403 | 405 |
| 404 DCHECK(renderTarget->renderTarget() == renderTarget); | 406 DCHECK(renderTarget->renderTarget() == renderTarget); |
| 405 DCHECK(renderTarget->renderSurface()); | 407 DCHECK(renderTarget->renderSurface()); |
| 406 DCHECK(renderTarget == m_stack.back().target); | 408 DCHECK(renderTarget == m_stack.back().target); |
| 407 | 409 |
| 408 gfx::Transform inverseDrawTransform(gfx::Transform::kSkipInitialization); | 410 gfx::Transform inverseDrawTransform(gfx::Transform::kSkipInitialization); |
| 409 if (!drawTransform.GetInverse(&inverseDrawTransform)) | 411 if (!drawTransform.GetInverse(&inverseDrawTransform)) |
| 410 return contentRect; | 412 return contentRect; |
| 411 | 413 |
| 412 // Take the ToEnclosingRect at each step, as we want to contain any unocclud
ed partial pixels in the resulting Rect. | 414 // Take the ToEnclosingRect at each step, as we want to contain any unocclud
ed partial pixels in the resulting Rect. |
| 413 Region unoccludedRegionInTargetSurface = gfx::ToEnclosingRect(MathUtil::mapC
lippedRect(drawTransform, gfx::RectF(contentRect))); | 415 Region unoccludedRegionInTargetSurface = gfx::ToEnclosingRect(MathUtil::mapC
lippedRect(drawTransform, gfx::RectF(contentRect))); |
| 414 // Layers can't clip across surfaces, so count this as internal occlusion. | 416 // Layers can't clip across surfaces, so count this as internal occlusion. |
| 415 // TODO(danakj): This would change if we clipped to the visibleContentRect()
. | 417 if (isClipped) |
| 416 unoccludedRegionInTargetSurface.Intersect(clippedRectInTarget); | 418 unoccludedRegionInTargetSurface.Intersect(clipRectInTarget); |
| 417 unoccludedRegionInTargetSurface.Subtract(m_stack.back().occlusionFromInsideT
arget); | 419 unoccludedRegionInTargetSurface.Subtract(m_stack.back().occlusionFromInsideT
arget); |
| 418 gfx::RectF unoccludedRectInTargetSurfaceWithoutOutsideOcclusion = unoccluded
RegionInTargetSurface.bounds(); | 420 gfx::RectF unoccludedRectInTargetSurfaceWithoutOutsideOcclusion = unoccluded
RegionInTargetSurface.bounds(); |
| 419 unoccludedRegionInTargetSurface.Subtract(m_stack.back().occlusionFromOutside
Target); | 421 unoccludedRegionInTargetSurface.Subtract(m_stack.back().occlusionFromOutside
Target); |
| 420 | 422 |
| 421 // Treat other clipping as occlusion from outside the surface. | 423 // Treat other clipping as occlusion from outside the surface. |
| 424 // TODO(danakj): Clip to visibleContentRect? |
| 422 unoccludedRegionInTargetSurface.Intersect(renderTarget->renderSurface()->con
tentRect()); | 425 unoccludedRegionInTargetSurface.Intersect(renderTarget->renderSurface()->con
tentRect()); |
| 423 unoccludedRegionInTargetSurface.Intersect(screenSpaceClipRectInTargetSurface
(renderTarget->renderSurface(), m_screenSpaceClipRect)); | 426 unoccludedRegionInTargetSurface.Intersect(screenSpaceClipRectInTargetSurface
(renderTarget->renderSurface(), m_screenSpaceClipRect)); |
| 424 | 427 |
| 425 gfx::RectF unoccludedRectInTargetSurface = unoccludedRegionInTargetSurface.b
ounds(); | 428 gfx::RectF unoccludedRectInTargetSurface = unoccludedRegionInTargetSurface.b
ounds(); |
| 426 gfx::Rect unoccludedRect = gfx::ToEnclosingRect(MathUtil::projectClippedRect
(inverseDrawTransform, unoccludedRectInTargetSurface)); | 429 gfx::Rect unoccludedRect = gfx::ToEnclosingRect(MathUtil::projectClippedRect
(inverseDrawTransform, unoccludedRectInTargetSurface)); |
| 427 unoccludedRect.Intersect(contentRect); | 430 unoccludedRect.Intersect(contentRect); |
| 428 | 431 |
| 429 if (hasOcclusionFromOutsideTargetSurface) { | 432 if (hasOcclusionFromOutsideTargetSurface) { |
| 430 // Check if the unoccluded rect shrank when applying outside occlusion. | 433 // Check if the unoccluded rect shrank when applying outside occlusion. |
| 431 *hasOcclusionFromOutsideTargetSurface = !gfx::SubtractRects(unoccludedRe
ctInTargetSurfaceWithoutOutsideOcclusion, unoccludedRectInTargetSurface).IsEmpty
(); | 434 *hasOcclusionFromOutsideTargetSurface = !gfx::SubtractRects(unoccludedRe
ctInTargetSurfaceWithoutOutsideOcclusion, unoccludedRectInTargetSurface).IsEmpty
(); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 464 if (!drawTransform.GetInverse(&inverseDrawTransform)) | 467 if (!drawTransform.GetInverse(&inverseDrawTransform)) |
| 465 return contentRect; | 468 return contentRect; |
| 466 | 469 |
| 467 // A contributing surface doesn't get occluded by things inside its own surf
ace, so only things outside the surface can occlude it. That occlusion is | 470 // A contributing surface doesn't get occluded by things inside its own surf
ace, so only things outside the surface can occlude it. That occlusion is |
| 468 // found just below the top of the stack (if it exists). | 471 // found just below the top of the stack (if it exists). |
| 469 bool hasOcclusion = m_stack.size() > 1; | 472 bool hasOcclusion = m_stack.size() > 1; |
| 470 | 473 |
| 471 // Take the ToEnclosingRect at each step, as we want to contain any unocclud
ed partial pixels in the resulting Rect. | 474 // Take the ToEnclosingRect at each step, as we want to contain any unocclud
ed partial pixels in the resulting Rect. |
| 472 Region unoccludedRegionInTargetSurface = gfx::ToEnclosingRect(MathUtil::mapC
lippedRect(drawTransform, gfx::RectF(contentRect))); | 475 Region unoccludedRegionInTargetSurface = gfx::ToEnclosingRect(MathUtil::mapC
lippedRect(drawTransform, gfx::RectF(contentRect))); |
| 473 // Layers can't clip across surfaces, so count this as internal occlusion. | 476 // Layers can't clip across surfaces, so count this as internal occlusion. |
| 474 // TODO(danakj): This would change if we clipped to the visibleContentRect()
. | |
| 475 if (surface->isClipped()) | 477 if (surface->isClipped()) |
| 476 unoccludedRegionInTargetSurface.Intersect(surface->clipRect()); | 478 unoccludedRegionInTargetSurface.Intersect(surface->clipRect()); |
| 477 if (hasOcclusion) { | 479 if (hasOcclusion) { |
| 478 const StackObject& secondLast = m_stack[m_stack.size() - 2]; | 480 const StackObject& secondLast = m_stack[m_stack.size() - 2]; |
| 479 unoccludedRegionInTargetSurface.Subtract(secondLast.occlusionFromInsideT
arget); | 481 unoccludedRegionInTargetSurface.Subtract(secondLast.occlusionFromInsideT
arget); |
| 480 } | 482 } |
| 481 gfx::RectF unoccludedRectInTargetSurfaceWithoutOutsideOcclusion = unoccluded
RegionInTargetSurface.bounds(); | 483 gfx::RectF unoccludedRectInTargetSurfaceWithoutOutsideOcclusion = unoccluded
RegionInTargetSurface.bounds(); |
| 482 if (hasOcclusion) { | 484 if (hasOcclusion) { |
| 483 const StackObject& secondLast = m_stack[m_stack.size() - 2]; | 485 const StackObject& secondLast = m_stack[m_stack.size() - 2]; |
| 484 unoccludedRegionInTargetSurface.Subtract(secondLast.occlusionFromOutside
Target); | 486 unoccludedRegionInTargetSurface.Subtract(secondLast.occlusionFromOutside
Target); |
| 485 } | 487 } |
| 486 | 488 |
| 487 // Treat other clipping as occlusion from outside the target surface. | 489 // Treat other clipping as occlusion from outside the target surface. |
| 488 unoccludedRegionInTargetSurface.Intersect(contributingSurfaceRenderTarget->r
enderSurface()->contentRect()); | 490 unoccludedRegionInTargetSurface.Intersect(contributingSurfaceRenderTarget->r
enderSurface()->contentRect()); |
| 489 unoccludedRegionInTargetSurface.Intersect(screenSpaceClipRectInTargetSurface
(contributingSurfaceRenderTarget->renderSurface(), m_screenSpaceClipRect)); | 491 unoccludedRegionInTargetSurface.Intersect(screenSpaceClipRectInTargetSurface
(contributingSurfaceRenderTarget->renderSurface(), m_screenSpaceClipRect)); |
| 490 | 492 |
| 491 gfx::RectF unoccludedRectInTargetSurface = unoccludedRegionInTargetSurface.b
ounds(); | 493 gfx::RectF unoccludedRectInTargetSurface = unoccludedRegionInTargetSurface.b
ounds(); |
| 492 gfx::Rect unoccludedRect = gfx::ToEnclosingRect(MathUtil::projectClippedRect
(inverseDrawTransform, unoccludedRectInTargetSurface)); | 494 gfx::Rect unoccludedRect = gfx::ToEnclosingRect(MathUtil::projectClippedRect
(inverseDrawTransform, unoccludedRectInTargetSurface)); |
| 493 unoccludedRect.Intersect(contentRect); | 495 unoccludedRect.Intersect(contentRect); |
| 494 | 496 |
| 495 if (hasOcclusionFromOutsideTargetSurface) { | 497 if (hasOcclusionFromOutsideTargetSurface) { |
| 496 // Check if the unoccluded rect shrank when applying outside occlusion. | 498 // Check if the unoccluded rect shrank when applying outside occlusion. |
| 497 *hasOcclusionFromOutsideTargetSurface = !gfx::SubtractRects(unoccludedRe
ctInTargetSurfaceWithoutOutsideOcclusion, unoccludedRectInTargetSurface).IsEmpty
(); | 499 *hasOcclusionFromOutsideTargetSurface = !gfx::SubtractRects(unoccludedRe
ctInTargetSurfaceWithoutOutsideOcclusion, unoccludedRectInTargetSurface).IsEmpty
(); |
| 498 } | 500 } |
| 499 | 501 |
| 500 return unoccludedRect; | 502 return unoccludedRect; |
| 501 } | 503 } |
| 502 | 504 |
| 503 template<typename LayerType, typename RenderSurfaceType> | |
| 504 gfx::Rect OcclusionTrackerBase<LayerType, RenderSurfaceType>::layerClipRectInTar
get(const LayerType* layer) const | |
| 505 { | |
| 506 // TODO(danakj): Can we remove this use of drawableContentRect and just use
the clipRect() and target surface contentRect? | |
| 507 // TODO(danakj): Or can we use visibleContentRect() which is much tighter? | |
| 508 return layer->drawableContentRect(); | |
| 509 } | |
| 510 | |
| 511 // Instantiate (and export) templates here for the linker. | 505 // Instantiate (and export) templates here for the linker. |
| 512 template class OcclusionTrackerBase<Layer, RenderSurface>; | 506 template class OcclusionTrackerBase<Layer, RenderSurface>; |
| 513 template class OcclusionTrackerBase<LayerImpl, RenderSurfaceImpl>; | 507 template class OcclusionTrackerBase<LayerImpl, RenderSurfaceImpl>; |
| 514 | 508 |
| 515 } // namespace cc | 509 } // namespace cc |
| OLD | NEW |