Example #1
0
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);
}
Example #2
0
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)));
}
Example #5
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();
}
Example #7
0
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());
}
Example #13
0
// 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());
}
Example #18
0
// 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));
}
Example #20
0
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();
}
Example #24
0
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();
  }
}
Example #26
0
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;
}