Bug 1314200 - stylo: support transform; r?heycam draft
authorManish Goregaokar <manishearth@gmail.com>
Mon, 31 Oct 2016 16:30:43 -0700
changeset 437466 ab429395112e86e4fe2026f488780ac38f5e0209
parent 437246 d38d06f85ef59c5dbb5d4a1a8d895957a78714de
child 536645 5bc7336ecdfe7635bf6dfe602680e0f08707bac6
push id35419
push userbmo:manishearth@gmail.com
push dateThu, 10 Nov 2016 23:00:37 +0000
reviewersheycam
bugs1314200
milestone52.0a1
Bug 1314200 - stylo: support transform; r?heycam MozReview-Commit-ID: 50YhZtjF3vH
layout/style/ServoBindingTypes.h
layout/style/ServoBindings.cpp
layout/style/ServoBindings.h
layout/style/StyleAnimationValue.cpp
layout/style/StyleAnimationValue.h
layout/style/nsCSSValue.cpp
layout/style/nsCSSValue.h
--- a/layout/style/ServoBindingTypes.h
+++ b/layout/style/ServoBindingTypes.h
@@ -17,16 +17,17 @@ struct RawServoDeclarationBlock;
 
 namespace mozilla {
 namespace dom {
 class Element;
 class StyleChildrenIterator;
 } // namespace dom
 } // namespace mozilla
 
+class nsCSSValue;
 class nsIDocument;
 class nsINode;
 
 using mozilla::dom::StyleChildrenIterator;
 
 typedef nsINode RawGeckoNode;
 typedef mozilla::dom::Element RawGeckoElement;
 typedef nsIDocument RawGeckoDocument;
@@ -88,16 +89,18 @@ DECL_OWNED_REF_TYPE_FOR(StyleChildrenIte
 // are protected from noalias violations by a cell type
 DECL_BORROWED_REF_TYPE_FOR(RawGeckoNode)
 DECL_NULLABLE_BORROWED_REF_TYPE_FOR(RawGeckoNode)
 DECL_BORROWED_REF_TYPE_FOR(RawGeckoElement)
 DECL_NULLABLE_BORROWED_REF_TYPE_FOR(RawGeckoElement)
 DECL_BORROWED_REF_TYPE_FOR(RawGeckoDocument)
 DECL_NULLABLE_BORROWED_REF_TYPE_FOR(RawGeckoDocument)
 DECL_BORROWED_MUT_REF_TYPE_FOR(StyleChildrenIterator)
+DECL_BORROWED_REF_TYPE_FOR(nsCSSValue)
+DECL_BORROWED_MUT_REF_TYPE_FOR(nsCSSValue)
 
 #undef DECL_ARC_REF_TYPE_FOR
 #undef DECL_OWNED_REF_TYPE_FOR
 #undef DECL_NULLABLE_OWNED_REF_TYPE_FOR
 #undef DECL_BORROWED_REF_TYPE_FOR
 #undef DECL_NULLABLE_BORROWED_REF_TYPE_FOR
 #undef DECL_BORROWED_MUT_REF_TYPE_FOR
 #undef DECL_NULLABLE_BORROWED_MUT_REF_TYPE_FOR
--- a/layout/style/ServoBindings.cpp
+++ b/layout/style/ServoBindings.cpp
@@ -24,16 +24,17 @@
 #include "nsString.h"
 #include "nsStyleStruct.h"
 #include "nsStyleUtil.h"
 #include "nsTArray.h"
 
 #include "mozilla/EventStates.h"
 #include "mozilla/ServoElementSnapshot.h"
 #include "mozilla/ServoRestyleManager.h"
+#include "mozilla/StyleAnimationValue.h"
 #include "mozilla/DeclarationBlockInlines.h"
 #include "mozilla/dom/Element.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 #define IMPL_STRONG_REF_TYPE_FOR(type_) \
   already_AddRefed<type_>               \
@@ -961,16 +962,85 @@ Gecko_NewStyleQuoteValues(uint32_t aLen)
 {
   RefPtr<nsStyleQuoteValues> values = new nsStyleQuoteValues;
   values->mQuotePairs.SetLength(aLen);
   return values.forget().take();
 }
 
 NS_IMPL_THREADSAFE_FFI_REFCOUNTING(nsStyleQuoteValues, QuoteValues);
 
+nsCSSValueSharedList*
+Gecko_NewCSSValueSharedList(uint32_t aLen)
+{
+  RefPtr<nsCSSValueSharedList> list = new nsCSSValueSharedList;
+  if (aLen == 0) {
+    return list.forget().take();
+  }
+
+  list->mHead = new nsCSSValueList;
+  nsCSSValueList* cur = list->mHead;
+  for (uint32_t i = 0; i < aLen - 1; i++) {
+    cur->mNext = new nsCSSValueList;
+    cur = cur->mNext;
+  }
+
+  return list.forget().take();
+}
+
+void
+Gecko_CSSValue_SetAbsoluteLength(nsCSSValueBorrowedMut aCSSValue, nscoord aLen)
+{
+  aCSSValue->SetIntegerCoordValue(aLen);
+}
+
+void
+Gecko_CSSValue_SetNumber(nsCSSValueBorrowedMut aCSSValue, float aNumber)
+{
+  aCSSValue->SetFloatValue(aNumber, eCSSUnit_Number);
+}
+
+void
+Gecko_CSSValue_SetKeyword(nsCSSValueBorrowedMut aCSSValue, nsCSSKeyword aKeyword)
+{
+  aCSSValue->SetIntValue(aKeyword, eCSSUnit_Enumerated);
+}
+
+void
+Gecko_CSSValue_SetPercentage(nsCSSValueBorrowedMut aCSSValue, float aPercent)
+{
+  aCSSValue->SetFloatValue(aPercent, eCSSUnit_Number);
+}
+
+void
+Gecko_CSSValue_SetAngle(nsCSSValueBorrowedMut aCSSValue, float aRadians)
+{
+  aCSSValue->SetFloatValue(aRadians, eCSSUnit_Radian);
+}
+
+void
+Gecko_CSSValue_SetCalc(nsCSSValueBorrowedMut aCSSValue, nsStyleCoord::CalcValue aCalc)
+{
+  aCSSValue->SetCalcValue(&aCalc);
+}
+
+void
+Gecko_CSSValue_SetFunction(nsCSSValueBorrowedMut aCSSValue, int32_t aLen)
+{
+  nsCSSValue::Array* arr = nsCSSValue::Array::Create(aLen);
+  aCSSValue->SetArrayValue(arr, eCSSUnit_Function);
+}
+
+nsCSSValueBorrowedMut
+Gecko_CSSValue_GetArrayItem(nsCSSValueBorrowedMut aCSSValue, int32_t aIndex)
+{
+  return &aCSSValue->GetArrayValue()->Item(aIndex);
+}
+
+NS_IMPL_THREADSAFE_FFI_REFCOUNTING(nsCSSValueSharedList, CSSValueSharedList);
+
 #define STYLE_STRUCT(name, checkdata_cb)                                      \
                                                                               \
 void                                                                          \
 Gecko_Construct_nsStyle##name(nsStyle##name* ptr)                             \
 {                                                                             \
   new (ptr) nsStyle##name(StyleStructContext::ServoContext());                \
 }                                                                             \
                                                                               \
--- a/layout/style/ServoBindings.h
+++ b/layout/style/ServoBindings.h
@@ -251,16 +251,27 @@ void Gecko_FillAllMaskLists(nsStyleImage
 NS_DECL_THREADSAFE_FFI_REFCOUNTING(nsStyleCoord::Calc, Calc);
 
 nsCSSShadowArray* Gecko_NewCSSShadowArray(uint32_t len);
 NS_DECL_THREADSAFE_FFI_REFCOUNTING(nsCSSShadowArray, CSSShadowArray);
 
 nsStyleQuoteValues* Gecko_NewStyleQuoteValues(uint32_t len);
 NS_DECL_THREADSAFE_FFI_REFCOUNTING(nsStyleQuoteValues, QuoteValues);
 
+nsCSSValueSharedList* Gecko_NewCSSValueSharedList(uint32_t len);
+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);
+nsCSSValueBorrowedMut Gecko_CSSValue_GetArrayItem(nsCSSValueBorrowedMut css_value, int32_t index);
+NS_DECL_THREADSAFE_FFI_REFCOUNTING(nsCSSValueSharedList, CSSValueSharedList);
+
 // Style-struct management.
 #define STYLE_STRUCT(name, checkdata_cb)                                       \
   void Gecko_Construct_nsStyle##name(nsStyle##name* ptr);                      \
   void Gecko_CopyConstruct_nsStyle##name(nsStyle##name* ptr,                   \
                                          const nsStyle##name* other);          \
   void Gecko_Destroy_nsStyle##name(nsStyle##name* ptr);
 #include "nsStyleStructList.h"
 #undef STYLE_STRUCT
--- a/layout/style/StyleAnimationValue.cpp
+++ b/layout/style/StyleAnimationValue.cpp
@@ -266,37 +266,30 @@ ToPrimitive(nsCSSValue::Array* aArray)
       break;
     }
     default:
       arr = aArray;
   }
   return arr.forget();
 }
 
-inline void
-nscoordToCSSValue(nscoord aCoord, nsCSSValue& aCSSValue)
-{
-  aCSSValue.SetFloatValue(nsPresContext::AppUnitsToFloatCSSPixels(aCoord),
-                          eCSSUnit_Pixel);
-}
-
 static void
 AppendCSSShadowValue(const nsCSSShadowItem *aShadow,
                      nsCSSValueList **&aResultTail)
 {
   MOZ_ASSERT(aShadow, "shadow expected");
 
   // X, Y, Radius, Spread, Color, Inset
   RefPtr<nsCSSValue::Array> arr = nsCSSValue::Array::Create(6);
-  nscoordToCSSValue(aShadow->mXOffset, arr->Item(0));
-  nscoordToCSSValue(aShadow->mYOffset, arr->Item(1));
-  nscoordToCSSValue(aShadow->mRadius, arr->Item(2));
+  arr->Item(0).SetIntegerCoordValue(aShadow->mXOffset);
+  arr->Item(1).SetIntegerCoordValue(aShadow->mYOffset);
+  arr->Item(2).SetIntegerCoordValue(aShadow->mRadius);
   // NOTE: This code sometimes stores mSpread: 0 even when
   // the parser would be required to leave it null.
-  nscoordToCSSValue(aShadow->mSpread, arr->Item(3));
+  arr->Item(3).SetIntegerCoordValue(aShadow->mSpread);
   if (aShadow->mHasColor) {
     arr->Item(4).SetColorValue(aShadow->mColor);
   }
   if (aShadow->mInset) {
     arr->Item(5).SetIntValue(uint8_t(StyleBoxShadowType::Inset),
                              eCSSUnit_Enumerated);
   }
 
@@ -383,33 +376,23 @@ ExtractCalcValue(const nsCSSValue& aValu
     result.mPercent = aValue.GetPercentValue();
     result.mHasPercent = true;
     return result;
   }
   return ExtractCalcValueInternal(aValue);
 }
 
 static void
-SetCalcValue(const nsStyleCoord::CalcValue* aCalc, nsCSSValue& aValue)
+CalcValueToCSSValue(const nsStyleCoord::CalcValue* aCalc, nsCSSValue& aValue)
 {
-  RefPtr<nsCSSValue::Array> arr = nsCSSValue::Array::Create(1);
-  if (!aCalc->mHasPercent) {
-    nscoordToCSSValue(aCalc->mLength, arr->Item(0));
-  } else {
-    nsCSSValue::Array *arr2 = nsCSSValue::Array::Create(2);
-    arr->Item(0).SetArrayValue(arr2, eCSSUnit_Calc_Plus);
-    nscoordToCSSValue(aCalc->mLength, arr2->Item(0));
-    arr2->Item(1).SetPercentValue(aCalc->mPercent);
-  }
-
-  aValue.SetArrayValue(arr, eCSSUnit_Calc);
+  aValue.SetCalcValue(aCalc);
 }
 
 static void
-SetCalcValue(const PixelCalcValue& aCalc, nsCSSValue& aValue)
+CalcValueToCSSValue(const PixelCalcValue& aCalc, nsCSSValue& aValue)
 {
   RefPtr<nsCSSValue::Array> arr = nsCSSValue::Array::Create(1);
   if (!aCalc.mHasPercent) {
     arr->Item(0).SetFloatValue(aCalc.mLength, eCSSUnit_Pixel);
   } else {
     nsCSSValue::Array *arr2 = nsCSSValue::Array::Create(2);
     arr->Item(0).SetArrayValue(arr2, eCSSUnit_Calc_Plus);
     arr2->Item(0).SetFloatValue(aCalc.mLength, eCSSUnit_Pixel);
@@ -583,17 +566,17 @@ AddCSSValueCanonicalCalc(double aCoeff1,
   PixelCalcValue v1 = ExtractCalcValue(aValue1);
   PixelCalcValue v2 = ExtractCalcValue(aValue2);
   PixelCalcValue result;
   result.mLength = aCoeff1 * v1.mLength + aCoeff2 * v2.mLength;
   result.mPercent = aCoeff1 * v1.mPercent + aCoeff2 * v2.mPercent;
   result.mHasPercent = v1.mHasPercent || v2.mHasPercent;
   MOZ_ASSERT(result.mHasPercent || result.mPercent == 0.0f,
              "can't have a nonzero percentage part without having percentages");
-  SetCalcValue(result, aResult);
+  CalcValueToCSSValue(result, aResult);
 }
 
 static inline void
 AddCSSValuePixel(double aCoeff1, const nsCSSValue &aValue1,
                  double aCoeff2, const nsCSSValue &aValue2,
                  nsCSSValue &aResult, uint32_t aValueRestrictions = 0)
 {
   MOZ_ASSERT(aValue1.GetUnit() == eCSSUnit_Pixel, "unexpected unit");
@@ -3497,17 +3480,17 @@ StyleAnimationValue::UncomputeValue(nsCS
       aSpecifiedValue.
         SetIntValue(aComputedValue.GetIntValue(), eCSSUnit_Enumerated);
       break;
     case eUnit_Integer:
       aSpecifiedValue.
         SetIntValue(aComputedValue.GetIntValue(), eCSSUnit_Integer);
       break;
     case eUnit_Coord:
-      nscoordToCSSValue(aComputedValue.GetCoordValue(), aSpecifiedValue);
+      aSpecifiedValue.SetIntegerCoordValue(aComputedValue.GetCoordValue());
       break;
     case eUnit_Percent:
       aSpecifiedValue.SetPercentValue(aComputedValue.GetPercentValue());
       break;
     case eUnit_Float:
       aSpecifiedValue.
         SetFloatValue(aComputedValue.GetFloatValue(), eCSSUnit_Number);
       break;
@@ -3688,42 +3671,42 @@ StyleCoordToValue(const nsStyleCoord& aC
                          StyleAnimationValue::eUnit_Enumerated);
       break;
     case eStyleUnit_Integer:
       aValue.SetIntValue(aCoord.GetIntValue(),
                          StyleAnimationValue::eUnit_Integer);
       break;
     case eStyleUnit_Calc: {
       nsAutoPtr<nsCSSValue> val(new nsCSSValue);
-      SetCalcValue(aCoord.GetCalcValue(), *val);
+      CalcValueToCSSValue(aCoord.GetCalcValue(), *val);
       aValue.SetAndAdoptCSSValueValue(val.forget(),
                                       StyleAnimationValue::eUnit_Calc);
       break;
     }
     default:
       return false;
   }
   return true;
 }
 
 static bool
 StyleCoordToCSSValue(const nsStyleCoord& aCoord, nsCSSValue& aCSSValue)
 {
   switch (aCoord.GetUnit()) {
     case eStyleUnit_Coord:
-      nscoordToCSSValue(aCoord.GetCoordValue(), aCSSValue);
+      aCSSValue.SetIntegerCoordValue(aCoord.GetCoordValue());
       break;
     case eStyleUnit_Factor:
       aCSSValue.SetFloatValue(aCoord.GetFactorValue(), eCSSUnit_Number);
       break;
     case eStyleUnit_Percent:
       aCSSValue.SetPercentValue(aCoord.GetPercentValue());
       break;
     case eStyleUnit_Calc:
-      SetCalcValue(aCoord.GetCalcValue(), aCSSValue);
+      CalcValueToCSSValue(aCoord.GetCalcValue(), aCSSValue);
       break;
     case eStyleUnit_Degree:
       aCSSValue.SetFloatValue(aCoord.GetAngleValue(), eCSSUnit_Degree);
       break;
     case eStyleUnit_Grad:
       aCSSValue.SetFloatValue(aCoord.GetAngleValue(), eCSSUnit_Grad);
       break;
     case eStyleUnit_Radian:
@@ -3748,35 +3731,35 @@ SetPositionValue(const Position& aPos, n
   // NOTE: Array entries #0 and #2 here are intentionally left untouched, with
   // eCSSUnit_Null.  The purpose of these entries in our specified-style
   // <position> representation is to store edge names.  But for values
   // extracted from computed style (which is what we're dealing with here),
   // we'll just have a normalized "x,y" position, with no edge names needed.
   nsCSSValue& xValue = posArray->Item(1);
   nsCSSValue& yValue = posArray->Item(3);
 
-  SetCalcValue(&aPos.mXPosition, xValue);
-  SetCalcValue(&aPos.mYPosition, yValue);
+  CalcValueToCSSValue(&aPos.mXPosition, xValue);
+  CalcValueToCSSValue(&aPos.mYPosition, yValue);
 }
 
 static void
 SetPositionCoordValue(const Position::Coord& aPosCoord,
                       nsCSSValue& aCSSValue)
 {
   RefPtr<nsCSSValue::Array> posArray = nsCSSValue::Array::Create(2);
   aCSSValue.SetArrayValue(posArray.get(), eCSSUnit_Array);
 
   // NOTE: Array entry #0 here is intentionally left untouched, with
   // eCSSUnit_Null.  The purpose of this entry in our specified-style
   // <position-coord> representation is to store edge names.  But for values
   // extracted from computed style (which is what we're dealing with here),
   // we'll just have a normalized "x"/"y" position, with no edge names needed.
   nsCSSValue& value = posArray->Item(1);
 
-  SetCalcValue(&aPosCoord, value);
+  CalcValueToCSSValue(&aPosCoord, value);
 }
 
 /*
  * Assign |aOutput = aInput|, except with any non-pixel lengths
  * replaced with the equivalent in pixels, and any non-canonical calc()
  * expressions replaced with canonical ones.
  */
 static void
@@ -3788,17 +3771,17 @@ SubstitutePixelValues(nsStyleContext* aS
     nsRuleNode::ComputedCalc c =
       nsRuleNode::SpecifiedCalcToComputedCalc(aInput, aStyleContext,
                                               aStyleContext->PresContext(),
                                               conditions);
     nsStyleCoord::CalcValue c2;
     c2.mLength = c.mLength;
     c2.mPercent = c.mPercent;
     c2.mHasPercent = true; // doesn't matter for transform translate
-    SetCalcValue(&c2, aOutput);
+    CalcValueToCSSValue(&c2, aOutput);
   } else if (aInput.UnitHasArrayValue()) {
     const nsCSSValue::Array *inputArray = aInput.GetArrayValue();
     RefPtr<nsCSSValue::Array> outputArray =
       nsCSSValue::Array::Create(inputArray->Count());
     for (size_t i = 0, i_end = inputArray->Count(); i < i_end; ++i) {
       SubstitutePixelValues(aStyleContext,
                             inputArray->Item(i), outputArray->Item(i));
     }
@@ -3876,56 +3859,56 @@ ExtractImageLayerSizePairList(const nsSt
         item->mXValue.SetIntValue(size.mWidthType,
                                   eCSSUnit_Enumerated);
         break;
       case nsStyleImageLayers::Size::eAuto:
         item->mXValue.SetAutoValue();
         break;
       case nsStyleImageLayers::Size::eLengthPercentage:
         // XXXbz is there a good reason we can't just
-        // SetCalcValue(&size.mWidth, item->mXValue) here?
+        // CalcValueToCSSValue(&size.mWidth, item->mXValue) here?
         if (!size.mWidth.mHasPercent &&
             // negative values must have come from calc()
             size.mWidth.mLength >= 0) {
           MOZ_ASSERT(size.mWidth.mPercent == 0.0f,
                      "Shouldn't have mPercent");
-          nscoordToCSSValue(size.mWidth.mLength, item->mXValue);
+          item->mXValue.SetIntegerCoordValue(size.mWidth.mLength);
         } else if (size.mWidth.mLength == 0 &&
                    // negative values must have come from calc()
                    size.mWidth.mPercent >= 0.0f) {
           item->mXValue.SetPercentValue(size.mWidth.mPercent);
         } else {
-          SetCalcValue(&size.mWidth, item->mXValue);
+          CalcValueToCSSValue(&size.mWidth, item->mXValue);
         }
         break;
     }
 
     switch (size.mHeightType) {
       case nsStyleImageLayers::Size::eContain:
       case nsStyleImageLayers::Size::eCover:
         // leave it null
         break;
       case nsStyleImageLayers::Size::eAuto:
         item->mYValue.SetAutoValue();
         break;
       case nsStyleImageLayers::Size::eLengthPercentage:
         // XXXbz is there a good reason we can't just
-        // SetCalcValue(&size.mHeight, item->mYValue) here?
+        // CalcValueToCSSValue(&size.mHeight, item->mYValue) here?
         if (!size.mHeight.mHasPercent &&
             // negative values must have come from calc()
             size.mHeight.mLength >= 0) {
           MOZ_ASSERT(size.mHeight.mPercent == 0.0f,
                      "Shouldn't have mPercent");
-          nscoordToCSSValue(size.mHeight.mLength, item->mYValue);
+          item->mYValue.SetIntegerCoordValue(size.mHeight.mLength);
         } else if (size.mHeight.mLength == 0 &&
                    // negative values must have come from calc()
                    size.mHeight.mPercent >= 0.0f) {
           item->mYValue.SetPercentValue(size.mHeight.mPercent);
         } else {
-          SetCalcValue(&size.mHeight, item->mYValue);
+          CalcValueToCSSValue(&size.mHeight, item->mYValue);
         }
         break;
     }
   }
 
   aComputedValue.SetAndAdoptCSSValuePairListValue(result.forget());
 }
 
@@ -4080,18 +4063,18 @@ StyleAnimationValue::ExtractComputedValu
                                      eUnit_Integer);
           break;
         }
 
         case eCSSProperty_border_spacing: {
           const nsStyleTableBorder *styleTableBorder =
             static_cast<const nsStyleTableBorder*>(styleStruct);
           nsAutoPtr<nsCSSValuePair> pair(new nsCSSValuePair);
-          nscoordToCSSValue(styleTableBorder->mBorderSpacingCol, pair->mXValue);
-          nscoordToCSSValue(styleTableBorder->mBorderSpacingRow, pair->mYValue);
+          pair->mXValue.SetIntegerCoordValue(styleTableBorder->mBorderSpacingCol);
+          pair->mYValue.SetIntegerCoordValue(styleTableBorder->mBorderSpacingRow);
           aComputedValue.SetAndAdoptCSSValuePairValue(pair.forget(),
                                                       eUnit_CSSValuePair);
           break;
         }
 
         case eCSSProperty_transform_origin: {
           const nsStyleDisplay *styleDisplay =
             static_cast<const nsStyleDisplay*>(styleStruct);
@@ -4201,51 +4184,51 @@ StyleAnimationValue::ExtractComputedValu
             static_cast<const nsStyleList*>(styleStruct);
           const nsRect &srect = list->mImageRegion;
           if (srect.IsEmpty()) {
             aComputedValue.SetAutoValue();
             break;
           }
 
           nsCSSRect *vrect = new nsCSSRect;
-          nscoordToCSSValue(srect.x, vrect->mLeft);
-          nscoordToCSSValue(srect.y, vrect->mTop);
-          nscoordToCSSValue(srect.XMost(), vrect->mRight);
-          nscoordToCSSValue(srect.YMost(), vrect->mBottom);
+          vrect->mLeft.SetIntegerCoordValue(srect.x);
+          vrect->mTop.SetIntegerCoordValue(srect.y);
+          vrect->mRight.SetIntegerCoordValue(srect.XMost());
+          vrect->mBottom.SetIntegerCoordValue(srect.YMost());
           aComputedValue.SetAndAdoptCSSRectValue(vrect, eUnit_CSSRect);
           break;
         }
 
         case eCSSProperty_clip: {
           const nsStyleEffects* effects =
             static_cast<const nsStyleEffects*>(styleStruct);
           if (!(effects->mClipFlags & NS_STYLE_CLIP_RECT)) {
             aComputedValue.SetAutoValue();
           } else {
             nsCSSRect *vrect = new nsCSSRect;
             const nsRect &srect = effects->mClip;
             if (effects->mClipFlags & NS_STYLE_CLIP_TOP_AUTO) {
               vrect->mTop.SetAutoValue();
             } else {
-              nscoordToCSSValue(srect.y, vrect->mTop);
+              vrect->mTop.SetIntegerCoordValue(srect.y);
             }
             if (effects->mClipFlags & NS_STYLE_CLIP_RIGHT_AUTO) {
               vrect->mRight.SetAutoValue();
             } else {
-              nscoordToCSSValue(srect.XMost(), vrect->mRight);
+              vrect->mRight.SetIntegerCoordValue(srect.XMost());
             }
             if (effects->mClipFlags & NS_STYLE_CLIP_BOTTOM_AUTO) {
               vrect->mBottom.SetAutoValue();
             } else {
-              nscoordToCSSValue(srect.YMost(), vrect->mBottom);
+              vrect->mBottom.SetIntegerCoordValue(srect.YMost());
             }
             if (effects->mClipFlags & NS_STYLE_CLIP_LEFT_AUTO) {
               vrect->mLeft.SetAutoValue();
             } else {
-              nscoordToCSSValue(srect.x, vrect->mLeft);
+              vrect->mLeft.SetIntegerCoordValue(srect.x);
             }
             aComputedValue.SetAndAdoptCSSRectValue(vrect, eUnit_CSSRect);
           }
           break;
         }
 
         case eCSSProperty_object_position: {
           const nsStylePosition* stylePos =
--- a/layout/style/StyleAnimationValue.h
+++ b/layout/style/StyleAnimationValue.h
@@ -11,16 +11,17 @@
 #include "mozilla/gfx/MatrixFwd.h"
 #include "mozilla/UniquePtr.h"
 #include "nsStringFwd.h"
 #include "nsStringBuffer.h"
 #include "nsCoord.h"
 #include "nsColor.h"
 #include "nsCSSProps.h"
 #include "nsCSSValue.h"
+#include "nsStyleCoord.h"
 
 class nsIFrame;
 class nsStyleContext;
 class gfx3DMatrix;
 struct RawServoDeclarationBlock;
 
 namespace mozilla {
 
@@ -591,12 +592,11 @@ private:
   }
 };
 
 struct PropertyStyleAnimationValuePair
 {
   nsCSSPropertyID mProperty;
   StyleAnimationValue mValue;
 };
-
 } // namespace mozilla
 
 #endif
--- a/layout/style/nsCSSValue.cpp
+++ b/layout/style/nsCSSValue.cpp
@@ -489,24 +489,32 @@ void nsCSSValue::SetStringValue(const ns
     mUnit = eCSSUnit_Null;
 }
 
 void nsCSSValue::SetColorValue(nscolor aValue)
 {
   SetIntegerColorValue(aValue, eCSSUnit_RGBAColor);
 }
 
+
+
 void nsCSSValue::SetIntegerColorValue(nscolor aValue, nsCSSUnit aUnit)
 {
   Reset();
   mUnit = aUnit;
   MOZ_ASSERT(IsIntegerColorUnit(), "bad unit");
   mValue.mColor = aValue;
 }
 
+void nsCSSValue::SetIntegerCoordValue(nscoord aValue)
+{
+  SetFloatValue(nsPresContext::AppUnitsToFloatCSSPixels(aValue),
+                eCSSUnit_Pixel);
+}
+
 void nsCSSValue::SetFloatColorValue(float aComponent1,
                                     float aComponent2,
                                     float aComponent3,
                                     float aAlpha,
                                     nsCSSUnit aUnit)
 {
   Reset();
   mUnit = aUnit;
@@ -804,16 +812,31 @@ void nsCSSValue::SetDummyValue()
 }
 
 void nsCSSValue::SetDummyInheritValue()
 {
   Reset();
   mUnit = eCSSUnit_DummyInherit;
 }
 
+void nsCSSValue::SetCalcValue(const nsStyleCoord::CalcValue* aCalc)
+{
+  RefPtr<nsCSSValue::Array> arr = nsCSSValue::Array::Create(1);
+  if (!aCalc->mHasPercent) {
+    arr->Item(0).SetIntegerCoordValue(aCalc->mLength);
+  } else {
+    nsCSSValue::Array *arr2 = nsCSSValue::Array::Create(2);
+    arr->Item(0).SetArrayValue(arr2, eCSSUnit_Calc_Plus);
+    arr2->Item(0).SetIntegerCoordValue(aCalc->mLength);
+    arr2->Item(1).SetPercentValue(aCalc->mPercent);
+  }
+
+  SetArrayValue(arr, eCSSUnit_Calc);
+}
+
 void nsCSSValue::StartImageLoad(nsIDocument* aDocument) const
 {
   MOZ_ASSERT(eCSSUnit_URL == mUnit, "Not a URL value!");
   mozilla::css::ImageValue* image =
     new mozilla::css::ImageValue(mValue.mURL->GetURI(),
                                  mValue.mURL->mString,
                                  mValue.mURL->mBaseURI,
                                  mValue.mURL->mReferrer,
--- a/layout/style/nsCSSValue.h
+++ b/layout/style/nsCSSValue.h
@@ -25,16 +25,17 @@
 #include "nsColor.h"
 #include "nsCoord.h"
 #include "nsProxyRelease.h"
 #include "nsRefPtrHashtable.h"
 #include "nsString.h"
 #include "nsStringBuffer.h"
 #include "nsTArray.h"
 #include "nsStyleConsts.h"
+#include "nsStyleCoord.h"
 #include "gfxFontFamilyList.h"
 
 class imgRequestProxy;
 class nsIContent;
 class nsIDocument;
 class nsIPrincipal;
 class nsIURI;
 class nsPresContext;
@@ -905,16 +906,18 @@ public:
                   "aValue must be an enum that fits within mValue.mInt");
     SetIntValue(static_cast<int32_t>(aValue), aUnit);
   }
   void SetPercentValue(float aValue);
   void SetFloatValue(float aValue, nsCSSUnit aUnit);
   void SetStringValue(const nsString& aValue, nsCSSUnit aUnit);
   void SetColorValue(nscolor aValue);
   void SetIntegerColorValue(nscolor aValue, nsCSSUnit aUnit);
+  // converts the nscoord to pixels
+  void SetIntegerCoordValue(nscoord aCoord);
   void SetFloatColorValue(float aComponent1,
                           float aComponent2,
                           float aComponent3,
                           float aAlpha, nsCSSUnit aUnit);
   void SetRGBAColorValue(const mozilla::css::RGBAColorData& aValue);
   void SetComplexColorValue(
     already_AddRefed<mozilla::css::ComplexColorValue> aValue);
   void SetArrayValue(nsCSSValue::Array* aArray, nsCSSUnit aUnit);
@@ -937,16 +940,19 @@ public:
   void SetUnsetValue();
   void SetNoneValue();
   void SetAllValue();
   void SetNormalValue();
   void SetSystemFontValue();
   void SetDummyValue();
   void SetDummyInheritValue();
 
+  // Converts an nsStyleCoord::CalcValue back into a CSSValue
+  void SetCalcValue(const nsStyleCoord::CalcValue* aCalc);
+
   // These are a little different - they allocate storage for you and
   // return a handle.
   nsCSSRect& SetRectValue();
   nsCSSValueList* SetListValue();
   nsCSSValuePairList* SetPairListValue();
 
   // These take ownership of the passed-in resource.
   void AdoptListValue(mozilla::UniquePtr<nsCSSValueList> aValue);
@@ -1202,17 +1208,17 @@ struct nsCSSValueSharedList final {
     MOZ_COUNT_CTOR(nsCSSValueSharedList);
   }
 
 private:
   // Private destructor, to discourage deletion outside of Release():
   ~nsCSSValueSharedList();
 
 public:
-  NS_INLINE_DECL_REFCOUNTING(nsCSSValueSharedList)
+  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(nsCSSValueSharedList)
 
   void AppendToString(nsCSSPropertyID aProperty, nsAString& aResult,
                       nsCSSValue::Serialization aValueSerialization) const;
 
   bool operator==(nsCSSValueSharedList const& aOther) const;
   bool operator!=(const nsCSSValueSharedList& aOther) const
   { return !(*this == aOther); }