Remove static effects from the effect memory pool.
Review URL: https://codereview.chromium.org/14081016 git-svn-id: http://skia.googlecode.com/svn/trunk@8828 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
d42f7587e5
commit
d42aca31b9
@ -119,6 +119,24 @@ private:
|
||||
T* fObj;
|
||||
};
|
||||
|
||||
// Calls ~T() in the destructor.
|
||||
template <typename T> class SkAutoTDestroy : SkNoncopyable {
|
||||
public:
|
||||
SkAutoTDestroy(T* obj = NULL) : fObj(obj) {}
|
||||
~SkAutoTDestroy() {
|
||||
if (NULL != fObj) {
|
||||
fObj->~T();
|
||||
}
|
||||
}
|
||||
|
||||
T* get() const { return fObj; }
|
||||
T& operator*() const { SkASSERT(fObj); return *fObj; }
|
||||
T* operator->() const { SkASSERT(fObj); return fObj; }
|
||||
|
||||
private:
|
||||
T* fObj;
|
||||
};
|
||||
|
||||
template <typename T> class SkAutoTDeleteArray : SkNoncopyable {
|
||||
public:
|
||||
SkAutoTDeleteArray(T array[]) : fArray(array) {}
|
||||
|
@ -27,10 +27,15 @@ class SkString;
|
||||
* GrEffectRef ref count reaches zero the scratch GrResources owned by the effect can be recycled
|
||||
* in service of later draws. However, the deferred draw queue may still own direct references to
|
||||
* the underlying GrEffect.
|
||||
*
|
||||
* GrEffectRefs created by new are placed in a per-thread managed pool. The pool is destroyed when
|
||||
* the thread ends. Therefore, all dynamically allocated GrEffectRefs must be unreffed before thread
|
||||
* termination.
|
||||
*/
|
||||
class GrEffectRef : public SkRefCnt {
|
||||
public:
|
||||
SK_DECLARE_INST_COUNT(GrEffectRef);
|
||||
virtual ~GrEffectRef();
|
||||
|
||||
GrEffect* get() { return fEffect; }
|
||||
const GrEffect* get() const { return fEffect; }
|
||||
@ -41,13 +46,18 @@ public:
|
||||
void* operator new(size_t size);
|
||||
void operator delete(void* target);
|
||||
|
||||
void* operator new(size_t size, void* placement) {
|
||||
return ::operator new(size, placement);
|
||||
}
|
||||
void operator delete(void* target, void* placement) {
|
||||
::operator delete(target, placement);
|
||||
}
|
||||
|
||||
private:
|
||||
friend class GrEffect; // to construct these
|
||||
|
||||
explicit GrEffectRef(GrEffect* effect);
|
||||
|
||||
virtual ~GrEffectRef();
|
||||
|
||||
GrEffect* fEffect;
|
||||
|
||||
typedef SkRefCnt INHERITED;
|
||||
@ -63,8 +73,12 @@ private:
|
||||
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.
|
||||
Because almost no code should ever handle a GrEffect directly outside of a GrEffectRef, we
|
||||
privately inherit from GrRefCnt to help prevent accidental direct ref'ing/unref'ing of effects.
|
||||
|
||||
Dynamically allocated GrEffects and their corresponding GrEffectRefs are managed by a per-thread
|
||||
memory pool. The ref count of an effect must reach 0 before the thread terminates and the pool
|
||||
is destroyed. To create a static effect use the macro GR_CREATE_STATIC_EFFECT declared below.
|
||||
*/
|
||||
class GrEffect : private GrRefCnt {
|
||||
public:
|
||||
@ -159,6 +173,13 @@ public:
|
||||
void* operator new(size_t size);
|
||||
void operator delete(void* target);
|
||||
|
||||
void* operator new(size_t size, void* placement) {
|
||||
return ::operator new(size, placement);
|
||||
}
|
||||
void operator delete(void* target, void* placement) {
|
||||
::operator delete(target, placement);
|
||||
}
|
||||
|
||||
/** These functions are used when recording effects into a deferred drawing queue. The inc call
|
||||
keeps the effect alive outside of GrEffectRef while allowing any resources owned by the
|
||||
effect to be returned to the cache for reuse. The dec call must balance the inc call. */
|
||||
@ -209,6 +230,14 @@ protected:
|
||||
return CreateEffectRef(const_cast<GrEffect*>(effect));
|
||||
}
|
||||
|
||||
/** Used by GR_CREATE_STATIC_EFFECT below */
|
||||
static GrEffectRef* CreateStaticEffectRef(void* refStorage, GrEffect* effect) {
|
||||
GrAssert(NULL == effect->fEffectRef);
|
||||
effect->fEffectRef = SkNEW_PLACEMENT_ARGS(refStorage, GrEffectRef, (effect));
|
||||
return effect->fEffectRef;
|
||||
}
|
||||
|
||||
|
||||
/** Helper used in subclass factory functions to unref the effect after it has been wrapped in a
|
||||
GrEffectRef. E.g.:
|
||||
|
||||
@ -285,4 +314,21 @@ inline GrEffectRef::GrEffectRef(GrEffect* effect) {
|
||||
fEffect = effect;
|
||||
}
|
||||
|
||||
/**
|
||||
* This creates an effect outside of the effect memory pool. The effect's destructor will be called
|
||||
* at global destruction time. NAME will be the name of the created GrEffectRef.
|
||||
*/
|
||||
#define GR_CREATE_STATIC_EFFECT(NAME, EFFECT_CLASS, ARGS) \
|
||||
enum { \
|
||||
k_##NAME##_EffectRefOffset = GR_CT_ALIGN_UP(sizeof(EFFECT_CLASS), 8), \
|
||||
k_##NAME##_StorageSize = k_##NAME##_EffectRefOffset + sizeof(GrEffectRef) \
|
||||
}; \
|
||||
static SkAlignedSStorage<k_##NAME##_StorageSize> g_##NAME##_Storage; \
|
||||
static void* NAME##_RefLocation = (char*)g_##NAME##_Storage.get() + k_##NAME##_EffectRefOffset; \
|
||||
static GrEffect* NAME##_Effect SkNEW_PLACEMENT_ARGS(g_##NAME##_Storage.get(), EFFECT_CLASS, ARGS);\
|
||||
static SkAutoTDestroy<GrEffect> NAME##_ad(NAME##_Effect); \
|
||||
static GrEffectRef* NAME(GrEffect::CreateStaticEffectRef(NAME##_RefLocation, NAME##_Effect)); \
|
||||
static SkAutoTDestroy<GrEffectRef> NAME##_Ref_ad(NAME)
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -450,12 +450,9 @@ class QuadEdgeEffect : public GrEffect {
|
||||
public:
|
||||
|
||||
static GrEffectRef* Create() {
|
||||
// we go through this so we only have one copy of each effect
|
||||
static SkAutoTUnref<GrEffectRef> gQuadEdgeEffectRef(
|
||||
CreateEffectRef(AutoEffectUnref(SkNEW(QuadEdgeEffect))));
|
||||
|
||||
gQuadEdgeEffectRef.get()->ref();
|
||||
return gQuadEdgeEffectRef;
|
||||
GR_CREATE_STATIC_EFFECT(gQuadEdgeEffect, QuadEdgeEffect, ());
|
||||
gQuadEdgeEffect->ref();
|
||||
return gQuadEdgeEffect;
|
||||
}
|
||||
|
||||
virtual ~QuadEdgeEffect() {}
|
||||
|
@ -508,12 +508,9 @@ class HairQuadEdgeEffect : public GrEffect {
|
||||
public:
|
||||
|
||||
static GrEffectRef* Create() {
|
||||
// we go through this so we only have one copy of each effect
|
||||
static SkAutoTUnref<GrEffectRef> gHairQuadEdgeEffectRef(
|
||||
CreateEffectRef(AutoEffectUnref(SkNEW(HairQuadEdgeEffect))));
|
||||
|
||||
gHairQuadEdgeEffectRef.get()->ref();
|
||||
return gHairQuadEdgeEffectRef;
|
||||
GR_CREATE_STATIC_EFFECT(gHairQuadEdgeEffect, HairQuadEdgeEffect, ());
|
||||
gHairQuadEdgeEffect->ref();
|
||||
return gHairQuadEdgeEffect;
|
||||
}
|
||||
|
||||
virtual ~HairQuadEdgeEffect() {}
|
||||
@ -609,12 +606,9 @@ class HairLineEdgeEffect : public GrEffect {
|
||||
public:
|
||||
|
||||
static GrEffectRef* Create() {
|
||||
// we go through this so we only have one copy of each effect
|
||||
static SkAutoTUnref<GrEffectRef> gHairLineEdgeEffectRef(
|
||||
CreateEffectRef(AutoEffectUnref(SkNEW(HairLineEdgeEffect))));
|
||||
|
||||
gHairLineEdgeEffectRef.get()->ref();
|
||||
return gHairLineEdgeEffectRef;
|
||||
GR_CREATE_STATIC_EFFECT(gHairLineEdge, HairLineEdgeEffect, ());
|
||||
gHairLineEdge->ref();
|
||||
return gHairLineEdge;
|
||||
}
|
||||
|
||||
virtual ~HairLineEdgeEffect() {}
|
||||
|
@ -30,10 +30,9 @@ class GrGLRectEffect;
|
||||
class GrRectEffect : public GrEffect {
|
||||
public:
|
||||
static GrEffectRef* Create() {
|
||||
static SkAutoTUnref<GrEffectRef> gRectEffectRef(
|
||||
CreateEffectRef(AutoEffectUnref(SkNEW(GrRectEffect))));
|
||||
gRectEffectRef.get()->ref();
|
||||
return gRectEffectRef;
|
||||
GR_CREATE_STATIC_EFFECT(gRectEffect, GrRectEffect, ());
|
||||
gRectEffect->ref();
|
||||
return gRectEffect;
|
||||
}
|
||||
|
||||
virtual ~GrRectEffect() {}
|
||||
|
@ -51,18 +51,15 @@ inline bool circle_stays_circle(const SkMatrix& m) {
|
||||
class CircleEdgeEffect : public GrEffect {
|
||||
public:
|
||||
static GrEffectRef* Create(bool stroke) {
|
||||
// we go through this so we only have one copy of each effect (stroked/filled)
|
||||
static SkAutoTUnref<GrEffectRef> gCircleStrokeEdgeEffectRef(
|
||||
CreateEffectRef(AutoEffectUnref(SkNEW_ARGS(CircleEdgeEffect, (true)))));
|
||||
static SkAutoTUnref<GrEffectRef> gCircleFillEdgeEffectRef(
|
||||
CreateEffectRef(AutoEffectUnref(SkNEW_ARGS(CircleEdgeEffect, (false)))));
|
||||
GR_CREATE_STATIC_EFFECT(gCircleStrokeEdge, CircleEdgeEffect, (true));
|
||||
GR_CREATE_STATIC_EFFECT(gCircleFillEdge, CircleEdgeEffect, (false));
|
||||
|
||||
if (stroke) {
|
||||
gCircleStrokeEdgeEffectRef.get()->ref();
|
||||
return gCircleStrokeEdgeEffectRef;
|
||||
gCircleStrokeEdge->ref();
|
||||
return gCircleStrokeEdge;
|
||||
} else {
|
||||
gCircleFillEdgeEffectRef.get()->ref();
|
||||
return gCircleFillEdgeEffectRef;
|
||||
gCircleFillEdge->ref();
|
||||
return gCircleFillEdge;
|
||||
}
|
||||
}
|
||||
|
||||
@ -162,18 +159,15 @@ GrEffectRef* CircleEdgeEffect::TestCreate(SkMWCRandom* random,
|
||||
class EllipseEdgeEffect : public GrEffect {
|
||||
public:
|
||||
static GrEffectRef* Create(bool stroke) {
|
||||
// we go through this so we only have one copy of each effect (stroked/filled)
|
||||
static SkAutoTUnref<GrEffectRef> gEllipseStrokeEdgeEffectRef(
|
||||
CreateEffectRef(AutoEffectUnref(SkNEW_ARGS(EllipseEdgeEffect, (true)))));
|
||||
static SkAutoTUnref<GrEffectRef> gEllipseFillEdgeEffectRef(
|
||||
CreateEffectRef(AutoEffectUnref(SkNEW_ARGS(EllipseEdgeEffect, (false)))));
|
||||
GR_CREATE_STATIC_EFFECT(gEllipseStrokeEdge, EllipseEdgeEffect, (true));
|
||||
GR_CREATE_STATIC_EFFECT(gEllipseFillEdge, EllipseEdgeEffect, (false));
|
||||
|
||||
if (stroke) {
|
||||
gEllipseStrokeEdgeEffectRef.get()->ref();
|
||||
return gEllipseStrokeEdgeEffectRef;
|
||||
gEllipseStrokeEdge->ref();
|
||||
return gEllipseStrokeEdge;
|
||||
} else {
|
||||
gEllipseFillEdgeEffectRef.get()->ref();
|
||||
return gEllipseFillEdgeEffectRef;
|
||||
gEllipseFillEdge->ref();
|
||||
return gEllipseFillEdge;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user