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