author | David Anderson <danderson@mozilla.com> |
Tue, 30 Jun 2015 21:07:09 -0400 | |
changeset 250839 | 6234e37d912a054e8c07259c4dca19ce4c062055 |
parent 250838 | be49031960aa935f2f0d6fa594251c9e1fa12536 |
child 250840 | aff9ea7ce4fe01d4737aa6c6c059567cdbc6ba06 |
push id | 61681 |
push user | mstange@themasta.com |
push date | Wed, 01 Jul 2015 04:52:34 +0000 |
treeherder | mozilla-inbound@4a28b2cb9562 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | botond |
bugs | 1148582 |
milestone | 42.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/gfx/layers/ImageLayers.cpp +++ b/gfx/layers/ImageLayers.cpp @@ -52,13 +52,13 @@ void ImageLayer::ComputeEffectiveTransfo mEffectiveTransformForBuffer = SnapTransform(local, sourceRect, nullptr) * SnapTransformTranslation(aTransformToSurface, nullptr); } else { mEffectiveTransformForBuffer = mEffectiveTransform; } - ComputeEffectiveTransformForMaskLayer(aTransformToSurface); + ComputeEffectiveTransformForMaskLayers(aTransformToSurface); } } }
--- a/gfx/layers/Layers.cpp +++ b/gfx/layers/Layers.cpp @@ -852,31 +852,41 @@ Layer::GetEffectiveMixBlendMode() gfxContext::GraphicsOperator Layer::DeprecatedGetEffectiveMixBlendMode() { return ThebesOp(GetEffectiveMixBlendMode()); } void -Layer::ComputeEffectiveTransformForMaskLayer(const Matrix4x4& aTransformToSurface) +Layer::ComputeEffectiveTransformForMaskLayers(const gfx::Matrix4x4& aTransformToSurface) { - if (mMaskLayer) { - mMaskLayer->mEffectiveTransform = aTransformToSurface; + if (GetMaskLayer()) { + ComputeEffectiveTransformForMaskLayer(GetMaskLayer(), aTransformToSurface); + } + for (size_t i = 0; i < GetAncestorMaskLayerCount(); i++) { + Layer* maskLayer = GetAncestorMaskLayerAt(i); + ComputeEffectiveTransformForMaskLayer(maskLayer, aTransformToSurface); + } +} + +/* static */ void +Layer::ComputeEffectiveTransformForMaskLayer(Layer* aMaskLayer, const gfx::Matrix4x4& aTransformToSurface) +{ + aMaskLayer->mEffectiveTransform = aTransformToSurface; #ifdef DEBUG - bool maskIs2D = mMaskLayer->GetTransform().CanDraw2D(); - NS_ASSERTION(maskIs2D, "How did we end up with a 3D transform here?!"); + bool maskIs2D = aMaskLayer->GetTransform().CanDraw2D(); + NS_ASSERTION(maskIs2D, "How did we end up with a 3D transform here?!"); #endif - // The mask layer can have an async transform applied to it in some - // situations, so be sure to use its GetLocalTransform() rather than - // its GetTransform(). - mMaskLayer->mEffectiveTransform = mMaskLayer->GetLocalTransform() * - mMaskLayer->mEffectiveTransform; - } + // The mask layer can have an async transform applied to it in some + // situations, so be sure to use its GetLocalTransform() rather than + // its GetTransform(). + aMaskLayer->mEffectiveTransform = aMaskLayer->GetLocalTransform() * + aMaskLayer->mEffectiveTransform; } RenderTargetRect Layer::TransformRectToRenderTarget(const LayerIntRect& aRect) { LayerRect rect(aRect); RenderTargetRect quad = RenderTargetRect::FromUnknown( GetEffectiveTransform().TransformBounds( @@ -1231,19 +1241,19 @@ ContainerLayer::DefaultComputeEffectiveT mUseIntermediateSurface = useIntermediateSurface && !GetEffectiveVisibleRegion().IsEmpty(); if (useIntermediateSurface) { ComputeEffectiveTransformsForChildren(Matrix4x4::From2D(residual)); } else { ComputeEffectiveTransformsForChildren(idealTransform); } if (idealTransform.CanDraw2D()) { - ComputeEffectiveTransformForMaskLayer(aTransformToSurface); + ComputeEffectiveTransformForMaskLayers(aTransformToSurface); } else { - ComputeEffectiveTransformForMaskLayer(Matrix4x4()); + ComputeEffectiveTransformForMaskLayers(Matrix4x4()); } } void ContainerLayer::DefaultComputeSupportsComponentAlphaChildren(bool* aNeedsSurfaceCopy) { if (!(GetContentFlags() & Layer::CONTENT_COMPONENT_ALPHA_DESCENDANT) || !Manager()->AreComponentAlphaLayersEnabled()) {
--- a/gfx/layers/Layers.h +++ b/gfx/layers/Layers.h @@ -1509,19 +1509,21 @@ public: * pixel grid (whatever aTransformToSurface is relative to). * * We promise that when this is called on a layer, all ancestor layers * have already had ComputeEffectiveTransforms called. */ virtual void ComputeEffectiveTransforms(const gfx::Matrix4x4& aTransformToSurface) = 0; /** - * computes the effective transform for a mask layer, if this layer has one + * Computes the effective transform for mask layers, if this layer has any. */ - void ComputeEffectiveTransformForMaskLayer(const gfx::Matrix4x4& aTransformToSurface); + void ComputeEffectiveTransformForMaskLayers(const gfx::Matrix4x4& aTransformToSurface); + static void ComputeEffectiveTransformForMaskLayer(Layer* aMaskLayer, + const gfx::Matrix4x4& aTransformToSurface); /** * Calculate the scissor rect required when rendering this layer. * Returns a rectangle relative to the intermediate surface belonging to the * nearest ancestor that has an intermediate surface, or relative to the root * viewport if no ancestor has an intermediate surface, corresponding to the * clip rect for this layer intersected with aCurrentScissorRect. */ @@ -1827,17 +1829,17 @@ public: "Residual transform can only be a translation"); if (!gfx::ThebesPoint(residual.GetTranslation()).WithinEpsilonOf(mResidualTranslation, 1e-3f)) { mResidualTranslation = gfx::ThebesPoint(residual.GetTranslation()); NS_ASSERTION(-0.5 <= mResidualTranslation.x && mResidualTranslation.x < 0.5 && -0.5 <= mResidualTranslation.y && mResidualTranslation.y < 0.5, "Residual translation out of range"); mValidRegion.SetEmpty(); } - ComputeEffectiveTransformForMaskLayer(aTransformToSurface); + ComputeEffectiveTransformForMaskLayers(aTransformToSurface); } LayerManager::PaintedLayerCreationHint GetCreationHint() const { return mCreationHint; } bool UsedForReadback() { return mUsedForReadback; } void SetUsedForReadback(bool aUsed) { mUsedForReadback = aUsed; } /** * Returns the residual translation. Apply this translation when drawing @@ -2138,17 +2140,17 @@ public: virtual const gfxRGBA& GetColor() { return mColor; } MOZ_LAYER_DECL_NAME("ColorLayer", TYPE_COLOR) virtual void ComputeEffectiveTransforms(const gfx::Matrix4x4& aTransformToSurface) override { gfx::Matrix4x4 idealTransform = GetLocalTransform() * aTransformToSurface; mEffectiveTransform = SnapTransformTranslation(idealTransform, nullptr); - ComputeEffectiveTransformForMaskLayer(aTransformToSurface); + ComputeEffectiveTransformForMaskLayers(aTransformToSurface); } protected: ColorLayer(LayerManager* aManager, void* aImplData) : Layer(aManager, aImplData), mColor(0.0, 0.0, 0.0, 0.0) {} @@ -2290,17 +2292,17 @@ public: // 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(GetLocalTransform(), gfxRect(0, 0, mBounds.width, mBounds.height), nullptr)* SnapTransformTranslation(aTransformToSurface, nullptr); - ComputeEffectiveTransformForMaskLayer(aTransformToSurface); + ComputeEffectiveTransformForMaskLayers(aTransformToSurface); } protected: CanvasLayer(LayerManager* aManager, void* aImplData) : Layer(aManager, aImplData) , mPreTransCallback(nullptr) , mPreTransCallbackData(nullptr) , mPostTransCallback(nullptr)
--- a/gfx/layers/basic/BasicContainerLayer.cpp +++ b/gfx/layers/basic/BasicContainerLayer.cpp @@ -39,27 +39,27 @@ BasicContainerLayer::ComputeEffectiveTra // containers. Matrix residual; Matrix4x4 idealTransform = GetLocalTransform() * aTransformToSurface; idealTransform.ProjectTo2D(); if (!idealTransform.CanDraw2D()) { mEffectiveTransform = idealTransform; ComputeEffectiveTransformsForChildren(Matrix4x4()); - ComputeEffectiveTransformForMaskLayer(Matrix4x4()); + ComputeEffectiveTransformForMaskLayers(Matrix4x4()); mUseIntermediateSurface = true; return; } mEffectiveTransform = SnapTransformTranslation(idealTransform, &residual); // We always pass the ideal matrix down to our children, so there is no // need to apply any compensation using the residual from SnapTransformTranslation. ComputeEffectiveTransformsForChildren(idealTransform); - ComputeEffectiveTransformForMaskLayer(aTransformToSurface); + ComputeEffectiveTransformForMaskLayers(aTransformToSurface); 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,
--- a/gfx/layers/basic/BasicPaintedLayer.h +++ b/gfx/layers/basic/BasicPaintedLayer.h @@ -81,17 +81,17 @@ public: if (!BasicManager()->IsRetained()) { // Don't do any snapping of our transform, since we're just going to // draw straight through without intermediate buffers. mEffectiveTransform = GetLocalTransform() * aTransformToSurface; if (gfxPoint(0,0) != mResidualTranslation) { mResidualTranslation = gfxPoint(0,0); mValidRegion.SetEmpty(); } - ComputeEffectiveTransformForMaskLayer(aTransformToSurface); + ComputeEffectiveTransformForMaskLayers(aTransformToSurface); return; } PaintedLayer::ComputeEffectiveTransforms(aTransformToSurface); } BasicLayerManager* BasicManager() { return static_cast<BasicLayerManager*>(mManager);
--- a/gfx/layers/composite/AsyncCompositionManager.cpp +++ b/gfx/layers/composite/AsyncCompositionManager.cpp @@ -609,16 +609,28 @@ AsyncCompositionManager::ApplyAsyncConte // Each layer has multiple clips. Its local clip, which must move with async // transforms, and its scrollframe clips, which are the clips between each // scrollframe and its ancestor scrollframe. Scrollframe clips include the // composition bounds and any other clips induced by layout. // // The final clip for the layer is the intersection of these clips. Maybe<ParentLayerIntRect> asyncClip = aLayer->GetClipRect(); + // The transform of a mask layer is relative to the masked layer's parent + // layer. So whenever we apply an async transform to a layer, we need to + // apply that same transform to the layer's own mask layer. + // A layer can also have "ancestor" mask layers for any rounded clips from + // its ancestor scroll frames. A scroll frame mask layer only needs to be + // async transformed for async scrolls of this scroll frame's ancestor + // scroll frames, not for async scrolls of this scroll frame itself. + // In the loop below, we iterate over scroll frames from inside to outside. + // At each iteration, this array contains the layer's ancestor mask layers + // of all scroll frames inside the current one. + nsTArray<Layer*> ancestorMaskLayers; + for (uint32_t i = 0; i < aLayer->GetFrameMetricsCount(); i++) { AsyncPanZoomController* controller = aLayer->GetAsyncPanZoomController(i); if (!controller) { continue; } hasAsyncTransform = true; @@ -671,32 +683,53 @@ AsyncCompositionManager::ApplyAsyncConte ParentLayerIntRect clip = metrics.ClipRect(); if (asyncClip) { asyncClip = Some(clip.Intersect(*asyncClip)); } else { asyncClip = Some(clip); } } + // Do the same for the ancestor mask layers: ancestorMaskLayers contains + // the ancestor mask layers for scroll frames *inside* the current scroll + // frame, so these are the ones we need to shift by our async transform. + for (Layer* ancestorMaskLayer : ancestorMaskLayers) { + SetShadowTransform(ancestorMaskLayer, + ancestorMaskLayer->GetLocalTransform() * asyncTransform); + } + + // Append the ancestor mask layer for this scroll frame to ancestorMaskLayers. + if (metrics.GetMaskLayerIndex()) { + size_t maskLayerIndex = metrics.GetMaskLayerIndex().value(); + Layer* ancestorMaskLayer = aLayer->GetAncestorMaskLayerAt(maskLayerIndex); + ancestorMaskLayers.AppendElement(ancestorMaskLayer); + } + combinedAsyncTransformWithoutOverscroll *= asyncTransformWithoutOverscroll; combinedAsyncTransform *= asyncTransform; } if (hasAsyncTransform) { if (asyncClip) { aLayer->AsLayerComposite()->SetShadowClipRect(asyncClip); } // Apply the APZ transform on top of GetLocalTransform() here (rather than // GetTransform()) in case the OMTA code in SampleAnimations already set a // shadow transform; in that case we want to apply ours on top of that one // rather than clobber it. SetShadowTransform(aLayer, aLayer->GetLocalTransform() * AdjustForClip(combinedAsyncTransform, aLayer)); + // Do the same for the layer's own mask layer, if it has one. + if (Layer* maskLayer = aLayer->GetMaskLayer()) { + SetShadowTransform(maskLayer, + maskLayer->GetLocalTransform() * combinedAsyncTransform); + } + const FrameMetrics& bottom = LayerMetricsWrapper::BottommostScrollableMetrics(aLayer); MOZ_ASSERT(bottom.IsScrollable()); // must be true because hasAsyncTransform is true // For the purpose of aligning fixed and sticky layers, we disregard // the overscroll transform as well as any OMTA transform when computing the // 'aCurrentTransformForRoot' parameter. This ensures that the overscroll // and OMTA transforms are not unapplied, and therefore that the visual // effects apply to fixed and sticky layers. We do this by using
--- a/gfx/layers/composite/ImageLayerComposite.cpp +++ b/gfx/layers/composite/ImageLayerComposite.cpp @@ -138,17 +138,17 @@ ImageLayerComposite::ComputeEffectiveTra mEffectiveTransformForBuffer = SnapTransform(local, sourceRect, nullptr) * SnapTransformTranslation(aTransformToSurface, nullptr); } else { mEffectiveTransformForBuffer = mEffectiveTransform; } - ComputeEffectiveTransformForMaskLayer(aTransformToSurface); + ComputeEffectiveTransformForMaskLayers(aTransformToSurface); } CompositableHost* ImageLayerComposite::GetCompositableHost() { if (mImageHost && mImageHost->IsAttached()) { return mImageHost.get(); }