Bug 1323912 - Part 3. Pass opacity in gradient-mask painting path. r=mstange
authorcku <cku@mozilla.com>
Wed, 04 Jan 2017 01:05:05 +0800
changeset 373021 e83758b801cf05ee034f6d41831924c90b5faa4a
parent 373020 04689bf3a1f2edc7956e203b599a154a4e7ba026
child 373022 dc22594f021497215362df65b7e9ccc4c409b628
push id6996
push userjlorenzo@mozilla.com
push dateMon, 06 Mar 2017 20:48:21 +0000
treeherdermozilla-beta@d89512dab048 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmstange
bugs1323912
milestone53.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1323912 - Part 3. Pass opacity in gradient-mask painting path. r=mstange MozReview-Commit-ID: E2RdOHGoia8
layout/painting/nsCSSRendering.cpp
layout/painting/nsCSSRendering.h
--- a/layout/painting/nsCSSRendering.cpp
+++ b/layout/painting/nsCSSRendering.cpp
@@ -2781,17 +2781,18 @@ void
 nsCSSRendering::PaintGradient(nsPresContext* aPresContext,
                               nsRenderingContext& aRenderingContext,
                               nsStyleGradient* aGradient,
                               const nsRect& aDirtyRect,
                               const nsRect& aDest,
                               const nsRect& aFillArea,
                               const nsSize& aRepeatSize,
                               const CSSIntRect& aSrc,
-                              const nsSize& aIntrinsicSize)
+                              const nsSize& aIntrinsicSize,
+                              float aOpacity)
 {
   PROFILER_LABEL("nsCSSRendering", "PaintGradient",
     js::ProfileEntry::Category::GRAPHICS);
 
   Telemetry::AutoTimer<Telemetry::GRADIENT_DURATION, Telemetry::Microsecond> gradientTimer;
   if (aDest.IsEmpty() || aFillArea.IsEmpty()) {
     return;
   }
@@ -3130,16 +3131,17 @@ nsCSSRendering::PaintGradient(nsPresCont
   // which is a lookup table used to evaluate the gradient. This surface can use
   // much memory (ram and/or GPU ram) and can be expensive to create. So we cache it.
   // The cache key correlates 1:1 with the arguments for CreateGradientStops (also the implied backend type)
   // Note that GradientStop is a simple struct with a stop value (while GradientStops has the surface).
   nsTArray<gfx::GradientStop> rawStops(stops.Length());
   rawStops.SetLength(stops.Length());
   for(uint32_t i = 0; i < stops.Length(); i++) {
     rawStops[i].color = stops[i].mColor;
+    rawStops[i].color.a *= aOpacity;
     rawStops[i].offset = stopScale * (stops[i].mPosition - stopOrigin);
   }
   RefPtr<mozilla::gfx::GradientStops> gs =
     gfxGradientCache::GetOrCreateGradientStops(ctx->GetDrawTarget(),
                                                rawStops,
                                                isRepeat ? gfx::ExtendMode::REPEAT : gfx::ExtendMode::CLAMP);
   gradientPattern->SetColorStops(gs);
 
@@ -3205,16 +3207,17 @@ nsCSSRendering::PaintGradient(nsPresCont
       ctx->Rectangle(fillRect);
 
       gfxRect dirtyFillRect = fillRect.Intersect(dirtyAreaToFill);
       gfxRect fillRectRelativeToTile = dirtyFillRect - tileRect.TopLeft();
       Color edgeColor;
       if (aGradient->mShape == NS_STYLE_GRADIENT_SHAPE_LINEAR && !isRepeat &&
           RectIsBeyondLinearGradientEdge(fillRectRelativeToTile, matrix, stops,
                                          gradientStart, gradientEnd, &edgeColor)) {
+        edgeColor.a = aOpacity;
         ctx->SetColor(edgeColor);
       } else {
         ctx->SetMatrix(
           ctx->CurrentMatrix().Copy().Translate(tileRect.TopLeft()));
         ctx->SetPattern(gradientPattern);
       }
       ctx->Fill();
       ctx->SetMatrix(ctm);
@@ -5703,17 +5706,18 @@ nsImageRenderer::Draw(nsPresContext*    
                                            ConvertImageRendererToDrawFlags(mFlags),
                                            mExtendMode, aOpacity);
       break;
     }
     case eStyleImageType_Gradient:
     {
       nsCSSRendering::PaintGradient(aPresContext, aRenderingContext,
                                     mGradientData, aDirtyRect,
-                                    aDest, aFill, aRepeatSize, aSrc, mSize);
+                                    aDest, aFill, aRepeatSize, aSrc, mSize,
+                                    aOpacity);
       break;
     }
     case eStyleImageType_Element:
     {
       RefPtr<gfxDrawable> drawable = DrawableForElement(aDest,
                                                           aRenderingContext);
       if (!drawable) {
         NS_WARNING("Could not create drawable for element");
--- a/layout/painting/nsCSSRendering.h
+++ b/layout/painting/nsCSSRendering.h
@@ -474,17 +474,18 @@ struct nsCSSRendering {
   static void PaintGradient(nsPresContext* aPresContext,
                             nsRenderingContext& aRenderingContext,
                             nsStyleGradient* aGradient,
                             const nsRect& aDirtyRect,
                             const nsRect& aDest,
                             const nsRect& aFill,
                             const nsSize& aRepeatSize,
                             const mozilla::CSSIntRect& aSrc,
-                            const nsSize& aIntrinsiceSize);
+                            const nsSize& aIntrinsiceSize,
+                            float aOpacity = 1.0);
 
   /**
    * Find the frame whose background style should be used to draw the
    * canvas background. aForFrame must be the frame for the root element
    * whose background style should be used. This function will return
    * aForFrame unless the <body> background should be propagated, in
    * which case we return the frame associated with the <body>'s background.
    */