joshualitt | b0a8a37 | 2014-09-23 09:50:21 -0700 | [diff] [blame] | 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 GrBackendProcessorFactory_DEFINED |
| 9 | #define GrBackendProcessorFactory_DEFINED |
| 10 | |
| 11 | #include "GrTypes.h" |
| 12 | #include "SkTemplates.h" |
| 13 | #include "SkThread.h" |
| 14 | #include "SkTypes.h" |
| 15 | #include "SkTArray.h" |
| 16 | |
| 17 | class GrGLProcessor; |
| 18 | class GrGLCaps; |
| 19 | class GrProcessor; |
| 20 | |
| 21 | /** |
bsalomon | b762cb5 | 2014-10-15 11:25:21 -0700 | [diff] [blame] | 22 | * Used by processors to build their keys. It incorporates each per-processor key into a larger shader |
| 23 | * key. |
joshualitt | b0a8a37 | 2014-09-23 09:50:21 -0700 | [diff] [blame] | 24 | */ |
| 25 | class GrProcessorKeyBuilder { |
| 26 | public: |
| 27 | GrProcessorKeyBuilder(SkTArray<unsigned char, true>* data) : fData(data), fCount(0) { |
| 28 | SkASSERT(0 == fData->count() % sizeof(uint32_t)); |
| 29 | } |
| 30 | |
| 31 | void add32(uint32_t v) { |
| 32 | ++fCount; |
| 33 | fData->push_back_n(4, reinterpret_cast<uint8_t*>(&v)); |
| 34 | } |
| 35 | |
| 36 | /** Inserts count uint32_ts into the key. The returned pointer is only valid until the next |
| 37 | add*() call. */ |
| 38 | uint32_t* SK_WARN_UNUSED_RESULT add32n(int count) { |
| 39 | SkASSERT(count > 0); |
| 40 | fCount += count; |
| 41 | return reinterpret_cast<uint32_t*>(fData->push_back_n(4 * count)); |
| 42 | } |
| 43 | |
| 44 | size_t size() const { return sizeof(uint32_t) * fCount; } |
| 45 | |
| 46 | private: |
| 47 | SkTArray<uint8_t, true>* fData; // unowned ptr to the larger key. |
bsalomon | b762cb5 | 2014-10-15 11:25:21 -0700 | [diff] [blame] | 48 | int fCount; // number of uint32_ts added to fData by the processor. |
joshualitt | b0a8a37 | 2014-09-23 09:50:21 -0700 | [diff] [blame] | 49 | }; |
| 50 | |
| 51 | /** |
| 52 | * This class is used to pass the key that was created for a GrGLProcessor back to it |
| 53 | * when it emits code. It may allow the emit step to skip calculations that were |
| 54 | * performed when computing the key. |
| 55 | */ |
| 56 | class GrProcessorKey { |
| 57 | public: |
| 58 | GrProcessorKey(const uint32_t* key, int count) : fKey(key), fCount(count) { |
| 59 | SkASSERT(0 == reinterpret_cast<intptr_t>(key) % sizeof(uint32_t)); |
| 60 | } |
| 61 | |
bsalomon | b762cb5 | 2014-10-15 11:25:21 -0700 | [diff] [blame] | 62 | /** Gets the uint32_t values that the processor inserted into the key. */ |
joshualitt | b0a8a37 | 2014-09-23 09:50:21 -0700 | [diff] [blame] | 63 | uint32_t get32(int index) const { |
| 64 | SkASSERT(index >=0 && index < fCount); |
| 65 | return fKey[index]; |
| 66 | } |
| 67 | |
bsalomon | b762cb5 | 2014-10-15 11:25:21 -0700 | [diff] [blame] | 68 | /** Gets the number of uint32_t values that the processor inserted into the key. */ |
joshualitt | b0a8a37 | 2014-09-23 09:50:21 -0700 | [diff] [blame] | 69 | int count32() const { return fCount; } |
| 70 | |
| 71 | private: |
| 72 | const uint32_t* fKey; // unowned ptr into the larger key. |
bsalomon | b762cb5 | 2014-10-15 11:25:21 -0700 | [diff] [blame] | 73 | int fCount; // number of uint32_ts inserted by the processor into its key. |
joshualitt | b0a8a37 | 2014-09-23 09:50:21 -0700 | [diff] [blame] | 74 | }; |
| 75 | |
| 76 | /** |
| 77 | * Given a GrProcessor of a particular type, creates the corresponding graphics-backend-specific |
bsalomon | b762cb5 | 2014-10-15 11:25:21 -0700 | [diff] [blame] | 78 | * processor object. It also tracks equivalence of shaders generated via a key. The factory for an |
| 79 | * processor is accessed via GrProcessor::getFactory(). Each factory instance is assigned an ID at |
joshualitt | b0a8a37 | 2014-09-23 09:50:21 -0700 | [diff] [blame] | 80 | * construction. The ID of GrProcessor::getFactory() is used as a type identifier. Thus, a |
| 81 | * GrProcessor subclass must always return the same object from getFactory() and that factory object |
| 82 | * must be unique to the GrProcessor subclass (and unique from any further derived subclasses). |
| 83 | * |
| 84 | * Rather than subclassing this class themselves, it is recommended that GrProcessor authors use |
bsalomon | b762cb5 | 2014-10-15 11:25:21 -0700 | [diff] [blame] | 85 | * the templated subclass GrTBackendProcessorFactory by writing their getFactory() method as: |
joshualitt | b0a8a37 | 2014-09-23 09:50:21 -0700 | [diff] [blame] | 86 | * |
bsalomon | b762cb5 | 2014-10-15 11:25:21 -0700 | [diff] [blame] | 87 | * const GrBackendProcessorFactory& MyProcessor::getFactory() const { |
| 88 | * return GrTBackendProcessorFactory<MyProcessor>::getInstance(); |
joshualitt | b0a8a37 | 2014-09-23 09:50:21 -0700 | [diff] [blame] | 89 | * } |
| 90 | * |
bsalomon | b762cb5 | 2014-10-15 11:25:21 -0700 | [diff] [blame] | 91 | * Using GrTBackendProcessorFactory places a few constraints on the processor. See that class's |
| 92 | * comments. |
joshualitt | b0a8a37 | 2014-09-23 09:50:21 -0700 | [diff] [blame] | 93 | */ |
| 94 | class GrBackendProcessorFactory : SkNoncopyable { |
| 95 | public: |
| 96 | /** |
bsalomon | b762cb5 | 2014-10-15 11:25:21 -0700 | [diff] [blame] | 97 | * Generates an processor's key. The key is based on the aspects of the GrProcessor object's |
joshualitt | b0a8a37 | 2014-09-23 09:50:21 -0700 | [diff] [blame] | 98 | * configuration that affect GLSL code generation. Two GrProcessor instances that would cause |
| 99 | * this->createGLInstance()->emitCode() to produce different code must produce different keys. |
| 100 | */ |
| 101 | virtual void getGLProcessorKey(const GrProcessor&, const GrGLCaps&, |
| 102 | GrProcessorKeyBuilder*) const = 0; |
| 103 | |
| 104 | /** |
bsalomon | b762cb5 | 2014-10-15 11:25:21 -0700 | [diff] [blame] | 105 | * Produces a human-reable name for the v. |
joshualitt | b0a8a37 | 2014-09-23 09:50:21 -0700 | [diff] [blame] | 106 | */ |
| 107 | virtual const char* name() const = 0; |
| 108 | |
| 109 | /** |
| 110 | * A unique value for every instance of this factory. It is automatically incorporated into the |
bsalomon | b762cb5 | 2014-10-15 11:25:21 -0700 | [diff] [blame] | 111 | * processor's key. This allows keys generated by getGLProcessorKey() to only be unique within a |
joshualitt | b0a8a37 | 2014-09-23 09:50:21 -0700 | [diff] [blame] | 112 | * GrProcessor subclass and not necessarily across subclasses. |
| 113 | */ |
bsalomon | f276541 | 2014-10-15 18:34:46 -0700 | [diff] [blame] | 114 | uint32_t classID() const { return fProcessorClassID; } |
joshualitt | b0a8a37 | 2014-09-23 09:50:21 -0700 | [diff] [blame] | 115 | |
| 116 | protected: |
bsalomon | f276541 | 2014-10-15 18:34:46 -0700 | [diff] [blame] | 117 | GrBackendProcessorFactory() : fProcessorClassID(GenClassID()) {} |
joshualitt | b0a8a37 | 2014-09-23 09:50:21 -0700 | [diff] [blame] | 118 | virtual ~GrBackendProcessorFactory() {} |
| 119 | |
| 120 | private: |
| 121 | enum { |
bsalomon | f276541 | 2014-10-15 18:34:46 -0700 | [diff] [blame] | 122 | kIllegalProcessorClassID = 0, |
joshualitt | b0a8a37 | 2014-09-23 09:50:21 -0700 | [diff] [blame] | 123 | }; |
| 124 | |
bsalomon | f276541 | 2014-10-15 18:34:46 -0700 | [diff] [blame] | 125 | static uint32_t GenClassID() { |
| 126 | // fCurrProcessorClassID has been initialized to kIllegalProcessorClassID. The |
joshualitt | b0a8a37 | 2014-09-23 09:50:21 -0700 | [diff] [blame] | 127 | // atomic inc returns the old value not the incremented value. So we add |
| 128 | // 1 to the returned value. |
bsalomon | f276541 | 2014-10-15 18:34:46 -0700 | [diff] [blame] | 129 | uint32_t id = static_cast<uint32_t>(sk_atomic_inc(&fCurrProcessorClassID)) + 1; |
joshualitt | b0a8a37 | 2014-09-23 09:50:21 -0700 | [diff] [blame] | 130 | if (!id) { |
| 131 | SkFAIL("This should never wrap as it should only be called once for each GrProcessor " |
| 132 | "subclass."); |
| 133 | } |
| 134 | return id; |
| 135 | } |
| 136 | |
bsalomon | f276541 | 2014-10-15 18:34:46 -0700 | [diff] [blame] | 137 | const uint32_t fProcessorClassID; |
| 138 | static int32_t fCurrProcessorClassID; |
joshualitt | b0a8a37 | 2014-09-23 09:50:21 -0700 | [diff] [blame] | 139 | }; |
| 140 | |
| 141 | class GrFragmentProcessor; |
| 142 | class GrGeometryProcessor; |
| 143 | class GrGLFragmentProcessor; |
| 144 | class GrGLGeometryProcessor; |
| 145 | |
| 146 | /** |
| 147 | * Backend processor factory cannot actually create anything, it is up to subclasses to implement |
| 148 | * a create binding which matches Gr to GL in a type safe way |
| 149 | */ |
| 150 | |
| 151 | class GrBackendFragmentProcessorFactory : public GrBackendProcessorFactory { |
| 152 | public: |
| 153 | /** |
| 154 | * Creates a GrGLProcessor instance that is used both to generate code for the GrProcessor in a |
| 155 | * GLSL program and to manage updating uniforms for the program when it is used. |
| 156 | */ |
| 157 | virtual GrGLFragmentProcessor* createGLInstance(const GrFragmentProcessor&) const = 0; |
| 158 | }; |
| 159 | |
| 160 | class GrBackendGeometryProcessorFactory : public GrBackendProcessorFactory { |
| 161 | public: |
| 162 | /** |
| 163 | * Creates a GrGLProcessor instance that is used both to generate code for the GrProcessor in a |
| 164 | * GLSL program and to manage updating uniforms for the program when it is used. |
| 165 | */ |
| 166 | virtual GrGLGeometryProcessor* createGLInstance(const GrGeometryProcessor&) const = 0; |
| 167 | }; |
| 168 | |
| 169 | #endif |