Bug 1024148 - Part 2: Merge nsDisplayOpacity into nsDisplayBackgroundColor. r=mattwoodrow
authorBenoit Girard <b56girard@gmail.com>
Sat, 14 Jun 2014 11:10:45 -0400
changeset 188957 1218c119a5d4789b455f0950984adc41c22c6b98
parent 188956 c5f6188b4794dbeb5b5e475d1e7bce7c4a8517e7
child 188958 ec6629d52c34d78b76e4daa41aeb51e51f17f1a2
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersmattwoodrow
bugs1024148
milestone33.0a1
Bug 1024148 - Part 2: Merge nsDisplayOpacity into nsDisplayBackgroundColor. r=mattwoodrow
gfx/src/nsColor.h
layout/base/nsCSSRendering.cpp
layout/base/nsCSSRendering.h
layout/base/nsDisplayList.cpp
layout/base/nsDisplayList.h
layout/reftests/bugs/759036-1-ref.html
layout/reftests/bugs/759036-1.html
layout/reftests/bugs/reftest.list
--- a/gfx/src/nsColor.h
+++ b/gfx/src/nsColor.h
@@ -24,16 +24,20 @@ typedef uint32_t nscolor;
 #define NS_RGB(_r,_g,_b) \
   ((nscolor) ((255 << 24) | ((_b)<<16) | ((_g)<<8) | (_r)))
 
 // Make a color out of r,g,b,a values. This assumes that the r,g,b,a
 // values are properly constrained to 0-255.
 #define NS_RGBA(_r,_g,_b,_a) \
   ((nscolor) (((_a) << 24) | ((_b)<<16) | ((_g)<<8) | (_r)))
 
+// Make a color out of a gfxRGBA.
+#define NS_RGBA_FROM_GFXRGBA(gfxColor) \
+  ((nscolor) (gfxColor.Packed()))
+
 // Extract color components from nscolor
 #define NS_GET_R(_rgba) ((uint8_t) ((_rgba) & 0xff))
 #define NS_GET_G(_rgba) ((uint8_t) (((_rgba) >> 8) & 0xff))
 #define NS_GET_B(_rgba) ((uint8_t) (((_rgba) >> 16) & 0xff))
 #define NS_GET_A(_rgba) ((uint8_t) (((_rgba) >> 24) & 0xff))
 
 // Fast approximate division by 255. It has the property that
 // for all 0 <= n <= 255*255, FAST_DIVIDE_BY_255(n) == n/255.
--- a/layout/base/nsCSSRendering.cpp
+++ b/layout/base/nsCSSRendering.cpp
@@ -1597,17 +1597,18 @@ nsCSSRendering::PaintBackground(nsPresCo
 
   PaintBackgroundWithSC(aPresContext, aRenderingContext, aForFrame,
                         aDirtyRect, aBorderArea, sc,
                         *aForFrame->StyleBorder(), aFlags,
                         aBGClipRect, aLayer);
 }
 
 void
-nsCSSRendering::PaintBackgroundColor(nsPresContext* aPresContext,
+nsCSSRendering::PaintBackgroundColor(gfxRGBA aColor,
+                                     nsPresContext* aPresContext,
                                      nsRenderingContext& aRenderingContext,
                                      nsIFrame* aForFrame,
                                      const nsRect& aDirtyRect,
                                      const nsRect& aBorderArea,
                                      uint32_t aFlags)
 {
   PROFILER_LABEL("nsCSSRendering", "PaintBackgroundColor",
     js::ProfileEntry::Category::GRAPHICS);
@@ -1629,17 +1630,17 @@ nsCSSRendering::PaintBackgroundColor(nsP
     nsIContent* content = aForFrame->GetContent();
     if (!content || content->GetParent()) {
       return;
     }
 
     sc = aForFrame->StyleContext();
   }
 
-  PaintBackgroundColorWithSC(aPresContext, aRenderingContext, aForFrame,
+  PaintBackgroundColorWithSC(aColor, aPresContext, aRenderingContext, aForFrame,
                              aDirtyRect, aBorderArea, sc,
                              *aForFrame->StyleBorder(), aFlags);
 }
 
 static bool
 IsOpaqueBorderEdge(const nsStyleBorder& aBorder, mozilla::css::Side aSide)
 {
   if (aBorder.GetComputedBorder().Side(aSide) == 0)
@@ -2868,17 +2869,18 @@ nsCSSRendering::PaintBackgroundWithSC(ns
           }
         }
       }
     }
   }
 }
 
 void
-nsCSSRendering::PaintBackgroundColorWithSC(nsPresContext* aPresContext,
+nsCSSRendering::PaintBackgroundColorWithSC(gfxRGBA aColor,
+                                           nsPresContext* aPresContext,
                                            nsRenderingContext& aRenderingContext,
                                            nsIFrame* aForFrame,
                                            const nsRect& aDirtyRect,
                                            const nsRect& aBorderArea,
                                            nsStyleContext* aBackgroundSC,
                                            const nsStyleBorder& aBorder,
                                            uint32_t aFlags)
 {
@@ -2898,21 +2900,21 @@ nsCSSRendering::PaintBackgroundColorWith
   }
 
   NS_ASSERTION(!IsCanvasFrame(aForFrame), "Should not be trying to paint a background color for canvas frames!");
 
   // Determine whether we are drawing background images and/or
   // background colors.
   bool drawBackgroundImage;
   bool drawBackgroundColor;
-  nscolor bgColor = DetermineBackgroundColor(aPresContext,
-                                             aBackgroundSC,
-                                             aForFrame,
-                                             drawBackgroundImage,
-                                             drawBackgroundColor);
+  DetermineBackgroundColor(aPresContext,
+                           aBackgroundSC,
+                           aForFrame,
+                           drawBackgroundImage,
+                           drawBackgroundColor);
 
   NS_ASSERTION(drawBackgroundImage || drawBackgroundColor,
                "Should not be trying to paint a background if we don't have one");
   if (!drawBackgroundColor) {
     return;
   }
 
   // Compute the outermost boundary of the area that might be painted.
@@ -2946,17 +2948,17 @@ nsCSSRendering::PaintBackgroundColorWith
   }
 
   BackgroundClipState clipState;
   GetBackgroundClip(ctx, currentBackgroundClip, bg->BottomLayer().mAttachment,
                     aForFrame, clipBorderArea,
                     aDirtyRect, haveRoundedCorners, bgRadii, appUnitsPerPixel,
                     &clipState);
 
-  ctx->SetColor(gfxRGBA(bgColor));
+  ctx->SetColor(aColor);
 
   gfxContextAutoSaveRestore autoSR;
   DrawBackgroundColor(clipState, ctx, haveRoundedCorners, appUnitsPerPixel);
 }
 
 static inline bool
 IsTransformed(nsIFrame* aForFrame, nsIFrame* aTopFrame)
 {
--- a/layout/base/nsCSSRendering.h
+++ b/layout/base/nsCSSRendering.h
@@ -490,18 +490,19 @@ struct nsCSSRendering {
   static void PaintBackground(nsPresContext* aPresContext,
                               nsRenderingContext& aRenderingContext,
                               nsIFrame* aForFrame,
                               const nsRect& aDirtyRect,
                               const nsRect& aBorderArea,
                               uint32_t aFlags,
                               nsRect* aBGClipRect = nullptr,
                               int32_t aLayer = -1);
- 
-  static void PaintBackgroundColor(nsPresContext* aPresContext,
+
+  static void PaintBackgroundColor(gfxRGBA aColor,
+                                   nsPresContext* aPresContext,
                                    nsRenderingContext& aRenderingContext,
                                    nsIFrame* aForFrame,
                                    const nsRect& aDirtyRect,
                                    const nsRect& aBorderArea,
                                    uint32_t aFlags);
 
   /**
    * Same as |PaintBackground|, except using the provided style structs.
@@ -518,17 +519,18 @@ struct nsCSSRendering {
                                     const nsRect& aDirtyRect,
                                     const nsRect& aBorderArea,
                                     nsStyleContext *aStyleContext,
                                     const nsStyleBorder& aBorder,
                                     uint32_t aFlags,
                                     nsRect* aBGClipRect = nullptr,
                                     int32_t aLayer = -1);
 
-  static void PaintBackgroundColorWithSC(nsPresContext* aPresContext,
+  static void PaintBackgroundColorWithSC(gfxRGBA aColor,
+                                         nsPresContext* aPresContext,
                                          nsRenderingContext& aRenderingContext,
                                          nsIFrame* aForFrame,
                                          const nsRect& aDirtyRect,
                                          const nsRect& aBorderArea,
                                          nsStyleContext *aStyleContext,
                                          const nsStyleBorder& aBorder,
                                          uint32_t aFlags);
   /**
--- a/layout/base/nsDisplayList.cpp
+++ b/layout/base/nsDisplayList.cpp
@@ -2588,56 +2588,68 @@ nsDisplayThemedBackground::GetBoundsInte
 #ifdef XP_MACOSX
   // Bug 748219
   r.Inflate(mFrame->PresContext()->AppUnitsPerDevPixel());
 #endif
 
   return r + ToReferenceFrame();
 }
 
+bool
+nsDisplayBackgroundColor::ApplyOpacity(nsDisplayListBuilder* aBuilder,
+                                       float aOpacity,
+                                       const DisplayItemClip* aClip)
+{
+  mColor.a = mColor.a * aOpacity;
+  if (aClip) {
+    IntersectClip(aBuilder, *aClip);
+  }
+  return true;
+}
+
 void
 nsDisplayBackgroundColor::Paint(nsDisplayListBuilder* aBuilder,
-                                nsRenderingContext* aCtx) 
+                                nsRenderingContext* aCtx)
 {
   if (mColor == NS_RGBA(0, 0, 0, 0)) {
     return;
   }
 
   nsPoint offset = ToReferenceFrame();
   uint32_t flags = aBuilder->GetBackgroundPaintFlags();
   CheckForBorderItem(this, flags);
-  nsCSSRendering::PaintBackgroundColor(mFrame->PresContext(), *aCtx, mFrame,
+  nsCSSRendering::PaintBackgroundColor(mColor, mFrame->PresContext(), *aCtx, mFrame,
                                        mVisibleRect,
                                        nsRect(offset, mFrame->GetSize()),
                                        flags);
 }
 
 nsRegion
 nsDisplayBackgroundColor::GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
-                                          bool* aSnap) 
+                                          bool* aSnap)
 {
-  if (NS_GET_A(mColor) != 255) {
+  if (mColor.a != 1) {
     return nsRegion();
   }
 
   if (!mBackgroundStyle)
     return nsRegion();
 
   *aSnap = true;
 
   const nsStyleBackground::Layer& bottomLayer = mBackgroundStyle->BottomLayer();
   nsRect borderBox = nsRect(ToReferenceFrame(), mFrame->GetSize());
   nsPresContext* presContext = mFrame->PresContext();
   return nsDisplayBackgroundImage::GetInsideClipRegion(this, presContext, bottomLayer.mClip, borderBox, aSnap);
 }
 
 bool
-nsDisplayBackgroundColor::IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor) 
+nsDisplayBackgroundColor::IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor)
 {
-  *aColor = mColor;
+  *aColor = NS_RGBA_FROM_GFXRGBA(mColor);
 
   if (!mBackgroundStyle)
     return true;
 
   return (!nsLayoutUtils::HasNonZeroCorner(mFrame->StyleBorder()->mBorderRadius) &&
           mBackgroundStyle->BottomLayer().mClip == NS_STYLE_BG_CLIP_BORDER);
 }
 
@@ -2654,19 +2666,19 @@ nsDisplayBackgroundColor::HitTest(nsDisp
 
   aOutFrames->AppendElement(mFrame);
 }
 
 #ifdef MOZ_DUMP_PAINTING
 void
 nsDisplayBackgroundColor::WriteDebugInfo(nsACString& aTo)
 {
-  aTo += nsPrintfCString(" (rgba %d,%d,%d,%d)", 
-          NS_GET_R(mColor), NS_GET_G(mColor),
-          NS_GET_B(mColor), NS_GET_A(mColor));
+  aTo += nsPrintfCString(" (rgba %f,%f,%f,%f)",
+          mColor.r, mColor.g,
+          mColor.b, mColor.a);
 }
 #endif
 
 nsRect
 nsDisplayOutline::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) {
   *aSnap = false;
   return mFrame->GetVisualOverflowRectRelativeToSelf() + ToReferenceFrame();
 }
--- a/layout/base/nsDisplayList.h
+++ b/layout/base/nsDisplayList.h
@@ -2320,54 +2320,64 @@ protected:
 class nsDisplayBackgroundColor : public nsDisplayItem
 {
 public:
   nsDisplayBackgroundColor(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
                            const nsStyleBackground* aBackgroundStyle,
                            nscolor aColor)
     : nsDisplayItem(aBuilder, aFrame)
     , mBackgroundStyle(aBackgroundStyle)
-    , mColor(aColor)
+    , mColor(gfxRGBA(aColor))
   { }
 
   virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) MOZ_OVERRIDE;
-  
+
   virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
                                    bool* aSnap) MOZ_OVERRIDE;
   virtual bool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor) MOZ_OVERRIDE;
   virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
                        HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) MOZ_OVERRIDE;
 
+  virtual bool ApplyOpacity(nsDisplayListBuilder* aBuilder,
+                            float aOpacity,
+                            const DisplayItemClip* aClip) MOZ_OVERRIDE;
+
   virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE
   {
     *aSnap = true;
     return nsRect(ToReferenceFrame(), Frame()->GetSize());
   }
 
   virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE
   {
-    return new nsDisplayItemBoundsGeometry(this, aBuilder);
+    return new nsDisplaySolidColorGeometry(this, aBuilder,
+                                           NS_RGBA_FROM_GFXRGBA(mColor));
   }
 
   virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
                                          const nsDisplayItemGeometry* aGeometry,
                                          nsRegion* aInvalidRegion) MOZ_OVERRIDE
   {
-    const nsDisplayItemBoundsGeometry* geometry = static_cast<const nsDisplayItemBoundsGeometry*>(aGeometry);
+    const nsDisplaySolidColorGeometry* geometry = static_cast<const nsDisplaySolidColorGeometry*>(aGeometry);
+    if (NS_RGBA_FROM_GFXRGBA(mColor) != geometry->mColor) {
+      bool dummy;
+      aInvalidRegion->Or(geometry->mBounds, GetBounds(aBuilder, &dummy));
+      return;
+    }
     ComputeInvalidationRegionDifference(aBuilder, geometry, aInvalidRegion);
   }
 
   NS_DISPLAY_DECL_NAME("BackgroundColor", TYPE_BACKGROUND_COLOR)
 #ifdef MOZ_DUMP_PAINTING
   virtual void WriteDebugInfo(nsACString& aTo) MOZ_OVERRIDE;
 #endif
 
 protected:
   const nsStyleBackground* mBackgroundStyle;
-  nscolor mColor;
+  gfxRGBA mColor;
 };
 
 /**
  * The standard display item to paint the outer CSS box-shadows of a frame.
  */
 class nsDisplayBoxShadowOuter : public nsDisplayItem {
 public:
   nsDisplayBoxShadowOuter(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
--- a/layout/reftests/bugs/759036-1-ref.html
+++ b/layout/reftests/bugs/759036-1-ref.html
@@ -6,17 +6,17 @@
       height: 300px;
       width: 300px;
       overflow:hidden;
       border-radius:30px;
     }
     #inner {
       width: 380px;
       height: 260px;
-      background-color: #7fff7f;
+      background-color: #66ff66;
     }
   </style>
 </head>
 <body>
   <div id="container">
     <div id="inner">
     </div>
   </div>
--- a/layout/reftests/bugs/759036-1.html
+++ b/layout/reftests/bugs/759036-1.html
@@ -2,17 +2,17 @@
 <html>
 <head>
   <style>
     #container {
       height: 300px;
       width: 300px;
       overflow:hidden;
       border-radius:30px;
-      opacity: 0.5;
+      opacity: 0.6;
     }
     #inner {
       width: 380px;
       height: 260px;
       background-color: #00ff00;
     }
   </style>
 </head>
--- a/layout/reftests/bugs/reftest.list
+++ b/layout/reftests/bugs/reftest.list
@@ -1714,17 +1714,17 @@ needs-focus == 731726-1.html 731726-1-re
 == 748692-1a.html 748692-1-ref.html
 == 748692-1b.html 748692-1-ref.html
 skip-if(B2G) == 748803-1.html 748803-1-ref.html
 == 750551-1.html 750551-1-ref.html
 skip-if(B2G) == 751012-1a.html 751012-1-ref.html
 skip-if(B2G) == 751012-1b.html 751012-1-ref.html
 random-if(Android||(B2G&&browserIsRemote)) == 753329-1.html about:blank
 == 758561-1.html 758561-1-ref.html
-fuzzy-if(true,1,19) fails-if(d2d) random-if(Android&&AndroidVersion<15) == 759036-1.html 759036-1-ref.html
+fuzzy-if(true,1,90) random-if(Android&&AndroidVersion<15) == 759036-1.html 759036-1-ref.html
 fuzzy-if(true,17,5879) random-if(Android&&AndroidVersion<15) == 759036-2.html 759036-2-ref.html
 random-if(Android&&AndroidVersion<15) == 776265-1a.html 776265-1-ref.html
 == 776265-1b.html 776265-1-ref.html
 == 776265-1c.html 776265-1-ref.html
 == 776265-1d.html 776265-1-ref.html
 == 776265-2a.html 776265-2-ref.html
 == 776265-2b.html 776265-2-ref.html
 == 776265-2c.html 776265-2-ref.html
@@ -1773,17 +1773,17 @@ skip-if(B2G&&browserIsRemote) == 858803-
 == 883987-1c.html 883987-1-ref.html
 == 883987-1d.html 883987-1-ref.html
 == 883987-1e.html 883987-1-ref.html
 == 883987-1f.html 883987-1-ref.html
 == 890495-1.html 890495-1-ref.html
 random-if(B2G&&browserIsRemote) == 894931-1.html 894931-1-ref.html
 == 897491-1.html 897491-1-ref.html
 == 897491-2.html 897491-2-ref.html
-fuzzy(1,10000) fuzzy-if(Android&&AndroidVersion>=15,5,10000) == 902330-1.html 902330-1-ref.html
+fuzzy(2,10000) fuzzy-if(Android&&AndroidVersion>=15,5,10000) == 902330-1.html 902330-1-ref.html
 fuzzy-if(Android,8,400) == 906199-1.html 906199-1-ref.html
 == 921716-1.html 921716-1-ref.html
 test-pref(layout.css.sticky.enabled,true) random-if(B2G&&browserIsRemote) == 926155-1.html 926155-1-ref.html
 fuzzy-if(cocoaWidget,1,40) random-if(B2G&&browserIsRemote) == 928607-1.html 928607-1-ref.html
 random-if(B2G&&browserIsRemote) == 931464-1.html 931464-1-ref.html
 == 931853.html 931853-ref.html
 == 931853-quirks.html 931853-quirks-ref.html
 fuzzy-if(OSX==10.6,2,30) skip-if(B2G&&browserIsRemote) == 933264-1.html 933264-1-ref.html