Let them eat GrEffectRef.
Changes the remaining existing code that operates on naked GrEffects to GrEffectRef.
Review URL: https://codereview.appspot.com/7124058
git-svn-id: http://skia.googlecode.com/svn/trunk@7321 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/include/gpu/GrEffect.h b/include/gpu/GrEffect.h
index 507bd57..0e6aab0 100644
--- a/include/gpu/GrEffect.h
+++ b/include/gpu/GrEffect.h
@@ -34,6 +34,9 @@
GrEffect* get() { return fEffect; }
const GrEffect* get() const { return fEffect; }
+ const GrEffect* operator-> () { return fEffect; }
+ const GrEffect* operator-> () const { return fEffect; }
+
void* operator new(size_t size);
void operator delete(void* target);
@@ -58,8 +61,11 @@
GrEffect subclass objects should be created by factory functions that return GrEffectRef.
There is no public way to wrap a GrEffect in a GrEffectRef. Thus, a factory should be a static
member function of a GrEffect subclass.
+
+ Because almost no code should ever handle a GrEffect outside of a GrEffectRef, we privately
+ inherit from GrRefCnt to help prevent accidental direct ref'ing/unref'ing of effects.
*/
-class GrEffect : public GrRefCnt {
+class GrEffect : private GrRefCnt {
public:
SK_DECLARE_INST_COUNT(GrEffect)
@@ -113,16 +119,16 @@
computed by the GrBackendEffectFactory:
effectA.getFactory().glEffectKey(effectA) == effectB.getFactory().glEffectKey(effectB).
*/
- bool isEqual(const GrEffect& other) const {
- if (&this->getFactory() != &other.getFactory()) {
+ bool isEqual(const GrEffectRef& other) const {
+ if (&this->getFactory() != &other->getFactory()) {
return false;
}
bool result = this->onIsEqual(other);
#if GR_DEBUG
if (result) {
- GrAssert(this->numTextures() == other.numTextures());
+ GrAssert(this->numTextures() == other->numTextures());
for (int i = 0; i < this->numTextures(); ++i) {
- GrAssert(*fTextureAccesses[i] == *other.fTextureAccesses[i]);
+ GrAssert(*fTextureAccesses[i] == *other->fTextureAccesses[i]);
}
}
#endif
@@ -154,6 +160,11 @@
void* operator new(size_t size);
void operator delete(void* target);
+ /** These use non-standard names because GrEffects should only be ref'ed an unref'ed deep in
+ the bowels. Rendering code should use GrEffectRef. */
+ void addRef() { this->ref(); }
+ void subRef() { this->unref(); }
+
protected:
/**
* Subclasses call this from their constructor to register GrTextureAcceses. The effect subclass
@@ -164,7 +175,8 @@
GrEffect() : fEffectRef(NULL) {};
- /** This should be called by GrEffect subclass factories */
+ /** This should be called by GrEffect subclass factories. See the comment on AutoEffectUnref for
+ an example factory function. */
static GrEffectRef* CreateEffectRef(GrEffect* effect) {
if (NULL == effect->fEffectRef) {
effect->fEffectRef = SkNEW_ARGS(GrEffectRef, (effect));
@@ -175,16 +187,41 @@
return effect->fEffectRef;
}
+ /** Helper used in subclass factory functions to unref the effect after it has been wrapped in a
+ GrEffectRef. E.g.:
+
+ class EffectSubclass : public GrEffect {
+ public:
+ GrEffectRef* Create(ParamType1 param1, ParamType2 param2, ...) {
+ AutoEffectUnref effect(SkNEW_ARGS(EffectSubclass, (param1, param2, ...)));
+ return CreateEffectRef(effect);
+ }
+ */
+ class AutoEffectUnref {
+ public:
+ AutoEffectUnref(GrEffect* effect) : fEffect(effect) { }
+ ~AutoEffectUnref() { fEffect->subRef(); }
+ operator GrEffect*() { return fEffect; }
+ private:
+ GrEffect* fEffect;
+ };
+
+ /** Helper for getting the GrEffect out of a GrEffectRef and down-casting to a GrEffect subclass
+ */
+ template <typename T>
+ static const T& CastEffect(const GrEffectRef& effectRef) {
+ GrAssert(NULL != effectRef.get());
+ return *static_cast<const T*>(effectRef.get());
+ }
+
private:
/** Subclass implements this to support isEqual(). It will only be called if it is known that
- the two effects are of the same subclass (i.e. they return the same object
- from getFactory()).*/
- virtual bool onIsEqual(const GrEffect& other) const = 0;
+ the two effects are of the same subclass (i.e. they return the same object from
+ getFactory()).*/
+ virtual bool onIsEqual(const GrEffectRef& other) const = 0;
- void EffectRefDestroyed() {
- fEffectRef = NULL;
- }
+ void EffectRefDestroyed() { fEffectRef = NULL; }
friend class GrEffectRef; // to call GrEffectRef destroyed