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); }
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); }