Bug 1910492. Make ViewportUtils use Matrix4x4Flagged. r=layout-reviewers,emilio

Generally we want to move to more flagged matrices because the transforms are usually simple, just offsets, or simple 2d transforms and the operations do show up in profiles if we do them in the "dumb" way of assuming a full 3d transform.

This specific code isn't necessarily performance critical, but it simplifies nsIFrame::GetTransformMatrix (which is performance critical) so that everything there is Matrix4x4Flagged except the one conversion for GetResultingTransformMatrix.

Matrix4x4TypedFlagged::ToUnknownMatrix gets its first user with this change and we need to make some fixes so that it actually works. We need to friend all template instantiations of this class so that it can access the private constructor of the class with different units. We also need to move the MatrixType enum outside of the class so it doesn't get the templated units imprinted on its type. Maybe there is a better way to do this.

Differential Revision: https://phabricator.services.mozilla.com/D218018
This commit is contained in:
Timothy Nikkel 2024-08-10 10:31:18 +00:00
parent 92da71b93f
commit 03258de701
5 changed files with 95 additions and 25 deletions

View File

@ -988,6 +988,8 @@ class Matrix4x4Typed {
template <class F>
GFX2D_API RectTyped<TargetUnits, F> TransformBounds(
const RectTyped<SourceUnits, F>& aRect) const {
// If you change this also change Matrix4x4TypedFlagged::TransformBounds to
// match.
PointTyped<TargetUnits, F> quad[4];
F min_x, max_x;
F min_y, max_y;
@ -1942,6 +1944,13 @@ class Matrix5x4 {
* This does not allow access to the parent class directly, as a caller
* could then mutate the parent class without updating the type.
*/
enum class MatrixType : uint8_t {
Identity,
Simple, // 2x3 Matrix
Full // 4x4 Matrix
};
template <typename SourceUnits, typename TargetUnits>
class Matrix4x4TypedFlagged
: protected Matrix4x4Typed<SourceUnits, TargetUnits> {
@ -1996,6 +2005,21 @@ class Matrix4x4TypedFlagged
matrixType);
}
static Matrix4x4TypedFlagged Scaling(Float aScaleX, Float aScaleY,
Float aScaleZ) {
MatrixType matrixType = MatrixType::Full;
if (aScaleZ == 1.0) {
if (aScaleX == 1.0 && aScaleY == 1.0) {
matrixType = MatrixType::Identity;
} else {
matrixType = MatrixType::Simple;
}
}
return Matrix4x4TypedFlagged(aScaleX, 0.0f, 0.0f, 0.0f, 0.0f, aScaleY, 0.0f,
0.0f, 0.0f, 0.0f, aScaleZ, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, matrixType);
}
template <class F>
PointTyped<TargetUnits, F> TransformPoint(
const PointTyped<SourceUnits, F>& aPoint) const {
@ -2010,6 +2034,49 @@ class Matrix4x4TypedFlagged
return Parent::TransformPoint(aPoint);
}
template <class F>
RectTyped<TargetUnits, F> TransformBounds(
const RectTyped<SourceUnits, F>& aRect) const {
if (mType == MatrixType::Identity) {
return aRect;
}
if (mType == MatrixType::Simple) {
PointTyped<TargetUnits, F> quad[4];
F min_x, max_x;
F min_y, max_y;
quad[0] = TransformPointSimple(aRect.TopLeft());
quad[1] = TransformPointSimple(aRect.TopRight());
quad[2] = TransformPointSimple(aRect.BottomLeft());
quad[3] = TransformPointSimple(aRect.BottomRight());
min_x = max_x = quad[0].x;
min_y = max_y = quad[0].y;
for (int i = 1; i < 4; i++) {
if (quad[i].x < min_x) {
min_x = quad[i].x;
}
if (quad[i].x > max_x) {
max_x = quad[i].x;
}
if (quad[i].y < min_y) {
min_y = quad[i].y;
}
if (quad[i].y > max_y) {
max_y = quad[i].y;
}
}
return RectTyped<TargetUnits, F>(min_x, min_y, max_x - min_x,
max_y - min_y);
}
return Parent::TransformBounds(aRect);
}
template <class F>
RectTyped<TargetUnits, F> TransformAndClipBounds(
const RectTyped<SourceUnits, F>& aRect,
@ -2321,18 +2388,16 @@ class Matrix4x4TypedFlagged
const Parent& GetMatrix() const { return *this; }
private:
enum class MatrixType : uint8_t {
Identity,
Simple, // 2x3 Matrix
Full // 4x4 Matrix
};
Matrix4x4Flagged ToUnknownMatrix() const {
return Matrix4x4Flagged{_11, _12, _13, _14, _21, _22, _23, _24, _31,
_32, _33, _34, _41, _42, _43, _44, mType};
}
private:
Matrix4x4TypedFlagged(Float a11, Float a12, Float a13, Float a14, Float a21,
Float a22, Float a23, Float a24, Float a31, Float a32,
Float a33, Float a34, Float a41, Float a42, Float a43,
Float a44,
typename Matrix4x4TypedFlagged::MatrixType aType)
Float a44, const MatrixType aType)
: Parent(a11, a12, a13, a14, a21, a22, a23, a24, a31, a32, a33, a34, a41,
a42, a43, a44),
mType(aType) {}
@ -2344,10 +2409,6 @@ class Matrix4x4TypedFlagged
aUnknown._33, aUnknown._34, aUnknown._41, aUnknown._42, aUnknown._43,
aUnknown._44, aUnknown.mType};
}
Matrix4x4Flagged ToUnknownMatrix() const {
return Matrix4x4Flagged{_11, _12, _13, _14, _21, _22, _23, _24, _31,
_32, _33, _34, _41, _42, _43, _44, mType};
}
template <class F>
PointTyped<TargetUnits, F> TransformPointSimple(
@ -2373,6 +2434,9 @@ class Matrix4x4TypedFlagged
}
MatrixType mType;
template <typename, typename>
friend class Matrix4x4TypedFlagged;
};
using Matrix4x4Flagged = Matrix4x4TypedFlagged<UnknownUnits, UnknownUnits>;

View File

@ -268,6 +268,9 @@ typedef gfx::ScaleFactors2D<ParentLayerPixel, ParentLayerPixel>
typedef gfx::ScaleFactors2D<gfx::UnknownUnits, gfx::UnknownUnits> Scale2D;
typedef gfx::Matrix4x4Typed<CSSPixel, CSSPixel> CSSToCSSMatrix4x4;
typedef gfx::Matrix4x4TypedFlagged<CSSPixel, CSSPixel> CSSToCSSMatrix4x4Flagged;
typedef gfx::Matrix4x4TypedFlagged<LayoutDevicePixel, LayoutDevicePixel>
LayoutDeviceToLayoutDeviceMatrix4x4Flagged;
typedef gfx::Matrix4x4Typed<LayoutDevicePixel, LayoutDevicePixel>
LayoutDeviceToLayoutDeviceMatrix4x4;
typedef gfx::Matrix4x4Typed<LayoutDevicePixel, ParentLayerPixel>

View File

@ -24,7 +24,8 @@ using layers::InputAPZContext;
using layers::ScrollableLayerGuid;
template <typename Units>
gfx::Matrix4x4Typed<Units, Units> ViewportUtils::GetVisualToLayoutTransform(
gfx::Matrix4x4TypedFlagged<Units, Units>
ViewportUtils::GetVisualToLayoutTransform(
ScrollableLayerGuid::ViewID aScrollId) {
static_assert(
std::is_same_v<Units, CSSPixel> ||
@ -65,12 +66,12 @@ gfx::Matrix4x4Typed<Units, Units> ViewportUtils::GetVisualToLayoutTransform(
content->GetPrimaryFrame()->PresContext()->CSSToDevPixelScale();
}
return gfx::Matrix4x4Typed<Units, Units>::Scaling(1 / resolution,
1 / resolution, 1)
return gfx::Matrix4x4TypedFlagged<Units, Units>::Scaling(1 / resolution,
1 / resolution, 1)
.PostTranslate(transform.x, transform.y, 0);
}
CSSToCSSMatrix4x4 GetVisualToLayoutTransform(PresShell* aContext) {
CSSToCSSMatrix4x4Flagged GetVisualToLayoutTransform(PresShell* aContext) {
ScrollableLayerGuid::ViewID targetScrollId =
InputAPZContext::GetTargetLayerGuid().mScrollId;
if (targetScrollId == ScrollableLayerGuid::NULL_SCROLL_ID) {
@ -232,9 +233,9 @@ LayoutDeviceRect ViewportUtils::ToScreenRelativeVisual(
// Definitions of the two explicit instantiations forward declared in the header
// file. This causes code for these instantiations to be emitted into the object
// file for ViewportUtils.cpp.
template CSSToCSSMatrix4x4 ViewportUtils::GetVisualToLayoutTransform<CSSPixel>(
ScrollableLayerGuid::ViewID);
template LayoutDeviceToLayoutDeviceMatrix4x4
template CSSToCSSMatrix4x4Flagged ViewportUtils::GetVisualToLayoutTransform<
CSSPixel>(ScrollableLayerGuid::ViewID);
template LayoutDeviceToLayoutDeviceMatrix4x4Flagged
ViewportUtils::GetVisualToLayoutTransform<LayoutDevicePixel>(
ScrollableLayerGuid::ViewID);

View File

@ -36,7 +36,7 @@ class ViewportUtils {
APZCCallbackHelper::UpdateCallbackTransform. See that method's
documentation for additional details. */
template <typename Units = CSSPixel>
static gfx::Matrix4x4Typed<Units, Units> GetVisualToLayoutTransform(
static gfx::Matrix4x4TypedFlagged<Units, Units> GetVisualToLayoutTransform(
layers::ScrollableLayerGuid::ViewID aScrollId);
/* The functions below apply GetVisualToLayoutTransform() or its inverse
@ -117,9 +117,10 @@ class ViewportUtils {
// translation unit (in this case, ViewportUtils.cpp) will contain the
// definitions of these instantiations. This allows us to keep the definition
// out-of-line in the source.
extern template CSSToCSSMatrix4x4 ViewportUtils::GetVisualToLayoutTransform<
CSSPixel>(layers::ScrollableLayerGuid::ViewID);
extern template LayoutDeviceToLayoutDeviceMatrix4x4
extern template CSSToCSSMatrix4x4Flagged
ViewportUtils::GetVisualToLayoutTransform<CSSPixel>(
layers::ScrollableLayerGuid::ViewID);
extern template LayoutDeviceToLayoutDeviceMatrix4x4Flagged
ViewportUtils::GetVisualToLayoutTransform<LayoutDevicePixel>(
layers::ScrollableLayerGuid::ViewID);

View File

@ -7424,7 +7424,7 @@ Matrix4x4Flagged nsIFrame::GetTransformMatrix(ViewportType aViewportType,
if (isTransformed || zoomedContentRoot) {
MOZ_ASSERT(GetParent());
Matrix4x4 result;
Matrix4x4Flagged result;
int32_t scaleFactor =
((aFlags & IN_CSS_UNITS) ? AppUnitsPerCSSPixel()
: PresContext()->AppUnitsPerDevPixel());
@ -7433,6 +7433,7 @@ Matrix4x4Flagged nsIFrame::GetTransformMatrix(ViewportType aViewportType,
* coordinates to our parent.
*/
if (isTransformed) {
// Note: this converts from Matrix4x4 to Matrix4x4Flagged.
result = nsDisplayTransform::GetResultingTransformMatrix(
this, nsPoint(), scaleFactor,
nsDisplayTransform::INCLUDE_PERSPECTIVE);
@ -7448,7 +7449,7 @@ Matrix4x4Flagged nsIFrame::GetTransformMatrix(ViewportType aViewportType,
NSAppUnitsToFloatPixels(delta.y, scaleFactor), 0.0f);
if (zoomedContentRoot) {
Matrix4x4 layoutToVisual;
Matrix4x4Flagged layoutToVisual;
ScrollableLayerGuid::ViewID targetScrollId =
nsLayoutUtils::FindOrCreateIDFor(zoomedContentRoot->GetContent());
if (aFlags & nsIFrame::IN_CSS_UNITS) {