Home | History | Annotate | Download | only in debug
      1 
      2 /*
      3  * Copyright 2012 Google Inc.
      4  *
      5  * Use of this source code is governed by a BSD-style license that can be
      6  * found in the LICENSE file.
      7  */
      8 
      9 #ifndef GrFakeRefObj_DEFINED
     10 #define GrFakeRefObj_DEFINED
     11 
     12 #include "gl/GrGLInterface.h"
     13 #include "GrNoncopyable.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 : public GrNoncopyable {
     23 public:
     24     GrFakeRefObj()
     25         : fRef(0)
     26         , fHighRefCount(0)
     27         , fMarkedForDeletion(false)
     28         , fDeleted(false) {
     29 
     30         // source for globally unique IDs - 0 is reserved!
     31         static int fNextID = 0;
     32 
     33         fID = ++fNextID;
     34     }
     35     virtual ~GrFakeRefObj() {};
     36 
     37     void ref() {
     38         fRef++;
     39         if (fHighRefCount < fRef) {
     40             fHighRefCount = fRef;
     41         }
     42     }
     43     void unref() {
     44         fRef--;
     45         GrAlwaysAssert(fRef >= 0);
     46 
     47         // often in OpenGL a given object may still be in use when the
     48         // delete call is made. In these cases the object is marked
     49         // for deletion and then freed when it is no longer in use
     50         if (0 == fRef && fMarkedForDeletion) {
     51             this->deleteAction();
     52         }
     53     }
     54     int getRefCount() const             { return fRef; }
     55     int getHighRefCount() const         { return fHighRefCount; }
     56 
     57     GrGLuint getID() const              { return fID; }
     58 
     59     void setMarkedForDeletion()         { fMarkedForDeletion = true; }
     60     bool getMarkedForDeletion() const   { return fMarkedForDeletion; }
     61 
     62     bool getDeleted() const             { return fDeleted; }
     63 
     64     // The deleteAction fires if the object has been marked for deletion but
     65     // couldn't be deleted earlier due to refs
     66     virtual void deleteAction() {
     67         this->setDeleted();
     68     }
     69 
     70 protected:
     71 private:
     72     int         fRef;               // ref count
     73     int         fHighRefCount;      // high water mark of the ref count
     74     GrGLuint    fID;                // globally unique ID
     75     bool        fMarkedForDeletion;
     76     // The deleted flag is only set when OpenGL thinks the object is deleted
     77     // It is obviously still allocated w/in this framework
     78     bool        fDeleted;
     79 
     80     // setDeleted should only ever appear in the deleteAction method!
     81     void setDeleted()                   { fDeleted = true; }
     82 };
     83 
     84 ////////////////////////////////////////////////////////////////////////////////
     85 // Each class derived from GrFakeRefObj should use this macro to add a
     86 // factory creation entry point. This entry point is used by the GrGLDebug
     87 // object to instantiate the various objects
     88 // all globally unique IDs
     89 #define GR_DEFINE_CREATOR(className)                        \
     90     public:                                                 \
     91     static GrFakeRefObj *create ## className() {            \
     92         return SkNEW(className);                            \
     93     }
     94 
     95 #endif // GrFakeRefObj_DEFINED
     96