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;
}
예제 #3
0
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;
}