void PageOverlay::update() { if (!m_frameImpl->frameWidget()->isAcceleratedCompositingActive()) return; LocalFrame* frame = m_frameImpl->frame(); if (!frame) return; if (!m_layer) { m_layer = GraphicsLayer::create(this); m_layer->setDrawsContent(true); if (WebDevToolsAgentImpl* devTools = m_frameImpl->devToolsAgentImpl()) devTools->willAddPageOverlay(m_layer.get()); // This is required for contents of overlay to stay in sync with the page // while scrolling. WebLayer* platformLayer = m_layer->platformLayer(); platformLayer->addMainThreadScrollingReasons( MainThreadScrollingReason::kPageOverlay); if (frame->isMainFrame()) { frame->host()->visualViewport().containerLayer()->addChild(m_layer.get()); } else { toWebFrameWidgetImpl(m_frameImpl->frameWidget()) ->rootGraphicsLayer() ->addChild(m_layer.get()); } } FloatSize size(frame->host()->visualViewport().size()); if (size != m_layer->size()) m_layer->setSize(size); m_layer->setNeedsDisplay(); }
TEST_F(ScrollingCoordinatorTest, fastFractionalScrollingDiv) { registerMockedHttpURLLoad("fractional-scroll-div.html"); navigateTo(m_baseURL + "fractional-scroll-div.html"); forceFullCompositingUpdate(); Document* document = frame()->document(); Element* scrollableElement = document->getElementById("scroller"); ASSERT(scrollableElement); scrollableElement->setScrollTop(1.0); scrollableElement->setScrollLeft(1.0); forceFullCompositingUpdate(); // Make sure the fractional scroll offset change 1.0 -> 1.2 gets propagated // to compositor. scrollableElement->setScrollTop(1.2); scrollableElement->setScrollLeft(1.2); forceFullCompositingUpdate(); LayoutObject* layoutObject = scrollableElement->layoutObject(); ASSERT_TRUE(layoutObject->isBox()); LayoutBox* box = toLayoutBox(layoutObject); ASSERT_TRUE(box->usesCompositedScrolling()); CompositedLayerMapping* compositedLayerMapping = box->layer()->compositedLayerMapping(); ASSERT_TRUE(compositedLayerMapping->hasScrollingLayer()); ASSERT(compositedLayerMapping->scrollingContentsLayer()); WebLayer* webScrollLayer = compositedLayerMapping->scrollingContentsLayer()->platformLayer(); ASSERT_TRUE(webScrollLayer); ASSERT_NEAR(1.2, webScrollLayer->scrollPositionDouble().x, 0.01); ASSERT_NEAR(1.2, webScrollLayer->scrollPositionDouble().y, 0.01); }
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()); }
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()); }
TEST_P(CompositorWorkerTest, disconnectedProxies) { // This case is identical to compositor-proxy-basic, but the proxies are // disconnected (the result should be the same as // compositor-proxy-plumbing-no-proxies). registerMockedHttpURLLoad("compositor-proxy-basic-disconnected.html"); navigateTo(m_baseURL + "compositor-proxy-basic-disconnected.html"); forceFullCompositingUpdate(); Document* document = frame()->document(); Element* tallElement = document->getElementById("tall"); WebLayer* tallLayer = webLayerFromElement(tallElement); EXPECT_TRUE(!tallLayer); Element* proxiedElement = document->getElementById("proxied"); WebLayer* proxiedLayer = webLayerFromElement(proxiedElement); EXPECT_TRUE(!proxiedLayer); Element* scrollElement = document->getElementById("proxied-scroller"); WebLayer* scrollLayer = scrollingWebLayerFromElement(scrollElement); EXPECT_FALSE(!!scrollLayer->compositorMutableProperties()); WebLayer* rootScrollLayer = getRootScrollLayer(); EXPECT_FALSE(!!rootScrollLayer->compositorMutableProperties()); }
TEST_P(CompositorWorkerTest, noProxies) { // This case is identical to compositor-proxy-basic, but no proxies have // actually been created. registerMockedHttpURLLoad("compositor-proxy-plumbing-no-proxies.html"); navigateTo(m_baseURL + "compositor-proxy-plumbing-no-proxies.html"); forceFullCompositingUpdate(); Document* document = frame()->document(); Element* tallElement = document->getElementById("tall"); WebLayer* tallLayer = webLayerFromElement(tallElement); EXPECT_TRUE(!tallLayer); Element* proxiedElement = document->getElementById("proxied"); WebLayer* proxiedLayer = webLayerFromElement(proxiedElement); EXPECT_TRUE(!proxiedLayer); // Note: we presume the existance of mutable properties implies that the the // element has a corresponding compositor proxy. Element ids (which are also // used by animations) do not have this implication, so we do not check for // them here. Element* scrollElement = document->getElementById("proxied-scroller"); WebLayer* scrollLayer = scrollingWebLayerFromElement(scrollElement); EXPECT_FALSE(!!scrollLayer->compositorMutableProperties()); WebLayer* rootScrollLayer = getRootScrollLayer(); EXPECT_FALSE(!!rootScrollLayer->compositorMutableProperties()); }
TEST_F(ScrollingCoordinatorChromiumTest, wheelEventHandler) { registerMockedHttpURLLoad("wheel-event-handler.html"); navigateTo(m_baseURL + "wheel-event-handler.html"); WebLayer* rootScrollLayer = getRootScrollLayer(); ASSERT_TRUE(rootScrollLayer->haveWheelEventHandlers()); }
TEST_F(ScrollingCoordinatorTest, scrollEventHandler) { registerMockedHttpURLLoad("scroll-event-handler.html"); navigateTo(m_baseURL + "scroll-event-handler.html"); forceFullCompositingUpdate(); WebLayer* rootScrollLayer = getRootScrollLayer(); ASSERT_TRUE(rootScrollLayer->haveScrollEventHandlers()); }
void GraphicsLayerChromium::updateContentsRect() { WebLayer* contentsLayer = contentsLayerIfRegistered(); if (!contentsLayer) return; contentsLayer->setPosition(FloatPoint(m_contentsRect.x(), m_contentsRect.y())); contentsLayer->setBounds(IntSize(m_contentsRect.width(), m_contentsRect.height())); }
TEST_F(ScrollingCoordinatorTest, clippedBodyTest) { registerMockedHttpURLLoad("clipped-body.html"); navigateTo(m_baseURL + "clipped-body.html"); forceFullCompositingUpdate(); WebLayer* rootScrollLayer = getRootScrollLayer(); ASSERT_EQ(0u, rootScrollLayer->nonFastScrollableRegion().size()); }
TEST_F(ScrollingCoordinatorChromiumTest, nonFastScrollableRegion) { registerMockedHttpURLLoad("non-fast-scrollable.html"); navigateTo(m_baseURL + "non-fast-scrollable.html"); WebLayer* rootScrollLayer = getRootScrollLayer(); WebVector<WebRect> nonFastScrollableRegion = rootScrollLayer->nonFastScrollableRegion(); ASSERT_EQ(1u, nonFastScrollableRegion.size()); ASSERT_EQ(WebRect(8, 8, 10, 10), nonFastScrollableRegion[0]); }
void GraphicsLayerChromium::updateLayerBackgroundColor() { WebLayer* contentsLayer = contentsLayerIfRegistered(); if (!contentsLayer) return; // We never create the contents layer just for background color yet. if (m_backgroundColorSet) contentsLayer->setBackgroundColor(m_backgroundColor.rgb()); else contentsLayer->setBackgroundColor(static_cast<RGBA32>(0)); }
void GraphicsLayer::setContentsClippingMaskLayer(GraphicsLayer* contentsClippingMaskLayer) { if (contentsClippingMaskLayer == m_contentsClippingMaskLayer) return; m_contentsClippingMaskLayer = contentsClippingMaskLayer; WebLayer* contentsLayer = contentsLayerIfRegistered(); if (!contentsLayer) return; WebLayer* contentsClippingMaskWebLayer = m_contentsClippingMaskLayer ? m_contentsClippingMaskLayer->platformLayer() : 0; contentsLayer->setMaskLayer(contentsClippingMaskWebLayer); updateContentsRect(); }
TEST_P(CompositorWorkerTest, applyingMutationsMultipleElements) { registerMockedHttpURLLoad("compositor-proxy-basic.html"); navigateTo(m_baseURL + "compositor-proxy-basic.html"); Document* document = frame()->document(); { forceFullCompositingUpdate(); Element* proxiedElement = document->getElementById("proxied-transform"); WebLayer* proxiedLayer = webLayerFromElement(proxiedElement); EXPECT_TRUE(proxiedLayer->compositorMutableProperties() & CompositorMutableProperty::kTransform); EXPECT_FALSE(proxiedLayer->compositorMutableProperties() & (CompositorMutableProperty::kScrollLeft | CompositorMutableProperty::kScrollTop | CompositorMutableProperty::kOpacity)); EXPECT_TRUE(proxiedLayer->elementId()); TransformationMatrix transformMatrix(11, 12, 13, 14, 21, 22, 23, 24, 31, 32, 33, 34, 41, 42, 43, 44); CompositorMutation mutation; mutation.setTransform(TransformationMatrix::toSkMatrix44(transformMatrix)); proxiedElement->updateFromCompositorMutation(mutation); forceFullCompositingUpdate(); const String& cssValue = document->domWindow() ->getComputedStyle(proxiedElement, String()) ->getPropertyValueInternal(CSSPropertyTransform); EXPECT_EQ( "matrix3d(11, 12, 13, 14, 21, 22, 23, 24, 31, 32, 33, 34, 41, 42, 43, " "44)", cssValue); } { Element* proxiedElement = document->getElementById("proxied-opacity"); WebLayer* proxiedLayer = webLayerFromElement(proxiedElement); EXPECT_TRUE(proxiedLayer->compositorMutableProperties() & CompositorMutableProperty::kOpacity); EXPECT_FALSE(proxiedLayer->compositorMutableProperties() & (CompositorMutableProperty::kScrollLeft | CompositorMutableProperty::kScrollTop | CompositorMutableProperty::kTransform)); EXPECT_TRUE(proxiedLayer->elementId()); CompositorMutation mutation; mutation.setOpacity(0.5); proxiedElement->updateFromCompositorMutation(mutation); forceFullCompositingUpdate(); const String& cssValue = document->domWindow() ->getComputedStyle(proxiedElement, String()) ->getPropertyValueInternal(CSSPropertyOpacity); EXPECT_EQ("0.5", cssValue); } }
TEST_F(ScrollingCoordinatorChromiumTest, fastScrollingByDefault) { navigateTo("about:blank"); // Make sure the scrolling coordinator is active. FrameView* frameView = m_webViewImpl->mainFrameImpl()->frameView(); Page* page = m_webViewImpl->mainFrameImpl()->frame()->page(); ASSERT_TRUE(page->scrollingCoordinator()); ASSERT_TRUE(page->scrollingCoordinator()->coordinatesScrollingForFrameView(frameView)); // Fast scrolling should be enabled by default. WebLayer* rootScrollLayer = getRootScrollLayer(); ASSERT_TRUE(rootScrollLayer->scrollable()); ASSERT_FALSE(rootScrollLayer->shouldScrollOnMainThread()); ASSERT_FALSE(rootScrollLayer->haveWheelEventHandlers()); }
TEST_F(ScrollingCoordinatorTest, fastScrollingCanBeDisabledWithSetting) { navigateTo("about:blank"); webViewImpl()->settings()->setThreadedScrollingEnabled(false); forceFullCompositingUpdate(); // Make sure the scrolling coordinator is active. FrameView* frameView = frame()->view(); Page* page = frame()->page(); ASSERT_TRUE(page->scrollingCoordinator()); ASSERT_TRUE(page->scrollingCoordinator()->coordinatesScrollingForFrameView(frameView)); // Main scrolling should be enabled with the setting override. WebLayer* rootScrollLayer = getRootScrollLayer(); ASSERT_TRUE(rootScrollLayer->scrollable()); ASSERT_TRUE(rootScrollLayer->shouldScrollOnMainThread()); }
void ScrollingCoordinatorChromium::scrollableAreaScrollLayerDidChange(ScrollableArea* scrollableArea) { GraphicsLayerChromium* scrollLayer = static_cast<GraphicsLayerChromium*>(scrollLayerForScrollableArea(scrollableArea)); if (scrollLayer) scrollLayer->setScrollableArea(scrollableArea); WebLayer* webLayer = scrollingWebLayerForScrollableArea(scrollableArea); if (webLayer) { webLayer->setScrollable(true); webLayer->setScrollPosition(IntPoint(scrollableArea->scrollPosition() - scrollableArea->minimumScrollPosition())); webLayer->setMaxScrollPosition(IntSize(scrollableArea->scrollSize(HorizontalScrollbar), scrollableArea->scrollSize(VerticalScrollbar))); } if (WebScrollbarLayer* scrollbarLayer = getWebScrollbarLayer(scrollableArea, HorizontalScrollbar)) setupScrollbarLayer(horizontalScrollbarLayerForScrollableArea(scrollableArea), scrollbarLayer, webLayer); if (WebScrollbarLayer* scrollbarLayer = getWebScrollbarLayer(scrollableArea, VerticalScrollbar)) setupScrollbarLayer(verticalScrollbarLayerForScrollableArea(scrollableArea), scrollbarLayer, webLayer); }
static std::unique_ptr<Array<protocol::LayerTree::ScrollRect>> buildScrollRectsForLayer(GraphicsLayer* graphicsLayer, bool reportWheelScrollers) { std::unique_ptr<Array<protocol::LayerTree::ScrollRect>> scrollRects = Array<protocol::LayerTree::ScrollRect>::create(); WebLayer* webLayer = graphicsLayer->platformLayer(); WebVector<WebRect> nonFastScrollableRects = webLayer->nonFastScrollableRegion(); for (size_t i = 0; i < nonFastScrollableRects.size(); ++i) { scrollRects->addItem(buildScrollRect( nonFastScrollableRects[i], protocol::LayerTree::ScrollRect::TypeEnum::RepaintsOnScroll)); } WebVector<WebRect> touchEventHandlerRects = webLayer->touchEventHandlerRegion(); for (size_t i = 0; i < touchEventHandlerRects.size(); ++i) { scrollRects->addItem(buildScrollRect( touchEventHandlerRects[i], protocol::LayerTree::ScrollRect::TypeEnum::TouchEventHandler)); } if (reportWheelScrollers) { WebRect webRect(webLayer->position().x, webLayer->position().y, webLayer->bounds().width, webLayer->bounds().height); scrollRects->addItem(buildScrollRect( webRect, protocol::LayerTree::ScrollRect::TypeEnum::WheelEventHandler)); } return scrollRects->length() ? std::move(scrollRects) : nullptr; }
static std::unique_ptr<protocol::LayerTree::Layer> buildObjectForLayer( GraphicsLayer* graphicsLayer, int nodeId, bool reportWheelEventListeners) { WebLayer* webLayer = graphicsLayer->platformLayer(); std::unique_ptr<protocol::LayerTree::Layer> layerObject = protocol::LayerTree::Layer::create() .setLayerId(idForLayer(graphicsLayer)) .setOffsetX(webLayer->position().x) .setOffsetY(webLayer->position().y) .setWidth(webLayer->bounds().width) .setHeight(webLayer->bounds().height) .setPaintCount(graphicsLayer->paintCount()) .setDrawsContent(webLayer->drawsContent()) .build(); if (nodeId) layerObject->setBackendNodeId(nodeId); GraphicsLayer* parent = graphicsLayer->parent(); if (parent) layerObject->setParentLayerId(idForLayer(parent)); if (!graphicsLayer->contentsAreVisible()) layerObject->setInvisible(true); const TransformationMatrix& transform = graphicsLayer->transform(); if (!transform.isIdentity()) { TransformationMatrix::FloatMatrix4 flattenedMatrix; transform.toColumnMajorFloatArray(flattenedMatrix); std::unique_ptr<Array<double>> transformArray = Array<double>::create(); for (size_t i = 0; i < WTF_ARRAY_LENGTH(flattenedMatrix); ++i) transformArray->addItem(flattenedMatrix[i]); layerObject->setTransform(std::move(transformArray)); const FloatPoint3D& transformOrigin = graphicsLayer->transformOrigin(); // FIXME: rename these to setTransformOrigin* if (webLayer->bounds().width > 0) layerObject->setAnchorX(transformOrigin.x() / webLayer->bounds().width); else layerObject->setAnchorX(0.0); if (webLayer->bounds().height > 0) layerObject->setAnchorY(transformOrigin.y() / webLayer->bounds().height); else layerObject->setAnchorY(0.0); layerObject->setAnchorZ(transformOrigin.z()); } std::unique_ptr<Array<protocol::LayerTree::ScrollRect>> scrollRects = buildScrollRectsForLayer(graphicsLayer, reportWheelEventListeners); if (scrollRects) layerObject->setScrollRects(std::move(scrollRects)); return layerObject; }
void GraphicsLayer::updateContentsRect() { WebLayer* contentsLayer = contentsLayerIfRegistered(); if (!contentsLayer) return; contentsLayer->setPosition(FloatPoint(m_contentsRect.x(), m_contentsRect.y())); contentsLayer->setBounds(IntSize(m_contentsRect.width(), m_contentsRect.height())); if (m_contentsClippingMaskLayer) { if (m_contentsClippingMaskLayer->size() != m_contentsRect.size()) { m_contentsClippingMaskLayer->setSize(m_contentsRect.size()); m_contentsClippingMaskLayer->setNeedsDisplay(); } m_contentsClippingMaskLayer->setPosition(FloatPoint()); m_contentsClippingMaskLayer->setOffsetFromRenderer(offsetFromRenderer() + IntSize(m_contentsRect.location().x(), m_contentsRect.location().y())); } }
TEST_F(ScrollingCoordinatorTest, fractionalScrollingNonLayerFixedPosition) { registerMockedHttpURLLoad("fractional-scroll-fixed-position.html"); navigateTo(m_baseURL + "fractional-scroll-fixed-position.html"); // Prevent fixed-position element from getting its own layer. webViewImpl()->settings()->setPreferCompositingToLCDTextEnabled(false); forceFullCompositingUpdate(); FrameView* frameView = frame()->view(); frameView->scrollTo(DoublePoint(1.5, 1.5)); WebLayer* rootScrollLayer = getRootScrollLayer(); // Scroll on main if there is non-composited fixed position element. // And the containing scroll layer should not get fractional scroll offset. ASSERT_TRUE(rootScrollLayer->shouldScrollOnMainThread()); ASSERT_EQ(1.0, rootScrollLayer->scrollPositionDouble().x); ASSERT_EQ(1.0, rootScrollLayer->scrollPositionDouble().y); ASSERT_EQ(0.0, rootScrollLayer->position().x); ASSERT_EQ(0.0, rootScrollLayer->position().y); }
TEST_F(ScrollingCoordinatorTest, iframeScrolling) { registerMockedHttpURLLoad("iframe-scrolling.html"); registerMockedHttpURLLoad("iframe-scrolling-inner.html"); navigateTo(m_baseURL + "iframe-scrolling.html"); forceFullCompositingUpdate(); // Verify the properties of the accelerated scrolling element starting from the LayoutObject // all the way to the WebLayer. Element* scrollableFrame = frame()->document()->getElementById("scrollable"); ASSERT_TRUE(scrollableFrame); LayoutObject* layoutObject = scrollableFrame->layoutObject(); ASSERT_TRUE(layoutObject); ASSERT_TRUE(layoutObject->isLayoutPart()); LayoutPart* layoutPart = toLayoutPart(layoutObject); ASSERT_TRUE(layoutPart); ASSERT_TRUE(layoutPart->widget()); ASSERT_TRUE(layoutPart->widget()->isFrameView()); FrameView* innerFrameView = toFrameView(layoutPart->widget()); LayoutView* innerLayoutView = innerFrameView->layoutView(); ASSERT_TRUE(innerLayoutView); PaintLayerCompositor* innerCompositor = innerLayoutView->compositor(); ASSERT_TRUE(innerCompositor->inCompositingMode()); ASSERT_TRUE(innerCompositor->scrollLayer()); GraphicsLayer* scrollLayer = innerCompositor->scrollLayer(); ASSERT_EQ(innerFrameView, scrollLayer->scrollableArea()); WebLayer* webScrollLayer = scrollLayer->platformLayer(); ASSERT_TRUE(webScrollLayer->scrollable()); #if OS(ANDROID) // Now verify we've attached impl-side scrollbars onto the scrollbar layers ASSERT_TRUE(innerCompositor->layerForHorizontalScrollbar()); ASSERT_TRUE(innerCompositor->layerForHorizontalScrollbar()->hasContentsLayer()); ASSERT_TRUE(innerCompositor->layerForVerticalScrollbar()); ASSERT_TRUE(innerCompositor->layerForVerticalScrollbar()->hasContentsLayer()); #endif }
static PassRefPtr<TypeBuilder::Array<TypeBuilder::LayerTree::ScrollRect> > buildScrollRectsForLayer(GraphicsLayer* graphicsLayer) { RefPtr<TypeBuilder::Array<TypeBuilder::LayerTree::ScrollRect> > scrollRects = TypeBuilder::Array<TypeBuilder::LayerTree::ScrollRect>::create(); WebLayer* webLayer = graphicsLayer->platformLayer(); for (size_t i = 0; i < webLayer->nonFastScrollableRegion().size(); ++i) { scrollRects->addItem(buildScrollRect(webLayer->nonFastScrollableRegion()[i], TypeBuilder::LayerTree::ScrollRect::Type::RepaintsOnScroll)); } for (size_t i = 0; i < webLayer->touchEventHandlerRegion().size(); ++i) { scrollRects->addItem(buildScrollRect(webLayer->touchEventHandlerRegion()[i], TypeBuilder::LayerTree::ScrollRect::Type::TouchEventHandler)); } if (webLayer->haveWheelEventHandlers()) { WebRect webRect(webLayer->position().x, webLayer->position().y, webLayer->bounds().width, webLayer->bounds().height); scrollRects->addItem(buildScrollRect(webRect, TypeBuilder::LayerTree::ScrollRect::Type::WheelEventHandler)); } return scrollRects->length() ? scrollRects.release() : nullptr; }
void GraphicsLayer::updateChildList() { WebLayer* childHost = m_layer->layer(); childHost->removeAllChildren(); clearContentsLayerIfUnregistered(); if (m_contentsLayer) { // FIXME: add the contents layer in the correct order with negative z-order children. // This does not cause visible rendering issues because currently contents layers are only used // for replaced elements that don't have children. childHost->addChild(m_contentsLayer); } for (size_t i = 0; i < m_children.size(); ++i) childHost->addChild(m_children[i]->platformLayer()); for (size_t i = 0; i < m_linkHighlights.size(); ++i) childHost->addChild(m_linkHighlights[i]->layer()); }
TEST_F(ScrollingCoordinatorTest, FixedPositionLosingBackingShouldTriggerMainThreadScroll) { webViewImpl()->settings()->setPreferCompositingToLCDTextEnabled(false); registerMockedHttpURLLoad("fixed-position-losing-backing.html"); navigateTo(m_baseURL + "fixed-position-losing-backing.html"); forceFullCompositingUpdate(); WebLayer* scrollLayer = frame()->page()->deprecatedLocalMainFrame()->view()->layerForScrolling()->platformLayer(); Document* document = frame()->document(); Element* fixedPos = document->getElementById("fixed"); EXPECT_TRUE(static_cast<LayoutBoxModelObject*>(fixedPos->layoutObject())->layer()->hasCompositedLayerMapping()); EXPECT_FALSE(scrollLayer->shouldScrollOnMainThread()); fixedPos->setInlineStyleProperty(CSSPropertyTransform, CSSValueNone); forceFullCompositingUpdate(); EXPECT_FALSE(static_cast<LayoutBoxModelObject*>(fixedPos->layoutObject())->layer()->hasCompositedLayerMapping()); EXPECT_TRUE(scrollLayer->shouldScrollOnMainThread()); }
void GraphicsLayerChromium::updateChildList() { WebLayer* childHost = m_transformLayer ? m_transformLayer.get() : m_layer->layer(); childHost->removeAllChildren(); clearContentsLayerIfUnregistered(); if (m_transformLayer) { // Add the primary layer first. Even if we have negative z-order children, the primary layer always comes behind. childHost->addChild(m_layer->layer()); } else if (m_contentsLayer) { // FIXME: add the contents layer in the correct order with negative z-order children. // This does not cause visible rendering issues because currently contents layers are only used // for replaced elements that don't have children. childHost->addChild(m_contentsLayer); } const Vector<GraphicsLayer*>& childLayers = children(); size_t numChildren = childLayers.size(); for (size_t i = 0; i < numChildren; ++i) { GraphicsLayerChromium* curChild = static_cast<GraphicsLayerChromium*>(childLayers[i]); childHost->addChild(curChild->platformLayer()); } if (m_linkHighlight) childHost->addChild(m_linkHighlight->layer()); if (m_transformLayer && m_contentsLayer) { // If we have a transform layer, then the contents layer is parented in the // primary layer (which is itself a child of the transform layer). m_layer->layer()->removeAllChildren(); m_layer->layer()->addChild(m_contentsLayer); } }
TEST_F(ScrollingCoordinatorTest, overflowScrolling) { registerMockedHttpURLLoad("overflow-scrolling.html"); navigateTo(m_baseURL + "overflow-scrolling.html"); forceFullCompositingUpdate(); // Verify the properties of the accelerated scrolling element starting from the LayoutObject // all the way to the WebLayer. Element* scrollableElement = frame()->document()->getElementById("scrollable"); ASSERT(scrollableElement); LayoutObject* layoutObject = scrollableElement->layoutObject(); ASSERT_TRUE(layoutObject->isBox()); ASSERT_TRUE(layoutObject->hasLayer()); LayoutBox* box = toLayoutBox(layoutObject); ASSERT_TRUE(box->usesCompositedScrolling()); ASSERT_EQ(PaintsIntoOwnBacking, box->layer()->compositingState()); CompositedLayerMapping* compositedLayerMapping = box->layer()->compositedLayerMapping(); ASSERT_TRUE(compositedLayerMapping->hasScrollingLayer()); ASSERT(compositedLayerMapping->scrollingContentsLayer()); GraphicsLayer* graphicsLayer = compositedLayerMapping->scrollingContentsLayer(); ASSERT_EQ(box->layer()->scrollableArea(), graphicsLayer->scrollableArea()); WebLayer* webScrollLayer = compositedLayerMapping->scrollingContentsLayer()->platformLayer(); ASSERT_TRUE(webScrollLayer->scrollable()); ASSERT_TRUE(webScrollLayer->userScrollableHorizontal()); ASSERT_TRUE(webScrollLayer->userScrollableVertical()); #if OS(ANDROID) // Now verify we've attached impl-side scrollbars onto the scrollbar layers ASSERT_TRUE(compositedLayerMapping->layerForHorizontalScrollbar()); ASSERT_TRUE(compositedLayerMapping->layerForHorizontalScrollbar()->hasContentsLayer()); ASSERT_TRUE(compositedLayerMapping->layerForVerticalScrollbar()); ASSERT_TRUE(compositedLayerMapping->layerForVerticalScrollbar()->hasContentsLayer()); #endif }
TEST_F(ScrollingCoordinatorTest, overflowHidden) { registerMockedHttpURLLoad("overflow-hidden.html"); navigateTo(m_baseURL + "overflow-hidden.html"); forceFullCompositingUpdate(); // Verify the properties of the accelerated scrolling element starting from the LayoutObject // all the way to the WebLayer. Element* overflowElement = frame()->document()->getElementById("unscrollable-y"); ASSERT(overflowElement); LayoutObject* layoutObject = overflowElement->layoutObject(); ASSERT_TRUE(layoutObject->isBox()); ASSERT_TRUE(layoutObject->hasLayer()); LayoutBox* box = toLayoutBox(layoutObject); ASSERT_TRUE(box->usesCompositedScrolling()); ASSERT_EQ(PaintsIntoOwnBacking, box->layer()->compositingState()); CompositedLayerMapping* compositedLayerMapping = box->layer()->compositedLayerMapping(); ASSERT_TRUE(compositedLayerMapping->hasScrollingLayer()); ASSERT(compositedLayerMapping->scrollingContentsLayer()); GraphicsLayer* graphicsLayer = compositedLayerMapping->scrollingContentsLayer(); ASSERT_EQ(box->layer()->scrollableArea(), graphicsLayer->scrollableArea()); WebLayer* webScrollLayer = compositedLayerMapping->scrollingContentsLayer()->platformLayer(); ASSERT_TRUE(webScrollLayer->scrollable()); ASSERT_TRUE(webScrollLayer->userScrollableHorizontal()); ASSERT_FALSE(webScrollLayer->userScrollableVertical()); overflowElement = frame()->document()->getElementById("unscrollable-x"); ASSERT(overflowElement); layoutObject = overflowElement->layoutObject(); ASSERT_TRUE(layoutObject->isBox()); ASSERT_TRUE(layoutObject->hasLayer()); box = toLayoutBox(layoutObject); ASSERT_TRUE(box->scrollableArea()->usesCompositedScrolling()); ASSERT_EQ(PaintsIntoOwnBacking, box->layer()->compositingState()); compositedLayerMapping = box->layer()->compositedLayerMapping(); ASSERT_TRUE(compositedLayerMapping->hasScrollingLayer()); ASSERT(compositedLayerMapping->scrollingContentsLayer()); graphicsLayer = compositedLayerMapping->scrollingContentsLayer(); ASSERT_EQ(box->layer()->scrollableArea(), graphicsLayer->scrollableArea()); webScrollLayer = compositedLayerMapping->scrollingContentsLayer()->platformLayer(); ASSERT_TRUE(webScrollLayer->scrollable()); ASSERT_FALSE(webScrollLayer->userScrollableHorizontal()); ASSERT_TRUE(webScrollLayer->userScrollableVertical()); }
TEST_F(ScrollingCoordinatorTest, rtlIframe) { registerMockedHttpURLLoad("rtl-iframe.html"); registerMockedHttpURLLoad("rtl-iframe-inner.html"); navigateTo(m_baseURL + "rtl-iframe.html"); forceFullCompositingUpdate(); // Verify the properties of the accelerated scrolling element starting from the LayoutObject // all the way to the WebLayer. Element* scrollableFrame = frame()->document()->getElementById("scrollable"); ASSERT_TRUE(scrollableFrame); LayoutObject* layoutObject = scrollableFrame->layoutObject(); ASSERT_TRUE(layoutObject); ASSERT_TRUE(layoutObject->isLayoutPart()); LayoutPart* layoutPart = toLayoutPart(layoutObject); ASSERT_TRUE(layoutPart); ASSERT_TRUE(layoutPart->widget()); ASSERT_TRUE(layoutPart->widget()->isFrameView()); FrameView* innerFrameView = toFrameView(layoutPart->widget()); LayoutView* innerLayoutView = innerFrameView->layoutView(); ASSERT_TRUE(innerLayoutView); PaintLayerCompositor* innerCompositor = innerLayoutView->compositor(); ASSERT_TRUE(innerCompositor->inCompositingMode()); ASSERT_TRUE(innerCompositor->scrollLayer()); GraphicsLayer* scrollLayer = innerCompositor->scrollLayer(); ASSERT_EQ(innerFrameView, scrollLayer->scrollableArea()); WebLayer* webScrollLayer = scrollLayer->platformLayer(); ASSERT_TRUE(webScrollLayer->scrollable()); int expectedScrollPosition = 958 + (innerFrameView->verticalScrollbar()->isOverlayScrollbar() ? 0 : 15); ASSERT_EQ(expectedScrollPosition, webScrollLayer->scrollPositionDouble().x); }
void NonCompositedContentHost::setViewport(const WebCore::IntSize& viewportSize, const WebCore::IntSize& contentsSize, const WebCore::IntPoint& scrollPosition, const WebCore::IntPoint& scrollOrigin) { if (!haveScrollLayer()) return; bool visibleRectChanged = m_viewportSize != viewportSize; m_viewportSize = viewportSize; WebLayer* layer = scrollLayer(); layer->setScrollPosition(scrollPosition + scrollOrigin); layer->setPosition(WebFloatPoint(-scrollPosition)); // Due to the possibility of pinch zoom, the noncomposited layer is always // assumed to be scrollable. layer->setScrollable(true); m_graphicsLayer->setSize(contentsSize); // In RTL-style pages, the origin of the initial containing block for the // root layer may be positive; translate the layer to avoid negative // coordinates. m_layerAdjust = -toSize(scrollOrigin); if (m_graphicsLayer->transform().m41() != m_layerAdjust.width() || m_graphicsLayer->transform().m42() != m_layerAdjust.height()) { WebCore::TransformationMatrix transform = m_graphicsLayer->transform(); transform.setM41(m_layerAdjust.width()); transform.setM42(m_layerAdjust.height()); m_graphicsLayer->setTransform(transform); // If a tiled layer is shifted left or right, the content that goes into // each tile will change. Invalidate the entire layer when this happens. m_graphicsLayer->setNeedsDisplay(); } else if (visibleRectChanged) m_graphicsLayer->setNeedsDisplay(); WebCore::GraphicsLayer* clipLayer = m_graphicsLayer->parent()->parent(); WebCore::GraphicsLayer* rootLayer = clipLayer; while (rootLayer->parent()) rootLayer = rootLayer->parent(); setScrollbarBoundsContainPageScale(rootLayer, clipLayer); }