michael@0: /* michael@0: * Copyright 2012 Google Inc. michael@0: * michael@0: * Use of this source code is governed by a BSD-style license that can be michael@0: * found in the LICENSE file. michael@0: */ michael@0: michael@0: #ifndef GrTBackendEffectFactory_DEFINED michael@0: #define GrTBackendEffectFactory_DEFINED michael@0: michael@0: #include "GrBackendEffectFactory.h" michael@0: #include "GrDrawEffect.h" michael@0: #include "gl/GrGLProgramEffects.h" michael@0: michael@0: /** michael@0: * Implements GrBackendEffectFactory for a GrEffect subclass as a singleton. michael@0: */ michael@0: template michael@0: class GrTBackendEffectFactory : public GrBackendEffectFactory { michael@0: michael@0: public: michael@0: typedef typename EffectClass::GLEffect GLEffect; michael@0: michael@0: /** Returns a human-readable name that is accessible via GrEffect or michael@0: GrGLEffect and is consistent between the two of them. michael@0: */ michael@0: virtual const char* name() const SK_OVERRIDE { return EffectClass::Name(); } michael@0: michael@0: /** Returns a value that identifies the GLSL shader code generated by michael@0: a GrEffect. This enables caching of generated shaders. Part of the michael@0: id identifies the GrEffect subclass. The remainder is based michael@0: on the aspects of the GrEffect object's configuration that affect michael@0: GLSL code generation. */ michael@0: virtual EffectKey glEffectKey(const GrDrawEffect& drawEffect, michael@0: const GrGLCaps& caps) const SK_OVERRIDE { michael@0: SkASSERT(kIllegalEffectClassID != fEffectClassID); michael@0: EffectKey effectKey = GLEffect::GenKey(drawEffect, caps); michael@0: EffectKey textureKey = GrGLProgramEffects::GenTextureKey(drawEffect, caps); michael@0: EffectKey transformKey = GrGLProgramEffects::GenTransformKey(drawEffect); michael@0: EffectKey attribKey = GrGLProgramEffects::GenAttribKey(drawEffect); michael@0: #ifdef SK_DEBUG michael@0: static const EffectKey kIllegalEffectKeyMask = (uint16_t) (~((1U << kEffectKeyBits) - 1)); michael@0: SkASSERT(!(kIllegalEffectKeyMask & effectKey)); michael@0: michael@0: static const EffectKey kIllegalTextureKeyMask = (uint16_t) (~((1U << kTextureKeyBits) - 1)); michael@0: SkASSERT(!(kIllegalTextureKeyMask & textureKey)); michael@0: michael@0: static const EffectKey kIllegalTransformKeyMask = (uint16_t) (~((1U << kTransformKeyBits) - 1)); michael@0: SkASSERT(!(kIllegalTransformKeyMask & transformKey)); michael@0: michael@0: static const EffectKey kIllegalAttribKeyMask = (uint16_t) (~((1U << kAttribKeyBits) - 1)); michael@0: SkASSERT(!(kIllegalAttribKeyMask & textureKey)); michael@0: michael@0: static const EffectKey kIllegalClassIDMask = (uint16_t) (~((1U << kClassIDBits) - 1)); michael@0: SkASSERT(!(kIllegalClassIDMask & fEffectClassID)); michael@0: #endif michael@0: return (fEffectClassID << (kEffectKeyBits+kTextureKeyBits+kTransformKeyBits+kAttribKeyBits)) | michael@0: (attribKey << (kEffectKeyBits+kTextureKeyBits+kTransformKeyBits)) | michael@0: (transformKey << (kEffectKeyBits+kTextureKeyBits)) | michael@0: (textureKey << kEffectKeyBits) | michael@0: (effectKey); michael@0: } michael@0: michael@0: /** Returns a new instance of the appropriate *GL* implementation class michael@0: for the given GrEffect; caller is responsible for deleting michael@0: the object. */ michael@0: virtual GrGLEffect* createGLInstance(const GrDrawEffect& drawEffect) const SK_OVERRIDE { michael@0: return SkNEW_ARGS(GLEffect, (*this, drawEffect)); michael@0: } michael@0: michael@0: /** This class is a singleton. This function returns the single instance. michael@0: */ michael@0: static const GrBackendEffectFactory& getInstance() { michael@0: static SkAlignedSTStorage<1, GrTBackendEffectFactory> gInstanceMem; michael@0: static const GrTBackendEffectFactory* gInstance; michael@0: if (!gInstance) { michael@0: gInstance = SkNEW_PLACEMENT(gInstanceMem.get(), michael@0: GrTBackendEffectFactory); michael@0: } michael@0: return *gInstance; michael@0: } michael@0: michael@0: protected: michael@0: GrTBackendEffectFactory() { michael@0: fEffectClassID = GenID(); michael@0: } michael@0: }; michael@0: michael@0: #endif