Bug 1207734 - Part 7. Pass a combined transform list to the nsDisplayTransform.
MozReview-Commit-ID: 9kM3U9zp0My
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -8166,17 +8166,17 @@ nsDisplayTransform::ComputePerspectiveMa
aOutMatrix.ChangeBasis(Point3D(perspectiveOrigin.x, perspectiveOrigin.y, 0));
return true;
}
nsDisplayTransform::FrameTransformProperties::FrameTransformProperties(const nsIFrame* aFrame,
float aAppUnitsPerPixel,
const nsRect* aBoundsOverride)
: mFrame(aFrame)
- , mTransformList(aFrame->StyleDisplay()->mSpecifiedTransform)
+ , mTransformList(aFrame->StyleDisplay()->GetCombinedTransform())
, mToTransformOrigin(GetDeltaToTransformOrigin(aFrame, aAppUnitsPerPixel, aBoundsOverride))
{
}
/* Wraps up the transform matrix in a change-of-basis matrix pair that
* translates from local coordinate space to transform coordinate space, then
* hands it back.
*/
--- a/layout/style/nsCSSValue.cpp
+++ b/layout/style/nsCSSValue.cpp
@@ -2499,16 +2499,36 @@ nsCSSValueSharedList::SizeOfIncludingThi
size_t n = 0;
if (mRefCnt <= 1) {
n += aMallocSizeOf(this);
n += mHead->SizeOfIncludingThis(aMallocSizeOf);
}
return n;
}
+already_AddRefed<nsCSSValueSharedList>
+nsCSSValueSharedList::Clone() const
+{
+ if (!mHead) {
+ return do_AddRef(new nsCSSValueSharedList());
+ }
+
+ RefPtr<nsCSSValueSharedList> result = new nsCSSValueSharedList(mHead->Clone());
+
+ nsCSSValueList* head = result->mHead;
+ for (const nsCSSValueList* list = mHead->mNext; list != nullptr; list = list->mNext) {
+ nsCSSValueList* cloned = list->Clone();
+ head->mNext = cloned;
+ head = head->mNext;
+ }
+ head->mNext = nullptr;
+
+ return result.forget();
+}
+
// --- nsCSSRect -----------------
nsCSSRect::nsCSSRect(void)
{
MOZ_COUNT_CTOR(nsCSSRect);
}
nsCSSRect::nsCSSRect(const nsCSSRect& aCopy)
--- a/layout/style/nsCSSValue.h
+++ b/layout/style/nsCSSValue.h
@@ -1177,16 +1177,18 @@ struct nsCSSValueSharedList final {
}
// Takes ownership of aList.
explicit nsCSSValueSharedList(nsCSSValueList* aList)
: mHead(aList)
{
}
+ already_AddRefed<nsCSSValueSharedList> Clone() const;
+
private:
// Private destructor, to discourage deletion outside of Release():
~nsCSSValueSharedList();
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(nsCSSValueSharedList)
void AppendToString(nsCSSPropertyID aProperty, nsAString& aResult) const;
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -3997,16 +3997,62 @@ nsStyleDisplay::CalcDifference(const nsS
mAnimationIterationCountCount != aNewData.mAnimationIterationCountCount ||
mScrollSnapCoordinate != aNewData.mScrollSnapCoordinate)) {
hint |= nsChangeHint_NeutralChange;
}
return hint;
}
+already_AddRefed<nsCSSValueSharedList>
+nsStyleDisplay::GetCombinedTransform() const
+{
+ if (!mSpecifiedTransform && !mSpecifiedScale && !mSpecifiedTranslate &&
+ !mSpecifiedRotate) {
+ return nullptr;
+ }
+
+ // https://drafts.csswg.org/css-transforms-2/#ctm
+ // translate > rotate > scale > transform
+ nsTArray<nsCSSValueList*> lists;
+ if (mSpecifiedTranslate) {
+ RefPtr<nsCSSValueSharedList> scale = mSpecifiedTranslate->Clone();
+ lists.AppendElement(scale->mHead);
+ scale->mHead = nullptr;
+ }
+
+ if (mSpecifiedRotate) {
+ RefPtr<nsCSSValueSharedList> scale = mSpecifiedRotate->Clone();
+ lists.AppendElement(scale->mHead);
+ scale->mHead = nullptr;
+ }
+
+ if (mSpecifiedScale) {
+ RefPtr<nsCSSValueSharedList> scale = mSpecifiedScale->Clone();
+ lists.AppendElement(scale->mHead);
+ scale->mHead = nullptr;
+ }
+
+ if (mSpecifiedTransform) {
+ RefPtr<nsCSSValueSharedList> transform = mSpecifiedTransform->Clone();
+ lists.AppendElement(transform->mHead);
+ transform->mHead = nullptr;
+ }
+
+ // Concat all lists.
+ MOZ_ASSERT(lists.Length());
+ RefPtr<nsCSSValueSharedList> result = new nsCSSValueSharedList();
+ for (uint32_t i = 0; i < lists.Length() - 1; i++) {
+ lists[i]->mNext = lists[i + 1];
+ }
+
+ // TODO: should we cache this combined list?
+ result->mHead = lists[0];
+ return result.forget();
+}
// --------------------
// nsStyleVisibility
//
nsStyleVisibility::nsStyleVisibility(const nsPresContext* aContext)
: mDirection(aContext->GetBidi() == IBMBIDI_TEXTDIRECTION_RTL
? NS_STYLE_DIRECTION_RTL
: NS_STYLE_DIRECTION_LTR)
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -2740,16 +2740,18 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsSt
return mSpecifiedTransform != nullptr ||
mSpecifiedRotate != nullptr ||
mSpecifiedTranslate != nullptr ||
mSpecifiedScale != nullptr ||
mTransformStyle == NS_STYLE_TRANSFORM_STYLE_PRESERVE_3D ||
(mWillChangeBitField & NS_STYLE_WILL_CHANGE_TRANSFORM);
}
+ already_AddRefed<nsCSSValueSharedList> GetCombinedTransform() const;
+
bool HasPerspectiveStyle() const {
return mChildPerspective.GetUnit() == eStyleUnit_Coord;
}
bool BackfaceIsHidden() const {
return mBackfaceVisibility == NS_STYLE_BACKFACE_VISIBILITY_HIDDEN;
}