112 if (
type->isArray()) {
118 if (
type->hasPrecision() && !
type->highPrecision()) {
134 switch (
type.typeKind()) {
144 case ChildType::kBlender:
return "blender";
145 case ChildType::kColorFilter:
return "color filter";
146 case ChildType::kShader:
return "shader";
180 auto writableData = [&]() {
184 return data->writable_data();
187 for (
const auto& u : uniforms) {
188 if (u.flags & Flags::kColor_Flag) {
189 SkASSERT(u.type == Type::kFloat3 || u.type == Type::kFloat4);
191 float*
color = SkTAddOffset<float>(writableData(), u.offset);
192 if (u.type == Type::kFloat4) {
194 for (
int i = 0; i < u.count; ++i) {
203 for (
int i = 0; i < u.count; ++i) {
214 return data ? data : originalData;
221 fCompileRPProgramOnce([&] {
226 if (!(
fFlags & kDisableOptimization_Flag)) {
235 *fBaseProgram, fMain, debugTrace,
true);
237 debugTrace = &tempDebugTrace;
239 *fBaseProgram, fMain, debugTrace,
false);
242 *fBaseProgram, fMain,
nullptr,
false);
249 fRPProgram->dump(&stream,
true);
252 SkDebugf(
"----- RP unsupported -----\n\n");
257 return fRPProgram.get();
263 bool alwaysCopyIntoAlloc,
270 if (alwaysCopyIntoAlloc || originalData != transformedData) {
273 int numBytes = transformedData->size();
274 int numFloats = numBytes /
sizeof(float);
276 memcpy(uniformsInAlloc, transformedData->data(), numBytes);
277 return SkSpan{uniformsInAlloc, numFloats};
280 return SkSpan{
static_cast<const float*
>(originalData->data()),
281 originalData->size() /
sizeof(float)};
285 if (
SkShader* shader = fChildren[index].shader()) {
286 if (fSampleUsages[index].isPassThrough()) {
300 if (
SkColorFilter* colorFilter = fChildren[index].colorFilter()) {
307 if (
SkBlender* blender = fChildren[index].blender()) {
311 fStage.fPipeline->append(SkRasterPipelineOp::srcover);
321 if (xform.flags.mask()) {
323 this->applyColorSpaceXform(xform,
color);
332 if (xform.flags.mask()) {
334 this->applyColorSpaceXform(xform,
color);
345 fStage.fPipeline->append(SkRasterPipelineOp::exchange_src,
color);
349 fStage.fPipeline->append(SkRasterPipelineOp::exchange_src,
color);
360 return CanDraw(caps, effect->fBaseProgram.get());
366 if (!f) {
return true; }
367 switch (f->getFlattenableType()) {
384 if (reflected.size() != effectPtrs.
size()) {
389 for (
size_t i = 0; i < effectPtrs.
size(); ++i) {
390 std::optional<ChildType> effectType = effectPtrs[i].type();
391 if (effectType && effectType != reflected[i].
type) {
406 size_t childCount =
buffer.read32();
407 if (effect && !
buffer.validate(childCount == effect->
children().size())) {
412 children->reserve_exact(childCount);
414 for (
size_t i = 0; i < childCount; i++) {
420 children->push_back(std::move(obj));
425 auto childInfo = effect->
children();
427 for (
size_t i = 0; i < childCount; i++) {
428 std::optional<ChildType> ct = (*children)[i].type();
429 if (ct.has_value() && (*ct) != childInfo[i].type) {
441 for (
const auto& child :
children) {
442 buffer.writeFlattenable(child.flattenable());
448 settings.fInlineThreshold = 0;
449 settings.fForceNoInline =
options.forceUnoptimized;
450 settings.fOptimize = !
options.forceUnoptimized;
451 settings.fMaxVersionAllowed =
options.maxVersionAllowed;
459 settings.fUseMemoryPool =
false;
465#define RETURN_FAILURE(...) return Result{nullptr, SkStringPrintf(__VA_ARGS__)}
472 std::unique_ptr<SkSL::Program> program =
479 return MakeInternal(std::move(program),
options, kind);
498 flags |= kAllowColorFilter_Flag;
502 flags |= kAllowShader_Flag;
506 flags |= kAllowBlender_Flag;
512 if (
options.forceUnoptimized) {
513 flags |= kDisableOptimization_Flag;
524 coordsParam ? program->usage()->get(*coordsParam)
527 if (sampleCoordsUsage.
fRead || sampleCoordsUsage.
fWrite) {
528 flags |= kUsesSampleCoords_Flag;
534 if (
flags & (kAllowColorFilter_Flag | kAllowBlender_Flag)) {
540 flags |= kSamplesOutsideMain_Flag;
546 if (
flags & kAllowColorFilter_Flag) {
548 flags |= kAlphaUnchanged_Flag;
555 flags |= kUsesColorTransform_Flag;
560 flags |= kAlwaysOpaque_Flag;
567 std::vector<SkSL::SampleUsage> sampleUsages;
568 int elidedSampleCoords = 0;
579 if (var.type().isEffectChild()) {
582 *program, var, sampleCoordsUsage.
fWrite != 0, &elidedSampleCoords);
587 sampleUsages.push_back(
usage.isSampled() ?
usage
588 :
SkSL::SampleUsage::PassThrough());
591 else if (var.modifierFlags().isUniform()) {
601 if (elidedSampleCoords == sampleCoordsUsage.
fRead && sampleCoordsUsage.
fWrite == 0) {
602 flags &= ~kUsesSampleCoords_Flag;
612 std::move(sampleUsages),
614 return Result{std::move(effect),
SkString()};
622 options.forceUnoptimized =
true;
624 options.allowPrivateAccess =
true;
634 std::unique_ptr<SkSL::Program> program =
635 compiler.convertProgram(kind, *fBaseProgram->fSource, settings);
648 SkDEBUGFAILF(
"makeUnoptimizedClone: MakeInternal failed\n%s",
649 result.errorText.c_str());
659 auto result = MakeFromSource(std::move(sksl),
options, programKind);
667 auto result = MakeFromSource(std::move(sksl),
options, programKind);
675 auto result = MakeFromSource(std::move(sksl),
options, programKind);
697 auto [effect, err] =
make(std::move(sksl),
options);
706 cache->insert_or_update(
key, effect);
731 static_assert(
sizeof(
int) ==
sizeof(
float));
735SkRuntimeEffect::SkRuntimeEffect(std::unique_ptr<SkSL::Program> baseProgram,
740 std::vector<SkSL::SampleUsage>&& sampleUsages,
742 : fHash(
SkChecksum::Hash32(baseProgram->fSource->c_str(), baseProgram->fSource->size()))
743 , fStableKey(
options.fStableKey)
744 , fBaseProgram(
std::move(baseProgram))
748 , fSampleUsages(
std::move(sampleUsages))
751 SkASSERT(fChildren.size() == fSampleUsages.size());
757 struct KnownOptions {
758 bool forceUnoptimized, allowPrivateAccess;
762 static_assert(
sizeof(Options) ==
sizeof(KnownOptions));
764 sizeof(
options.forceUnoptimized), fHash);
766 sizeof(
options.allowPrivateAccess), fHash);
768 sizeof(
options.fStableKey), fHash);
770 sizeof(
options.maxVersionAllowed), fHash);
776 return *fBaseProgram->fSource;
780 return fUniforms.empty() ? 0
781 :
SkAlign4(fUniforms.back().offset + fUniforms.back().sizeInBytes());
785 auto iter = std::find_if(fUniforms.begin(), fUniforms.end(), [
name](
const Uniform& u) {
786 return u.name == name;
788 return iter == fUniforms.end() ? nullptr : &(*iter);
792 auto iter = std::find_if(fChildren.begin(), fChildren.end(), [
name](
const Child& c) {
793 return c.name == name;
795 return iter == fChildren.end() ? nullptr : &(*iter);
811 if (!uniformsCallback) {
814 return SkLocalMatrixShader::MakeWrapped<SkRuntimeShader>(localMatrix,
817 std::move(uniformsCallback),
824 const SkMatrix* localMatrix)
const {
826 for (
size_t i = 0; i < childCount; ++i) {
827 children.emplace_back(childShaders[i]);
834 const SkMatrix* localMatrix)
const {
844 if (
uniforms->size() != this->uniformSize()) {
847 return SkLocalMatrixShader::MakeWrapped<SkRuntimeShader>(localMatrix,
856 size_t childCount)
const {
858 for (
size_t i = 0; i < childCount; ++i) {
859 children.emplace_back(childColorFilters[i]);
875 if (
uniforms->size() != this->uniformSize()) {
896 if (
uniforms->size() != this->uniformSize()) {
919 switch (fChild->getFlattenableType()) {
921 return ChildType::kShader;
923 return ChildType::kColorFilter;
925 return ChildType::kBlender;
935 ?
static_cast<SkShader*
>(fChild.get())
enum skgpu::ganesh::@8087::DegenerateTestData::@390 fStage
static const uint32_t rgba[kNumPixels]
static constexpr bool SkIsAlign4(T x)
static constexpr T SkAlign4(T x)
#define SkAssertResult(cond)
#define SkDEBUGFAILF(fmt,...)
SkBlenderBase * as_BB(SkBlender *blend)
static SkColorFilterBase * as_CFB(SkColorFilter *filter)
SkColorSpace * sk_srgb_linear_singleton()
SkColorSpace * sk_srgb_singleton()
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
#define SK_REGISTER_FLATTENABLE(type)
#define RETURN_FAILURE(...)
sk_sp< T > sk_ref_sp(T *obj)
static bool verify_child_effects(const std::vector< SkRuntimeEffect::Child > &reflected, SkSpan< const SkRuntimeEffect::ChildPtr > effectPtrs)
static size_t uniform_element_size(SkRuntimeEffect::Uniform::Type type)
static bool init_uniform_type(const SkSL::Context &ctx, const SkSL::Type *type, SkRuntimeEffect::Uniform *v)
static bool flattenable_is_valid_as_child(const SkFlattenable *f)
constexpr bool kRPEnableLiveTrace
static ChildType child_type(const SkSL::Type &type)
sk_sp< SkRuntimeEffect > SkMakeCachedRuntimeEffect(SkRuntimeEffect::Result(*make)(SkString sksl, const SkRuntimeEffect::Options &), SkString sksl)
SkShaderBase * as_SB(SkShader *shader)
constexpr size_t SkToSizeT(S x)
Type::kYUV Type::kRGBA() int(0.7 *637)
void toLinearSrgb(const void *color) override
bool appendColorFilter(int index) override
bool appendBlender(int index) override
void fromLinearSrgb(const void *color) override
bool appendShader(int index) override
T * makeArrayDefault(size_t count)
bool appendStages(const SkStageRec &rec) const
SkSL::Version skslVersion() const
static sk_sp< const SkCapabilities > RasterBackend()
virtual bool appendStages(const SkStageRec &rec, bool shaderIsOpaque) const =0
static sk_sp< SkData > MakeWithCopy(const void *data, size_t length)
static sk_sp< SkData > MakeEmpty()
static void Register(const char name[], Factory)
sk_sp< SkBlender > makeBlender() const
SkRuntimeBlendBuilder(sk_sp< SkRuntimeEffect >)
~SkRuntimeColorFilterBuilder()
SkRuntimeColorFilterBuilder(sk_sp< SkRuntimeEffect >)
sk_sp< SkColorFilter > makeColorFilter() const
sk_sp< const SkData > uniforms() const
const SkRuntimeEffect * effect() const
SkSpan< const SkRuntimeEffect::ChildPtr > children() const
static bool ReadChildEffects(SkReadBuffer &buffer, const SkRuntimeEffect *effect, skia_private::TArray< SkRuntimeEffect::ChildPtr > *children)
static sk_sp< SkShader > MakeDeferredShader(const SkRuntimeEffect *effect, UniformsCallback uniformsCallback, SkSpan< const SkRuntimeEffect::ChildPtr > children, const SkMatrix *localMatrix=nullptr)
static const char * ChildTypeToStr(SkRuntimeEffect::ChildType type)
std::function< sk_sp< const SkData >(const UniformsCallbackContext &)> UniformsCallback
static SkSpan< const float > UniformsAsSpan(SkSpan< const SkRuntimeEffect::Uniform > uniforms, sk_sp< const SkData > originalData, bool alwaysCopyIntoAlloc, const SkColorSpace *destColorSpace, SkArenaAlloc *alloc)
static void AllowPrivateAccess(SkRuntimeEffect::Options *options)
static SkRuntimeEffect::Uniform VarAsUniform(const SkSL::Variable &, const SkSL::Context &, size_t *offset)
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 *)
static void WriteChildEffects(SkWriteBuffer &buffer, SkSpan< const SkRuntimeEffect::ChildPtr > children)
static SkRuntimeEffect::Child VarAsChild(const SkSL::Variable &var, int index)
SkBlender * blender() const
SkShader * shader() const
std::optional< ChildType > type() const
SkColorFilter * colorFilter() const
size_t uniformSize() const
const Child * findChild(std::string_view name) const
static void RegisterFlattenables()
SkSpan< const Child > children() const
sk_sp< SkShader > makeShader(sk_sp< const SkData > uniforms, sk_sp< SkShader > children[], size_t childCount, const SkMatrix *localMatrix=nullptr) const
bool allowColorFilter() const
~SkRuntimeEffect() override
static Result MakeForColorFilter(SkString sksl, const Options &)
bool allowBlender() const
sk_sp< SkBlender > makeBlender(sk_sp< const SkData > uniforms, SkSpan< const ChildPtr > children={}) const
SkSpan< const Uniform > uniforms() const
static Result MakeForBlender(SkString sksl, const Options &)
static Result MakeForShader(SkString sksl, const Options &)
static TracedShader MakeTraced(sk_sp< SkShader > shader, const SkIPoint &traceCoord)
sk_sp< SkColorFilter > makeColorFilter(sk_sp< const SkData > uniforms) const
const Uniform * findUniform(std::string_view name) const
const std::string & source() const
~SkRuntimeShaderBuilder()
sk_sp< SkShader > makeShader(const SkMatrix *localMatrix=nullptr) const
SkRuntimeShaderBuilder(sk_sp< SkRuntimeEffect >)
SkRuntimeEffect::TracedShader makeTracedClone(const SkIPoint &coord)
const std::unique_ptr< Type > fFloat2
const std::unique_ptr< Type > fHalf4
const std::unique_ptr< Type > fInt4
const std::unique_ptr< Type > fHalf2x2
const std::unique_ptr< Type > fInt2
const std::unique_ptr< Type > fInt
const std::unique_ptr< Type > fFloat2x2
const std::unique_ptr< Type > fFloat4x4
const std::unique_ptr< Type > fInt3
const std::unique_ptr< Type > fFloat4
const std::unique_ptr< Type > fHalf2
const std::unique_ptr< Type > fHalf3x3
const std::unique_ptr< Type > fFloat3x3
const std::unique_ptr< Type > fHalf3
const std::unique_ptr< Type > fFloat
const std::unique_ptr< Type > fFloat3
const std::unique_ptr< Type > fHalf
const std::unique_ptr< Type > fHalf4x4
const BuiltinTypes & fTypes
std::unique_ptr< Statement > & declaration()
std::string_view name() const
const Type & type() const
ModifierFlags modifierFlags() const
virtual const Layout & layout() const
virtual bool appendStages(const SkStageRec &, const SkShaders::MatrixRec &) const =0
virtual SkRuntimeEffect * asRuntimeEffect() const
void markTotalMatrixInvalid()
constexpr size_t size() const
const char * c_str() const
FlutterSemanticsFlag flags
static const uint8_t buffer[]
static sk_sp< SkImage > make(sk_sp< SkColorSpace > cs)
uint64_t Hash64(const void *data, size_t bytes, uint64_t seed)
uint32_t Hash32(const void *data, size_t bytes, uint32_t seed)
constexpr SkColor4f kTransparent
bool ReturnsOpaqueColor(const FunctionDefinition &function)
bool ReferencesFragCoords(const Program &program)
SampleUsage GetSampleUsage(const Program &program, const Variable &child, bool writesToSampleCoords=true, int *elidedSampleCoordCount=nullptr)
bool ReturnsInputAlpha(const FunctionDefinition &function, const ProgramUsage &usage)
bool CallsColorTransformIntrinsics(const Program &program)
bool CallsSampleOutsideMain(const Program &program)
static constexpr int kDefaultInlineThreshold
@ kPrivateRuntimeColorFilter
std::unique_ptr< RP::Program > MakeRasterPipelineProgram(const SkSL::Program &program, const FunctionDefinition &function, DebugTracePriv *debugTrace, bool writeTraceOps)
const myers::Point & get(const myers::Segment &)
static void usage(char *argv0)
std::unique_ptr< ProgramConfig > fConfig