📄 renderlayercompositor.cpp
字号:
} else { if (layer->backing()) layer->backing()->forceCompositingLayer(false); }}void RenderLayerCompositor::setCompositingParent(RenderLayer* childLayer, RenderLayer* parentLayer){ ASSERT(childLayer->isComposited()); ASSERT(!parentLayer || parentLayer->isComposited()); if (parentLayer) { GraphicsLayer* hostingLayer = parentLayer->backing()->parentForSublayers(); GraphicsLayer* hostedLayer = childLayer->backing()->childForSuperlayers(); hostingLayer->addChild(hostedLayer); } else childLayer->backing()->childForSuperlayers()->removeFromParent(); // FIXME: setCompositingParent() is only called at present by rebuildCompositingLayerTree(), // which calls updateGraphicsLayerGeometry via updateLayerCompositingState(), so this should // be optimized. if (parentLayer) childLayer->backing()->updateGraphicsLayerGeometry();}void RenderLayerCompositor::removeCompositedChildren(RenderLayer* layer){ ASSERT(layer->isComposited()); GraphicsLayer* hostingLayer = layer->backing()->parentForSublayers(); hostingLayer->removeAllChildren();}void RenderLayerCompositor::parentInRootLayer(RenderLayer* layer){ ASSERT(layer->isComposited()); GraphicsLayer* layerAnchor = layer->backing()->childForSuperlayers(); if (layerAnchor->parent() != m_rootPlatformLayer) { layerAnchor->removeFromParent(); if (m_rootPlatformLayer) m_rootPlatformLayer->addChild(layerAnchor); }}void RenderLayerCompositor::rebuildCompositingLayerTree(RenderLayer* layer, struct CompositingState& ioCompState){ updateLayerCompositingState(layer, StyleDifferenceEqual); // host the document layer in the RenderView's root layer if (layer->isRootLayer()) parentInRootLayer(layer); CompositingState childState = ioCompState; if (layer->isComposited()) childState.m_compositingAncestor = layer;#ifndef NDEBUG ++childState.m_depth;#endif RenderLayerBacking* layerBacking = layer->backing(); // FIXME: make this more incremental if (layer->isComposited()) { layerBacking->parentForSublayers()->removeAllChildren(); layerBacking->updateInternalHierarchy(); } // The children of this stacking context don't need to composite, unless there is // a compositing layer among them, so start by assuming false. childState.m_subtreeIsCompositing = false; if (layer->isStackingContext()) { ASSERT(!layer->m_zOrderListsDirty); Vector<RenderLayer*>* negZOrderList = layer->negZOrderList(); if (negZOrderList && negZOrderList->size() > 0) { for (Vector<RenderLayer*>::const_iterator it = negZOrderList->begin(); it != negZOrderList->end(); ++it) { RenderLayer* curLayer = (*it); rebuildCompositingLayerTree(curLayer, childState); if (curLayer->isComposited()) setCompositingParent(curLayer, childState.m_compositingAncestor); } } if (layerBacking && layerBacking->contentsLayer()) { // we only have a contents layer if we have an m_layer layerBacking->contentsLayer()->removeFromParent(); GraphicsLayer* hostingLayer = layerBacking->clippingLayer() ? layerBacking->clippingLayer() : layerBacking->graphicsLayer(); hostingLayer->addChild(layerBacking->contentsLayer()); } } ASSERT(!layer->m_normalFlowListDirty); Vector<RenderLayer*>* normalFlowList = layer->normalFlowList(); if (normalFlowList && normalFlowList->size() > 0) { for (Vector<RenderLayer*>::iterator it = normalFlowList->begin(); it != normalFlowList->end(); ++it) { RenderLayer* curLayer = (*it); rebuildCompositingLayerTree(curLayer, childState); if (curLayer->isComposited()) setCompositingParent(curLayer, childState.m_compositingAncestor); } } if (layer->isStackingContext()) { Vector<RenderLayer*>* posZOrderList = layer->posZOrderList(); if (posZOrderList && posZOrderList->size() > 0) { for (Vector<RenderLayer*>::const_iterator it = posZOrderList->begin(); it != posZOrderList->end(); ++it) { RenderLayer* curLayer = (*it); rebuildCompositingLayerTree(curLayer, childState); if (curLayer->isComposited()) setCompositingParent(curLayer, childState.m_compositingAncestor); } } }}void RenderLayerCompositor::repaintCompositedLayersAbsoluteRect(const IntRect& absRect){ recursiveRepaintLayerRect(rootRenderLayer(), absRect);}void RenderLayerCompositor::recursiveRepaintLayerRect(RenderLayer* layer, const IntRect& rect){ if (layer->isComposited()) layer->setBackingNeedsRepaintInRect(rect); if (layer->hasCompositingDescendant()) { Vector<RenderLayer*>* negZOrderList = layer->negZOrderList(); if (negZOrderList) { for (Vector<RenderLayer*>::iterator it = negZOrderList->begin(); it != negZOrderList->end(); ++it) { RenderLayer* curLayer = (*it); int x = 0, y = 0; curLayer->convertToLayerCoords(layer, x, y); IntRect childRect(rect); childRect.move(-x, -y); recursiveRepaintLayerRect(curLayer, childRect); } } Vector<RenderLayer*>* posZOrderList = layer->posZOrderList(); if (posZOrderList) { for (Vector<RenderLayer*>::iterator it = posZOrderList->begin(); it != posZOrderList->end(); ++it) { RenderLayer* curLayer = (*it); int x = 0, y = 0; curLayer->convertToLayerCoords(layer, x, y); IntRect childRect(rect); childRect.move(-x, -y); recursiveRepaintLayerRect(curLayer, childRect); } } Vector<RenderLayer*>* normalFlowList = layer->normalFlowList(); if (normalFlowList) { for (Vector<RenderLayer*>::iterator it = normalFlowList->begin(); it != normalFlowList->end(); ++it) { RenderLayer* curLayer = (*it); int x = 0, y = 0; curLayer->convertToLayerCoords(layer, x, y); IntRect childRect(rect); childRect.move(-x, -y); recursiveRepaintLayerRect(curLayer, childRect); } } }}RenderLayer* RenderLayerCompositor::rootRenderLayer() const{ return m_renderView->layer();}GraphicsLayer* RenderLayerCompositor::rootPlatformLayer() const{ return m_rootPlatformLayer;}void RenderLayerCompositor::didMoveOnscreen(){ if (!m_rootPlatformLayer) return; Frame* frame = m_renderView->frameView()->frame(); Page* page = frame ? frame->page() : 0; if (!page) return; page->chrome()->client()->attachRootGraphicsLayer(frame, m_rootPlatformLayer); m_rootLayerAttached = true;}void RenderLayerCompositor::willMoveOffscreen(){ if (!m_rootPlatformLayer || !m_rootLayerAttached) return; Frame* frame = m_renderView->frameView()->frame(); Page* page = frame ? frame->page() : 0; if (!page) return; page->chrome()->client()->attachRootGraphicsLayer(frame, 0); m_rootLayerAttached = false;}void RenderLayerCompositor::updateRootLayerPosition(){ if (m_rootPlatformLayer) m_rootPlatformLayer->setSize(FloatSize(m_renderView->docWidth(), m_renderView->docHeight()));}bool RenderLayerCompositor::has3DContent() const{ return layerHas3DContent(rootRenderLayer());}bool RenderLayerCompositor::needsToBeComposited(const RenderLayer* layer) const{ return requiresCompositingLayer(layer) || (layer->backing() && layer->backing()->forcedCompositingLayer());}static bool requiresCompositingLayerForTransform(RenderObject* renderer){ RenderStyle* style = renderer->style(); // Note that we ask the renderer if it has a transform, because the style may have transforms, // but the renderer may be an inline that doesn't suppport them. return renderer->hasTransform() && (style->transform().has3DOperation() || style->transformStyle3D() == TransformStyle3DPreserve3D || style->hasPerspective());}#define VERBOSE_COMPOSITINGLAYER 0// 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.// staticbool RenderLayerCompositor::requiresCompositingLayer(const RenderLayer* layer) const{ // FIXME: cache the result of these tests?#if VERBOSE_COMPOSITINGLAYER bool gotReason = false; if (!gotReason && inCompositingMode() && layer->isRootLayer()) { fprintf(stderr, "RenderLayer %p requires compositing layer because: it's the document root\n", layer); gotReason = true; } if (!gotReason && requiresCompositingLayerForTransform(layer->renderer())) { fprintf(stderr, "RenderLayer %p requires compositing layer because: it has 3d transform, perspective, backface, or animating transform\n", layer); gotReason = true; } if (!gotReason && layer->renderer()->style()->backfaceVisibility() == BackfaceVisibilityHidden) { fprintf(stderr, "RenderLayer %p requires compositing layer because: it has backface-visibility: hidden\n", layer); gotReason = true; } if (!gotReason && clipsCompositingDescendants(layer)) { fprintf(stderr, "RenderLayer %p requires compositing layer because: it has overflow clip\n", layer); gotReason = true; } if (!gotReason && requiresCompositingForAnimation(layer)) { fprintf(stderr, "RenderLayer %p requires compositing layer because: it has a running transition for opacity or transform\n", layer); gotReason = true; } if (!gotReason) fprintf(stderr, "RenderLayer %p does not require compositing layer\n", layer);#endif // The root layer always has a compositing layer, but it may not have backing. return (inCompositingMode() && layer->isRootLayer()) || requiresCompositingLayerForTransform(layer->renderer()) || layer->renderer()->style()->backfaceVisibility() == BackfaceVisibilityHidden || clipsCompositingDescendants(layer) || requiresCompositingForAnimation(layer);}// Return true if the given layer has some ancestor in the RenderLayer hierarchy that clips,// up to the enclosing compositing ancestor. This is required because compositing layers are parented// according to the z-order hierarchy, yet clipping goes down the renderer hierarchy.// Thus, a RenderLayer can be clipped by a RenderLayer that is an ancestor in the renderer hierarchy,// but a sibling in the z-order hierarchy.bool RenderLayerCompositor::clippedByAncestor(RenderLayer* layer) const{ if (!layer->isComposited() || !layer->parent()) return false; RenderLayer* compositingAncestor = layer->ancestorCompositingLayer(); // We need ancestor clipping if something clips between this layer and its compositing, stacking context ancestor for (RenderLayer* curLayer = layer->parent(); curLayer && curLayer != compositingAncestor; curLayer = curLayer->parent()) { // FIXME: need to look at hasClip() too eventually if (curLayer->renderer()->hasOverflowClip()) return true; // Clip is reset for an absolutely positioned element. // FIXME: many cases are broken. We need more of the logic in calculateClipRects() here if (curLayer->renderer()->style()->position() == AbsolutePosition) break; } return false;}// Return true if the given layer is a stacking context and has compositing child// layers that it needs to clip. In this case we insert a clipping GraphicsLayer// into the hierarchy between this layer and its children in the z-order hierarchy.bool RenderLayerCompositor::clipsCompositingDescendants(const RenderLayer* layer) const{ // FIXME: need to look at hasClip() too eventually return layer->hasCompositingDescendant() && layer->isStackingContext() && layer->renderer()->hasOverflowClip();}bool RenderLayerCompositor::requiresCompositingForAnimation(const RenderLayer* layer) const{ AnimationController* animController = layer->renderer()->animation(); if (animController) return animController->isAnimatingPropertyOnRenderer(layer->renderer(), CSSPropertyOpacity) || animController->isAnimatingPropertyOnRenderer(layer->renderer(), CSSPropertyWebkitTransform); return false;}// If an element has negative z-index children, those children render in front of the // layer background, so we need an extra 'contents' layer for the foreground of the layer// object.bool RenderLayerCompositor::needsContentsCompositingLayer(const RenderLayer* layer) const{ return (layer->m_negZOrderList && layer->m_negZOrderList->size() > 0);}void RenderLayerCompositor::ensureRootPlatformLayer(){ if (m_rootPlatformLayer) return; m_rootPlatformLayer = GraphicsLayer::createGraphicsLayer(0); m_rootPlatformLayer->setSize(FloatSize(m_renderView->docWidth(), m_renderView->docHeight())); m_rootPlatformLayer->setPosition(FloatPoint(0, 0)); if (GraphicsLayer::graphicsContextsFlipped()) m_rootPlatformLayer->setChildrenTransform(flipTransform()); // Need to clip to prevent transformed content showing outside this frame m_rootPlatformLayer->setMasksToBounds(true); didMoveOnscreen();}bool RenderLayerCompositor::layerHas3DContent(const RenderLayer* layer) const{ const RenderStyle* style = layer->renderer()->style(); if (style && (style->transformStyle3D() == TransformStyle3DPreserve3D || style->hasPerspective() || style->transform().has3DOperation())) return true; if (layer->isStackingContext()) { Vector<RenderLayer*>* negZOrderList = layer->negZOrderList(); if (negZOrderList) { for (Vector<RenderLayer*>::iterator it = negZOrderList->begin(); it != negZOrderList->end(); ++it) { RenderLayer* curLayer = (*it); if (layerHas3DContent(curLayer)) return true; } } Vector<RenderLayer*>* posZOrderList = layer->posZOrderList(); if (posZOrderList) { for (Vector<RenderLayer*>::iterator it = posZOrderList->begin(); it != posZOrderList->end(); ++it) { RenderLayer* curLayer = (*it); if (layerHas3DContent(curLayer)) return true; } } } Vector<RenderLayer*>* normalFlowList = layer->normalFlowList(); if (normalFlowList) { for (Vector<RenderLayer*>::iterator it = normalFlowList->begin(); it != normalFlowList->end(); ++it) { RenderLayer* curLayer = (*it); if (layerHas3DContent(curLayer)) return true; } } return false;}} // namespace WebCore#endif // USE(ACCELERATED_COMPOSITING)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -