void CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::markOccludedBehindLayer(const LayerType* layer) { ASSERT(!m_stack.isEmpty()); ASSERT(layer->targetRenderSurface() == m_stack.last().surface); if (m_stack.isEmpty()) return; if (!layerOpacityKnown(layer) || layer->drawOpacity() < 1) return; IntRect scissorInTarget = layerScissorRectInTargetSurface(layer); if (layerTransformsToTargetKnown(layer)) m_stack.last().occlusionInTarget.unite(computeOcclusionBehindLayer<LayerType>(layer, contentToTargetSurfaceTransform<LayerType>(layer), scissorInTarget, m_usePaintTracking)); // We must clip the occlusion within the layer's scissorInTarget within screen space as well. If the scissor rect can't be moved to screen space and // remain rectilinear, then we don't add any occlusion in screen space. if (layerTransformsToScreenKnown(layer)) { TransformationMatrix targetToScreenTransform = m_stack.last().surface->screenSpaceTransform(); FloatQuad scissorInScreenQuad = targetToScreenTransform.mapQuad(FloatQuad(FloatRect(scissorInTarget))); if (!scissorInScreenQuad.isRectilinear()) return; IntRect scissorInScreenRect = intersection(m_scissorRectInScreenSpace, enclosedIntRect(CCMathUtil::mapClippedRect(targetToScreenTransform, FloatRect(scissorInTarget)))); m_stack.last().occlusionInScreen.unite(computeOcclusionBehindLayer<LayerType>(layer, contentToScreenSpaceTransform<LayerType>(layer), scissorInScreenRect, m_usePaintTracking)); } }
IntRect CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::unoccludedContentRect(const LayerType* layer, const IntRect& contentRect) const { ASSERT(!m_stack.isEmpty()); if (m_stack.isEmpty()) return contentRect; if (contentRect.isEmpty()) return contentRect; ASSERT(layer->targetRenderSurface() == m_stack.last().surface); // We want to return a rect that contains all the visible parts of |contentRect| in both screen space and in the target surface. // So we find the visible parts of |contentRect| in each space, and take the intersection. TransformationMatrix contentToScreenSpace = contentToScreenSpaceTransform<LayerType>(layer); TransformationMatrix contentToTargetSurface = contentToTargetSurfaceTransform<LayerType>(layer); IntRect unoccludedInScreen = computeUnoccludedContentRect(contentRect, contentToScreenSpace, m_scissorRectInScreenSpace, m_stack.last().occlusionInScreen); if (unoccludedInScreen.isEmpty()) return IntRect(); IntRect unoccludedInTarget = computeUnoccludedContentRect(contentRect, contentToTargetSurface, layerScissorRectInTargetSurface(layer), m_stack.last().occlusionInTarget); return intersection(unoccludedInScreen, unoccludedInTarget); }
bool CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::occluded(const LayerType* layer, const IntRect& contentRect) const { ASSERT(!m_stack.isEmpty()); if (m_stack.isEmpty()) return false; if (contentRect.isEmpty()) return true; ASSERT(layer->targetRenderSurface() == m_stack.last().surface); if (testContentRectOccluded(contentRect, contentToScreenSpaceTransform<LayerType>(layer), m_scissorRectInScreenSpace, m_stack.last().occlusionInScreen)) return true; if (testContentRectOccluded(contentRect, contentToTargetSurfaceTransform<LayerType>(layer), layerScissorRectInTargetSurface(layer), m_stack.last().occlusionInTarget)) return true; return false; }