Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
SkRuntimeShader.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2023 Google LLC
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
8
10#include "include/core/SkData.h"
20#include "src/base/SkTLazy.h"
29
30#include <cstdint>
31#include <optional>
32#include <string>
33#include <utility>
34
35#if defined(SK_BUILD_FOR_DEBUGGER)
36 constexpr bool kLenientSkSLDeserialization = true;
37#else
38 constexpr bool kLenientSkSLDeserialization = false;
39#endif
40
41class SkColorSpace;
42struct SkIPoint;
43
46 sk_sp<const SkData> uniforms,
48 : fEffect(std::move(effect))
49 , fDebugTrace(std::move(debugTrace))
50 , fUniformData(std::move(uniforms))
51 , fChildren(children.begin(), children.end()) {}
52
55 UniformsCallback uniformsCallback,
57 : fEffect(std::move(effect))
58 , fDebugTrace(std::move(debugTrace))
59 , fUniformsCallback(std::move(uniformsCallback))
60 , fChildren(children.begin(), children.end()) {}
61
63 const SkIPoint& coord) {
64 auto debugTrace = sk_make_sp<SkSL::DebugTracePriv>();
65 debugTrace->setSource(effect->source());
66 debugTrace->setTraceCoord(coord);
67 return debugTrace;
68}
69
71 sk_sp<SkRuntimeEffect> unoptimized = fEffect->makeUnoptimizedClone();
72 sk_sp<SkSL::DebugTracePriv> debugTrace = make_debug_trace(unoptimized.get(), coord);
73 auto debugShader = sk_make_sp<SkRuntimeShader>(
74 unoptimized, debugTrace, this->uniformData(nullptr), SkSpan(fChildren));
75
76 return SkRuntimeEffect::TracedShader{std::move(debugShader), std::move(debugTrace)};
77}
78
81 // SkRP has support for many parts of #version 300 already, but for now, we restrict its
82 // usage in runtime effects to just #version 100.
83 return false;
84 }
85 if (const SkSL::RP::Program* program = fEffect->getRPProgram(fDebugTrace.get())) {
86 std::optional<SkShaders::MatrixRec> newMRec = mRec.apply(rec);
87 if (!newMRec.has_value()) {
88 return false;
89 }
90 SkSpan<const float> uniforms =
92 this->uniformData(rec.fDstCS),
93 /*alwaysCopyIntoAlloc=*/fUniformData == nullptr,
94 rec.fDstCS,
95 rec.fAlloc);
96 RuntimeEffectRPCallbacks callbacks(rec, *newMRec, fChildren, fEffect->fSampleUsages);
97 bool success = program->appendStages(rec.fPipeline, rec.fAlloc, &callbacks, uniforms);
98 return success;
99 }
100 return false;
101}
102
104 buffer.writeString(fEffect->source().c_str());
105 buffer.writeDataAsByteArray(this->uniformData(nullptr).get());
107}
108
110 if (fUniformData) {
111 return fUniformData;
112 }
113
114 // We want to invoke the uniforms-callback each time a paint occurs.
115 SkASSERT(fUniformsCallback);
116 sk_sp<const SkData> uniforms = fUniformsCallback({dstCS});
117 SkASSERT(uniforms && uniforms->size() == fEffect->uniformSize());
118 return uniforms;
119}
120
121sk_sp<SkFlattenable> SkRuntimeShader::CreateProc(SkReadBuffer& buffer) {
122 if (!buffer.validate(buffer.allowSkSL())) {
123 return nullptr;
124 }
125
126 SkString sksl;
127 buffer.readString(&sksl);
128 sk_sp<SkData> uniforms = buffer.readByteArrayAsData();
129
130 SkTLazy<SkMatrix> localM;
132 uint32_t flags = buffer.read32();
133 if (flags & kHasLegacyLocalMatrix_Flag) {
134 buffer.readMatrix(localM.init());
135 }
136 }
137
139 if constexpr (!kLenientSkSLDeserialization) {
140 if (!buffer.validate(effect != nullptr)) {
141 return nullptr;
142 }
143 }
144
147 return nullptr;
148 }
149
150 if constexpr (kLenientSkSLDeserialization) {
151 if (!effect) {
152 // If any children were SkShaders, return the first one. This is a reasonable fallback.
153 for (int i = 0; i < children.size(); i++) {
154 if (children[i].shader()) {
155 SkDebugf("Serialized SkSL failed to compile. Replacing shader with child %d.\n",
156 i);
157 return sk_ref_sp(children[i].shader());
158 }
159 }
160
161 // We don't know what to do, so just return nullptr (but *don't* poison the buffer).
162 SkDebugf("Serialized SkSL failed to compile. Ignoring/dropping SkSL shader.\n");
163 return nullptr;
164 }
165 }
166
167 return effect->makeShader(std::move(uniforms), SkSpan(children), localM.getMaybeNull());
168}
#define SkASSERT(cond)
Definition SkAssert.h:116
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
sk_sp< T > sk_ref_sp(T *obj)
Definition SkRefCnt.h:381
constexpr bool kLenientSkSLDeserialization
sk_sp< SkRuntimeEffect > SkMakeCachedRuntimeEffect(SkRuntimeEffect::Result(*make)(SkString sksl, const SkRuntimeEffect::Options &), SkString sksl)
static sk_sp< SkSL::DebugTracePriv > make_debug_trace(SkRuntimeEffect *effect, const SkIPoint &coord)
constexpr bool kLenientSkSLDeserialization
SkRuntimeEffectPriv::UniformsCallback UniformsCallback
static sk_sp< const SkCapabilities > RasterBackend()
static bool ReadChildEffects(SkReadBuffer &buffer, const SkRuntimeEffect *effect, skia_private::TArray< SkRuntimeEffect::ChildPtr > *children)
static SkSpan< const float > UniformsAsSpan(SkSpan< const SkRuntimeEffect::Uniform > uniforms, sk_sp< const SkData > originalData, bool alwaysCopyIntoAlloc, const SkColorSpace *destColorSpace, SkArenaAlloc *alloc)
static bool CanDraw(const SkCapabilities *, const SkSL::Program *)
static void WriteChildEffects(SkWriteBuffer &buffer, SkSpan< const SkRuntimeEffect::ChildPtr > children)
size_t uniformSize() const
sk_sp< SkShader > makeShader(sk_sp< const SkData > uniforms, sk_sp< SkShader > children[], size_t childCount, const SkMatrix *localMatrix=nullptr) const
SkSpan< const Uniform > uniforms() const
static Result MakeForShader(SkString sksl, const Options &)
const std::string & source() const
bool appendStages(const SkStageRec &rec, const SkShaders::MatrixRec &mRec) const override
SkRuntimeEffect::TracedShader makeTracedClone(const SkIPoint &coord)
SkSpan< const SkRuntimeEffect::ChildPtr > children() const
SkRuntimeShader(sk_sp< SkRuntimeEffect > effect, sk_sp< SkSL::DebugTracePriv > debugTrace, sk_sp< const SkData > uniforms, SkSpan< const SkRuntimeEffect::ChildPtr > children)
sk_sp< const SkData > uniformData(const SkColorSpace *dstCS) const
void flatten(SkWriteBuffer &buffer) const override
sk_sp< SkRuntimeEffect > effect() const
std::optional< MatrixRec > apply(const SkStageRec &rec, const SkMatrix &postInv={}) const
constexpr size_t size() const
Definition SkSpan_impl.h:95
T * init(Args &&... args)
Definition SkTLazy.h:45
const T * getMaybeNull() const
Definition SkTLazy.h:108
T * get() const
Definition SkRefCnt.h:303
static const char * begin(const StringSlice &s)
Definition editor.cpp:252
FlutterSemanticsFlag flags
glong glong end
static const uint8_t buffer[]
Definition ref_ptr.h:256
SkRasterPipeline * fPipeline
SkColorSpace * fDstCS
SkArenaAlloc * fAlloc