Bug 1296477 - Part 2: stylo: Implement remaining `content` values; r?heycam draft
authorManish Goregaokar <manishearth@gmail.com>
Sat, 11 Mar 2017 22:40:54 -0800
changeset 498400 7c6d1f04f1d573d4deabc65fa94c3fade2e71f38
parent 498399 29ff041644fd3dbd475b0e42c439bb625ea2b876
child 498401 a762784d2229c0b441c027fdfc099236e092c0db
push id49165
push userbmo:manishearth@gmail.com
push dateTue, 14 Mar 2017 17:12:23 +0000
reviewersheycam
bugs1296477
milestone55.0a1
Bug 1296477 - Part 2: stylo: Implement remaining `content` values; r?heycam MozReview-Commit-ID: 9fLM5bdR8hr
layout/style/ServoBindings.cpp
layout/style/ServoBindings.h
layout/style/nsCSSValue.cpp
layout/style/nsStyleStruct.cpp
layout/style/nsStyleStruct.h
--- a/layout/style/ServoBindings.cpp
+++ b/layout/style/ServoBindings.cpp
@@ -915,16 +915,31 @@ Gecko_SetCursorImage(nsCursorImage* aCur
 
 void
 Gecko_CopyCursorArrayFrom(nsStyleUserInterface* aDest,
                           const nsStyleUserInterface* aSrc)
 {
   aDest->mCursorImages = aSrc->mCursorImages;
 }
 
+void
+Gecko_SetContentDataImage(nsStyleContentData* aContent, ServoBundledURI aURI)
+{
+  RefPtr<nsStyleImageRequest> req = CreateStyleImageRequest(nsStyleImageRequest::Mode::Track, aURI);
+  aContent->SetImageRequest(req.forget());
+}
+
+void
+Gecko_SetContentDataArray(nsStyleContentData* aContent,
+                          nsStyleContentType aType, uint32_t aLen)
+{
+  nsCSSValue::Array* arr = nsCSSValue::Array::Create(aLen);
+  aContent->SetCounters(aType, arr);
+}
+
 nsStyleGradient*
 Gecko_CreateGradient(uint8_t aShape,
                      uint8_t aSize,
                      bool aRepeating,
                      bool aLegacySyntax,
                      uint32_t aStopCount)
 {
   nsStyleGradient* result = new nsStyleGradient();
@@ -1307,20 +1322,35 @@ Gecko_CSSValue_GetCalc(nsCSSValueBorrowe
 void
 Gecko_CSSValue_SetFunction(nsCSSValueBorrowedMut aCSSValue, int32_t aLen)
 {
   nsCSSValue::Array* arr = nsCSSValue::Array::Create(aLen);
   aCSSValue->SetArrayValue(arr, eCSSUnit_Function);
 }
 
 void
-Gecko_CSSValue_SetString(nsCSSValueBorrowedMut aCSSValue, const nsString aString)
+Gecko_CSSValue_SetString(nsCSSValueBorrowedMut aCSSValue, const uint8_t* aString, uint32_t aLength)
 {
   MOZ_ASSERT(aCSSValue->GetUnit() == eCSSUnit_Null);
-  aCSSValue->SetStringValue(aString, eCSSUnit_String);
+  nsString string;
+  nsDependentCSubstring slice(reinterpret_cast<const char*>(aString),
+                                  aLength);
+  AppendUTF8toUTF16(slice, string);
+  aCSSValue->SetStringValue(string, eCSSUnit_String);
+}
+
+void
+Gecko_CSSValue_SetIdent(nsCSSValueBorrowedMut aCSSValue, const uint8_t* aString, uint32_t aLength)
+{
+  MOZ_ASSERT(aCSSValue->GetUnit() == eCSSUnit_Null);
+  nsString string;
+  nsDependentCSubstring slice(reinterpret_cast<const char*>(aString),
+                                  aLength);
+  AppendUTF8toUTF16(slice, string);
+  aCSSValue->SetStringValue(string, eCSSUnit_Ident);
 }
 
 void
 Gecko_CSSValue_SetArray(nsCSSValueBorrowedMut aCSSValue, int32_t aLength)
 {
   MOZ_ASSERT(aCSSValue->GetUnit() == eCSSUnit_Null);
   RefPtr<nsCSSValue::Array> array
     = nsCSSValue::Array::Create(aLength);
--- a/layout/style/ServoBindings.h
+++ b/layout/style/ServoBindings.h
@@ -240,16 +240,19 @@ void Gecko_CopyListStyleImageFrom(nsStyl
 
 // cursor style.
 void Gecko_SetCursorArrayLength(nsStyleUserInterface* ui, size_t len);
 void Gecko_SetCursorImage(nsCursorImage* cursor,
                           ServoBundledURI uri);
 void Gecko_CopyCursorArrayFrom(nsStyleUserInterface* dest,
                                const nsStyleUserInterface* src);
 
+void Gecko_SetContentDataImage(nsStyleContentData* content_data, ServoBundledURI uri);
+void Gecko_SetContentDataArray(nsStyleContentData* content_data, nsStyleContentType type, uint32_t len);
+
 // Dirtiness tracking.
 uint32_t Gecko_GetNodeFlags(RawGeckoNodeBorrowed node);
 void Gecko_SetNodeFlags(RawGeckoNodeBorrowed node, uint32_t flags);
 void Gecko_UnsetNodeFlags(RawGeckoNodeBorrowed node, uint32_t flags);
 void Gecko_SetOwnerDocumentNeedsStyleFlush(RawGeckoElementBorrowed element);
 
 // Incremental restyle.
 // Also, we might want a ComputedValues to ComputedValues API for animations?
@@ -343,17 +346,18 @@ nsStyleCoord::CalcValue Gecko_CSSValue_G
 
 void Gecko_CSSValue_SetAbsoluteLength(nsCSSValueBorrowedMut css_value, nscoord len);
 void Gecko_CSSValue_SetNumber(nsCSSValueBorrowedMut css_value, float number);
 void Gecko_CSSValue_SetKeyword(nsCSSValueBorrowedMut css_value, nsCSSKeyword keyword);
 void Gecko_CSSValue_SetPercentage(nsCSSValueBorrowedMut css_value, float percent);
 void Gecko_CSSValue_SetAngle(nsCSSValueBorrowedMut css_value, float radians);
 void Gecko_CSSValue_SetCalc(nsCSSValueBorrowedMut css_value, nsStyleCoord::CalcValue calc);
 void Gecko_CSSValue_SetFunction(nsCSSValueBorrowedMut css_value, int32_t len);
-void Gecko_CSSValue_SetString(nsCSSValueBorrowedMut css_value, const nsString string);
+void Gecko_CSSValue_SetString(nsCSSValueBorrowedMut css_value, const uint8_t* string, uint32_t len);
+void Gecko_CSSValue_SetIdent(nsCSSValueBorrowedMut css_value, const uint8_t* string, uint32_t len);
 void Gecko_CSSValue_SetArray(nsCSSValueBorrowedMut css_value, int32_t len);
 void Gecko_CSSValue_SetURL(nsCSSValueBorrowedMut css_value, ServoBundledURI uri);
 void Gecko_CSSValue_SetLocal(nsCSSValueBorrowedMut css_value, const nsString family);
 void Gecko_CSSValue_SetInteger(nsCSSValueBorrowedMut css_value, int32_t integer);
 void Gecko_CSSValue_Drop(nsCSSValueBorrowedMut css_value);
 NS_DECL_THREADSAFE_FFI_REFCOUNTING(nsCSSValueSharedList, CSSValueSharedList);
 bool Gecko_PropertyId_IsPrefEnabled(nsCSSPropertyID id);
 
--- a/layout/style/nsCSSValue.cpp
+++ b/layout/style/nsCSSValue.cpp
@@ -424,17 +424,17 @@ nscoord nsCSSValue::GetPixelLength() con
 #define DO_RELEASE(member) {                                                  \
   MOZ_ASSERT(!ServoStyleSet::IsInServoTraversal(false));                      \
   mValue.member->Release();                                                   \
 }
 
 void nsCSSValue::DoReset()
 {
   if (UnitHasStringValue()) {
-    DO_RELEASE(mString);
+    mValue.mString->Release();
   } else if (IsFloatColorUnit()) {
     DO_RELEASE(mFloatColor);
   } else if (eCSSUnit_ComplexColor == mUnit) {
     DO_RELEASE(mComplexColor);
   } else if (UnitHasArrayValue()) {
     DO_RELEASE(mArray);
   } else if (eCSSUnit_URL == mUnit) {
     DO_RELEASE(mURL);
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -3677,21 +3677,20 @@ nsStyleVisibility::CalcDifference(const 
   return hint;
 }
 
 nsStyleContentData::~nsStyleContentData()
 {
   MOZ_COUNT_DTOR(nsStyleContentData);
 
   if (mType == eStyleContentType_Image) {
-    MOZ_ASSERT(NS_IsMainThread());
-    mContent.mImage->Release();
+    NS_ReleaseOnMainThread(dont_AddRef(mContent.mImage));
+    mContent.mImage = nullptr;
   } else if (mType == eStyleContentType_Counter ||
              mType == eStyleContentType_Counters) {
-    MOZ_ASSERT(NS_IsMainThread());
     mContent.mCounters->Release();
   } else if (mContent.mString) {
     free(mContent.mString);
   }
 }
 
 nsStyleContentData::nsStyleContentData(const nsStyleContentData& aOther)
   : mType(aOther.mType)
@@ -3756,16 +3755,24 @@ nsStyleContent::~nsStyleContent()
 
 void
 nsStyleContent::Destroy(nsPresContext* aContext)
 {
   this->~nsStyleContent();
   aContext->PresShell()->FreeByObjectID(eArenaObjectID_nsStyleContent, this);
 }
 
+void
+nsStyleContent::FinishStyle(nsPresContext* aPresContext)
+{
+  for (nsStyleContentData& data : mContents) {
+    data.Resolve(aPresContext);
+  }
+}
+
 nsStyleContent::nsStyleContent(const nsStyleContent& aSource)
   : mContents(aSource.mContents)
   , mIncrements(aSource.mIncrements)
   , mResets(aSource.mResets)
 {
   MOZ_COUNT_CTOR(nsStyleContent);
 }
 
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -3201,32 +3201,39 @@ public:
     mContent.mString = NS_strdup(aString);
   }
 
   void SetCounters(nsStyleContentType aType, nsCSSValue::Array* aCounters)
   {
     MOZ_ASSERT(aType == eStyleContentType_Counter ||
                aType == eStyleContentType_Counters);
     MOZ_ASSERT(aCounters);
+    MOZ_ASSERT(aCounters->Count() == 2 || aCounters->Count() == 3);
     MOZ_ASSERT(mType == eStyleContentType_Uninitialized,
                "should only initialize nsStyleContentData once");
     mType = aType;
     mContent.mCounters = aCounters;
     mContent.mCounters->AddRef();
   }
 
   void SetImageRequest(already_AddRefed<nsStyleImageRequest> aRequest)
   {
     MOZ_ASSERT(mType == eStyleContentType_Uninitialized,
                "should only initialize nsStyleContentData once");
     mType = eStyleContentType_Image;
     mContent.mImage = aRequest.take();
     MOZ_ASSERT(mContent.mImage);
   }
 
+  void Resolve(nsPresContext* aPresContext) {
+    if (mType == eStyleContentType_Image) {
+      mContent.mImage->Resolve(aPresContext);
+    }
+  }
+
 private:
   nsStyleContentType mType;
   union {
     char16_t *mString;
     nsStyleImageRequest* mImage;
     nsCSSValue::Array* mCounters;
   } mContent;
 };
@@ -3245,17 +3252,17 @@ struct nsStyleCounterData
   }
 };
 
 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleContent
 {
   explicit nsStyleContent(const nsPresContext* aContext);
   nsStyleContent(const nsStyleContent& aContent);
   ~nsStyleContent();
-  void FinishStyle(nsPresContext* aPresContext) {}
+  void FinishStyle(nsPresContext* aPresContext);
 
   void* operator new(size_t sz, nsStyleContent* aSelf) { return aSelf; }
   void* operator new(size_t sz, nsPresContext* aContext) {
     return aContext->PresShell()->
       AllocateByObjectID(mozilla::eArenaObjectID_nsStyleContent, sz);
   }
   void Destroy(nsPresContext* aContext);