void RenderTreeAsText::writeLayers(TextStream& ts, const RenderLayer* rootLayer, RenderLayer* layer, const LayoutRect& paintRect, int indent, RenderAsTextBehavior behavior) { // FIXME: Apply overflow to the root layer to not break every test. Complete hack. Sigh. LayoutRect paintDirtyRect(paintRect); if (rootLayer == layer) { paintDirtyRect.setWidth(max<LayoutUnit>(paintDirtyRect.width(), rootLayer->renderer()->layoutOverflowRect().maxX())); paintDirtyRect.setHeight(max<LayoutUnit>(paintDirtyRect.height(), rootLayer->renderer()->layoutOverflowRect().maxY())); } // Calculate the clip rects we should use. LayoutRect layerBounds; ClipRect damageRect; layer->clipper().calculateRects(ClipRectsContext(rootLayer, UncachedClipRects), paintDirtyRect, layerBounds, damageRect); // FIXME: Apply overflow to the root layer to not break every test. Complete hack. Sigh. if (rootLayer == layer) layerBounds.setSize(layer->size().expandedTo(pixelSnappedIntSize(layer->renderer()->maxLayoutOverflow(), LayoutPoint(0, 0)))); // Ensure our lists are up-to-date. layer->stackingNode()->updateLayerListsIfNeeded(); bool shouldPaint = (behavior & RenderAsTextShowAllLayers) ? true : layer->intersectsDamageRect(layerBounds, damageRect.rect(), rootLayer); if (shouldPaint) write(ts, *layer, layerBounds, damageRect.rect(), indent, behavior); if (Vector<RenderLayerStackingNode*>* normalFlowList = layer->stackingNode()->normalFlowList()) { int currIndent = indent; if (behavior & RenderAsTextShowLayerNesting) { writeIndent(ts, indent); ts << " normal flow list(" << normalFlowList->size() << ")\n"; ++currIndent; } for (unsigned i = 0; i != normalFlowList->size(); ++i) writeLayers(ts, rootLayer, normalFlowList->at(i)->layer(), paintDirtyRect, currIndent, behavior); } if (Vector<RenderLayerStackingNode*>* posList = layer->stackingNode()->zOrderList()) { int currIndent = indent; if (behavior & RenderAsTextShowLayerNesting) { writeIndent(ts, indent); ts << " positive z-order list(" << posList->size() << ")\n"; ++currIndent; } for (unsigned i = 0; i != posList->size(); ++i) writeLayers(ts, rootLayer, posList->at(i)->layer(), paintDirtyRect, currIndent, behavior); } }
void CompositingInputsUpdater::updateRecursive(DeprecatedPaintLayer* layer, UpdateType updateType, AncestorInfo info) { if (!layer->childNeedsCompositingInputsUpdate() && updateType != ForceUpdate) return; m_geometryMap.pushMappingsToAncestor(layer, layer->parent()); if (layer->hasCompositedDeprecatedPaintLayerMapping()) info.enclosingCompositedLayer = layer; if (layer->needsCompositingInputsUpdate()) { if (info.enclosingCompositedLayer) info.enclosingCompositedLayer->compositedDeprecatedPaintLayerMapping()->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateSubtree); updateType = ForceUpdate; } if (updateType == ForceUpdate) { DeprecatedPaintLayer::AncestorDependentCompositingInputs properties; if (!layer->isRootLayer()) { properties.clippedAbsoluteBoundingBox = enclosingIntRect(m_geometryMap.absoluteRect(layer->boundingBoxForCompositingOverlapTest())); // FIXME: Setting the absBounds to 1x1 instead of 0x0 makes very little sense, // but removing this code will make JSGameBench sad. // See https://codereview.chromium.org/13912020/ if (properties.clippedAbsoluteBoundingBox.isEmpty()) properties.clippedAbsoluteBoundingBox.setSize(IntSize(1, 1)); IntRect clipRect = pixelSnappedIntRect(layer->clipper().backgroundClipRect(ClipRectsContext(m_rootLayer, AbsoluteClipRects)).rect()); properties.clippedAbsoluteBoundingBox.intersect(clipRect); const DeprecatedPaintLayer* parent = layer->parent(); properties.opacityAncestor = parent->isTransparent() ? parent : parent->opacityAncestor(); properties.transformAncestor = parent->hasTransformRelatedProperty() ? parent : parent->transformAncestor(); properties.filterAncestor = parent->hasFilter() ? parent : parent->filterAncestor(); bool layerIsFixedPosition = layer->layoutObject()->style()->position() == FixedPosition; properties.nearestFixedPositionLayer = layerIsFixedPosition ? layer : parent->nearestFixedPositionLayer(); if (info.hasAncestorWithClipOrOverflowClip) { const DeprecatedPaintLayer* parentLayerOnClippingContainerChain = findParentLayerOnClippingContainerChain(layer); const bool parentHasClipOrOverflowClip = parentLayerOnClippingContainerChain->layoutObject()->hasClipOrOverflowClip(); properties.clippingContainer = parentHasClipOrOverflowClip ? parentLayerOnClippingContainerChain->layoutObject() : parentLayerOnClippingContainerChain->clippingContainer(); } if (info.lastScrollingAncestor) { const LayoutObject* containingBlock = layer->layoutObject()->containingBlock(); const DeprecatedPaintLayer* parentLayerOnContainingBlockChain = findParentLayerOnContainingBlockChain(containingBlock); properties.ancestorScrollingLayer = parentLayerOnContainingBlockChain->ancestorScrollingLayer(); if (parentLayerOnContainingBlockChain->scrollsOverflow()) properties.ancestorScrollingLayer = parentLayerOnContainingBlockChain; if (layer->layoutObject()->isOutOfFlowPositioned() && !layer->subtreeIsInvisible()) { const DeprecatedPaintLayer* clippingLayer = properties.clippingContainer ? properties.clippingContainer->enclosingLayer() : layer->compositor()->rootLayer(); if (hasClippedStackingAncestor(layer, clippingLayer)) properties.clipParent = clippingLayer; } if (layer->stackingNode()->isTreatedAsStackingContextForPainting() && properties.ancestorScrollingLayer && !info.ancestorStackingContext->layoutObject()->isDescendantOf(properties.ancestorScrollingLayer->layoutObject())) properties.scrollParent = properties.ancestorScrollingLayer; } } properties.hasAncestorWithClipPath = info.hasAncestorWithClipPath; layer->updateAncestorDependentCompositingInputs(properties); } if (layer->stackingNode()->isStackingContext()) info.ancestorStackingContext = layer; if (layer->scrollsOverflow()) info.lastScrollingAncestor = layer; if (layer->layoutObject()->hasClipOrOverflowClip()) info.hasAncestorWithClipOrOverflowClip = true; if (layer->layoutObject()->hasClipPath()) info.hasAncestorWithClipPath = true; DeprecatedPaintLayer::DescendantDependentCompositingInputs descendantProperties; for (DeprecatedPaintLayer* child = layer->firstChild(); child; child = child->nextSibling()) { updateRecursive(child, updateType, info); descendantProperties.hasDescendantWithClipPath |= child->hasDescendantWithClipPath() || child->layoutObject()->hasClipPath(); descendantProperties.hasNonIsolatedDescendantWithBlendMode |= (!child->stackingNode()->isStackingContext() && child->hasNonIsolatedDescendantWithBlendMode()) || child->layoutObject()->style()->hasBlendMode(); } layer->updateDescendantDependentCompositingInputs(descendantProperties); layer->didUpdateCompositingInputs(); m_geometryMap.popMappingsToAncestor(layer->parent()); }
void CompositingInputsUpdater::update(RenderLayer* layer, UpdateType updateType, AncestorInfo info) { if (!layer->childNeedsCompositingInputsUpdate() && updateType != ForceUpdate) return; m_geometryMap.pushMappingsToAncestor(layer, layer->parent()); if (layer->hasCompositedLayerMapping()) info.enclosingCompositedLayer = layer; if (layer->needsCompositingInputsUpdate()) { if (info.enclosingCompositedLayer) info.enclosingCompositedLayer->compositedLayerMapping()->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateSubtree); updateType = ForceUpdate; } if (updateType == ForceUpdate) { RenderLayer::CompositingInputs properties; if (!layer->isRootLayer()) { properties.clippedAbsoluteBoundingBox = enclosingIntRect(m_geometryMap.absoluteRect(layer->boundingBoxForCompositingOverlapTest())); // FIXME: Setting the absBounds to 1x1 instead of 0x0 makes very little sense, // but removing this code will make JSGameBench sad. // See https://codereview.chromium.org/13912020/ if (properties.clippedAbsoluteBoundingBox.isEmpty()) properties.clippedAbsoluteBoundingBox.setSize(IntSize(1, 1)); IntRect clipRect = pixelSnappedIntRect(layer->clipper().backgroundClipRect(ClipRectsContext(m_rootRenderLayer, AbsoluteClipRects)).rect()); properties.clippedAbsoluteBoundingBox.intersect(clipRect); const RenderLayer* parent = layer->parent(); properties.opacityAncestor = parent->isTransparent() ? parent : parent->compositingInputs().opacityAncestor; properties.transformAncestor = parent->hasTransform() ? parent : parent->compositingInputs().transformAncestor; properties.filterAncestor = parent->hasFilter() ? parent : parent->compositingInputs().filterAncestor; if (layer->renderer()->isOutOfFlowPositioned() && info.ancestorScrollingLayer && !layer->subtreeIsInvisible()) { const RenderObject* container = layer->renderer()->containingBlock(); const RenderObject* scroller = info.ancestorScrollingLayer->renderer(); properties.isUnclippedDescendant = scroller != container && scroller->isDescendantOf(container); } } layer->updateCompositingInputs(properties); } if (layer->scrollsOverflow()) info.ancestorScrollingLayer = layer; for (RenderLayer* child = layer->firstChild(); child; child = child->nextSibling()) update(child, updateType, info); m_geometryMap.popMappingsToAncestor(layer->parent()); layer->clearChildNeedsCompositingInputsUpdate(); }