OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2012 Google Inc. | 2 * Copyright 2012 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #ifndef GrProcessor_DEFINED | 8 #ifndef GrProcessor_DEFINED |
9 #define GrProcessor_DEFINED | 9 #define GrProcessor_DEFINED |
10 | 10 |
11 #include "GrBackendProcessorFactory.h" | 11 #include "GrBackendProcessorFactory.h" |
12 #include "GrColor.h" | 12 #include "GrColor.h" |
13 #include "GrProcessorUnitTest.h" | 13 #include "GrProcessorUnitTest.h" |
14 #include "GrProgramElement.h" | 14 #include "GrProgramElement.h" |
15 #include "GrTextureAccess.h" | 15 #include "GrTextureAccess.h" |
16 | 16 |
17 class GrContext; | 17 class GrContext; |
18 class GrCoordTransform; | 18 class GrCoordTransform; |
19 | 19 |
20 /** Provides custom vertex shader, fragment shader, uniform data for a particula
r stage of the | 20 /** Provides custom shader code to the Ganesh shading pipeline. GrProcessor obje
cts *must* be |
21 Ganesh shading pipeline. | 21 immutable: after being constructed, their fields may not change. |
22 Subclasses must have a function that produces a human-readable name: | |
23 static const char* Name(); | |
24 GrProcessor objects *must* be immutable: after being constructed, their fiel
ds may not change. | |
25 | 22 |
26 Dynamically allocated GrProcessors are managed by a per-thread memory pool.
The ref count of an | 23 Dynamically allocated GrProcessors are managed by a per-thread memory pool.
The ref count of an |
27 effect must reach 0 before the thread terminates and the pool is destroyed.
To create a static | 24 processor must reach 0 before the thread terminates and the pool is destroye
d. To create a |
28 effect use the macro GR_CREATE_STATIC_EFFECT declared below. | 25 static processor use the helper macro GR_CREATE_STATIC_PROCESSOR declared be
low. |
29 */ | 26 */ |
30 class GrProcessor : public GrProgramElement { | 27 class GrProcessor : public GrProgramElement { |
31 public: | 28 public: |
32 SK_DECLARE_INST_COUNT(GrProcessor) | 29 SK_DECLARE_INST_COUNT(GrProcessor) |
33 | 30 |
34 virtual ~GrProcessor(); | 31 virtual ~GrProcessor(); |
35 | 32 |
36 struct InvariantOutput{ | 33 struct InvariantOutput{ |
37 InvariantOutput() : fColor(0), fValidFlags(0), fIsSingleComponent(false)
, | 34 InvariantOutput() : fColor(0), fValidFlags(0), fIsSingleComponent(false)
, |
38 fNonMulStageFound(false) {} | 35 fNonMulStageFound(false) {} |
39 | 36 |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
134 friend class GrPaint; | 131 friend class GrPaint; |
135 | 132 |
136 GrColor fColor; | 133 GrColor fColor; |
137 uint32_t fValidFlags; | 134 uint32_t fValidFlags; |
138 bool fIsSingleComponent; | 135 bool fIsSingleComponent; |
139 bool fNonMulStageFound; | 136 bool fNonMulStageFound; |
140 }; | 137 }; |
141 | 138 |
142 /** | 139 /** |
143 * This function is used to perform optimizations. When called the invarient
Ouput param | 140 * This function is used to perform optimizations. When called the invarient
Ouput param |
144 * indicate whether the input components to this effect in the FS will have
known values. | 141 * indicate whether the input components to this processor in the FS will ha
ve known values. |
145 * In inout the validFlags member is a bitfield of GrColorComponentFlags. Th
e isSingleComponent | 142 * In inout the validFlags member is a bitfield of GrColorComponentFlags. Th
e isSingleComponent |
146 * member indicates whether the input will be 1 or 4 bytes. The function upd
ates the members of | 143 * member indicates whether the input will be 1 or 4 bytes. The function upd
ates the members of |
147 * inout to indicate known values of its output. A component of the color me
mber only has | 144 * inout to indicate known values of its output. A component of the color me
mber only has |
148 * meaning if the corresponding bit in validFlags is set. | 145 * meaning if the corresponding bit in validFlags is set. |
149 */ | 146 */ |
150 void computeInvariantOutput(InvariantOutput* inout) const { | 147 void computeInvariantOutput(InvariantOutput* inout) const { |
151 this->onComputeInvariantOutput(inout); | 148 this->onComputeInvariantOutput(inout); |
152 #ifdef SK_DEBUG | 149 #ifdef SK_DEBUG |
153 inout->validate(); | 150 inout->validate(); |
154 #endif | 151 #endif |
155 } | 152 } |
156 | 153 |
157 /** This object, besides creating back-end-specific helper objects, is used
for run-time-type- | 154 /** This object, besides creating back-end-specific helper objects, is used
for run-time-type- |
158 identification. The factory should be an instance of templated class, | 155 identification. The factory should be an instance of templated class, |
159 GrTBackendEffectFactory. It is templated on the subclass of GrProcessor.
The subclass must | 156 GrTBackendEffectFactory. It is templated on the subclass of GrProcessor.
The subclass must |
160 have a nested type (or typedef) named GLProcessor which will be the subc
lass of | 157 have a nested type (or typedef) named GLProcessor which will be the subc
lass of |
161 GrGLProcessor created by the factory. | 158 GrGLProcessor created by the factory. |
162 | 159 |
163 Example: | 160 Example: |
164 class MyCustomEffect : public GrProcessor { | 161 class MyCustomProcessor : public GrProcessor { |
165 ... | 162 ... |
166 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE
{ | 163 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE
{ |
167 return GrTBackendEffectFactory<MyCustomEffect>::getInstance(); | 164 return GrTBackendEffectFactory<MyCustomProcessor>::getInstance()
; |
168 } | 165 } |
169 ... | 166 ... |
170 }; | 167 }; |
171 */ | 168 */ |
172 virtual const GrBackendProcessorFactory& getFactory() const = 0; | 169 virtual const GrBackendProcessorFactory& getFactory() const = 0; |
173 | 170 |
174 /** Human-meaningful string to identify this effect; may be embedded | 171 /** Human-meaningful string to identify this prcoessor; may be embedded |
175 in generated shader code. */ | 172 in generated shader code. */ |
176 const char* name() const; | 173 const char* name() const; |
177 | 174 |
178 int numTextures() const { return fTextureAccesses.count(); } | 175 int numTextures() const { return fTextureAccesses.count(); } |
179 | 176 |
180 /** Returns the access pattern for the texture at index. index must be valid
according to | 177 /** Returns the access pattern for the texture at index. index must be valid
according to |
181 numTextures(). */ | 178 numTextures(). */ |
182 const GrTextureAccess& textureAccess(int index) const { return *fTextureAcce
sses[index]; } | 179 const GrTextureAccess& textureAccess(int index) const { return *fTextureAcce
sses[index]; } |
183 | 180 |
184 /** Shortcut for textureAccess(index).texture(); */ | 181 /** Shortcut for textureAccess(index).texture(); */ |
185 GrTexture* texture(int index) const { return this->textureAccess(index).getT
exture(); } | 182 GrTexture* texture(int index) const { return this->textureAccess(index).getT
exture(); } |
186 | 183 |
187 /** Will this effect read the fragment position? */ | 184 /** Will this processor read the fragment position? */ |
188 bool willReadFragmentPosition() const { return fWillReadFragmentPosition; } | 185 bool willReadFragmentPosition() const { return fWillReadFragmentPosition; } |
189 | 186 |
190 void* operator new(size_t size); | 187 void* operator new(size_t size); |
191 void operator delete(void* target); | 188 void operator delete(void* target); |
192 | 189 |
193 void* operator new(size_t size, void* placement) { | 190 void* operator new(size_t size, void* placement) { |
194 return ::operator new(size, placement); | 191 return ::operator new(size, placement); |
195 } | 192 } |
196 void operator delete(void* target, void* placement) { | 193 void operator delete(void* target, void* placement) { |
197 ::operator delete(target, placement); | 194 ::operator delete(target, placement); |
198 } | 195 } |
199 | 196 |
200 /** | 197 /** |
201 * Helper for down-casting to a GrProcessor subclass | 198 * Helper for down-casting to a GrProcessor subclass |
202 */ | 199 */ |
203 template <typename T> const T& cast() const { return *static_cast<const T*>(
this); } | 200 template <typename T> const T& cast() const { return *static_cast<const T*>(
this); } |
204 | 201 |
205 protected: | 202 protected: |
206 /** | 203 /** |
207 * Subclasses call this from their constructor to register GrTextureAccesses
. The effect | 204 * Subclasses call this from their constructor to register GrTextureAccesses
. The processor |
208 * subclass manages the lifetime of the accesses (this function only stores
a pointer). The | 205 * subclass manages the lifetime of the accesses (this function only stores
a pointer). The |
209 * GrTextureAccess is typically a member field of the GrProcessor subclass.
This must only be | 206 * GrTextureAccess is typically a member field of the GrProcessor subclass.
This must only be |
210 * called from the constructor because GrProcessors are immutable. | 207 * called from the constructor because GrProcessors are immutable. |
211 */ | 208 */ |
212 void addTextureAccess(const GrTextureAccess* textureAccess); | 209 void addTextureAccess(const GrTextureAccess* textureAccess); |
213 | 210 |
214 GrProcessor() | 211 GrProcessor() |
215 : fWillReadFragmentPosition(false) {} | 212 : fWillReadFragmentPosition(false) {} |
216 | 213 |
217 /** | 214 /** |
218 * If the effect will generate a backend-specific effect that will read the
fragment position | 215 * If the prcoessor will generate a backend-specific processor that will rea
d the fragment |
219 * in the FS then it must call this method from its constructor. Otherwise,
the request to | 216 * position in the FS then it must call this method from its constructor. Ot
herwise, the |
220 * access the fragment position will be denied. | 217 * request to access the fragment position will be denied. |
221 */ | 218 */ |
222 void setWillReadFragmentPosition() { fWillReadFragmentPosition = true; } | 219 void setWillReadFragmentPosition() { fWillReadFragmentPosition = true; } |
223 | 220 |
224 SkDEBUGCODE(void assertTexturesEqual(const GrProcessor& other) const;) | 221 SkDEBUGCODE(void assertTexturesEqual(const GrProcessor& other) const;) |
225 | 222 |
226 private: | 223 private: |
227 | 224 |
228 /** | 225 /** |
229 * Subclass implements this to support getConstantColorComponents(...). | 226 * Subclass implements this to support getConstantColorComponents(...). |
230 */ | 227 */ |
231 virtual void onComputeInvariantOutput(InvariantOutput* inout) const = 0; | 228 virtual void onComputeInvariantOutput(InvariantOutput* inout) const = 0; |
232 | 229 |
233 SkSTArray<4, const GrTextureAccess*, true> fTextureAccesses; | 230 SkSTArray<4, const GrTextureAccess*, true> fTextureAccesses; |
234 bool fWillReadFragmentPosition; | 231 bool fWillReadFragmentPosition; |
235 | 232 |
236 typedef GrProgramElement INHERITED; | 233 typedef GrProgramElement INHERITED; |
237 }; | 234 }; |
238 | 235 |
| 236 |
| 237 /** |
| 238 * This creates a processor outside of the memory pool. The processor's destruct
or will be called |
| 239 * at global destruction time. NAME will be the name of the created instance. |
| 240 */ |
| 241 #define GR_CREATE_STATIC_PROCESSOR(NAME, PROC_CLASS, ARGS)
\ |
| 242 static SkAlignedSStorage<sizeof(PROC_CLASS)> g_##NAME##_Storage;
\ |
| 243 static PROC_CLASS* NAME SkNEW_PLACEMENT_ARGS(g_##NAME##_Storage.get(), PROC_CLAS
S, ARGS); \ |
| 244 static SkAutoTDestroy<GrProcessor> NAME##_ad(NAME); |
| 245 |
239 #endif | 246 #endif |
OLD | NEW |