Bug 1323912 - Part 3. Pass opacity in gradient-mask painting path.
MozReview-Commit-ID: E2RdOHGoia8
--- 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.
*/