blob: accb5ce62152effa6b05f7ad10e7583af92ac782 [file] [log] [blame]
/*
* 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 <atomic>
#include "SkTypes.h"
#include "gl/GrGLInterface.h"
////////////////////////////////////////////////////////////////////////////////
// This object is used to track the OpenGL objects. We don't use real
// reference counting (i.e., we don't free the objects when their ref count
// 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
class GrFakeRefObj : SkNoncopyable {
public:
GrFakeRefObj()
: fRef(0)
, fMarkedForDeletion(false)
, fDeleted(false) {
// source for globally unique IDs - 0 is reserved!
static std::atomic<int> fNextID{0};
fID = ++fNextID;
}
virtual ~GrFakeRefObj() {}
void ref() {
fRef++;
}
void unref() {
fRef--;
GrAlwaysAssert(fRef >= 0);
// often in OpenGL a given object may still be in use when the
// 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) {
this->deleteAction();
}
}
int getRefCount() const { return fRef; }
GrGLuint getID() const { return fID; }
void setMarkedForDeletion() { fMarkedForDeletion = true; }
bool getMarkedForDeletion() const { return fMarkedForDeletion; }
bool getDeleted() const { return fDeleted; }
// 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:
int fRef; // ref count
GrGLuint fID; // globally unique ID
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!
void setDeleted() { fDeleted = true; }
};
////////////////////////////////////////////////////////////////////////////////
// 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 new className; }
#endif // GrFakeRefObj_DEFINED