Bug 1335998 - Part 1: Implement Gecko_CSSValue_InitSharedList and read the transform from the shared list.
We create interpolatematrix and accumulatematrix from Servo side
not on the main thread, so we cannot use nsCSSValueList_heap (which is not
thread safe so we cannot create it and destroy it on different threads).
Therefore, we use nsCSSValueSharedList to represent the cloned lists in
interpolatematrix and accumulatematrix.
MozReview-Commit-ID: L5WBKHwsrUz
--- a/js/src/devtools/rootAnalysis/analyzeHeapWrites.js
+++ b/js/src/devtools/rootAnalysis/analyzeHeapWrites.js
@@ -385,16 +385,17 @@ function ignoreContents(entry)
"Gecko_NewStyleQuoteValues",
"Gecko_NewCSSValueSharedList",
"Gecko_NewNoneTransform",
"Gecko_NewGridTemplateAreasValue",
/nsCSSValue::SetCalcValue/,
/CSSValueSerializeCalcOps::Append/,
"Gecko_CSSValue_SetFunction",
"Gecko_CSSValue_SetArray",
+ "Gecko_CSSValue_InitSharedList",
"Gecko_EnsureMozBorderColors",
"Gecko_ClearMozBorderColors",
"Gecko_AppendMozBorderColors",
"Gecko_CopyMozBorderColors",
"Gecko_SetNullImageValue",
// Needs main thread assertions or other fixes.
/UndisplayedMap::GetEntryFor/,
--- a/layout/style/ServoBindings.cpp
+++ b/layout/style/ServoBindings.cpp
@@ -2027,16 +2027,31 @@ Gecko_CSSValue_SetPairList(nsCSSValueBor
MOZ_ASSERT(NS_IsMainThread());
nsCSSValuePairList* item = aCSSValue->SetPairListValue();
for (uint32_t i = 1; i < aLen; ++i) {
item->mNext = new nsCSSValuePairList;
item = item->mNext;
}
}
+void
+Gecko_CSSValue_InitSharedList(nsCSSValueBorrowedMut aCSSValue,
+ uint32_t aLen)
+{
+ MOZ_ASSERT(aLen > 0, "Must create at least one nsCSSValueList (mHead)");
+
+ nsCSSValueSharedList* list = new nsCSSValueSharedList;
+ aCSSValue->SetSharedListValue(list);
+ list->mHead = new nsCSSValueList;
+ nsCSSValueList* cur = list->mHead;
+ for (uint32_t i = 1; i < aLen; ++i) {
+ cur->mNext = new nsCSSValueList;
+ cur = cur->mNext;
+ }
+}
bool
Gecko_PropertyId_IsPrefEnabled(nsCSSPropertyID id)
{
return nsCSSProps::IsEnabled(id);
}
void
--- a/layout/style/ServoBindings.h
+++ b/layout/style/ServoBindings.h
@@ -503,16 +503,17 @@ void Gecko_CSSValue_SetStringFromAtom(ns
void Gecko_CSSValue_SetAtomIdent(nsCSSValueBorrowedMut css_value, nsIAtom* atom);
void Gecko_CSSValue_SetArray(nsCSSValueBorrowedMut css_value, int32_t len);
void Gecko_CSSValue_SetURL(nsCSSValueBorrowedMut css_value, ServoBundledURI uri);
void Gecko_CSSValue_SetInt(nsCSSValueBorrowedMut css_value, int32_t integer, nsCSSUnit unit);
void Gecko_CSSValue_SetPair(nsCSSValueBorrowedMut css_value,
nsCSSValueBorrowed xvalue, nsCSSValueBorrowed yvalue);
void Gecko_CSSValue_SetList(nsCSSValueBorrowedMut css_value, uint32_t len);
void Gecko_CSSValue_SetPairList(nsCSSValueBorrowedMut css_value, uint32_t len);
+void Gecko_CSSValue_InitSharedList(nsCSSValueBorrowedMut css_value, uint32_t len);
void Gecko_CSSValue_Drop(nsCSSValueBorrowedMut css_value);
NS_DECL_THREADSAFE_FFI_REFCOUNTING(nsCSSValueSharedList, CSSValueSharedList);
bool Gecko_PropertyId_IsPrefEnabled(nsCSSPropertyID id);
void Gecko_nsStyleFont_SetLang(nsStyleFont* font, nsIAtom* atom);
void Gecko_nsStyleFont_CopyLangFrom(nsStyleFont* aFont, const nsStyleFont* aSource);
void Gecko_nsStyleFont_FixupNoneGeneric(nsStyleFont* font,
RawGeckoPresContextBorrowed pres_context);
--- a/layout/style/nsStyleTransformMatrix.cpp
+++ b/layout/style/nsStyleTransformMatrix.cpp
@@ -435,33 +435,53 @@ ProcessMatrixOperator(Matrix4x4& aMatrix
nsStyleContext* aContext,
nsPresContext* aPresContext,
RuleNodeCacheConditions& aConditions,
TransformReferenceBox& aRefBox,
bool* aContains3dTransform)
{
NS_PRECONDITION(aData->Count() == 4, "Invalid array!");
- Matrix4x4 matrix1, matrix2;
- if (aData->Item(1).GetUnit() == eCSSUnit_List) {
- matrix1 = nsStyleTransformMatrix::ReadTransforms(aData->Item(1).GetListValue(),
- aContext, aPresContext,
- aConditions,
- aRefBox, nsPresContext::AppUnitsPerCSSPixel(),
- aContains3dTransform);
- }
- if (aData->Item(2).GetUnit() == eCSSUnit_List) {
- matrix2 = ReadTransforms(aData->Item(2).GetListValue(),
- aContext, aPresContext,
- aConditions,
- aRefBox, nsPresContext::AppUnitsPerCSSPixel(),
- aContains3dTransform);
- }
+ auto readTransform = [&](const nsCSSValue& aValue) -> Matrix4x4 {
+ const nsCSSValueList* list = nullptr;
+ switch (aValue.GetUnit()) {
+ case eCSSUnit_List:
+ // For Gecko style backend.
+ list = aValue.GetListValue();
+ break;
+ case eCSSUnit_SharedList:
+ // For Servo style backend. The transform lists of interpolatematrix
+ // are not created on the main thread (i.e. during parallel traversal),
+ // and nsCSSValueList_heap is not thread safe. Therefore, we use
+ // nsCSSValueSharedList as a workaround.
+ list = aValue.GetSharedListValue()->mHead;
+ break;
+ default:
+ list = nullptr;
+ }
+
+ Matrix4x4 matrix;
+ if (!list) {
+ return matrix;
+ }
+
+ float appUnitPerCSSPixel = nsPresContext::AppUnitsPerCSSPixel();
+ matrix = nsStyleTransformMatrix::ReadTransforms(list,
+ aContext,
+ aPresContext,
+ aConditions,
+ aRefBox,
+ appUnitPerCSSPixel,
+ aContains3dTransform);
+ return matrix;
+ };
+
+ Matrix4x4 matrix1 = readTransform(aData->Item(1));
+ Matrix4x4 matrix2 = readTransform(aData->Item(2));
double progress = aData->Item(3).GetPercentValue();
-
aMatrix =
OperateTransformMatrix<Operator>(matrix1, matrix2, progress) * aMatrix;
}
/* Helper function to process two matrices that we need to interpolate between */
void
ProcessInterpolateMatrix(Matrix4x4& aMatrix,
const nsCSSValue::Array* aData,