• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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