2012-04-05 14:40:53 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* 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 GrFakeRefObj_DEFINED
|
|
|
|
#define GrFakeRefObj_DEFINED
|
|
|
|
|
|
|
|
#include "gl/GrGLInterface.h"
|
2012-04-16 16:24:35 +00:00
|
|
|
#include "GrNoncopyable.h"
|
2012-04-05 14:40:53 +00:00
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// This object is used to track the OpenGL objects. We don't use real
|
2012-08-23 18:09:54 +00:00
|
|
|
// reference counting (i.e., we don't free the objects when their ref count
|
2012-04-05 14:40:53 +00:00
|
|
|
// goes to 0) so that we can detect invalid memory accesses. The refs we
|
|
|
|
// are tracking in this class are actually OpenGL's references to the objects
|
|
|
|
// not "ours"
|
|
|
|
// Each object also gets a unique globally identifying ID
|
2012-04-16 16:24:35 +00:00
|
|
|
class GrFakeRefObj : public GrNoncopyable {
|
2012-04-05 14:40:53 +00:00
|
|
|
public:
|
2012-08-23 18:09:54 +00:00
|
|
|
GrFakeRefObj()
|
2012-04-05 14:40:53 +00:00
|
|
|
: fRef(0)
|
|
|
|
, fHighRefCount(0)
|
|
|
|
, fMarkedForDeletion(false)
|
|
|
|
, fDeleted(false) {
|
|
|
|
|
2012-04-16 16:24:35 +00:00
|
|
|
// source for globally unique IDs - 0 is reserved!
|
2012-08-23 18:09:54 +00:00
|
|
|
static int fNextID = 0;
|
2012-04-05 14:40:53 +00:00
|
|
|
|
|
|
|
fID = ++fNextID;
|
|
|
|
}
|
|
|
|
virtual ~GrFakeRefObj() {};
|
|
|
|
|
2012-08-23 18:09:54 +00:00
|
|
|
void ref() {
|
|
|
|
fRef++;
|
2012-04-05 14:40:53 +00:00
|
|
|
if (fHighRefCount < fRef) {
|
|
|
|
fHighRefCount = fRef;
|
|
|
|
}
|
|
|
|
}
|
2012-08-23 18:09:54 +00:00
|
|
|
void unref() {
|
|
|
|
fRef--;
|
2012-04-05 14:40:53 +00:00
|
|
|
GrAlwaysAssert(fRef >= 0);
|
|
|
|
|
2012-08-23 18:09:54 +00:00
|
|
|
// often in OpenGL a given object may still be in use when the
|
2012-04-05 14:40:53 +00:00
|
|
|
// delete call is made. In these cases the object is marked
|
|
|
|
// for deletion and then freed when it is no longer in use
|
|
|
|
if (0 == fRef && fMarkedForDeletion) {
|
2012-08-23 18:09:54 +00:00
|
|
|
this->deleteAction();
|
2012-04-05 14:40:53 +00:00
|
|
|
}
|
|
|
|
}
|
2012-04-16 16:24:35 +00:00
|
|
|
int getRefCount() const { return fRef; }
|
|
|
|
int getHighRefCount() const { return fHighRefCount; }
|
2012-04-05 14:40:53 +00:00
|
|
|
|
2012-04-16 16:24:35 +00:00
|
|
|
GrGLuint getID() const { return fID; }
|
2012-04-05 14:40:53 +00:00
|
|
|
|
2012-04-16 16:24:35 +00:00
|
|
|
void setMarkedForDeletion() { fMarkedForDeletion = true; }
|
|
|
|
bool getMarkedForDeletion() const { return fMarkedForDeletion; }
|
2012-04-05 14:40:53 +00:00
|
|
|
|
2012-04-16 16:24:35 +00:00
|
|
|
bool getDeleted() const { return fDeleted; }
|
2012-04-05 14:40:53 +00:00
|
|
|
|
|
|
|
// The deleteAction fires if the object has been marked for deletion but
|
|
|
|
// couldn't be deleted earlier due to refs
|
|
|
|
virtual void deleteAction() {
|
|
|
|
this->setDeleted();
|
|
|
|
}
|
|
|
|
|
|
|
|
protected:
|
|
|
|
private:
|
2012-04-16 16:24:35 +00:00
|
|
|
int fRef; // ref count
|
2012-04-05 14:40:53 +00:00
|
|
|
int fHighRefCount; // high water mark of the ref count
|
2012-04-16 16:24:35 +00:00
|
|
|
GrGLuint fID; // globally unique ID
|
2012-04-05 14:40:53 +00:00
|
|
|
bool fMarkedForDeletion;
|
|
|
|
// The deleted flag is only set when OpenGL thinks the object is deleted
|
|
|
|
// It is obviously still allocated w/in this framework
|
|
|
|
bool fDeleted;
|
|
|
|
|
|
|
|
// setDeleted should only ever appear in the deleteAction method!
|
2012-04-16 16:24:35 +00:00
|
|
|
void setDeleted() { fDeleted = true; }
|
2012-04-05 14:40:53 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Each class derived from GrFakeRefObj should use this macro to add a
|
|
|
|
// factory creation entry point. This entry point is used by the GrGLDebug
|
|
|
|
// object to instantiate the various objects
|
|
|
|
// all globally unique IDs
|
|
|
|
#define GR_DEFINE_CREATOR(className) \
|
|
|
|
public: \
|
|
|
|
static GrFakeRefObj *create ## className() { \
|
|
|
|
return SkNEW(className); \
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif // GrFakeRefObj_DEFINED
|