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
diff --git a/include/gpu/GrProgramStageFactory.h b/include/gpu/GrProgramStageFactory.h
new file mode 100644
index 0000000..e73b9ba
--- /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