Bug 1359844 - Handle nsStyleBorder::CalcDifference off main thread. draft
authorcku <cku@mozilla.com>
Tue, 18 Apr 2017 15:04:35 +0800
changeset 568748 0cbcf56a260c24bc04f8337965924cea5a1b638d
parent 568747 46d17d8f0f30ad8a99675c34cf201d3b1630dda6
child 626018 e4658746af0809be6482272a9731a150e58a1742
push id55969
push userbmo:cku@mozilla.com
push dateWed, 26 Apr 2017 15:09:44 +0000
bugs1359844
milestone55.0a1
Bug 1359844 - Handle nsStyleBorder::CalcDifference off main thread. Image loading status can be accessed in main thread only, so we can not use nsStyleImage::IsLoaded in nsStyleBorder::CalcDifference, which might be executed on a background thread. The drawback of this change is we may paint a border-image, once, even before it was actually loaded, which is a waste, because we have nothing to draw yet. PS: We did not check nsStyleImage::IsLoaded in both background-image and mask-image's CalcDifference. MozReview-Commit-ID: 5knH6dZziL8
layout/style/nsStyleStruct.cpp
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -479,17 +479,21 @@ nsStyleBorder::CalcDifference(const nsSt
     }
   }
 
   if (mBorderRadius != aNewData.mBorderRadius ||
       !mBorderColors != !aNewData.mBorderColors) {
     return nsChangeHint_RepaintFrame;
   }
 
-  if (IsBorderImageLoaded() || aNewData.IsBorderImageLoaded()) {
+  // Loading status of the border image can be accessed in main thread only
+  // while CalcDifference might be executed on a background thread. As a
+  // result, we have to check mBorderImage* fields even before border image was
+  // actually loaded.
+  if (!mBorderImageSource.IsEmpty() || !aNewData.mBorderImageSource.IsEmpty()) {
     if (mBorderImageSource  != aNewData.mBorderImageSource  ||
         mBorderImageRepeatH != aNewData.mBorderImageRepeatH ||
         mBorderImageRepeatV != aNewData.mBorderImageRepeatV ||
         mBorderImageSlice   != aNewData.mBorderImageSlice   ||
         mBorderImageFill    != aNewData.mBorderImageFill    ||
         mBorderImageWidth   != aNewData.mBorderImageWidth) {
       return nsChangeHint_RepaintFrame;
     }
@@ -508,19 +512,17 @@ nsStyleBorder::CalcDifference(const nsSt
 
   // mBorder is the specified border value.  Changes to this don't
   // need any change processing, since we operate on the computed
   // border values instead.
   if (mBorder != aNewData.mBorder) {
     return nsChangeHint_NeutralChange;
   }
 
-  // mBorderImage* fields are checked only when border image was
-  // actualy loaded. But we need to return neutral change even when
-  // they are not actually used.
+  // mBorderImage* fields are checked only when border-image is not 'none'.
   if (mBorderImageSource  != aNewData.mBorderImageSource  ||
       mBorderImageRepeatH != aNewData.mBorderImageRepeatH ||
       mBorderImageRepeatV != aNewData.mBorderImageRepeatV ||
       mBorderImageSlice   != aNewData.mBorderImageSlice   ||
       mBorderImageFill    != aNewData.mBorderImageFill    ||
       mBorderImageWidth   != aNewData.mBorderImageWidth) {
     return nsChangeHint_NeutralChange;
   }