| /* |
| * Copyright 2025 Google LLC |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| #include "tools/graphite/precompile/PrecompileEffectFactories.h" |
| |
| #include "include/effects/SkRuntimeEffect.h" |
| #include "include/gpu/graphite/precompile/PrecompileBlender.h" |
| #include "include/gpu/graphite/precompile/PrecompileColorFilter.h" |
| #include "include/gpu/graphite/precompile/PrecompileRuntimeEffect.h" |
| #include "include/gpu/graphite/precompile/PrecompileShader.h" |
| #include "src/core/SkRuntimeEffectPriv.h" |
| |
| namespace skiatest::graphite { |
| |
| using namespace skgpu::graphite; |
| |
| namespace PrecompileFactories { |
| |
| //-------------------------------------------------------------------------------------------------- |
| const char* GetAnnulusShaderCode() { |
| static const char* sCode = |
| // draw a annulus centered at "center" w/ inner and outer radii in "radii" |
| "uniform float2 center;" |
| "uniform float2 radii;" |
| "half4 main(float2 xy) {" |
| "float len = length(xy - center);" |
| "half value = len < radii.x ? 0.0 : (len > radii.y ? 0.0 : 1.0);" |
| "return half4(value);" |
| "}"; |
| |
| return sCode; |
| } |
| |
| SkRuntimeEffect* GetAnnulusShaderEffect() { |
| SkRuntimeEffect::Options options; |
| options.fName = "AnnulusShader"; |
| |
| static SkRuntimeEffect* sEffect = SkMakeRuntimeEffect(SkRuntimeEffect::MakeForShader, |
| GetAnnulusShaderCode(), |
| options); |
| |
| return sEffect; |
| } |
| |
| std::pair<sk_sp<SkShader>, sk_sp<PrecompileShader>> CreateAnnulusRuntimeShader() { |
| SkRuntimeEffect* effect = GetAnnulusShaderEffect(); |
| |
| static const float kUniforms[4] = { 50.0f, 50.0f, 40.0f, 50.0f }; |
| |
| sk_sp<SkData> uniforms = SkData::MakeWithCopy(kUniforms, sizeof(kUniforms)); |
| |
| sk_sp<SkShader> s = effect->makeShader(std::move(uniforms), /* children= */ {}); |
| sk_sp<PrecompileShader> o = PrecompileRuntimeEffects::MakePrecompileShader(sk_ref_sp(effect)); |
| return { std::move(s), std::move(o) }; |
| } |
| |
| //-------------------------------------------------------------------------------------------------- |
| SkRuntimeEffect* GetSrcBlenderEffect() { |
| SkRuntimeEffect::Options options; |
| options.fName = "SrcBlender"; |
| |
| static SkRuntimeEffect* sEffect = SkMakeRuntimeEffect( |
| SkRuntimeEffect::MakeForBlender, |
| "half4 main(half4 src, half4 dst) {" |
| "return src;" |
| "}", |
| options); |
| |
| return sEffect; |
| } |
| |
| std::pair<sk_sp<SkBlender>, sk_sp<PrecompileBlender>> CreateSrcRuntimeBlender() { |
| SkRuntimeEffect* effect = GetSrcBlenderEffect(); |
| |
| sk_sp<SkBlender> b = effect->makeBlender(/* uniforms= */ nullptr); |
| sk_sp<PrecompileBlender> o = |
| PrecompileRuntimeEffects::MakePrecompileBlender(sk_ref_sp(effect)); |
| return { std::move(b) , std::move(o) }; |
| } |
| |
| SkRuntimeEffect* GetDstBlenderEffect() { |
| SkRuntimeEffect::Options options; |
| options.fName = "DstBlender"; |
| |
| static SkRuntimeEffect* sEffect = SkMakeRuntimeEffect( |
| SkRuntimeEffect::MakeForBlender, |
| "half4 main(half4 src, half4 dst) {" |
| "return dst;" |
| "}", |
| options); |
| |
| return sEffect; |
| } |
| |
| std::pair<sk_sp<SkBlender>, sk_sp<PrecompileBlender>> CreateDstRuntimeBlender() { |
| SkRuntimeEffect* effect = GetDstBlenderEffect(); |
| |
| sk_sp<SkBlender> b = effect->makeBlender(/* uniforms= */ nullptr); |
| sk_sp<PrecompileBlender> o = |
| PrecompileRuntimeEffects::MakePrecompileBlender(sk_ref_sp(effect)); |
| return { std::move(b) , std::move(o) }; |
| } |
| |
| SkRuntimeEffect* GetComboBlenderEffect() { |
| SkRuntimeEffect::Options options; |
| options.fName = "ComboBlender"; |
| |
| static SkRuntimeEffect* sEffect = SkMakeRuntimeEffect( |
| SkRuntimeEffect::MakeForBlender, |
| "uniform float blendFrac;" |
| "uniform blender a;" |
| "uniform blender b;" |
| "half4 main(half4 src, half4 dst) {" |
| "return (blendFrac * a.eval(src, dst)) + ((1 - blendFrac) * b.eval(src, dst));" |
| "}", |
| options); |
| |
| return sEffect; |
| } |
| |
| std::pair<sk_sp<SkBlender>, sk_sp<PrecompileBlender>> CreateComboRuntimeBlender() { |
| SkRuntimeEffect* effect = GetComboBlenderEffect(); |
| |
| auto [src, srcO] = CreateSrcRuntimeBlender(); |
| auto [dst, dstO] = CreateDstRuntimeBlender(); |
| |
| SkRuntimeEffect::ChildPtr children[] = { src, dst }; |
| |
| const float kUniforms[] = { 1.0f }; |
| |
| sk_sp<SkData> uniforms = SkData::MakeWithCopy(kUniforms, sizeof(kUniforms)); |
| sk_sp<SkBlender> b = effect->makeBlender(std::move(uniforms), children); |
| sk_sp<PrecompileBlender> o = PrecompileRuntimeEffects::MakePrecompileBlender( |
| sk_ref_sp(effect), |
| {{ {{ srcO }}, {{ dstO }} }}); |
| return { std::move(b) , std::move(o) }; |
| } |
| |
| //-------------------------------------------------------------------------------------------------- |
| SkRuntimeEffect* GetDoubleColorFilterEffect() { |
| SkRuntimeEffect::Options options; |
| options.fName = "DoubleColorFilter"; |
| |
| static SkRuntimeEffect* sEffect = SkMakeRuntimeEffect( |
| SkRuntimeEffect::MakeForColorFilter, |
| "half4 main(half4 c) {" |
| "return 2*c;" |
| "}", |
| options); |
| |
| return sEffect; |
| } |
| |
| std::pair<sk_sp<SkColorFilter>, sk_sp<PrecompileColorFilter>> CreateDoubleRuntimeColorFilter() { |
| SkRuntimeEffect* effect = GetDoubleColorFilterEffect(); |
| |
| return { effect->makeColorFilter(/* uniforms= */ nullptr), |
| PrecompileRuntimeEffects::MakePrecompileColorFilter(sk_ref_sp(effect)) }; |
| } |
| |
| SkRuntimeEffect* GetHalfColorFilterEffect() { |
| SkRuntimeEffect::Options options; |
| // We withhold this name to test out the default name case |
| //options.fName = "HalfColorFilter"; |
| |
| static SkRuntimeEffect* sEffect = SkMakeRuntimeEffect( |
| SkRuntimeEffect::MakeForColorFilter, |
| "half4 main(half4 c) {" |
| "return 0.5*c;" |
| "}", |
| options); |
| |
| return sEffect; |
| } |
| |
| std::pair<sk_sp<SkColorFilter>, sk_sp<PrecompileColorFilter>> CreateHalfRuntimeColorFilter() { |
| SkRuntimeEffect* effect = GetHalfColorFilterEffect(); |
| |
| return { effect->makeColorFilter(/* uniforms= */ nullptr), |
| PrecompileRuntimeEffects::MakePrecompileColorFilter(sk_ref_sp(effect)) }; |
| } |
| |
| SkRuntimeEffect* GetComboColorFilterEffect() { |
| SkRuntimeEffect::Options options; |
| options.fName = "ComboColorFilter"; |
| |
| static SkRuntimeEffect* sEffect = SkMakeRuntimeEffect( |
| SkRuntimeEffect::MakeForColorFilter, |
| "uniform float blendFrac;" |
| "uniform colorFilter a;" |
| "uniform colorFilter b;" |
| "half4 main(half4 c) {" |
| "return (blendFrac * a.eval(c)) + ((1 - blendFrac) * b.eval(c));" |
| "}", |
| options); |
| |
| return sEffect; |
| } |
| |
| std::pair<sk_sp<SkColorFilter>, sk_sp<PrecompileColorFilter>> CreateComboRuntimeColorFilter() { |
| SkRuntimeEffect* effect = GetComboColorFilterEffect(); |
| |
| auto [src, srcO] = CreateDoubleRuntimeColorFilter(); |
| auto [dst, dstO] = CreateHalfRuntimeColorFilter(); |
| |
| SkRuntimeEffect::ChildPtr children[] = { src, dst }; |
| |
| const float kUniforms[] = { 0.5f }; |
| |
| sk_sp<SkData> uniforms = SkData::MakeWithCopy(kUniforms, sizeof(kUniforms)); |
| sk_sp<SkColorFilter> cf = effect->makeColorFilter(std::move(uniforms), children); |
| sk_sp<PrecompileColorFilter> o = |
| PrecompileRuntimeEffects::MakePrecompileColorFilter(sk_ref_sp(effect), |
| {{ {{ srcO }}, {{ dstO }} }}); |
| return { std::move(cf) , std::move(o) }; |
| } |
| |
| } // namespace PrecompileFactories |
| |
| } // namespace skiatest::graphite |