--- a/gfx/layers/apz/src/APZCTreeManager.cpp
+++ b/gfx/layers/apz/src/APZCTreeManager.cpp
@@ -382,17 +382,19 @@ APZCTreeManager::PrepareNodeForLayer(con
if (!(state && state->mController.get())) {
needsApzc = false;
}
RefPtr<HitTestingTreeNode> node = nullptr;
if (!needsApzc) {
node = RecycleOrCreateNode(aState, nullptr, aLayersId);
AttachNodeToTree(node, aParent, aNextSibling);
- node->SetHitTestData(GetEventRegions(aLayer), aLayer.GetTransform(),
+ node->SetHitTestData(
+ GetEventRegions(aLayer),
+ aLayer.GetTransformTyped(),
aLayer.GetClipRect() ? Some(ParentLayerIntRegion(*aLayer.GetClipRect())) : Nothing(),
GetEventRegionsOverride(aParent, aLayer));
node->SetScrollbarData(aLayer.GetScrollbarTargetContainerId(),
aLayer.GetScrollbarDirection(),
aLayer.GetScrollbarSize());
return node;
}
@@ -491,17 +493,20 @@ APZCTreeManager::PrepareNodeForLayer(con
aState.mIsFirstPaint && (aLayersId == aState.mOriginatingLayersId));
// Since this is the first time we are encountering an APZC with this guid,
// the node holding it must be the primary holder. It may be newly-created
// or not, depending on whether it went through the newApzc branch above.
MOZ_ASSERT(node->IsPrimaryHolder() && node->GetApzc() && node->GetApzc()->Matches(guid));
ParentLayerIntRegion clipRegion = ComputeClipRegion(state->mController, aLayer);
- node->SetHitTestData(GetEventRegions(aLayer), aLayer.GetTransform(), Some(clipRegion),
+ node->SetHitTestData(
+ GetEventRegions(aLayer),
+ aLayer.GetTransformTyped(),
+ Some(clipRegion),
GetEventRegionsOverride(aParent, aLayer));
apzc->SetAncestorTransform(aAncestorTransform);
PrintAPZCInfo(aLayer, apzc);
// Bind the APZC instance into the tree of APZCs
AttachNodeToTree(node, aParent, aNextSibling);
@@ -549,17 +554,20 @@ APZCTreeManager::PrepareNodeForLayer(con
// Even though different layers associated with a given APZC may be at
// different levels in the layer tree (e.g. one being an uncle of another),
// we require from Layout that the CSS transforms up to their common
// ancestor be the same.
MOZ_ASSERT(aAncestorTransform == apzc->GetAncestorTransform());
ParentLayerIntRegion clipRegion = ComputeClipRegion(state->mController, aLayer);
- node->SetHitTestData(GetEventRegions(aLayer), aLayer.GetTransform(), Some(clipRegion),
+ node->SetHitTestData(
+ GetEventRegions(aLayer),
+ aLayer.GetTransformTyped(),
+ Some(clipRegion),
GetEventRegionsOverride(aParent, aLayer));
}
node->SetScrollbarData(aLayer.GetScrollbarTargetContainerId(),
aLayer.GetScrollbarDirection(),
aLayer.GetScrollbarSize());
return node;
}
@@ -1867,17 +1875,17 @@ APZCTreeManager::GetScreenToApzcTransfor
// result is initialized to PC.Inverse() * OC.Inverse() * NC.Inverse() * MC.Inverse()
result = ancestorUntransform;
for (AsyncPanZoomController* parent = aApzc->GetParent(); parent; parent = parent->GetParent()) {
// ancestorUntransform is updated to RC.Inverse() * QC.Inverse() when parent == P
ancestorUntransform = parent->GetAncestorTransform().Inverse();
// asyncUntransform is updated to PA.Inverse() when parent == P
- Matrix4x4 asyncUntransform = parent->GetCurrentAsyncTransformWithOverscroll().Inverse();
+ Matrix4x4 asyncUntransform = parent->GetCurrentAsyncTransformWithOverscroll().Inverse().ToUnknownMatrix();
// untransformSinceLastApzc is RC.Inverse() * QC.Inverse() * PA.Inverse()
Matrix4x4 untransformSinceLastApzc = ancestorUntransform * asyncUntransform;
// result is RC.Inverse() * QC.Inverse() * PA.Inverse() * PC.Inverse() * OC.Inverse() * NC.Inverse() * MC.Inverse()
result = untransformSinceLastApzc * result;
// The above value for result when parent == P matches the required output
// as explained in the comment above this method. Note that any missing
@@ -1899,17 +1907,17 @@ APZCTreeManager::GetApzcToGeckoTransform
// The comments below assume there is a chain of layers L..R with L and P having APZC instances as
// explained in the comment above. This function is called with aApzc at L, and the loop
// below performs one iteration, where parent is at P. The comments explain what values are stored
// in the variables at these two levels. All the comments use standard matrix notation where the
// leftmost matrix in a multiplication is applied first.
// asyncUntransform is LA.Inverse()
- Matrix4x4 asyncUntransform = aApzc->GetCurrentAsyncTransformWithOverscroll().Inverse();
+ Matrix4x4 asyncUntransform = aApzc->GetCurrentAsyncTransformWithOverscroll().Inverse().ToUnknownMatrix();
// aTransformToGeckoOut is initialized to LA.Inverse() * LD * MC * NC * OC * PC
result = asyncUntransform * aApzc->GetTransformToLastDispatchedPaint() * aApzc->GetAncestorTransform();
for (AsyncPanZoomController* parent = aApzc->GetParent(); parent; parent = parent->GetParent()) {
// aTransformToGeckoOut is LA.Inverse() * LD * MC * NC * OC * PC * PD * QC * RC
result = result * parent->GetTransformToLastDispatchedPaint() * parent->GetAncestorTransform();
--- a/gfx/layers/apz/src/AsyncPanZoomController.cpp
+++ b/gfx/layers/apz/src/AsyncPanZoomController.cpp
@@ -2901,20 +2901,20 @@ bool AsyncPanZoomController::UpdateAnima
RequestContentRepaint();
}
UpdateSharedCompositorFrameMetrics();
return true;
}
return false;
}
-Matrix4x4 AsyncPanZoomController::GetOverscrollTransform() const {
+AsyncTransformComponentMatrix AsyncPanZoomController::GetOverscrollTransform() const {
ReentrantMonitorAutoEnter lock(mMonitor);
if (!IsOverscrolled()) {
- return Matrix4x4();
+ return AsyncTransformComponentMatrix();
}
// The overscroll effect is a uniform stretch along the overscrolled axis,
// with the edge of the content where we have reached the end of the
// scrollable area pinned into place.
// The kStretchFactor parameter determines how much overscroll can stretch the
// content.
@@ -2941,17 +2941,17 @@ Matrix4x4 AsyncPanZoomController::GetOve
bool overscrolledAtBottom = mY.GetOverscroll() > 0;
if (overscrolledAtBottom) {
ParentLayerCoord overscrolledCompositionHeight = scaleY * compositionSize.height;
ParentLayerCoord extraCompositionHeight = overscrolledCompositionHeight - compositionSize.height;
translation.y = -extraCompositionHeight;
}
// Combine the transformations into a matrix.
- return Matrix4x4::Scaling(scaleX, scaleY, 1)
+ return AsyncTransformComponentMatrix::Scaling(scaleX, scaleY, 1)
.PostTranslate(translation.x, translation.y, 0);
}
bool AsyncPanZoomController::AdvanceAnimations(const TimeStamp& aSampleTime)
{
APZThreadUtils::AssertOnCompositorThread();
// Don't send any state-change notifications until the end of the function,
@@ -3035,18 +3035,19 @@ AsyncTransform AsyncPanZoomController::G
ParentLayerPoint translation = (currentScrollOffset - lastPaintScrollOffset)
* mFrameMetrics.GetZoom() * mTestAsyncZoom.scale;
return AsyncTransform(
LayerToParentLayerScale(mFrameMetrics.GetAsyncZoom().scale * mTestAsyncZoom.scale),
-translation);
}
-Matrix4x4 AsyncPanZoomController::GetCurrentAsyncTransformWithOverscroll() const {
- return Matrix4x4(GetCurrentAsyncTransform()) * GetOverscrollTransform();
+AsyncTransformComponentMatrix AsyncPanZoomController::GetCurrentAsyncTransformWithOverscroll() const {
+ return AsyncTransformComponentMatrix(GetCurrentAsyncTransform())
+ * GetOverscrollTransform();
}
Matrix4x4 AsyncPanZoomController::GetTransformToLastDispatchedPaint() const {
ReentrantMonitorAutoEnter lock(mMonitor);
LayerPoint scrollChange =
(mLastContentPaintMetrics.GetScrollOffset() - mLastDispatchedPaintMetrics.GetScrollOffset())
* mLastContentPaintMetrics.GetDevPixelsPerCSSPixel()
--- a/gfx/layers/apz/src/AsyncPanZoomController.h
+++ b/gfx/layers/apz/src/AsyncPanZoomController.h
@@ -170,17 +170,17 @@ public:
*/
void SampleContentTransformForFrame(AsyncTransform* aOutTransform,
ParentLayerPoint& aScrollOffset);
/**
* Return a visual effect that reflects this apzc's
* overscrolled state, if any.
*/
- Matrix4x4 GetOverscrollTransform() const;
+ AsyncTransformComponentMatrix GetOverscrollTransform() const;
/**
* A shadow layer update has arrived. |aLayerMetrics| is the new FrameMetrics
* for the container layer corresponding to this APZC.
* |aIsFirstPaint| is a flag passed from the shadow
* layers code indicating that the frame metrics being sent with this call are
* the initial metrics and the initial paint of the frame has just happened.
*/
@@ -226,17 +226,17 @@ public:
* amount.
*/
AsyncTransform GetCurrentAsyncTransform() const;
/**
* Returns the same transform as GetCurrentAsyncTransform(), but includes
* any transform due to axis over-scroll.
*/
- Matrix4x4 GetCurrentAsyncTransformWithOverscroll() const;
+ AsyncTransformComponentMatrix GetCurrentAsyncTransformWithOverscroll() const;
/**
* Returns the transform to take something from the coordinate space of the
* last thing we know gecko painted, to the coordinate space of the last thing
* we asked gecko to paint. In cases where that last request has not yet been
* processed, this is needed to transform input events properly into a space
* gecko will understand.
*/
--- a/gfx/layers/apz/src/HitTestingTreeNode.cpp
+++ b/gfx/layers/apz/src/HitTestingTreeNode.cpp
@@ -4,16 +4,17 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "HitTestingTreeNode.h"
#include "AsyncPanZoomController.h" // for AsyncPanZoomController
#include "LayersLogging.h" // for Stringify
#include "mozilla/gfx/Point.h" // for Point4D
+#include "mozilla/layers/APZUtils.h" // for CompleteAsyncTransform
#include "mozilla/layers/APZThreadUtils.h" // for AssertOnCompositorThread
#include "mozilla/layers/AsyncCompositionManager.h" // for ViewTransform::operator Matrix4x4()
#include "nsPrintfCString.h" // for nsPrintfCString
#include "UnitTransforms.h" // for ViewAs
namespace mozilla {
namespace layers {
@@ -201,17 +202,17 @@ HitTestingTreeNode::IsPrimaryHolder() co
uint64_t
HitTestingTreeNode::GetLayersId() const
{
return mLayersId;
}
void
HitTestingTreeNode::SetHitTestData(const EventRegions& aRegions,
- const gfx::Matrix4x4& aTransform,
+ const CSSTransformMatrix& aTransform,
const Maybe<ParentLayerIntRegion>& aClipRegion,
const EventRegionsOverride& aOverride)
{
mEventRegions = aRegions;
mTransform = aTransform;
mClipRegion = aClipRegion;
mOverride = aOverride;
}
@@ -222,22 +223,22 @@ HitTestingTreeNode::IsOutsideClip(const
// test against clip rect in ParentLayer coordinate space
return (mClipRegion.isSome() && !mClipRegion->Contains(aPoint.x, aPoint.y));
}
Maybe<LayerPoint>
HitTestingTreeNode::Untransform(const ParentLayerPoint& aPoint) const
{
// convert into Layer coordinate space
- gfx::Matrix4x4 localTransform = mTransform;
- if (mApzc) {
- localTransform = localTransform * mApzc->GetCurrentAsyncTransformWithOverscroll();
- }
- return UntransformBy(
- ViewAs<LayerToParentLayerMatrix4x4>(localTransform).Inverse(), aPoint);
+ LayerToParentLayerMatrix4x4 transform = mTransform *
+ CompleteAsyncTransform(
+ mApzc
+ ? mApzc->GetCurrentAsyncTransformWithOverscroll()
+ : AsyncTransformComponentMatrix());
+ return UntransformBy(transform.Inverse(), aPoint);
}
HitTestResult
HitTestingTreeNode::HitTest(const ParentLayerPoint& aPoint) const
{
// This should only ever get called if the point is inside the clip region
// for this node.
MOZ_ASSERT(!IsOutsideClip(aPoint));
--- a/gfx/layers/apz/src/HitTestingTreeNode.h
+++ b/gfx/layers/apz/src/HitTestingTreeNode.h
@@ -80,17 +80,17 @@ public:
AsyncPanZoomController* GetNearestContainingApzc() const;
AsyncPanZoomController* GetNearestContainingApzcWithSameLayersId() const;
bool IsPrimaryHolder() const;
uint64_t GetLayersId() const;
/* Hit test related methods */
void SetHitTestData(const EventRegions& aRegions,
- const gfx::Matrix4x4& aTransform,
+ const CSSTransformMatrix& aTransform,
const Maybe<ParentLayerIntRegion>& aClipRegion,
const EventRegionsOverride& aOverride);
bool IsOutsideClip(const ParentLayerPoint& aPoint) const;
/* Scrollbar info */
void SetScrollbarData(FrameMetrics::ViewID aScrollViewId, Layer::ScrollDirection aDir, int32_t aScrollSize);
bool MatchesScrollDragMetrics(const AsyncDragMetrics& aDragMetrics) const;
@@ -130,17 +130,17 @@ private:
* disabled, it will contain the visible region of L, which we use as an
* approximation to the hit region for the purposes of obscuring other layers.
* This value is in L's LayerPixels.
*/
EventRegions mEventRegions;
/* This is the transform from layer L. This does NOT include any async
* transforms. */
- gfx::Matrix4x4 mTransform;
+ CSSTransformMatrix mTransform;
/* This is clip rect for L that we wish to use for hit-testing purposes. Note
* that this may not be exactly the same as the clip rect on layer L because
* of the touch-sensitive region provided by the GeckoContentController, or
* because we may use the composition bounds of the layer if the clip is not
* present. This value is in L's ParentLayerPixels. */
Maybe<ParentLayerIntRegion> mClipRegion;
--- a/gfx/layers/client/TiledContentClient.cpp
+++ b/gfx/layers/client/TiledContentClient.cpp
@@ -1400,17 +1400,17 @@ ClientMultiTiledLayerBuffer::ValidateTil
*/
static Maybe<LayerRect>
GetCompositorSideCompositionBounds(const LayerMetricsWrapper& aScrollAncestor,
const LayerToParentLayerMatrix4x4& aTransformToCompBounds,
const AsyncTransform& aAPZTransform,
const LayerRect& aClip)
{
LayerToParentLayerMatrix4x4 transform = aTransformToCompBounds *
- ViewAs<ParentLayerToParentLayerMatrix4x4>(aAPZTransform);
+ AsyncTransformComponentMatrix(aAPZTransform);
return UntransformBy(transform.Inverse(),
aScrollAncestor.Metrics().GetCompositionBounds(), aClip);
}
bool
ClientMultiTiledLayerBuffer::ComputeProgressiveUpdateRegion(const nsIntRegion& aInvalidRegion,
const nsIntRegion& aOldValidRegion,
--- a/gfx/layers/composite/AsyncCompositionManager.cpp
+++ b/gfx/layers/composite/AsyncCompositionManager.cpp
@@ -15,16 +15,17 @@
#include "mozilla/StyleAnimationValue.h" // for StyleAnimationValue, etc
#include "mozilla/WidgetUtils.h" // for ComputeTransformForRotation
#include "mozilla/dom/KeyframeEffect.h" // for KeyframeEffectReadOnly
#include "mozilla/dom/AnimationEffectReadOnlyBinding.h" // for dom::FillMode
#include "mozilla/gfx/BaseRect.h" // for BaseRect
#include "mozilla/gfx/Point.h" // for RoundedToInt, PointTyped
#include "mozilla/gfx/Rect.h" // for RoundedToInt, RectTyped
#include "mozilla/gfx/ScaleFactor.h" // for ScaleFactor
+#include "mozilla/layers/APZUtils.h" // for CompleteAsyncTransform
#include "mozilla/layers/Compositor.h" // for Compositor
#include "mozilla/layers/CompositorParent.h" // for CompositorParent, etc
#include "mozilla/layers/LayerMetricsWrapper.h" // for LayerMetricsWrapper
#include "nsCoord.h" // for NSAppUnitsToFloatPixels, etc
#include "nsDebug.h" // for NS_ASSERTION, etc
#include "nsDeviceContext.h" // for nsDeviceContext
#include "nsDisplayList.h" // for nsDisplayTransform, etc
#include "nsMathUtils.h" // for NS_round
@@ -216,41 +217,41 @@ TransformClipRect(Layer* aLayer,
* Set the given transform as the shadow transform on the layer, assuming
* that the given transform already has the pre- and post-scales applied.
* That is, this function cancels out the pre- and post-scales from aTransform
* before setting it as the shadow transform on the layer, so that when
* the layer's effective transform is computed, the pre- and post-scales will
* only be applied once.
*/
static void
-SetShadowTransform(Layer* aLayer, Matrix4x4 aTransform)
+SetShadowTransform(Layer* aLayer, LayerToParentLayerMatrix4x4 aTransform)
{
if (ContainerLayer* c = aLayer->AsContainerLayer()) {
aTransform.PreScale(1.0f / c->GetPreXScale(),
1.0f / c->GetPreYScale(),
1);
}
aTransform.PostScale(1.0f / aLayer->GetPostXScale(),
1.0f / aLayer->GetPostYScale(),
1);
- aLayer->AsLayerComposite()->SetShadowTransform(aTransform);
+ aLayer->AsLayerComposite()->SetShadowTransform(aTransform.ToUnknownMatrix());
}
static void
TranslateShadowLayer(Layer* aLayer,
const gfxPoint& aTranslation,
bool aAdjustClipRect)
{
// This layer might also be a scrollable layer and have an async transform.
// To make sure we don't clobber that, we start with the shadow transform.
// (i.e. GetLocalTransform() instead of GetTransform()).
// Note that the shadow transform is reset on every frame of composition so
// we don't have to worry about the adjustments compounding over successive
// frames.
- Matrix4x4 layerTransform = aLayer->GetLocalTransform();
+ LayerToParentLayerMatrix4x4 layerTransform = aLayer->GetLocalTransformTyped();
// Apply the translation to the layer transform.
layerTransform.PostTranslate(aTranslation.x, aTranslation.y, 0);
SetShadowTransform(aLayer, layerTransform);
aLayer->AsLayerComposite()->SetShadowTransformSetByAnimation(false);
if (aAdjustClipRect) {
@@ -378,18 +379,18 @@ AsyncTransformShouldBeUnapplied(Layer* a
}
return false;
}
void
AsyncCompositionManager::AlignFixedAndStickyLayers(Layer* aLayer,
Layer* aTransformedSubtreeRoot,
FrameMetrics::ViewID aTransformScrollId,
- const Matrix4x4& aPreviousTransformForRoot,
- const Matrix4x4& aCurrentTransformForRoot,
+ const LayerToParentLayerMatrix4x4& aPreviousTransformForRoot,
+ const LayerToParentLayerMatrix4x4& aCurrentTransformForRoot,
const ScreenMargin& aFixedLayerMargins)
{
FrameMetrics::ViewID fixedTo; // the scroll id of the scroll frame we are fixed/sticky to
bool isRootOfFixedSubtree = aLayer->GetIsFixedPosition() &&
!aLayer->GetParent()->GetIsFixedPosition();
if (isRootOfFixedSubtree) {
fixedTo = aLayer->GetFixedPositionScrollContainerId();
}
@@ -421,18 +422,18 @@ AsyncCompositionManager::AlignFixedAndSt
// Accumulate the transforms between this layer and the subtree root layer.
Matrix4x4 ancestorTransform;
AccumulateLayerTransforms(aLayer->GetParent(), aTransformedSubtreeRoot,
ancestorTransform);
// Calculate the cumulative transforms between the subtree root with the
// old transform and the current transform.
- Matrix4x4 oldCumulativeTransform = ancestorTransform * aPreviousTransformForRoot;
- Matrix4x4 newCumulativeTransform = ancestorTransform * aCurrentTransformForRoot;
+ Matrix4x4 oldCumulativeTransform = ancestorTransform * aPreviousTransformForRoot.ToUnknownMatrix();
+ Matrix4x4 newCumulativeTransform = ancestorTransform * aCurrentTransformForRoot.ToUnknownMatrix();
if (newCumulativeTransform.IsSingular()) {
return;
}
// Add in the layer's local transform, if it isn't already included in
// |aPreviousTransformForRoot| and |aCurrentTransformForRoot| (this happens
// when the fixed/sticky layer is itself the transformed subtree root).
Matrix4x4 localTransform;
@@ -692,20 +693,20 @@ AsyncCompositionManager::RecordShadowTra
if (transform.IsTranslation() && !shadowTransform.IsIdentity()) {
Point translation = transform.GetTranslation();
mLayerTransformRecorder.RecordTransform(aLayer, translation);
return;
}
}
}
-Matrix4x4
-AdjustForClip(const Matrix4x4& asyncTransform, Layer* aLayer)
+static AsyncTransformComponentMatrix
+AdjustForClip(const AsyncTransformComponentMatrix& asyncTransform, Layer* aLayer)
{
- Matrix4x4 result = asyncTransform;
+ AsyncTransformComponentMatrix result = asyncTransform;
// Container layers start at the origin, but they are clipped to where they
// actually have content on the screen. The tree transform is meant to apply
// to the clipped area. If the tree transform includes a scale component,
// then applying it to container as-is will produce incorrect results. To
// avoid this, translate the layer so that the clip rect starts at the origin,
// apply the tree transform, and translate back.
if (const Maybe<ParentLayerIntRect>& shadowClipRect = aLayer->AsLayerComposite()->GetShadowClipRect()) {
@@ -796,19 +797,20 @@ AsyncCompositionManager::ApplyAsyncConte
bool appliedTransform = false;
for (Layer* child = aLayer->GetFirstChild();
child; child = child->GetNextSibling()) {
appliedTransform |=
ApplyAsyncContentTransformToTree(child, aOutFoundRoot,
clipDeferredFromChildren);
}
- Matrix4x4 oldTransform = aLayer->GetTransform();
+ LayerToParentLayerMatrix4x4 oldTransform = aLayer->GetTransformTyped() *
+ AsyncTransformMatrix();
- Matrix4x4 combinedAsyncTransform;
+ AsyncTransformComponentMatrix combinedAsyncTransform;
bool hasAsyncTransform = false;
ScreenMargin fixedLayerMargins;
// 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.
//
@@ -834,19 +836,20 @@ AsyncCompositionManager::ApplyAsyncConte
}
hasAsyncTransform = true;
AsyncTransform asyncTransformWithoutOverscroll;
ParentLayerPoint scrollOffset;
controller->SampleContentTransformForFrame(&asyncTransformWithoutOverscroll,
scrollOffset);
- Matrix4x4 overscrollTransform = controller->GetOverscrollTransform();
- Matrix4x4 asyncTransform =
- Matrix4x4(asyncTransformWithoutOverscroll) * overscrollTransform;
+ AsyncTransformComponentMatrix overscrollTransform = controller->GetOverscrollTransform();
+ AsyncTransformComponentMatrix asyncTransform =
+ AsyncTransformComponentMatrix(asyncTransformWithoutOverscroll)
+ * overscrollTransform;
if (!aLayer->IsScrollInfoLayer()) {
controller->MarkAsyncTransformAppliedToContent();
}
const FrameMetrics& metrics = aLayer->GetFrameMetrics(i);
#if defined(MOZ_ANDROID_APZ)
@@ -892,18 +895,17 @@ AsyncCompositionManager::ApplyAsyncConte
mIsFirstPaint = false;
#endif
// Transform the current local clip by this APZC's async transform. If we're
// using containerful scrolling, then the clip is not part of the scrolled
// frame and should not be transformed.
if (asyncClip && !metrics.UsesContainerScrolling()) {
MOZ_ASSERT(asyncTransform.Is2D());
- asyncClip = Some(TransformBy(
- ViewAs<ParentLayerToParentLayerMatrix4x4>(asyncTransform), *asyncClip));
+ asyncClip = Some(TransformBy(asyncTransform, *asyncClip));
}
// Combine the local clip with the ancestor scrollframe clip. This is not
// included in the async transform above, since the ancestor clip should not
// move with this APZC.
if (metrics.HasClipRect()) {
ParentLayerIntRect clip = metrics.ClipRect();
if (aLayer->GetParent() && aLayer->GetParent()->GetTransformIsPerspective()) {
@@ -918,17 +920,17 @@ AsyncCompositionManager::ApplyAsyncConte
}
}
// 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);
+ ancestorMaskLayer->GetLocalTransformTyped() * 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);
}
@@ -937,18 +939,20 @@ AsyncCompositionManager::ApplyAsyncConte
// 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
// GetTransform() as the base transform rather than GetLocalTransform(),
// which would include those factors.
- Matrix4x4 transformWithoutOverscrollOrOmta = aLayer->GetTransform() *
- AdjustForClip(asyncTransformWithoutOverscroll, aLayer);
+ LayerToParentLayerMatrix4x4 transformWithoutOverscrollOrOmta =
+ aLayer->GetTransformTyped()
+ * CompleteAsyncTransform(
+ AdjustForClip(asyncTransformWithoutOverscroll, aLayer));
// Since fixed/sticky layers are relative to their nearest scrolling ancestor,
// we use the ViewID from the bottommost scrollable metrics here.
AlignFixedAndStickyLayers(aLayer, aLayer, metrics.GetScrollId(), oldTransform,
transformWithoutOverscrollOrOmta, fixedLayerMargins);
}
if (hasAsyncTransform || clipDeferredFromChildren) {
@@ -957,22 +961,23 @@ AsyncCompositionManager::ApplyAsyncConte
}
if (hasAsyncTransform) {
// 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));
+ aLayer->GetLocalTransformTyped()
+ * 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);
+ maskLayer->GetLocalTransformTyped() * combinedAsyncTransform);
}
appliedTransform = true;
}
ExpandRootClipRect(aLayer, fixedLayerMargins);
if (aLayer->GetScrollbarDirection() != Layer::NONE) {
@@ -1007,23 +1012,23 @@ ApplyAsyncTransformToScrollbarForContent
// disparity between scrollbars and visible content.
if (aContent.IsScrollInfoLayer()) {
return;
}
const FrameMetrics& metrics = aContent.Metrics();
AsyncPanZoomController* apzc = aContent.GetApzc();
- Matrix4x4 asyncTransform = apzc->GetCurrentAsyncTransform();
+ AsyncTransformComponentMatrix asyncTransform = apzc->GetCurrentAsyncTransform();
// |asyncTransform| represents the amount by which we have scrolled and
// zoomed since the last paint. Because the scrollbar was sized and positioned based
// on the painted content, we need to adjust it based on asyncTransform so that
// it reflects what the user is actually seeing now.
- Matrix4x4 scrollbarTransform;
+ AsyncTransformComponentMatrix scrollbarTransform;
if (aScrollbar->GetScrollbarDirection() == Layer::VERTICAL) {
const ParentLayerCoord asyncScrollY = asyncTransform._42;
const float asyncZoomY = asyncTransform._22;
// The scroll thumb needs to be scaled in the direction of scrolling by the
// inverse of the async zoom. This is because zooming in decreases the
// fraction of the whole srollable rect that is in view.
const float yScale = 1.f / asyncZoomY;
@@ -1094,58 +1099,62 @@ ApplyAsyncTransformToScrollbarForContent
if (metrics.IsRootContent()) {
xTranslation *= metrics.GetPresShellResolution();
}
scrollbarTransform.PostScale(xScale, 1.f, 1.f);
scrollbarTransform.PostTranslate(xTranslation, 0, 0);
}
- Matrix4x4 transform = aScrollbar->GetLocalTransform() * scrollbarTransform;
+ LayerToParentLayerMatrix4x4 transform =
+ aScrollbar->GetLocalTransformTyped() * scrollbarTransform;
- Matrix4x4 compensation;
+ AsyncTransformComponentMatrix compensation;
// If the scrollbar layer is for the root then the content's resolution
// applies to the scrollbar as well. Since we don't actually want the scroll
// thumb's size to vary with the zoom (other than its length reflecting the
// fraction of the scrollable length that's in view, which is taken care of
// above), we apply a transform to cancel out this resolution.
if (metrics.IsRootContent()) {
compensation =
- Matrix4x4::Scaling(metrics.GetPresShellResolution(),
- metrics.GetPresShellResolution(),
- 1.0f).Inverse();
+ AsyncTransformComponentMatrix::Scaling(
+ metrics.GetPresShellResolution(),
+ metrics.GetPresShellResolution(),
+ 1.0f).Inverse();
}
// If the scrollbar layer is a child of the content it is a scrollbar for,
// then we need to adjust for any async transform (including an overscroll
// transform) on the content. This needs to be cancelled out because layout
// positions and sizes the scrollbar on the assumption that there is no async
// transform, and without this adjustment the scrollbar will end up in the
// wrong place.
//
// Note that since the async transform is applied on top of the content's
// regular transform, we need to make sure to unapply the async transform in
// the same coordinate space. This requires applying the content transform
// and then unapplying it after unapplying the async transform.
if (aScrollbarIsDescendant) {
- Matrix4x4 asyncUntransform = (asyncTransform * apzc->GetOverscrollTransform()).Inverse();
+ Matrix4x4 asyncUntransform = (asyncTransform * apzc->GetOverscrollTransform()).Inverse().ToUnknownMatrix();
Matrix4x4 contentTransform = aContent.GetTransform();
Matrix4x4 contentUntransform = contentTransform.Inverse();
- Matrix4x4 asyncCompensation = contentTransform
- * asyncUntransform
- * contentUntransform;
+ AsyncTransformComponentMatrix asyncCompensation =
+ ViewAs<AsyncTransformComponentMatrix>(
+ contentTransform
+ * asyncUntransform
+ * contentUntransform);
compensation = compensation * asyncCompensation;
// We also need to make a corresponding change on the clip rect of all the
// layers on the ancestor chain from the scrollbar layer up to but not
// including the layer with the async transform. Otherwise the scrollbar
// shifts but gets clipped and so appears to flicker.
for (Layer* ancestor = aScrollbar; ancestor != aContent.GetLayer(); ancestor = ancestor->GetParent()) {
- TransformClipRect(ancestor, ViewAs<ParentLayerToParentLayerMatrix4x4>(asyncCompensation));
+ TransformClipRect(ancestor, asyncCompensation);
}
}
transform = transform * compensation;
SetShadowTransform(aScrollbar, transform);
}
static LayerMetricsWrapper
@@ -1224,17 +1233,18 @@ AsyncCompositionManager::TransformScroll
// tree, and this function just gets called with the root layer. In that
// case TopmostScrollableMetrics will return an empty FrameMetrics but we
// still want to use the actual non-scrollable metrics from the layer.
metrics = LayerMetricsWrapper::BottommostMetrics(aLayer);
}
// We must apply the resolution scale before a pan/zoom transform, so we call
// GetTransform here.
- Matrix4x4 oldTransform = aLayer->GetTransform();
+ LayerToParentLayerMatrix4x4 oldTransform = aLayer->GetTransformTyped() *
+ AsyncTransformMatrix();
CSSToLayerScale geckoZoom = metrics.LayersPixelsPerCSSPixel().ToScaleFactor();
LayerIntPoint scrollOffsetLayerPixels = RoundedToInt(metrics.GetScrollOffset() * geckoZoom);
if (mIsFirstPaint) {
mContentRect = metrics.GetScrollableRect();
SetFirstPaintViewport(scrollOffsetLayerPixels,
@@ -1283,23 +1293,23 @@ AsyncCompositionManager::TransformScroll
// transformation we need to apply.
ParentLayerPoint geckoScroll(0, 0);
if (metrics.IsScrollable()) {
geckoScroll = metrics.GetScrollOffset() * userZoom;
}
LayerToParentLayerScale asyncZoom = userZoom / metrics.LayersPixelsPerCSSPixel().ToScaleFactor();
ParentLayerPoint translation = userRect.TopLeft() - geckoScroll;
- Matrix4x4 treeTransform = AsyncTransform(asyncZoom, -translation);
+ AsyncTransformComponentMatrix treeTransform = AsyncTransform(asyncZoom, -translation);
// Apply the tree 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() * treeTransform);
+ SetShadowTransform(aLayer, aLayer->GetLocalTransformTyped() * treeTransform);
// Make sure that overscroll and under-zoom are represented in the old
// transform so that fixed position content moves and scales accordingly.
// These calculations will effectively scale and offset fixed position layers
// in screen space when the compensatory transform is performed in
// AlignFixedAndStickyLayers.
ParentLayerRect contentScreenRect = mContentRect * userZoom;
Point3D overscrollTranslation;
@@ -1326,17 +1336,18 @@ AsyncCompositionManager::TransformScroll
underZoomScale.height = (mContentRect.height * userZoom.scale) /
metrics.GetCompositionBounds().height;
}
oldTransform.PreScale(underZoomScale.width, underZoomScale.height, 1);
// Make sure fixed position layers don't move away from their anchor points
// when we're asynchronously panning or zooming
AlignFixedAndStickyLayers(aLayer, aLayer, metrics.GetScrollId(), oldTransform,
- aLayer->GetLocalTransform(), fixedLayerMargins);
+ aLayer->GetLocalTransformTyped(),
+ fixedLayerMargins);
ExpandRootClipRect(aLayer, fixedLayerMargins);
}
void
AsyncCompositionManager::GetFrameUniformity(FrameUniformityData* aOutData)
{
MOZ_ASSERT(CompositorParent::IsInCompositorThread());
--- a/gfx/layers/composite/AsyncCompositionManager.h
+++ b/gfx/layers/composite/AsyncCompositionManager.h
@@ -31,27 +31,20 @@ class CompositorParent;
// Represents async transforms consisting of a scale and a translation.
struct AsyncTransform {
explicit AsyncTransform(LayerToParentLayerScale aScale = LayerToParentLayerScale(),
ParentLayerPoint aTranslation = ParentLayerPoint())
: mScale(aScale)
, mTranslation(aTranslation)
{}
- operator gfx::Matrix4x4() const
+ operator AsyncTransformComponentMatrix() const
{
- return
- gfx::Matrix4x4::Scaling(mScale.scale, mScale.scale, 1)
- .PostTranslate(mTranslation.x, mTranslation.y, 0);
- }
-
- // For convenience, to avoid writing the cumbersome
- // "gfx::Matrix4x4(a) * gfx::Matrix4x4(b)".
- friend gfx::Matrix4x4 operator*(const AsyncTransform& a, const AsyncTransform& b) {
- return gfx::Matrix4x4(a) * gfx::Matrix4x4(b);
+ return AsyncTransformComponentMatrix::Scaling(mScale.scale, mScale.scale, 1)
+ .PostTranslate(mTranslation.x, mTranslation.y, 0);
}
bool operator==(const AsyncTransform& rhs) const {
return mTranslation == rhs.mTranslation && mScale == rhs.mScale;
}
bool operator!=(const AsyncTransform& rhs) const {
return !(*this == rhs);
@@ -175,18 +168,18 @@ private:
* 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,
FrameMetrics::ViewID aTransformScrollId,
- const gfx::Matrix4x4& aPreviousTransformForRoot,
- const gfx::Matrix4x4& aCurrentTransformForRoot,
+ const LayerToParentLayerMatrix4x4& aPreviousTransformForRoot,
+ const LayerToParentLayerMatrix4x4& aCurrentTransformForRoot,
const ScreenMargin& aFixedLayerMargins);
/**
* DRAWING PHASE ONLY
*
* For reach RefLayer in our layer tree, look up its referent and connect it
* to the layer tree, if found.
* aHasRemoteContent - indicates if the layer tree contains a remote reflayer.
--- a/gfx/layers/composite/ContainerLayerComposite.cpp
+++ b/gfx/layers/composite/ContainerLayerComposite.cpp
@@ -597,17 +597,17 @@ RenderLayers(ContainerT* aContainer,
// Since the composition bounds are in the parent layer's coordinates,
// use the parent's effective transform rather than the layer's own.
ParentLayerRect compositionBounds = layer->GetFrameMetrics(i - 1).GetCompositionBounds();
aManager->GetCompositor()->DrawDiagnostics(DiagnosticFlags::CONTAINER,
compositionBounds.ToUnknownRect(),
gfx::Rect(aClipRect.ToUnknownRect()),
asyncTransform * aContainer->GetEffectiveTransform());
if (AsyncPanZoomController* apzc = layer->GetAsyncPanZoomController(i - 1)) {
- asyncTransform = apzc->GetCurrentAsyncTransformWithOverscroll()
+ asyncTransform = apzc->GetCurrentAsyncTransformWithOverscroll().ToUnknownMatrix()
* asyncTransform;
}
}
}
if (gfxPrefs::APZMinimap()) {
RenderMinimap(aContainer, aManager, aClipRect, layer);
}
@@ -747,17 +747,17 @@ ContainerRender(ContainerT* aContainer,
// enabled).
if (gfxPrefs::LayersDrawFPS() && aContainer->IsScrollInfoLayer()) {
// Since aContainer doesn't have any children we can just iterate from the top metrics
// on it down to the bottom using GetFirstChild and not worry about walking onto another
// underlying layer.
for (LayerMetricsWrapper i(aContainer); i; i = i.GetFirstChild()) {
if (AsyncPanZoomController* apzc = i.GetApzc()) {
if (!apzc->GetAsyncTransformAppliedToContent()
- && !Matrix4x4(apzc->GetCurrentAsyncTransform()).IsIdentity()) {
+ && !AsyncTransformComponentMatrix(apzc->GetCurrentAsyncTransform()).IsIdentity()) {
aManager->UnusedApzTransformWarning();
break;
}
}
}
}
}