Bug 1338936 - Part 1: stylo: Add stubbed-out ServoSpecifiedValues interface, use it for pres attr mapping; r=bz,emilio
authorManish Goregaokar <manishearth@gmail.com>
Sun, 12 Feb 2017 16:02:29 -0800
changeset 486774 a0c56ecc911127591ea25904486bfa019836f0c2
parent 486773 b53a9cea93fd598ea2baa8314e5cad63cfa4bf5d
child 486775 28d72f228244590ced658878c5ac42a7a7ee6aea
push id46055
push userbmo:manishearth@gmail.com
push dateSun, 19 Feb 2017 22:04:43 +0000
reviewersbz, emilio
bugs1338936
milestone54.0a1
Bug 1338936 - Part 1: stylo: Add stubbed-out ServoSpecifiedValues interface, use it for pres attr mapping; r=bz,emilio MozReview-Commit-ID: 6wg32flypt7
dom/base/nsMappedAttributes.cpp
dom/base/nsMappedAttributes.h
layout/style/GenericSpecifiedValues.h
layout/style/GenericSpecifiedValuesInlines.h
layout/style/ServoSpecifiedValues.cpp
layout/style/ServoSpecifiedValues.h
layout/style/moz.build
layout/style/nsHTMLStyleSheet.cpp
layout/style/nsRuleData.h
--- a/dom/base/nsMappedAttributes.cpp
+++ b/dom/base/nsMappedAttributes.cpp
@@ -12,16 +12,17 @@
 #include "nsMappedAttributes.h"
 #include "nsHTMLStyleSheet.h"
 #include "nsRuleData.h"
 #include "nsRuleWalker.h"
 #include "mozilla/GenericSpecifiedValues.h"
 #include "mozilla/HashFunctions.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/ServoDeclarationBlock.h"
+#include "mozilla/ServoSpecifiedValues.h"
 
 using namespace mozilla;
 
 nsMappedAttributes::nsMappedAttributes(nsHTMLStyleSheet* aSheet,
                                        nsMapRuleToAttributesFunc aMapRuleFunc)
   : mAttrCount(0),
     mSheet(aSheet),
     mRuleMapper(aMapRuleFunc),
@@ -284,24 +285,19 @@ nsMappedAttributes::SizeOfIncludingThis(
   size_t n = aMallocSizeOf(this);
   for (uint16_t i = 0; i < mAttrCount; ++i) {
     n += Attrs()[i].mValue.SizeOfExcludingThis(aMallocSizeOf);
   }
   return n;
 }
 
 void
-nsMappedAttributes::LazilyResolveServoDeclaration(nsRuleData* aRuleData,
-                                                  nsCSSPropertyID* aIndexToIdMapping,
-                                                  size_t aRuleDataSize)
+nsMappedAttributes::LazilyResolveServoDeclaration(nsPresContext* aContext)
 {
-  MapRuleInfoInto(aRuleData);
 
   MOZ_ASSERT(!mServoStyle,
              "LazilyResolveServoDeclaration should not be called if mServoStyle is already set");
-  mServoStyle = Servo_DeclarationBlock_CreateEmpty().Consume();
-  for (size_t i = 0; i < aRuleDataSize; i++) {
-    nsCSSValue& val = aRuleData->mValueStorage[i];
-    if (val.GetUnit() != eCSSUnit_Null) {
-      Servo_DeclarationBlock_AddPresValue(mServoStyle.get(), aIndexToIdMapping[i], &val);
-    }
+  if (mRuleMapper) {
+    mServoStyle = Servo_DeclarationBlock_CreateEmpty().Consume();
+    ServoSpecifiedValues servo = ServoSpecifiedValues(aContext, mServoStyle.get());
+    (*mRuleMapper)(this, &servo);
   }
 }
--- a/dom/base/nsMappedAttributes.h
+++ b/dom/base/nsMappedAttributes.h
@@ -67,26 +67,19 @@ public:
     return &Attrs()[aPos].mValue;
   }
   // Remove the attr at position aPos.  The value of the attr is placed in
   // aValue; any value that was already in aValue is destroyed.
   void RemoveAttrAt(uint32_t aPos, nsAttrValue& aValue);
   const nsAttrName* GetExistingAttrNameFromQName(const nsAString& aName) const;
   int32_t IndexOfAttr(nsIAtom* aLocalName) const;
 
-  // Apply the contained mapper to an empty nsRuleData object
-  // that is able to contain all properties. Set contained servo declaration block
-  // to result of this computation.
-  // aIndexToIdMapping is
-  // a table that maps from an index in the rule data to the corresponding
-  // property ID. aRuleDataSize is the length of the backing storage
-  // of the rule data.
-  void LazilyResolveServoDeclaration(nsRuleData* aRuleData,
-                                     nsCSSPropertyID* aIndexToIdMapping,
-                                     size_t aRuleDataSize);
+  // Apply the contained mapper to the contained set of servo rules,
+  // unless the servo rules have already been initialized.
+  void LazilyResolveServoDeclaration(nsPresContext* aPresContext);
 
   // Obtain the contained servo declaration block
   // May return null if called before the inner block
   // has been (lazily) resolved
   const RefPtr<RawServoDeclarationBlock>& GetServoStyle() const
   {
     return mServoStyle;
   }
--- a/layout/style/GenericSpecifiedValues.h
+++ b/layout/style/GenericSpecifiedValues.h
@@ -14,28 +14,32 @@
 #define mozilla_GenericSpecifiedValues_h
 
 #include "mozilla/ServoUtils.h"
 #include "nsCSSProps.h"
 #include "nsCSSValue.h"
 #include "nsPresContext.h"
 
 struct nsRuleData;
+
 namespace mozilla {
+
+class ServoSpecifiedValues;
+
 // This provides a common interface for attribute mappers (MapAttributesIntoRule)
 // to use regardless of the style backend. If the style backend is Gecko,
 // this will contain an nsRuleData. If it is Servo, it will be a PropertyDeclarationBlock.
 class GenericSpecifiedValues {
 protected:
     explicit GenericSpecifiedValues(StyleBackendType aType, nsPresContext* aPresContext,
                                     uint32_t aSIDs)
         : mType(aType), mPresContext(aPresContext), mSIDs(aSIDs) {}
 
 public:
-    MOZ_DECL_STYLO_METHODS(nsRuleData, nsRuleData)
+    MOZ_DECL_STYLO_METHODS(nsRuleData, ServoSpecifiedValues)
 
     // Check if we already contain a certain longhand
     inline bool PropertyIsSet(nsCSSPropertyID aId);
     // Check if we are able to hold longhands from a given
     // style struct. Pass the result of NS_STYLE_INHERIT_BIT to this
     // function. Can accept multiple inherit bits or'd together.
     inline bool ShouldComputeStyleStruct(uint64_t aInheritBits) {
         return aInheritBits & mSIDs;
--- a/layout/style/GenericSpecifiedValuesInlines.h
+++ b/layout/style/GenericSpecifiedValuesInlines.h
@@ -11,20 +11,21 @@
  * in stylo mode.
  */
 
 #ifndef mozilla_GenericSpecifiedValuesInlines_h
 #define mozilla_GenericSpecifiedValuesInlines_h
 
 #include "nsRuleData.h"
 #include "mozilla/GenericSpecifiedValues.h"
+#include "mozilla/ServoSpecifiedValues.h"
 
 namespace mozilla {
 
-MOZ_DEFINE_STYLO_METHODS(GenericSpecifiedValues, nsRuleData, nsRuleData)
+MOZ_DEFINE_STYLO_METHODS(GenericSpecifiedValues, nsRuleData, ServoSpecifiedValues)
 
 bool
 GenericSpecifiedValues::PropertyIsSet(nsCSSPropertyID aId)
 {
   MOZ_STYLO_FORWARD(PropertyIsSet, (aId))
 }
 
 void
new file mode 100644
--- /dev/null
+++ b/layout/style/ServoSpecifiedValues.cpp
@@ -0,0 +1,27 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "mozilla/ServoSpecifiedValues.h"
+
+namespace {
+
+#define STYLE_STRUCT(name, checkdata_cb) | NS_STYLE_INHERIT_BIT(name)
+const uint64_t ALL_SIDS = 0
+#include "nsStyleStructList.h"
+;
+#undef STYLE_STRUCT
+
+} // anonymous namespace
+
+using namespace mozilla;
+
+ServoSpecifiedValues::ServoSpecifiedValues(nsPresContext* aContext,
+                                           RawServoDeclarationBlock* aDecl)
+
+  : GenericSpecifiedValues(StyleBackendType::Servo, aContext, ALL_SIDS)
+  ,  mDecl(aDecl)
+{
+
+}
new file mode 100644
--- /dev/null
+++ b/layout/style/ServoSpecifiedValues.h
@@ -0,0 +1,109 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/*
+ * Servo-backed specified value store, to be used when mapping presentation
+ * attributes
+ */
+
+#ifndef mozilla_ServoSpecifiedValues_h
+#define mozilla_ServoSpecifiedValues_h
+
+#include "mozilla/GenericSpecifiedValues.h"
+#include "mozilla/ServoBindings.h"
+
+namespace mozilla {
+
+class ServoSpecifiedValues final: public GenericSpecifiedValues
+{
+public:
+
+  ServoSpecifiedValues(nsPresContext* aContext, RawServoDeclarationBlock* aDecl);
+
+  // GenericSpecifiedValues overrides
+  bool PropertyIsSet(nsCSSPropertyID aId) {
+    return false;
+  }
+
+  void SetIdentStringValue(nsCSSPropertyID aId,
+                           const nsString& aValue) {
+
+  }
+
+  void SetIdentStringValueIfUnset(nsCSSPropertyID aId,
+                                  const nsString& aValue) {
+
+  }
+
+  void SetKeywordValue(nsCSSPropertyID aId,
+                       int32_t aValue) {
+  }
+
+  void SetKeywordValueIfUnset(nsCSSPropertyID aId,
+                              int32_t aValue) {
+
+  }
+
+
+  void SetIntValue(nsCSSPropertyID aId,
+                   int32_t aValue) {
+  }
+
+  void SetPixelValue(nsCSSPropertyID aId,
+                     float aValue) {
+  }
+
+  void SetPixelValueIfUnset(nsCSSPropertyID aId,
+                            float aValue) {
+  }
+
+  void SetPercentValue(nsCSSPropertyID aId,
+                       float aValue) {
+  }
+
+  void SetAutoValue(nsCSSPropertyID aId) {
+  }
+
+  void SetAutoValueIfUnset(nsCSSPropertyID aId) {
+  }
+
+  void SetPercentValueIfUnset(nsCSSPropertyID aId,
+                              float aValue) {
+
+  }
+
+  void SetCurrentColor(nsCSSPropertyID aId) {
+
+  }
+
+  void SetCurrentColorIfUnset(nsCSSPropertyID aId) {
+
+  }
+
+  void SetColorValue(nsCSSPropertyID aId,
+                     nscolor aValue) {
+
+  }
+
+  void SetColorValueIfUnset(nsCSSPropertyID aId,
+                            nscolor aValue) {
+
+  }
+
+  void SetFontFamily(const nsString& aValue) {
+
+  }
+  void SetTextDecorationColorOverride() {
+
+  }
+
+private:
+  RefPtr<RawServoDeclarationBlock> mDecl;
+};
+
+} // namespace mozilla
+
+#endif // mozilla_ServoSpecifiedValues_h
--- a/layout/style/moz.build
+++ b/layout/style/moz.build
@@ -97,16 +97,17 @@ EXPORTS.mozilla += [
     'ServoArcTypeList.h',
     'ServoBindingList.h',
     'ServoBindings.h',
     'ServoBindingTypes.h',
     'ServoCSSRuleList.h',
     'ServoDeclarationBlock.h',
     'ServoElementSnapshot.h',
     'ServoPropPrefList.h',
+    'ServoSpecifiedValues.h',
     'ServoStyleRule.h',
     'ServoStyleSet.h',
     'ServoStyleSheet.h',
     'ServoTypes.h',
     'ServoUtils.h',
     'SheetType.h',
     'StyleAnimationValue.h',
     'StyleAnimationValueInlines.h',
@@ -225,16 +226,17 @@ UNIFIED_SOURCES += [
 # - nsCSSRuleProcessor.cpp needs to be built separately because it uses
 # plarena.h.
 # - nsLayoutStylesheetCache.cpp needs to be built separately because it uses
 # nsExceptionHandler.h, which includes windows.h.
 SOURCES += [
     'BindingStyleRule.cpp',
     'nsCSSRuleProcessor.cpp',
     'nsLayoutStylesheetCache.cpp',
+    'ServoSpecifiedValues.cpp',
 ]
 
 include('/ipc/chromium/chromium-config.mozbuild')
 
 FINAL_LIBRARY = 'xul'
 
 LOCAL_INCLUDES += [
     '../base',
--- a/layout/style/nsHTMLStyleSheet.cpp
+++ b/layout/style/nsHTMLStyleSheet.cpp
@@ -549,104 +549,27 @@ nsHTMLStyleSheet::DropMappedAttributes(n
   uint32_t entryCount = mMappedAttrTable.EntryCount() - 1;
 #endif
 
   mMappedAttrTable.Remove(aMapped);
 
   NS_ASSERTION(entryCount == mMappedAttrTable.EntryCount(), "not removed");
 }
 
-namespace {
-  // Struct containing once-initialized information about
-  // our synthesized rule data
-  struct StaticRuleDataInfo
-  {
-    // the bitmask used.
-    uint64_t mMask;
-    // the number of properties contained
-    size_t mPropCount;
-    // offset of given style struct in array
-    size_t mOffsets[nsStyleStructID_Length];
-    // location of property in given array
-    nsCSSPropertyID* mIndexToPropertyMapping;
-  };
-}
-
-static void
-CalculateIndexArray(StaticRuleDataInfo* aInfo)
-{
-  // this will leak at shutdown, but it's not much and this code is temporary
-  // anyway.
-  aInfo->mIndexToPropertyMapping = new nsCSSPropertyID[aInfo->mPropCount];
-  size_t structOffset;
-  size_t propertyIndex;
-  #define CSS_PROP_LIST_EXCLUDE_LOGICAL
-  #define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_,     \
-                   kwtable_, stylestruct_, stylestructoffset_, animtype_) \
-    structOffset = aInfo->mOffsets[eStyleStruct_##stylestruct_]; \
-    propertyIndex = nsCSSProps::PropertyIndexInStruct(eCSSProperty_##id_); \
-    aInfo->mIndexToPropertyMapping[structOffset + propertyIndex] = eCSSProperty_##id_;
-  #include "nsCSSPropList.h"
-  #undef CSS_PROP
-  #undef CSS_PROP_LIST_EXCLUDE_LOGICAL
-}
-
-static StaticRuleDataInfo
-CalculateRuleDataInfo()
-{
-  StaticRuleDataInfo sizes;
-  sizes.mMask = 0;
-  sizes.mPropCount = 0;
-#define STYLE_STRUCT(name, checkdata_cb) \
-  sizes.mMask |= NS_STYLE_INHERIT_BIT(name); \
-  sizes.mOffsets[eStyleStruct_##name] = sizes.mPropCount; \
-  sizes.mPropCount += nsCSSProps::PropertyCountInStruct(eStyleStruct_##name);
-#include "nsStyleStructList.h"
-#undef STYLE_STRUCT
-
-  CalculateIndexArray(&sizes);
-
-  return sizes;
-}
-
-
-
 void
 nsHTMLStyleSheet::CalculateMappedServoDeclarations()
 {
-  // avoid recalculating or reallocating
-  static StaticRuleDataInfo sizes = CalculateRuleDataInfo();
-
-  if (!mMappedAttrsDirty) {
-    return;
-  }
-  mMappedAttrsDirty = false;
-
-  void* dataStorage = alloca(sizes.mPropCount * sizeof(nsCSSValue));
+  nsPresContext* presContext = mDocument->GetShell()->GetPresContext();
   for (auto iter = mMappedAttrTable.Iter(); !iter.Done(); iter.Next()) {
     MappedAttrTableEntry* attr = static_cast<MappedAttrTableEntry*>(iter.Get());
     if (attr->mAttributes->GetServoStyle()) {
       // Only handle cases which haven't been filled in already
       continue;
     }
-    // Construction cleans up any values we may have set
-    AutoCSSValueArray dataArray(dataStorage, sizes.mPropCount);
-
-    // synthesized ruleData
-    // we pass null for the style context because the code we call into
-    // doesn't deal with the style context. This is temporary.
-    nsRuleData ruleData(sizes.mMask, dataArray.get(),
-                        mDocument->GetShell()->GetPresContext(), nullptr);
-    // Copy the offsets; ruleData won't know where to find properties otherwise
-    mozilla::PodCopy(ruleData.mValueOffsets,
-                     sizes.mOffsets,
-                     nsStyleStructID_Length);
-    attr->mAttributes->LazilyResolveServoDeclaration(&ruleData,
-                                                     sizes.mIndexToPropertyMapping,
-                                                     sizes.mPropCount);
+    attr->mAttributes->LazilyResolveServoDeclaration(presContext);
   }
 }
 
 nsIStyleRule*
 nsHTMLStyleSheet::LangRuleFor(const nsString& aLanguage)
 {
   auto entry =
     static_cast<LangRuleTableEntry*>(mLangRuleTable.Add(&aLanguage, fallible));
--- a/layout/style/nsRuleData.h
+++ b/layout/style/nsRuleData.h
@@ -208,18 +208,14 @@ struct nsRuleData final: mozilla::Generi
     if (!PropertyIsSet(aId)) {
       SetColorValue(aId, aValue);
     }
   }
 
   void SetFontFamily(const nsString& aValue);
   void SetTextDecorationColorOverride();
 
-  nsRuleData* AsRuleData() {
-    return this;
-  }
-
 private:
   inline size_t GetPoisonOffset();
 
 };
 
 #endif