GraphicsLayer* PaintLayerCompositor::fixedRootBackgroundLayer() const
{
    // Get the fixed root background from the LayoutView layer's compositedLayerMapping.
    PaintLayer* viewLayer = m_layoutView.layer();
    if (!viewLayer)
        return nullptr;

    if (viewLayer->compositingState() == PaintsIntoOwnBacking && viewLayer->compositedLayerMapping()->backgroundLayerPaintsFixedRootBackground())
        return viewLayer->compositedLayerMapping()->backgroundLayer();

    return nullptr;
}
void CompositorAnimations::attachCompositedLayers(const Element& element, const Animation& animation)
{
    ASSERT(element.layoutObject());

    PaintLayer* layer = toLayoutBoxModelObject(element.layoutObject())->layer();
    ASSERT(layer);

    WebCompositorAnimationPlayer* compositorPlayer = animation.compositorPlayer();
    ASSERT(compositorPlayer);

    ASSERT(layer->compositedLayerMapping());
    compositorPlayer->attachLayer(layer->compositedLayerMapping()->mainGraphicsLayer()->platformLayer());
}
예제 #3
0
TEST_F(CompositedLayerMappingTest, TallLayerWholeDocumentInterestRect)
{
    setBodyInnerHTML("<div id='target' style='width: 200px; height: 10000px; will-change: transform'></div>");

    document().settings()->setMainFrameClipsContent(false);

    document().view()->updateAllLifecyclePhases();
    Element* element = document().getElementById("target");
    PaintLayer* paintLayer = toLayoutBoxModelObject(element->layoutObject())->layer();
    ASSERT_TRUE(paintLayer->graphicsLayerBacking());
    ASSERT_TRUE(paintLayer->compositedLayerMapping());
    // recomputeInterestRect computes the interest rect; computeInterestRect applies the extra setting to paint everything.
    EXPECT_RECT_EQ(IntRect(0, 0, 200, 4592), recomputeInterestRect(paintLayer->graphicsLayerBacking()));
    EXPECT_RECT_EQ(IntRect(0, 0, 200, 10000), computeInterestRect(paintLayer->compositedLayerMapping(), paintLayer->graphicsLayerBacking(), IntRect()));
}
bool CompositorAnimations::startAnimationOnCompositor(const Element& element, int group, double startTime, double timeOffset, const Timing& timing, const Animation& animation, const EffectModel& effect, Vector<int>& startedAnimationIds, double animationPlaybackRate)
{
    ASSERT(startedAnimationIds.isEmpty());
    ASSERT(isCandidateForAnimationOnCompositor(timing, element, &animation, effect, animationPlaybackRate));
    ASSERT(canStartAnimationOnCompositor(element));

    const KeyframeEffectModelBase& keyframeEffect = toKeyframeEffectModelBase(effect);

    PaintLayer* layer = toLayoutBoxModelObject(element.layoutObject())->layer();
    ASSERT(layer);

    Vector<OwnPtr<WebCompositorAnimation>> animations;
    CompositorAnimationsImpl::getAnimationOnCompositor(timing, group, startTime, timeOffset, keyframeEffect, animations, animationPlaybackRate);
    ASSERT(!animations.isEmpty());
    for (auto& compositorAnimation : animations) {
        int id = compositorAnimation->id();
        if (RuntimeEnabledFeatures::compositorAnimationTimelinesEnabled()) {
            WebCompositorAnimationPlayer* compositorPlayer = animation.compositorPlayer();
            ASSERT(compositorPlayer);
            compositorPlayer->addAnimation(compositorAnimation.leakPtr());
        } else if (!layer->compositedLayerMapping()->mainGraphicsLayer()->addAnimation(compositorAnimation.release())) {
            // FIXME: We should know ahead of time whether these animations can be started.
            for (int startedAnimationId : startedAnimationIds)
                cancelAnimationOnCompositor(element, animation, startedAnimationId);
            startedAnimationIds.clear();
            return false;
        }
        startedAnimationIds.append(id);
    }
    ASSERT(!startedAnimationIds.isEmpty());
    return true;
}
void GraphicsLayerTreeBuilder::rebuild(PaintLayer& layer, AncestorInfo info)
{
    // Make the layer compositing if necessary, and set up clipping and content layers.
    // Note that we can only do work here that is independent of whether the descendant layers
    // have been processed. computeCompositingRequirements() will already have done the paint invalidation if necessary.

    layer.stackingNode()->updateLayerListsIfNeeded();

    const bool hasCompositedLayerMapping = layer.hasCompositedLayerMapping();
    CompositedLayerMapping* currentCompositedLayerMapping = layer.compositedLayerMapping();

    // If this layer has a compositedLayerMapping, then that is where we place subsequent children GraphicsLayers.
    // Otherwise children continue to append to the child list of the enclosing layer.
    GraphicsLayerVector layerChildren;
    AncestorInfo infoForChildren(info);
    if (hasCompositedLayerMapping) {
        infoForChildren.childLayersOfEnclosingCompositedLayer = &layerChildren;
        infoForChildren.enclosingCompositedLayer = &layer;
    }

#if ENABLE(ASSERT)
    LayerListMutationDetector mutationChecker(layer.stackingNode());
#endif

    if (layer.stackingNode()->isStackingContext()) {
        PaintLayerStackingNodeIterator iterator(*layer.stackingNode(), NegativeZOrderChildren);
        while (PaintLayerStackingNode* curNode = iterator.next())
            rebuild(*curNode->layer(), infoForChildren);

        // If a negative z-order child is compositing, we get a foreground layer which needs to get parented.
        if (hasCompositedLayerMapping && currentCompositedLayerMapping->foregroundLayer())
            infoForChildren.childLayersOfEnclosingCompositedLayer->append(currentCompositedLayerMapping->foregroundLayer());
    }

    PaintLayerStackingNodeIterator iterator(*layer.stackingNode(), NormalFlowChildren | PositiveZOrderChildren);
    while (PaintLayerStackingNode* curNode = iterator.next())
        rebuild(*curNode->layer(), infoForChildren);

    if (hasCompositedLayerMapping) {
        bool parented = false;
        if (layer.layoutObject()->isLayoutPart())
            parented = PaintLayerCompositor::attachFrameContentLayersToIframeLayer(toLayoutPart(layer.layoutObject()));

        if (!parented)
            currentCompositedLayerMapping->setSublayers(layerChildren);

        if (shouldAppendLayer(layer))
            info.childLayersOfEnclosingCompositedLayer->append(currentCompositedLayerMapping->childForSuperlayers());
    }

    if (layer.scrollParent()
        && layer.scrollParent()->hasCompositedLayerMapping()
        && layer.scrollParent()->compositedLayerMapping()->needsToReparentOverflowControls()
        && layer.scrollParent()->getScrollableArea()->topmostScrollChild() == &layer)
        info.childLayersOfEnclosingCompositedLayer->append(layer.scrollParent()->compositedLayerMapping()->detachLayerForOverflowControls(*info.enclosingCompositedLayer));
}
예제 #6
0
static CompositedLayerMapping* mappingFromElement(Element* element) {
  if (!element)
    return nullptr;
  LayoutObject* layoutObject = element->layoutObject();
  if (!layoutObject || !layoutObject->isBoxModelObject())
    return nullptr;
  PaintLayer* layer = toLayoutBoxModelObject(layoutObject)->layer();
  if (!layer)
    return nullptr;
  if (!layer->hasCompositedLayerMapping())
    return nullptr;
  return layer->compositedLayerMapping();
}
bool PaintLayerCompositor::attachFrameContentLayersToIframeLayer(LayoutPart* layoutObject)
{
    PaintLayerCompositor* innerCompositor = frameContentsCompositor(layoutObject);
    if (!innerCompositor || !innerCompositor->staleInCompositingMode() || innerCompositor->rootLayerAttachment() != RootLayerAttachedViaEnclosingFrame)
        return false;

    PaintLayer* layer = layoutObject->layer();
    if (!layer->hasCompositedLayerMapping())
        return false;

    layer->compositedLayerMapping()->setSublayers(GraphicsLayerVector(1, innerCompositor->rootGraphicsLayer()));
    return true;
}
static void paintLayers(PaintLayer& layer, SimDisplayItemList& displayList)
{
    if (layer.isAllowedToQueryCompositingState() && layer.compositingState() == PaintsIntoOwnBacking) {
        CompositedLayerMapping* mapping = layer.compositedLayerMapping();
        GraphicsLayer* graphicsLayer = mapping->mainGraphicsLayer();
        if (graphicsLayer->hasTrackedPaintInvalidations()) {
            ContentLayerDelegate* delegate = graphicsLayer->contentLayerDelegateForTesting();
            delegate->paintContents(&displayList, WebRect(0, 0, layer.size().width(), layer.size().height()));
            graphicsLayer->resetTrackedPaintInvalidations();
        }
    }
    for (PaintLayer* child = layer.firstChild(); child; child = child->nextSibling())
        paintLayers(*child, displayList);
}
bool CompositorAnimations::canAttachCompositedLayers(const Element& element, const Animation& animation)
{
    if (!RuntimeEnabledFeatures::compositorAnimationTimelinesEnabled())
        return false;

    if (!animation.compositorPlayer())
        return false;

    if (!element.layoutObject() || !element.layoutObject()->isBoxModelObject())
        return false;

    PaintLayer* layer = toLayoutBoxModelObject(element.layoutObject())->layer();

    if (!layer || !layer->isAllowedToQueryCompositingState()
        || !layer->compositedLayerMapping()
        || !layer->compositedLayerMapping()->mainGraphicsLayer())
        return false;

    if (!layer->compositedLayerMapping()->mainGraphicsLayer()->platformLayer())
        return false;

    return true;
}
static WebLayer* webLayerFromElement(Element* element)
{
    if (!element)
        return 0;
    LayoutObject* layoutObject = element->layoutObject();
    if (!layoutObject || !layoutObject->isBoxModelObject())
        return 0;
    PaintLayer* layer = toLayoutBoxModelObject(layoutObject)->layer();
    if (!layer)
        return 0;
    if (!layer->hasCompositedLayerMapping())
        return 0;
    CompositedLayerMapping* compositedLayerMapping = layer->compositedLayerMapping();
    GraphicsLayer* graphicsLayer = compositedLayerMapping->mainGraphicsLayer();
    if (!graphicsLayer)
        return 0;
    return graphicsLayer->platformLayer();
}
예제 #11
0
TEST_P(CompositedLayerMappingTest, VerticalRightLeftWritingModeDocument) {
  setBodyInnerHTML(
      "<style>html,body { margin: 0px } html { -webkit-writing-mode: "
      "vertical-rl}</style> <div id='target' style='width: 10000px; height: "
      "200px;'></div>");

  document().view()->updateAllLifecyclePhases();
  document().view()->layoutViewportScrollableArea()->setScrollOffset(
      ScrollOffset(-5000, 0), ProgrammaticScroll);
  document().view()->updateAllLifecyclePhases();

  PaintLayer* paintLayer = document().layoutViewItem().layer();
  ASSERT_TRUE(paintLayer->graphicsLayerBacking());
  ASSERT_TRUE(paintLayer->compositedLayerMapping());
  // A scroll by -5000px is equivalent to a scroll by (10000 - 5000 - 800)px =
  // 4200px in non-RTL mode. Expanding the resulting rect by 4000px in each
  // direction yields this result.
  EXPECT_RECT_EQ(
      IntRect(200, 0, 8800, 600),
      recomputeInterestRect(paintLayer->graphicsLayerBackingForScrolling()));
}
bool PaintLayerCompositor::allocateOrClearCompositedLayerMapping(PaintLayer* layer, const CompositingStateTransitionType compositedLayerUpdate)
{
    bool compositedLayerMappingChanged = false;

    // FIXME: It would be nice to directly use the layer's compositing reason,
    // but allocateOrClearCompositedLayerMapping also gets called without having updated compositing
    // requirements fully.
    switch (compositedLayerUpdate) {
    case AllocateOwnCompositedLayerMapping:
        ASSERT(!layer->hasCompositedLayerMapping());
        setCompositingModeEnabled(true);

        // If we need to issue paint invalidations, do so before allocating the compositedLayerMapping and clearing out the groupedMapping.
        paintInvalidationOnCompositingChange(layer);

        // If this layer was previously squashed, we need to remove its reference to a groupedMapping right away, so
        // that computing paint invalidation rects will know the layer's correct compositingState.
        // FIXME: do we need to also remove the layer from it's location in the squashing list of its groupedMapping?
        // Need to create a test where a squashed layer pops into compositing. And also to cover all other
        // sorts of compositingState transitions.
        layer->setLostGroupedMapping(false);
        layer->setGroupedMapping(nullptr, PaintLayer::InvalidateLayerAndRemoveFromMapping);

        layer->ensureCompositedLayerMapping();
        compositedLayerMappingChanged = true;

        // At this time, the ScrollingCooridnator only supports the top-level frame.
        if (layer->isRootLayer() && m_layoutView.frame()->isLocalRoot()) {
            if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
                scrollingCoordinator->frameViewRootLayerDidChange(m_layoutView.frameView());
        }
        break;
    case RemoveOwnCompositedLayerMapping:
    // PutInSquashingLayer means you might have to remove the composited layer mapping first.
    case PutInSquashingLayer:
        if (layer->hasCompositedLayerMapping()) {
            // If we're removing the compositedLayerMapping from 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()) {
                PaintLayer* sourceLayer = toLayoutBoxModelObject(layer->layoutObject()->parent())->layer();
                if (sourceLayer->hasCompositedLayerMapping()) {
                    ASSERT(sourceLayer->compositedLayerMapping()->mainGraphicsLayer()->replicaLayer() == layer->compositedLayerMapping()->mainGraphicsLayer());
                    sourceLayer->compositedLayerMapping()->mainGraphicsLayer()->setReplicatedByLayer(nullptr);
                }
            }

            layer->clearCompositedLayerMapping();
            compositedLayerMappingChanged = true;
        }

        break;
    case RemoveFromSquashingLayer:
    case NoCompositingStateChange:
        // Do nothing.
        break;
    }

    if (compositedLayerMappingChanged && layer->layoutObject()->isLayoutPart()) {
        PaintLayerCompositor* innerCompositor = frameContentsCompositor(toLayoutPart(layer->layoutObject()));
        if (innerCompositor && innerCompositor->staleInCompositingMode())
            innerCompositor->updateRootLayerAttachment();
    }

    if (compositedLayerMappingChanged)
        layer->clipper().clearClipRectsIncludingDescendants(PaintingClipRects);

    // If a fixed position layer gained/lost a compositedLayerMapping or the reason not compositing it changed,
    // the scrolling coordinator needs to recalculate whether it can do fast scrolling.
    if (compositedLayerMappingChanged) {
        if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
            scrollingCoordinator->frameViewFixedObjectsDidChange(m_layoutView.frameView());
    }

    return compositedLayerMappingChanged;
}