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()); }
PassRefPtr<TypeBuilder::LayerTree::Layer> InspectorLayerTreeAgent::buildObjectForLayer(ErrorString* errorString, RenderLayer* renderLayer) { RenderObject* renderer = &renderLayer->renderer(); RenderLayerBacking* backing = renderLayer->backing(); Node* node = renderer->node(); bool isReflection = renderLayer->isReflection(); bool isGenerated = (isReflection ? renderer->parent() : renderer)->isBeforeOrAfterContent(); bool isAnonymous = renderer->isAnonymous(); if (renderer->isRenderView()) node = &renderer->document(); else if (isReflection && isGenerated) node = renderer->parent()->generatingElement(); else if (isGenerated) node = renderer->generatingNode(); else if (isReflection || isAnonymous) node = renderer->parent()->element(); // Basic set of properties. RefPtr<TypeBuilder::LayerTree::Layer> layerObject = TypeBuilder::LayerTree::Layer::create() .setLayerId(bind(renderLayer)) .setNodeId(idForNode(errorString, node)) .setBounds(buildObjectForIntRect(renderer->absoluteBoundingBoxRect())) .setMemory(backing->backingStoreMemoryEstimate()) .setCompositedBounds(buildObjectForIntRect(enclosingIntRect(backing->compositedBounds()))) .setPaintCount(backing->graphicsLayer()->repaintCount()); if (node && node->shadowHost()) layerObject->setIsInShadowTree(true); if (isReflection) layerObject->setIsReflection(true); if (isGenerated) { if (isReflection) renderer = renderer->parent(); layerObject->setIsGeneratedContent(true); layerObject->setPseudoElementId(bindPseudoElement(toPseudoElement(renderer->node()))); if (renderer->isBeforeContent()) layerObject->setPseudoElement("before"); else if (renderer->isAfterContent()) layerObject->setPseudoElement("after"); } // FIXME: RenderView is now really anonymous but don't tell about it to the frontend before making sure it can handle it. if (isAnonymous && !renderer->isRenderView()) { layerObject->setIsAnonymous(true); if (RenderStyle* style = renderer->style()) { if (style->styleType() == FIRST_LETTER) layerObject->setPseudoElement("first-letter"); else if (style->styleType() == FIRST_LINE) layerObject->setPseudoElement("first-line"); } } return layerObject; }
PassRefPtr<TypeBuilder::LayerTree::Layer> InspectorLayerTreeAgent::buildObjectForLayer(RenderLayer* renderLayer) { bool isComposited = renderLayer->isComposited(); // Basic set of properties. RefPtr<TypeBuilder::LayerTree::Layer> layerObject = TypeBuilder::LayerTree::Layer::create() .setLayerId(bind(renderLayer)) .setBounds(buildObjectForIntRect(enclosingIntRect(renderLayer->localBoundingBox()))) .setIsComposited(isComposited); // Optional properties for composited layers only. if (isComposited) { RenderLayerBacking* backing = renderLayer->backing(); layerObject->setMemory(backing->backingStoreMemoryEstimate()); layerObject->setCompositedBounds(buildObjectForIntRect(backing->compositedBounds())); layerObject->setPaintCount(backing->graphicsLayer()->repaintCount()); } // Process children layers. RefPtr<TypeBuilder::Array<TypeBuilder::LayerTree::Layer> > childrenArray = TypeBuilder::Array<TypeBuilder::LayerTree::Layer>::create(); renderLayer->updateLayerListsIfNeeded(); // Check if we have a reflection layer. if (renderLayer->reflectionLayer()) childrenArray->addItem(buildObjectForLayer(renderLayer->reflectionLayer())); if (renderLayer->isStackingContext()) { if (Vector<RenderLayer*>* negZOrderList = renderLayer->negZOrderList()) { size_t listSize = negZOrderList->size(); for (size_t i = 0; i < listSize; ++i) childrenArray->addItem(buildObjectForLayer(negZOrderList->at(i))); } } if (Vector<RenderLayer*>* normalFlowList = renderLayer->normalFlowList()) { size_t listSize = normalFlowList->size(); for (size_t i = 0; i < listSize; ++i) childrenArray->addItem(buildObjectForLayer(normalFlowList->at(i))); } if (renderLayer->isStackingContext()) { if (Vector<RenderLayer*>* posZOrderList = renderLayer->posZOrderList()) { size_t listSize = posZOrderList->size(); for (size_t i = 0; i < listSize; ++i) childrenArray->addItem(buildObjectForLayer(posZOrderList->at(i))); } } layerObject->setChildLayers(childrenArray); return layerObject; }
static void updateOffsetFromViewportForSelf(RenderLayer* renderLayer) { // These conditions must match the conditions in RenderLayerCompositor::requiresCompositingForPosition. RenderLayerBacking* backing = renderLayer->backing(); if (!backing) return; RenderStyle* style = renderLayer->renderer()->style(); if (!style) return; if (!renderLayer->renderer()->isOutOfFlowPositioned() || renderLayer->renderer()->style()->position() != FixedPosition) return; if (!renderLayer->renderer()->container()->isRenderView()) return; if (!renderLayer->isStackingContext()) return; CoordinatedGraphicsLayer* graphicsLayer = toCoordinatedGraphicsLayer(backing->graphicsLayer()); graphicsLayer->setFixedToViewport(true); }