Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Typedefs | Functions
GrFragmentProcessors Namespace Reference

Typedefs

using ChildType = SkRuntimeEffect::ChildType
 

Functions

static std::unique_ptr< GrFragmentProcessormake_fp_from_shader_mask_filter (const SkMaskFilterBase *maskfilter, const GrFPArgs &args, const SkMatrix &ctm)
 
std::unique_ptr< GrFragmentProcessorMake (const SkMaskFilter *maskfilter, const GrFPArgs &args, const SkMatrix &ctm)
 
bool IsSupported (const SkMaskFilter *maskfilter)
 
GrFPResult MakeChildFP (const SkRuntimeEffect::ChildPtr &child, const GrFPArgs &childArgs)
 
static GrFPResult make_effect_fp (sk_sp< SkRuntimeEffect > effect, const char *name, sk_sp< const SkData > uniforms, std::unique_ptr< GrFragmentProcessor > inputFP, std::unique_ptr< GrFragmentProcessor > destColorFP, SkSpan< const SkRuntimeEffect::ChildPtr > children, const GrFPArgs &childArgs)
 
static std::unique_ptr< GrFragmentProcessormake_blender_fp (const SkRuntimeBlender *rtb, std::unique_ptr< GrFragmentProcessor > srcFP, std::unique_ptr< GrFragmentProcessor > dstFP, const GrFPArgs &fpArgs)
 
static std::unique_ptr< GrFragmentProcessormake_blender_fp (const SkBlendModeBlender *blender, std::unique_ptr< GrFragmentProcessor > srcFP, std::unique_ptr< GrFragmentProcessor > dstFP, const GrFPArgs &fpArgs)
 
std::unique_ptr< GrFragmentProcessorMake (const SkBlenderBase *blender, std::unique_ptr< GrFragmentProcessor > srcFP, std::unique_ptr< GrFragmentProcessor > dstFP, const GrFPArgs &fpArgs)
 
static SkPMColor4f map_color (const SkColor4f &c, SkColorSpace *src, SkColorSpace *dst)
 
static GrFPResult make_colorfilter_fp (GrRecordingContext *, const SkBlendModeColorFilter *filter, std::unique_ptr< GrFragmentProcessor > inputFP, const GrColorInfo &dstColorInfo, const SkSurfaceProps &props)
 
static GrFPResult make_colorfilter_fp (GrRecordingContext *context, const SkComposeColorFilter *filter, std::unique_ptr< GrFragmentProcessor > inputFP, const GrColorInfo &dstColorInfo, const SkSurfaceProps &props)
 
static GrFPResult make_colorfilter_fp (GrRecordingContext *, const SkColorSpaceXformColorFilter *filter, std::unique_ptr< GrFragmentProcessor > inputFP, const GrColorInfo &, const SkSurfaceProps &)
 
static GrFPResult make_colorfilter_fp (GrRecordingContext *, const SkGaussianColorFilter *, std::unique_ptr< GrFragmentProcessor > inputFP, const GrColorInfo &, const SkSurfaceProps &)
 
static std::unique_ptr< GrFragmentProcessorrgb_to_hsl (std::unique_ptr< GrFragmentProcessor > child)
 
static std::unique_ptr< GrFragmentProcessorhsl_to_rgb (std::unique_ptr< GrFragmentProcessor > child)
 
static GrFPResult make_colorfilter_fp (GrRecordingContext *, const SkMatrixColorFilter *filter, std::unique_ptr< GrFragmentProcessor > inputFP, const GrColorInfo &, const SkSurfaceProps &)
 
static GrFPResult make_colorfilter_fp (GrRecordingContext *context, const SkRuntimeColorFilter *filter, std::unique_ptr< GrFragmentProcessor > inputFP, const GrColorInfo &colorInfo, const SkSurfaceProps &props)
 
static GrFPResult make_colorfilter_fp (GrRecordingContext *context, const SkTableColorFilter *filter, std::unique_ptr< GrFragmentProcessor > inputFP, const GrColorInfo &, const SkSurfaceProps &)
 
static GrFPResult make_colorfilter_fp (GrRecordingContext *context, const SkWorkingFormatColorFilter *filter, std::unique_ptr< GrFragmentProcessor > inputFP, const GrColorInfo &dstColorInfo, const SkSurfaceProps &props)
 
GrFPResult Make (GrRecordingContext *ctx, const SkColorFilter *cf, std::unique_ptr< GrFragmentProcessor > inputFP, const GrColorInfo &dstColorInfo, const SkSurfaceProps &props)
 
static std::unique_ptr< GrFragmentProcessormake_shader_fp (const SkBlendShader *shader, const GrFPArgs &args, const SkShaders::MatrixRec &mRec)
 
static std::unique_ptr< GrFragmentProcessormake_shader_fp (const SkColorFilterShader *shader, const GrFPArgs &args, const SkShaders::MatrixRec &mRec)
 
static std::unique_ptr< GrFragmentProcessormake_shader_fp (const SkColorShader *shader, const GrFPArgs &args, const SkShaders::MatrixRec &mRec)
 
static std::unique_ptr< GrFragmentProcessormake_shader_fp (const SkColor4Shader *shader, const GrFPArgs &args, const SkShaders::MatrixRec &mRec)
 
static std::unique_ptr< GrFragmentProcessormake_shader_fp (const SkCoordClampShader *shader, const GrFPArgs &args, const SkShaders::MatrixRec &mRec)
 
static std::unique_ptr< GrFragmentProcessormake_shader_fp (const SkCTMShader *shader, const GrFPArgs &args, const SkShaders::MatrixRec &mRec)
 
static std::unique_ptr< GrFragmentProcessormake_shader_fp (const SkEmptyShader *shader, const GrFPArgs &, const SkShaders::MatrixRec &)
 
static bool needs_subset (sk_sp< const SkImage > img, const SkRect &subset)
 
static std::unique_ptr< GrFragmentProcessormake_shader_fp (const SkImageShader *shader, const GrFPArgs &args, const SkShaders::MatrixRec &mRec)
 
static std::unique_ptr< GrFragmentProcessormake_shader_fp (const SkLocalMatrixShader *shader, const GrFPArgs &args, const SkShaders::MatrixRec &mRec)
 
static std::unique_ptr< GrFragmentProcessormake_shader_fp (const SkPerlinNoiseShader *shader, const GrFPArgs &args, const SkShaders::MatrixRec &mRec)
 
static std::unique_ptr< GrFragmentProcessormake_shader_fp (const SkPictureShader *shader, const GrFPArgs &args, const SkShaders::MatrixRec &mRec)
 
static std::unique_ptr< GrFragmentProcessormake_shader_fp (const SkRuntimeShader *shader, const GrFPArgs &args, const SkShaders::MatrixRec &mRec)
 
static std::unique_ptr< GrFragmentProcessormake_shader_fp (const SkTransformShader *shader, const GrFPArgs &, const SkShaders::MatrixRec &)
 
static std::unique_ptr< GrFragmentProcessormake_shader_fp (const SkTriColorShader *shader, const GrFPArgs &, const SkShaders::MatrixRec &)
 
static std::unique_ptr< GrFragmentProcessormake_shader_fp (const SkWorkingColorSpaceShader *shader, const GrFPArgs &args, const SkShaders::MatrixRec &mRec)
 
static std::unique_ptr< GrFragmentProcessormake_gradient_fp (const SkConicalGradient *shader, const GrFPArgs &args, const SkShaders::MatrixRec &mRec)
 
static std::unique_ptr< GrFragmentProcessormake_gradient_fp (const SkLinearGradient *shader, const GrFPArgs &args, const SkShaders::MatrixRec &mRec)
 
static std::unique_ptr< GrFragmentProcessormake_gradient_fp (const SkRadialGradient *shader, const GrFPArgs &args, const SkShaders::MatrixRec &mRec)
 
static std::unique_ptr< GrFragmentProcessormake_gradient_fp (const SkSweepGradient *shader, const GrFPArgs &args, const SkShaders::MatrixRec &mRec)
 
static std::unique_ptr< GrFragmentProcessormake_shader_fp (const SkGradientBaseShader *shader, const GrFPArgs &args, const SkShaders::MatrixRec &mRec)
 
std::unique_ptr< GrFragmentProcessorMake (const SkShader *shader, const GrFPArgs &args, const SkMatrix &ctm)
 
std::unique_ptr< GrFragmentProcessorMake (const SkShader *shader, const GrFPArgs &args, const SkShaders::MatrixRec &mRec)
 

Typedef Documentation

◆ ChildType

Definition at line 152 of file GrFragmentProcessors.cpp.

Function Documentation

◆ hsl_to_rgb()

static std::unique_ptr< GrFragmentProcessor > GrFragmentProcessors::hsl_to_rgb ( std::unique_ptr< GrFragmentProcessor child)
static

Definition at line 383 of file GrFragmentProcessors.cpp.

383 {
384 static const SkRuntimeEffect* effect =
386 "half4 main(half4 color) {"
387 "return $hsl_to_rgb(color.rgb, color.a);"
388 "}");
390 return GrSkSLFP::Make(
391 effect, "HslToRgb", std::move(child), GrSkSLFP::OptFlags::kPreservesOpaqueInput);
392}
#define SkASSERT(cond)
Definition SkAssert.h:116
SkRuntimeEffect * SkMakeRuntimeEffect(SkRuntimeEffect::Result(*make)(SkString, const SkRuntimeEffect::Options &), const char *sksl, SkRuntimeEffect::Options options=SkRuntimeEffect::Options{})
static std::unique_ptr< GrSkSLFP > Make(const SkRuntimeEffect *effect, const char *name, std::unique_ptr< GrFragmentProcessor > inputFP, OptFlags optFlags, Args &&... args)
Definition GrSkSLFP.h:158
static bool SupportsConstantOutputForConstantInput(const SkRuntimeEffect *effect)
static Result MakeForColorFilter(SkString sksl, const Options &)

◆ IsSupported()

bool GrFragmentProcessors::IsSupported ( const SkMaskFilter maskfilter)

Definition at line 135 of file GrFragmentProcessors.cpp.

135 {
136 if (!maskfilter) {
137 return false;
138 }
139 auto mfb = as_MFB(maskfilter);
140 switch (mfb->type()) {
142 return true;
147 return false;
148 }
150}
#define SkUNREACHABLE
Definition SkAssert.h:135
SkMaskFilterBase * as_MFB(SkMaskFilter *mf)

◆ Make() [1/5]

std::unique_ptr< GrFragmentProcessor > GrFragmentProcessors::Make ( const SkBlenderBase ,
std::unique_ptr< GrFragmentProcessor srcFP,
std::unique_ptr< GrFragmentProcessor dstFP,
const GrFPArgs fpArgs 
)

Returns a GrFragmentProcessor that implements this blend for the Ganesh GPU backend. The GrFragmentProcessor expects premultiplied inputs and returns a premultiplied output.

Definition at line 259 of file GrFragmentProcessors.cpp.

262 {
263 if (!blender) {
264 return nullptr;
265 }
266 switch (blender->type()) {
267#define M(type) \
268 case SkBlenderBase::BlenderType::k##type: \
269 return make_blender_fp(static_cast<const Sk##type##Blender*>(blender), \
270 std::move(srcFP), \
271 std::move(dstFP), \
272 fpArgs);
274#undef M
275 }
277}
#define M(type)
#define SK_ALL_BLENDERS(M)
virtual BlenderType type() const =0

◆ Make() [2/5]

std::unique_ptr< GrFragmentProcessor > GrFragmentProcessors::Make ( const SkMaskFilter maskfilter,
const GrFPArgs args,
const SkMatrix ctm 
)

Definition at line 116 of file GrFragmentProcessors.cpp.

118 {
119 if (!maskfilter) {
120 return nullptr;
121 }
122 auto mfb = as_MFB(maskfilter);
123 switch (mfb->type()) {
125 return make_fp_from_shader_mask_filter(mfb, args, ctm);
130 return nullptr;
131 }
133}
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args

◆ Make() [3/5]

std::unique_ptr< GrFragmentProcessor > GrFragmentProcessors::Make ( const SkShader ,
const GrFPArgs ,
const SkMatrix ctm 
)

Call on the root SkShader to produce a GrFragmentProcessor.

The returned GrFragmentProcessor expects an unpremultiplied input color and produces a premultiplied output.

Definition at line 1101 of file GrFragmentProcessors.cpp.

1103 {
1104 return Make(shader, args, SkShaders::MatrixRec(ctm));
1105}
static std::unique_ptr< SkEncoder > Make(SkWStream *dst, const SkPixmap *src, const SkYUVAPixmaps *srcYUVA, const SkColorSpace *srcYUVAColorSpace, const SkJpegEncoder::Options &options)

◆ Make() [4/5]

std::unique_ptr< GrFragmentProcessor > GrFragmentProcessors::Make ( const SkShader shader,
const GrFPArgs args,
const SkShaders::MatrixRec mRec 
)

Definition at line 1107 of file GrFragmentProcessors.cpp.

1109 {
1110 if (!shader) {
1111 return nullptr;
1112 }
1113 auto base = as_SB(shader);
1114 switch (base->type()) {
1115#define M(type) \
1116 case SkShaderBase::ShaderType::k##type: \
1117 return make_shader_fp(static_cast<const Sk##type##Shader*>(base), args, mRec);
1119#undef M
1120 }
1122}
SkShaderBase * as_SB(SkShader *shader)
#define SK_ALL_SHADERS(M)

◆ Make() [5/5]

GrFPResult GrFragmentProcessors::Make ( GrRecordingContext ,
const SkColorFilter ,
std::unique_ptr< GrFragmentProcessor inputFP,
const GrColorInfo dstColorInfo,
const SkSurfaceProps  
)

Returns a GrFragmentProcessor that implements the color filter in GPU shader code.

The fragment processor receives a input FP that generates a premultiplied input color, and produces a premultiplied output color.

A GrFPFailure indicates that the color filter isn't implemented for the GPU backend.

Definition at line 474 of file GrFragmentProcessors.cpp.

478 {
479 if (!cf) {
480 return GrFPFailure(nullptr);
481 }
482 auto cfb = as_CFB(cf);
483 switch (cfb->type()) {
485 return GrFPFailure(nullptr);
486#define M(type) \
487 case SkColorFilterBase::Type::k##type: \
488 return make_colorfilter_fp(ctx, \
489 static_cast<const Sk##type##ColorFilter*>(cf), \
490 std::move(inputFP), \
491 dstColorInfo, \
492 props);
494#undef M
495 }
497}
static GrFPResult GrFPFailure(std::unique_ptr< GrFragmentProcessor > fp)
#define SK_ALL_COLOR_FILTERS(M)
static SkColorFilterBase * as_CFB(SkColorFilter *filter)

◆ make_blender_fp() [1/2]

static std::unique_ptr< GrFragmentProcessor > GrFragmentProcessors::make_blender_fp ( const SkBlendModeBlender blender,
std::unique_ptr< GrFragmentProcessor srcFP,
std::unique_ptr< GrFragmentProcessor dstFP,
const GrFPArgs fpArgs 
)
static

Definition at line 250 of file GrFragmentProcessors.cpp.

254 {
255 SkASSERT(blender);
256 return GrBlendFragmentProcessor::Make(std::move(srcFP), std::move(dstFP), blender->mode());
257}
SkBlendMode mode() const
std::unique_ptr< GrFragmentProcessor > Make(std::unique_ptr< GrFragmentProcessor > src, std::unique_ptr< GrFragmentProcessor > dst, SkBlendMode mode, bool shareBlendLogic=true)

◆ make_blender_fp() [2/2]

static std::unique_ptr< GrFragmentProcessor > GrFragmentProcessors::make_blender_fp ( const SkRuntimeBlender rtb,
std::unique_ptr< GrFragmentProcessor srcFP,
std::unique_ptr< GrFragmentProcessor dstFP,
const GrFPArgs fpArgs 
)
static

Definition at line 220 of file GrFragmentProcessors.cpp.

224 {
225 SkASSERT(rtb);
226 if (!SkRuntimeEffectPriv::CanDraw(fpArgs.fContext->priv().caps(), rtb->effect().get())) {
227 return nullptr;
228 }
229
231 rtb->effect()->uniforms(),
232 rtb->uniforms(),
233 fpArgs.fDstColorInfo->colorSpace());
234 SkASSERT(uniforms);
235 GrFPArgs childArgs(fpArgs.fContext,
236 fpArgs.fDstColorInfo,
237 fpArgs.fSurfaceProps,
239 auto [success, fp] = make_effect_fp(rtb->effect(),
240 "runtime_blender",
241 std::move(uniforms),
242 std::move(srcFP),
243 std::move(dstFP),
244 rtb->children(),
245 childArgs);
246
247 return success ? std::move(fp) : nullptr;
248}
const GrCaps * caps() const
SkColorSpace * colorSpace() const
GrRecordingContextPriv priv()
sk_sp< SkRuntimeEffect > effect() const
SkSpan< const SkRuntimeEffect::ChildPtr > children() const
sk_sp< const SkData > uniforms() const
static sk_sp< const SkData > TransformUniforms(SkSpan< const SkRuntimeEffect::Uniform > uniforms, sk_sp< const SkData > originalData, const SkColorSpaceXformSteps &)
static bool CanDraw(const SkCapabilities *, const SkSL::Program *)
SkSpan< const Uniform > uniforms() const
T * get() const
Definition SkRefCnt.h:303
const SkSurfaceProps & fSurfaceProps
Definition GrFPArgs.h:39
const GrColorInfo * fDstColorInfo
Definition GrFPArgs.h:37
GrRecordingContext * fContext
Definition GrFPArgs.h:35

◆ make_colorfilter_fp() [1/8]

static GrFPResult GrFragmentProcessors::make_colorfilter_fp ( GrRecordingContext ,
const SkBlendModeColorFilter filter,
std::unique_ptr< GrFragmentProcessor inputFP,
const GrColorInfo dstColorInfo,
const SkSurfaceProps props 
)
static

Definition at line 284 of file GrFragmentProcessors.cpp.

288 {
289 if (filter->mode() == SkBlendMode::kDst) {
290 // If the blend mode is "dest," the blend color won't factor into it at all.
291 // We can return the input FP as-is.
292 return GrFPSuccess(std::move(inputFP));
293 }
294
295 SkDEBUGCODE(const bool fpHasConstIO = !inputFP || inputFP->hasConstantOutputForConstantInput();)
296
297 SkPMColor4f color = map_color(filter->color(), sk_srgb_singleton(), dstColorInfo.colorSpace());
298
300 auto xferFP =
301 GrBlendFragmentProcessor::Make(std::move(colorFP), std::move(inputFP), filter->mode());
302
303 if (xferFP == nullptr) {
304 // This is only expected to happen if the blend mode is "dest" and the input FP is null.
305 // Since we already did an early-out in the "dest" blend mode case, we shouldn't get here.
306 SkDEBUGFAIL("GrBlendFragmentProcessor::Make returned null unexpectedly");
307 return GrFPFailure(nullptr);
308 }
309
310 // With a solid color input this should always be able to compute the blended color
311 // (at least for coeff modes).
312 // Occasionally, we even do better than we started; specifically, in "src" blend mode, we end up
313 // ditching the input FP entirely, which turns a non-constant operation into a constant one.
315 xferFP->hasConstantOutputForConstantInput() >= fpHasConstIO);
316
317 return GrFPSuccess(std::move(xferFP));
318}
static GrFPResult GrFPSuccess(std::unique_ptr< GrFragmentProcessor > fp)
SkColor4f color
#define SkDEBUGFAIL(message)
Definition SkAssert.h:118
static SkRGBA4f< kDstAT > map_color(const SkColor4f &c, SkColorSpace *src, SkColorSpace *dst)
@ kLastCoeffMode
last porter duff blend mode
SkColorSpace * sk_srgb_singleton()
#define SkDEBUGCODE(...)
Definition SkDebug.h:23
static std::unique_ptr< GrFragmentProcessor > MakeColor(SkPMColor4f color)

◆ make_colorfilter_fp() [2/8]

static GrFPResult GrFragmentProcessors::make_colorfilter_fp ( GrRecordingContext ,
const SkColorSpaceXformColorFilter filter,
std::unique_ptr< GrFragmentProcessor inputFP,
const GrColorInfo ,
const SkSurfaceProps  
)
static

Definition at line 344 of file GrFragmentProcessors.cpp.

348 {
349 // wish our caller would let us know if our input was opaque...
350 constexpr SkAlphaType alphaType = kPremul_SkAlphaType;
352 std::move(inputFP), filter->src().get(), alphaType, filter->dst().get(), alphaType));
353}
SkAlphaType
Definition SkAlphaType.h:26
@ kPremul_SkAlphaType
pixel components are premultiplied by alpha
Definition SkAlphaType.h:29
static std::unique_ptr< GrFragmentProcessor > Make(std::unique_ptr< GrFragmentProcessor > child, SkColorSpace *src, SkAlphaType srcAT, SkColorSpace *dst, SkAlphaType dstAT)
sk_sp< SkColorSpace > dst() const
sk_sp< SkColorSpace > src() const

◆ make_colorfilter_fp() [3/8]

static GrFPResult GrFragmentProcessors::make_colorfilter_fp ( GrRecordingContext ,
const SkGaussianColorFilter ,
std::unique_ptr< GrFragmentProcessor inputFP,
const GrColorInfo ,
const SkSurfaceProps  
)
static

Definition at line 355 of file GrFragmentProcessors.cpp.

359 {
360 static const SkRuntimeEffect* effect =
362 "half4 main(half4 inColor) {"
363 "half factor = 1 - inColor.a;"
364 "factor = exp(-factor * factor * 4) - 0.018;"
365 "return half4(factor);"
366 "}");
368 return GrFPSuccess(
369 GrSkSLFP::Make(effect, "gaussian_fp", std::move(inputFP), GrSkSLFP::OptFlags::kNone));
370}

◆ make_colorfilter_fp() [4/8]

static GrFPResult GrFragmentProcessors::make_colorfilter_fp ( GrRecordingContext ,
const SkMatrixColorFilter filter,
std::unique_ptr< GrFragmentProcessor inputFP,
const GrColorInfo ,
const SkSurfaceProps  
)
static

Definition at line 394 of file GrFragmentProcessors.cpp.

398 {
399 switch (filter->domain()) {
401 return GrFPSuccess(GrFragmentProcessor::ColorMatrix(std::move(inputFP),
402 filter->matrix(),
403 /* unpremulInput = */ true,
404 /* clampRGBOutput = */ true,
405 /* premulOutput = */ true));
406
408 auto fp = rgb_to_hsl(std::move(inputFP));
409 fp = GrFragmentProcessor::ColorMatrix(std::move(fp),
410 filter->matrix(),
411 /* unpremulInput = */ false,
412 /* clampRGBOutput = */ false,
413 /* premulOutput = */ false);
414 return GrFPSuccess(hsl_to_rgb(std::move(fp)));
415 }
416 }
418}
static std::unique_ptr< GrFragmentProcessor > ColorMatrix(std::unique_ptr< GrFragmentProcessor > child, const float matrix[20], bool unpremulInput, bool clampRGBOutput, bool premulOutput)
const float * matrix() const
static std::unique_ptr< GrFragmentProcessor > hsl_to_rgb(std::unique_ptr< GrFragmentProcessor > child)
static std::unique_ptr< GrFragmentProcessor > rgb_to_hsl(std::unique_ptr< GrFragmentProcessor > child)

◆ make_colorfilter_fp() [5/8]

static GrFPResult GrFragmentProcessors::make_colorfilter_fp ( GrRecordingContext context,
const SkComposeColorFilter filter,
std::unique_ptr< GrFragmentProcessor inputFP,
const GrColorInfo dstColorInfo,
const SkSurfaceProps props 
)
static

Definition at line 320 of file GrFragmentProcessors.cpp.

324 {
325 // Unfortunately, we need to clone the input before we know we need it. This lets us return
326 // the original FP if either internal color filter fails.
327 auto inputClone = inputFP ? inputFP->clone() : nullptr;
328
329 auto [innerSuccess, innerFP] =
330 Make(context, filter->inner().get(), std::move(inputFP), dstColorInfo, props);
331 if (!innerSuccess) {
332 return GrFPFailure(std::move(inputClone));
333 }
334
335 auto [outerSuccess, outerFP] =
336 Make(context, filter->outer().get(), std::move(innerFP), dstColorInfo, props);
337 if (!outerSuccess) {
338 return GrFPFailure(std::move(inputClone));
339 }
340
341 return GrFPSuccess(std::move(outerFP));
342}
sk_sp< SkColorFilterBase > inner() const
sk_sp< SkColorFilterBase > outer() const

◆ make_colorfilter_fp() [6/8]

static GrFPResult GrFragmentProcessors::make_colorfilter_fp ( GrRecordingContext context,
const SkRuntimeColorFilter filter,
std::unique_ptr< GrFragmentProcessor inputFP,
const GrColorInfo colorInfo,
const SkSurfaceProps props 
)
static

Definition at line 420 of file GrFragmentProcessors.cpp.

424 {
426 filter->effect()->uniforms(), filter->uniforms(), colorInfo.colorSpace());
427 SkASSERT(uniforms);
428
429 GrFPArgs childArgs(context, &colorInfo, props, GrFPArgs::Scope::kRuntimeEffect);
430 return make_effect_fp(filter->effect(),
431 "runtime_color_filter",
432 std::move(uniforms),
433 std::move(inputFP),
434 /*destColorFP=*/nullptr,
435 filter->children(),
436 childArgs);
437}
SkSpan< const SkRuntimeEffect::ChildPtr > children() const
sk_sp< SkRuntimeEffect > effect() const
sk_sp< const SkData > uniforms() const
static GrFPResult make_effect_fp(sk_sp< SkRuntimeEffect > effect, const char *name, sk_sp< const SkData > uniforms, std::unique_ptr< GrFragmentProcessor > inputFP, std::unique_ptr< GrFragmentProcessor > destColorFP, SkSpan< const SkRuntimeEffect::ChildPtr > children, const GrFPArgs &childArgs)

◆ make_colorfilter_fp() [7/8]

static GrFPResult GrFragmentProcessors::make_colorfilter_fp ( GrRecordingContext context,
const SkTableColorFilter filter,
std::unique_ptr< GrFragmentProcessor inputFP,
const GrColorInfo ,
const SkSurfaceProps  
)
static

Definition at line 439 of file GrFragmentProcessors.cpp.

443 {
444 auto cte = ColorTableEffect::Make(std::move(inputFP), context, filter->bitmap());
445 return cte ? GrFPSuccess(std::move(cte)) : GrFPFailure(nullptr);
446}
static std::unique_ptr< GrFragmentProcessor > Make(std::unique_ptr< GrFragmentProcessor > inputFP, GrRecordingContext *context, const SkBitmap &bitmap)
const SkBitmap & bitmap() const

◆ make_colorfilter_fp() [8/8]

static GrFPResult GrFragmentProcessors::make_colorfilter_fp ( GrRecordingContext context,
const SkWorkingFormatColorFilter filter,
std::unique_ptr< GrFragmentProcessor inputFP,
const GrColorInfo dstColorInfo,
const SkSurfaceProps props 
)
static

Definition at line 448 of file GrFragmentProcessors.cpp.

452 {
453 sk_sp<SkColorSpace> dstCS = dstColorInfo.refColorSpace();
454 if (!dstCS) {
455 dstCS = SkColorSpace::MakeSRGB();
456 }
457
458 SkAlphaType workingAT;
459 sk_sp<SkColorSpace> workingCS = filter->workingFormat(dstCS, &workingAT);
460
461 GrColorInfo dst = {dstColorInfo.colorType(), dstColorInfo.alphaType(), dstCS},
462 working = {dstColorInfo.colorType(), workingAT, workingCS};
463
464 auto [ok, fp] = Make(context,
465 filter->child().get(),
466 GrColorSpaceXformEffect::Make(std::move(inputFP), dst, working),
467 working,
468 props);
469
470 return ok ? GrFPSuccess(GrColorSpaceXformEffect::Make(std::move(fp), working, dst))
471 : GrFPFailure(std::move(fp));
472}
static bool ok(int result)
sk_sp< SkColorSpace > refColorSpace() const
GrColorType colorType() const
Definition GrColorInfo.h:43
SkAlphaType alphaType() const
Definition GrColorInfo.h:44
static sk_sp< SkColorSpace > MakeSRGB()
sk_sp< SkColorFilter > child() const
sk_sp< SkColorSpace > workingFormat(const sk_sp< SkColorSpace > &dstCS, SkAlphaType *at) const
const uint32_t fp
Definition ref_ptr.h:256

◆ make_effect_fp()

static GrFPResult GrFragmentProcessors::make_effect_fp ( sk_sp< SkRuntimeEffect effect,
const char *  name,
sk_sp< const SkData uniforms,
std::unique_ptr< GrFragmentProcessor inputFP,
std::unique_ptr< GrFragmentProcessor destColorFP,
SkSpan< const SkRuntimeEffect::ChildPtr children,
const GrFPArgs childArgs 
)
static

Definition at line 194 of file GrFragmentProcessors.cpp.

200 {
202 for (const auto& child : children) {
203 auto [success, childFP] = MakeChildFP(child, childArgs);
204 if (!success) {
205 return GrFPFailure(std::move(inputFP));
206 }
207 childFPs.push_back(std::move(childFP));
208 }
209 auto fp = GrSkSLFP::MakeWithData(std::move(effect),
210 name,
211 childArgs.fDstColorInfo->refColorSpace(),
212 std::move(inputFP),
213 std::move(destColorFP),
214 std::move(uniforms),
215 SkSpan(childFPs));
216 SkASSERT(fp);
217 return GrFPSuccess(std::move(fp));
218}
static std::unique_ptr< GrSkSLFP > MakeWithData(sk_sp< SkRuntimeEffect > effect, const char *name, sk_sp< SkColorSpace > dstColorSpace, std::unique_ptr< GrFragmentProcessor > inputFP, std::unique_ptr< GrFragmentProcessor > destColorFP, const sk_sp< const SkData > &uniforms, SkSpan< std::unique_ptr< GrFragmentProcessor > > childFPs)
Definition GrSkSLFP.cpp:289
const char * name
Definition fuchsia.cc:50
GrFPResult MakeChildFP(const SkRuntimeEffect::ChildPtr &child, const GrFPArgs &childArgs)

◆ make_fp_from_shader_mask_filter()

static std::unique_ptr< GrFragmentProcessor > GrFragmentProcessors::make_fp_from_shader_mask_filter ( const SkMaskFilterBase maskfilter,
const GrFPArgs args,
const SkMatrix ctm 
)
static

Definition at line 107 of file GrFragmentProcessors.cpp.

109 {
110 SkASSERT(maskfilter);
111 auto shaderMF = static_cast<const SkShaderMaskFilterImpl*>(maskfilter);
112 auto fp = Make(shaderMF->shader().get(), args, ctm);
113 return GrFragmentProcessor::MulInputByChildAlpha(std::move(fp));
114}
static std::unique_ptr< GrFragmentProcessor > MulInputByChildAlpha(std::unique_ptr< GrFragmentProcessor > child)

◆ make_gradient_fp() [1/4]

static std::unique_ptr< GrFragmentProcessor > GrFragmentProcessors::make_gradient_fp ( const SkConicalGradient shader,
const GrFPArgs args,
const SkShaders::MatrixRec mRec 
)
static

Definition at line 860 of file GrFragmentProcessors.cpp.

862 {
863 // The 2 point conical gradient can reject a pixel so it does change opacity even if the input
864 // was opaque. Thus, all of these layout FPs disable that optimization.
865 std::unique_ptr<GrFragmentProcessor> fp;
866 SkTLazy<SkMatrix> matrix;
867 switch (shader->getType()) {
869 static const SkRuntimeEffect* kEffect =
871 "uniform half r0_2;"
872 "half4 main(float2 p) {"
873 // validation flag, set to negative to discard fragment later.
874 "half v = 1;"
875 "float t = r0_2 - p.y * p.y;"
876 "if (t >= 0) {"
877 "t = p.x + sqrt(t);"
878 "} else {"
879 "v = -1;"
880 "}"
881 "return half4(half(t), v, 0, 0);"
882 "}"
883 );
884 float r0 = shader->getStartRadius() / shader->getCenterX1();
885 fp = GrSkSLFP::Make(kEffect,
886 "TwoPointConicalStripLayout",
887 /*inputFP=*/nullptr,
889 "r0_2",
890 r0 * r0);
891 } break;
892
894 static const SkRuntimeEffect* kEffect =
896 "uniform half r0;"
897 "uniform half lengthScale;"
898 "half4 main(float2 p) {"
899 // validation flag, set to negative to discard fragment later
900 "half v = 1;"
901 "float t = length(p) * lengthScale - r0;"
902 "return half4(half(t), v, 0, 0);"
903 "}"
904 );
905 float dr = shader->getDiffRadius();
906 float r0 = shader->getStartRadius() / dr;
907 bool isRadiusIncreasing = dr >= 0;
908 fp = GrSkSLFP::Make(kEffect,
909 "TwoPointConicalRadialLayout",
910 /*inputFP=*/nullptr,
912 "r0",
913 r0,
914 "lengthScale",
915 isRadiusIncreasing ? 1.0f : -1.0f);
916
917 // GPU radial matrix is different from the original matrix, since we map the diff radius
918 // to have |dr| = 1, so manually compute the final gradient matrix here.
919
920 // Map center to (0, 0)
921 matrix.set(SkMatrix::Translate(-shader->getStartCenter().fX,
922 -shader->getStartCenter().fY));
923 // scale |diffRadius| to 1
924 matrix->postScale(1 / dr, 1 / dr);
925 } break;
926
928 static const SkRuntimeEffect* kEffect =
930 // Optimization flags, all specialized:
931 "uniform int isRadiusIncreasing;"
932 "uniform int isFocalOnCircle;"
933 "uniform int isWellBehaved;"
934 "uniform int isSwapped;"
935 "uniform int isNativelyFocal;"
936
937 "uniform half invR1;" // 1/r1
938 "uniform half fx;" // focalX = r0/(r0-r1)
939
940 "half4 main(float2 p) {"
941 "float t = -1;"
942 "half v = 1;" // validation flag,set to negative to discard fragment later
943
944 "float x_t = -1;"
945 "if (bool(isFocalOnCircle)) {"
946 "x_t = dot(p, p) / p.x;"
947 "} else if (bool(isWellBehaved)) {"
948 "x_t = length(p) - p.x * invR1;"
949 "} else {"
950 "float temp = p.x * p.x - p.y * p.y;"
951
952 // Only do sqrt if temp >= 0; this is significantly slower than
953 // checking temp >= 0 in the if statement that checks r(t) >= 0.
954 // But GPU may break if we sqrt a negative float. (Although I
955 // haven't observed that on any devices so far, and the old
956 // approach also does sqrt negative value without a check.) If
957 // the performance is really critical, maybe we should just
958 // compute the area where temp and x_t are always valid and drop
959 // all these ifs.
960 "if (temp >= 0) {"
961 "if (bool(isSwapped) || !bool(isRadiusIncreasing)) {"
962 "x_t = -sqrt(temp) - p.x * invR1;"
963 "} else {"
964 "x_t = sqrt(temp) - p.x * invR1;"
965 "}"
966 "}"
967 "}"
968
969 // The final calculation of t from x_t has lots of static
970 // optimizations but only do them when x_t is positive (which
971 // can be assumed true if isWellBehaved is true)
972 "if (!bool(isWellBehaved)) {"
973 // This will still calculate t even though it will be ignored
974 // later in the pipeline to avoid a branch
975 "if (x_t <= 0.0) {"
976 "v = -1;"
977 "}"
978 "}"
979 "if (bool(isRadiusIncreasing)) {"
980 "if (bool(isNativelyFocal)) {"
981 "t = x_t;"
982 "} else {"
983 "t = x_t + fx;"
984 "}"
985 "} else {"
986 "if (bool(isNativelyFocal)) {"
987 "t = -x_t;"
988 "} else {"
989 "t = -x_t + fx;"
990 "}"
991 "}"
992
993 "if (bool(isSwapped)) {"
994 "t = 1 - t;"
995 "}"
996
997 "return half4(half(t), v, 0, 0);"
998 "}"
999 );
1000
1001 const SkConicalGradient::FocalData& focalData = shader->getFocalData();
1002 bool isRadiusIncreasing = (1 - focalData.fFocalX) > 0,
1003 isFocalOnCircle = focalData.isFocalOnCircle(),
1004 isWellBehaved = focalData.isWellBehaved(), isSwapped = focalData.isSwapped(),
1005 isNativelyFocal = focalData.isNativelyFocal();
1006
1007 fp = GrSkSLFP::Make(kEffect, "TwoPointConicalFocalLayout", /*inputFP=*/nullptr,
1009 "isRadiusIncreasing", GrSkSLFP::Specialize<int>(isRadiusIncreasing),
1010 "isFocalOnCircle", GrSkSLFP::Specialize<int>(isFocalOnCircle),
1011 "isWellBehaved", GrSkSLFP::Specialize<int>(isWellBehaved),
1012 "isSwapped", GrSkSLFP::Specialize<int>(isSwapped),
1013 "isNativelyFocal", GrSkSLFP::Specialize<int>(isNativelyFocal),
1014 "invR1", 1.0f / focalData.fR1,
1015 "fx", focalData.fFocalX);
1016 } break;
1017 }
1019 *shader, args, mRec, std::move(fp), matrix.getMaybeNull());
1020}
const SkPoint & getStartCenter() const
SkScalar getDiffRadius() const
SkScalar getCenterX1() const
SkScalar getStartRadius() const
const FocalData & getFocalData() const
static SkMatrix Translate(SkScalar dx, SkScalar dy)
Definition SkMatrix.h:91
static Result MakeForShader(SkString sksl, const Options &)
std::unique_ptr< GrFragmentProcessor > MakeGradientFP(const SkGradientBaseShader &shader, const GrFPArgs &args, const SkShaders::MatrixRec &mRec, std::unique_ptr< GrFragmentProcessor > layout, const SkMatrix *overrideMatrix)
unsigned useCenter Optional< SkMatrix > matrix
Definition SkRecords.h:258
float fX
x-axis value
float fY
y-axis value

◆ make_gradient_fp() [2/4]

static std::unique_ptr< GrFragmentProcessor > GrFragmentProcessors::make_gradient_fp ( const SkLinearGradient shader,
const GrFPArgs args,
const SkShaders::MatrixRec mRec 
)
static

Definition at line 1022 of file GrFragmentProcessors.cpp.

1024 {
1025 return GrGradientShader::MakeLinear(*shader, args, mRec);
1026}
std::unique_ptr< GrFragmentProcessor > MakeLinear(const SkLinearGradient &shader, const GrFPArgs &args, const SkShaders::MatrixRec &mRec)

◆ make_gradient_fp() [3/4]

static std::unique_ptr< GrFragmentProcessor > GrFragmentProcessors::make_gradient_fp ( const SkRadialGradient shader,
const GrFPArgs args,
const SkShaders::MatrixRec mRec 
)
static

Definition at line 1028 of file GrFragmentProcessors.cpp.

1030 {
1031 static const SkRuntimeEffect* effect = SkMakeRuntimeEffect(
1033 "half4 main(float2 coord) {"
1034 "return half4(half(length(coord)), 1, 0, 0);" // y = 1 for always valid
1035 "}");
1036 // The radial gradient never rejects a pixel so it doesn't change opacity
1037 auto fp = GrSkSLFP::Make(
1038 effect, "RadialLayout", /*inputFP=*/nullptr, GrSkSLFP::OptFlags::kPreservesOpaqueInput);
1039 return GrGradientShader::MakeGradientFP(*shader, args, mRec, std::move(fp));
1040}

◆ make_gradient_fp() [4/4]

static std::unique_ptr< GrFragmentProcessor > GrFragmentProcessors::make_gradient_fp ( const SkSweepGradient shader,
const GrFPArgs args,
const SkShaders::MatrixRec mRec 
)
static

Definition at line 1042 of file GrFragmentProcessors.cpp.

1044 {
1045 // On some devices they incorrectly implement atan2(y,x) as atan(y/x). In actuality it is
1046 // atan2(y,x) = 2 * atan(y / (sqrt(x^2 + y^2) + x)). So to work around this we pass in (sqrt(x^2
1047 // + y^2) + x) as the second parameter to atan2 in these cases. We let the device handle the
1048 // undefined behavior of the second paramenter being 0 instead of doing the divide ourselves and
1049 // using atan instead.
1050 int useAtanWorkaround =
1051 args.fContext->priv().caps()->shaderCaps()->fAtan2ImplementedAsAtanYOverX;
1053 "uniform half bias;"
1054 "uniform half scale;"
1055 "uniform int useAtanWorkaround;" // specialized
1056
1057 "half4 main(float2 coord) {"
1058 "half angle;"
1059 "if (bool(useAtanWorkaround)) {"
1060 "angle = half(2 * atan(-coord.y, length(coord) - coord.x));"
1061 "} else {"
1062 // Hardcode pi/2 for the angle when x == 0, to avoid undefined behavior in this
1063 // case. This hasn't proven to be necessary in the atan workaround case.
1064 "angle = (coord.x != 0) ? half(atan(-coord.y, -coord.x)) :"
1065 " sign(coord.y) * -1.5707963267949;"
1066 "}"
1067
1068 // 0.1591549430918 is 1/(2*pi), used since atan returns values [-pi, pi]
1069 "half t = (angle * 0.1591549430918 + 0.5 + bias) * scale;"
1070 "return half4(t, 1, 0, 0);" // y = 1 for always valid
1071 "}"
1072 );
1073
1074 // The sweep gradient never rejects a pixel so it doesn't change opacity
1075 auto fp = GrSkSLFP::Make(effect, "SweepLayout", /*inputFP=*/nullptr,
1077 "bias", shader->tBias(),
1078 "scale", shader->tScale(),
1079 "useAtanWorkaround", GrSkSLFP::Specialize(useAtanWorkaround));
1080 return GrGradientShader::MakeGradientFP(*shader, args, mRec, std::move(fp));
1081}
static GrSpecializedUniform< T > Specialize(const T &value)
Definition GrSkSLFP.h:76
SkScalar tBias() const
SkScalar tScale() const

◆ make_shader_fp() [1/16]

static std::unique_ptr< GrFragmentProcessor > GrFragmentProcessors::make_shader_fp ( const SkBlendShader shader,
const GrFPArgs args,
const SkShaders::MatrixRec mRec 
)
static

Definition at line 499 of file GrFragmentProcessors.cpp.

501 {
502 auto fpA = Make(shader->dst().get(), args, mRec);
503 auto fpB = Make(shader->src().get(), args, mRec);
504 if (!fpA || !fpB) {
505 // This is unexpected. Both src and dst shaders should be valid. Just fail.
506 return nullptr;
507 }
508 return GrBlendFragmentProcessor::Make(std::move(fpB), std::move(fpA), shader->mode());
509}
sk_sp< SkShader > dst() const
SkBlendMode mode() const
sk_sp< SkShader > src() const

◆ make_shader_fp() [2/16]

static std::unique_ptr< GrFragmentProcessor > GrFragmentProcessors::make_shader_fp ( const SkColor4Shader shader,
const GrFPArgs args,
const SkShaders::MatrixRec mRec 
)
static

Definition at line 538 of file GrFragmentProcessors.cpp.

540 {
541 SkColorSpaceXformSteps steps{shader->colorSpace().get(),
543 args.fDstColorInfo->colorSpace(),
545 SkColor4f color = shader->color();
546 steps.apply(color.vec());
547 return GrFragmentProcessor::MakeColor(color.premul());
548}
kUnpremul_SkAlphaType
SkColor4f color() const
sk_sp< SkColorSpace > colorSpace() const

◆ make_shader_fp() [3/16]

static std::unique_ptr< GrFragmentProcessor > GrFragmentProcessors::make_shader_fp ( const SkColorFilterShader shader,
const GrFPArgs args,
const SkShaders::MatrixRec mRec 
)
static

Definition at line 511 of file GrFragmentProcessors.cpp.

513 {
514 auto shaderFP = Make(shader->shader().get(), args, mRec);
515 if (!shaderFP) {
516 return nullptr;
517 }
518
519 // TODO I guess, but it shouldn't come up as used today.
520 SkASSERT(shader->alpha() == 1.0f);
521
522 auto [success, fp] = Make(args.fContext,
523 shader->filter().get(),
524 std::move(shaderFP),
525 *args.fDstColorInfo,
526 args.fSurfaceProps);
527 // If the filter FP could not be created, we still want to return the shader FP, so checking
528 // success can be omitted here.
529 return std::move(fp);
530}
sk_sp< SkColorFilterBase > filter() const
sk_sp< SkShader > shader() const

◆ make_shader_fp() [4/16]

static std::unique_ptr< GrFragmentProcessor > GrFragmentProcessors::make_shader_fp ( const SkColorShader shader,
const GrFPArgs args,
const SkShaders::MatrixRec mRec 
)
static

Definition at line 532 of file GrFragmentProcessors.cpp.

534 {
535 return GrFragmentProcessor::MakeColor(SkColorToPMColor4f(shader->color(), *args.fDstColorInfo));
536}
SkPMColor4f SkColorToPMColor4f(SkColor c, const GrColorInfo &colorInfo)
Definition SkGr.cpp:275
SkColor color() const

◆ make_shader_fp() [5/16]

static std::unique_ptr< GrFragmentProcessor > GrFragmentProcessors::make_shader_fp ( const SkCoordClampShader shader,
const GrFPArgs args,
const SkShaders::MatrixRec mRec 
)
static

Definition at line 550 of file GrFragmentProcessors.cpp.

552 {
553 static const SkRuntimeEffect* effect =
555 "uniform shader c;"
556 "uniform float4 s;"
557 "half4 main(float2 p) {"
558 "return c.eval(clamp(p, s.LT, s.RB));"
559 "}");
560
561 auto fp = Make(shader->shader().get(), args, mRec.applied());
562 if (!fp) {
563 return nullptr;
564 }
565
567 if (fp->compatibleWithCoverageAsAlpha()) {
569 }
570 if (fp->preservesOpaqueInput()) {
572 }
573 fp = GrSkSLFP::Make(effect,
574 "clamp_fp",
575 /*inputFP=*/nullptr,
576 flags,
577 "c",
578 std::move(fp),
579 "s",
580 shader->subset());
581
582 auto [total, ok] = mRec.applyForFragmentProcessor({});
583 if (!ok) {
584 return nullptr;
585 }
586 return GrMatrixEffect::Make(total, std::move(fp));
587}
static std::unique_ptr< GrFragmentProcessor > Make(const SkMatrix &matrix, std::unique_ptr< GrFragmentProcessor > child)
sk_sp< SkShader > shader() const
MatrixRec applied() const
std::tuple< SkMatrix, bool > applyForFragmentProcessor(const SkMatrix &postInv) const
FlutterSemanticsFlag flags

◆ make_shader_fp() [6/16]

static std::unique_ptr< GrFragmentProcessor > GrFragmentProcessors::make_shader_fp ( const SkCTMShader shader,
const GrFPArgs args,
const SkShaders::MatrixRec mRec 
)
static

Definition at line 589 of file GrFragmentProcessors.cpp.

591 {
592 SkMatrix ctmInv;
593 if (!shader->ctm().invert(&ctmInv)) {
594 return nullptr;
595 }
596
597 auto base = Make(shader->proxyShader().get(), args, shader->ctm());
598 if (!base) {
599 return nullptr;
600 }
601
602 // In order for the shader to be evaluated with the original CTM, we explicitly evaluate it
603 // at sk_FragCoord, and pass that through the inverse of the original CTM. This avoids requiring
604 // local coords for the shader and mapping from the draw's local to device and then back.
606}
static std::unique_ptr< GrFragmentProcessor > DeviceSpace(std::unique_ptr< GrFragmentProcessor >)
const SkMatrix & ctm() const
sk_sp< SkShader > proxyShader() const
bool invert(SkMatrix *inverse) const
Definition SkMatrix.h:1206

◆ make_shader_fp() [7/16]

static std::unique_ptr< GrFragmentProcessor > GrFragmentProcessors::make_shader_fp ( const SkEmptyShader shader,
const GrFPArgs ,
const SkShaders::MatrixRec  
)
static

Definition at line 608 of file GrFragmentProcessors.cpp.

610 {
611 return nullptr;
612}

◆ make_shader_fp() [8/16]

static std::unique_ptr< GrFragmentProcessor > GrFragmentProcessors::make_shader_fp ( const SkGradientBaseShader shader,
const GrFPArgs args,
const SkShaders::MatrixRec mRec 
)
static

Definition at line 1083 of file GrFragmentProcessors.cpp.

1085 {
1086 SkASSERT(shader);
1087
1088 switch (shader->asGradient()) {
1089#define M(type) \
1090 case SkShaderBase::GradientType::k##type: \
1091 return make_gradient_fp(static_cast<const Sk##type##Gradient*>(shader), args, mRec);
1093#undef M
1095 SkDEBUGFAIL("Gradient shader says its type is none");
1096 return nullptr;
1097 }
1099}
#define SK_ALL_GRADIENTS(M)
virtual GradientType asGradient(GradientInfo *info=nullptr, SkMatrix *localMatrix=nullptr) const

◆ make_shader_fp() [9/16]

static std::unique_ptr< GrFragmentProcessor > GrFragmentProcessors::make_shader_fp ( const SkImageShader shader,
const GrFPArgs args,
const SkShaders::MatrixRec mRec 
)
static

Definition at line 618 of file GrFragmentProcessors.cpp.

620 {
621 SkTileMode tileModes[2] = {shader->tileModeX(), shader->tileModeY()};
622 const SkRect shaderSubset = shader->subset();
623 const SkRect* subset = needs_subset(shader->image(), shaderSubset) ? &shaderSubset : nullptr;
625 args.fContext, shader->image(), shader->sampling(), tileModes, SkMatrix::I(), subset);
626 if (!fp) {
627 return nullptr;
628 }
629
630 auto [total, ok] = mRec.applyForFragmentProcessor({});
631 if (!ok) {
632 return nullptr;
633 }
634 fp = GrMatrixEffect::Make(total, std::move(fp));
635
636 if (!shader->isRaw()) {
637 fp = GrColorSpaceXformEffect::Make(std::move(fp),
638 shader->image()->colorSpace(),
639 shader->image()->alphaType(),
640 args.fDstColorInfo->colorSpace(),
642
643 // Alpha-only image shaders are tinted by the input color (typically the paint color).
644 // We suppress that behavior when sampled from a runtime effect.
645 if (shader->image()->isAlphaOnly() && args.fScope != GrFPArgs::Scope::kRuntimeEffect) {
646 fp = GrBlendFragmentProcessor::Make<SkBlendMode::kDstIn>(std::move(fp), nullptr);
647 }
648 }
649
650 return fp;
651}
SkTileMode
Definition SkTileMode.h:13
SkSamplingOptions sampling() const
SkTileMode tileModeX() const
sk_sp< SkImage > image() const
bool isRaw() const
SkTileMode tileModeY() const
SkRect subset() const
bool isAlphaOnly() const
Definition SkImage.cpp:239
SkColorSpace * colorSpace() const
Definition SkImage.cpp:156
SkAlphaType alphaType() const
Definition SkImage.cpp:154
static const SkMatrix & I()
std::unique_ptr< GrFragmentProcessor > AsFragmentProcessor(GrRecordingContext *rContext, const SkImage *img, SkSamplingOptions sampling, const SkTileMode tileModes[2], const SkMatrix &m, const SkRect *subset, const SkRect *domain)

◆ make_shader_fp() [10/16]

static std::unique_ptr< GrFragmentProcessor > GrFragmentProcessors::make_shader_fp ( const SkLocalMatrixShader shader,
const GrFPArgs args,
const SkShaders::MatrixRec mRec 
)
static

Definition at line 653 of file GrFragmentProcessors.cpp.

655 {
656 return Make(shader->wrappedShader().get(), args, mRec.concat(shader->localMatrix()));
657}
const SkMatrix & localMatrix() const
sk_sp< SkShader > wrappedShader() const
MatrixRec concat(const SkMatrix &m) const

◆ make_shader_fp() [11/16]

static std::unique_ptr< GrFragmentProcessor > GrFragmentProcessors::make_shader_fp ( const SkPerlinNoiseShader shader,
const GrFPArgs args,
const SkShaders::MatrixRec mRec 
)
static

Definition at line 659 of file GrFragmentProcessors.cpp.

661 {
662 SkASSERT(args.fContext);
663 SkASSERT(shader->numOctaves());
664
665 // Either we don't stitch tiles, or we have a valid tile size
666 SkASSERT(!shader->stitchTiles() || !shader->tileSize().isEmpty());
667
668 auto paintingData = shader->getPaintingData();
669 paintingData->generateBitmaps();
670
671 GrRecordingContext* context = args.fContext;
672
673 const SkBitmap& permutationsBitmap = paintingData->getPermutationsBitmap();
674 const SkBitmap& noiseBitmap = paintingData->getNoiseBitmap();
675
676 auto permutationsView = std::get<0>(GrMakeCachedBitmapProxyView(
677 context,
678 permutationsBitmap,
679 /*label=*/"PerlinNoiseShader_FragmentProcessor_PermutationsView"));
680
681 auto noiseView = std::get<0>(GrMakeCachedBitmapProxyView(
682 context, noiseBitmap, /*label=*/"PerlinNoiseShader_FragmentProcessor_NoiseView"));
683
684 if (!permutationsView || !noiseView) {
685 return nullptr;
686 }
687
688 std::unique_ptr<GrFragmentProcessor> fp =
690 shader->numOctaves(),
691 shader->stitchTiles(),
692 std::move(paintingData),
693 std::move(permutationsView),
694 std::move(noiseView),
695 *context->priv().caps());
696 if (!fp) {
697 return nullptr;
698 }
699 auto [total, ok] = mRec.applyForFragmentProcessor({});
700 if (!ok) {
701 return nullptr;
702 }
703 return GrMatrixEffect::Make(total, std::move(fp));
704}
std::tuple< GrSurfaceProxyView, GrColorType > GrMakeCachedBitmapProxyView(GrRecordingContext *rContext, const SkBitmap &bitmap, std::string_view label, skgpu::Mipmapped mipmapped)
Definition SkGr.cpp:188
static std::unique_ptr< GrFragmentProcessor > Make(SkPerlinNoiseShaderType type, int numOctaves, bool stitchTiles, std::unique_ptr< SkPerlinNoiseShader::PaintingData > paintingData, GrSurfaceProxyView permutationsView, GrSurfaceProxyView noiseView, const GrCaps &caps)
SkPerlinNoiseShaderType noiseType() const
std::unique_ptr< PaintingData > getPaintingData() const
bool isEmpty() const
Definition SkSize.h:31

◆ make_shader_fp() [12/16]

static std::unique_ptr< GrFragmentProcessor > GrFragmentProcessors::make_shader_fp ( const SkPictureShader shader,
const GrFPArgs args,
const SkShaders::MatrixRec mRec 
)
static

Definition at line 706 of file GrFragmentProcessors.cpp.

708 {
709 auto ctx = args.fContext;
710 SkColorType dstColorType = GrColorTypeToSkColorType(args.fDstColorInfo->colorType());
711 if (dstColorType == kUnknown_SkColorType) {
712 dstColorType = kRGBA_8888_SkColorType;
713 }
715 if (args.fDstColorInfo->colorSpace()) {
716 dstCS = sk_ref_sp(args.fDstColorInfo->colorSpace());
717 }
718
720 mRec.totalMatrix(),
721 dstColorType,
722 dstCS.get(),
723 ctx->priv().caps()->maxTextureSize(),
724 args.fSurfaceProps);
725 if (!info.success) {
726 return nullptr;
727 }
728
729 // Gotta be sure the GPU can support our requested colortype (might be FP16)
730 if (!ctx->colorTypeSupportedAsSurface(info.imageInfo.colorType())) {
731 info.imageInfo = info.imageInfo.makeColorType(kRGBA_8888_SkColorType);
732 }
733
736 std::tuple keyData = {dstCS->toXYZD50Hash(),
737 dstCS->transferFnHash(),
738 static_cast<uint32_t>(dstColorType),
739 shader->picture()->uniqueID(),
740 shader->tile(),
741 info.tileScale,
742 info.props};
744 &key, kDomain, sizeof(keyData) / sizeof(uint32_t), "Picture Shader Image");
745 memcpy(&builder[0], &keyData, sizeof(keyData));
746 builder.finish();
747
748 GrProxyProvider* provider = ctx->priv().proxyProvider();
750 if (auto proxy = provider->findOrCreateProxyByUniqueKey(key)) {
752 } else {
753 const int msaaSampleCount = 0;
754 const bool createWithMips = false;
755 const bool kUnprotected = false;
756 auto image = info.makeImage(SkSurfaces::RenderTarget(ctx,
758 info.imageInfo,
759 msaaSampleCount,
761 &info.props,
762 createWithMips,
763 kUnprotected),
764 shader->picture().get());
765 if (!image) {
766 return nullptr;
767 }
768
769 auto [v, ct] = skgpu::ganesh::AsView(ctx, image, skgpu::Mipmapped::kNo);
770 view = std::move(v);
771 provider->assignUniqueKeyToProxy(key, view.asTextureProxy());
772 }
773
774 const GrSamplerState sampler(static_cast<GrSamplerState::WrapMode>(shader->tileModeX()),
775 static_cast<GrSamplerState::WrapMode>(shader->tileModeY()),
776 shader->filter());
778 std::move(view), kPremul_SkAlphaType, SkMatrix::I(), sampler, *ctx->priv().caps());
779 SkMatrix scale = SkMatrix::Scale(info.tileScale.width(), info.tileScale.height());
780 auto [total, ok] = mRec.applyForFragmentProcessor(scale);
781 if (!ok) {
782 return nullptr;
783 }
784 return GrMatrixEffect::Make(total, std::move(fp));
785}
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition DM.cpp:213
static constexpr SkColorType GrColorTypeToSkColorType(GrColorType ct)
@ kTopLeft_GrSurfaceOrigin
Definition GrTypes.h:148
SkColorType
Definition SkColorType.h:19
@ kRGBA_8888_SkColorType
pixel with 8 bits for red, green, blue, alpha; in 32-bit word
Definition SkColorType.h:24
@ kUnknown_SkColorType
uninitialized
Definition SkColorType.h:20
sk_sp< T > sk_ref_sp(T *obj)
Definition SkRefCnt.h:381
bool assignUniqueKeyToProxy(const skgpu::UniqueKey &, GrTextureProxy *)
sk_sp< GrTextureProxy > findOrCreateProxyByUniqueKey(const skgpu::UniqueKey &, UseAllocator=UseAllocator::kYes)
GrTextureProxy * asTextureProxy() const
static std::unique_ptr< GrFragmentProcessor > Make(GrSurfaceProxyView, SkAlphaType, const SkMatrix &=SkMatrix::I(), GrSamplerState::Filter=GrSamplerState::Filter::kNearest, GrSamplerState::MipmapMode mipmapMode=GrSamplerState::MipmapMode::kNone)
static SkMatrix Scale(SkScalar sx, SkScalar sy)
Definition SkMatrix.h:75
SkRect tile() const
SkTileMode tileModeY() const
SkTileMode tileModeX() const
SkFilterMode filter() const
sk_sp< SkPicture > picture() const
uint32_t uniqueID() const
Definition SkPicture.h:155
SkMatrix totalMatrix() const
static Domain GenerateDomain()
sk_sp< SkImage > image
Definition examples.cpp:29
SK_API sk_sp< SkSurface > RenderTarget(GrRecordingContext *context, skgpu::Budgeted budgeted, const SkImageInfo &imageInfo, int sampleCount, GrSurfaceOrigin surfaceOrigin, const SkSurfaceProps *surfaceProps, bool shouldCreateWithMips=false, bool isProtected=false)
std::tuple< GrSurfaceProxyView, GrColorType > AsView(GrRecordingContext *rContext, const SkImage *img, skgpu::Mipmapped mipmapped, GrImageTexGenPolicy policy)
const Scalar scale
static CachedImageInfo Make(const SkRect &bounds, const SkMatrix &totalM, SkColorType dstColorType, SkColorSpace *dstColorSpace, const int maxTextureSize, const SkSurfaceProps &propsIn)

◆ make_shader_fp() [13/16]

static std::unique_ptr< GrFragmentProcessor > GrFragmentProcessors::make_shader_fp ( const SkRuntimeShader shader,
const GrFPArgs args,
const SkShaders::MatrixRec mRec 
)
static

Definition at line 787 of file GrFragmentProcessors.cpp.

789 {
790 if (!SkRuntimeEffectPriv::CanDraw(args.fContext->priv().caps(), shader->asRuntimeEffect())) {
791 return nullptr;
792 }
793
795 shader->asRuntimeEffect()->uniforms(),
796 shader->uniformData(args.fDstColorInfo->colorSpace()),
797 args.fDstColorInfo->colorSpace());
798 SkASSERT(uniforms);
799
800 bool success;
801 std::unique_ptr<GrFragmentProcessor> fp;
802 GrFPArgs childArgs(
803 args.fContext, args.fDstColorInfo, args.fSurfaceProps, GrFPArgs::Scope::kRuntimeEffect);
804 std::tie(success, fp) = make_effect_fp(shader->effect(),
805 "runtime_shader",
806 std::move(uniforms),
807 /*inputFP=*/nullptr,
808 /*destColorFP=*/nullptr,
809 shader->children(),
810 childArgs);
811 if (!success) {
812 return nullptr;
813 }
814
815 auto [total, ok] = mRec.applyForFragmentProcessor({});
816 if (!ok) {
817 return nullptr;
818 }
819 return GrMatrixEffect::Make(total, std::move(fp));
820}
SkSpan< const SkRuntimeEffect::ChildPtr > children() const
sk_sp< const SkData > uniformData(const SkColorSpace *dstCS) const
sk_sp< SkRuntimeEffect > effect() const
SkRuntimeEffect * asRuntimeEffect() const override

◆ make_shader_fp() [14/16]

static std::unique_ptr< GrFragmentProcessor > GrFragmentProcessors::make_shader_fp ( const SkTransformShader shader,
const GrFPArgs ,
const SkShaders::MatrixRec  
)
static

Definition at line 822 of file GrFragmentProcessors.cpp.

824 {
825 return nullptr;
826}

◆ make_shader_fp() [15/16]

static std::unique_ptr< GrFragmentProcessor > GrFragmentProcessors::make_shader_fp ( const SkTriColorShader shader,
const GrFPArgs ,
const SkShaders::MatrixRec  
)
static

Definition at line 828 of file GrFragmentProcessors.cpp.

830 {
831 return nullptr;
832}

◆ make_shader_fp() [16/16]

static std::unique_ptr< GrFragmentProcessor > GrFragmentProcessors::make_shader_fp ( const SkWorkingColorSpaceShader shader,
const GrFPArgs args,
const SkShaders::MatrixRec mRec 
)
static

Definition at line 834 of file GrFragmentProcessors.cpp.

836 {
837 const GrColorInfo* dstInfo = args.fDstColorInfo;
838 sk_sp<SkColorSpace> dstCS = dstInfo->refColorSpace();
839 if (!dstCS) {
840 dstCS = SkColorSpace::MakeSRGB();
841 }
842
843 GrColorInfo dst = {dstInfo->colorType(), dstInfo->alphaType(), dstCS},
844 working = {dstInfo->colorType(), dstInfo->alphaType(), shader->workingSpace()};
845 GrFPArgs workingArgs(args.fContext, &working, args.fSurfaceProps, args.fScope);
846
847 auto childFP = Make(shader->shader().get(), workingArgs, mRec);
848 if (!childFP) {
849 return nullptr;
850 }
851
852 auto childWithWorkingInput = GrFragmentProcessor::Compose(
853 std::move(childFP), GrColorSpaceXformEffect::Make(nullptr, dst, working));
854
855 return GrColorSpaceXformEffect::Make(std::move(childWithWorkingInput), working, dst);
856}
static std::unique_ptr< GrFragmentProcessor > Compose(std::unique_ptr< GrFragmentProcessor > f, std::unique_ptr< GrFragmentProcessor > g)
sk_sp< SkShader > shader() const
sk_sp< SkColorSpace > workingSpace() const

◆ MakeChildFP()

GrFPResult GrFragmentProcessors::MakeChildFP ( const SkRuntimeEffect::ChildPtr child,
const GrFPArgs childArgs 
)

Returns a GrFragmentProcessor for the passed-in runtime effect child. The processor will be created with generic/null inputs, since the runtime effect is responsible for filling in the arguments to the function.

Definition at line 154 of file GrFragmentProcessors.cpp.

154 {
155 std::optional<ChildType> type = child.type();
156 if (!type.has_value()) {
157 // We have a null child effect.
158 return GrFPNullableSuccess(nullptr);
159 }
160
161 switch (*type) {
162 case ChildType::kShader: {
163 // Convert a SkShader into a child FP.
165 mRec.markTotalMatrixInvalid();
166 auto childFP = GrFragmentProcessors::Make(child.shader(), childArgs, mRec);
167 return childFP ? GrFPSuccess(std::move(childFP))
168 : GrFPFailure(nullptr);
169 }
170 case ChildType::kColorFilter: {
171 // Convert a SkColorFilter into a child FP.
172 auto [success, childFP] = GrFragmentProcessors::Make(childArgs.fContext,
173 child.colorFilter(),
174 /*inputFP=*/nullptr,
175 *childArgs.fDstColorInfo,
176 childArgs.fSurfaceProps);
177 return success ? GrFPSuccess(std::move(childFP))
178 : GrFPFailure(nullptr);
179 }
180 case ChildType::kBlender: {
181 // Convert a SkBlender into a child FP.
182 auto childFP = GrFragmentProcessors::Make(as_BB(child.blender()),
183 /*srcFP=*/nullptr,
185 childArgs);
186 return childFP ? GrFPSuccess(std::move(childFP))
187 : GrFPFailure(nullptr);
188 }
189 }
190
192}
static GrFPResult GrFPNullableSuccess(std::unique_ptr< GrFragmentProcessor > fp)
SkBlenderBase * as_BB(SkBlender *blend)
static std::unique_ptr< GrFragmentProcessor > DestColor()
SkBlender * blender() const
std::optional< ChildType > type() const
SkColorFilter * colorFilter() const
std::unique_ptr< GrFragmentProcessor > Make(const SkMaskFilter *maskfilter, const GrFPArgs &args, const SkMatrix &ctm)

◆ map_color()

static SkPMColor4f GrFragmentProcessors::map_color ( const SkColor4f c,
SkColorSpace src,
SkColorSpace dst 
)
static

Definition at line 279 of file GrFragmentProcessors.cpp.

279 {
280 SkPMColor4f color = {c.fR, c.fG, c.fB, c.fA};
282 return color;
283}
void apply(float rgba[4]) const

◆ needs_subset()

static bool GrFragmentProcessors::needs_subset ( sk_sp< const SkImage img,
const SkRect subset 
)
static

Definition at line 614 of file GrFragmentProcessors.cpp.

614 {
615 return subset != SkRect::Make(img->dimensions());
616}
SkISize dimensions() const
Definition SkImage.h:297
static SkRect Make(const SkISize &size)
Definition SkRect.h:669

◆ rgb_to_hsl()

static std::unique_ptr< GrFragmentProcessor > GrFragmentProcessors::rgb_to_hsl ( std::unique_ptr< GrFragmentProcessor child)
static

Definition at line 372 of file GrFragmentProcessors.cpp.

372 {
373 static const SkRuntimeEffect* effect =
375 "half4 main(half4 color) {"
376 "return $rgb_to_hsl(color.rgb, color.a);"
377 "}");
379 return GrSkSLFP::Make(
380 effect, "RgbToHsl", std::move(child), GrSkSLFP::OptFlags::kPreservesOpaqueInput);
381}