blob: dbeffafe37ab05579ccc598ffd34e898cb939987 [file] [log] [blame]
Ethan Nicholas00543112018-07-31 09:44:36 -04001/*
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
Mike Kleinc0bd9f92019-04-23 12:05:21 -050011#include "include/core/SkRefCnt.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050012#include "src/gpu/GrCaps.h"
13#include "src/gpu/GrCoordTransform.h"
14#include "src/gpu/GrFragmentProcessor.h"
15#include "src/gpu/GrShaderCaps.h"
Greg Danielf91aeb22019-06-18 09:58:02 -040016#include "src/gpu/GrSkSLFPFactoryCache.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050017#include "src/sksl/SkSLCompiler.h"
18#include "src/sksl/SkSLPipelineStageCodeGenerator.h"
Mike Klein0ec1c572018-12-04 11:52:51 -050019#include <atomic>
Ethan Nicholas00543112018-07-31 09:44:36 -040020
Ethan Nicholas78aceb22018-08-31 16:13:58 -040021#if GR_TEST_UTILS
22#define GR_FP_SRC_STRING const char*
23#else
24#define GR_FP_SRC_STRING static const char*
25#endif
26
Robert Phillips1efecea2019-02-15 16:58:40 -050027class GrContext_Base;
Ethan Nicholas00543112018-07-31 09:44:36 -040028class GrSkSLFPFactory;
29
30class GrSkSLFP : public GrFragmentProcessor {
31public:
32 /**
33 * Returns a new unique identifier. Each different SkSL fragment processor should call
34 * NewIndex once, statically, and use this index for all calls to Make.
35 */
36 static int NewIndex() {
Mike Klein0ec1c572018-12-04 11:52:51 -050037 static std::atomic<int> nextIndex{0};
38 return nextIndex++;
Ethan Nicholas00543112018-07-31 09:44:36 -040039 }
40
41 /**
42 * Creates a new fragment processor from an SkSL source string and a struct of inputs to the
43 * program. The input struct's type is derived from the 'in' variables in the SkSL source, so
44 * e.g. the shader:
45 *
46 * in bool dither;
47 * in float x;
48 * in float y;
49 * ....
50 *
51 * would expect a pointer to a struct set up like:
52 *
53 * struct {
54 * bool dither;
55 * float x;
56 * float y;
57 * };
58 *
59 * As turning SkSL into GLSL / SPIR-V / etc. is fairly expensive, and the output may differ
60 * based on the inputs, internally the process is divided into two steps: we first parse and
61 * semantically analyze the SkSL into an internal representation, and then "specialize" this
62 * internal representation based on the inputs. The unspecialized internal representation of
63 * the program is cached, so further specializations of the same code are much faster than the
64 * first call.
65 *
66 * This caching is based on the 'index' parameter, which should be derived by statically calling
67 * 'NewIndex()'. Each given SkSL string should have a single, statically defined index
68 * associated with it.
69 */
Ethan Nicholaseace9352018-10-15 20:09:54 +000070 static std::unique_ptr<GrSkSLFP> Make(
Robert Phillips1efecea2019-02-15 16:58:40 -050071 GrContext_Base* context,
Ethan Nicholaseace9352018-10-15 20:09:54 +000072 int index,
73 const char* name,
74 const char* sksl,
75 const void* inputs,
Ethan Nicholas0d997662019-04-08 09:46:01 -040076 size_t inputSize,
Brian Osman3b1e4c22019-08-12 15:12:14 -040077 SkSL::Program::Kind kind = SkSL::Program::kPipelineStage_Kind,
78 const SkMatrix* matrix = nullptr);
Ethan Nicholas00543112018-07-31 09:44:36 -040079
Ethan Nicholasa70693b2019-03-04 13:07:36 -050080 static std::unique_ptr<GrSkSLFP> Make(
81 GrContext_Base* context,
82 int index,
83 const char* name,
84 SkString sksl,
85 const void* inputs,
Ethan Nicholas0d997662019-04-08 09:46:01 -040086 size_t inputSize,
Brian Osman3b1e4c22019-08-12 15:12:14 -040087 SkSL::Program::Kind kind = SkSL::Program::kPipelineStage_Kind,
88 const SkMatrix* matrix = nullptr);
Ethan Nicholasa70693b2019-03-04 13:07:36 -050089
Ethan Nicholas00543112018-07-31 09:44:36 -040090 const char* name() const override;
91
Ethan Nicholasce008112018-08-30 09:19:50 -040092 void addChild(std::unique_ptr<GrFragmentProcessor> child);
93
Ethan Nicholas00543112018-07-31 09:44:36 -040094 std::unique_ptr<GrFragmentProcessor> clone() const override;
95
96private:
Ethan Nicholas0d997662019-04-08 09:46:01 -040097 GrSkSLFP(sk_sp<GrSkSLFPFactoryCache> factoryCache, const GrShaderCaps* shaderCaps,
98 SkSL::Program::Kind kind, int fIndex, const char* name, const char* sksl,
Brian Osman3b1e4c22019-08-12 15:12:14 -040099 SkString skslString, const void* inputs, size_t inputSize, const SkMatrix* matrix);
Ethan Nicholas00543112018-07-31 09:44:36 -0400100
101 GrSkSLFP(const GrSkSLFP& other);
102
103 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
104
105 void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
106
107 bool onIsEqual(const GrFragmentProcessor&) const override;
108
109 void createFactory() const;
110
111 sk_sp<GrSkSLFPFactoryCache> fFactoryCache;
112
113 const sk_sp<GrShaderCaps> fShaderCaps;
114
115 mutable sk_sp<GrSkSLFPFactory> fFactory;
116
Ethan Nicholas0d997662019-04-08 09:46:01 -0400117 SkSL::Program::Kind fKind;
118
Ethan Nicholas00543112018-07-31 09:44:36 -0400119 int fIndex;
120
121 const char* fName;
122
Ethan Nicholasa70693b2019-03-04 13:07:36 -0500123 // For object lifetime purposes, we have fields for the SkSL as both a const char* and a
124 // SkString. The const char* is the one we actually use, but it may point to the SkString's
125 // bytes. Since GrSkSLFPs are frequently created from constant strings, this allows us to
126 // generally avoid the overhead of copying the bytes into an SkString (in which case fSkSLString
127 // is the empty string), while still allowing the GrSkSLFP to manage the string's lifetime when
128 // needed.
129 SkString fSkSLString;
130
Ethan Nicholas00543112018-07-31 09:44:36 -0400131 const char* fSkSL;
132
Ethan Nicholaseace9352018-10-15 20:09:54 +0000133 const std::unique_ptr<int8_t[]> fInputs;
Ethan Nicholas00543112018-07-31 09:44:36 -0400134
135 size_t fInputSize;
136
Brian Osman3b1e4c22019-08-12 15:12:14 -0400137 GrCoordTransform fCoordTransform;
138
Ethan Nicholas00543112018-07-31 09:44:36 -0400139 mutable SkSL::String fKey;
140
141 GR_DECLARE_FRAGMENT_PROCESSOR_TEST
142
143 typedef GrFragmentProcessor INHERITED;
144
Ethan Nicholasce008112018-08-30 09:19:50 -0400145 friend class GrGLSLSkSLFP;
146
Ethan Nicholas00543112018-07-31 09:44:36 -0400147 friend class GrSkSLFPFactory;
148};
149
150/**
151 * Produces GrFragmentProcessors from SkSL code. As the shader code produced from the SkSL depends
152 * upon the inputs to the SkSL (static if's, etc.) we first create a factory for a given SkSL
153 * string, then use that to create the actual GrFragmentProcessor.
154 */
Mike Klein408ef212018-10-30 15:23:00 +0000155class GrSkSLFPFactory : public SkNVRefCnt<GrSkSLFPFactory> {
Ethan Nicholas00543112018-07-31 09:44:36 -0400156public:
157 /**
158 * Constructs a GrSkSLFPFactory for a given SkSL source string. Creating a factory will
159 * preprocess the SkSL and determine which of its inputs are declared "key" (meaning they cause
160 * the produced shaders to differ), so it is important to reuse the same factory instance for
161 * the same shader in order to avoid repeatedly re-parsing the SkSL.
162 */
Ethan Nicholas0d997662019-04-08 09:46:01 -0400163 GrSkSLFPFactory(const char* name, const GrShaderCaps* shaderCaps, const char* sksl,
164 SkSL::Program::Kind kind = SkSL::Program::kPipelineStage_Kind);
Ethan Nicholas00543112018-07-31 09:44:36 -0400165
166 const SkSL::Program* getSpecialization(const SkSL::String& key, const void* inputs,
167 size_t inputSize);
168
Ethan Nicholas0d997662019-04-08 09:46:01 -0400169 SkSL::Program::Kind fKind;
170
Ethan Nicholas00543112018-07-31 09:44:36 -0400171 const char* fName;
172
173 SkSL::Compiler fCompiler;
174
175 std::shared_ptr<SkSL::Program> fBaseProgram;
176
177 std::vector<const SkSL::Variable*> fInputVars;
178
Ethan Nicholas00543112018-07-31 09:44:36 -0400179 std::unordered_map<SkSL::String, std::unique_ptr<const SkSL::Program>> fSpecializations;
180
181 friend class GrSkSLFP;
182};
183
184#endif