Bug 1341703 - Part 3. Handle nsStyleBorder::CalcDifference off main thread. draft
authorcku <cku@mozilla.com>
Tue, 18 Apr 2017 15:04:35 +0800
changeset 568808 67530e29e25a638d6a2ef35dd944604da63d5958
parent 568807 a477e80f03b61be9961bc61770a2b55cce139b91
child 568809 e97d5e1cfdf40ccb4698d6a0a82afd7e52637779
push id55988
push userbmo:cku@mozilla.com
push dateWed, 26 Apr 2017 16:19:04 +0000
bugs1341703
milestone55.0a1
Bug 1341703 - Part 3. 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
@@ -474,17 +474,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;
     }
@@ -503,19 +507,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;
   }