1 /*
2 * Copyright 2025 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 */
7
8 #include "tools/graphite/precompile/PrecompileEffectFactories.h"
9
10 #include "include/effects/SkRuntimeEffect.h"
11 #include "include/gpu/graphite/precompile/PrecompileBlender.h"
12 #include "include/gpu/graphite/precompile/PrecompileColorFilter.h"
13 #include "include/gpu/graphite/precompile/PrecompileRuntimeEffect.h"
14 #include "include/gpu/graphite/precompile/PrecompileShader.h"
15 #include "src/core/SkRuntimeEffectPriv.h"
16
17 namespace skiatest::graphite {
18
19 using namespace skgpu::graphite;
20
21 namespace PrecompileFactories {
22
23 //--------------------------------------------------------------------------------------------------
GetAnnulusShaderCode()24 const char* GetAnnulusShaderCode() {
25 static const char* sCode =
26 // draw a annulus centered at "center" w/ inner and outer radii in "radii"
27 "uniform float2 center;"
28 "uniform float2 radii;"
29 "half4 main(float2 xy) {"
30 "float len = length(xy - center);"
31 "half value = len < radii.x ? 0.0 : (len > radii.y ? 0.0 : 1.0);"
32 "return half4(value);"
33 "}";
34
35 return sCode;
36 }
37
GetAnnulusShaderEffect()38 SkRuntimeEffect* GetAnnulusShaderEffect() {
39 SkRuntimeEffect::Options options;
40 options.fName = "AnnulusShader";
41
42 static SkRuntimeEffect* sEffect = SkMakeRuntimeEffect(SkRuntimeEffect::MakeForShader,
43 GetAnnulusShaderCode(),
44 options);
45
46 return sEffect;
47 }
48
CreateAnnulusRuntimeShader()49 std::pair<sk_sp<SkShader>, sk_sp<PrecompileShader>> CreateAnnulusRuntimeShader() {
50 SkRuntimeEffect* effect = GetAnnulusShaderEffect();
51
52 static const float kUniforms[4] = { 50.0f, 50.0f, 40.0f, 50.0f };
53
54 sk_sp<SkData> uniforms = SkData::MakeWithCopy(kUniforms, sizeof(kUniforms));
55
56 sk_sp<SkShader> s = effect->makeShader(std::move(uniforms), /* children= */ {});
57 sk_sp<PrecompileShader> o = PrecompileRuntimeEffects::MakePrecompileShader(sk_ref_sp(effect));
58 return { std::move(s), std::move(o) };
59 }
60
61 //--------------------------------------------------------------------------------------------------
GetSrcBlenderEffect()62 SkRuntimeEffect* GetSrcBlenderEffect() {
63 SkRuntimeEffect::Options options;
64 options.fName = "SrcBlender";
65
66 static SkRuntimeEffect* sEffect = SkMakeRuntimeEffect(
67 SkRuntimeEffect::MakeForBlender,
68 "half4 main(half4 src, half4 dst) {"
69 "return src;"
70 "}",
71 options);
72
73 return sEffect;
74 }
75
CreateSrcRuntimeBlender()76 std::pair<sk_sp<SkBlender>, sk_sp<PrecompileBlender>> CreateSrcRuntimeBlender() {
77 SkRuntimeEffect* effect = GetSrcBlenderEffect();
78
79 sk_sp<SkBlender> b = effect->makeBlender(/* uniforms= */ nullptr);
80 sk_sp<PrecompileBlender> o =
81 PrecompileRuntimeEffects::MakePrecompileBlender(sk_ref_sp(effect));
82 return { std::move(b) , std::move(o) };
83 }
84
GetDstBlenderEffect()85 SkRuntimeEffect* GetDstBlenderEffect() {
86 SkRuntimeEffect::Options options;
87 options.fName = "DstBlender";
88
89 static SkRuntimeEffect* sEffect = SkMakeRuntimeEffect(
90 SkRuntimeEffect::MakeForBlender,
91 "half4 main(half4 src, half4 dst) {"
92 "return dst;"
93 "}",
94 options);
95
96 return sEffect;
97 }
98
CreateDstRuntimeBlender()99 std::pair<sk_sp<SkBlender>, sk_sp<PrecompileBlender>> CreateDstRuntimeBlender() {
100 SkRuntimeEffect* effect = GetDstBlenderEffect();
101
102 sk_sp<SkBlender> b = effect->makeBlender(/* uniforms= */ nullptr);
103 sk_sp<PrecompileBlender> o =
104 PrecompileRuntimeEffects::MakePrecompileBlender(sk_ref_sp(effect));
105 return { std::move(b) , std::move(o) };
106 }
107
GetComboBlenderEffect()108 SkRuntimeEffect* GetComboBlenderEffect() {
109 SkRuntimeEffect::Options options;
110 options.fName = "ComboBlender";
111
112 static SkRuntimeEffect* sEffect = SkMakeRuntimeEffect(
113 SkRuntimeEffect::MakeForBlender,
114 "uniform float blendFrac;"
115 "uniform blender a;"
116 "uniform blender b;"
117 "half4 main(half4 src, half4 dst) {"
118 "return (blendFrac * a.eval(src, dst)) + ((1 - blendFrac) * b.eval(src, dst));"
119 "}",
120 options);
121
122 return sEffect;
123 }
124
CreateComboRuntimeBlender()125 std::pair<sk_sp<SkBlender>, sk_sp<PrecompileBlender>> CreateComboRuntimeBlender() {
126 SkRuntimeEffect* effect = GetComboBlenderEffect();
127
128 auto [src, srcO] = CreateSrcRuntimeBlender();
129 auto [dst, dstO] = CreateDstRuntimeBlender();
130
131 SkRuntimeEffect::ChildPtr children[] = { src, dst };
132
133 const float kUniforms[] = { 1.0f };
134
135 sk_sp<SkData> uniforms = SkData::MakeWithCopy(kUniforms, sizeof(kUniforms));
136 sk_sp<SkBlender> b = effect->makeBlender(std::move(uniforms), children);
137 sk_sp<PrecompileBlender> o = PrecompileRuntimeEffects::MakePrecompileBlender(
138 sk_ref_sp(effect),
139 { { srcO }, { dstO } });
140 return { std::move(b) , std::move(o) };
141 }
142
143 //--------------------------------------------------------------------------------------------------
GetDoubleColorFilterEffect()144 SkRuntimeEffect* GetDoubleColorFilterEffect() {
145 SkRuntimeEffect::Options options;
146 options.fName = "DoubleColorFilter";
147
148 static SkRuntimeEffect* sEffect = SkMakeRuntimeEffect(
149 SkRuntimeEffect::MakeForColorFilter,
150 "half4 main(half4 c) {"
151 "return 2*c;"
152 "}",
153 options);
154
155 return sEffect;
156 }
157
CreateDoubleRuntimeColorFilter()158 std::pair<sk_sp<SkColorFilter>, sk_sp<PrecompileColorFilter>> CreateDoubleRuntimeColorFilter() {
159 SkRuntimeEffect* effect = GetDoubleColorFilterEffect();
160
161 return { effect->makeColorFilter(/* uniforms= */ nullptr),
162 PrecompileRuntimeEffects::MakePrecompileColorFilter(sk_ref_sp(effect)) };
163 }
164
GetHalfColorFilterEffect()165 SkRuntimeEffect* GetHalfColorFilterEffect() {
166 SkRuntimeEffect::Options options;
167 // We withhold this name to test out the default name case
168 //options.fName = "HalfColorFilter";
169
170 static SkRuntimeEffect* sEffect = SkMakeRuntimeEffect(
171 SkRuntimeEffect::MakeForColorFilter,
172 "half4 main(half4 c) {"
173 "return 0.5*c;"
174 "}",
175 options);
176
177 return sEffect;
178 }
179
CreateHalfRuntimeColorFilter()180 std::pair<sk_sp<SkColorFilter>, sk_sp<PrecompileColorFilter>> CreateHalfRuntimeColorFilter() {
181 SkRuntimeEffect* effect = GetHalfColorFilterEffect();
182
183 return { effect->makeColorFilter(/* uniforms= */ nullptr),
184 PrecompileRuntimeEffects::MakePrecompileColorFilter(sk_ref_sp(effect)) };
185 }
186
GetComboColorFilterEffect()187 SkRuntimeEffect* GetComboColorFilterEffect() {
188 SkRuntimeEffect::Options options;
189 options.fName = "ComboColorFilter";
190
191 static SkRuntimeEffect* sEffect = SkMakeRuntimeEffect(
192 SkRuntimeEffect::MakeForColorFilter,
193 "uniform float blendFrac;"
194 "uniform colorFilter a;"
195 "uniform colorFilter b;"
196 "half4 main(half4 c) {"
197 "return (blendFrac * a.eval(c)) + ((1 - blendFrac) * b.eval(c));"
198 "}",
199 options);
200
201 return sEffect;
202 }
203
CreateComboRuntimeColorFilter()204 std::pair<sk_sp<SkColorFilter>, sk_sp<PrecompileColorFilter>> CreateComboRuntimeColorFilter() {
205 SkRuntimeEffect* effect = GetComboColorFilterEffect();
206
207 auto [src, srcO] = CreateDoubleRuntimeColorFilter();
208 auto [dst, dstO] = CreateHalfRuntimeColorFilter();
209
210 SkRuntimeEffect::ChildPtr children[] = { src, dst };
211
212 const float kUniforms[] = { 0.5f };
213
214 sk_sp<SkData> uniforms = SkData::MakeWithCopy(kUniforms, sizeof(kUniforms));
215 sk_sp<SkColorFilter> cf = effect->makeColorFilter(std::move(uniforms), children);
216 sk_sp<PrecompileColorFilter> o =
217 PrecompileRuntimeEffects::MakePrecompileColorFilter(sk_ref_sp(effect),
218 { { srcO }, { dstO } });
219 return { std::move(cf) , std::move(o) };
220 }
221
222 } // namespace PrecompileFactories
223
224 } // namespace skiatest::graphite
225