diff options
author | bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-05-18 19:54:48 +0000 |
---|---|---|
committer | bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-05-18 19:54:48 +0000 |
commit | ae4f96a9e06df44f70c3d5f7324f5a7fabcd1026 (patch) | |
tree | 41ef511ed566df9ec627233706afa7749d35e970 /include | |
parent | e9678a21ed3afe26f05d04f9979ca1c915f3f90b (diff) | |
download | skia-ae4f96a9e06df44f70c3d5f7324f5a7fabcd1026.tar.gz |
Some refactoring of GrCustomStage and friends
Review URL: http://codereview.appspot.com/6209071/
git-svn-id: http://skia.googlecode.com/svn/trunk@4003 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'include')
-rw-r--r-- | include/gpu/GrCustomStage.h | 30 | ||||
-rw-r--r-- | include/gpu/GrProgramStageFactory.h | 106 |
2 files changed, 129 insertions, 7 deletions
diff --git a/include/gpu/GrCustomStage.h b/include/gpu/GrCustomStage.h index 64bcce3036..908b10d6ec 100644 --- a/include/gpu/GrCustomStage.h +++ b/include/gpu/GrCustomStage.h @@ -9,16 +9,18 @@ #define GrCustomStage_DEFINED #include "GrRefCnt.h" +#include "GrNoncopyable.h" +#include "GrProgramStageFactory.h" +#include "SkTemplates.h" class GrContext; -class GrProgramStageFactory; /** Provides custom vertex shader, fragment shader, uniform data for a - particular stage of the Ganesh shading pipeline. - TODO: may want to refcount these? */ + particular stage of the Ganesh shading pipeline. */ class GrCustomStage : public GrRefCnt { public: + typedef GrProgramStageFactory::StageKey StageKey; GrCustomStage(); virtual ~GrCustomStage(); @@ -31,10 +33,24 @@ public: stage guaranteed to produce an opaque output? */ virtual bool isOpaque(bool inputTextureIsOpaque) const; - /** This pointer, besides creating back-end-specific helper - objects, is used for run-time-type-identification. Every - subclass must return a consistent unique value for it. */ - virtual GrProgramStageFactory* getFactory() const = 0; + /** This object, besides creating back-end-specific helper + objects, is used for run-time-type-identification. The factory should be + an instance of templated class, GrTProgramStageFactory. It is templated + on the subclass of GrCustomStage. The subclass must have a nested type + (or typedef) named GLProgramStage which will be the subclass of + GrGLProgramStage created by the factory. + + Example: + class MyCustomStage : public GrCustomStage { + ... + virtual const GrProgramStageFactory& getFactory() const + SK_OVERRIDE { + return GrTProgramStageFactory<MyCustomStage>::getInstance(); + } + ... + }; + */ + virtual const GrProgramStageFactory& getFactory() const = 0; /** Returns true if the other custom stage will generate equal output. diff --git a/include/gpu/GrProgramStageFactory.h b/include/gpu/GrProgramStageFactory.h new file mode 100644 index 0000000000..e73b9ba7df --- /dev/null +++ b/include/gpu/GrProgramStageFactory.h @@ -0,0 +1,106 @@ +/* + * 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 GrProgramStageFactory_DEFINED +#define GrProgramStageFactory_DEFINED + +#include "GrTypes.h" + +/** Given a GrCustomStage of a particular type, creates the corresponding + graphics-backend-specific GrProgramStage. Also tracks equivalence + of shaders generated via a key. + */ + +class GrCustomStage; +class GrGLProgramStage; + +class GrProgramStageFactory : public GrNoncopyable { +public: + typedef uint16_t StageKey; + enum { + kProgramStageKeyBits = 10, + }; + + virtual StageKey stageKey(const GrCustomStage* stage) const = 0; + virtual GrGLProgramStage* createGLInstance( + const GrCustomStage* stage) const = 0; + + bool operator ==(const GrProgramStageFactory& b) const { + return fStageClassID == b.fStageClassID; + } + bool operator !=(const GrProgramStageFactory& b) const { + return !(*this == b); + } + +protected: + enum { + kIllegalStageClassID = 0, + }; + + GrProgramStageFactory() { + fStageClassID = kIllegalStageClassID; + } + + static StageKey GenID() { + // fCurrStageClassID has been initialized to kIllegalStageClassID. 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(&fCurrStageClassID) + 1; + GrAssert(id < (1 << (8 * sizeof(StageKey) - kProgramStageKeyBits))); + return id; + } + + StageKey fStageClassID; + +private: + static int32_t fCurrStageClassID; +}; + +template <typename StageClass> +class GrTProgramStageFactory : public GrProgramStageFactory { + +public: + typedef typename StageClass::GLProgramStage GLProgramStage; + + /** Returns an value that idenitifes the shader code generated by + a GrCustomStage. This enables caching of generated shaders. Part of the + id identifies the GrCustomShader subclass. The remainder is based + on the aspects of the GrCustomStage object's configuration that affect + code generation. */ + virtual StageKey stageKey(const GrCustomStage* stage) const SK_OVERRIDE { + GrAssert(kIllegalStageClassID != fStageClassID); + StageKey stageID = GLProgramStage::GenKey(stage); + static const StageKey kIllegalIDMask = + ~((1 << kProgramStageKeyBits) - 1); + GrAssert(!(kIllegalIDMask & stageID)); + return fStageClassID | stageID; + } + + /** Returns a new instance of the appropriate *GL* implementation class + for the given GrCustomStage; caller is responsible for deleting + the object. */ + virtual GLProgramStage* createGLInstance( + const GrCustomStage* stage) const SK_OVERRIDE { + return new GLProgramStage(stage); + } + + static const GrProgramStageFactory& getInstance() { + static SkAlignedSTStorage<1, GrTProgramStageFactory> gInstanceMem; + static const GrTProgramStageFactory* gInstance; + if (!gInstance) { + gInstance = new (gInstanceMem.get()) GrTProgramStageFactory(); + } + return *gInstance; + } + +protected: + GrTProgramStageFactory() { + fStageClassID = GenID() << kProgramStageKeyBits; + } +}; + +#endif |