mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1019996 - Apply overscroll effect to fixed and sticky layers. r=kats, r=Cwiiis
This commit is contained in:
parent
3f3c080e26
commit
6d1e6271e0
@ -1974,8 +1974,8 @@ bool AsyncPanZoomController::UpdateAnimation(const TimeStamp& aSampleTime,
|
||||
return false;
|
||||
}
|
||||
|
||||
void AsyncPanZoomController::ApplyOverscrollEffect(ViewTransform* aTransform) const {
|
||||
// The overscroll effect applied here is a combination of a translation in
|
||||
void AsyncPanZoomController::GetOverscrollTransform(ViewTransform* aTransform) const {
|
||||
// The overscroll effect is a combination of a translation in
|
||||
// the direction of overscroll, and shrinking in both directions.
|
||||
// With the effect applied, we can think of the composited region as being
|
||||
// made up of the following subregions.
|
||||
@ -2066,8 +2066,9 @@ void AsyncPanZoomController::ApplyOverscrollEffect(ViewTransform* aTransform) co
|
||||
}
|
||||
|
||||
bool AsyncPanZoomController::SampleContentTransformForFrame(const TimeStamp& aSampleTime,
|
||||
ViewTransform* aNewTransform,
|
||||
ScreenPoint& aScrollOffset) {
|
||||
ViewTransform* aOutTransform,
|
||||
ScreenPoint& aScrollOffset,
|
||||
ViewTransform* aOutOverscrollTransform) {
|
||||
// The eventual return value of this function. The compositor needs to know
|
||||
// whether or not to advance by a frame as soon as it can. For example, if a
|
||||
// fling is happening, it has to keep compositing so that the animation is
|
||||
@ -2082,12 +2083,22 @@ bool AsyncPanZoomController::SampleContentTransformForFrame(const TimeStamp& aSa
|
||||
requestAnimationFrame = UpdateAnimation(aSampleTime, &deferredTasks);
|
||||
|
||||
aScrollOffset = mFrameMetrics.GetScrollOffset() * mFrameMetrics.GetZoom();
|
||||
*aNewTransform = GetCurrentAsyncTransform();
|
||||
*aOutTransform = GetCurrentAsyncTransform();
|
||||
|
||||
if (IsOverscrolled()) {
|
||||
// GetCurrentAsyncTransform() does not consider any overscroll we may have.
|
||||
// Adjust the transform to account for that.
|
||||
ApplyOverscrollEffect(aNewTransform);
|
||||
// If we are overscrolled, we would like the compositor to apply an
|
||||
// additional transform that produces an overscroll effect.
|
||||
if (aOutOverscrollTransform && IsOverscrolled()) {
|
||||
GetOverscrollTransform(aOutOverscrollTransform);
|
||||
|
||||
// Since the caller will apply aOverscrollTransform after aNewTransform,
|
||||
// aOverscrollTransform's translation will be not be scaled by
|
||||
// aNewTransform's scale. Since the resulting transform is then
|
||||
// multiplied by the CSS transform, which cancels out the non-transient
|
||||
// part of aNewTransform->mScale, this results in an overscroll
|
||||
// translation whose magnitude varies with the zoom. To avoid this,
|
||||
// we adjust for that here.
|
||||
aOutOverscrollTransform->mTranslation.x *= aOutTransform->mScale.scale;
|
||||
aOutOverscrollTransform->mTranslation.y *= aOutTransform->mScale.scale;
|
||||
}
|
||||
|
||||
LogRendertraceRect(GetGuid(), "viewport", "red",
|
||||
|
@ -154,21 +154,26 @@ public:
|
||||
Vector<Task*>* aOutDeferredTasks);
|
||||
|
||||
/**
|
||||
* The compositor calls this when it's about to draw pannable/zoomable content
|
||||
* and is setting up transforms for compositing the layer tree. This is not
|
||||
* idempotent. For example, a fling transform can be applied each time this is
|
||||
* called (though not necessarily). |aSampleTime| is the time that this is
|
||||
* sampled at; this is used for interpolating animations. Calling this sets a
|
||||
* new transform in |aNewTransform| which should be multiplied to the transform
|
||||
* in the shadow layer corresponding to this APZC.
|
||||
* RQuery the transforms that should be applied to the layer corresponding
|
||||
* to this APZC due to asynchronous panning and zooming.
|
||||
* |aSampleTime| is the time that this is sampled at; this is used for
|
||||
* interpolating animations.
|
||||
* This function returns two transforms via out parameters:
|
||||
* |aOutTransform| is the transform due to regular panning and zooming
|
||||
* |aOverscrollTransform| is the transform due to overscrolling
|
||||
* The two are separated because some clients want to ignore the overscroll
|
||||
* transform for some purposes (and for convenience to these clients, the
|
||||
* overscroll transform parameter may be nullptr). Clients who do not want
|
||||
* to ignore the overscroll transform should multiply the two transforms
|
||||
* together.
|
||||
*
|
||||
* Return value indicates whether or not any currently running animation
|
||||
* should continue. That is, if true, the compositor should schedule another
|
||||
* composite.
|
||||
* The return value indicates whether or not any currently running animation
|
||||
* should continue. If true, the compositor should schedule another composite.
|
||||
*/
|
||||
bool SampleContentTransformForFrame(const TimeStamp& aSampleTime,
|
||||
ViewTransform* aNewTransform,
|
||||
ScreenPoint& aScrollOffset);
|
||||
ViewTransform* aOutTransform,
|
||||
ScreenPoint& aScrollOffset,
|
||||
ViewTransform* aOutOverscrollTransform = nullptr);
|
||||
|
||||
/**
|
||||
* A shadow layer update has arrived. |aLayerMetrics| is the new FrameMetrics
|
||||
@ -643,10 +648,10 @@ private:
|
||||
bool IsPanningState(PanZoomState mState);
|
||||
|
||||
/**
|
||||
* Apply to |aTransform| a visual effect that reflects this apzc's
|
||||
* Return in |aTransform| a visual effect that reflects this apzc's
|
||||
* overscrolled state, if any.
|
||||
*/
|
||||
void ApplyOverscrollEffect(ViewTransform* aTransform) const;
|
||||
void GetOverscrollTransform(ViewTransform* aTransform) const;
|
||||
|
||||
enum AxisLockMode {
|
||||
FREE, /* No locking at all */
|
||||
|
@ -239,6 +239,7 @@ void
|
||||
AsyncCompositionManager::AlignFixedAndStickyLayers(Layer* aLayer,
|
||||
Layer* aTransformedSubtreeRoot,
|
||||
const Matrix4x4& aPreviousTransformForRoot,
|
||||
const Matrix4x4& aCurrentTransformForRoot,
|
||||
const LayerMargin& aFixedLayerMargins)
|
||||
{
|
||||
bool isRootFixed = aLayer->GetIsFixedPosition() &&
|
||||
@ -262,7 +263,7 @@ AsyncCompositionManager::AlignFixedAndStickyLayers(Layer* aLayer,
|
||||
Matrix oldRootTransform;
|
||||
Matrix newRootTransform;
|
||||
if (!aPreviousTransformForRoot.Is2D(&oldRootTransform) ||
|
||||
!aTransformedSubtreeRoot->GetLocalTransform().Is2D(&newRootTransform)) {
|
||||
!aCurrentTransformForRoot.Is2D(&newRootTransform)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -347,7 +348,8 @@ AsyncCompositionManager::AlignFixedAndStickyLayers(Layer* aLayer,
|
||||
for (Layer* child = aLayer->GetFirstChild();
|
||||
child; child = child->GetNextSibling()) {
|
||||
AlignFixedAndStickyLayers(child, aTransformedSubtreeRoot,
|
||||
aPreviousTransformForRoot, aFixedLayerMargins);
|
||||
aPreviousTransformForRoot,
|
||||
aCurrentTransformForRoot, aFixedLayerMargins);
|
||||
}
|
||||
}
|
||||
|
||||
@ -498,6 +500,15 @@ SampleAnimations(Layer* aLayer, TimeStamp aPoint)
|
||||
return activeAnimations;
|
||||
}
|
||||
|
||||
Matrix4x4
|
||||
CombineWithCSSTransform(const gfx3DMatrix& treeTransform, Layer* aLayer)
|
||||
{
|
||||
Matrix4x4 result;
|
||||
ToMatrix4x4(treeTransform, result);
|
||||
result = result * aLayer->GetTransform();
|
||||
return result;
|
||||
}
|
||||
|
||||
bool
|
||||
AsyncCompositionManager::ApplyAsyncContentTransformToTree(TimeStamp aCurrentFrame,
|
||||
Layer *aLayer,
|
||||
@ -519,12 +530,13 @@ AsyncCompositionManager::ApplyAsyncContentTransformToTree(TimeStamp aCurrentFram
|
||||
LayerComposite* layerComposite = aLayer->AsLayerComposite();
|
||||
Matrix4x4 oldTransform = aLayer->GetTransform();
|
||||
|
||||
ViewTransform treeTransform;
|
||||
ViewTransform treeTransformWithoutOverscroll, overscrollTransform;
|
||||
ScreenPoint scrollOffset;
|
||||
*aWantNextFrame |=
|
||||
controller->SampleContentTransformForFrame(aCurrentFrame,
|
||||
&treeTransform,
|
||||
scrollOffset);
|
||||
&treeTransformWithoutOverscroll,
|
||||
scrollOffset,
|
||||
&overscrollTransform);
|
||||
|
||||
const FrameMetrics& metrics = container->GetFrameMetrics();
|
||||
CSSToLayerScale paintScale = metrics.LayersPixelsPerCSSPixel();
|
||||
@ -532,9 +544,9 @@ AsyncCompositionManager::ApplyAsyncContentTransformToTree(TimeStamp aCurrentFram
|
||||
metrics.mDisplayPort : metrics.mCriticalDisplayPort);
|
||||
LayerMargin fixedLayerMargins(0, 0, 0, 0);
|
||||
ScreenPoint offset(0, 0);
|
||||
SyncFrameMetrics(scrollOffset, treeTransform.mScale.scale, metrics.mScrollableRect,
|
||||
mLayersUpdated, displayPort, paintScale,
|
||||
mIsFirstPaint, fixedLayerMargins, offset);
|
||||
SyncFrameMetrics(scrollOffset, treeTransformWithoutOverscroll.mScale.scale,
|
||||
metrics.mScrollableRect, mLayersUpdated, displayPort,
|
||||
paintScale, mIsFirstPaint, fixedLayerMargins, offset);
|
||||
|
||||
mIsFirstPaint = false;
|
||||
mLayersUpdated = false;
|
||||
@ -542,9 +554,8 @@ AsyncCompositionManager::ApplyAsyncContentTransformToTree(TimeStamp aCurrentFram
|
||||
// Apply the render offset
|
||||
mLayerManager->GetCompositor()->SetScreenRenderOffset(offset);
|
||||
|
||||
Matrix4x4 transform;
|
||||
ToMatrix4x4(gfx3DMatrix(treeTransform), transform);
|
||||
transform = transform * aLayer->GetTransform();
|
||||
Matrix4x4 transform = CombineWithCSSTransform(
|
||||
treeTransformWithoutOverscroll * overscrollTransform, aLayer);
|
||||
|
||||
// GetTransform already takes the pre- and post-scale into account. Since we
|
||||
// will apply the pre- and post-scale again when computing the effective
|
||||
@ -564,7 +575,14 @@ AsyncCompositionManager::ApplyAsyncContentTransformToTree(TimeStamp aCurrentFram
|
||||
LayoutDeviceToLayerScale resolution = metrics.mCumulativeResolution;
|
||||
oldTransform.Scale(resolution.scale, resolution.scale, 1);
|
||||
|
||||
AlignFixedAndStickyLayers(aLayer, aLayer, oldTransform, fixedLayerMargins);
|
||||
// For the purpose of aligning fixed and sticky layers, we disregard
|
||||
// the overscroll transform when computing the 'aCurrentTransformForRoot'
|
||||
// parameter. This ensures that the overscroll transform is not unapplied,
|
||||
// and therefore that the visual effect applies to fixed and sticky layers.
|
||||
Matrix4x4 transformWithoutOverscroll = CombineWithCSSTransform(
|
||||
treeTransformWithoutOverscroll, aLayer);
|
||||
AlignFixedAndStickyLayers(aLayer, aLayer, oldTransform,
|
||||
transformWithoutOverscroll, fixedLayerMargins);
|
||||
|
||||
appliedTransform = true;
|
||||
}
|
||||
@ -867,7 +885,8 @@ AsyncCompositionManager::TransformScrollableLayer(Layer* aLayer)
|
||||
|
||||
// Make sure fixed position layers don't move away from their anchor points
|
||||
// when we're asynchronously panning or zooming
|
||||
AlignFixedAndStickyLayers(aLayer, aLayer, oldTransform, fixedLayerMargins);
|
||||
AlignFixedAndStickyLayers(aLayer, aLayer, oldTransform,
|
||||
aLayer->GetLocalTransform(), fixedLayerMargins);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -41,6 +41,12 @@ struct ViewTransform {
|
||||
gfx3DMatrix::ScalingMatrix(mScale.scale, mScale.scale, 1);
|
||||
}
|
||||
|
||||
// For convenience, to avoid writing the cumbersome
|
||||
// "gfx3dMatrix(a) * gfx3DMatrix(b)".
|
||||
friend gfx3DMatrix operator*(const ViewTransform& a, const ViewTransform& b) {
|
||||
return gfx3DMatrix(a) * gfx3DMatrix(b);
|
||||
}
|
||||
|
||||
bool operator==(const ViewTransform& rhs) const {
|
||||
return mTranslation == rhs.mTranslation && mScale == rhs.mScale;
|
||||
}
|
||||
@ -155,14 +161,18 @@ private:
|
||||
* aTransformedSubtreeRoot. The translation is chosen so that the layer's
|
||||
* anchor point relative to aTransformedSubtreeRoot's parent layer is the same
|
||||
* as it was when aTransformedSubtreeRoot's GetLocalTransform() was
|
||||
* aPreviousTransformForRoot. For sticky position layers, the translation is
|
||||
* further intersected with the layer's sticky scroll ranges.
|
||||
* aPreviousTransformForRoot. aCurrentTransformForRoot is
|
||||
* aTransformedSubtreeRoot's current GetLocalTransform() modulo any
|
||||
* overscroll-related transform, which we don't want to adjust for.
|
||||
* For sticky position layers, the translation is further intersected with
|
||||
* the layer's sticky scroll ranges.
|
||||
* This function will also adjust layers so that the given content document
|
||||
* fixed position margins will be respected during asynchronous panning and
|
||||
* zooming.
|
||||
*/
|
||||
void AlignFixedAndStickyLayers(Layer* aLayer, Layer* aTransformedSubtreeRoot,
|
||||
const gfx::Matrix4x4& aPreviousTransformForRoot,
|
||||
const gfx::Matrix4x4& aCurrentTransformForRoot,
|
||||
const LayerMargin& aFixedLayerMargins);
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user