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