зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1148582 - Apply async transforms to (ancestor) mask layers correctly. r=botond
This commit is contained in:
Родитель
833a90534d
Коммит
eae17dff97
|
@ -57,7 +57,7 @@ void ImageLayer::ComputeEffectiveTransforms(const gfx::Matrix4x4& aTransformToSu
|
|||
mEffectiveTransformForBuffer = mEffectiveTransform;
|
||||
}
|
||||
|
||||
ComputeEffectiveTransformForMaskLayer(aTransformToSurface);
|
||||
ComputeEffectiveTransformForMaskLayers(aTransformToSurface);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -857,21 +857,31 @@ Layer::DeprecatedGetEffectiveMixBlendMode()
|
|||
}
|
||||
|
||||
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
|
||||
|
@ -1236,9 +1246,9 @@ ContainerLayer::DefaultComputeEffectiveTransforms(const Matrix4x4& aTransformToS
|
|||
}
|
||||
|
||||
if (idealTransform.CanDraw2D()) {
|
||||
ComputeEffectiveTransformForMaskLayer(aTransformToSurface);
|
||||
ComputeEffectiveTransformForMaskLayers(aTransformToSurface);
|
||||
} else {
|
||||
ComputeEffectiveTransformForMaskLayer(Matrix4x4());
|
||||
ComputeEffectiveTransformForMaskLayers(Matrix4x4());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1514,9 +1514,11 @@ public:
|
|||
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.
|
||||
|
@ -1832,7 +1834,7 @@ public:
|
|||
"Residual translation out of range");
|
||||
mValidRegion.SetEmpty();
|
||||
}
|
||||
ComputeEffectiveTransformForMaskLayer(aTransformToSurface);
|
||||
ComputeEffectiveTransformForMaskLayers(aTransformToSurface);
|
||||
}
|
||||
|
||||
LayerManager::PaintedLayerCreationHint GetCreationHint() const { return mCreationHint; }
|
||||
|
@ -2143,7 +2145,7 @@ public:
|
|||
{
|
||||
gfx::Matrix4x4 idealTransform = GetLocalTransform() * aTransformToSurface;
|
||||
mEffectiveTransform = SnapTransformTranslation(idealTransform, nullptr);
|
||||
ComputeEffectiveTransformForMaskLayer(aTransformToSurface);
|
||||
ComputeEffectiveTransformForMaskLayers(aTransformToSurface);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
@ -2295,7 +2297,7 @@ public:
|
|||
SnapTransform(GetLocalTransform(), gfxRect(0, 0, mBounds.width, mBounds.height),
|
||||
nullptr)*
|
||||
SnapTransformTranslation(aTransformToSurface, nullptr);
|
||||
ComputeEffectiveTransformForMaskLayer(aTransformToSurface);
|
||||
ComputeEffectiveTransformForMaskLayers(aTransformToSurface);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
|
|
@ -44,7 +44,7 @@ BasicContainerLayer::ComputeEffectiveTransforms(const Matrix4x4& aTransformToSur
|
|||
if (!idealTransform.CanDraw2D()) {
|
||||
mEffectiveTransform = idealTransform;
|
||||
ComputeEffectiveTransformsForChildren(Matrix4x4());
|
||||
ComputeEffectiveTransformForMaskLayer(Matrix4x4());
|
||||
ComputeEffectiveTransformForMaskLayers(Matrix4x4());
|
||||
mUseIntermediateSurface = true;
|
||||
return;
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ BasicContainerLayer::ComputeEffectiveTransforms(const Matrix4x4& aTransformToSur
|
|||
// need to apply any compensation using the residual from SnapTransformTranslation.
|
||||
ComputeEffectiveTransformsForChildren(idealTransform);
|
||||
|
||||
ComputeEffectiveTransformForMaskLayer(aTransformToSurface);
|
||||
ComputeEffectiveTransformForMaskLayers(aTransformToSurface);
|
||||
|
||||
Layer* child = GetFirstChild();
|
||||
bool hasSingleBlendingChild = false;
|
||||
|
|
|
@ -86,7 +86,7 @@ public:
|
|||
mResidualTranslation = gfxPoint(0,0);
|
||||
mValidRegion.SetEmpty();
|
||||
}
|
||||
ComputeEffectiveTransformForMaskLayer(aTransformToSurface);
|
||||
ComputeEffectiveTransformForMaskLayers(aTransformToSurface);
|
||||
return;
|
||||
}
|
||||
PaintedLayer::ComputeEffectiveTransforms(aTransformToSurface);
|
||||
|
|
|
@ -614,6 +614,18 @@ AsyncCompositionManager::ApplyAsyncContentTransformToTree(Layer *aLayer)
|
|||
// 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) {
|
||||
|
@ -676,6 +688,21 @@ AsyncCompositionManager::ApplyAsyncContentTransformToTree(Layer *aLayer)
|
|||
}
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
@ -692,6 +719,12 @@ AsyncCompositionManager::ApplyAsyncContentTransformToTree(Layer *aLayer)
|
|||
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
|
||||
|
||||
|
|
|
@ -143,7 +143,7 @@ ImageLayerComposite::ComputeEffectiveTransforms(const gfx::Matrix4x4& aTransform
|
|||
mEffectiveTransformForBuffer = mEffectiveTransform;
|
||||
}
|
||||
|
||||
ComputeEffectiveTransformForMaskLayer(aTransformToSurface);
|
||||
ComputeEffectiveTransformForMaskLayers(aTransformToSurface);
|
||||
}
|
||||
|
||||
CompositableHost*
|
||||
|
|
Загрузка…
Ссылка в новой задаче