Bug 1250037 - part 1 - only blur one quadrant of a box-shadow and mirror it to the other quadrants. r=mchang

MozReview-Commit-ID: B4FSDmAMfXK
This commit is contained in:
Lee Salzman 2016-11-17 16:03:59 -05:00
Родитель 7110a88674
Коммит e79ff03dbb
8 изменённых файлов: 489 добавлений и 344 удалений

Просмотреть файл

@ -336,10 +336,26 @@ AlphaBoxBlur::AlphaBoxBlur(const Rect& aRect,
const IntSize& aBlurRadius,
const Rect* aDirtyRect,
const Rect* aSkipRect)
: mSpreadRadius(aSpreadRadius),
mBlurRadius(aBlurRadius),
mSurfaceAllocationSize(0)
: mSurfaceAllocationSize(0)
{
Init(aRect, aSpreadRadius, aBlurRadius, aDirtyRect, aSkipRect);
}
AlphaBoxBlur::AlphaBoxBlur()
: mSurfaceAllocationSize(0)
{
}
void
AlphaBoxBlur::Init(const Rect& aRect,
const IntSize& aSpreadRadius,
const IntSize& aBlurRadius,
const Rect* aDirtyRect,
const Rect* aSkipRect)
{
mSpreadRadius = aSpreadRadius;
mBlurRadius = aBlurRadius;
Rect rect(aRect);
rect.Inflate(Size(aBlurRadius + aSpreadRadius));
rect.RoundOut();
@ -356,8 +372,7 @@ AlphaBoxBlur::AlphaBoxBlur(const Rect& aRect,
mHasDirtyRect = false;
}
mRect = IntRect(int32_t(rect.x), int32_t(rect.y),
int32_t(rect.width), int32_t(rect.height));
mRect = TruncatedToInt(rect);
if (mRect.IsEmpty()) {
return;
}
@ -367,11 +382,8 @@ AlphaBoxBlur::AlphaBoxBlur(const Rect& aRect,
// blurring/spreading we need to do. We convert it to IntRect to avoid
// expensive int<->float conversions if we were to use Rect instead.
Rect skipRect = *aSkipRect;
skipRect.RoundIn();
skipRect.Deflate(Size(aBlurRadius + aSpreadRadius));
mSkipRect = IntRect(int32_t(skipRect.x), int32_t(skipRect.y),
int32_t(skipRect.width), int32_t(skipRect.height));
mSkipRect = RoundedIn(skipRect);
mSkipRect = mSkipRect.Intersect(mRect);
if (mSkipRect.IsEqualInterior(mRect))
return;
@ -398,8 +410,7 @@ AlphaBoxBlur::AlphaBoxBlur(const Rect& aRect,
int32_t aStride,
float aSigmaX,
float aSigmaY)
: mRect(int32_t(aRect.x), int32_t(aRect.y),
int32_t(aRect.width), int32_t(aRect.height)),
: mRect(TruncatedToInt(aRect)),
mSpreadRadius(),
mBlurRadius(CalculateBlurRadius(Point(aSigmaX, aSigmaY))),
mStride(aStride),

Просмотреть файл

@ -69,6 +69,14 @@ public:
float aSigmaX,
float aSigmaY);
AlphaBoxBlur();
void Init(const Rect& aRect,
const IntSize& aSpreadRadius,
const IntSize& aBlurRadius,
const Rect* aDirtyRect,
const Rect* aSkipRect);
~AlphaBoxBlur();
/**

Просмотреть файл

@ -224,6 +224,15 @@ struct RectCornerRadii {
return true;
}
bool AreRadiiSame() const {
for (size_t i = 1; i < RectCorner::Count; i++) {
if (radii[i] != radii[0]) {
return false;
}
}
return true;
}
void Scale(Float aXScale, Float aYScale) {
for (int i = 0; i < RectCorner::Count; i++) {
radii[i].Scale(aXScale, aYScale);

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -10,14 +10,13 @@
#include "nsSize.h"
#include "gfxPoint.h"
#include "mozilla/RefPtr.h"
#include "mozilla/UniquePtr.h"
#include "mozilla/gfx/Blur.h"
class gfxContext;
struct gfxRect;
namespace mozilla {
namespace gfx {
class AlphaBoxBlur;
struct Color;
struct RectCornerRadii;
class SourceSurface;
@ -73,21 +72,19 @@ public:
* represents an area where blurring is unnecessary and shouldn't be done
* for speed reasons. It is safe to pass nullptr here.
*/
gfxContext* Init(const gfxRect& aRect,
const mozilla::gfx::IntSize& aSpreadRadius,
const mozilla::gfx::IntSize& aBlurRadius,
const gfxRect* aDirtyRect,
const gfxRect* aSkipRect);
already_AddRefed<gfxContext>
Init(const gfxRect& aRect,
const mozilla::gfx::IntSize& aSpreadRadius,
const mozilla::gfx::IntSize& aBlurRadius,
const gfxRect* aDirtyRect,
const gfxRect* aSkipRect);
/**
* Returns the context that should be drawn to supply the alpha mask to be
* blurred. If the returned surface is null, then there was an error in
* its creation.
*/
gfxContext* GetContext()
{
return mContext;
}
already_AddRefed<DrawTarget>
InitDrawTarget(const mozilla::gfx::Rect& aRect,
const mozilla::gfx::IntSize& aSpreadRadius,
const mozilla::gfx::IntSize& aBlurRadius,
const mozilla::gfx::Rect* aDirtyRect = nullptr,
const mozilla::gfx::Rect* aSkipRect = nullptr);
already_AddRefed<mozilla::gfx::SourceSurface>
DoBlur(DrawTarget* aDT, mozilla::gfx::IntPoint* aTopLeft);
@ -129,7 +126,7 @@ public:
*/
static void BlurRectangle(gfxContext *aDestinationCtx,
const gfxRect& aRect,
RectCornerRadii* aCornerRadii,
const RectCornerRadii* aCornerRadii,
const gfxPoint& aBlurStdDev,
const Color& aShadowColor,
const gfxRect& aDirtyRect,
@ -147,48 +144,39 @@ public:
* @param aShadowClipRect The destiniation inner rect of the
* inset path in device pixels.
* @param aBlurRadius The standard deviation of the blur.
* @param aSpreadRadius The spread radius in device pixels.
* @param aShadowColor The color of the blur.
* @param aHasBorderRadius If this element also has a border radius
* @param aInnerClipRadii Corner radii for the inside rect if it is a rounded rect.
* @param aSKipRect An area in device pixels we don't have to paint in.
* @param aSkipRect An area in device pixels we don't have to paint in.
*/
void BlurInsetBox(gfxContext* aDestinationCtx,
const mozilla::gfx::Rect aDestinationRect,
const mozilla::gfx::Rect aShadowClipRect,
const mozilla::gfx::IntSize aBlurRadius,
const mozilla::gfx::IntSize aSpreadRadius,
const mozilla::gfx::Rect& aDestinationRect,
const mozilla::gfx::Rect& aShadowClipRect,
const mozilla::gfx::IntSize& aBlurRadius,
const mozilla::gfx::Color& aShadowColor,
const bool aHasBorderRadius,
const RectCornerRadii& aInnerClipRadii,
const mozilla::gfx::Rect aSkipRect,
const mozilla::gfx::Point aShadowOffset);
const RectCornerRadii* aInnerClipRadii,
const mozilla::gfx::Rect& aSkipRect,
const mozilla::gfx::Point& aShadowOffset);
protected:
already_AddRefed<mozilla::gfx::SourceSurface>
GetInsetBlur(const mozilla::gfx::Rect aOuterRect,
const mozilla::gfx::Rect aWhitespaceRect,
const bool aIsDestRect,
GetInsetBlur(const mozilla::gfx::Rect& aOuterRect,
const mozilla::gfx::Rect& aWhitespaceRect,
bool aIsDestRect,
const mozilla::gfx::Color& aShadowColor,
const mozilla::gfx::IntSize& aBlurRadius,
const bool aHasBorderRadius,
const RectCornerRadii& aInnerClipRadii,
DrawTarget* aDestDrawTarget);
/**
* The context of the temporary alpha surface.
*/
RefPtr<gfxContext> mContext;
const RectCornerRadii* aInnerClipRadii,
DrawTarget* aDestDrawTarget,
bool aMirrorCorners);
/**
* The temporary alpha surface.
*/
mozilla::UniquePtr<unsigned char[]> mData;
uint8_t* mData;
/**
* The object that actually does the blurring for us.
*/
mozilla::UniquePtr<mozilla::gfx::AlphaBoxBlur> mBlur;
mozilla::gfx::AlphaBoxBlur mBlur;
};
#endif /* GFX_BLUR_H */

Просмотреть файл

@ -1632,7 +1632,6 @@ nsCSSRendering::PaintBoxShadowInner(nsPresContext* aPresContext,
// transparent in the shadow, so drawing them changes nothing.
gfxContext* renderContext = aRenderingContext.ThebesContext();
DrawTarget* drawTarget = renderContext->GetDrawTarget();
nsContextBoxBlur blurringArea;
// Clip the context to the area of the frame's padding rect, so no part of the
// shadow is painted outside. Also cut out anything beyond where the inset shadow
@ -6123,9 +6122,8 @@ nsContextBoxBlur::InsetBoxBlur(gfxContext* aDestinationCtx,
mAlphaBoxBlur.BlurInsetBox(aDestinationCtx, transformedDestRect,
transformedShadowClipRect,
blurRadius, spreadRadius,
aShadowColor, aHasBorderRadius,
aInnerClipRectRadii, transformedSkipRect,
aShadowOffset);
blurRadius, aShadowColor,
aHasBorderRadius ? &aInnerClipRectRadii : nullptr,
transformedSkipRect, aShadowOffset);
return true;
}

Просмотреть файл

@ -18,12 +18,12 @@ fuzzy-if(skiaContent,1,50) HTTP(..) == boxshadow-dynamic.xul boxshadow-dynamic-r
random-if(d2d) == boxshadow-onecorner.html boxshadow-onecorner-ref.html
random-if(d2d) == boxshadow-twocorners.html boxshadow-twocorners-ref.html
random-if(d2d) == boxshadow-threecorners.html boxshadow-threecorners-ref.html
== boxshadow-skiprect.html boxshadow-skiprect-ref.html
fuzzy(2,440) == boxshadow-skiprect.html boxshadow-skiprect-ref.html
== boxshadow-opacity.html boxshadow-opacity-ref.html
== boxshadow-color-rounding.html boxshadow-color-rounding-ref.html
== boxshadow-color-rounding-middle.html boxshadow-color-rounding-middle-ref.html
fuzzy-if(OSX==1010,1,24) fuzzy-if(d2d,16,568) == boxshadow-large-border-radius.html boxshadow-large-border-radius-ref.html # Bug 1209649
fuzzy-if(d2d,2,1080) == boxshadow-border-radius-int.html boxshadow-border-radius-int-ref.html
fuzzy(3,500) fuzzy-if(d2d,3,1080) == boxshadow-border-radius-int.html boxshadow-border-radius-int-ref.html
== boxshadow-inset-neg-spread.html about:blank
== boxshadow-inset-neg-spread2.html boxshadow-inset-neg-spread2-ref.html
fuzzy(26,3610) == boxshadow-rotated.html boxshadow-rotated-ref.html # Bug 1211264

Просмотреть файл

@ -1,4 +1,4 @@
== outline-and-box-shadow.html outline-and-box-shadow-ref.html
fuzzy(2,18) == outline-and-box-shadow.html outline-and-box-shadow-ref.html
== outline-and-3d-transform-1a.html outline-and-3d-transform-1-ref.html
== outline-and-3d-transform-1b.html outline-and-3d-transform-1-ref.html
fuzzy-if(gtkWidget,136,120) fuzzy-if(Android,255,356) fuzzy-if(d2d,16,96) fuzzy-if(cocoaWidget,255,120) fuzzy-if(winWidget,255,216) == outline-and-3d-transform-2.html outline-and-3d-transform-2-ref.html