예제 #1
0
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;
}
예제 #2
0
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());
}
예제 #3
0
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);
}
예제 #4
0
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());
}
예제 #5
0
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
}
예제 #7
0
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;
}
예제 #8
0
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());
}
예제 #14
0
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;
}
예제 #15
0
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;
}