Adding an option to render only the shadow in SkDropShadowImageFilter

This is basically how blink uses the filter. Currently, I can't use it for "ShadowOnly" mode with the filter at all, but instead of copying the code and risking to have the codepaths diverge, I'm simply going to add the option here.

BUG=skia:

Review URL: https://codereview.chromium.org/646213004
This commit is contained in:
sugoi 2014-10-23 13:59:52 -07:00 committed by Commit bot
parent d0777fd2cf
commit 234f036b3e
13 changed files with 100 additions and 29 deletions

View File

@ -46,6 +46,10 @@ blurcircles
bleed
drawbitmapmatrix
# sugoi https://codereview.chromium.org/646213004/
# New shadow only option in SkDropShadowImageFilter
dropshadowimagefilter
#bsalomon slight(?) changes after reseting GrContext between GMs
dftext
megalooper_0x0

View File

@ -102,7 +102,7 @@ protected:
return SkString("dropshadowimagefilter");
}
virtual SkISize onISize() { return SkISize::Make(400, 700); }
virtual SkISize onISize() { return SkISize::Make(400, 656); }
void draw_frame(SkCanvas* canvas, const SkRect& r) {
SkPaint paint;
@ -134,12 +134,20 @@ protected:
SkImageFilter* filters[] = {
NULL,
SkDropShadowImageFilter::Create(7.0f, 0.0f, 0.0f, 3.0f, SK_ColorBLUE),
SkDropShadowImageFilter::Create(0.0f, 7.0f, 3.0f, 0.0f, SK_ColorBLUE),
SkDropShadowImageFilter::Create(7.0f, 7.0f, 3.0f, 3.0f, SK_ColorBLUE),
SkDropShadowImageFilter::Create(7.0f, 7.0f, 3.0f, 3.0f, SK_ColorBLUE, cfif),
SkDropShadowImageFilter::Create(7.0f, 7.0f, 3.0f, 3.0f, SK_ColorBLUE, NULL, &cropRect),
SkDropShadowImageFilter::Create(7.0f, 7.0f, 3.0f, 3.0f, SK_ColorBLUE, NULL, &bogusRect),
SkDropShadowImageFilter::Create(7.0f, 0.0f, 0.0f, 3.0f, SK_ColorBLUE,
SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode),
SkDropShadowImageFilter::Create(0.0f, 7.0f, 3.0f, 0.0f, SK_ColorBLUE,
SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode),
SkDropShadowImageFilter::Create(7.0f, 7.0f, 3.0f, 3.0f, SK_ColorBLUE,
SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode),
SkDropShadowImageFilter::Create(7.0f, 7.0f, 3.0f, 3.0f, SK_ColorBLUE,
SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode, cfif, NULL, 0),
SkDropShadowImageFilter::Create(7.0f, 7.0f, 3.0f, 3.0f, SK_ColorBLUE,
SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode, NULL, &cropRect, 0),
SkDropShadowImageFilter::Create(7.0f, 7.0f, 3.0f, 3.0f, SK_ColorBLUE,
SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode, NULL, &bogusRect, 0),
SkDropShadowImageFilter::Create(7.0f, 7.0f, 3.0f, 3.0f, SK_ColorBLUE,
SkDropShadowImageFilter::kDrawShadowOnly_ShadowMode),
};
SkRect r = SkRect::MakeWH(SkIntToScalar(64), SkIntToScalar(64));

View File

@ -231,7 +231,8 @@ protected:
FailImageFilter::Create(),
SkColorFilterImageFilter::Create(cf),
SkBlurImageFilter::Create(12.0f, 0.0f),
SkDropShadowImageFilter::Create(10.0f, 5.0f, 3.0f, 3.0f, SK_ColorBLUE),
SkDropShadowImageFilter::Create(10.0f, 5.0f, 3.0f, 3.0f, SK_ColorBLUE,
SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode),
};
cf->unref();

View File

@ -101,8 +101,8 @@ protected:
SkImageFilter* filters[] = {
SkBlurImageFilter::Create(SkIntToScalar(12), SkIntToScalar(12)),
SkDropShadowImageFilter::Create(SkIntToScalar(10), SkIntToScalar(10),
SkIntToScalar(3), SkIntToScalar(3),
SK_ColorGREEN),
SkIntToScalar(3), SkIntToScalar(3), SK_ColorGREEN,
SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode),
SkDisplacementMapEffect::Create(SkDisplacementMapEffect::kR_ChannelSelectorType,
SkDisplacementMapEffect::kR_ChannelSelectorType,
SkIntToScalar(12),

View File

@ -142,7 +142,8 @@ protected:
draw(canvas, checkerboard, rect, SkDropShadowImageFilter::Create(
SkIntToScalar(10), SkIntToScalar(10), SkIntToScalar(3), SkIntToScalar(3),
SK_ColorBLUE, noop_cropped.get(), &big_rect));
SK_ColorBLUE, SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode,
noop_cropped.get(), &big_rect, 0));
draw(canvas, checkerboard, rect, SkDisplacementMapEffect::Create(
SkDisplacementMapEffect::kR_ChannelSelectorType,

View File

@ -110,8 +110,8 @@ protected:
SkImageFilter* filters[] = {
SkBlurImageFilter::Create(SkIntToScalar(4), SkIntToScalar(4)),
SkDropShadowImageFilter::Create(SkIntToScalar(5), SkIntToScalar(10),
SkIntToScalar(3), SkIntToScalar(3),
SK_ColorYELLOW),
SkIntToScalar(3), SkIntToScalar(3), SK_ColorYELLOW,
SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode),
SkDisplacementMapEffect::Create(SkDisplacementMapEffect::kR_ChannelSelectorType,
SkDisplacementMapEffect::kR_ChannelSelectorType,
SkIntToScalar(12),

View File

@ -243,13 +243,14 @@ private:
// V34: Add SkTextBlob serialization.
// V35: Store SkRect (rather then width & height) in header
// V36: Remove (obsolete) alphatype from SkColorTable
// V37: Added shadow only option to SkDropShadowImageFilter
// Note: If the picture version needs to be increased then please follow the
// steps to generate new SKPs in (only accessible to Googlers): http://goo.gl/qATVcw
// Only SKPs within the min/current picture version range (inclusive) can be read.
static const uint32_t MIN_PICTURE_VERSION = 19;
static const uint32_t CURRENT_PICTURE_VERSION = 36;
static const uint32_t CURRENT_PICTURE_VERSION = 37;
mutable uint32_t fUniqueID;

View File

@ -11,20 +11,46 @@
class SK_API SkDropShadowImageFilter : public SkImageFilter {
public:
enum ShadowMode {
kDrawShadowAndForeground_ShadowMode,
kDrawShadowOnly_ShadowMode
};
/** @deprecated use another Create function below instead */
static SkDropShadowImageFilter* Create(SkScalar dx, SkScalar dy,
SkScalar sigmaX, SkScalar sigmaY, SkColor color,
SkImageFilter* input = NULL,
const CropRect* cropRect = NULL,
uint32_t uniqueID = 0) {
return SkNEW_ARGS(SkDropShadowImageFilter, (dx, dy, sigmaX, sigmaY,
color, input, cropRect, uniqueID));
return SkNEW_ARGS(SkDropShadowImageFilter, (dx, dy, sigmaX, sigmaY, color,
kDrawShadowAndForeground_ShadowMode,
input, cropRect, uniqueID));
}
static SkDropShadowImageFilter* Create(SkScalar dx, SkScalar dy,
SkScalar sigmaX, SkScalar sigmaY, SkColor color,
ShadowMode shadowMode,
SkImageFilter* input,
const CropRect* cropRect,
uint32_t uniqueID) {
return SkNEW_ARGS(SkDropShadowImageFilter, (dx, dy, sigmaX, sigmaY, color,
shadowMode, input, cropRect, uniqueID));
}
static SkDropShadowImageFilter* Create(SkScalar dx, SkScalar dy,
SkScalar sigmaX, SkScalar sigmaY, SkColor color,
ShadowMode shadowMode) {
return SkNEW_ARGS(SkDropShadowImageFilter, (dx, dy, sigmaX, sigmaY, color,
shadowMode, NULL, NULL, 0));
}
virtual void computeFastBounds(const SkRect&, SkRect*) const SK_OVERRIDE;
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkDropShadowImageFilter)
protected:
SkDropShadowImageFilter(SkScalar dx, SkScalar dy, SkScalar sigmaX, SkScalar sigmaY, SkColor,
SkImageFilter* input, const CropRect* cropRect, uint32_t uniqueID);
ShadowMode shadowMode, SkImageFilter* input, const CropRect* cropRect,
uint32_t uniqueID);
#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
explicit SkDropShadowImageFilter(SkReadBuffer&);
#endif
@ -36,5 +62,6 @@ protected:
private:
SkScalar fDx, fDy, fSigmaX, fSigmaY;
SkColor fColor;
ShadowMode fShadowMode;
typedef SkImageFilter INHERITED;
};

View File

@ -122,6 +122,11 @@ static SkColor make_color() {
return (R(2) == 1) ? 0xFFC0F0A0 : 0xFF000090;
}
static SkDropShadowImageFilter::ShadowMode make_shadow_mode() {
return (R(2) == 1) ? SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode :
SkDropShadowImageFilter::kDrawShadowOnly_ShadowMode;
}
static SkPoint3 make_point() {
return SkPoint3(make_scalar(), make_scalar(), make_scalar(true));
}
@ -340,8 +345,9 @@ static SkImageFilter* make_image_filter(bool canBeNull = true) {
}
break;
case DROP_SHADOW:
filter = SkDropShadowImageFilter::Create(make_scalar(), make_scalar(),
make_scalar(true), make_scalar(true), make_color(), make_image_filter());
filter = SkDropShadowImageFilter::Create(make_scalar(), make_scalar(), make_scalar(true),
make_scalar(true), make_color(), make_shadow_mode(), make_image_filter(),
NULL, 0);
break;
case MORPHOLOGY:
if (R(2) == 1) {

View File

@ -50,6 +50,7 @@ public:
kRemoveAndroidPaintOpts_Version = 32,
kFlattenCreateProc_Version = 33,
kRemoveColorTableAlpha_Version = 36,
kDropShadowMode_Version = 37,
};
/**

View File

@ -17,14 +17,15 @@
SkDropShadowImageFilter::SkDropShadowImageFilter(SkScalar dx, SkScalar dy,
SkScalar sigmaX, SkScalar sigmaY, SkColor color,
SkImageFilter* input, const CropRect* cropRect,
uint32_t uniqueID)
ShadowMode shadowMode, SkImageFilter* input,
const CropRect* cropRect, uint32_t uniqueID)
: INHERITED(1, &input, cropRect, uniqueID)
, fDx(dx)
, fDy(dy)
, fSigmaX(sigmaX)
, fSigmaY(sigmaY)
, fColor(color)
, fShadowMode(shadowMode)
{
}
@ -36,6 +37,9 @@ SkDropShadowImageFilter::SkDropShadowImageFilter(SkReadBuffer& buffer)
fSigmaX = buffer.readScalar();
fSigmaY = buffer.readScalar();
fColor = buffer.readColor();
fShadowMode = buffer.isVersionLT(SkReadBuffer::kDropShadowMode_Version) ?
kDrawShadowAndForeground_ShadowMode :
static_cast<ShadowMode>(buffer.readInt());
buffer.validate(SkScalarIsFinite(fDx) &&
SkScalarIsFinite(fDy) &&
SkScalarIsFinite(fSigmaX) &&
@ -50,7 +54,11 @@ SkFlattenable* SkDropShadowImageFilter::CreateProc(SkReadBuffer& buffer) {
SkScalar sigmaX = buffer.readScalar();
SkScalar sigmaY = buffer.readScalar();
SkColor color = buffer.readColor();
return Create(dx, dy, sigmaX, sigmaY, color, common.getInput(0), &common.cropRect(), common.uniqueID());
ShadowMode shadowMode = buffer.isVersionLT(SkReadBuffer::kDropShadowMode_Version) ?
kDrawShadowAndForeground_ShadowMode :
static_cast<ShadowMode>(buffer.readInt());
return Create(dx, dy, sigmaX, sigmaY, color, shadowMode, common.getInput(0),
&common.cropRect(), common.uniqueID());
}
void SkDropShadowImageFilter::flatten(SkWriteBuffer& buffer) const {
@ -60,6 +68,7 @@ void SkDropShadowImageFilter::flatten(SkWriteBuffer& buffer) const {
buffer.writeScalar(fSigmaX);
buffer.writeScalar(fSigmaY);
buffer.writeColor(fColor);
buffer.writeInt(static_cast<int>(fShadowMode));
}
bool SkDropShadowImageFilter::onFilterImage(Proxy* proxy, const SkBitmap& source,
@ -98,7 +107,9 @@ bool SkDropShadowImageFilter::onFilterImage(Proxy* proxy, const SkBitmap& source
canvas.translate(SkIntToScalar(srcOffset.fX - bounds.fLeft),
SkIntToScalar(srcOffset.fY - bounds.fTop));
canvas.drawBitmap(src, offsetVec.fX, offsetVec.fY, &paint);
canvas.drawBitmap(src, 0, 0);
if (fShadowMode == kDrawShadowAndForeground_ShadowMode) {
canvas.drawBitmap(src, 0, 0);
}
*result = device->accessBitmap(false);
offset->fX = bounds.fLeft;
offset->fY = bounds.fTop;
@ -116,7 +127,11 @@ void SkDropShadowImageFilter::computeFastBounds(const SkRect& src, SkRect* dst)
shadowBounds.offset(fDx, fDy);
shadowBounds.outset(SkScalarMul(fSigmaX, SkIntToScalar(3)),
SkScalarMul(fSigmaY, SkIntToScalar(3)));
dst->join(shadowBounds);
if (fShadowMode == kDrawShadowAndForeground_ShadowMode) {
dst->join(shadowBounds);
} else {
*dst = shadowBounds;
}
}
bool SkDropShadowImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& ctm,
@ -130,7 +145,9 @@ bool SkDropShadowImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix&
ctm.mapVectors(&sigma, 1);
bounds.outset(SkScalarCeilToInt(SkScalarMul(sigma.x(), SkIntToScalar(3))),
SkScalarCeilToInt(SkScalarMul(sigma.y(), SkIntToScalar(3))));
bounds.join(src);
if (fShadowMode == kDrawShadowAndForeground_ShadowMode) {
bounds.join(src);
}
if (getInput(0) && !getInput(0)->filterBounds(bounds, ctm, &bounds)) {
return false;
}

View File

@ -256,7 +256,9 @@ static void test_crop_rects(SkBaseDevice* device, skiatest::Reporter* reporter)
SkDisplacementMapEffect::kB_ChannelSelectorType,
40.0f, input.get(), input.get(), &cropRect),
SkBlurImageFilter::Create(SK_Scalar1, SK_Scalar1, input.get(), &cropRect),
SkDropShadowImageFilter::Create(SK_Scalar1, SK_Scalar1, SK_Scalar1, SK_Scalar1, SK_ColorGREEN, input.get(), &cropRect),
SkDropShadowImageFilter::Create(SK_Scalar1, SK_Scalar1, SK_Scalar1, SK_Scalar1,
SK_ColorGREEN, SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode,
input.get(), &cropRect, 0),
SkLightingImageFilter::CreatePointLitDiffuse(location, SK_ColorGREEN, 0, 0, input.get(), &cropRect),
SkLightingImageFilter::CreatePointLitSpecular(location, SK_ColorGREEN, 0, 0, 0, input.get(), &cropRect),
SkMatrixConvolutionImageFilter::Create(kernelSize, kernel, gain, bias, SkIPoint::Make(1, 1), SkMatrixConvolutionImageFilter::kRepeat_TileMode, false, input.get(), &cropRect),
@ -409,7 +411,8 @@ DEF_TEST(ImageFilterDrawTiled, reporter) {
20.0f, gradient_source.get()) },
{ "blur", SkBlurImageFilter::Create(SK_Scalar1, SK_Scalar1) },
{ "drop shadow", SkDropShadowImageFilter::Create(
SK_Scalar1, SK_Scalar1, SK_Scalar1, SK_Scalar1, SK_ColorGREEN) },
SK_Scalar1, SK_Scalar1, SK_Scalar1, SK_Scalar1, SK_ColorGREEN,
SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode) },
{ "diffuse lighting", SkLightingImageFilter::CreatePointLitDiffuse(
location, SK_ColorGREEN, 0, 0) },
{ "specular lighting",
@ -537,7 +540,8 @@ static SkImageFilter* makeDropShadow(SkImageFilter* input = NULL) {
return SkDropShadowImageFilter::Create(
SkIntToScalar(100), SkIntToScalar(100),
SkIntToScalar(10), SkIntToScalar(10),
SK_ColorBLUE, input);
SK_ColorBLUE, SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode,
input, NULL, 0);
}
DEF_TEST(ImageFilterBlurThenShadowBounds, reporter) {

View File

@ -234,7 +234,8 @@ DEF_TEST(RecordDraw_SaveLayerAffectsClipBounds, r) {
// We draw a rectangle with a long drop shadow. We used to not update the clip
// bounds based on SaveLayer paints, so the drop shadow could be cut off.
SkPaint paint;
paint.setImageFilter(SkDropShadowImageFilter::Create(20, 0, 0, 0, SK_ColorBLACK))->unref();
paint.setImageFilter(SkDropShadowImageFilter::Create(20, 0, 0, 0, SK_ColorBLACK,
SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode))->unref();
recorder.saveLayer(NULL, &paint);
recorder.clipRect(SkRect::MakeWH(20, 40));