Add SkBlender class; thread into SkVMBlitter.
Like SkColorFilter, SkShader, etc., this has a public-facing component (SkBlender) and a private subclass (SkBlenderBase) which can be obtained via a helper function (as_BB). At present there are no public- facing methods, but the type needs to be exposed to be usable by the outside world. These classes exist for SkRuntimeEffect to subclass. The blender base provides a `program` method with the parameters that blending will use. Change-Id: I75c772fd4108a9c21fbda84201a8b23d3750a0df Bug: skia:12080 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/416916 Auto-Submit: John Stiles <johnstiles@google.com> Commit-Queue: Brian Osman <brianosman@google.com> Reviewed-by: Brian Osman <brianosman@google.com>
This commit is contained in:
parent
3674f589ee
commit
2d8b835cad
@ -586,7 +586,7 @@ void RunSkSLMemoryBenchmarks(NanoJSONResultsWriter* log) {
|
||||
SkSL::Compiler compiler(&caps);
|
||||
compiler.moduleForProgramKind(SkSL::ProgramKind::kRuntimeColorFilter);
|
||||
compiler.moduleForProgramKind(SkSL::ProgramKind::kRuntimeShader);
|
||||
compiler.moduleForProgramKind(SkSL::ProgramKind::kRuntimeBlendFilter);
|
||||
compiler.moduleForProgramKind(SkSL::ProgramKind::kRuntimeBlender);
|
||||
int after = heap_bytes_used();
|
||||
bench("sksl_compiler_runtimeeffect", after - before);
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ skia_core_public = [
|
||||
"$_include/core/SkAnnotation.h",
|
||||
"$_include/core/SkBBHFactory.h",
|
||||
"$_include/core/SkBitmap.h",
|
||||
"$_include/core/SkBlender.h",
|
||||
"$_include/core/SkBlendMode.h",
|
||||
"$_include/core/SkBlurTypes.h",
|
||||
"$_include/core/SkCanvas.h",
|
||||
@ -125,6 +126,7 @@ skia_core_sources = [
|
||||
"$_src/core/SkBitmapProcState.h",
|
||||
"$_src/core/SkBitmapProcState_matrixProcs.cpp",
|
||||
"$_src/core/SkBlendMode.cpp",
|
||||
"$_src/core/SkBlenderBase.h",
|
||||
"$_src/core/SkBlitBWMaskTemplate.h",
|
||||
"$_src/core/SkBlitRow.h",
|
||||
"$_src/core/SkBlitRow_D32.cpp",
|
||||
@ -163,6 +165,7 @@ skia_core_sources = [
|
||||
"$_src/core/SkCubicClipper.cpp",
|
||||
"$_src/core/SkCubicClipper.h",
|
||||
"$_src/core/SkCubicMap.cpp",
|
||||
"$_src/core/SkCubicSolver.h",
|
||||
"$_src/core/SkData.cpp",
|
||||
"$_src/core/SkDataTable.cpp",
|
||||
"$_src/core/SkDebug.cpp",
|
||||
|
26
include/core/SkBlender.h
Normal file
26
include/core/SkBlender.h
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright 2021 Google LLC
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkBlender_DEFINED
|
||||
#define SkBlender_DEFINED
|
||||
|
||||
#include "include/core/SkFlattenable.h"
|
||||
|
||||
/**
|
||||
* SkBlender represents a custom blend function in the Skia pipeline. When an SkBlender is
|
||||
* present in a paint, the SkBlendMode is ignored. A blender combines a source color (the
|
||||
* result of our paint) and destination color (from the canvas) into a final color.
|
||||
*/
|
||||
class SK_API SkBlender : public SkFlattenable {
|
||||
private:
|
||||
SkBlender() = default;
|
||||
friend class SkBlenderBase;
|
||||
|
||||
using INHERITED = SkFlattenable;
|
||||
};
|
||||
|
||||
#endif
|
@ -27,8 +27,9 @@ class SK_API SkFlattenable : public SkRefCnt {
|
||||
public:
|
||||
enum Type {
|
||||
kSkColorFilter_Type,
|
||||
kSkBlender_Type,
|
||||
kSkDrawable_Type,
|
||||
kSkDrawLooper_Type, // no longer used internally by Skia
|
||||
kSkDrawLooper_Type, // no longer used internally by Skia
|
||||
kSkImageFilter_Type,
|
||||
kSkMaskFilter_Type,
|
||||
kSkPathEffect_Type,
|
||||
|
@ -204,7 +204,7 @@ private:
|
||||
kUsesSampleCoords_Flag = 0x1,
|
||||
kAllowColorFilter_Flag = 0x2,
|
||||
kAllowShader_Flag = 0x4,
|
||||
kAllowBlendFilter_Flag = 0x8,
|
||||
kAllowBlender_Flag = 0x8,
|
||||
};
|
||||
|
||||
SkRuntimeEffect(SkString sksl,
|
||||
@ -227,7 +227,7 @@ private:
|
||||
bool usesSampleCoords() const { return (fFlags & kUsesSampleCoords_Flag); }
|
||||
bool allowShader() const { return (fFlags & kAllowShader_Flag); }
|
||||
bool allowColorFilter() const { return (fFlags & kAllowColorFilter_Flag); }
|
||||
bool allowBlendFilter() const { return (fFlags & kAllowBlendFilter_Flag); }
|
||||
bool allowBlender() const { return (fFlags & kAllowBlender_Flag); }
|
||||
|
||||
const SkFilterColorProgram* getFilterColorProgram();
|
||||
|
||||
|
@ -22,7 +22,7 @@ enum class ProgramKind : int8_t {
|
||||
kFragmentProcessor,
|
||||
kRuntimeColorFilter, // Runtime effect only suitable as SkColorFilter
|
||||
kRuntimeShader, // " " " " " SkShader
|
||||
kRuntimeBlendFilter, // " " " " " SkBlendFilter
|
||||
kRuntimeBlender, // " " " " " SkBlender
|
||||
kGeneric,
|
||||
};
|
||||
|
||||
|
52
src/core/SkBlenderBase.h
Normal file
52
src/core/SkBlenderBase.h
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 2021 Google LLC
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkBlenderBase_DEFINED
|
||||
#define SkBlenderBase_DEFINED
|
||||
|
||||
#include "include/core/SkBlender.h"
|
||||
#include "include/core/SkColorSpace.h"
|
||||
#include "src/core/SkArenaAlloc.h"
|
||||
#include "src/core/SkVM.h"
|
||||
|
||||
/**
|
||||
* Encapsulates a custom blend function for Runtime Effects. These combine a source color (the
|
||||
* result of our paint) and destination color (from the canvas) into a final color.
|
||||
*/
|
||||
class SkBlenderBase : public SkBlender {
|
||||
public:
|
||||
SK_WARN_UNUSED_RESULT
|
||||
skvm::Color program(skvm::Builder* p, skvm::Color src, skvm::Color dst,
|
||||
const SkColorInfo& colorInfo, skvm::Uniforms* uniforms,
|
||||
SkArenaAlloc* alloc) const {
|
||||
return this->onProgram(p, src, dst, colorInfo, uniforms, alloc);
|
||||
}
|
||||
|
||||
static SkFlattenable::Type GetFlattenableType() { return kSkBlender_Type; }
|
||||
Type getFlattenableType() const override { return GetFlattenableType(); }
|
||||
|
||||
private:
|
||||
virtual skvm::Color onProgram(skvm::Builder* p, skvm::Color src, skvm::Color dst,
|
||||
const SkColorInfo& colorInfo, skvm::Uniforms* uniforms,
|
||||
SkArenaAlloc* alloc) const = 0;
|
||||
|
||||
using INHERITED = SkFlattenable;
|
||||
};
|
||||
|
||||
inline SkBlenderBase* as_BB(SkBlender* blend) {
|
||||
return static_cast<SkBlenderBase*>(blend);
|
||||
}
|
||||
|
||||
inline const SkBlenderBase* as_BB(const SkBlender* blend) {
|
||||
return static_cast<const SkBlenderBase*>(blend);
|
||||
}
|
||||
|
||||
inline const SkBlenderBase* as_BB(const sk_sp<SkBlender>& blend) {
|
||||
return static_cast<SkBlenderBase*>(blend.get());
|
||||
}
|
||||
|
||||
#endif // SkBlenderBase_DEFINED
|
@ -187,7 +187,7 @@ SkRuntimeEffect::Result SkRuntimeEffect::Make(SkString sksl,
|
||||
switch (kind) {
|
||||
case SkSL::ProgramKind::kRuntimeColorFilter: flags |= kAllowColorFilter_Flag; break;
|
||||
case SkSL::ProgramKind::kRuntimeShader: flags |= kAllowShader_Flag; break;
|
||||
case SkSL::ProgramKind::kRuntimeBlendFilter: flags |= kAllowBlendFilter_Flag; break;
|
||||
case SkSL::ProgramKind::kRuntimeBlender: flags |= kAllowBlender_Flag; break;
|
||||
default: SkUNREACHABLE;
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "include/private/SkMacros.h"
|
||||
#include "src/core/SkArenaAlloc.h"
|
||||
#include "src/core/SkBlendModePriv.h"
|
||||
#include "src/core/SkBlenderBase.h"
|
||||
#include "src/core/SkColorFilterBase.h"
|
||||
#include "src/core/SkColorSpacePriv.h"
|
||||
#include "src/core/SkColorSpaceXformSteps.h"
|
||||
@ -38,6 +39,7 @@ namespace {
|
||||
struct Params {
|
||||
sk_sp<SkShader> shader;
|
||||
sk_sp<SkShader> clip;
|
||||
sk_sp<SkBlender> blender;
|
||||
SkColorInfo dst;
|
||||
SkBlendMode blendMode;
|
||||
Coverage coverage;
|
||||
@ -55,6 +57,7 @@ namespace {
|
||||
struct Key {
|
||||
uint64_t shader,
|
||||
clip,
|
||||
blender,
|
||||
colorSpace;
|
||||
uint8_t colorType,
|
||||
alphaType,
|
||||
@ -66,13 +69,14 @@ namespace {
|
||||
// they'll be folded into the shader key if used.
|
||||
|
||||
bool operator==(const Key& that) const {
|
||||
return this->shader == that.shader
|
||||
&& this->clip == that.clip
|
||||
&& this->colorSpace == that.colorSpace
|
||||
&& this->colorType == that.colorType
|
||||
&& this->alphaType == that.alphaType
|
||||
&& this->blendMode == that.blendMode
|
||||
&& this->coverage == that.coverage;
|
||||
return this->shader == that.shader
|
||||
&& this->clip == that.clip
|
||||
&& this->blender == that.blender
|
||||
&& this->colorSpace == that.colorSpace
|
||||
&& this->colorType == that.colorType
|
||||
&& this->alphaType == that.alphaType
|
||||
&& this->blendMode == that.blendMode
|
||||
&& this->coverage == that.coverage;
|
||||
}
|
||||
|
||||
Key withCoverage(Coverage c) const {
|
||||
@ -84,15 +88,16 @@ namespace {
|
||||
SK_END_REQUIRE_DENSE;
|
||||
|
||||
static SkString debug_name(const Key& key) {
|
||||
return SkStringPrintf(
|
||||
"Shader-%" PRIx64 "_Clip-%" PRIx64 "_CS-%" PRIx64 "_CT-%d_AT-%d_Blend-%d_Cov-%d",
|
||||
key.shader,
|
||||
key.clip,
|
||||
key.colorSpace,
|
||||
key.colorType,
|
||||
key.alphaType,
|
||||
key.blendMode,
|
||||
key.coverage);
|
||||
return SkStringPrintf("Shader-%" PRIx64 "_Clip-%" PRIx64 "_Blender-%" PRIx64
|
||||
"_CS-%" PRIx64 "_CT-%d_AT-%d_Blend-%d_Cov-%d",
|
||||
key.shader,
|
||||
key.clip,
|
||||
key.blender,
|
||||
key.colorSpace,
|
||||
key.colorType,
|
||||
key.alphaType,
|
||||
key.blendMode,
|
||||
key.coverage);
|
||||
}
|
||||
|
||||
static SkLRUCache<Key, skvm::Program>* try_acquire_program_cache() {
|
||||
@ -119,6 +124,12 @@ namespace {
|
||||
};
|
||||
}
|
||||
|
||||
static skvm::Color dst_color(skvm::Builder* p, const Params& params) {
|
||||
skvm::PixelFormat dstFormat = skvm::SkColorType_to_PixelFormat(params.dst.colorType());
|
||||
skvm::Ptr dst_ptr = p->arg(SkColorTypeBytesPerPixel(params.dst.colorType()));
|
||||
return p->load(dstFormat, dst_ptr);
|
||||
}
|
||||
|
||||
// If build_program() can't build this program, cache_key() sets *ok to false.
|
||||
static Key cache_key(const Params& params,
|
||||
skvm::Uniforms* uniforms, SkArenaAlloc* alloc, bool* ok) {
|
||||
@ -127,7 +138,8 @@ namespace {
|
||||
g = uniforms->pushF(params.paint.fG),
|
||||
b = uniforms->pushF(params.paint.fB),
|
||||
a = uniforms->pushF(params.paint.fA);
|
||||
auto hash_shader = [&](const sk_sp<SkShader>& shader) {
|
||||
|
||||
auto hash_shader = [&](const sk_sp<SkShader>& shader, skvm::Color* outColor) {
|
||||
const SkShaderBase* sb = as_SB(shader);
|
||||
skvm::Builder p;
|
||||
|
||||
@ -140,16 +152,20 @@ namespace {
|
||||
};
|
||||
|
||||
uint64_t hash = 0;
|
||||
if (auto c = sb->program(&p,
|
||||
device,/*local=*/device, paint,
|
||||
params.matrices, /*localM=*/nullptr,
|
||||
params.dst, uniforms,alloc)) {
|
||||
*outColor = sb->program(&p, device, /*local=*/device, paint, params.matrices,
|
||||
/*localM=*/nullptr, params.dst, uniforms, alloc);
|
||||
if (*outColor) {
|
||||
hash = p.hash();
|
||||
// p.hash() folds in all instructions to produce r,g,b,a but does not know
|
||||
// precisely which value we'll treat as which channel. Imagine the shader
|
||||
// called std::swap(*r,*b)... it draws differently, but p.hash() is unchanged.
|
||||
// We'll fold the hash of their IDs in order to disambiguate.
|
||||
const skvm::Val outputs[] = { c.r.id, c.g.id, c.b.id, c.a.id };
|
||||
const skvm::Val outputs[] = {
|
||||
outColor->r.id,
|
||||
outColor->g.id,
|
||||
outColor->b.id,
|
||||
outColor->a.id
|
||||
};
|
||||
hash ^= SkOpts::hash(outputs, sizeof(outputs));
|
||||
} else {
|
||||
*ok = false;
|
||||
@ -157,20 +173,52 @@ namespace {
|
||||
return hash;
|
||||
};
|
||||
|
||||
// Calculate a hash for the color shader.
|
||||
SkASSERT(params.shader);
|
||||
uint64_t shaderHash = hash_shader(params.shader);
|
||||
skvm::Color src;
|
||||
uint64_t shaderHash = hash_shader(params.shader, &src);
|
||||
|
||||
// Calculate a hash for the clip shader, if one exists.
|
||||
uint64_t clipHash = 0;
|
||||
skvm::Color cov;
|
||||
if (params.clip) {
|
||||
clipHash = hash_shader(params.clip);
|
||||
clipHash = hash_shader(params.clip, &cov);
|
||||
if (clipHash == 0) {
|
||||
clipHash = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate a hash for the blend shader, if one exists.
|
||||
uint64_t blendHash = 0;
|
||||
if (params.blender) {
|
||||
const SkBlenderBase* blender = as_BB(params.blender);
|
||||
skvm::Builder p;
|
||||
|
||||
skvm::Color dst = dst_color(&p, params);
|
||||
skvm::Color outColor = blender->program(&p, src, dst, params.dst, uniforms, alloc);
|
||||
if (outColor) {
|
||||
blendHash = p.hash();
|
||||
// Like in `hash_shader` above, we must fold the color component IDs into our hash.
|
||||
const skvm::Val outputs[] = {
|
||||
outColor.r.id,
|
||||
outColor.g.id,
|
||||
outColor.b.id,
|
||||
outColor.a.id
|
||||
};
|
||||
blendHash ^= SkOpts::hash(outputs, sizeof(outputs));
|
||||
} else {
|
||||
*ok = false;
|
||||
}
|
||||
|
||||
if (blendHash == 0) {
|
||||
blendHash = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
shaderHash,
|
||||
clipHash,
|
||||
blendHash,
|
||||
params.dst.colorSpace() ? params.dst.colorSpace()->hash() : 0,
|
||||
SkToU8(params.dst.colorType()),
|
||||
SkToU8(params.dst.alphaType()),
|
||||
@ -196,7 +244,7 @@ namespace {
|
||||
skvm::Color paint = p->uniformColor(params.paint, uniforms);
|
||||
|
||||
// See note about arguments above: a SpriteShader will call p->arg() once during program().
|
||||
skvm::Color src = as_SB(params.shader)->program(p, device,/*local=*/device, paint,
|
||||
skvm::Color src = as_SB(params.shader)->program(p, device, /*local=*/device, paint,
|
||||
params.matrices, /*localM=*/nullptr,
|
||||
params.dst, uniforms, alloc);
|
||||
SkASSERT(src);
|
||||
@ -266,7 +314,7 @@ namespace {
|
||||
} break;
|
||||
}
|
||||
if (params.clip) {
|
||||
skvm::Color clip = as_SB(params.clip)->program(p, device,/*local=*/device, paint,
|
||||
skvm::Color clip = as_SB(params.clip)->program(p, device, /*local=*/device, paint,
|
||||
params.matrices, /*localM=*/nullptr,
|
||||
params.dst, uniforms, alloc);
|
||||
SkAssertResult(clip);
|
||||
@ -276,19 +324,25 @@ namespace {
|
||||
cov.a *= clip.a;
|
||||
}
|
||||
|
||||
// The math for some blend modes lets us fold coverage into src before the blend,
|
||||
// which is simpler than the canonical post-blend lerp().
|
||||
if (SkBlendMode_ShouldPreScaleCoverage(params.blendMode,
|
||||
// The math for some blend modes lets us fold coverage into src before the blend, which is
|
||||
// simpler than the canonical post-blend lerp().
|
||||
bool applyPostBlendCoverage = true;
|
||||
if (!params.blender &&
|
||||
SkBlendMode_ShouldPreScaleCoverage(params.blendMode,
|
||||
params.coverage == Coverage::MaskLCD16)) {
|
||||
applyPostBlendCoverage = false;
|
||||
src.r *= cov.r;
|
||||
src.g *= cov.g;
|
||||
src.b *= cov.b;
|
||||
src.a *= cov.a;
|
||||
}
|
||||
|
||||
src = blend(params.blendMode, src, dst);
|
||||
} else {
|
||||
src = blend(params.blendMode, src, dst);
|
||||
// Apply our blend function to the computed color.
|
||||
src = params.blender
|
||||
? as_BB(params.blender)->program(p, src, dst, params.dst, uniforms, alloc)
|
||||
: blend(params.blendMode, src, dst);
|
||||
|
||||
if (applyPostBlendCoverage) {
|
||||
src.r = lerp(dst.r, src.r, cov.r);
|
||||
src.g = lerp(dst.g, src.g, cov.g);
|
||||
src.b = lerp(dst.b, src.b, cov.b);
|
||||
@ -528,6 +582,7 @@ namespace {
|
||||
return {
|
||||
std::move(shader),
|
||||
std::move(clip),
|
||||
/*blender=*/nullptr,
|
||||
{ device.colorType(), device.alphaType(), device.refColorSpace() },
|
||||
blendMode,
|
||||
Coverage::Full, // Placeholder... withCoverage() will change as needed.
|
||||
|
@ -298,13 +298,13 @@ const ParsedModule& Compiler::loadRuntimeShaderModule() {
|
||||
return fRuntimeShaderModule;
|
||||
}
|
||||
|
||||
const ParsedModule& Compiler::loadRuntimeBlendFilterModule() {
|
||||
if (!fRuntimeBlendFilterModule.fSymbols) {
|
||||
fRuntimeBlendFilterModule = this->parseModule(
|
||||
ProgramKind::kRuntimeBlendFilter, MODULE_DATA(rt_blend), this->loadPublicModule());
|
||||
add_glsl_type_aliases(fRuntimeBlendFilterModule.fSymbols.get(), fContext->fTypes);
|
||||
const ParsedModule& Compiler::loadRuntimeBlenderModule() {
|
||||
if (!fRuntimeBlenderModule.fSymbols) {
|
||||
fRuntimeBlenderModule = this->parseModule(
|
||||
ProgramKind::kRuntimeBlender, MODULE_DATA(rt_blend), this->loadPublicModule());
|
||||
add_glsl_type_aliases(fRuntimeBlenderModule.fSymbols.get(), fContext->fTypes);
|
||||
}
|
||||
return fRuntimeBlendFilterModule;
|
||||
return fRuntimeBlenderModule;
|
||||
}
|
||||
|
||||
const ParsedModule& Compiler::moduleForProgramKind(ProgramKind kind) {
|
||||
@ -315,7 +315,7 @@ const ParsedModule& Compiler::moduleForProgramKind(ProgramKind kind) {
|
||||
case ProgramKind::kFragmentProcessor: return this->loadFPModule(); break;
|
||||
case ProgramKind::kRuntimeColorFilter: return this->loadRuntimeColorFilterModule(); break;
|
||||
case ProgramKind::kRuntimeShader: return this->loadRuntimeShaderModule(); break;
|
||||
case ProgramKind::kRuntimeBlendFilter: return this->loadRuntimeBlendFilterModule(); break;
|
||||
case ProgramKind::kRuntimeBlender: return this->loadRuntimeBlenderModule(); break;
|
||||
case ProgramKind::kGeneric: return this->loadPublicModule(); break;
|
||||
}
|
||||
SkUNREACHABLE;
|
||||
|
@ -208,7 +208,7 @@ private:
|
||||
const ParsedModule& loadPublicModule();
|
||||
const ParsedModule& loadRuntimeColorFilterModule();
|
||||
const ParsedModule& loadRuntimeShaderModule();
|
||||
const ParsedModule& loadRuntimeBlendFilterModule();
|
||||
const ParsedModule& loadRuntimeBlenderModule();
|
||||
|
||||
/** Verifies that @if and @switch statements were actually optimized away. */
|
||||
void verifyStaticTests(const Program& program);
|
||||
@ -248,7 +248,7 @@ private:
|
||||
ParsedModule fPublicModule; // [Root] + Public features
|
||||
ParsedModule fRuntimeColorFilterModule; // [Public] + Runtime shader decls
|
||||
ParsedModule fRuntimeShaderModule; // [Public] + Runtime color filter decls
|
||||
ParsedModule fRuntimeBlendFilterModule; // [Public] + Runtime blend filter decls
|
||||
ParsedModule fRuntimeBlenderModule; // [Public] + Runtime blender decls
|
||||
|
||||
// holds ModifiersPools belonging to the core includes for lifetime purposes
|
||||
ModifiersPool fCoreModifiers;
|
||||
|
@ -292,7 +292,7 @@ ResultCode processCommand(std::vector<SkSL::String>& args) {
|
||||
} else if (inputPath.ends_with(".fp")) {
|
||||
kind = SkSL::ProgramKind::kFragmentProcessor;
|
||||
} else if (inputPath.ends_with(".rtb")) {
|
||||
kind = SkSL::ProgramKind::kRuntimeBlendFilter;
|
||||
kind = SkSL::ProgramKind::kRuntimeBlender;
|
||||
} else if (inputPath.ends_with(".rtcf")) {
|
||||
kind = SkSL::ProgramKind::kRuntimeColorFilter;
|
||||
} else if (inputPath.ends_with(".rts")) {
|
||||
|
@ -46,7 +46,7 @@ void DSLFunction::init(const DSLType& returnType, const char* name,
|
||||
SkSL::ProgramKind kind = DSLWriter::Context().fConfig->fKind;
|
||||
if (isMain && (kind == ProgramKind::kRuntimeColorFilter ||
|
||||
kind == ProgramKind::kRuntimeShader ||
|
||||
kind == ProgramKind::kRuntimeBlendFilter ||
|
||||
kind == ProgramKind::kRuntimeBlender ||
|
||||
kind == ProgramKind::kFragmentProcessor)) {
|
||||
const SkSL::Type& type = param->fType.skslType();
|
||||
// We verify that the signature is fully correct later. For now, if this is an .fp
|
||||
|
@ -92,7 +92,7 @@ static bool check_parameters(const Context& context,
|
||||
ProgramKind kind = context.fConfig->fKind;
|
||||
if (isMain && (kind == ProgramKind::kRuntimeColorFilter ||
|
||||
kind == ProgramKind::kRuntimeShader ||
|
||||
kind == ProgramKind::kRuntimeBlendFilter ||
|
||||
kind == ProgramKind::kRuntimeBlender ||
|
||||
kind == ProgramKind::kFragmentProcessor)) {
|
||||
// We verify that the signature is fully correct later. For now, if this is an .fp or
|
||||
// runtime effect of any flavor, a float2 param is supposed to be the coords, and
|
||||
@ -178,7 +178,7 @@ static bool check_main_signature(const Context& context, int offset, const Type&
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ProgramKind::kRuntimeBlendFilter: {
|
||||
case ProgramKind::kRuntimeBlender: {
|
||||
// (half4|float4) main(half4|float4, half4|float4)
|
||||
if (!typeIsValidForColor(returnType)) {
|
||||
errors.error(offset, "'main' must return: 'vec4', 'float4', or 'half4'");
|
||||
|
Loading…
Reference in New Issue
Block a user