mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-28 15:23:51 +00:00
Bug 1365876. Blur text shadows on the CPU. r=lsalzman
This commit is contained in:
parent
bd32331e0f
commit
b4e1afb9e9
@ -36,14 +36,16 @@ gfxAlphaBoxBlur::Init(gfxContext* aDestinationCtx,
|
||||
const IntSize& aSpreadRadius,
|
||||
const IntSize& aBlurRadius,
|
||||
const gfxRect* aDirtyRect,
|
||||
const gfxRect* aSkipRect)
|
||||
const gfxRect* aSkipRect,
|
||||
bool aUseHardwareAccel)
|
||||
{
|
||||
DrawTarget* refDT = aDestinationCtx->GetDrawTarget();
|
||||
Maybe<Rect> dirtyRect = aDirtyRect ? Some(ToRect(*aDirtyRect)) : Nothing();
|
||||
Maybe<Rect> skipRect = aSkipRect ? Some(ToRect(*aSkipRect)) : Nothing();
|
||||
RefPtr<DrawTarget> dt =
|
||||
InitDrawTarget(refDT, ToRect(aRect), aSpreadRadius, aBlurRadius,
|
||||
dirtyRect.ptrOr(nullptr), skipRect.ptrOr(nullptr));
|
||||
dirtyRect.ptrOr(nullptr), skipRect.ptrOr(nullptr),
|
||||
aUseHardwareAccel);
|
||||
if (!dt) {
|
||||
return nullptr;
|
||||
}
|
||||
@ -60,7 +62,8 @@ gfxAlphaBoxBlur::InitDrawTarget(const DrawTarget* aReferenceDT,
|
||||
const IntSize& aSpreadRadius,
|
||||
const IntSize& aBlurRadius,
|
||||
const Rect* aDirtyRect,
|
||||
const Rect* aSkipRect)
|
||||
const Rect* aSkipRect,
|
||||
bool aUseHardwareAccel)
|
||||
{
|
||||
mBlur.Init(aRect, aSpreadRadius, aBlurRadius, aDirtyRect, aSkipRect);
|
||||
size_t blurDataSize = mBlur.GetSurfaceAllocationSize();
|
||||
@ -75,10 +78,10 @@ gfxAlphaBoxBlur::InitDrawTarget(const DrawTarget* aReferenceDT,
|
||||
// Otherwise, DrawSurfaceWithShadow only supports square blurs without spread.
|
||||
// When blurring small draw targets such as short spans text, the cost of
|
||||
// creating and flushing an accelerated draw target may exceed the speedup
|
||||
// gained from the faster blur, so we also make sure the blurred data exceeds
|
||||
// a sufficient number of pixels to offset this cost.
|
||||
// gained from the faster blur. It's up to the users of this blur
|
||||
// to determine whether they want to use hardware acceleration.
|
||||
if (aBlurRadius.IsSquare() && aSpreadRadius.IsEmpty() &&
|
||||
blurDataSize >= 8192 &&
|
||||
aUseHardwareAccel &&
|
||||
backend == BackendType::DIRECT2D1_1) {
|
||||
mAccelerated = true;
|
||||
mDrawTarget =
|
||||
|
@ -74,6 +74,9 @@ public:
|
||||
* @param aSkipRect A pointer to a rect, measured in device units, that
|
||||
* represents an area where blurring is unnecessary and shouldn't be done
|
||||
* for speed reasons. It is safe to pass nullptr here.
|
||||
*
|
||||
* @param aUseHardwareAccel Flag to state whether or not we can use hardware
|
||||
* acceleration to speed up this blur.
|
||||
*/
|
||||
already_AddRefed<gfxContext>
|
||||
Init(gfxContext* aDestinationCtx,
|
||||
@ -81,7 +84,8 @@ public:
|
||||
const mozilla::gfx::IntSize& aSpreadRadius,
|
||||
const mozilla::gfx::IntSize& aBlurRadius,
|
||||
const gfxRect* aDirtyRect,
|
||||
const gfxRect* aSkipRect);
|
||||
const gfxRect* aSkipRect,
|
||||
bool aUseHardwareAccel = true);
|
||||
|
||||
already_AddRefed<DrawTarget>
|
||||
InitDrawTarget(const mozilla::gfx::DrawTarget* aReferenceDT,
|
||||
@ -89,7 +93,8 @@ public:
|
||||
const mozilla::gfx::IntSize& aSpreadRadius,
|
||||
const mozilla::gfx::IntSize& aBlurRadius,
|
||||
const mozilla::gfx::Rect* aDirtyRect = nullptr,
|
||||
const mozilla::gfx::Rect* aSkipRect = nullptr);
|
||||
const mozilla::gfx::Rect* aSkipRect = nullptr,
|
||||
bool aUseHardwareAccel = true);
|
||||
|
||||
/**
|
||||
* Performs the blur and optionally colors the result if aShadowColor is not null.
|
||||
|
@ -6025,7 +6025,8 @@ nsLayoutUtils::PaintTextShadow(const nsIFrame* aFrame,
|
||||
nsContextBoxBlur contextBoxBlur;
|
||||
gfxContext* shadowContext = contextBoxBlur.Init(shadowRect, 0, blurRadius,
|
||||
presCtx->AppUnitsPerDevPixel(),
|
||||
aDestCtx, aDirtyRect, nullptr);
|
||||
aDestCtx, aDirtyRect, nullptr,
|
||||
nsContextBoxBlur::DISABLE_HARDWARE_ACCELERATION_BLUR);
|
||||
if (!shadowContext)
|
||||
continue;
|
||||
|
||||
|
@ -6972,12 +6972,14 @@ nsTextFrame::PaintShadows(nsCSSShadowArray* aShadow,
|
||||
|
||||
// If the textrun uses any color or SVG fonts, we need to force use of a mask
|
||||
// for shadow rendering even if blur radius is zero.
|
||||
uint32_t blurFlags = 0;
|
||||
// Force disable hardware acceleration for text shadows since it's usually
|
||||
// more expensive than just doing it on the CPU.
|
||||
uint32_t blurFlags = nsContextBoxBlur::DISABLE_HARDWARE_ACCELERATION_BLUR;
|
||||
uint32_t numGlyphRuns;
|
||||
const gfxTextRun::GlyphRun* run = mTextRun->GetGlyphRuns(&numGlyphRuns);
|
||||
while (numGlyphRuns-- > 0) {
|
||||
if (run->mFont->AlwaysNeedsMaskForShadow()) {
|
||||
blurFlags = nsContextBoxBlur::FORCE_MASK;
|
||||
blurFlags |= nsContextBoxBlur::FORCE_MASK;
|
||||
break;
|
||||
}
|
||||
run++;
|
||||
|
@ -4292,13 +4292,16 @@ nsContextBoxBlur::Init(const nsRect& aRect, nscoord aSpreadRadius,
|
||||
|
||||
// Create the temporary surface for blurring
|
||||
dirtyRect = transform.TransformBounds(dirtyRect);
|
||||
bool useHardwareAccel = !(aFlags & DISABLE_HARDWARE_ACCELERATION_BLUR);
|
||||
if (aSkipRect) {
|
||||
gfxRect skipRect = transform.TransformBounds(*aSkipRect);
|
||||
mContext = mAlphaBoxBlur.Init(aDestinationCtx, rect, spreadRadius,
|
||||
blurRadius, &dirtyRect, &skipRect);
|
||||
blurRadius, &dirtyRect, &skipRect,
|
||||
useHardwareAccel);
|
||||
} else {
|
||||
mContext = mAlphaBoxBlur.Init(aDestinationCtx, rect, spreadRadius,
|
||||
blurRadius, &dirtyRect, nullptr);
|
||||
blurRadius, &dirtyRect, nullptr,
|
||||
useHardwareAccel);
|
||||
}
|
||||
|
||||
if (mContext) {
|
||||
|
@ -715,7 +715,8 @@ class nsContextBoxBlur {
|
||||
|
||||
public:
|
||||
enum {
|
||||
FORCE_MASK = 0x01
|
||||
FORCE_MASK = 0x01,
|
||||
DISABLE_HARDWARE_ACCELERATION_BLUR = 0x02
|
||||
};
|
||||
/**
|
||||
* Prepares a gfxContext to draw on. Do not call this twice; if you want
|
||||
|
Loading…
Reference in New Issue
Block a user