1 /*
2  * Copyright 2018 Google Inc.
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 #ifndef GrSkSLFP_DEFINED
9 #define GrSkSLFP_DEFINED
10 
11 #include "include/core/SkRefCnt.h"
12 #include "include/effects/SkRuntimeEffect.h"
13 #include "include/gpu/GrContextOptions.h"
14 #include "src/gpu/GrFragmentProcessor.h"
15 #include <atomic>
16 
17 class GrShaderCaps;
18 class SkData;
19 class SkRuntimeEffect;
20 
21 class GrSkSLFP : public GrFragmentProcessor {
22 public:
23     /**
24      * Creates a new fragment processor from an SkRuntimeEffect and a data blob containing values
25      * for all of the 'uniform' variables in the SkSL source. The layout of the uniforms blob is
26      * dictated by the SkRuntimeEffect.
27      */
28     static std::unique_ptr<GrSkSLFP> Make(sk_sp<SkRuntimeEffect> effect,
29                                           const char* name,
30                                           sk_sp<SkData> uniforms);
31 
32     const char* name() const override;
33 
34     void addChild(std::unique_ptr<GrFragmentProcessor> child);
35 
36     std::unique_ptr<GrFragmentProcessor> clone() const override;
37 
38 private:
39     GrSkSLFP(sk_sp<SkRuntimeEffect> effect, const char* name, sk_sp<SkData> uniforms);
40 
41     GrSkSLFP(const GrSkSLFP& other);
42 
43     std::unique_ptr<GrGLSLFragmentProcessor> onMakeProgramImpl() const override;
44 
45     void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
46 
47     bool onIsEqual(const GrFragmentProcessor&) const override;
48 
49     SkPMColor4f constantOutputForConstantInput(const SkPMColor4f&) const override;
50 
51     sk_sp<SkRuntimeEffect> fEffect;
52     const char*            fName;
53     sk_sp<SkData>          fUniforms;
54 
55     GR_DECLARE_FRAGMENT_PROCESSOR_TEST
56 
57     using INHERITED = GrFragmentProcessor;
58 
59     friend class GrGLSLSkSLFP;
60 
61     friend class GrSkSLFPFactory;
62 };
63 
64 class GrRuntimeFPBuilder : public SkRuntimeEffectBuilder<std::unique_ptr<GrFragmentProcessor>> {
65 public:
66     ~GrRuntimeFPBuilder();
67 
68     // NOTE: We use a static variable as a cache. CODE and MAKE must remain template parameters.
69     template <const char* CODE, SkRuntimeEffect::Result (*MAKE)(SkString sksl)>
Make()70     static GrRuntimeFPBuilder Make() {
71         static const SkRuntimeEffect::Result gResult = MAKE(SkString(CODE));
72 #ifdef SK_DEBUG
73         if (!gResult.effect) {
74             SK_ABORT("Code failed: %s", gResult.errorText.c_str());
75         }
76 #endif
77         return GrRuntimeFPBuilder(gResult.effect);
78     }
79 
80     std::unique_ptr<GrFragmentProcessor> makeFP();
81 
82 private:
83     explicit GrRuntimeFPBuilder(sk_sp<SkRuntimeEffect>);
84     GrRuntimeFPBuilder(GrRuntimeFPBuilder&& that) = default;
85 
86     using INHERITED = SkRuntimeEffectBuilder<std::unique_ptr<GrFragmentProcessor>>;
87 };
88 
89 #endif
90