bool RenderLayerCompositor::requiresCompositingForMobileSites(const RenderLayer* layer) const { // First, check if we are in an iframe, and if so bail out if (m_renderView->document()->frame()->tree()->parent()) return false; RenderObject* renderer = layer->renderer(); // Check for transforms if (requiresCompositingForTransform(renderer)) return true; // Check for animations if (requiresCompositingForAnimation(renderer)) return true; #if ENABLE(COMPOSITED_FIXED_ELEMENTS) // For the moment, we want to only enable fixed composited layers on mobile websites. // We can consider a website as being a 'mobile' site if all the // following checks are true: // 1) - the viewport width is either undefined (-1) or equal to device-width (0), and // 2) - no scaling is allowed if (!layer->isFixed()) return false; Settings* settings = m_renderView->document()->settings(); if (!settings) return false; if ((settings->viewportWidth() == -1 || settings->viewportWidth() == 0) && !settings->viewportUserScalable()) return true; #endif return false; }
bool RenderLayerCompositor::updateBacking(RenderLayer* layer, CompositingChangeRepaint shouldRepaint) { bool layerChanged = false; if (needsToBeComposited(layer)) { enableCompositingMode(); // 3D transforms turn off the testing of overlap. if (requiresCompositingForTransform(layer->renderer())) setCompositingConsultsOverlap(false); if (!layer->backing()) { // If we need to repaint, do so before making backing if (shouldRepaint == CompositingChangeRepaintNow) repaintOnCompositingChange(layer); layer->ensureBacking(); layerChanged = true; } } else { if (layer->backing()) { // If we're removing backing on a reflection, clear the source GraphicsLayer's pointer to // its replica GraphicsLayer. In practice this should never happen because reflectee and reflection // are both either composited, or not composited. if (layer->isReflection()) { RenderLayer* sourceLayer = toRenderBoxModelObject(layer->renderer()->parent())->layer(); if (RenderLayerBacking* backing = sourceLayer->backing()) { ASSERT(backing->graphicsLayer()->replicaLayer() == layer->backing()->graphicsLayer()); backing->graphicsLayer()->setReplicatedByLayer(0); } } layer->clearBacking(); layerChanged = true; // The layer's cached repaints rects are relative to the repaint container, so change when // compositing changes; we need to update them here. layer->computeRepaintRects(); // If we need to repaint, do so now that we've removed the backing if (shouldRepaint == CompositingChangeRepaintNow) repaintOnCompositingChange(layer); } } #if ENABLE(VIDEO) if (layerChanged && layer->renderer()->isVideo()) { // If it's a video, give the media player a chance to hook up to the layer. RenderVideo* video = toRenderVideo(layer->renderer()); video->acceleratedRenderingStateChanged(); } #endif return layerChanged; }
CompositingReasons CompositingReasonFinder::styleDeterminedReasons(RenderObject* renderer) const { CompositingReasons directReasons = CompositingReasonNone; if (requiresCompositingForTransform(renderer)) directReasons |= CompositingReason3DTransform; if (requiresCompositingForBackfaceVisibilityHidden(renderer)) directReasons |= CompositingReasonBackfaceVisibilityHidden; if (requiresCompositingForFilters(renderer)) directReasons |= CompositingReasonFilters; if (requiresCompositingForWillChange(renderer)) directReasons |= CompositingReasonWillChange; ASSERT(!(directReasons & ~CompositingReasonComboAllStyleDeterminedReasons)); return directReasons; }
// Note: this specifies whether the RL needs a compositing layer for intrinsic reasons. // Use needsToBeComposited() to determine if a RL actually needs a compositing layer. // static bool RenderLayerCompositor::requiresCompositingLayer(const RenderLayer* layer) const { RenderObject* renderer = layer->renderer(); // The compositing state of a reflection should match that of its reflected layer. if (layer->isReflection()) { renderer = renderer->parent(); // The RenderReplica's parent is the object being reflected. layer = toRenderBoxModelObject(renderer)->layer(); } // The root layer always has a compositing layer, but it may not have backing. return (inCompositingMode() && layer->isRootLayer()) || #if PLATFORM(ANDROID) requiresCompositingForMobileSites(layer) || #else requiresCompositingForTransform(renderer) || requiresCompositingForVideo(renderer) || requiresCompositingForCanvas(renderer) || requiresCompositingForPlugin(renderer) || requiresCompositingForAnimation(renderer) || #endif renderer->style()->backfaceVisibility() == BackfaceVisibilityHidden || clipsCompositingDescendants(layer); }
CompositingReasons CompositingReasonFinder::potentialCompositingReasonsFromStyle(LayoutObject* layoutObject) const { if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) return CompositingReasonNone; CompositingReasons reasons = CompositingReasonNone; const ComputedStyle& style = layoutObject->styleRef(); if (requiresCompositingForTransform(layoutObject)) reasons |= CompositingReason3DTransform; if (style.backfaceVisibility() == BackfaceVisibilityHidden) reasons |= CompositingReasonBackfaceVisibilityHidden; if (requiresCompositingForAnimation(style)) reasons |= CompositingReasonActiveAnimation; if (style.hasWillChangeCompositingHint() && !style.subtreeWillChangeContents()) reasons |= CompositingReasonWillChangeCompositingHint; if (style.hasInlineTransform()) reasons |= CompositingReasonInlineTransform; if (style.transformStyle3D() == TransformStyle3DPreserve3D) reasons |= CompositingReasonPreserve3DWith3DDescendants; if (style.hasPerspective()) reasons |= CompositingReasonPerspectiveWith3DDescendants; if (style.hasCompositorProxy()) reasons |= CompositingReasonCompositorProxy; // If the implementation of createsGroup changes, we need to be aware of that in this part of code. ASSERT((layoutObject->isTransparent() || layoutObject->hasMask() || layoutObject->hasFilter() || style.hasBlendMode()) == layoutObject->createsGroup()); if (style.hasMask()) reasons |= CompositingReasonMaskWithCompositedDescendants; if (style.hasFilter()) reasons |= CompositingReasonFilterWithCompositedDescendants; if (style.hasBackdropFilter()) reasons |= CompositingReasonBackdropFilter; // See Layer::updateTransform for an explanation of why we check both. if (layoutObject->hasTransformRelatedProperty() && style.hasTransform()) reasons |= CompositingReasonTransformWithCompositedDescendants; if (layoutObject->isTransparent()) reasons |= CompositingReasonOpacityWithCompositedDescendants; if (style.hasBlendMode()) reasons |= CompositingReasonBlendingWithCompositedDescendants; if (layoutObject->hasReflection()) reasons |= CompositingReasonReflectionWithCompositedDescendants; ASSERT(!(reasons & ~CompositingReasonComboAllStyleDeterminedReasons)); return reasons; }