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)); }
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 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(); }
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; }