| /* |
| * Copyright 2012 Google Inc. |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| #ifndef GrBackendEffectFactory_DEFINED |
| #define GrBackendEffectFactory_DEFINED |
| |
| #include "GrTypes.h" |
| #include "SkTemplates.h" |
| #include "SkThread_platform.h" |
| #include "GrNoncopyable.h" |
| |
| /** Given a GrEffect of a particular type, creates the corresponding graphics-backend-specific |
| effect object. Also tracks equivalence of shaders generated via a key. Each factory instance |
| is assigned a generation ID at construction. The ID of the return of GrEffect::getFactory() |
| is used as a type identifier. Thus a GrEffect subclass must return a singleton from |
| getFactory(). GrEffect subclasses should use the derived class GrTBackendEffectFactory that is |
| templated on the GrEffect subclass as their factory object. It requires that the GrEffect |
| subclass has a nested class (or typedef) GLEffect which is its GL implementation and a subclass |
| of GrGLEffect. |
| */ |
| |
| class GrEffectRef; |
| class GrGLEffect; |
| class GrGLCaps; |
| class GrDrawEffect; |
| |
| class GrBackendEffectFactory : public GrNoncopyable { |
| public: |
| typedef uint32_t EffectKey; |
| enum { |
| kNoEffectKey = 0, |
| kEffectKeyBits = 15, |
| /** |
| * Some aspects of the generated code may be determined by the particular textures that are |
| * associated with the effect. These manipulations are performed by GrGLShaderBuilder beyond |
| * GrGLEffects' control. So there is a dedicated part of the key which is combined |
| * automatically with the bits produced by GrGLEffect::GenKey(). |
| */ |
| kTextureKeyBits = 6, |
| kAttribKeyBits = 6 |
| }; |
| |
| virtual EffectKey glEffectKey(const GrDrawEffect&, const GrGLCaps&) const = 0; |
| virtual GrGLEffect* createGLInstance(const GrDrawEffect&) const = 0; |
| |
| bool operator ==(const GrBackendEffectFactory& b) const { |
| return fEffectClassID == b.fEffectClassID; |
| } |
| bool operator !=(const GrBackendEffectFactory& b) const { |
| return !(*this == b); |
| } |
| |
| virtual const char* name() const = 0; |
| |
| protected: |
| enum { |
| kIllegalEffectClassID = 0, |
| }; |
| |
| GrBackendEffectFactory() { |
| fEffectClassID = kIllegalEffectClassID; |
| } |
| virtual ~GrBackendEffectFactory() {} |
| |
| static EffectKey GenID() { |
| SkDEBUGCODE(static const int32_t kClassIDBits = 8 * sizeof(EffectKey) - |
| kTextureKeyBits - kEffectKeyBits - kAttribKeyBits); |
| // fCurrEffectClassID has been initialized to kIllegalEffectClassID. The |
| // atomic inc returns the old value not the incremented value. So we add |
| // 1 to the returned value. |
| int32_t id = sk_atomic_inc(&fCurrEffectClassID) + 1; |
| SkASSERT(id < (1 << kClassIDBits)); |
| return static_cast<EffectKey>(id); |
| } |
| |
| EffectKey fEffectClassID; |
| |
| private: |
| static int32_t fCurrEffectClassID; |
| }; |
| |
| #endif |