aboutsummaryrefslogtreecommitdiffhomepage
path: root/include
diff options
context:
space:
mode:
authorGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-05-18 19:54:48 +0000
committerGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-05-18 19:54:48 +0000
commitae4f96a9e06df44f70c3d5f7324f5a7fabcd1026 (patch)
tree41ef511ed566df9ec627233706afa7749d35e970 /include
parente9678a21ed3afe26f05d04f9979ca1c915f3f90b (diff)
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.h30
-rw-r--r--include/gpu/GrProgramStageFactory.h106
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