New factories for SkShaders

Bug: skia:8937
Change-Id: Ic253b70fbf89059321185912aa771b1c1de7d231
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/206693
Reviewed-by: Mike Reed <reed@google.com>
Auto-Submit: Mike Reed <reed@google.com>
Commit-Queue: Mike Reed <reed@google.com>
This commit is contained in:
Mike Reed 2019-04-09 13:55:36 -04:00 committed by Skia Commit-Bot
parent d54b1fcdd9
commit c8bea7deb6
36 changed files with 251 additions and 98 deletions

View File

@ -20,10 +20,9 @@ protected:
const char* onGetName() override { return "mixer-lerp"; }
void onDelayedSetup() override {
auto s0 = SkShader::MakeColorShader(SK_ColorRED);
auto s1 = SkShader::MakeColorShader(SK_ColorBLUE);
auto mx = SkMixer::MakeShaderLerp(SkShader::MakeColorShader(0xFF880000));
fShader = SkShader::MakeMixer(s0, s1, mx);
auto s0 = SkShaders::Color(SK_ColorRED);
auto s1 = SkShaders::Color(SK_ColorBLUE);
fShader = SkShaders::Lerp(SkShaders::Color(0xFF880000), s0, s1);
}
void onDraw(int loops, SkCanvas* canvas) override {

View File

@ -6,7 +6,7 @@ REG_FIDDLE(Paint_getShader, 256, 256, true, 0) {
void draw(SkCanvas* canvas) {
SkPaint paint;
SkDebugf("nullptr %c= shader\n", paint.getShader() ? '!' : '=');
paint.setShader(SkShader::MakeEmptyShader());
paint.setShader(SkShaders::Empty());
SkDebugf("nullptr %c= shader\n", paint.getShader() ? '!' : '=');
}
} // END FIDDLE

View File

@ -5,7 +5,7 @@
REG_FIDDLE(Paint_refShader, 256, 256, true, 0) {
void draw(SkCanvas* canvas) {
SkPaint paint1, paint2;
paint1.setShader(SkShader::MakeEmptyShader());
paint1.setShader(SkShaders::Empty());
SkDebugf("shader unique: %s\n", paint1.getShader()->unique() ? "true" : "false");
paint2.setShader(paint1.refShader());
SkDebugf("shader unique: %s\n", paint1.getShader()->unique() ? "true" : "false");

View File

@ -6,7 +6,7 @@ REG_FIDDLE(Paint_setShader, 256, 64, false, 0) {
void draw(SkCanvas* canvas) {
SkPaint paint;
paint.setColor(SK_ColorBLUE);
paint.setShader(SkShader::MakeColorShader(SK_ColorRED));
paint.setShader(SkShaders::Color(SK_ColorRED));
canvas->drawRect(SkRect::MakeWH(40, 40), paint);
paint.setShader(nullptr);
canvas->translate(50, 0);

View File

@ -204,10 +204,10 @@ static sk_sp<SkShader> make_fuzz_shader(Fuzz* fuzz, int depth) {
case 0:
return nullptr;
case 1:
return SkShader::MakeEmptyShader();
return SkShaders::Empty();
case 2:
fuzz->next(&color);
return SkShader::MakeColorShader(color);
return SkShaders::Color(color);
case 3:
img = make_fuzz_image(fuzz);
fuzz->nextRange(&tmX, 0, SkTileMode::kLastTileMode);
@ -238,7 +238,7 @@ static sk_sp<SkShader> make_fuzz_shader(Fuzz* fuzz, int depth) {
shader1 = make_fuzz_shader(fuzz, depth - 1); // limit recursion.
shader2 = make_fuzz_shader(fuzz, depth - 1);
fuzz->nextRange(&blendMode, 0, SkBlendMode::kLastMode);
return SkShader::MakeComposeShader(std::move(shader1), std::move(shader2), blendMode);
return SkShaders::Blend(blendMode, std::move(shader1), std::move(shader2));
case 8: {
auto pic = make_fuzz_picture(fuzz, depth - 1);
bool useTile;

View File

@ -43,7 +43,7 @@ DEF_SIMPLE_GM(alpha_image, canvas, 256, 256) {
canvas->drawImage(image.get(), 16, 16, &paint);
paint.setColorFilter(nullptr);
paint.setShader(SkShader::MakeColorShader(SK_ColorCYAN));
paint.setShader(SkShaders::Color(SK_ColorCYAN));
canvas->drawImage(image.get(), 144, 16, &paint);
paint.setColorFilter(make_color_filter());

View File

@ -15,11 +15,11 @@
#include "SkGradientShader.h"
static sk_sp<SkShader> make_opaque_color() {
return SkShader::MakeColorShader(0xFFFF0000);
return SkShaders::Color(0xFFFF0000);
}
static sk_sp<SkShader> make_alpha_color() {
return SkShader::MakeColorShader(0x80FF0000);
return SkShaders::Color(0x80FF0000);
}
static sk_sp<SkColorFilter> make_cf_null() {
@ -108,9 +108,9 @@ DEF_SIMPLE_GM(color4shader, canvas, 360, 480) {
for (const auto& c4 : colors) {
sk_sp<SkShader> shaders[] {
SkShader::MakeColorShader(c4, nullptr),
SkShader::MakeColorShader(c4, srgb),
SkShader::MakeColorShader(c4, spin),
SkShaders::Color(c4, nullptr),
SkShaders::Color(c4, srgb),
SkShaders::Color(c4, spin),
};
canvas->save();

View File

@ -259,8 +259,8 @@ template <typename Maker> void do_mixershader(SkCanvas* canvas, Maker&& maker) {
DEF_SIMPLE_GM(mixershader, canvas, 800, 700) {
do_mixershader(canvas, [](sk_sp<SkShader> a, sk_sp<SkShader> b, SkBlendMode mode, float t) {
auto sh = SkShader::MakeBlend(mode, a, b);
return SkShader::MakeLerp(t, a, sh);
auto sh = SkShaders::Blend(mode, a, b);
return SkShaders::Lerp(t, a, sh);
});
}
@ -268,13 +268,6 @@ DEF_SIMPLE_GM(mixershader, canvas, 800, 700) {
DEF_SIMPLE_GM(mixershader2, canvas, 800, 700) {
do_mixershader(canvas, [](sk_sp<SkShader> a, sk_sp<SkShader> b, SkBlendMode mode, float t) {
// Use mixers to simulate MakeCompose(a, b, mode, t)
auto blender = SkMixer::MakeBlend(mode);
auto mx = SkMixer::MakeLerp(t)->makeMerge(SkMixer::MakeFirst(), blender);
if (true) {
auto data = mx->serialize();
mx = SkMixerBase::Deserialize(data->data(), data->size());
}
return SkShader::MakeMixer(a, b, mx);
return SkShaders::Lerp(t, a, SkShaders::Blend(mode, a, b));
});
}

View File

@ -32,7 +32,7 @@ static sk_sp<SkShader> make_shader(SkBlendMode mode) {
colors[1] = SkColorSetARGB(0x80, 0, 0, 0);
auto shaderB = SkGradientShader::MakeLinear(pts, colors, nullptr, 2, SkTileMode::kClamp);
return SkShader::MakeComposeShader(std::move(shaderA), std::move(shaderB), mode);
return SkShaders::Blend(mode, std::move(shaderA), std::move(shaderB));
}
class ComposeShaderGM : public skiagm::GM {
@ -180,9 +180,9 @@ protected:
sk_sp<SkShader> shaders[] = {
// gradient should appear over color bitmap
SkShader::MakeComposeShader(fLinearGradientShader, fColorBitmapShader, mode),
SkShaders::Blend(mode, fLinearGradientShader, fColorBitmapShader),
// gradient should appear over alpha8 bitmap colorized by the paint color
SkShader::MakeComposeShader(fLinearGradientShader, fAlpha8BitmapShader, mode),
SkShaders::Blend(mode, fLinearGradientShader, fAlpha8BitmapShader),
};
SkPaint paint;
@ -252,8 +252,7 @@ DEF_SIMPLE_GM(composeshader_bitmap2, canvas, 200, 200) {
sk_sp<SkImage> skSrc = SkImage::MakeFromBitmap(skBitmap);
sk_sp<SkImage> skMaskImage = SkImage::MakeFromBitmap(skMask);
paint.setShader(
SkShader::MakeComposeShader(skMaskImage->makeShader(), skSrc->makeShader(),
SkBlendMode::kSrcIn));
SkShaders::Blend(SkBlendMode::kSrcIn, skMaskImage->makeShader(), skSrc->makeShader()));
canvas->drawRect(r, paint);
}
@ -296,7 +295,7 @@ static void draw_composed(SkCanvas* canvas, sk_sp<SkShader> src, sk_sp<SkShader>
SkBlendMode mode, SkAlpha alpha) {
SkPaint p;
p.setAlpha(alpha);
p.setShader(SkShader::MakeBlend(mode, dst, src));
p.setShader(SkShaders::Blend(mode, dst, src));
canvas->drawRect(SkRect::MakeWH(gCellSize, gCellSize), p);
}

View File

@ -62,7 +62,7 @@ protected:
break;
case 2:
SkPaint paint;
paint.setShader(SkShader::MakeColorShader(color));
paint.setShader(SkShaders::Color(color));
surface->getCanvas()->drawPaint(paint);
break;
}

View File

@ -64,7 +64,7 @@ protected:
SkBlurMask::ConvertRadiusToSigma(4),
{ { SK_Scalar1, SK_Scalar1, SK_Scalar1 }, 0, 128, 16*2 }));
paint.setColorFilter(nullptr);
paint.setShader(SkShader::MakeColorShader(SK_ColorBLUE));
paint.setShader(SkShaders::Color(SK_ColorBLUE));
paint.setDither(true);
canvas->drawCircle(SkIntToScalar(50), SkIntToScalar(50),
SkIntToScalar(30), paint);

View File

@ -99,7 +99,7 @@ static void draw_pair(SkCanvas* canvas, const SkFont& font, SkColor color,
SkPaint paint;
paint.setColor(color);
canvas->drawString(text, 10, 20, font, paint);
paint.setShader(SkShader::MakeColorShader(paint.getColor()));
paint.setShader(SkShaders::Color(paint.getColor()));
canvas->drawString(text, 10, 40, font, paint);
paint.setShader(shader);
canvas->drawString(text, 10, 60, font, paint);

View File

@ -1004,19 +1004,18 @@ DEF_SIMPLE_GM(fancy_gradients, canvas, 800, 300) {
sk_sp<SkShader> sweep2 = SkGradientShader::MakeSweep(center.x(), center.y(), colors, pos,
SK_ARRAY_COUNT(colors), 0, &m);
sk_sp<SkShader> sweep(SkShader::MakeComposeShader(sweep1, sweep2, SkBlendMode::kExclusion));
sk_sp<SkShader> sweep(SkShaders::Blend(SkBlendMode::kExclusion, sweep1, sweep2));
SkScalar radialPos[] = { 0, .02f, .02f, .04f, .04f, .08f, .08f, .16f, .16f, .31f, .31f,
.62f, .62f, 1, 1, 1 };
static_assert(SK_ARRAY_COUNT(colors) == SK_ARRAY_COUNT(radialPos),
"color/pos size mismatch");
return SkShader::MakeComposeShader(sweep,
SkGradientShader::MakeRadial(center, 100, colors,
radialPos,
SK_ARRAY_COUNT(radialPos),
SkTileMode::kClamp),
SkBlendMode::kExclusion);
return SkShaders::Blend(SkBlendMode::kExclusion, sweep,
SkGradientShader::MakeRadial(center, 100, colors,
radialPos,
SK_ARRAY_COUNT(radialPos),
SkTileMode::kClamp));
});
}

View File

@ -49,17 +49,17 @@ DEF_SIMPLE_GM(localmatrixshader_nested, canvas, 450, 1200) {
// SkLocalMatrixShader(SkComposeShader(SkImageShader(inner)), outer)
[](const sk_sp<SkImage>& img, const SkMatrix& inner, const SkMatrix& outer) {
return SkShader::MakeBlend(SkBlendMode::kSrcOver,
SkShader::MakeColorShader(SK_ColorTRANSPARENT),
img->makeShader(&inner))
return SkShaders::Blend(SkBlendMode::kSrcOver,
SkShaders::Color(SK_ColorTRANSPARENT),
img->makeShader(&inner))
->makeWithLocalMatrix(outer);
},
// SkLocalMatrixShader(SkComposeShader(SkLocalMatrixShader(SkImageShader(I), inner)), outer)
[](const sk_sp<SkImage>& img, const SkMatrix& inner, const SkMatrix& outer) {
return SkShader::MakeBlend(SkBlendMode::kSrcOver,
SkShader::MakeColorShader(SK_ColorTRANSPARENT),
img->makeShader()->makeWithLocalMatrix(inner))
return SkShaders::Blend(SkBlendMode::kSrcOver,
SkShaders::Color(SK_ColorTRANSPARENT),
img->makeShader()->makeWithLocalMatrix(inner))
->makeWithLocalMatrix(outer);
},
};

View File

@ -179,8 +179,7 @@ protected:
paint.setShader(sh2);
canvas->drawRect(r, paint);
auto mixer = SkMixer::MakeShaderLerp(sh2); // MakeLerp(0.5)
auto sh = SkShader::MakeMixer(fS0, fS1, mixer);
auto sh = SkShaders::Lerp(sh2, fS0, fS1);
canvas->translate(SIZE + 10.0f, 0);
paint.setShader(sh);
canvas->drawRect(r, paint);

View File

@ -35,7 +35,7 @@ static sk_sp<SkShader> make_shader1(SkScalar shaderScale) {
}
static sk_sp<SkShader> make_shader2() {
return SkShader::MakeColorShader(SK_ColorBLUE);
return SkShaders::Color(SK_ColorBLUE);
}
static sk_sp<SkColorFilter> make_color_filter() {

View File

@ -28,6 +28,10 @@ class SkRasterPipeline;
class GrContext;
class GrFragmentProcessor;
#ifndef SK_SUPPORT_LEGACY_SHADER_FACTORIES
#define SK_SUPPORT_LEGACY_SHADER_FACTORIES
#endif
/** \class SkShader
*
* Shaders specify the source color(s) for what is being drawn. If a paint
@ -170,6 +174,7 @@ public:
//////////////////////////////////////////////////////////////////////////
// Factory methods for stock shaders
#ifdef SK_SUPPORT_LEGACY_SHADER_FACTORIES
/**
* Call this to create a new "empty" shader, that will not draw anything.
*/
@ -210,6 +215,7 @@ public:
static sk_sp<SkShader> MakeLerp(float weight, sk_sp<SkShader> dst, sk_sp<SkShader> src);
static sk_sp<SkShader> MakeMixer(sk_sp<SkShader> dst, sk_sp<SkShader> src, sk_sp<SkMixer>);
#endif
#ifdef SK_SUPPORT_LEGACY_BITMAPSHADER_FACTORY
/** DEPRECATED. call bitmap.makeShader()
@ -265,4 +271,18 @@ private:
typedef SkFlattenable INHERITED;
};
class SK_API SkShaders {
public:
static sk_sp<SkShader> Empty();
static sk_sp<SkShader> Color(SkColor);
static sk_sp<SkShader> Color(const SkColor4f&, sk_sp<SkColorSpace>);
static sk_sp<SkShader> Blend(SkBlendMode mode, sk_sp<SkShader> dst, sk_sp<SkShader> src);
static sk_sp<SkShader> Lerp(float t, sk_sp<SkShader> dst, sk_sp<SkShader> src);
static sk_sp<SkShader> Lerp(sk_sp<SkShader> red, sk_sp<SkShader> dst, sk_sp<SkShader> src);
private:
SkShaders() = delete;
};
#endif

View File

@ -149,7 +149,7 @@ protected:
SkScalar scaleFreq = 2.0;
fShader1 = SkPerlinNoiseShader::MakeImprovedNoise(fXFreq/scaleFreq, fYFreq/scaleFreq, 4,
fSeed);
fShaderCompose = SkShader::MakeComposeShader(fShader0, fShader1, SkBlendMode::kSrcOver);
fShaderCompose = SkShaders::Blend(SkBlendMode::kSrcOver, fShader0, fShader1);
paint.setShader(fShaderCompose);

View File

@ -48,7 +48,7 @@ protected:
paint.setStyle(SkPaint::kStroke_Style);
paint.setStrokeWidth(SkIntToScalar(10));
paint.setMaskFilter(SkEmbossMaskFilter::Make(SkBlurMask::ConvertRadiusToSigma(4), fLight));
paint.setShader(SkShader::MakeColorShader(SK_ColorBLUE));
paint.setShader(SkShaders::Color(SK_ColorBLUE));
paint.setDither(true);
canvas->drawCircle(SkIntToScalar(50), SkIntToScalar(50),

View File

@ -106,7 +106,7 @@ public:
fMatrix.setScale(SkIntToScalar(zoom), SkIntToScalar(zoom));
fInverse.setScale(SK_Scalar1 / zoom, SK_Scalar1 / zoom);
fShader0 = ToolUtils::create_checkerboard_shader(0xFFDDDDDD, 0xFFFFFFFF, zoom);
fShader1 = SkShader::MakeColorShader(SK_ColorWHITE);
fShader1 = SkShaders::Color(SK_ColorWHITE);
fShader = fShader0;
SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);

View File

@ -159,12 +159,11 @@ protected:
canvas->translate(0, SIZE + 10.f);
auto sh = fSurface->makeImageSnapshot()->makeShader();
auto mx = SkMixer::MakeShaderLerp(sh);
canvas->save();
paint.setShader(sh); canvas->drawRect(r, paint);
canvas->translate(SIZE + 10.f, 0);
paint.setShader(SkShader::MakeMixer(fSH0, fSH1, mx)); canvas->drawRect(r, paint);
paint.setShader(SkShaders::Lerp(sh, fSH0, fSH1)); canvas->drawRect(r, paint);
canvas->restore();
}

View File

@ -31,7 +31,7 @@ static sk_sp<SkShader> make_bitmapfade(const SkBitmap& bm) {
auto shaderB = bm.makeShader();
return SkShader::MakeComposeShader(std::move(shaderB), std::move(shaderA), SkBlendMode::kDstIn);
return SkShaders::Blend(SkBlendMode::kDstIn, std::move(shaderB), std::move(shaderA));
}
class ShaderView : public Sample {
@ -57,8 +57,7 @@ public:
colors[1] = SkColorSetARGB(0x80, 0, 0, 0);
auto shaderB = SkGradientShader::MakeLinear(pts, colors, nullptr, 2, SkTileMode::kClamp);
fShader = SkShader::MakeComposeShader(std::move(shaderA), std::move(shaderB),
SkBlendMode::kDstIn);
fShader = SkShaders::Blend(SkBlendMode::kDstIn, std::move(shaderA), std::move(shaderB));
}
protected:

View File

@ -82,6 +82,7 @@
SK_REGISTER_FLATTENABLE(SkColorShader);
SK_REGISTER_FLATTENABLE(SkShader_Blend);
SK_REGISTER_FLATTENABLE(SkShader_Lerp);
SK_REGISTER_FLATTENABLE(SkShader_LerpRed);
SK_REGISTER_FLATTENABLE(SkEmptyShader);
SK_REGISTER_FLATTENABLE(SkLocalMatrixShader);
SK_REGISTER_FLATTENABLE(SkPictureShader);

View File

@ -56,7 +56,7 @@ sk_sp<SkFlattenable> SkColor4Shader::CreateProc(SkReadBuffer& buffer) {
sk_sp<SkData> data = buffer.readByteArrayAsData();
colorSpace = data ? SkColorSpace::Deserialize(data->data(), data->size()) : nullptr;
}
return SkShader::MakeColorShader(color, std::move(colorSpace));
return SkShaders::Color(color, std::move(colorSpace));
}
void SkColor4Shader::flatten(SkWriteBuffer& buffer) const {
@ -71,7 +71,13 @@ void SkColor4Shader::flatten(SkWriteBuffer& buffer) const {
}
#ifdef SK_SUPPORT_LEGACY_SHADER_FACTORIES
sk_sp<SkShader> SkShader::MakeColorShader(const SkColor4f& color, sk_sp<SkColorSpace> space) {
return SkShaders::Color(color, std::move(space));
}
#endif
sk_sp<SkShader> SkShaders::Color(const SkColor4f& color, sk_sp<SkColorSpace> space) {
if (!SkScalarsAreFinite(color.vec(), 4)) {
return nullptr;
}

View File

@ -16,9 +16,19 @@
#include "SkWriteBuffer.h"
#include "SkString.h"
#ifdef SK_SUPPORT_LEGACY_SHADER_FACTORIES
sk_sp<SkShader> SkShader::MakeBlend(SkBlendMode mode, sk_sp<SkShader> dst, sk_sp<SkShader> src) {
return SkShaders::Blend(mode, std::move(dst), std::move(src));
}
sk_sp<SkShader> SkShader::MakeLerp(float weight, sk_sp<SkShader> dst, sk_sp<SkShader> src) {
return SkShaders::Lerp(weight, std::move(dst), std::move(src));
}
#endif
sk_sp<SkShader> SkShaders::Blend(SkBlendMode mode, sk_sp<SkShader> dst, sk_sp<SkShader> src) {
switch (mode) {
case SkBlendMode::kClear: return MakeColorShader(0);
case SkBlendMode::kClear: return Color(0);
case SkBlendMode::kDst: return dst;
case SkBlendMode::kSrc: return src;
default: break;
@ -26,7 +36,7 @@ sk_sp<SkShader> SkShader::MakeBlend(SkBlendMode mode, sk_sp<SkShader> dst, sk_sp
return sk_sp<SkShader>(new SkShader_Blend(mode, std::move(dst), std::move(src)));
}
sk_sp<SkShader> SkShader::MakeLerp(float weight, sk_sp<SkShader> dst, sk_sp<SkShader> src) {
sk_sp<SkShader> SkShaders::Lerp(float weight, sk_sp<SkShader> dst, sk_sp<SkShader> src) {
if (SkScalarIsNaN(weight)) {
return nullptr;
}
@ -41,6 +51,16 @@ sk_sp<SkShader> SkShader::MakeLerp(float weight, sk_sp<SkShader> dst, sk_sp<SkSh
return sk_sp<SkShader>(new SkShader_Lerp(weight, std::move(dst), std::move(src)));
}
sk_sp<SkShader> SkShaders::Lerp(sk_sp<SkShader> red, sk_sp<SkShader> dst, sk_sp<SkShader> src) {
if (!red) {
return nullptr;
}
if (dst == src) {
return dst;
}
return sk_sp<SkShader>(new SkShader_LerpRed(std::move(red), std::move(dst), std::move(src)));
}
///////////////////////////////////////////////////////////////////////////////
static bool append_shader_or_paint(const SkStageRec& rec, SkShader* shader) {
@ -83,7 +103,7 @@ sk_sp<SkFlattenable> SkShader_Blend::CreateProc(SkReadBuffer& buffer) {
if (!buffer.validate(mode <= (unsigned)SkBlendMode::kLastMode)) {
return nullptr;
}
return MakeBlend(static_cast<SkBlendMode>(mode), std::move(dst), std::move(src));
return SkShaders::Blend(static_cast<SkBlendMode>(mode), std::move(dst), std::move(src));
}
void SkShader_Blend::flatten(SkWriteBuffer& buffer) const {
@ -107,7 +127,7 @@ sk_sp<SkFlattenable> SkShader_Lerp::CreateProc(SkReadBuffer& buffer) {
sk_sp<SkShader> dst(buffer.readShader());
sk_sp<SkShader> src(buffer.readShader());
float t = buffer.readScalar();
return buffer.isValid() ? MakeLerp(t, std::move(dst), std::move(src)) : nullptr;
return buffer.isValid() ? SkShaders::Lerp(t, std::move(dst), std::move(src)) : nullptr;
}
void SkShader_Lerp::flatten(SkWriteBuffer& buffer) const {
@ -127,21 +147,75 @@ bool SkShader_Lerp::onAppendStages(const SkStageRec& rec) const {
return true;
}
sk_sp<SkFlattenable> SkShader_LerpRed::CreateProc(SkReadBuffer& buffer) {
sk_sp<SkShader> dst(buffer.readShader());
sk_sp<SkShader> src(buffer.readShader());
sk_sp<SkShader> red(buffer.readShader());
return buffer.isValid() ?
SkShaders::Lerp(std::move(red), std::move(dst), std::move(src)) : nullptr;
}
void SkShader_LerpRed::flatten(SkWriteBuffer& buffer) const {
buffer.writeFlattenable(fDst.get());
buffer.writeFlattenable(fSrc.get());
buffer.writeFlattenable(fRed.get());
}
bool SkShader_LerpRed::onAppendStages(const SkStageRec& rec) const {
struct Storage {
float fRed[4 * SkRasterPipeline_kMaxStride];
};
auto storage = rec.fAlloc->make<Storage>();
if (!as_SB(fRed)->appendStages(rec)) {
return false;
}
// actually, we just need the first (red) channel, but for now we store rgba
rec.fPipeline->append(SkRasterPipeline::store_src, storage->fRed);
float* res0 = append_two_shaders(rec, fDst.get(), fSrc.get());
if (!res0) {
return false;
}
rec.fPipeline->append(SkRasterPipeline::load_dst, res0);
rec.fPipeline->append(SkRasterPipeline::lerp_native, &storage->fRed[0]);
return true;
}
#if SK_SUPPORT_GPU
#include "effects/GrConstColorProcessor.h"
#include "effects/GrXfermodeFragmentProcessor.h"
#include "GrRecordingContext.h"
#include "effects/GrSkSLFP.h"
/////////////////////////////////////////////////////////////////////
std::unique_ptr<GrFragmentProcessor> SkShader_Blend::asFragmentProcessor(
const GrFPArgs& args) const {
std::unique_ptr<GrFragmentProcessor> fpA(as_SB(fDst)->asFragmentProcessor(args));
if (!fpA) {
return nullptr;
static std::unique_ptr<GrFragmentProcessor>
sksl_mixer_fp(const GrFPArgs& args, int index, const char* sksl, sk_sp<SkData> inputs,
std::unique_ptr<GrFragmentProcessor> fp1,
std::unique_ptr<GrFragmentProcessor> fp2,
std::unique_ptr<GrFragmentProcessor> fp3 = nullptr)
{
std::unique_ptr<GrSkSLFP> result = GrSkSLFP::Make(args.fContext, index, "Runtime Mixer", sksl,
inputs ? inputs->data() : nullptr,
inputs ? inputs->size() : 0,
SkSL::Program::kMixer_Kind);
result->addChild(std::move(fp1));
result->addChild(std::move(fp2));
if (fp3) {
result->addChild(std::move(fp3));
}
std::unique_ptr<GrFragmentProcessor> fpB(as_SB(fSrc)->asFragmentProcessor(args));
if (!fpB) {
return std::move(result);
}
static std::unique_ptr<GrFragmentProcessor> as_fp(const GrFPArgs& args, SkShader* shader) {
return shader ? as_SB(shader)->asFragmentProcessor(args)
: nullptr;//GrConstColorProcessor::Make(args, );
}
std::unique_ptr<GrFragmentProcessor> SkShader_Blend::asFragmentProcessor(const GrFPArgs& args) const {
auto fpA = as_fp(args, fDst.get());
auto fpB = as_fp(args, fSrc.get());
if (!fpA || !fpB) {
return nullptr;
}
return GrXfermodeFragmentProcessor::MakeFromTwoProcessors(std::move(fpB),
@ -149,14 +223,43 @@ std::unique_ptr<GrFragmentProcessor> SkShader_Blend::asFragmentProcessor(
}
std::unique_ptr<GrFragmentProcessor> SkShader_Lerp::asFragmentProcessor(const GrFPArgs& args) const {
std::unique_ptr<GrFragmentProcessor> fpA(as_SB(fDst)->asFragmentProcessor(args));
if (!fpA) {
auto fpA = as_fp(args, fDst.get());
auto fpB = as_fp(args, fSrc.get());
if (!fpA || !fpB) {
return nullptr;
}
std::unique_ptr<GrFragmentProcessor> fpB(as_SB(fSrc)->asFragmentProcessor(args));
if (!fpB) {
static int index = GrSkSLFP::NewIndex();
return sksl_mixer_fp(args,
index,
"in uniform float weight;"
"void main(half4 input1, half4 input2) {"
" sk_OutColor = mix(input1, input2, half(weight));"
"}",
SkData::MakeWithCopy(&fWeight, sizeof(float)),
std::move(fpA),
std::move(fpB),
nullptr);
}
std::unique_ptr<GrFragmentProcessor> SkShader_LerpRed::asFragmentProcessor(const GrFPArgs& args) const {
auto fpA = as_fp(args, fDst.get());
auto fpB = as_fp(args, fSrc.get());
auto red = as_SB(fRed)->asFragmentProcessor(args);
if (!fpA || !fpB || !red) {
return nullptr;
}
return nullptr; // todo
static int index = GrSkSLFP::NewIndex();
return sksl_mixer_fp(args,
index,
"in fragmentProcessor lerpControl;"
"void main(half4 input1, half4 input2) {"
" sk_OutColor = mix(input1, input2, process(lerpControl).r);"
"}",
nullptr,
std::move(fpA),
std::move(fpB),
std::move(red));
}
#endif

View File

@ -67,4 +67,31 @@ private:
typedef SkShaderBase INHERITED;
};
class SkShader_LerpRed final : public SkShaderBase {
public:
SkShader_LerpRed(sk_sp<SkShader> red, sk_sp<SkShader> dst, sk_sp<SkShader> src)
: fDst(std::move(dst))
, fSrc(std::move(src))
, fRed(std::move(red))
{}
#if SK_SUPPORT_GPU
std::unique_ptr<GrFragmentProcessor> asFragmentProcessor(const GrFPArgs&) const override;
#endif
protected:
SkShader_LerpRed(SkReadBuffer&);
void flatten(SkWriteBuffer&) const override;
bool onAppendStages(const SkStageRec&) const override;
private:
SK_FLATTENABLE_HOOKS(SkShader_LerpRed)
sk_sp<SkShader> fDst;
sk_sp<SkShader> fSrc;
sk_sp<SkShader> fRed;
typedef SkShaderBase INHERITED;
};
#endif

View File

@ -283,7 +283,7 @@ sk_sp<SkShader> SkMakeBitmapShaderForPaint(const SkPaint& paint, const SkBitmap&
// Compose the image shader with the paint's shader. Alpha images+shaders should output the
// texture's alpha multiplied by the shader's color. DstIn (d*sa) will achieve this with
// the source image and dst shader (MakeBlend takes dst first, src second).
s = SkShader::MakeBlend(SkBlendMode::kDstIn, paint.refShader(), std::move(s));
s = SkShaders::Blend(SkBlendMode::kDstIn, paint.refShader(), std::move(s));
}
return s;
}

View File

@ -12,6 +12,7 @@
#include "SkWriteBuffer.h"
#include "SkString.h"
#ifdef SK_SUPPORT_LEGACY_SHADER_FACTORIES
sk_sp<SkShader> SkShader::MakeMixer(sk_sp<SkShader> s0, sk_sp<SkShader> s1, sk_sp<SkMixer> mixer) {
if (!mixer) {
return nullptr;
@ -24,6 +25,7 @@ sk_sp<SkShader> SkShader::MakeMixer(sk_sp<SkShader> s0, sk_sp<SkShader> s1, sk_s
}
return sk_sp<SkShader>(new SkShader_Mixer(std::move(s0), std::move(s1), std::move(mixer)));
}
#endif
///////////////////////////////////////////////////////////////////////////////
@ -32,7 +34,11 @@ sk_sp<SkFlattenable> SkShader_Mixer::CreateProc(SkReadBuffer& buffer) {
sk_sp<SkShader> s1(buffer.readShader());
sk_sp<SkMixer> mx(buffer.readMixer());
#ifdef SK_SUPPORT_LEGACY_SHADER_FACTORIES
return MakeMixer(std::move(s0), std::move(s1), std::move(mx));
#else
return nullptr;
#endif
}
void SkShader_Mixer::flatten(SkWriteBuffer& buffer) const {

View File

@ -137,7 +137,7 @@ SkPictureShader::~SkPictureShader() {
sk_sp<SkShader> SkPictureShader::Make(sk_sp<SkPicture> picture, SkTileMode tmx, SkTileMode tmy,
const SkMatrix* localMatrix, const SkRect* tile) {
if (!picture || picture->cullRect().isEmpty() || (tile && tile->isEmpty())) {
return SkShader::MakeEmptyShader();
return SkShaders::Empty();
}
return sk_sp<SkShader>(new SkPictureShader(std::move(picture), tmx, tmy, localMatrix, tile));
}
@ -214,7 +214,7 @@ sk_sp<SkShader> SkPictureShader::refBitmapShader(const SkMatrix& viewMatrix,
const SkISize tileSize = scaledSize.toCeil();
if (tileSize.isEmpty()) {
return SkShader::MakeEmptyShader();
return SkShaders::Empty();
}
// The actual scale, compensating for rounding & clamping.

View File

@ -141,9 +141,13 @@ sk_sp<SkShader> SkShaderBase::makeAsALocalMatrixShader(SkMatrix*) const {
return nullptr;
}
sk_sp<SkShader> SkShader::MakeEmptyShader() { return sk_make_sp<SkEmptyShader>(); }
#ifdef SK_SUPPORT_LEGACY_SHADER_FACTORIES
sk_sp<SkShader> SkShader::MakeEmptyShader() { return SkShaders::Empty(); }
sk_sp<SkShader> SkShader::MakeColorShader(SkColor color) { return SkShaders::Color(color); }
#endif
sk_sp<SkShader> SkShader::MakeColorShader(SkColor color) { return sk_make_sp<SkColorShader>(color); }
sk_sp<SkShader> SkShaders::Empty() { return sk_make_sp<SkEmptyShader>(); }
sk_sp<SkShader> SkShaders::Color(SkColor color) { return sk_make_sp<SkColorShader>(color); }
#ifdef SK_SUPPORT_LEGACY_BITMAPSHADER_FACTORY
sk_sp<SkShader> SkShader::MakeBitmapShader(const SkBitmap& src, SkTileMode tmx, SkTileMode tmy,
@ -224,5 +228,5 @@ bool SkShaderBase::onAppendStages(const SkStageRec& rec) const {
///////////////////////////////////////////////////////////////////////////////////////////////////
sk_sp<SkFlattenable> SkEmptyShader::CreateProc(SkReadBuffer&) {
return SkShader::MakeEmptyShader();
return SkShaders::Empty();
}

View File

@ -561,18 +561,18 @@ static sk_sp<SkShader> make_degenerate_gradient(const SkColor4f colors[], const
case SkTileMode::kDecal:
// normally this would reject the area outside of the interpolation region, so since
// inside region is empty when the radii are equal, the entire draw region is empty
return SkShader::MakeEmptyShader();
return SkShaders::Empty();
case SkTileMode::kRepeat:
case SkTileMode::kMirror:
// repeat and mirror are treated the same: the border colors are never visible,
// but approximate the final color as infinite repetitions of the colors, so
// it can be represented as the average color of the gradient.
return SkShader::MakeColorShader(
return SkShaders::Color(
average_gradient_color(colors, pos, colorCount), std::move(colorSpace));
case SkTileMode::kClamp:
// Depending on how the gradient shape degenerates, there may be a more specialized
// fallback representation for the factories to use, but this is a reasonable default.
return SkShader::MakeColorShader(colors[colorCount - 1], std::move(colorSpace));
return SkShaders::Color(colors[colorCount - 1], std::move(colorSpace));
}
SkDEBUGFAIL("Should not be reached");
return nullptr;
@ -670,7 +670,7 @@ sk_sp<SkShader> SkGradientShader::MakeLinear(const SkPoint pts[2],
return nullptr;
}
if (1 == colorCount) {
return SkShader::MakeColorShader(colors[0], std::move(colorSpace));
return SkShaders::Color(colors[0], std::move(colorSpace));
}
if (localMatrix && !localMatrix->invert(nullptr)) {
return nullptr;
@ -717,7 +717,7 @@ sk_sp<SkShader> SkGradientShader::MakeRadial(const SkPoint& center, SkScalar rad
return nullptr;
}
if (1 == colorCount) {
return SkShader::MakeColorShader(colors[0], std::move(colorSpace));
return SkShaders::Color(colors[0], std::move(colorSpace));
}
if (localMatrix && !localMatrix->invert(nullptr)) {
return nullptr;
@ -840,7 +840,7 @@ sk_sp<SkShader> SkGradientShader::MakeSweep(SkScalar cx, SkScalar cy,
return nullptr;
}
if (1 == colorCount) {
return SkShader::MakeColorShader(colors[0], std::move(colorSpace));
return SkShaders::Color(colors[0], std::move(colorSpace));
}
if (!SkScalarIsFinite(startAngle) || !SkScalarIsFinite(endAngle) || startAngle > endAngle) {
return nullptr;

View File

@ -68,7 +68,7 @@ struct GradRec {
static void none_gradproc(skiatest::Reporter* reporter, const GradRec&, const GradRec&) {
sk_sp<SkShader> s(SkShader::MakeEmptyShader());
sk_sp<SkShader> s(SkShaders::Empty());
REPORTER_ASSERT(reporter, SkShader::kNone_GradientType == s->asAGradient(nullptr));
}

View File

@ -186,7 +186,7 @@ public:
{
SkPaint greenColorShaderPaint;
greenColorShaderPaint.setShader(SkShader::MakeColorShader(SK_ColorGREEN));
greenColorShaderPaint.setShader(SkShaders::Color(SK_ColorGREEN));
SkImageFilter::CropRect leftSideCropRect(SkRect::MakeXYWH(0, 0, 32, 64));
sk_sp<SkImageFilter> paintFilterLeft(SkPaintImageFilter::Make(greenColorShaderPaint,

View File

@ -761,7 +761,7 @@ DEF_TEST(Picture_getRecordingCanvas, r) {
DEF_TEST(MiniRecorderLeftHanging, r) {
// Any shader or other ref-counted effect will do just fine here.
SkPaint paint;
paint.setShader(SkShader::MakeColorShader(SK_ColorRED));
paint.setShader(SkShaders::Color(SK_ColorRED));
SkMiniRecorder rec;
REPORTER_ASSERT(r, rec.drawRect(SkRect::MakeWH(20,30), paint));

View File

@ -58,7 +58,7 @@ DEF_TEST(Recorder_RefLeaking, r) {
SkRect bounds = SkRect::MakeWH(320, 240);
SkPaint paint;
paint.setShader(SkShader::MakeEmptyShader());
paint.setShader(SkShaders::Empty());
REPORTER_ASSERT(r, paint.getShader()->unique());
{

View File

@ -60,10 +60,9 @@ DEF_TEST(ComposeShaderSingle, reporter) {
SkCanvas canvas(srcBitmap);
SkPaint p;
p.setShader(
SkShader::MakeComposeShader(
SkShader::MakeEmptyShader(),
SkPerlinNoiseShader::MakeFractalNoise(1.0f, 1.0f, 2, 0.0f),
SkBlendMode::kClear));
SkShaders::Blend(SkBlendMode::kClear,
SkShaders::Empty(),
SkPerlinNoiseShader::MakeFractalNoise(1.0f, 1.0f, 2, 0.0f)));
SkRRect rr;
SkVector rd[] = {{0, 0}, {0, 0}, {0, 0}, {0, 0}};
rr.setRectRadii({0, 0, 0, 0}, rd);