void PannerNode::setPosition(float x, float y, float z) { FloatPoint3D position = FloatPoint3D(x, y, z); if (m_position == position) return; // This synchronizes with process(). MutexLocker processLocker(m_processLock); m_position = position; markPannerAsDirty(PannerNode::AzimuthElevationDirty | PannerNode::DistanceConeGainDirty | PannerNode::DopplerRateDirty); }
void PannerNode::setOrientation(float x, float y, float z) { FloatPoint3D orientation = FloatPoint3D(x, y, z); if (m_orientation == orientation) return; // This synchronizes with process(). MutexLocker processLocker(m_processLock); m_orientation = orientation; markPannerAsDirty(PannerNode::DistanceConeGainDirty); }
TEST_F(PaintPropertyTreeBuilderTest, Transform) { loadTestData("transform.html"); Element* transform = document().getElementById("transform"); ObjectPaintProperties* transformProperties = transform->layoutObject()->objectPaintProperties(); EXPECT_EQ(TransformationMatrix().translate3d(123, 456, 789), transformProperties->transform()->matrix()); EXPECT_EQ(FloatPoint3D(200, 150, 0), transformProperties->transform()->origin()); EXPECT_EQ(transformProperties->paintOffsetTranslation(), transformProperties->transform()->parent()); EXPECT_EQ(TransformationMatrix().translate(50, 100), transformProperties->paintOffsetTranslation()->matrix()); EXPECT_EQ(document().view()->scrollTranslation(), transformProperties->paintOffsetTranslation()->parent()); }
TEST(TransformationMatrixTest, ApplyTransformOrigin) { TransformationMatrix matrix; // (0,0,0) is a fixed point of this scale. // (1,1,1) should be scaled appropriately. matrix.scale3d(2, 3, 4); EXPECT_EQ(FloatPoint3D(0, 0, 0), matrix.mapPoint(FloatPoint3D(0, 0, 0))); EXPECT_EQ(FloatPoint3D(2, 3, -4), matrix.mapPoint(FloatPoint3D(1, 1, -1))); // With the transform origin applied, (1,2,3) is the fixed point. // (0,0,0) should be scaled according to its distance from (1,2,3). matrix.applyTransformOrigin(1, 2, 3); EXPECT_EQ(FloatPoint3D(1, 2, 3), matrix.mapPoint(FloatPoint3D(1, 2, 3))); EXPECT_EQ(FloatPoint3D(-1, -4, -9), matrix.mapPoint(FloatPoint3D(0, 0, 0))); }
void LayerTreeHostProxy::ensureRootLayer() { if (m_rootLayer) return; m_rootLayer = createLayer(InvalidWebLayerID); m_rootLayer->setMasksToBounds(false); m_rootLayer->setDrawsContent(false); m_rootLayer->setAnchorPoint(FloatPoint3D(0, 0, 0)); // The root layer should not have zero size, or it would be optimized out. m_rootLayer->setSize(FloatSize(1.0, 1.0)); m_textureMapper = TextureMapperGL::create(); toTextureMapperNode(m_rootLayer.get())->setTextureMapper(m_textureMapper.get()); }
static PassRefPtr<TransformPaintPropertyNode> createPaintOffsetTranslationIfNeeded(const LayoutBoxModelObject& object, PaintPropertyTreeBuilderContext& context) { // TODO(trchen): Eliminate PaintLayer dependency. bool shouldCreatePaintOffsetTranslationNode = object.layer() && object.layer()->paintsWithTransform(GlobalPaintNormalPhase); if (context.paintOffset == LayoutPoint() || !shouldCreatePaintOffsetTranslationNode) return nullptr; RefPtr<TransformPaintPropertyNode> newTransformNodeForPaintOffsetTranslation = TransformPaintPropertyNode::create( TransformationMatrix().translate(context.paintOffset.x(), context.paintOffset.y()), FloatPoint3D(), context.currentTransform); context.currentTransform = newTransformNodeForPaintOffsetTranslation.get(); context.paintOffset = LayoutPoint(); return newTransformNodeForPaintOffsetTranslation.release(); }
PannerNode::PannerNode(float sampleRate) : AudioNode(sampleRate), m_panningModel(PanningMode::HRTF) { m_distanceEffect.reset(new DistanceEffect()); m_coneEffect.reset(new ConeEffect()); addInput(unique_ptr<AudioNodeInput>(new AudioNodeInput(this))); addOutput(unique_ptr<AudioNodeOutput>(new AudioNodeOutput(this, 2))); m_distanceGain = std::make_shared<AudioParam>("distanceGain", 1.0, 0.0, 1.0); m_coneGain = std::make_shared<AudioParam>("coneGain", 1.0, 0.0, 1.0); m_position = FloatPoint3D(0, 0, 0); m_orientation = FloatPoint3D(1, 0, 0); m_velocity = FloatPoint3D(0, 0, 0); // Node-specific default mixing rules. m_channelCount = 2; m_channelCountMode = ChannelCountMode::ClampedMax; m_channelInterpretation = ChannelInterpretation::Speakers; setNodeType(NodeTypePanner); initialize(); }
void TextureMapperNode::computeTransformations() { if (!m_transforms.dirty) return; m_transforms.dirty = false; if ((m_size.isEmpty() && m_state.masksToBounds)) return; TextureMapperNode* parent = m_parent; computeLocalTransform(); m_transforms.target = TransformationMatrix(parent ? parent->m_transforms.forDescendants : TransformationMatrix()).multiply(m_transforms.local); m_transforms.forDescendants = (m_layerType == ClipLayer ? TransformationMatrix() : m_transforms.target); if (m_effectTarget) return; m_transforms.targetBoundingRect = IntRect(m_transforms.target.mapRect(entireRect())); if (m_state.replicaLayer) m_state.replicaLayer->computeTransformations(); flattenTo2DSpaceIfNecessary(); if (!m_state.backfaceVisibility && m_transforms.target.inverse().m33() < 0) { m_state.visible = false; return; } m_state.visible = true; if (parent && parent->m_state.preserves3D) m_transforms.centerZ = m_transforms.target.mapPoint(FloatPoint3D(m_size.width() / 2, m_size.height() / 2, 0)).z(); if (!m_children.size()) return; if (m_state.childrenTransform.isIdentity()) return; const FloatPoint centerPoint = FloatPoint(m_size.width() / 2, m_size.height() / 2); if (m_transforms.perspectiveDirty) m_transforms.perspective = TransformationMatrix() .translate(centerPoint.x(), centerPoint.y()) .multiply(m_state.childrenTransform) .translate(-centerPoint.x(), -centerPoint.y()); m_transforms.perspectiveDirty = false; m_transforms.forDescendants.multiply(m_transforms.perspective); }
void PaintPropertyTreeBuilder::updateSvgLocalToBorderBoxTransform(const LayoutObject& object, PaintPropertyTreeBuilderContext& context) { if (!object.isSVGRoot()) return; AffineTransform transform = AffineTransform::translation(context.paintOffset.x().toFloat(), context.paintOffset.y().toFloat()); transform *= toLayoutSVGRoot(object).localToBorderBoxTransform(); if (transform.isIdentity()) return; RefPtr<TransformPaintPropertyNode> svgLocalToBorderBoxTransform = TransformPaintPropertyNode::create( transform, FloatPoint3D(0, 0, 0), context.currentTransform); context.currentTransform = svgLocalToBorderBoxTransform.get(); context.paintOffset = LayoutPoint(); object.getMutableForPainting().ensureObjectPaintProperties().setSvgLocalToBorderBoxTransform(svgLocalToBorderBoxTransform.release()); }
void CoordinatedGraphicsScene::ensureRootLayer() { if (m_rootLayer) return; m_rootLayer = GraphicsLayer::create(0 /* factory */, this); m_rootLayer->setMasksToBounds(false); m_rootLayer->setDrawsContent(false); m_rootLayer->setAnchorPoint(FloatPoint3D(0, 0, 0)); // The root layer should not have zero size, or it would be optimized out. m_rootLayer->setSize(FloatSize(1.0, 1.0)); ASSERT(m_textureMapper); toTextureMapperLayer(m_rootLayer.get())->setTextureMapper(m_textureMapper.get()); }
void PaintPropertyTreeBuilder::buildTreeRootNodes(FrameView& rootFrame, PaintPropertyTreeBuilderContext& context) { // Only create extra root clip and transform nodes when RLS is enabled, because the main frame // unconditionally create frame translation / clip nodes otherwise. if (rootFrame.frame().settings() && rootFrame.frame().settings()->rootLayerScrolls()) { transformRoot = TransformPaintPropertyNode::create(TransformationMatrix(), FloatPoint3D(), nullptr); context.currentTransform = context.transformForAbsolutePosition = context.transformForFixedPosition = transformRoot.get(); clipRoot = ClipPaintPropertyNode::create(transformRoot, FloatRoundedRect(LayoutRect::infiniteIntRect()), nullptr); context.currentClip = context.clipForAbsolutePosition = context.clipForFixedPosition = clipRoot.get(); } // The root frame never creates effect node so we unconditionally create a root node here. effectRoot = EffectPaintPropertyNode::create(1.0, nullptr); context.currentEffect = effectRoot.get(); }
void CoordinatedGraphicsScene::ensureRootLayer() { if (m_rootLayer) return; m_rootLayer = std::make_unique<TextureMapperLayer>(); m_rootLayer->setMasksToBounds(false); m_rootLayer->setDrawsContent(false); m_rootLayer->setAnchorPoint(FloatPoint3D(0, 0, 0)); // The root layer should not have zero size, or it would be optimized out. m_rootLayer->setSize(FloatSize(1.0, 1.0)); ASSERT(m_textureMapper); m_rootLayer->setTextureMapper(m_textureMapper.get()); }
// Returns the Z coordinate of a point on the given layer that projects // to point p which lies on the z = 0 plane. It does it by computing the // intersection of a line starting from p along the Z axis and the plane // of the layer. float CCLayerSorter::LayerIntersector::layerZFromProjectedPoint(GraphNode* layer, const FloatPoint& p) { const FloatPoint3D zAxis(0, 0, 1); FloatPoint3D w = FloatPoint3D(p.x(), p.y(), 0) - layer->origin; float d = layer->normal.dot(zAxis); float n = -layer->normal.dot(w); // Check if layer is parallel to the z = 0 axis if (!d) return layer->origin.z(); // The intersection point would be given by: // p + (n / d) * u but since we are only interested in the // z coordinate and p's z coord is zero, all we need is the value of n/d. return n / d; }
TEST_F(PaintPropertyTreeBuilderTest, Perspective) { loadTestData("perspective.html"); Element* perspective = document().getElementById("perspective"); ObjectPaintProperties* perspectiveProperties = perspective->layoutObject()->objectPaintProperties(); EXPECT_EQ(TransformationMatrix().applyPerspective(100), perspectiveProperties->perspective()->matrix()); // The perspective origin is the center of the border box plus accumulated paint offset. EXPECT_EQ(FloatPoint3D(250, 250, 0), perspectiveProperties->perspective()->origin()); EXPECT_EQ(document().view()->scrollTranslation(), perspectiveProperties->perspective()->parent()); // Adding perspective doesn't clear paint offset. The paint offset will be passed down to children. Element* inner = document().getElementById("inner"); ObjectPaintProperties* innerProperties = inner->layoutObject()->objectPaintProperties(); EXPECT_EQ(TransformationMatrix().translate(50, 100), innerProperties->paintOffsetTranslation()->matrix()); EXPECT_EQ(perspectiveProperties->perspective(), innerProperties->paintOffsetTranslation()->parent()); }
void PaintPropertyTreeBuilder::updateScrollAndScrollTranslation( const LayoutObject& object, PaintPropertyTreeBuilderContext& context) { if (object.hasOverflowClip()) { const LayoutBox& box = toLayoutBox(object); const PaintLayerScrollableArea* scrollableArea = box.getScrollableArea(); IntSize scrollOffset = box.scrolledContentOffset(); if (!scrollOffset.isZero() || scrollableArea->scrollsOverflow()) { TransformationMatrix matrix = TransformationMatrix().translate( -scrollOffset.width(), -scrollOffset.height()); object.getMutableForPainting() .ensurePaintProperties() .updateScrollTranslation( context.current.transform, matrix, FloatPoint3D(), context.current.shouldFlattenInheritedTransform, context.current.renderingContextID); IntSize scrollClip = scrollableArea->visibleContentRect().size(); IntSize scrollBounds = scrollableArea->contentsSize(); bool userScrollableHorizontal = scrollableArea->userInputScrollable(HorizontalScrollbar); bool userScrollableVertical = scrollableArea->userInputScrollable(VerticalScrollbar); object.getMutableForPainting().ensurePaintProperties().updateScroll( context.current.scroll, object.paintProperties()->scrollTranslation(), scrollClip, scrollBounds, userScrollableHorizontal, userScrollableVertical); } else { // Ensure pre-existing properties are cleared when there is no // scrolling. auto* properties = object.getMutableForPainting().paintProperties(); if (properties) { properties->clearScrollTranslation(); properties->clearScroll(); } } } if (object.paintProperties() && object.paintProperties()->scroll()) { context.current.transform = object.paintProperties()->scrollTranslation(); const auto* scroll = object.paintProperties()->scroll(); // TODO(pdr): Remove this const cast. context.current.scroll = const_cast<ScrollPaintPropertyNode*>(scroll); context.current.shouldFlattenInheritedTransform = false; } }
static PassRefPtr<TransformPaintPropertyNode> createScrollTranslationIfNeeded(const LayoutObject& object, PaintPropertyTreeBuilderContext& context) { if (!object.isBoxModelObject() || !object.hasOverflowClip()) return nullptr; PaintLayer* layer = toLayoutBoxModelObject(object).layer(); ASSERT(layer); DoubleSize scrollOffset = layer->scrollableArea()->scrollOffset(); if (scrollOffset.isZero() && !layer->scrollsOverflow()) return nullptr; RefPtr<TransformPaintPropertyNode> newTransformNodeForScrollTranslation = TransformPaintPropertyNode::create( TransformationMatrix().translate(-scrollOffset.width(), -scrollOffset.height()), FloatPoint3D(), context.currentTransform); context.currentTransform = newTransformNodeForScrollTranslation.get(); return newTransformNodeForScrollTranslation.release(); }
void PaintPropertyTreeBuilder::updateScrollTranslation(const LayoutObject& object, PaintPropertyTreeBuilderContext& context) { if (!object.isBoxModelObject() || !object.hasOverflowClip()) return; PaintLayer* layer = toLayoutBoxModelObject(object).layer(); ASSERT(layer); DoubleSize scrollOffset = layer->getScrollableArea()->scrollOffset(); if (scrollOffset.isZero() && !layer->scrollsOverflow()) return; RefPtr<TransformPaintPropertyNode> scrollTranslation = TransformPaintPropertyNode::create( TransformationMatrix().translate(-scrollOffset.width(), -scrollOffset.height()), FloatPoint3D(), context.currentTransform); context.currentTransform = scrollTranslation.get(); object.getMutableForPainting().ensureObjectPaintProperties().setScrollTranslation(scrollTranslation.release()); }
// Returns the Z coordinate of a point on the layer that projects // to point p which lies on the z = 0 plane. It does it by computing the // intersection of a line starting from p along the Z axis and the plane // of the layer. float CCLayerSorter::LayerShape::layerZFromProjectedPoint(const FloatPoint& p) const { const FloatPoint3D zAxis(0, 0, 1); FloatPoint3D w = FloatPoint3D(p) - transformOrigin; float d = layerNormal.dot(zAxis); float n = -layerNormal.dot(w); // Check if layer is parallel to the z = 0 axis which will make it // invisible and hence returning zero is fine. if (!d) return 0; // The intersection point would be given by: // p + (n / d) * u but since we are only interested in the // z coordinate and p's z coord is zero, all we need is the value of n/d. return n / d; }
// TODO(trchen): Remove this once we bake the paint offset into frameRect. void PaintPropertyTreeBuilder::updateScrollbarPaintOffset(const LayoutObject& object, const PaintPropertyTreeBuilderContext& context) { IntPoint roundedPaintOffset = roundedIntPoint(context.paintOffset); if (roundedPaintOffset == IntPoint()) return; if (!object.isBoxModelObject()) return; PaintLayerScrollableArea* scrollableArea = toLayoutBoxModelObject(object).getScrollableArea(); if (!scrollableArea) return; if (!scrollableArea->horizontalScrollbar() && !scrollableArea->verticalScrollbar()) return; auto paintOffset = TransformationMatrix().translate(roundedPaintOffset.x(), roundedPaintOffset.y()); object.getMutableForPainting().ensureObjectPaintProperties().setScrollbarPaintOffset( TransformPaintPropertyNode::create(paintOffset, FloatPoint3D(), context.currentTransform)); }
void PageOverlayController::installPageOverlay(PassRefPtr<PageOverlay> pageOverlay, PageOverlay::FadeMode fadeMode) { createRootLayersIfNeeded(); RefPtr<PageOverlay> overlay = pageOverlay; if (m_pageOverlays.contains(overlay)) return; m_pageOverlays.append(overlay); std::unique_ptr<GraphicsLayer> layer = GraphicsLayer::create(m_mainFrame.page()->chrome().client().graphicsLayerFactory(), *this); layer->setAnchorPoint(FloatPoint3D()); layer->setBackgroundColor(overlay->backgroundColor()); #ifndef NDEBUG layer->setName("Page Overlay content"); #endif updateSettingsForLayer(*layer); switch (overlay->overlayType()) { case PageOverlay::OverlayType::View: m_viewOverlayRootLayer->addChild(layer.get()); break; case PageOverlay::OverlayType::Document: m_documentOverlayRootLayer->addChild(layer.get()); break; } GraphicsLayer& rawLayer = *layer; m_overlayGraphicsLayers.set(overlay.get(), WTFMove(layer)); updateForceSynchronousScrollLayerPositionUpdates(); overlay->setPage(m_mainFrame.page()); if (FrameView* frameView = m_mainFrame.view()) frameView->enterCompositingMode(); updateOverlayGeometry(*overlay, rawLayer); if (fadeMode == PageOverlay::FadeMode::Fade) overlay->startFadeInAnimation(); }
void CoordinatedGraphicsLayer::computePixelAlignment(FloatPoint& position, FloatSize& size, FloatPoint3D& anchorPoint, FloatSize& alignmentOffset) { if (isIntegral(effectiveContentsScale())) { position = m_position; size = m_size; anchorPoint = m_anchorPoint; alignmentOffset = FloatSize(); return; } FloatPoint positionRelativeToBase = computePositionRelativeToBase(); FloatRect baseRelativeBounds(positionRelativeToBase, m_size); FloatRect scaledBounds = baseRelativeBounds; // Scale by the effective scale factor to compute the screen-relative bounds. scaledBounds.scale(effectiveContentsScale()); // Round to integer boundaries. // NOTE: When using enclosingIntRect (as mac) it will have different sizes depending on position. FloatRect alignedBounds = enclosingIntRect(scaledBounds); // Convert back to layer coordinates. alignedBounds.scale(1 / effectiveContentsScale()); // Convert back to layer coordinates. alignmentOffset = baseRelativeBounds.location() - alignedBounds.location(); position = m_position - alignmentOffset; size = alignedBounds.size(); // Now we have to compute a new anchor point which compensates for rounding. float anchorPointX = m_anchorPoint.x(); float anchorPointY = m_anchorPoint.y(); if (alignedBounds.width()) anchorPointX = (baseRelativeBounds.width() * anchorPointX + alignmentOffset.width()) / alignedBounds.width(); if (alignedBounds.height()) anchorPointY = (baseRelativeBounds.height() * anchorPointY + alignmentOffset.height()) / alignedBounds.height(); anchorPoint = FloatPoint3D(anchorPointX, anchorPointY, m_anchorPoint.z() * effectiveContentsScale()); }
bool RotateTransformOperation::shareSameAxis(const RotateTransformOperation* from, const RotateTransformOperation* to, FloatPoint3D* axis, double* fromAngle, double* toAngle) { *axis = FloatPoint3D(0, 0, 1); *fromAngle = 0; *toAngle = 0; if (!from && !to) return true; bool fromZero = !from || from->axis().isZero(); bool toZero = !to || to->axis().isZero(); if (fromZero && toZero) return true; if (fromZero) { *axis = to->axis(); *toAngle = to->angle(); return true; } if (toZero) { *axis = from->axis(); *fromAngle = from->angle(); return true; } FloatPoint3D fromAxis = from->axis(); FloatPoint3D toAxis = to->axis(); double fromSquared = fromAxis.lengthSquared(); double toSquared = toAxis.lengthSquared(); double dot = fromAxis.dot(toAxis); double error = std::abs(1 - (dot * dot) / (fromSquared * toSquared)); if (error > angleEpsilon) return false; *axis = from->axis(); *fromAngle = from->angle(); *toAngle = to->angle(); return true; }
void PaintPropertyTreeBuilder::updatePaintOffsetTranslation( const LayoutObject& object, PaintPropertyTreeBuilderContext& context) { if (object.isBoxModelObject() && context.current.paintOffset != LayoutPoint()) { // TODO(trchen): Eliminate PaintLayer dependency. PaintLayer* layer = toLayoutBoxModelObject(object).layer(); if (layer && layer->paintsWithTransform(GlobalPaintNormalPhase)) { // We should use the same subpixel paint offset values for snapping // regardless of whether a transform is present. If there is a transform // we round the paint offset but keep around the residual fractional // component for the transformed content to paint with. In spv1 this was // called "subpixel accumulation". For more information, see // PaintLayer::subpixelAccumulation() and // PaintLayerPainter::paintFragmentByApplyingTransform. IntPoint roundedPaintOffset = roundedIntPoint(context.current.paintOffset); LayoutPoint fractionalPaintOffset = LayoutPoint(context.current.paintOffset - roundedPaintOffset); context.current.transform = object.getMutableForPainting() .ensurePaintProperties() .updatePaintOffsetTranslation( context.current.transform, TransformationMatrix().translate(roundedPaintOffset.x(), roundedPaintOffset.y()), FloatPoint3D(), context.current.shouldFlattenInheritedTransform, context.current.renderingContextID); context.current.paintOffset = fractionalPaintOffset; return; } } if (object.isLayoutView()) return; if (auto* properties = object.getMutableForPainting().paintProperties()) properties->clearPaintOffsetTranslation(); }
WKCACFLayerRenderer::WKCACFLayerRenderer(WKCACFLayerRendererClient* client) : m_client(client) , m_mightBeAbleToCreateDeviceLater(true) , m_rootLayer(PlatformCALayer::create(PlatformCALayer::LayerTypeRootLayer, 0)) , m_context(wkCACFContextCreate()) , m_hostWindow(0) , m_renderTimer(this, &WKCACFLayerRenderer::renderTimerFired) , m_backingStoreDirty(false) , m_mustResetLostDeviceBeforeRendering(false) , m_syncLayerChanges(false) { // Point the CACFContext to this wkCACFContextSetUserData(m_context, this); // Under the root layer, we have a clipping layer to clip the content, // that contains a scroll layer that we use for scrolling the content. // The root layer is the size of the client area of the window. // The clipping layer is the size of the WebView client area (window less the scrollbars). // The scroll layer is the size of the root child layer. // Resizing the window will change the bounds of the rootLayer and the clip layer and will not // cause any repositioning. // Scrolling will affect only the position of the scroll layer without affecting the bounds. m_rootLayer->setName("WKCACFLayerRenderer rootLayer"); m_rootLayer->setAnchorPoint(FloatPoint3D(0, 0, 0)); m_rootLayer->setGeometryFlipped(true); #ifndef NDEBUG CGColorRef debugColor = CGColorCreateGenericRGB(1, 0, 0, 0.8); m_rootLayer->setBackgroundColor(debugColor); CGColorRelease(debugColor); #endif if (m_context) wkCACFContextSetLayer(m_context, m_rootLayer->platformLayer()); #ifndef NDEBUG char* printTreeFlag = getenv("CA_PRINT_TREE"); m_printTree = printTreeFlag && atoi(printTreeFlag); #endif }
void PaintPropertyTreeBuilder::updateScrollAndScrollTranslation( const LayoutObject& object, PaintPropertyTreeBuilderContext& context) { if (object.hasOverflowClip()) { const LayoutBox& box = toLayoutBox(object); const PaintLayerScrollableArea* scrollableArea = box.getScrollableArea(); IntSize scrollOffset = box.scrolledContentOffset(); if (!scrollOffset.isZero() || scrollableArea->scrollsOverflow()) { TransformationMatrix matrix = TransformationMatrix().translate( -scrollOffset.width(), -scrollOffset.height()); context.current.transform = object.getMutableForPainting() .ensurePaintProperties() .updateScrollTranslation( context.current.transform, matrix, FloatPoint3D(), context.current.shouldFlattenInheritedTransform, context.current.renderingContextID); IntSize scrollClip = scrollableArea->visibleContentRect().size(); IntSize scrollBounds = scrollableArea->contentsSize(); bool userScrollableHorizontal = scrollableArea->userInputScrollable(HorizontalScrollbar); bool userScrollableVertical = scrollableArea->userInputScrollable(VerticalScrollbar); context.current.scroll = object.getMutableForPainting().ensurePaintProperties().updateScroll( context.current.scroll, context.current.transform, scrollClip, scrollBounds, userScrollableHorizontal, userScrollableVertical); context.current.shouldFlattenInheritedTransform = false; return; } } if (auto* properties = object.getMutableForPainting().paintProperties()) { properties->clearScrollTranslation(); properties->clearScroll(); } }
void GraphicsLayer::setupContentsLayer(WebLayer* contentsLayer) { ASSERT(contentsLayer); m_contentsLayer = contentsLayer; m_contentsLayerId = m_contentsLayer->id(); m_contentsLayer->setWebLayerClient(this); m_contentsLayer->setTransformOrigin(FloatPoint3D()); m_contentsLayer->setUseParentBackfaceVisibility(true); // It is necessary to call setDrawsContent as soon as we receive the new contentsLayer, for // the correctness of early exit conditions in setDrawsContent() and setContentsVisible(). m_contentsLayer->setDrawsContent(m_contentsVisible); // Insert the content layer first. Video elements require this, because they have // shadow content that must display in front of the video. m_layer->layer()->insertChild(m_contentsLayer, 0); WebLayer* borderWebLayer = m_contentsClippingMaskLayer ? m_contentsClippingMaskLayer->platformLayer() : 0; m_contentsLayer->setMaskLayer(borderWebLayer); m_contentsLayer->setRenderingContext(m_3dRenderingContext); }
static PassRefPtr<TransformPaintPropertyNode> createPaintOffsetTranslationIfNeeded(const LayoutObject& object, PaintPropertyTreeBuilderContext& context) { bool shouldCreatePaintOffsetTranslationNode = false; if (object.isSVGRoot()) { // SVG doesn't use paint offset internally so emit a paint offset at the html->svg boundary. shouldCreatePaintOffsetTranslationNode = true; } else if (object.isBoxModelObject()) { // TODO(trchen): Eliminate PaintLayer dependency. PaintLayer* layer = toLayoutBoxModelObject(object).layer(); shouldCreatePaintOffsetTranslationNode = layer && layer->paintsWithTransform(GlobalPaintNormalPhase); } if (context.paintOffset == LayoutPoint() || !shouldCreatePaintOffsetTranslationNode) return nullptr; RefPtr<TransformPaintPropertyNode> newTransformNodeForPaintOffsetTranslation = TransformPaintPropertyNode::create( TransformationMatrix().translate(context.paintOffset.x(), context.paintOffset.y()), FloatPoint3D(), context.currentTransform); context.currentTransform = newTransformNodeForPaintOffsetTranslation.get(); context.paintOffset = LayoutPoint(); return newTransformNodeForPaintOffsetTranslation.release(); }
// TODO(trchen): Remove this once we bake the paint offset into frameRect. void PaintPropertyTreeBuilder::updateScrollbarPaintOffset( const LayoutObject& object, const PaintPropertyTreeBuilderContext& context) { IntPoint roundedPaintOffset = roundedIntPoint(context.current.paintOffset); if (roundedPaintOffset != IntPoint() && object.isBoxModelObject()) { if (PaintLayerScrollableArea* scrollableArea = toLayoutBoxModelObject(object).getScrollableArea()) { if (scrollableArea->horizontalScrollbar() || scrollableArea->verticalScrollbar()) { auto paintOffset = TransformationMatrix().translate( roundedPaintOffset.x(), roundedPaintOffset.y()); object.getMutableForPainting() .ensurePaintProperties() .updateScrollbarPaintOffset(context.current.transform, paintOffset, FloatPoint3D()); return; } } } if (auto* properties = object.getMutableForPainting().paintProperties()) properties->clearScrollbarPaintOffset(); }
void CACFLayerTreeHost::initialize() { // Point the CACFContext to this initializeContext(this, m_rootLayer.get()); // Under the root layer, we have a clipping layer to clip the content, // that contains a scroll layer that we use for scrolling the content. // The root layer is the size of the client area of the window. // The clipping layer is the size of the WebView client area (window less the scrollbars). // The scroll layer is the size of the root child layer. // Resizing the window will change the bounds of the rootLayer and the clip layer and will not // cause any repositioning. // Scrolling will affect only the position of the scroll layer without affecting the bounds. m_rootLayer->setName("CACFLayerTreeHost rootLayer"); m_rootLayer->setAnchorPoint(FloatPoint3D(0, 0, 0)); m_rootLayer->setGeometryFlipped(true); #ifndef NDEBUG CGColorRef debugColor = CGColorCreateGenericRGB(1, 0, 0, 0.8); m_rootLayer->setBackgroundColor(debugColor); CGColorRelease(debugColor); #endif }
RefPtr<PlatformCALayer> TileController::createTileLayer(const IntRect& tileRect, TileGrid& grid) { RefPtr<PlatformCALayer> layer = m_tileCacheLayer->createCompatibleLayerOrTakeFromPool(PlatformCALayer::LayerTypeTiledBackingTileLayer, &grid, tileRect.size()); layer->setAnchorPoint(FloatPoint3D()); layer->setPosition(tileRect.location()); layer->setBorderColor(m_tileDebugBorderColor); layer->setBorderWidth(m_tileDebugBorderWidth); layer->setEdgeAntialiasingMask(0); layer->setOpaque(m_tilesAreOpaque); #ifndef NDEBUG layer->setName("Tile"); #endif float temporaryScaleFactor = owningGraphicsLayer()->platformCALayerContentsScaleMultiplierForNewTiles(m_tileCacheLayer); m_hasTilesWithTemporaryScaleFactor |= temporaryScaleFactor != 1; layer->setContentsScale(m_deviceScaleFactor * temporaryScaleFactor); layer->setAcceleratesDrawing(m_acceleratesDrawing); layer->setNeedsDisplay(); return layer; }