# HG changeset patch # User cku # Date 1516778566 -32400 # Wed Jan 24 16:22:46 2018 +0900 # Node ID 2a33079d7cbafb0fc38bd41e047431df17662594 # Parent 92578c159fd48bccd471e7192cc260a68c32882e Bug 1207734 - Part 4.a. Store the final combined transform in nsStyleDisplay::mCombinedTransform. r=birtles MozReview-Commit-ID: FsuaMoclnL8 (grafted from 793e73f61ee1d0035b3d9d881df4eb784da3c4e9) diff --git a/layout/style/nsStyleStruct.cpp b/layout/style/nsStyleStruct.cpp --- 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,32 +3726,36 @@ 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()); MOZ_ASSERT(aPresContext->StyleSet()->IsServo()); if (mShapeOutside.GetType() == StyleShapeSourceType::Image) { const UniquePtr& shapeImage = mShapeOutside.GetShapeImage(); if (shapeImage) { shapeImage->ResolveImage(aPresContext); } } + + GenerateCombinedTransform(); } static inline nsChangeHint CompareTransformValues(const RefPtr& aList, const RefPtr& aNewList) { nsChangeHint result = nsChangeHint(0); if (!aList != !aNewList || (aList && *aList != *aNewList)) { @@ -4010,16 +4015,67 @@ nsStyleDisplay::CalcDifference(const nsS mAnimationIterationCountCount != aNewData.mAnimationIterationCountCount || mScrollSnapCoordinate != aNewData.mScrollSnapCoordinate)) { hint |= nsChangeHint_NeutralChange; } return hint; } +void +nsStyleDisplay::GenerateCombinedTransform() +{ + mCombinedTransform = nullptr; + + // Follow the order defined in the spec to append transform functions. + // https://drafts.csswg.org/css-transforms-2/#ctm + AutoTArray 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; + } + + if (shareLists.Length() == 1) { + mCombinedTransform = shareLists[0]; + return; + } + + // 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 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]; + } + + mCombinedTransform = new nsCSSValueSharedList(valueLists[0]); +} // -------------------- // nsStyleVisibility // nsStyleVisibility::nsStyleVisibility(const nsPresContext* aContext) : mDirection(aContext->GetBidi() == IBMBIDI_TEXTDIRECTION_RTL ? NS_STYLE_DIRECTION_RTL : NS_STYLE_DIRECTION_LTR) diff --git a/layout/style/nsStyleStruct.h b/layout/style/nsStyleStruct.h --- 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 mSpecifiedTransform; // [reset] RefPtr mSpecifiedRotate; // [reset] RefPtr mSpecifiedTranslate; // [reset] RefPtr 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 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 mTransitions; // [reset] @@ -2855,26 +2862,38 @@ 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 inline bool IsFixedPosContainingBlockForAppropriateFrame( StyleContextLike* aStyleContext) const; + /** + * Returns the final combined transform. + **/ + already_AddRefed GetCombinedTransform() const { + if (mCombinedTransform) { + return do_AddRef(mCombinedTransform); + } + + // backward compatible to gecko-backed style system. + return mSpecifiedTransform ? do_AddRef(mSpecifiedTransform) : nullptr; + } + 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 inline bool HasAbsPosContainingBlockStyleInternal( StyleContextLike* aStyleContext) const; template inline bool HasFixedPosContainingBlockStyleInternal( StyleContextLike* aStyleContext) const; - + void GenerateCombinedTransform(); 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; };