| /* |
| * 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 |