AffineTransform SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem(const RenderObject& renderer) { AffineTransform absoluteTransform = currentContentTransformation(); float deviceScaleFactor = renderer.document().deviceScaleFactor(); // Walk up the render tree, accumulating SVG transforms. const RenderObject* ancestor = &renderer; while (ancestor) { absoluteTransform = ancestor->localToParentTransform() * absoluteTransform; if (ancestor->isSVGRoot()) break; ancestor = ancestor->parent(); } // Continue walking up the layer tree, accumulating CSS transforms. RenderLayer* layer = ancestor ? ancestor->enclosingLayer() : nullptr; while (layer) { if (TransformationMatrix* layerTransform = layer->transform()) absoluteTransform = layerTransform->toAffineTransform() * absoluteTransform; // We can stop at compositing layers, to match the backing resolution. if (layer->isComposited()) break; layer = layer->parent(); } absoluteTransform.scale(deviceScaleFactor); return absoluteTransform; }
TEST_F(ScrollingCoordinatorChromiumTest, touchOverflowScrolling) { registerMockedHttpURLLoad("touch-overflow-scrolling.html"); navigateTo(m_baseURL + "touch-overflow-scrolling.html"); // Verify the properties of the accelerated scrolling element starting from the RenderObject // all the way to the WebLayer. Element* scrollableElement = m_webViewImpl->mainFrameImpl()->frame()->document()->getElementById("scrollable"); ASSERT(scrollableElement); RenderObject* renderer = scrollableElement->renderer(); ASSERT_TRUE(renderer->isBoxModelObject()); ASSERT_TRUE(renderer->hasLayer()); RenderLayer* layer = toRenderBoxModelObject(renderer)->layer(); ASSERT_TRUE(layer->usesCompositedScrolling()); ASSERT_TRUE(layer->isComposited()); RenderLayerBacking* layerBacking = layer->backing(); ASSERT_TRUE(layerBacking->hasScrollingLayer()); ASSERT(layerBacking->scrollingContentsLayer()); GraphicsLayerChromium* graphicsLayerChromium = static_cast<GraphicsLayerChromium*>(layerBacking->scrollingContentsLayer()); ASSERT_EQ(layer, graphicsLayerChromium->scrollableArea()); WebLayer* webScrollLayer = static_cast<WebLayer*>(layerBacking->scrollingContentsLayer()->platformLayer()); ASSERT_TRUE(webScrollLayer->scrollable()); }
void Internals::setBackgroundBlurOnNode(Node* node, int blurLength, ExceptionCode& ec) { if (!node) { ec = INVALID_ACCESS_ERR; return; } RenderObject* renderObject = node->renderer(); if (!renderObject) { ec = INVALID_NODE_TYPE_ERR; return; } RenderLayer* renderLayer = renderObject->enclosingLayer(); if (!renderLayer || !renderLayer->isComposited()) { ec = INVALID_STATE_ERR; return; } GraphicsLayer* graphicsLayer = renderLayer->backing()->graphicsLayer(); if (!graphicsLayer) { ec = INVALID_NODE_TYPE_ERR; return; } PlatformLayer* platformLayer = graphicsLayer->platformLayer(); if (!platformLayer) { ec = INVALID_NODE_TYPE_ERR; return; } FilterOperations filters; filters.operations().append(BlurFilterOperation::create(Length(blurLength, Fixed), FilterOperation::BLUR)); platformLayer->setBackgroundFilters(filters); }
TEST_F(ScrollingCoordinatorChromiumTest, fastScrollingForFixedPosition) { registerMockedHttpURLLoad("fixed-position.html"); navigateTo(m_baseURL + "fixed-position.html"); Page* page = m_webViewImpl->mainFrameImpl()->frame()->page(); ASSERT_TRUE(page->scrollingCoordinator()->supportsFixedPositionLayers()); // Fixed position should not fall back to main thread scrolling. WebLayer* rootScrollLayer = getRootScrollLayer(); ASSERT_FALSE(rootScrollLayer->shouldScrollOnMainThread()); // Verify the properties of the fixed position element starting from the RenderObject all the // way to the WebLayer. Element* fixedElement = m_webViewImpl->mainFrameImpl()->frame()->document()->getElementById("fixed"); ASSERT(fixedElement); RenderObject* renderer = fixedElement->renderer(); ASSERT_TRUE(renderer->isBoxModelObject()); ASSERT_TRUE(renderer->hasLayer()); RenderLayer* layer = toRenderBoxModelObject(renderer)->layer(); ASSERT_TRUE(layer->isComposited()); RenderLayerBacking* layerBacking = layer->backing(); WebLayer* webLayer = static_cast<WebLayer*>(layerBacking->graphicsLayer()->platformLayer()); ASSERT_TRUE(webLayer->fixedToContainerLayer()); }
static void write(TextStream& ts, RenderLayer& l, const LayoutRect& layerBounds, const LayoutRect& backgroundClipRect, const LayoutRect& clipRect, const LayoutRect& outlineClipRect, LayerPaintPhase paintPhase = LayerPaintPhaseAll, int indent = 0, RenderAsTextBehavior behavior = RenderAsTextBehaviorNormal) { IntRect adjustedLayoutBounds = pixelSnappedIntRect(layerBounds); IntRect adjustedBackgroundClipRect = pixelSnappedIntRect(backgroundClipRect); IntRect adjustedClipRect = pixelSnappedIntRect(clipRect); IntRect adjustedOutlineClipRect = pixelSnappedIntRect(outlineClipRect); writeIndent(ts, indent); ts << "layer "; if (behavior & RenderAsTextShowAddresses) ts << static_cast<const void*>(&l) << " "; ts << adjustedLayoutBounds; if (!adjustedLayoutBounds.isEmpty()) { if (!adjustedBackgroundClipRect.contains(adjustedLayoutBounds)) ts << " backgroundClip " << adjustedBackgroundClipRect; if (!adjustedClipRect.contains(adjustedLayoutBounds)) ts << " clip " << adjustedClipRect; if (!adjustedOutlineClipRect.contains(adjustedLayoutBounds)) ts << " outlineClip " << adjustedOutlineClipRect; } if (l.renderer()->hasOverflowClip()) { if (l.scrollXOffset()) ts << " scrollX " << l.scrollXOffset(); if (l.scrollYOffset()) ts << " scrollY " << l.scrollYOffset(); if (l.renderBox() && l.renderBox()->pixelSnappedClientWidth() != l.scrollWidth()) ts << " scrollWidth " << l.scrollWidth(); if (l.renderBox() && l.renderBox()->pixelSnappedClientHeight() != l.scrollHeight()) ts << " scrollHeight " << l.scrollHeight(); } if (paintPhase == LayerPaintPhaseBackground) ts << " layerType: background only"; else if (paintPhase == LayerPaintPhaseForeground) ts << " layerType: foreground only"; #if USE(ACCELERATED_COMPOSITING) if (behavior & RenderAsTextShowCompositedLayers) { if (l.isComposited()) ts << " (composited, bounds=" << l.backing()->compositedBounds() << ", drawsContent=" << l.backing()->graphicsLayer()->drawsContent() << ", paints into ancestor=" << l.backing()->paintsIntoCompositedAncestor() << ")"; } #else UNUSED_PARAM(behavior); #endif ts << "\n"; if (paintPhase != LayerPaintPhaseBackground) write(ts, *l.renderer(), indent + 1, behavior); }
void ImplicitAnimation::endAnimation() { #if USE(ACCELERATED_COMPOSITING) if (m_object && m_object->hasLayer()) { RenderLayer* layer = toRenderBoxModelObject(m_object)->layer(); if (layer->isComposited()) layer->backing()->transitionFinished(m_animatingProperty); } #endif }
RenderLayer* LinkHighlight::computeEnclosingCompositingLayer() { if (!m_node || !m_node->renderer()) return 0; RenderLayer* renderLayer = m_node->renderer()->enclosingLayer(); // Find the nearest enclosing composited layer and attach to it. We may need to cross frame boundaries // to find a suitable layer. while (renderLayer && !renderLayer->isComposited()) { if (!renderLayer->parent()) { // See if we've reached the root in an enclosed frame. if (renderLayer->renderer()->frame()->ownerRenderer()) renderLayer = renderLayer->renderer()->frame()->ownerRenderer()->enclosingLayer(); else renderLayer = 0; } else renderLayer = renderLayer->parent(); } if (!renderLayer || !renderLayer->isComposited()) return 0; GraphicsLayerChromium* newGraphicsLayer = static_cast<GraphicsLayerChromium*>(renderLayer->backing()->graphicsLayer()); m_clipLayer->setSublayerTransform(SkMatrix44()); if (!newGraphicsLayer->drawsContent()) { m_clipLayer->setSublayerTransform(newGraphicsLayer->platformLayer()->transform()); newGraphicsLayer = static_cast<GraphicsLayerChromium*>(m_owningWebViewImpl->nonCompositedContentHost()->topLevelRootLayer()); } if (m_currentGraphicsLayer != newGraphicsLayer) { if (m_currentGraphicsLayer) clearGraphicsLayerLinkHighlightPointer(); m_currentGraphicsLayer = newGraphicsLayer; m_currentGraphicsLayer->setLinkHighlight(this); } return renderLayer; }
static void write(TextStream& ts, RenderLayer& l, const IntRect& layerBounds, const IntRect& backgroundClipRect, const IntRect& clipRect, const IntRect& outlineClipRect, LayerPaintPhase paintPhase = LayerPaintPhaseAll, int indent = 0, RenderAsTextBehavior behavior = RenderAsTextBehaviorNormal) { writeIndent(ts, indent); ts << "layer "; if (behavior & RenderAsTextShowAddresses) ts << static_cast<const void*>(&l) << " "; ts << layerBounds; if (!layerBounds.isEmpty()) { if (!backgroundClipRect.contains(layerBounds)) ts << " backgroundClip " << backgroundClipRect; if (!clipRect.contains(layerBounds)) ts << " clip " << clipRect; if (!outlineClipRect.contains(layerBounds)) ts << " outlineClip " << outlineClipRect; } if (l.renderer()->hasOverflowClip()) { if (l.scrollXOffset()) ts << " scrollX " << l.scrollXOffset(); if (l.scrollYOffset()) ts << " scrollY " << l.scrollYOffset(); if (l.renderBox() && l.renderBox()->clientWidth() != l.scrollWidth()) ts << " scrollWidth " << l.scrollWidth(); if (l.renderBox() && l.renderBox()->clientHeight() != l.scrollHeight()) ts << " scrollHeight " << l.scrollHeight(); } if (paintPhase == LayerPaintPhaseBackground) ts << " layerType: background only"; else if (paintPhase == LayerPaintPhaseForeground) ts << " layerType: foreground only"; #if USE(ACCELERATED_COMPOSITING) if (behavior & RenderAsTextShowCompositedLayers) { if (l.isComposited()) ts << " (composited, bounds " << l.backing()->compositedBounds() << ")"; } #else UNUSED_PARAM(behavior); #endif ts << "\n"; if (paintPhase != LayerPaintPhaseBackground) write(ts, *l.renderer(), indent + 1, behavior); }
bool KeyframeAnimation::startAnimation(double beginTime) { #if USE(ACCELERATED_COMPOSITING) if (m_object && m_object->hasLayer()) { RenderLayer* layer = toRenderBoxModelObject(m_object)->layer(); if (layer->isComposited()) return layer->backing()->startAnimation(beginTime, m_animation.get(), m_keyframes); } #else UNUSED_PARAM(beginTime); #endif return false; }
bool ImplicitAnimation::startAnimation(double timeOffset) { #if USE(ACCELERATED_COMPOSITING) if (m_object && m_object->hasLayer()) { RenderLayer* layer = toRenderBoxModelObject(m_object)->layer(); if (layer->isComposited()) return layer->backing()->startTransition(timeOffset, m_animatingProperty, m_fromStyle.get(), m_toStyle.get()); } #else UNUSED_PARAM(timeOffset); #endif return false; }
void KeyframeAnimation::endAnimation() { if (!m_object) return; #if USE(ACCELERATED_COMPOSITING) if (m_object->hasLayer()) { RenderLayer* layer = toRenderBoxModelObject(m_object)->layer(); if (layer->isComposited()) layer->backing()->animationFinished(m_keyframes.animationName()); } #endif // Restore the original (unanimated) style if (!paused()) setNeedsStyleRecalc(m_object->node()); }
bool ScrollingCoordinator::hasVisibleSlowRepaintViewportConstrainedObjects(FrameView* frameView) const { const FrameView::ViewportConstrainedObjectSet* viewportConstrainedObjects = frameView->viewportConstrainedObjects(); if (!viewportConstrainedObjects) return false; for (FrameView::ViewportConstrainedObjectSet::const_iterator it = viewportConstrainedObjects->begin(), end = viewportConstrainedObjects->end(); it != end; ++it) { RenderObject* viewportConstrainedObject = *it; if (!viewportConstrainedObject->isBoxModelObject() || !viewportConstrainedObject->hasLayer()) return true; RenderLayer* layer = toRenderBoxModelObject(viewportConstrainedObject)->layer(); // Any explicit reason that a fixed position element is not composited shouldn't cause slow scrolling. if (!layer->isComposited() && layer->viewportConstrainedNotCompositedReason() == RenderLayer::NoNotCompositedReason) return true; } return false; }
void KeyframeAnimation::pauseAnimation(double timeOffset) { if (!m_object) return; #if USE(ACCELERATED_COMPOSITING) if (m_object->hasLayer()) { RenderLayer* layer = toRenderBoxModelObject(m_object)->layer(); if (layer->isComposited()) layer->backing()->animationPaused(timeOffset, m_keyframes.animationName()); } #else UNUSED_PARAM(timeOffset); #endif // Restore the original (unanimated) style if (!paused()) setNeedsStyleRecalc(m_object->node()); }
RenderLayer* LinkHighlight::computeEnclosingCompositingLayer() { if (!m_node || !m_node->renderer()) return 0; // Find the nearest enclosing composited layer and attach to it. We may need to cross frame boundaries // to find a suitable layer. RenderLayerModelObject* renderer = toRenderLayerModelObject(m_node->renderer()); RenderLayerModelObject* repaintContainer; do { repaintContainer = renderer->containerForRepaint(); if (!repaintContainer) { renderer = renderer->frame()->ownerRenderer(); if (!renderer) return 0; } } while (!repaintContainer); RenderLayer* renderLayer = repaintContainer->layer(); if (!renderLayer || !renderLayer->isComposited()) return 0; GraphicsLayer* newGraphicsLayer = renderLayer->backing()->graphicsLayer(); m_clipLayer->setSublayerTransform(SkMatrix44()); if (!newGraphicsLayer->drawsContent()) { if (renderLayer->usesCompositedScrolling()) { ASSERT(renderLayer->backing() && renderLayer->backing()->scrollingContentsLayer()); newGraphicsLayer = renderLayer->backing()->scrollingContentsLayer(); } else ASSERT_NOT_REACHED(); } if (m_currentGraphicsLayer != newGraphicsLayer) { if (m_currentGraphicsLayer) clearGraphicsLayerLinkHighlightPointer(); m_currentGraphicsLayer = newGraphicsLayer; m_currentGraphicsLayer->setLinkHighlight(this); } return renderLayer; }
RenderLayer* LinkHighlight::computeEnclosingCompositingLayer() { if (!m_node || !m_node->renderer()) return 0; // Find the nearest enclosing composited layer and attach to it. We may need to cross frame boundaries // to find a suitable layer. RenderLayerModelObject* renderer = toRenderLayerModelObject(m_node->renderer()); RenderLayerModelObject* repaintContainer; do { repaintContainer = renderer->containerForRepaint(); if (!repaintContainer) { renderer = renderer->frame()->ownerRenderer(); if (!renderer) return 0; } } while (!repaintContainer); RenderLayer* renderLayer = repaintContainer->layer(); if (!renderLayer || !renderLayer->isComposited()) return 0; GraphicsLayerChromium* newGraphicsLayer = static_cast<GraphicsLayerChromium*>(renderLayer->backing()->graphicsLayer()); m_clipLayer->setSublayerTransform(SkMatrix44()); m_usingNonCompositedContentHost = !newGraphicsLayer->drawsContent(); if (m_usingNonCompositedContentHost ) { m_clipLayer->setSublayerTransform(newGraphicsLayer->platformLayer()->transform()); newGraphicsLayer = static_cast<GraphicsLayerChromium*>(m_owningWebViewImpl->nonCompositedContentHost()->topLevelRootLayer()); } if (m_currentGraphicsLayer != newGraphicsLayer) { if (m_currentGraphicsLayer) clearGraphicsLayerLinkHighlightPointer(); m_currentGraphicsLayer = newGraphicsLayer; m_currentGraphicsLayer->setLinkHighlight(this); } return renderLayer; }
// The bounds of the GraphicsLayer created for a compositing layer is the union of the bounds of all the descendant // RenderLayers that are rendered by the composited RenderLayer. IntRect RenderLayerCompositor::calculateCompositedBounds(const RenderLayer* layer, const RenderLayer* ancestorLayer) { if (!layer->isSelfPaintingLayer()) return IntRect(); IntRect boundingBoxRect, unionBounds; boundingBoxRect = unionBounds = layer->localBoundingBox(); if (layer->renderer()->hasOverflowClip() || layer->renderer()->hasMask()) { int ancestorRelX = 0, ancestorRelY = 0; layer->convertToLayerCoords(ancestorLayer, ancestorRelX, ancestorRelY); boundingBoxRect.move(ancestorRelX, ancestorRelY); return boundingBoxRect; } if (RenderLayer* reflection = layer->reflectionLayer()) { if (!reflection->isComposited()) { IntRect childUnionBounds = calculateCompositedBounds(reflection, layer); unionBounds.unite(childUnionBounds); } } ASSERT(layer->isStackingContext() || (!layer->m_posZOrderList || layer->m_posZOrderList->size() == 0)); if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) { size_t listSize = negZOrderList->size(); for (size_t i = 0; i < listSize; ++i) { RenderLayer* curLayer = negZOrderList->at(i); if (!curLayer->isComposited()) { IntRect childUnionBounds = calculateCompositedBounds(curLayer, layer); unionBounds.unite(childUnionBounds); } } } if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) { size_t listSize = posZOrderList->size(); for (size_t i = 0; i < listSize; ++i) { RenderLayer* curLayer = posZOrderList->at(i); if (!curLayer->isComposited()) { IntRect childUnionBounds = calculateCompositedBounds(curLayer, layer); unionBounds.unite(childUnionBounds); } } } if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) { size_t listSize = normalFlowList->size(); for (size_t i = 0; i < listSize; ++i) { RenderLayer* curLayer = normalFlowList->at(i); if (!curLayer->isComposited()) { IntRect curAbsBounds = calculateCompositedBounds(curLayer, layer); unionBounds.unite(curAbsBounds); } } } if (layer->paintsWithTransform(PaintBehaviorNormal)) { TransformationMatrix* affineTrans = layer->transform(); boundingBoxRect = affineTrans->mapRect(boundingBoxRect); unionBounds = affineTrans->mapRect(unionBounds); } int ancestorRelX = 0, ancestorRelY = 0; layer->convertToLayerCoords(ancestorLayer, ancestorRelX, ancestorRelY); unionBounds.move(ancestorRelX, ancestorRelY); return unionBounds; }