Bug 1476843 - Use FillRoundedRect instead of creating a path when possible. r?Bas
MozReview-Commit-ID: 4H9DF57fEvg
--- a/gfx/thebes/gfxBlur.cpp
+++ b/gfx/thebes/gfxBlur.cpp
@@ -536,19 +536,18 @@ CreateBoxShadow(DrawTarget* aDestDrawTar
blur.InitDrawTarget(aDestDrawTarget, blurRect, zeroSpread, aBlurRadius);
if (!blurDT) {
return nullptr;
}
ColorPattern black(Color(0.f, 0.f, 0.f, 1.f));
if (aCornerRadii) {
- RefPtr<Path> roundedRect =
- MakePathForRoundedRect(*blurDT, minRect, *aCornerRadii);
- blurDT->Fill(roundedRect, black);
+ RoundedRect roundedRect(minRect, *aCornerRadii);
+ blurDT->FillRoundedRect(roundedRect, black);
} else {
blurDT->FillRect(minRect, black);
}
IntPoint topLeft;
RefPtr<SourceSurface> result = blur.DoBlur(&aShadowColor, &topLeft);
if (!result) {
return nullptr;
--- a/layout/generic/nsBulletFrame.cpp
+++ b/layout/generic/nsBulletFrame.cpp
@@ -382,16 +382,24 @@ BulletRenderer::Paint(gfxContext& aRende
mDest, aDirtyRect,
/* no SVGImageContext */ Nothing(),
aFlags);
}
if (IsPathType()) {
DrawTarget* drawTarget = aRenderingContext.GetDrawTarget();
+ if (mListStyleType == NS_STYLE_LIST_STYLE_DISC) {
+ Size halfDim = mPathRect.Size().ToUnknownSize() / 2.f;
+ RoundedRect rect(mPathRect.ToUnknownRect(),
+ RectCornerRadii(halfDim.width, halfDim.height));
+ drawTarget->FillRoundedRect(rect, ColorPattern(ToDeviceColor(mColor)));
+ return ImgDrawResult::SUCCESS;
+ }
+
if (!mPath) {
RefPtr<PathBuilder> builder = drawTarget->CreatePathBuilder();
switch (mListStyleType) {
case NS_STYLE_LIST_STYLE_CIRCLE:
case NS_STYLE_LIST_STYLE_DISC:
AppendEllipseToPath(builder, mPathRect.Center().ToUnknownPoint(), mPathRect.Size().ToUnknownSize());
break;
case NS_STYLE_LIST_STYLE_SQUARE:
@@ -411,19 +419,17 @@ BulletRenderer::Paint(gfxContext& aRende
case NS_STYLE_LIST_STYLE_SQUARE:
case NS_STYLE_LIST_STYLE_DISCLOSURE_CLOSED:
case NS_STYLE_LIST_STYLE_DISCLOSURE_OPEN:
drawTarget->Fill(mPath, ColorPattern(ToDeviceColor(mColor)));
break;
default:
MOZ_CRASH("unreachable");
}
- }
-
- if (IsTextType()) {
+ } else if (IsTextType()) {
PaintTextToContext(aFrame, &aRenderingContext, aDisableSubpixelAA);
}
return ImgDrawResult::SUCCESS;
}
void
BulletRenderer::PaintTextToContext(nsIFrame* aFrame,
--- a/layout/generic/nsImageFrame.cpp
+++ b/layout/generic/nsImageFrame.cpp
@@ -1551,20 +1551,19 @@ nsImageFrame::DisplayAltFeedback(gfxCont
drawTarget->StrokeRect(devPxRect, color);
// filled circle in bottom right quadrant of stroked rect:
nscoord twoPX = nsPresContext::CSSPixelsToAppUnits(2);
rect = nsRect(iconXPos + size/2, inner.y + size/2,
size/2 - twoPX, size/2 - twoPX);
devPxRect =
ToRect(nsLayoutUtils::RectToGfxRect(rect, PresContext()->AppUnitsPerDevPixel()));
- RefPtr<PathBuilder> builder = drawTarget->CreatePathBuilder();
- AppendEllipseToPath(builder, devPxRect.Center(), devPxRect.Size());
- RefPtr<Path> ellipse = builder->Finish();
- drawTarget->Fill(ellipse, color);
+ RoundedRect roundedRect(devPxRect, RectCornerRadii(devPxRect.width / 2.f,
+ devPxRect.height / 2.f));
+ drawTarget->FillRoundedRect(roundedRect, color);
}
// Reduce the inner rect by the width of the icon, and leave an
// additional ICON_PADDING pixels for padding
int32_t paddedIconSize =
nsPresContext::CSSPixelsToAppUnits(ICON_SIZE + ICON_PADDING);
if (wm.IsVertical()) {
inner.y += paddedIconSize;
--- a/layout/painting/DisplayItemClip.cpp
+++ b/layout/painting/DisplayItemClip.cpp
@@ -133,21 +133,18 @@ DisplayItemClip::FillIntersectionOfRound
if (!end) {
return;
}
// Push clips for any rects that come BEFORE the rect at |aEnd - 1|, if any:
ApplyRoundedRectClipsTo(aContext, aAppUnitsPerDevPixel, 0, end - 1);
// Now fill the rect at |aEnd - 1|:
- RefPtr<Path> roundedRect = MakeRoundedRectPath(aDrawTarget,
- aAppUnitsPerDevPixel,
- mRoundedClipRects[end - 1]);
ColorPattern color(ToDeviceColor(aColor));
- aDrawTarget.Fill(roundedRect, color);
+ FillRoundedRectPath(aDrawTarget, aAppUnitsPerDevPixel, mRoundedClipRects[end - 1], color);
// Finally, pop any clips that we may have pushed:
for (uint32_t i = 0; i < end - 1; ++i) {
aContext->PopClip();
}
}
already_AddRefed<Path>
@@ -158,16 +155,30 @@ DisplayItemClip::MakeRoundedRectPath(Dra
RectCornerRadii pixelRadii;
nsCSSRendering::ComputePixelRadii(aRoundRect.mRadii, A2D, &pixelRadii);
Rect rect = NSRectToSnappedRect(aRoundRect.mRect, A2D, aDrawTarget);
return MakePathForRoundedRect(aDrawTarget, rect, pixelRadii);
}
+void
+DisplayItemClip::FillRoundedRectPath(DrawTarget& aDrawTarget,
+ int32_t A2D,
+ const RoundedRect &aRoundRect,
+ const Pattern& aFill) const
+{
+ RectCornerRadii pixelRadii;
+ nsCSSRendering::ComputePixelRadii(aRoundRect.mRadii, A2D, &pixelRadii);
+
+ gfx::RoundedRect rect(NSRectToSnappedRect(aRoundRect.mRect, A2D, aDrawTarget),
+ pixelRadii);
+ aDrawTarget.FillRoundedRect(rect, aFill);
+}
+
nsRect
DisplayItemClip::ApproximateIntersectInward(const nsRect& aRect) const
{
nsRect r = aRect;
if (mHaveClipRect) {
r.IntersectRect(r, mClipRect);
}
for (uint32_t i = 0, iEnd = mRoundedClipRects.Length();
--- a/layout/painting/DisplayItemClip.h
+++ b/layout/painting/DisplayItemClip.h
@@ -93,16 +93,20 @@ public:
// Draw (fill) the rounded rects in this clip to aContext
void FillIntersectionOfRoundedRectClips(gfxContext* aContext,
const Color& aColor,
int32_t aAppUnitsPerDevPixel) const;
// 'Draw' (create as a path, does not stroke or fill) aRoundRect to aContext
already_AddRefed<Path> MakeRoundedRectPath(DrawTarget& aDrawTarget,
int32_t A2D,
const RoundedRect &aRoundRect) const;
+ void FillRoundedRectPath(DrawTarget& aDrawTarget,
+ int32_t A2D,
+ const RoundedRect &aRoundRect,
+ const gfx::Pattern& aFill) const;
// Returns true if the intersection of aRect and this clip region is
// non-empty. This is precise for DisplayItemClips with at most one
// rounded rectangle. When multiple rounded rectangles are present, we just
// check that the rectangle intersects all of them (but possibly in different
// places). So it may return true when the correct answer is false.
bool MayIntersect(const nsRect& aRect) const;
--- a/layout/painting/nsCSSRendering.cpp
+++ b/layout/painting/nsCSSRendering.cpp
@@ -2470,17 +2470,18 @@ SetupImageLayerClip(nsCSSRendering::Imag
MakePathForRoundedRect(*aCtx->GetDrawTarget(), bgAreaGfx,
aClipState.mClippedRadii);
aCtx->Clip(roundedRect);
}
}
static void
DrawBackgroundColor(nsCSSRendering::ImageLayerClipState& aClipState,
- gfxContext *aCtx, nscoord aAppUnitsPerPixel)
+ gfxContext *aCtx, nscoord aAppUnitsPerPixel,
+ const Color& aColor)
{
if (aClipState.mDirtyRectInDevPx.IsEmpty()) {
// Our caller won't draw anything under this condition, so no need
// to set more up.
return;
}
DrawTarget* drawTarget = aCtx->GetDrawTarget();
@@ -2518,20 +2519,20 @@ DrawBackgroundColor(nsCSSRendering::Imag
aClipState.mAdditionalBGClipArea, aAppUnitsPerPixel);
bgAdditionalAreaGfx.Round();
gfxUtils::ConditionRect(bgAdditionalAreaGfx);
aCtx->NewPath();
aCtx->Rectangle(bgAdditionalAreaGfx, true);
aCtx->Clip();
}
- RefPtr<Path> roundedRect =
- MakePathForRoundedRect(*drawTarget, bgAreaGfx, aClipState.mClippedRadii);
- aCtx->SetPath(roundedRect);
- aCtx->Fill();
+
+ RoundedRect roundedRect(bgAreaGfx, aClipState.mClippedRadii);
+ drawTarget->FillRoundedRect(roundedRect, ColorPattern(aColor),
+ DrawOptions(1.0f, CompositionOp::OP_OVER, aCtx->CurrentAntialiasMode()));
aCtx->Restore();
}
nscolor
nsCSSRendering::DetermineBackgroundColor(nsPresContext* aPresContext,
ComputedStyle* aComputedStyle,
nsIFrame* aFrame,
bool& aDrawBackgroundImage,
@@ -2709,17 +2710,17 @@ nsCSSRendering::PaintStyleImageLayerWith
aRenderingCtx.SetColor(Color::FromABGR(bgColor));
}
// If there is no background image, draw a color. (If there is
// neither a background image nor a color, we wouldn't have gotten
// this far.)
if (!drawBackgroundImage) {
if (!isCanvasFrame) {
- DrawBackgroundColor(clipState, &aRenderingCtx, appUnitsPerPixel);
+ DrawBackgroundColor(clipState, &aRenderingCtx, appUnitsPerPixel, Color::FromABGR(bgColor));
}
return ImgDrawResult::SUCCESS;
}
if (layers.mImageCount < 1) {
// Return if there are no background layers, all work from this point
// onwards happens iteratively on these.
return ImgDrawResult::SUCCESS;
@@ -2741,17 +2742,17 @@ nsCSSRendering::PaintStyleImageLayerWith
aParams.frame->AssociateImage(layers.mLayers[i].mImage,
&aParams.presCtx, 0);
}
}
// The background color is rendered over the entire dirty area,
// even if the image isn't.
if (drawBackgroundColor && !isCanvasFrame) {
- DrawBackgroundColor(clipState, &aRenderingCtx, appUnitsPerPixel);
+ DrawBackgroundColor(clipState, &aRenderingCtx, appUnitsPerPixel, Color::FromABGR(bgColor));
}
// Compute the outermost boundary of the area that might be painted.
// Same coordinate space as aParams.borderArea & aParams.bgClipRect.
Sides skipSides = aParams.frame->GetSkipSides();
nsRect paintBorderArea =
BoxDecorationRectForBackground(aParams.frame, aParams.borderArea,
skipSides, &aBorder);
@@ -4567,20 +4568,18 @@ nsContextBoxBlur::BlurRectangle(gfxConte
return;
}
Rect shadowGfxRect = NSRectToRect(aRect, aAppUnitsPerDevPixel);
if (aBlurRadius <= 0) {
ColorPattern color(ToDeviceColor(aShadowColor));
if (aCornerRadii) {
- RefPtr<Path> roundedRect = MakePathForRoundedRect(aDestDrawTarget,
- shadowGfxRect,
- *aCornerRadii);
- aDestDrawTarget.Fill(roundedRect, color);
+ RoundedRect roundedRect(shadowGfxRect, *aCornerRadii);
+ aDestDrawTarget.FillRoundedRect(roundedRect, color);
} else {
aDestDrawTarget.FillRect(shadowGfxRect, color);
}
return;
}
gfxFloat scaleX = 1;
gfxFloat scaleY = 1;
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -4794,20 +4794,18 @@ nsDisplayBackgroundColor::PaintWithClip(
aClip.AppendRoundedRects(&roundedRect);
bool pushedClip = false;
if (!fillRect.Contains(roundedRect[0].mRect)) {
dt->PushClipRect(bounds);
pushedClip = true;
}
- RefPtr<Path> path = aClip.MakeRoundedRectPath(*aCtx->GetDrawTarget(),
- A2D,
- roundedRect[0]);
- dt->Fill(path, fill);
+ aClip.FillRoundedRectPath(*aCtx->GetDrawTarget(),
+ A2D, roundedRect[0], fill);
if (pushedClip) {
dt->PopClip();
}
} else {
dt->FillRect(bounds, fill);
}
}