Home | History | Annotate | Download | only in gpu
      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_platform.h"
     14 #include "GrNoncopyable.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 GrEffectStage;
     28 class GrGLEffect;
     29 class GrGLCaps;
     30 
     31 class GrBackendEffectFactory : public GrNoncopyable {
     32 public:
     33     typedef uint32_t EffectKey;
     34     enum {
     35         kNoEffectKey = 0,
     36         kEffectKeyBits = 12,
     37         /**
     38          * Some aspects of the generated code may be determined by the particular textures that are
     39          * associated with the effect. These manipulations are performed by GrGLShaderBuilder beyond
     40          * GrGLEffects' control. So there is a dedicated part of the key which is combined
     41          * automatically with the bits produced by GrGLEffect::GenKey().
     42          */
     43         kTextureKeyBits = 6
     44     };
     45 
     46     virtual EffectKey glEffectKey(const GrEffectStage&, const GrGLCaps&) const = 0;
     47     virtual GrGLEffect* createGLInstance(const GrEffectRef&) const = 0;
     48 
     49     bool operator ==(const GrBackendEffectFactory& b) const {
     50         return fEffectClassID == b.fEffectClassID;
     51     }
     52     bool operator !=(const GrBackendEffectFactory& b) const {
     53         return !(*this == b);
     54     }
     55 
     56     virtual const char* name() const = 0;
     57 
     58 protected:
     59     enum {
     60         kIllegalEffectClassID = 0,
     61     };
     62 
     63     GrBackendEffectFactory() {
     64         fEffectClassID = kIllegalEffectClassID;
     65     }
     66     virtual ~GrBackendEffectFactory() {}
     67 
     68     static EffectKey GenID() {
     69         GR_DEBUGCODE(static const int32_t kClassIDBits = 8 * sizeof(EffectKey) -
     70                                             kTextureKeyBits -
     71                                     kEffectKeyBits);
     72         // fCurrEffectClassID has been initialized to kIllegalEffectClassID. The
     73         // atomic inc returns the old value not the incremented value. So we add
     74         // 1 to the returned value.
     75         int32_t id = sk_atomic_inc(&fCurrEffectClassID) + 1;
     76         GrAssert(id < (1 << kClassIDBits));
     77         return static_cast<EffectKey>(id);
     78     }
     79 
     80     EffectKey fEffectClassID;
     81 
     82 private:
     83     static int32_t fCurrEffectClassID;
     84 };
     85 
     86 #endif
     87