|
1 /* |
|
2 * Copyright 2012 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 GrBackendEffectFactory_DEFINED |
|
9 #define GrBackendEffectFactory_DEFINED |
|
10 |
|
11 #include "GrTypes.h" |
|
12 #include "SkTemplates.h" |
|
13 #include "SkThread.h" |
|
14 #include "SkTypes.h" |
|
15 |
|
16 /** Given a GrEffect of a particular type, creates the corresponding graphics-backend-specific |
|
17 effect object. Also tracks equivalence of shaders generated via a key. Each factory instance |
|
18 is assigned a generation ID at construction. The ID of the return of GrEffect::getFactory() |
|
19 is used as a type identifier. Thus a GrEffect subclass must return a singleton from |
|
20 getFactory(). GrEffect subclasses should use the derived class GrTBackendEffectFactory that is |
|
21 templated on the GrEffect subclass as their factory object. It requires that the GrEffect |
|
22 subclass has a nested class (or typedef) GLEffect which is its GL implementation and a subclass |
|
23 of GrGLEffect. |
|
24 */ |
|
25 |
|
26 class GrEffectRef; |
|
27 class GrGLEffect; |
|
28 class GrGLCaps; |
|
29 class GrDrawEffect; |
|
30 |
|
31 class GrBackendEffectFactory : public SkNoncopyable { |
|
32 public: |
|
33 typedef uint32_t EffectKey; |
|
34 enum { |
|
35 kNoEffectKey = 0, |
|
36 kEffectKeyBits = 10, |
|
37 /** |
|
38 * The framework automatically includes coord transforms and texture accesses in their |
|
39 * effect's EffectKey, so effects don't need to account for them in GenKey(). |
|
40 */ |
|
41 kTextureKeyBits = 4, |
|
42 kTransformKeyBits = 6, |
|
43 kAttribKeyBits = 6, |
|
44 kClassIDBits = 6 |
|
45 }; |
|
46 |
|
47 virtual EffectKey glEffectKey(const GrDrawEffect&, const GrGLCaps&) const = 0; |
|
48 virtual GrGLEffect* createGLInstance(const GrDrawEffect&) const = 0; |
|
49 |
|
50 bool operator ==(const GrBackendEffectFactory& b) const { |
|
51 return fEffectClassID == b.fEffectClassID; |
|
52 } |
|
53 bool operator !=(const GrBackendEffectFactory& b) const { |
|
54 return !(*this == b); |
|
55 } |
|
56 |
|
57 virtual const char* name() const = 0; |
|
58 |
|
59 static EffectKey GetTransformKey(EffectKey key) { |
|
60 return key >> (kEffectKeyBits + kTextureKeyBits) & ((1U << kTransformKeyBits) - 1); |
|
61 } |
|
62 |
|
63 protected: |
|
64 enum { |
|
65 kIllegalEffectClassID = 0, |
|
66 }; |
|
67 |
|
68 GrBackendEffectFactory() { |
|
69 fEffectClassID = kIllegalEffectClassID; |
|
70 } |
|
71 virtual ~GrBackendEffectFactory() {} |
|
72 |
|
73 static EffectKey GenID() { |
|
74 SkDEBUGCODE(static const int32_t kClassIDBits = 8 * sizeof(EffectKey) - |
|
75 kTextureKeyBits - kEffectKeyBits - kAttribKeyBits); |
|
76 // fCurrEffectClassID has been initialized to kIllegalEffectClassID. The |
|
77 // atomic inc returns the old value not the incremented value. So we add |
|
78 // 1 to the returned value. |
|
79 int32_t id = sk_atomic_inc(&fCurrEffectClassID) + 1; |
|
80 SkASSERT(id < (1 << kClassIDBits)); |
|
81 return static_cast<EffectKey>(id); |
|
82 } |
|
83 |
|
84 EffectKey fEffectClassID; |
|
85 |
|
86 private: |
|
87 static int32_t fCurrEffectClassID; |
|
88 }; |
|
89 |
|
90 #endif |