Beispiel #1
0
void
ImageLayerMLGPU::ComputeEffectiveTransforms(const gfx::Matrix4x4& aTransformToSurface)
{
  Matrix4x4 local = GetLocalTransform();

  // Snap image edges to pixel boundaries.
  gfxRect sourceRect(0, 0, 0, 0);
  if (mHost && mHost->IsAttached()) {
    IntSize size = mHost->GetImageSize();
    sourceRect.SizeTo(size.width, size.height);
  }

  // Snap our local transform first, and snap the inherited transform as well.
  // This makes our snapping equivalent to what would happen if our content
  // was drawn into a PaintedLayer (gfxContext would snap using the local
  // transform, then we'd snap again when compositing the PaintedLayer).
  mEffectiveTransform =
      SnapTransform(local, sourceRect, nullptr) *
      SnapTransformTranslation(aTransformToSurface, nullptr);
  mEffectiveTransformForBuffer = mEffectiveTransform;

  if (mScaleMode == ScaleMode::STRETCH &&
      mScaleToSize.width != 0.0 &&
      mScaleToSize.height != 0.0)
  {
    Size scale(sourceRect.Width() / mScaleToSize.width,
               sourceRect.Height() / mScaleToSize.height);
    mScale = Some(scale);
  }

  ComputeEffectiveTransformForMaskLayers(aTransformToSurface);
}
Beispiel #2
0
void ImageLayer::ComputeEffectiveTransforms(const gfx::Matrix4x4& aTransformToSurface)
{
  gfx::Matrix4x4 local = GetLocalTransform();

  // Snap image edges to pixel boundaries
  gfxRect sourceRect(0, 0, 0, 0);
  if (mContainer) {
    sourceRect.SizeTo(mContainer->GetCurrentSize());
  }
  // Snap our local transform first, and snap the inherited transform as well.
  // This makes our snapping equivalent to what would happen if our content
  // was drawn into a PaintedLayer (gfxContext would snap using the local
  // transform, then we'd snap again when compositing the PaintedLayer).
  mEffectiveTransform =
      SnapTransform(local, sourceRect, nullptr) *
      SnapTransformTranslation(aTransformToSurface, nullptr);

  if (mScaleMode != ScaleMode::SCALE_NONE &&
      sourceRect.width != 0.0 && sourceRect.height != 0.0) {
    NS_ASSERTION(mScaleMode == ScaleMode::STRETCH,
                 "No other scalemodes than stretch and none supported yet.");
    local.PreScale(mScaleToSize.width / sourceRect.width,
                   mScaleToSize.height / sourceRect.height, 1.0);

    mEffectiveTransformForBuffer =
        SnapTransform(local, sourceRect, nullptr) *
        SnapTransformTranslation(aTransformToSurface, nullptr);
  } else {
    mEffectiveTransformForBuffer = mEffectiveTransform;
  }

  ComputeEffectiveTransformForMaskLayers(aTransformToSurface);
}
void
BasicContainerLayer::ComputeEffectiveTransforms(const Matrix4x4& aTransformToSurface)
{
  // We push groups for container layers if we need to, which always
  // are aligned in device space, so it doesn't really matter how we snap
  // containers.
  Matrix residual;
  Matrix4x4 idealTransform = GetLocalTransform() * aTransformToSurface;
  if (!Extend3DContext() && !Is3DContextLeaf()) {
    // For 3D transform leaked from extended parent layer.
    idealTransform.ProjectTo2D();
  }

  if (!idealTransform.CanDraw2D()) {
    if (!Extend3DContext() ||
        (!idealTransform.Is2D() && Creates3DContextWithExtendingChildren())) {
      if (!Creates3DContextWithExtendingChildren()) {
        idealTransform.ProjectTo2D();
      }
      mEffectiveTransform = idealTransform;
      ComputeEffectiveTransformsForChildren(Matrix4x4());
      ComputeEffectiveTransformForMaskLayers(Matrix4x4());
      mUseIntermediateSurface = true;
      return;
    }

    mEffectiveTransform = idealTransform;
    ComputeEffectiveTransformsForChildren(idealTransform);
    ComputeEffectiveTransformForMaskLayers(idealTransform);
    mUseIntermediateSurface = false;
    return;
  }

  // With 2D transform or extended 3D context.

  Layer* child = GetFirstChild();
  bool hasSingleBlendingChild = false;
  if (!HasMultipleChildren() && child) {
    hasSingleBlendingChild = child->GetMixBlendMode() != CompositionOp::OP_OVER;
  }

  /* If we have a single childand it is not blending,, it can just inherit our opacity,
   * otherwise we need a PushGroup and we need to mark ourselves as using
   * an intermediate surface so our children don't inherit our opacity
   * via GetEffectiveOpacity.
   * Having a mask layer always forces our own push group
   * Having a blend mode also always forces our own push group
   */
  mUseIntermediateSurface =
    GetMaskLayer() ||
    GetForceIsolatedGroup() ||
    (GetMixBlendMode() != CompositionOp::OP_OVER && HasMultipleChildren()) ||
    (GetEffectiveOpacity() != 1.0 && (HasMultipleChildren() || hasSingleBlendingChild));

  if (!Extend3DContext()) {
    idealTransform.ProjectTo2D();
  }
  mEffectiveTransform =
    !mUseIntermediateSurface ?
    idealTransform : SnapTransformTranslation(idealTransform, &residual);
  Matrix4x4 childTransformToSurface =
    (!mUseIntermediateSurface ||
     (mUseIntermediateSurface && !Extend3DContext() /* 2D */)) ?
    idealTransform : Matrix4x4::From2D(residual);
  ComputeEffectiveTransformsForChildren(childTransformToSurface);

  ComputeEffectiveTransformForMaskLayers(aTransformToSurface);
}