mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 818575 - Make TransformShadowTree transform all descendant scrollable layers instead of just the first. r=roc
This commit is contained in:
parent
53e782ed8e
commit
7f172bf755
@ -230,6 +230,36 @@ LayerManager::GetPrimaryScrollableLayer()
|
||||
return mRoot;
|
||||
}
|
||||
|
||||
void
|
||||
LayerManager::GetScrollableLayers(nsTArray<Layer*>& aArray)
|
||||
{
|
||||
if (!mRoot) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsTArray<Layer*> queue;
|
||||
queue.AppendElement(mRoot);
|
||||
while (!queue.IsEmpty()) {
|
||||
ContainerLayer* containerLayer = queue.LastElement()->AsContainerLayer();
|
||||
queue.RemoveElementAt(queue.Length() - 1);
|
||||
if (!containerLayer) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const FrameMetrics& frameMetrics = containerLayer->GetFrameMetrics();
|
||||
if (frameMetrics.IsScrollable()) {
|
||||
aArray.AppendElement(containerLayer);
|
||||
continue;
|
||||
}
|
||||
|
||||
Layer* child = containerLayer->GetFirstChild();
|
||||
while (child) {
|
||||
queue.AppendElement(child);
|
||||
child = child->GetNextSibling();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
already_AddRefed<gfxASurface>
|
||||
LayerManager::CreateOptimalSurface(const gfxIntSize &aSize,
|
||||
gfxASurface::gfxImageFormat aFormat)
|
||||
|
@ -287,6 +287,12 @@ public:
|
||||
*/
|
||||
Layer* GetPrimaryScrollableLayer();
|
||||
|
||||
/**
|
||||
* Returns a list of all descendant layers for which
|
||||
* GetFrameMetrics().IsScrollable() is true.
|
||||
*/
|
||||
void GetScrollableLayers(nsTArray<Layer*>& aArray);
|
||||
|
||||
/**
|
||||
* CONSTRUCTION PHASE ONLY
|
||||
* Called when a managee has mutated.
|
||||
|
@ -892,37 +892,17 @@ CompositorParent::ApplyAsyncContentTransformToTree(TimeStamp aCurrentFrame,
|
||||
return appliedTransform;
|
||||
}
|
||||
|
||||
bool
|
||||
CompositorParent::TransformShadowTree(TimeStamp aCurrentFrame)
|
||||
void
|
||||
CompositorParent::TransformScrollableLayer(Layer* aLayer, const gfx3DMatrix& aRootTransform)
|
||||
{
|
||||
bool wantNextFrame = false;
|
||||
Layer* layer = mLayerManager->GetPrimaryScrollableLayer();
|
||||
ShadowLayer* shadow = layer->AsShadowLayer();
|
||||
ContainerLayer* container = layer->AsContainerLayer();
|
||||
Layer* root = mLayerManager->GetRoot();
|
||||
|
||||
// NB: we must sample animations *before* sampling pan/zoom
|
||||
// transforms.
|
||||
wantNextFrame |= SampleAnimations(root, aCurrentFrame);
|
||||
ShadowLayer* shadow = aLayer->AsShadowLayer();
|
||||
ContainerLayer* container = aLayer->AsContainerLayer();
|
||||
|
||||
const FrameMetrics& metrics = container->GetFrameMetrics();
|
||||
// We must apply the resolution scale before a pan/zoom transform, so we call
|
||||
// GetTransform here.
|
||||
const gfx3DMatrix& rootTransform = root->GetTransform();
|
||||
const gfx3DMatrix& currentTransform = layer->GetTransform();
|
||||
const gfx3DMatrix& currentTransform = aLayer->GetTransform();
|
||||
|
||||
// FIXME/bug 775437: unify this interface with the ~native-fennec
|
||||
// derived code
|
||||
//
|
||||
// Attempt to apply an async content transform to any layer that has
|
||||
// an async pan zoom controller (which means that it is rendered
|
||||
// async using Gecko). If this fails, fall back to transforming the
|
||||
// primary scrollable layer. "Failing" here means that we don't
|
||||
// find a frame that is async scrollable. Note that the fallback
|
||||
// code also includes Fennec which is rendered async. Fennec uses
|
||||
// its own platform-specific async rendering that is done partially
|
||||
// in Gecko and partially in Java.
|
||||
if (!ApplyAsyncContentTransformToTree(aCurrentFrame, root, &wantNextFrame)) {
|
||||
gfx3DMatrix treeTransform;
|
||||
|
||||
// Translate fixed position layers so that they stay in the correct position
|
||||
@ -930,8 +910,8 @@ CompositorParent::TransformShadowTree(TimeStamp aCurrentFrame)
|
||||
gfxPoint offset;
|
||||
gfxSize scaleDiff;
|
||||
|
||||
float rootScaleX = rootTransform.GetXScale(),
|
||||
rootScaleY = rootTransform.GetYScale();
|
||||
float rootScaleX = aRootTransform.GetXScale(),
|
||||
rootScaleY = aRootTransform.GetYScale();
|
||||
// The ratio of layers pixels to device pixels. The Java
|
||||
// compositor wants to see values in units of device pixels, so we
|
||||
// map our FrameMetrics values to that space. This is not exposed
|
||||
@ -998,22 +978,22 @@ CompositorParent::TransformShadowTree(TimeStamp aCurrentFrame)
|
||||
// within the page boundaries.
|
||||
if (mContentRect.width * tempScaleDiffX < mWidgetSize.width) {
|
||||
offset.x = -metricsScrollOffset.x;
|
||||
scaleDiff.height = NS_MIN(1.0f, mWidgetSize.width / (float)mContentRect.width);
|
||||
scaleDiff.width = NS_MIN(1.0f, mWidgetSize.width / (float)mContentRect.width);
|
||||
} else {
|
||||
offset.x = clamped(mScrollOffset.x / tempScaleDiffX, (float)mContentRect.x,
|
||||
mContentRect.XMost() - mWidgetSize.width / tempScaleDiffX) -
|
||||
metricsScrollOffset.x;
|
||||
scaleDiff.height = tempScaleDiffX;
|
||||
scaleDiff.width = tempScaleDiffX;
|
||||
}
|
||||
|
||||
if (mContentRect.height * tempScaleDiffY < mWidgetSize.height) {
|
||||
offset.y = -metricsScrollOffset.y;
|
||||
scaleDiff.width = NS_MIN(1.0f, mWidgetSize.height / (float)mContentRect.height);
|
||||
scaleDiff.height = NS_MIN(1.0f, mWidgetSize.height / (float)mContentRect.height);
|
||||
} else {
|
||||
offset.y = clamped(mScrollOffset.y / tempScaleDiffY, (float)mContentRect.y,
|
||||
mContentRect.YMost() - mWidgetSize.height / tempScaleDiffY) -
|
||||
metricsScrollOffset.y;
|
||||
scaleDiff.width = tempScaleDiffY;
|
||||
scaleDiff.height = tempScaleDiffY;
|
||||
}
|
||||
|
||||
// The transform already takes the resolution scale into account. Since we
|
||||
@ -1027,7 +1007,39 @@ CompositorParent::TransformShadowTree(TimeStamp aCurrentFrame)
|
||||
1.0f/container->GetPostYScale(),
|
||||
1);
|
||||
shadow->SetShadowTransform(computedTransform);
|
||||
TransformFixedLayers(layer, offset, scaleDiff);
|
||||
TransformFixedLayers(aLayer, offset, scaleDiff);
|
||||
}
|
||||
|
||||
bool
|
||||
CompositorParent::TransformShadowTree(TimeStamp aCurrentFrame)
|
||||
{
|
||||
bool wantNextFrame = false;
|
||||
Layer* root = mLayerManager->GetRoot();
|
||||
|
||||
// NB: we must sample animations *before* sampling pan/zoom
|
||||
// transforms.
|
||||
wantNextFrame |= SampleAnimations(root, aCurrentFrame);
|
||||
|
||||
const gfx3DMatrix& rootTransform = root->GetTransform();
|
||||
|
||||
// FIXME/bug 775437: unify this interface with the ~native-fennec
|
||||
// derived code
|
||||
//
|
||||
// Attempt to apply an async content transform to any layer that has
|
||||
// an async pan zoom controller (which means that it is rendered
|
||||
// async using Gecko). If this fails, fall back to transforming the
|
||||
// primary scrollable layer. "Failing" here means that we don't
|
||||
// find a frame that is async scrollable. Note that the fallback
|
||||
// code also includes Fennec which is rendered async. Fennec uses
|
||||
// its own platform-specific async rendering that is done partially
|
||||
// in Gecko and partially in Java.
|
||||
if (!ApplyAsyncContentTransformToTree(aCurrentFrame, root, &wantNextFrame)) {
|
||||
nsAutoTArray<Layer*,1> scrollableLayers;
|
||||
mLayerManager->GetScrollableLayers(scrollableLayers);
|
||||
|
||||
for (uint32_t i = 0; i < scrollableLayers.Length(); i++) {
|
||||
TransformScrollableLayer(scrollableLayers[i], rootTransform);
|
||||
}
|
||||
}
|
||||
|
||||
return wantNextFrame;
|
||||
|
@ -185,6 +185,7 @@ private:
|
||||
// Sample transforms for layer trees. Return true to request
|
||||
// another animation frame.
|
||||
bool TransformShadowTree(TimeStamp aCurrentFrame);
|
||||
void TransformScrollableLayer(Layer* aLayer, const gfx3DMatrix& aRootTransform);
|
||||
// Return true if an AsyncPanZoomController content transform was
|
||||
// applied for |aLayer|. *aWantNextFrame is set to true if the
|
||||
// controller wants another animation frame.
|
||||
|
Loading…
Reference in New Issue
Block a user