1 /* 2 * Copyright 2012 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef GrFakeRefObj_DEFINED 9 #define GrFakeRefObj_DEFINED 10 11 #include <atomic> 12 #include "SkTypes.h" 13 #include "gl/GrGLInterface.h" 14 15 //////////////////////////////////////////////////////////////////////////////// 16 // This object is used to track the OpenGL objects. We don't use real 17 // reference counting (i.e., we don't free the objects when their ref count 18 // goes to 0) so that we can detect invalid memory accesses. The refs we 19 // are tracking in this class are actually OpenGL's references to the objects 20 // not "ours" 21 // Each object also gets a unique globally identifying ID 22 class GrFakeRefObj : SkNoncopyable { 23 public: 24 GrFakeRefObj() 25 : fRef(0) 26 , fMarkedForDeletion(false) 27 , fDeleted(false) { 28 29 // source for globally unique IDs - 0 is reserved! 30 static std::atomic<int> fNextID{0}; 31 32 fID = ++fNextID; 33 } 34 virtual ~GrFakeRefObj() {} 35 36 void ref() { 37 fRef++; 38 } 39 void unref() { 40 fRef--; 41 GrAlwaysAssert(fRef >= 0); 42 43 // often in OpenGL a given object may still be in use when the 44 // delete call is made. In these cases the object is marked 45 // for deletion and then freed when it is no longer in use 46 if (0 == fRef && fMarkedForDeletion) { 47 this->deleteAction(); 48 } 49 } 50 int getRefCount() const { return fRef; } 51 52 GrGLuint getID() const { return fID; } 53 54 void setMarkedForDeletion() { fMarkedForDeletion = true; } 55 bool getMarkedForDeletion() const { return fMarkedForDeletion; } 56 57 bool getDeleted() const { return fDeleted; } 58 59 // The deleteAction fires if the object has been marked for deletion but 60 // couldn't be deleted earlier due to refs 61 virtual void deleteAction() { 62 this->setDeleted(); 63 } 64 65 protected: 66 private: 67 int fRef; // ref count 68 GrGLuint fID; // globally unique ID 69 bool fMarkedForDeletion; 70 // The deleted flag is only set when OpenGL thinks the object is deleted 71 // It is obviously still allocated w/in this framework 72 bool fDeleted; 73 74 // setDeleted should only ever appear in the deleteAction method! 75 void setDeleted() { fDeleted = true; } 76 }; 77 78 //////////////////////////////////////////////////////////////////////////////// 79 // Each class derived from GrFakeRefObj should use this macro to add a 80 // factory creation entry point. This entry point is used by the GrGLDebug 81 // object to instantiate the various objects 82 // all globally unique IDs 83 #define GR_DEFINE_CREATOR(className) \ 84 public: \ 85 static GrFakeRefObj *create##className() { return new className; } 86 87 #endif // GrFakeRefObj_DEFINED 88