# HG changeset patch # User Bas Schouten # Date 1518824618 -3600 # Node ID 19d0b0f36ccea9d991eb1891e6cb88b4e82f5d92 # Parent 0c9e7a6951127cc23e530b044a91bc0330d6b455 Bug 1437492 - Part 2: Based on profile data, use the simple-matrix optimized matrix class in some places. r=mattwoodrow MozReview-Commit-ID: EBRrGXc2wEj diff --git a/dom/base/Element.cpp b/dom/base/Element.cpp --- a/dom/base/Element.cpp +++ b/dom/base/Element.cpp @@ -3741,49 +3741,49 @@ Element::GetTransformToAncestor(Element& nsIFrame* ancestorFrame = aAncestor.GetPrimaryFrame(); Matrix4x4 transform; if (primaryFrame) { // If aAncestor is not actually an ancestor of this (including nullptr), // then the call to GetTransformToAncestor will return the transform // all the way up through the parent chain. transform = nsLayoutUtils::GetTransformToAncestor(primaryFrame, - ancestorFrame, nsIFrame::IN_CSS_UNITS); + ancestorFrame, nsIFrame::IN_CSS_UNITS).GetMatrix(); } DOMMatrixReadOnly* matrix = new DOMMatrix(this, transform, IsStyledByServo()); RefPtr result(matrix); return result.forget(); } already_AddRefed Element::GetTransformToParent() { nsIFrame* primaryFrame = GetPrimaryFrame(); Matrix4x4 transform; if (primaryFrame) { nsIFrame* parentFrame = primaryFrame->GetParent(); transform = nsLayoutUtils::GetTransformToAncestor(primaryFrame, - parentFrame, nsIFrame::IN_CSS_UNITS); + parentFrame, nsIFrame::IN_CSS_UNITS).GetMatrix(); } DOMMatrixReadOnly* matrix = new DOMMatrix(this, transform, IsStyledByServo()); RefPtr result(matrix); return result.forget(); } already_AddRefed Element::GetTransformToViewport() { nsIFrame* primaryFrame = GetPrimaryFrame(); Matrix4x4 transform; if (primaryFrame) { transform = nsLayoutUtils::GetTransformToAncestor(primaryFrame, - nsLayoutUtils::GetDisplayRootFrame(primaryFrame), nsIFrame::IN_CSS_UNITS); + nsLayoutUtils::GetDisplayRootFrame(primaryFrame), nsIFrame::IN_CSS_UNITS).GetMatrix(); } DOMMatrixReadOnly* matrix = new DOMMatrix(this, transform, IsStyledByServo()); RefPtr result(matrix); return result.forget(); } already_AddRefed diff --git a/gfx/layers/LayerTreeInvalidation.cpp b/gfx/layers/LayerTreeInvalidation.cpp --- a/gfx/layers/LayerTreeInvalidation.cpp +++ b/gfx/layers/LayerTreeInvalidation.cpp @@ -66,24 +66,24 @@ GetTransformIn3DContext(Layer* aLayer) { /** * Get a transform for the given layer depending on extending 3D * context. * * @return local transform for layers not participating 3D rendering * context, or the accmulated transform in the context for else. */ -static Matrix4x4 +static Matrix4x4Flagged GetTransformForInvalidation(Layer* aLayer) { return (!aLayer->Is3DContextLeaf() && !aLayer->Extend3DContext() ? aLayer->GetLocalTransform() : GetTransformIn3DContext(aLayer)); } static IntRect -TransformRect(const IntRect& aRect, const Matrix4x4& aTransform) +TransformRect(const IntRect& aRect, const Matrix4x4Flagged& aTransform) { if (aRect.IsEmpty()) { return IntRect(); } Rect rect(aRect.X(), aRect.Y(), aRect.Width(), aRect.Height()); rect = aTransform.TransformAndClipBounds(rect, Rect::MaxIntRect()); rect.RoundOut(); @@ -92,17 +92,17 @@ TransformRect(const IntRect& aRect, cons if (!gfxUtils::GfxRectToIntRect(ThebesRect(rect), &intRect)) { return IntRect(); } return intRect; } static void -AddTransformedRegion(nsIntRegion& aDest, const nsIntRegion& aSource, const Matrix4x4& aTransform) +AddTransformedRegion(nsIntRegion& aDest, const nsIntRegion& aSource, const Matrix4x4Flagged& aTransform) { for (auto iter = aSource.RectIter(); !iter.Done(); iter.Next()) { aDest.Or(aDest, TransformRect(iter.Get(), aTransform)); } aDest.SimplifyOutward(20); } static void @@ -323,17 +323,17 @@ public: } return true; } RefPtr mLayer; UniquePtr mMaskLayer; nsTArray> mAncestorMaskLayers; nsIntRegion mVisibleRegion; - Matrix4x4 mTransform; + Matrix4x4Flagged mTransform; float mPostXScale; float mPostYScale; float mOpacity; ParentLayerIntRect mClipRect; bool mUseClipRect; mozilla::CorruptionCanary mCanary; }; @@ -502,17 +502,17 @@ public: // Safe to bail out early now, persistent state has been set. if (areaOverflowed) { return false; } if (!mLayer->Extend3DContext()) { // |result| contains invalid regions only of children. - result.Transform(GetTransformForInvalidation(mLayer)); + result.Transform(GetTransformForInvalidation(mLayer).GetMatrix()); } // else, effective transforms have applied on children. LTI_DUMP(invalidOfLayer, "invalidOfLayer"); result.OrWith(invalidOfLayer); aOutRegion = Move(result); return true; diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -2639,16 +2639,35 @@ nsLayoutUtils::MatrixTransformRect(const double(nscoord_MAX) / aFactor, double(nscoord_MAX) / aFactor); image = aMatrix.TransformAndClipBounds(image, maxBounds); return RoundGfxRectToAppRect(ThebesRect(image), aFactor); } +nsRect +nsLayoutUtils::MatrixTransformRect(const nsRect &aBounds, + const Matrix4x4Flagged &aMatrix, float aFactor) +{ + RectDouble image = RectDouble(NSAppUnitsToDoublePixels(aBounds.x, aFactor), + NSAppUnitsToDoublePixels(aBounds.y, aFactor), + NSAppUnitsToDoublePixels(aBounds.width, aFactor), + NSAppUnitsToDoublePixels(aBounds.height, aFactor)); + + RectDouble maxBounds = RectDouble(double(nscoord_MIN) / aFactor * 0.5, + double(nscoord_MIN) / aFactor * 0.5, + double(nscoord_MAX) / aFactor, + double(nscoord_MAX) / aFactor); + + image = aMatrix.TransformAndClipBounds(image, maxBounds); + + return RoundGfxRectToAppRect(ThebesRect(image), aFactor); +} + nsPoint nsLayoutUtils::MatrixTransformPoint(const nsPoint &aPoint, const Matrix4x4 &aMatrix, float aFactor) { gfxPoint image = gfxPoint(NSAppUnitsToFloatPixels(aPoint.x, aFactor), NSAppUnitsToFloatPixels(aPoint.y, aFactor)); image = aMatrix.TransformPoint(image); return nsPoint(NSFloatPixelsToAppUnits(float(image.x), aFactor), @@ -2682,24 +2701,24 @@ nsLayoutUtils::FrameHasDisplayPort(nsIFr if (aScrolledFrame && aScrolledFrame != sf->GetScrolledFrame()) { return false; } return true; } return false; } -Matrix4x4 +Matrix4x4Flagged nsLayoutUtils::GetTransformToAncestor(nsIFrame *aFrame, const nsIFrame *aAncestor, uint32_t aFlags, nsIFrame** aOutAncestor) { nsIFrame* parent; - Matrix4x4 ctm; + Matrix4x4Flagged ctm; if (aFrame == aAncestor) { return ctm; } ctm = aFrame->GetTransformMatrix(aAncestor, &parent, aFlags); while (parent && parent != aAncestor && (!(aFlags & nsIFrame::STOP_AT_STACKING_CONTEXT_AND_DISPLAY_PORT) || (!parent->HasAnyStateBits(NS_FRAME_OUT_OF_FLOW) && !parent->IsStackingContext() && @@ -2713,54 +2732,54 @@ nsLayoutUtils::GetTransformToAncestor(ns *aOutAncestor = parent; } return ctm; } gfxSize nsLayoutUtils::GetTransformToAncestorScale(nsIFrame* aFrame) { - Matrix4x4 transform = GetTransformToAncestor(aFrame, + Matrix4x4Flagged transform = GetTransformToAncestor(aFrame, nsLayoutUtils::GetDisplayRootFrame(aFrame)); Matrix transform2D; if (transform.Is2D(&transform2D)) { return ThebesMatrix(transform2D).ScaleFactors(true); } return gfxSize(1, 1); } -static Matrix4x4 +static Matrix4x4Flagged GetTransformToAncestorExcludingAnimated(nsIFrame* aFrame, const nsIFrame* aAncestor) { nsIFrame* parent; - Matrix4x4 ctm; + Matrix4x4Flagged ctm; if (aFrame == aAncestor) { return ctm; } if (ActiveLayerTracker::IsScaleSubjectToAnimation(aFrame)) { return ctm; } ctm = aFrame->GetTransformMatrix(aAncestor, &parent); while (parent && parent != aAncestor) { if (ActiveLayerTracker::IsScaleSubjectToAnimation(parent)) { - return Matrix4x4(); + return Matrix4x4Flagged(); } if (!parent->Extend3DContext()) { ctm.ProjectTo2D(); } ctm = ctm * parent->GetTransformMatrix(aAncestor, &parent); } return ctm; } gfxSize nsLayoutUtils::GetTransformToAncestorScaleExcludingAnimated(nsIFrame* aFrame) { - Matrix4x4 transform = GetTransformToAncestorExcludingAnimated(aFrame, + Matrix4x4Flagged transform = GetTransformToAncestorExcludingAnimated(aFrame, nsLayoutUtils::GetDisplayRootFrame(aFrame)); Matrix transform2D; if (transform.Is2D(&transform2D)) { return ThebesMatrix(transform2D).ScaleFactors(true); } return gfxSize(1, 1); } @@ -2795,22 +2814,22 @@ nsLayoutUtils::FindNearestCommonAncestor nsLayoutUtils::TransformResult nsLayoutUtils::TransformPoints(nsIFrame* aFromFrame, nsIFrame* aToFrame, uint32_t aPointCount, CSSPoint* aPoints) { nsIFrame* nearestCommonAncestor = FindNearestCommonAncestorFrame(aFromFrame, aToFrame); if (!nearestCommonAncestor) { return NO_COMMON_ANCESTOR; } - Matrix4x4 downToDest = GetTransformToAncestor(aToFrame, nearestCommonAncestor); + Matrix4x4Flagged downToDest = GetTransformToAncestor(aToFrame, nearestCommonAncestor); if (downToDest.IsSingular()) { return NONINVERTIBLE_TRANSFORM; } downToDest.Invert(); - Matrix4x4 upToAncestor = GetTransformToAncestor(aFromFrame, nearestCommonAncestor); + Matrix4x4Flagged upToAncestor = GetTransformToAncestor(aFromFrame, nearestCommonAncestor); CSSToLayoutDeviceScale devPixelsPerCSSPixelFromFrame = aFromFrame->PresContext()->CSSToDevPixelScale(); CSSToLayoutDeviceScale devPixelsPerCSSPixelToFrame = aToFrame->PresContext()->CSSToDevPixelScale(); for (uint32_t i = 0; i < aPointCount; ++i) { LayoutDevicePoint devPixels = aPoints[i] * devPixelsPerCSSPixelFromFrame; // What should the behaviour be if some of the points aren't invertible // and others are? Just assume all points are for now. @@ -2827,22 +2846,22 @@ nsLayoutUtils::TransformPoints(nsIFrame* nsLayoutUtils::TransformResult nsLayoutUtils::TransformPoint(nsIFrame* aFromFrame, nsIFrame* aToFrame, nsPoint& aPoint) { nsIFrame* nearestCommonAncestor = FindNearestCommonAncestorFrame(aFromFrame, aToFrame); if (!nearestCommonAncestor) { return NO_COMMON_ANCESTOR; } - Matrix4x4 downToDest = GetTransformToAncestor(aToFrame, nearestCommonAncestor); + Matrix4x4Flagged downToDest = GetTransformToAncestor(aToFrame, nearestCommonAncestor); if (downToDest.IsSingular()) { return NONINVERTIBLE_TRANSFORM; } downToDest.Invert(); - Matrix4x4 upToAncestor = GetTransformToAncestor(aFromFrame, nearestCommonAncestor); + Matrix4x4Flagged upToAncestor = GetTransformToAncestor(aFromFrame, nearestCommonAncestor); float devPixelsPerAppUnitFromFrame = 1.0f / aFromFrame->PresContext()->AppUnitsPerDevPixel(); float devPixelsPerAppUnitToFrame = 1.0f / aToFrame->PresContext()->AppUnitsPerDevPixel(); Point4D toDevPixels = downToDest.ProjectPoint( upToAncestor.TransformPoint(Point(aPoint.x * devPixelsPerAppUnitFromFrame, aPoint.y * devPixelsPerAppUnitFromFrame))); @@ -2859,22 +2878,22 @@ nsLayoutUtils::TransformPoint(nsIFrame* nsLayoutUtils::TransformResult nsLayoutUtils::TransformRect(nsIFrame* aFromFrame, nsIFrame* aToFrame, nsRect& aRect) { nsIFrame* nearestCommonAncestor = FindNearestCommonAncestorFrame(aFromFrame, aToFrame); if (!nearestCommonAncestor) { return NO_COMMON_ANCESTOR; } - Matrix4x4 downToDest = GetTransformToAncestor(aToFrame, nearestCommonAncestor); + Matrix4x4Flagged downToDest = GetTransformToAncestor(aToFrame, nearestCommonAncestor); if (downToDest.IsSingular()) { return NONINVERTIBLE_TRANSFORM; } downToDest.Invert(); - Matrix4x4 upToAncestor = GetTransformToAncestor(aFromFrame, nearestCommonAncestor); + Matrix4x4Flagged upToAncestor = GetTransformToAncestor(aFromFrame, nearestCommonAncestor); float devPixelsPerAppUnitFromFrame = 1.0f / aFromFrame->PresContext()->AppUnitsPerDevPixel(); float devPixelsPerAppUnitToFrame = 1.0f / aToFrame->PresContext()->AppUnitsPerDevPixel(); gfx::Rect toDevPixels = downToDest.ProjectRectBounds( upToAncestor.ProjectRectBounds( gfx::Rect(aRect.x * devPixelsPerAppUnitFromFrame, @@ -2953,17 +2972,17 @@ nsLayoutUtils::ClampRectToScrollFrames(n closestScrollFrame->GetParent(), LayoutFrameType::Scroll); } return resultRect; } bool nsLayoutUtils::GetLayerTransformForFrame(nsIFrame* aFrame, - Matrix4x4* aTransform) + Matrix4x4Flagged* aTransform) { // FIXME/bug 796690: we can sometimes compute a transform in these // cases, it just increases complexity considerably. Punt for now. if (aFrame->Extend3DContext() || aFrame->HasTransformGetter()) { return false; } nsIFrame* root = nsLayoutUtils::GetDisplayRootFrame(aFrame); @@ -2995,36 +3014,36 @@ nsLayoutUtils::GetLayerTransformForFrame } static bool TransformGfxPointFromAncestor(nsIFrame *aFrame, const Point &aPoint, nsIFrame *aAncestor, Point* aOut) { - Matrix4x4 ctm = nsLayoutUtils::GetTransformToAncestor(aFrame, aAncestor); + Matrix4x4Flagged ctm = nsLayoutUtils::GetTransformToAncestor(aFrame, aAncestor); ctm.Invert(); Point4D point = ctm.ProjectPoint(aPoint); if (!point.HasPositiveWCoord()) { return false; } *aOut = point.As2DPoint(); return true; } static Rect TransformGfxRectToAncestor(nsIFrame *aFrame, const Rect &aRect, const nsIFrame *aAncestor, bool* aPreservesAxisAlignedRectangles = nullptr, - Maybe* aMatrixCache = nullptr, + Maybe* aMatrixCache = nullptr, bool aStopAtStackingContextAndDisplayPort = false, nsIFrame** aOutAncestor = nullptr) { - Matrix4x4 ctm; + Matrix4x4Flagged ctm; if (aMatrixCache && *aMatrixCache) { // We are given a matrix to use, so use it ctm = aMatrixCache->value(); } else { // Else, compute it uint32_t flags = 0; if (aStopAtStackingContextAndDisplayPort) { flags |= nsIFrame::STOP_AT_STACKING_CONTEXT_AND_DISPLAY_PORT; @@ -3087,17 +3106,17 @@ nsLayoutUtils::TransformAncestorPointToF NSFloatPixelsToAppUnits(float(result.y), factor)); } nsRect nsLayoutUtils::TransformFrameRectToAncestor(nsIFrame* aFrame, const nsRect& aRect, const nsIFrame* aAncestor, bool* aPreservesAxisAlignedRectangles /* = nullptr */, - Maybe* aMatrixCache /* = nullptr */, + Maybe* aMatrixCache /* = nullptr */, bool aStopAtStackingContextAndDisplayPort /* = false */, nsIFrame** aOutAncestor /* = nullptr */) { SVGTextFrame* text = GetContainingSVGTextFrame(aFrame); float srcAppUnitsPerDevPixel = aFrame->PresContext()->AppUnitsPerDevPixel(); Rect result; @@ -9558,17 +9577,17 @@ nsLayoutUtils::GetTouchActionFromFrame(n /* static */ void nsLayoutUtils::TransformToAncestorAndCombineRegions( const nsRegion& aRegion, nsIFrame* aFrame, const nsIFrame* aAncestorFrame, nsRegion* aPreciseTargetDest, nsRegion* aImpreciseTargetDest, - Maybe* aMatrixCache, + Maybe* aMatrixCache, const DisplayItemClip* aClip) { if (aRegion.IsEmpty()) { return; } bool isPrecise; RegionBuilder transformedRegion; for (nsRegion::RectIterator it = aRegion.RectIter(); !it.Done(); it.Next()) { diff --git a/layout/base/nsLayoutUtils.h b/layout/base/nsLayoutUtils.h --- a/layout/base/nsLayoutUtils.h +++ b/layout/base/nsLayoutUtils.h @@ -152,16 +152,17 @@ class nsLayoutUtils typedef mozilla::gfx::ExtendMode ExtendMode; typedef mozilla::gfx::SamplingFilter SamplingFilter; typedef mozilla::gfx::Float Float; typedef mozilla::gfx::Point Point; typedef mozilla::gfx::Rect Rect; typedef mozilla::gfx::RectDouble RectDouble; typedef mozilla::gfx::Size Size; typedef mozilla::gfx::Matrix4x4 Matrix4x4; + typedef mozilla::gfx::Matrix4x4Flagged Matrix4x4Flagged; typedef mozilla::gfx::RectCornerRadii RectCornerRadii; typedef mozilla::gfx::StrokeOptions StrokeOptions; typedef mozilla::image::ImgDrawResult ImgDrawResult; public: typedef mozilla::layers::FrameMetrics FrameMetrics; typedef mozilla::layers::ScrollMetadata ScrollMetadata; typedef FrameMetrics::ViewID ViewID; @@ -850,27 +851,27 @@ public: * recomputing the matrix. * non-null pointer to a non-empty Matrix4x4 - The provided matrix will be used * as the transform matrix and applied to the rect. */ static nsRect TransformFrameRectToAncestor(nsIFrame* aFrame, const nsRect& aRect, const nsIFrame* aAncestor, bool* aPreservesAxisAlignedRectangles = nullptr, - mozilla::Maybe* aMatrixCache = nullptr, + mozilla::Maybe* aMatrixCache = nullptr, bool aStopAtStackingContextAndDisplayPort = false, nsIFrame** aOutAncestor = nullptr); /** * Gets the transform for aFrame relative to aAncestor. Pass null for * aAncestor to go up to the root frame. aInCSSUnits set to true will * return CSS units, set to false (the default) will return App units. */ - static Matrix4x4 GetTransformToAncestor(nsIFrame *aFrame, + static Matrix4x4Flagged GetTransformToAncestor(nsIFrame *aFrame, const nsIFrame *aAncestor, uint32_t aFlags = 0, nsIFrame** aOutAncestor = nullptr); /** * Gets the scale factors of the transform for aFrame relative to the root * frame if this transform is 2D, or the identity scale factors otherwise. */ @@ -953,17 +954,17 @@ public: /** * Return true if a "layer transform" could be computed for aFrame, * and optionally return the computed transform. The returned * transform is what would be set on the layer currently if a layers * transaction were opened at the time this helper is called. */ static bool GetLayerTransformForFrame(nsIFrame* aFrame, - Matrix4x4* aTransform); + Matrix4x4Flagged* aTransform); /** * Given a point in the global coordinate space, returns that point expressed * in the coordinate system of aFrame. This effectively inverts all * transforms between this point and the root frame. * * @param aFrame The frame that acts as the coordinate space container. * @param aPoint The point, in the global space, to get in the frame-local space. @@ -989,16 +990,18 @@ public: * * @param aBounds The rectangle to transform. * @param aMatrix The matrix to transform it with. * @param aFactor The number of app units per graphics unit. * @return The smallest rect that contains the image of aBounds. */ static nsRect MatrixTransformRect(const nsRect &aBounds, const Matrix4x4 &aMatrix, float aFactor); + static nsRect MatrixTransformRect(const nsRect &aBounds, + const Matrix4x4Flagged &aMatrix, float aFactor); /** * Helper function that, given a point and a matrix, returns the image * of that point under the matrix transform. * * @param aPoint The point to transform. * @param aMatrix The matrix to transform it with. * @param aFactor The number of app units per graphics unit. @@ -2731,17 +2734,17 @@ public: */ static void TransformToAncestorAndCombineRegions( const nsRegion& aRegion, nsIFrame* aFrame, const nsIFrame* aAncestorFrame, nsRegion* aPreciseTargetDest, nsRegion* aImpreciseTargetDest, - mozilla::Maybe* aMatrixCache, + mozilla::Maybe* aMatrixCache, const mozilla::DisplayItemClip* aClip); /** * Populate aOutSize with the size of the content viewer corresponding * to the given prescontext. Return true if the size was set, false * otherwise. */ static bool diff --git a/layout/base/tests/test_getBoxQuads_convertPointRectQuad.html b/layout/base/tests/test_getBoxQuads_convertPointRectQuad.html --- a/layout/base/tests/test_getBoxQuads_convertPointRectQuad.html +++ b/layout/base/tests/test_getBoxQuads_convertPointRectQuad.html @@ -1,9 +1,9 @@ - +

diff --git a/layout/forms/nsComboboxControlFrame.cpp b/layout/forms/nsComboboxControlFrame.cpp --- a/layout/forms/nsComboboxControlFrame.cpp +++ b/layout/forms/nsComboboxControlFrame.cpp @@ -488,17 +488,17 @@ nsComboboxControlFrame::ReflowDropdown(n nsPoint nsComboboxControlFrame::GetCSSTransformTranslation() { nsIFrame* frame = this; bool is3DTransform = false; Matrix transform; while (frame) { nsIFrame* parent; - Matrix4x4 ctm = frame->GetTransformMatrix(nullptr, &parent); + Matrix4x4Flagged ctm = frame->GetTransformMatrix(nullptr, &parent); Matrix matrix; if (ctm.Is2D(&matrix)) { transform = transform * matrix; } else { is3DTransform = true; break; } frame = parent; diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -6861,17 +6861,17 @@ nsIFrame::GetNearestWidget(nsPoint& aOff nsPoint offsetToView; nsPoint offsetToWidget; nsIWidget* widget = GetClosestView(&offsetToView)->GetNearestWidget(&offsetToWidget); aOffset = offsetToView + offsetToWidget; return widget; } -Matrix4x4 +Matrix4x4Flagged nsIFrame::GetTransformMatrix(const nsIFrame* aStopAtAncestor, nsIFrame** aOutAncestor, uint32_t aFlags) { NS_PRECONDITION(aOutAncestor, "Need a place to put the ancestor!"); /* If we're transformed, we want to hand back the combination * transform/translate matrix that will apply our current transform, then @@ -6922,17 +6922,17 @@ nsIFrame::GetTransformMatrix(const nsIFr screenBounds.TopLeft() - toplevelScreenBounds.TopLeft(); Matrix4x4 transformToTop; transformToTop._41 = translation.x; transformToTop._42 = translation.y; *aOutAncestor = docRootFrame; Matrix4x4 docRootTransformToTop = - nsLayoutUtils::GetTransformToAncestor(docRootFrame, nullptr); + nsLayoutUtils::GetTransformToAncestor(docRootFrame, nullptr).GetMatrix(); if (docRootTransformToTop.IsSingular()) { NS_WARNING("Containing document is invisible, we can't compute a valid transform"); } else { docRootTransformToTop.Invert(); return transformToTop * docRootTransformToTop; } } } @@ -7210,17 +7210,17 @@ nsIFrame::TryUpdateTransformOnly(Layer** if (DoesLayerOrAncestorsHaveOutOfDateFrameMetrics(layer)) { // At least one scroll frame that can affect the position of this layer // has changed its scroll offset since the last paint. Schedule a full // paint to make sure that this layer's transform and all the frame // metrics that affect it are in sync. return false; } - gfx::Matrix4x4 transform3d; + gfx::Matrix4x4Flagged transform3d; if (!nsLayoutUtils::GetLayerTransformForFrame(this, &transform3d)) { // We're not able to compute a layer transform that we know would // be used at the next layers transaction, so we can't only update // the transform and will need to schedule an invalidating paint. return false; } gfx::Matrix transform; gfx::Matrix previousTransform; @@ -7235,17 +7235,17 @@ nsIFrame::TryUpdateTransformOnly(Layer** if (!transform3d.Is2D(&transform) || !layer->GetBaseTransform().Is2D(&previousTransform) || !gfx::FuzzyEqual(transform._11, previousTransform._11, kError) || !gfx::FuzzyEqual(transform._22, previousTransform._22, kError) || !gfx::FuzzyEqual(transform._21, previousTransform._21, kError) || !gfx::FuzzyEqual(transform._12, previousTransform._12, kError)) { return false; } - layer->SetBaseTransformForNextTransaction(transform3d); + layer->SetBaseTransformForNextTransaction(transform3d.GetMatrix()); *aLayerResult = layer; return true; } bool nsIFrame::IsInvalid(nsRect& aRect) { if (!HasAnyStateBits(NS_FRAME_NEEDS_PAINT)) { diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h --- a/layout/generic/nsIFrame.h +++ b/layout/generic/nsIFrame.h @@ -617,16 +617,17 @@ public: typedef mozilla::layout::FrameChildList ChildList; typedef mozilla::layout::FrameChildListID ChildListID; typedef mozilla::layout::FrameChildListIDs ChildListIDs; typedef mozilla::layout::FrameChildListIterator ChildListIterator; typedef mozilla::layout::FrameChildListArrayIterator ChildListArrayIterator; typedef mozilla::gfx::DrawTarget DrawTarget; typedef mozilla::gfx::Matrix Matrix; typedef mozilla::gfx::Matrix4x4 Matrix4x4; + typedef mozilla::gfx::Matrix4x4Flagged Matrix4x4Flagged; typedef mozilla::Sides Sides; typedef mozilla::LogicalSides LogicalSides; typedef mozilla::SmallPointerArray DisplayItemDataArray; typedef nsQueryFrame::ClassID ClassID; NS_DECL_QUERYFRAME_TARGET(nsIFrame) explicit nsIFrame(ClassID aID) @@ -2851,19 +2852,19 @@ public: * ancestor (if preserve-3d). * @return A Matrix4x4 that converts points in this frame's coordinate space * into points in aOutAncestor's coordinate space. */ enum { IN_CSS_UNITS = 1 << 0, STOP_AT_STACKING_CONTEXT_AND_DISPLAY_PORT = 1 << 1 }; - Matrix4x4 GetTransformMatrix(const nsIFrame* aStopAtAncestor, - nsIFrame **aOutAncestor, - uint32_t aFlags = 0); + Matrix4x4Flagged GetTransformMatrix(const nsIFrame* aStopAtAncestor, + nsIFrame **aOutAncestor, + uint32_t aFlags = 0); /** * Bit-flags to pass to IsFrameOfType() */ enum { eMathML = 1 << 0, eSVG = 1 << 1, eSVGForeignObject = 1 << 2, diff --git a/layout/painting/FrameLayerBuilder.cpp b/layout/painting/FrameLayerBuilder.cpp --- a/layout/painting/FrameLayerBuilder.cpp +++ b/layout/painting/FrameLayerBuilder.cpp @@ -3325,17 +3325,17 @@ void ContainerState::FinishPaintedLayerD containingPaintedLayerData->mReferenceFrame); if (inactiveLayerClip) { rect = inactiveLayerClip->ApplyNonRoundedIntersection(rect); } containingPaintedLayerData->mMaybeHitRegion.Or( containingPaintedLayerData->mMaybeHitRegion, rect); containingPaintedLayerData->mMaybeHitRegion.SimplifyOutward(8); } - Maybe matrixCache; + Maybe matrixCache; nsLayoutUtils::TransformToAncestorAndCombineRegions( data->mHitRegion, mContainerReferenceFrame, containingPaintedLayerData->mReferenceFrame, &containingPaintedLayerData->mHitRegion, &containingPaintedLayerData->mMaybeHitRegion, &matrixCache, inactiveLayerClip); @@ -5858,17 +5858,17 @@ FrameLayerBuilder::GetPaintedLayerScaleF } nsIFrame* root = presCtx->PresShell()->GetRootFrame(); MOZ_ASSERT(root); float resolution = presCtx->PresShell()->GetResolution(); - Matrix4x4 transform = Matrix4x4::Scaling(resolution, resolution, 1.0); + Matrix4x4Flagged transform = Matrix4x4::Scaling(resolution, resolution, 1.0); if (aFrame != root) { // aTransform is applied first, then the scale is applied to the result transform = nsLayoutUtils::GetTransformToAncestor(aFrame, root) * transform; } Matrix transform2d; if (transform.CanDraw2D(&transform2d)) { return ThebesMatrix(transform2d).ScaleFactors(true); diff --git a/layout/painting/nsDisplayList.cpp b/layout/painting/nsDisplayList.cpp --- a/layout/painting/nsDisplayList.cpp +++ b/layout/painting/nsDisplayList.cpp @@ -1901,17 +1901,17 @@ nsDisplayListBuilder::AdjustWindowDraggi nsIFrame* referenceFrame = const_cast(FindReferenceFrameFor(aFrame)); if (IsInTransform()) { // Only support 2d rectilinear transforms. Transform support is needed for // the horizontal flip transform that's applied to the urlbar textbox in // RTL mode - it should be able to exclude itself from the draggable region. referenceFrameToRootReferenceFrame = ViewAs( - nsLayoutUtils::GetTransformToAncestor(referenceFrame, mReferenceFrame)); + nsLayoutUtils::GetTransformToAncestor(referenceFrame, mReferenceFrame).GetMatrix()); Matrix referenceFrameToRootReferenceFrame2d; if (!referenceFrameToRootReferenceFrame.Is2D(&referenceFrameToRootReferenceFrame2d) || !referenceFrameToRootReferenceFrame2d.IsRectilinear()) { return; } } else { MOZ_ASSERT(referenceFrame == mReferenceFrame, "referenceFrameToRootReferenceFrame needs to be adjusted"); @@ -8359,17 +8359,17 @@ static bool IsFrameVisible(nsIFrame* aFr return false; } if (aFrame->BackfaceIsHidden() && aMatrix.IsBackfaceVisible()) { return false; } return true; } -const Matrix4x4& +const Matrix4x4Flagged& nsDisplayTransform::GetTransform() const { if (mTransform.IsIdentity()) { float scale = mFrame->PresContext()->AppUnitsPerDevPixel(); Point3D newOrigin = Point3D(NSAppUnitsToFloatPixels(mToReferenceFrame.x, scale), NSAppUnitsToFloatPixels(mToReferenceFrame.y, scale), 0.0f); @@ -8397,17 +8397,17 @@ nsDisplayTransform::GetTransformForRende // If aOutOrigin is provided, put the offset to origin into it, because // we need to keep it separate for webrender. The combination of // *aOutOrigin and the returned matrix here should always be equivalent // to what GetTransform() would have returned. float scale = mFrame->PresContext()->AppUnitsPerDevPixel(); *aOutOrigin = LayoutDevicePoint::FromAppUnits(ToReferenceFrame(), scale); return GetResultingTransformMatrix(mFrame, nsPoint(0, 0), scale, INCLUDE_PERSPECTIVE); } - return GetTransform(); + return GetTransform().GetMatrix(); } MOZ_ASSERT(!mTransformGetter); float scale = mFrame->PresContext()->AppUnitsPerDevPixel(); // Don't include perspective transform, or the offset to origin, since // nsDisplayPerspective will handle both of those. return GetResultingTransformMatrix(mFrame, ToReferenceFrame(), scale, 0); } @@ -8415,17 +8415,17 @@ nsDisplayTransform::GetTransformForRende const Matrix4x4& nsDisplayTransform::GetAccumulatedPreserved3DTransform(nsDisplayListBuilder* aBuilder) { MOZ_ASSERT(!mFrame->Extend3DContext() || IsLeafOf3DContext()); // XXX: should go back to fix mTransformGetter. if (!mTransformPreserves3DInited) { mTransformPreserves3DInited = true; if (!IsLeafOf3DContext()) { - mTransformPreserves3D = GetTransform(); + mTransformPreserves3D = GetTransform().GetMatrix(); return mTransformPreserves3D; } const nsIFrame* establisher; // Establisher of the 3D rendering context. for (establisher = mFrame; establisher && establisher->Combines3DTransformWithAncestors(); establisher = establisher->GetInFlowParent()) { } @@ -8526,17 +8526,17 @@ nsDisplayTransform::CreateWebRenderComma aManager, aDisplayListBuilder); } bool nsDisplayTransform::UpdateScrollData(mozilla::layers::WebRenderScrollData* aData, mozilla::layers::WebRenderLayerScrollData* aLayerData) { if (aLayerData) { - aLayerData->SetTransform(GetTransform()); + aLayerData->SetTransform(GetTransform().GetMatrix()); aLayerData->SetTransformIsPerspective(mFrame->HasPerspective()); } return true; } already_AddRefed nsDisplayTransform::BuildLayer(nsDisplayListBuilder *aBuilder, LayerManager *aManager, const ContainerLayerParameters& aContainerParameters) @@ -8819,17 +8819,17 @@ nsDisplayTransform::ComputeBounds(nsDisp * not depend on transforming bounds level by level. * * Here, it applies accumulated transforms on the leaf frames of the * 3d rendering context, and track and accmulate bounds at * nsDisplayListBuilder. */ nsDisplayListBuilder::AutoAccumulateTransform accTransform(aBuilder); - accTransform.Accumulate(GetTransform()); + accTransform.Accumulate(GetTransform().GetMatrix()); if (!IsLeafOf3DContext()) { // Do not dive into another 3D context. mStoredList.DoUpdateBoundsPreserves3D(aBuilder); } /* For Preserves3D, it is bounds of only children as leaf frames. * For non-leaf frames, their bounds are accumulated and kept at @@ -8868,17 +8868,17 @@ nsDisplayTransform::GetOpaqueRegion(nsDi bool* aSnap) const { *aSnap = false; nsRect untransformedVisible; if (!UntransformVisibleRect(aBuilder, &untransformedVisible)) { return nsRegion(); } - const Matrix4x4& matrix = GetTransform(); + const Matrix4x4Flagged& matrix = GetTransform(); nsRegion result; Matrix matrix2d; bool tmpSnap; if (matrix.Is2D(&matrix2d) && matrix2d.PreservesAxisAlignedRectangles() && mStoredList.GetOpaqueRegion(aBuilder, &tmpSnap).Contains(untransformedVisible)) { result = mVisibleRect.Intersect(GetBounds(aBuilder, &tmpSnap)); @@ -8892,17 +8892,17 @@ nsDisplayTransform::GetOpaqueRegion(nsDi */ Maybe nsDisplayTransform::IsUniform(nsDisplayListBuilder *aBuilder) const { nsRect untransformedVisible; if (!UntransformVisibleRect(aBuilder, &untransformedVisible)) { return Nothing(); } - const Matrix4x4& matrix = GetTransform(); + const Matrix4x4Flagged& matrix = GetTransform(); Matrix matrix2d; if (matrix.Is2D(&matrix2d) && matrix2d.PreservesAxisAlignedRectangles() && mStoredList.GetVisibleRect().Contains(untransformedVisible)) { return mStoredList.IsUniform(aBuilder); } @@ -8967,17 +8967,17 @@ bool nsDisplayTransform::UntransformRect result = transform.Inverse().ProjectRectBounds(result, childGfxBounds); *aOutRect = nsLayoutUtils::RoundGfxRectToAppRect(ThebesRect(result), factor); return true; } bool nsDisplayTransform::UntransformVisibleRect(nsDisplayListBuilder* aBuilder, nsRect *aOutRect) const { - const Matrix4x4& matrix = GetTransform(); + const Matrix4x4Flagged& matrix = GetTransform(); if (matrix.IsSingular()) return false; // GetTransform always operates in dev pixels. float factor = mFrame->PresContext()->AppUnitsPerDevPixel(); RectDouble result(NSAppUnitsToFloatPixels(mVisibleRect.x, factor), NSAppUnitsToFloatPixels(mVisibleRect.y, factor), NSAppUnitsToFloatPixels(mVisibleRect.width, factor), @@ -8996,17 +8996,17 @@ bool nsDisplayTransform::UntransformVisi *aOutRect = nsLayoutUtils::RoundGfxRectToAppRect(ThebesRect(result), factor); return true; } void nsDisplayTransform::WriteDebugInfo(std::stringstream& aStream) { - AppendToString(aStream, GetTransform()); + AppendToString(aStream, GetTransform().GetMatrix()); if (IsTransformSeparator()) { aStream << " transform-separator"; } if (IsLeafOf3DContext()) { aStream << " 3d-context-leaf"; } if (mFrame->Extend3DContext()) { aStream << " extends-3d-context"; diff --git a/layout/painting/nsDisplayList.h b/layout/painting/nsDisplayList.h --- a/layout/painting/nsDisplayList.h +++ b/layout/painting/nsDisplayList.h @@ -5927,16 +5927,17 @@ private: * * INVARIANT: The wrapped frame is transformed or we supplied a transform getter * function. * INVARIANT: The wrapped frame is non-null. */ class nsDisplayTransform: public nsDisplayItem { typedef mozilla::gfx::Matrix4x4 Matrix4x4; + typedef mozilla::gfx::Matrix4x4Flagged Matrix4x4Flagged; typedef mozilla::gfx::Point3D Point3D; /* * Avoid doing UpdateBounds() during construction. */ class StoreList : public nsDisplayWrapList { public: StoreList(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, @@ -6106,17 +6107,17 @@ public: }; /** * We include the perspective matrix from our containing block for the * purposes of visibility calculations, but we exclude it from the transform * we set on the layer (for rendering), since there will be an * nsDisplayPerspective created for that. */ - const Matrix4x4& GetTransform() const; + const Matrix4x4Flagged& GetTransform() const; Matrix4x4 GetTransformForRendering(mozilla::LayoutDevicePoint* aOutOrigin = nullptr); /** * Return the transform that is aggregation of all transform on the * preserves3d chain. */ const Matrix4x4& GetAccumulatedPreserved3DTransform(nsDisplayListBuilder* aBuilder); @@ -6307,17 +6308,17 @@ private: static Matrix4x4 GetResultingTransformMatrixInternal(const FrameTransformProperties& aProperties, const nsPoint& aOrigin, float aAppUnitsPerPixel, uint32_t aFlags, const nsRect* aBoundsOverride); StoreList mStoredList; - mutable Matrix4x4 mTransform; + mutable Matrix4x4Flagged mTransform; // Accumulated transform of ancestors on the preserves-3d chain. Matrix4x4 mTransformPreserves3D; ComputeTransformFunction mTransformGetter; RefPtr mAnimatedGeometryRootForChildren; RefPtr mAnimatedGeometryRootForScrollMetadata; nsRect mChildrenVisibleRect; uint32_t mIndex; mutable nsRect mBounds;