Bug 1207734 - Part 4.a. Store the final combined transform in nsStyleDisplay::mCombinedTransform.
MozReview-Commit-ID: FsuaMoclnL8
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -3662,16 +3662,17 @@ nsStyleDisplay::nsStyleDisplay(const nsS
, mScrollSnapCoordinate(aSource.mScrollSnapCoordinate)
, mBackfaceVisibility(aSource.mBackfaceVisibility)
, mTransformStyle(aSource.mTransformStyle)
, mTransformBox(aSource.mTransformBox)
, mSpecifiedTransform(aSource.mSpecifiedTransform)
, mSpecifiedRotate(aSource.mSpecifiedRotate)
, mSpecifiedTranslate(aSource.mSpecifiedTranslate)
, mSpecifiedScale(aSource.mSpecifiedScale)
+ , mCombinedTransform(aSource.mCombinedTransform)
, mTransformOrigin{ aSource.mTransformOrigin[0],
aSource.mTransformOrigin[1],
aSource.mTransformOrigin[2] }
, mChildPerspective(aSource.mChildPerspective)
, mPerspectiveOrigin{ aSource.mPerspectiveOrigin[0],
aSource.mPerspectiveOrigin[1] }
, mVerticalAlign(aSource.mVerticalAlign)
, mTransitions(aSource.mTransitions)
@@ -3725,16 +3726,18 @@ nsStyleDisplay::~nsStyleDisplay()
ReleaseSharedListOnMainThread("nsStyleDisplay::mSpecifiedTransform",
mSpecifiedTransform);
ReleaseSharedListOnMainThread("nsStyleDisplay::mSpecifiedRotate",
mSpecifiedRotate);
ReleaseSharedListOnMainThread("nsStyleDisplay::mSpecifiedTranslate",
mSpecifiedTranslate);
ReleaseSharedListOnMainThread("nsStyleDisplay::mSpecifiedScale",
mSpecifiedScale);
+ ReleaseSharedListOnMainThread("nsStyleDisplay::mCombinedTransform",
+ mCombinedTransform);
MOZ_COUNT_DTOR(nsStyleDisplay);
}
void
nsStyleDisplay::FinishStyle(nsPresContext* aPresContext)
{
MOZ_ASSERT(NS_IsMainThread());
@@ -4010,16 +4013,74 @@ nsStyleDisplay::CalcDifference(const nsS
mAnimationIterationCountCount != aNewData.mAnimationIterationCountCount ||
mScrollSnapCoordinate != aNewData.mScrollSnapCoordinate)) {
hint |= nsChangeHint_NeutralChange;
}
return hint;
}
+already_AddRefed<nsCSSValueSharedList>
+nsStyleDisplay::GetCombinedTransform() const
+{
+ MOZ_ASSERT(NS_IsMainThread());
+
+ if (mCombinedTransform) {
+ return do_AddRef(mCombinedTransform);
+ }
+
+ // Follow the order defined in the spec to append transform functions.
+ // https://drafts.csswg.org/css-transforms-2/#ctm
+ AutoTArray<nsCSSValueSharedList*, 4> shareLists;
+ if (mSpecifiedTranslate) {
+ shareLists.AppendElement(mSpecifiedTranslate.get());
+ }
+ if (mSpecifiedRotate) {
+ shareLists.AppendElement(mSpecifiedRotate.get());
+ }
+ if (mSpecifiedScale) {
+ shareLists.AppendElement(mSpecifiedScale.get());
+ }
+ if (mSpecifiedTransform) {
+ shareLists.AppendElement(mSpecifiedTransform.get());
+ }
+
+ if (shareLists.Length() == 0) {
+ return nullptr;
+ }
+ if (shareLists.Length() == 1) {
+ return do_AddRef(shareLists[0]);
+ }
+
+ // In common, we may have 3 transform functions(for rotate, translate and
+ // scale) in mSpecifiedTransform, one rotate function in mSpecifiedRotate,
+ // one translate function in mSpecifiedTranslate, and one scale function in
+ // mSpecifiedScale. So 6 slots are enough for the most cases.
+ AutoTArray<nsCSSValueList*, 6> valueLists;
+ for (auto list: shareLists) {
+ if (list) {
+ valueLists.AppendElement(list->mHead->Clone());
+ }
+ }
+
+ // Check we have at least one list or else valueLists.Length() - 1 below will
+ // underflow.
+ MOZ_ASSERT(valueLists.Length());
+
+ for (uint32_t i = 0; i < valueLists.Length() - 1; i++) {
+ valueLists[i]->mNext = valueLists[i + 1];
+ }
+
+ RefPtr<nsCSSValueSharedList>& combinedTransform =
+ const_cast<RefPtr<nsCSSValueSharedList>&>(this->mCombinedTransform);
+
+ combinedTransform = new nsCSSValueSharedList(valueLists[0]);
+ return do_AddRef(combinedTransform);
+}
+
// --------------------
// 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
@@ -2588,16 +2588,23 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsSt
// null, as appropriate.)
uint8_t mBackfaceVisibility;
uint8_t mTransformStyle;
StyleGeometryBox mTransformBox; // [reset] see nsStyleConsts.h
RefPtr<nsCSSValueSharedList> mSpecifiedTransform; // [reset]
RefPtr<nsCSSValueSharedList> mSpecifiedRotate; // [reset]
RefPtr<nsCSSValueSharedList> mSpecifiedTranslate; // [reset]
RefPtr<nsCSSValueSharedList> mSpecifiedScale; // [reset]
+
+ // Used to store the final combination of mSpecifiedTranslate,
+ // mSpecifiedRotate, mSpecifiedScale and mSpecifiedTransform.
+ // Use GetCombinedTransform() to get the final transform, instead of
+ // accessing mCombinedTransform directly.
+ RefPtr<nsCSSValueSharedList> mCombinedTransform;
+
nsStyleCoord mTransformOrigin[3]; // [reset] percent, coord, calc, 3rd param is coord, calc only
nsStyleCoord mChildPerspective; // [reset] none, coord
nsStyleCoord mPerspectiveOrigin[2]; // [reset] percent, coord, calc
nsStyleCoord mVerticalAlign; // [reset] coord, percent, calc, enum (see nsStyleConsts.h)
nsStyleAutoArray<mozilla::StyleTransition> mTransitions; // [reset]
@@ -2855,26 +2862,30 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsSt
* The same as IsFixedPosContainingBlock, except skipping the tests that
* are based on the frame rather than the style context (thus
* potentially returning a false positive).
*/
template<class StyleContextLike>
inline bool IsFixedPosContainingBlockForAppropriateFrame(
StyleContextLike* aStyleContext) const;
+ /**
+ * Returns the final combined transform.
+ **/
+ already_AddRefed<nsCSSValueSharedList> GetCombinedTransform() const;
+
private:
// Helpers for above functions, which do some but not all of the tests
// for them (since transform must be tested separately for each).
template<class StyleContextLike>
inline bool HasAbsPosContainingBlockStyleInternal(
StyleContextLike* aStyleContext) const;
template<class StyleContextLike>
inline bool HasFixedPosContainingBlockStyleInternal(
StyleContextLike* aStyleContext) const;
-
public:
// Return the 'float' and 'clear' properties, with inline-{start,end} values
// resolved to {left,right} according to the given writing mode. These are
// defined in WritingModes.h.
inline mozilla::StyleFloat PhysicalFloats(mozilla::WritingMode aWM) const;
inline mozilla::StyleClear PhysicalBreakType(mozilla::WritingMode aWM) const;
};