Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(52)

Side by Side Diff: src/gpu/gl/GrGLCreateNullInterface.cpp

Issue 19678010: Improve null gpu's memory handling (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: Added recycling of buffer id slots Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « gm/gmmain.cpp ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2011 Google Inc. 2 * Copyright 2011 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 8
9 #include "gl/GrGLInterface.h" 9 #include "gl/GrGLInterface.h"
10 #include "GrGLDefines.h" 10 #include "GrGLDefines.h"
11 #include "SkTDArray.h" 11 #include "SkTDArray.h"
12 #include "GrGLNoOpInterface.h" 12 #include "GrGLNoOpInterface.h"
13 13
14 // Functions not declared in GrGLBogusInterface.h (not common with the Debug GL interface). 14 // Functions not declared in GrGLBogusInterface.h (not common with the Debug GL interface).
15 15
16 namespace { // added to suppress 'no previous prototype' warning 16 namespace { // added to suppress 'no previous prototype' warning
17 17
18 class GrBufferObj {
19 public:
20 GrBufferObj(GrGLuint id) : fID(id), fDataPtr(NULL), fSize(0), fMapped(false) {
21 }
22 ~GrBufferObj() { SkDELETE_ARRAY(fDataPtr); }
23
24 void allocate(GrGLint size, const GrGLchar* dataPtr) {
25 if (NULL != fDataPtr) {
26 GrAssert(0 != fSize);
27 SkDELETE_ARRAY(fDataPtr);
28 }
29
30 fSize = size;
31 fDataPtr = SkNEW_ARRAY(char, size);
32 }
33
34 GrGLuint id() const { return fID; }
35 GrGLchar* dataPtr() { return fDataPtr; }
36 GrGLint size() const { return fSize; }
37
38 void setMapped(bool mapped) { fMapped = mapped; }
39 bool mapped() const { return fMapped; }
40
41 private:
42 GrGLuint fID;
43 GrGLchar* fDataPtr;
44 GrGLint fSize; // size in bytes
45 bool fMapped;
46 };
47
48 // In debug builds we do asserts that ensure we agree with GL about when a buffe r
49 // is mapped.
50 static SkTDArray<GrBufferObj*> gBuffers; // slot 0 is reserved for head of free list
51 static GrGLuint gCurrArrayBuffer;
52 static GrGLuint gCurrElementArrayBuffer;
53
54 static GrBufferObj* look_up(GrGLuint id) {
55 GrBufferObj* buffer = gBuffers[id];
56 GrAssert(NULL != buffer && buffer->id() == id);
57 return buffer;
58 }
59
60 static GrBufferObj* create_buffer() {
61 if (0 == gBuffers.count()) {
62 // slot zero is reserved for the head of the free list
63 *gBuffers.append() = NULL;
64 }
65
66 GrGLuint id;
67 GrBufferObj* buffer;
68
69 if (NULL == gBuffers[0]) {
70 // no free slots - create a new one
71 id = gBuffers.count();
72 buffer = SkNEW_ARGS(GrBufferObj, (id));
73 gBuffers.append(1, &buffer);
74 } else {
75 // recycle a slot from the free list
76 id = (GrGLuint) gBuffers[0];
77 gBuffers[0] = gBuffers[id];
78
79 buffer = SkNEW_ARGS(GrBufferObj, (id));
80 gBuffers[id] = buffer;
81 }
82
83 return buffer;
84 }
85
86 static void delete_buffer(GrBufferObj* buffer) {
87 GrAssert(gBuffers.count() > 0);
88
89 GrGLuint id = buffer->id();
90 SkDELETE(buffer);
91
92 // Add this slot to the free list
93 gBuffers[id] = gBuffers[0];
94 gBuffers[0] = (GrBufferObj*) id;
95 }
96
18 GrGLvoid GR_GL_FUNCTION_TYPE nullGLActiveTexture(GrGLenum texture) {} 97 GrGLvoid GR_GL_FUNCTION_TYPE nullGLActiveTexture(GrGLenum texture) {}
19 GrGLvoid GR_GL_FUNCTION_TYPE nullGLAttachShader(GrGLuint program, GrGLuint shade r) {} 98 GrGLvoid GR_GL_FUNCTION_TYPE nullGLAttachShader(GrGLuint program, GrGLuint shade r) {}
20 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBeginQuery(GrGLenum target, GrGLuint id) {} 99 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBeginQuery(GrGLenum target, GrGLuint id) {}
21 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindAttribLocation(GrGLuint program, GrGLuint index, const char* name) {} 100 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindAttribLocation(GrGLuint program, GrGLuint index, const char* name) {}
22 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindTexture(GrGLenum target, GrGLuint texture ) {} 101 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindTexture(GrGLenum target, GrGLuint texture ) {}
23 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindVertexArray(GrGLuint id) {} 102 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindVertexArray(GrGLuint id) {}
24 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBufferData(GrGLenum target, GrGLsizeiptr size , const GrGLvoid* data, GrGLenum usage) {} 103
104 GrGLvoid GR_GL_FUNCTION_TYPE nullGLGenBuffers(GrGLsizei n, GrGLuint* ids) {
105
106 for (int i = 0; i < n; ++i) {
107 GrBufferObj* buffer = create_buffer();
108 ids[i] = buffer->id();
109 }
110 }
111
112 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBufferData(GrGLenum target,
113 GrGLsizeiptr size,
114 const GrGLvoid* data,
115 GrGLenum usage) {
116 GrGLuint id = 0;
117
118 switch (target) {
119 case GR_GL_ARRAY_BUFFER:
120 id = gCurrArrayBuffer;
121 break;
122 case GR_GL_ELEMENT_ARRAY_BUFFER:
123 id = gCurrElementArrayBuffer;
124 break;
125 default:
126 GrCrash("Unexpected target to nullGLBufferData");
127 break;
128 }
129
130 if (id > 0) {
131 GrBufferObj* buffer = look_up(id);
132 buffer->allocate(size, (const GrGLchar*) data);
133 }
134 }
135
25 GrGLvoid GR_GL_FUNCTION_TYPE nullGLPixelStorei(GrGLenum pname, GrGLint param) {} 136 GrGLvoid GR_GL_FUNCTION_TYPE nullGLPixelStorei(GrGLenum pname, GrGLint param) {}
26 GrGLvoid GR_GL_FUNCTION_TYPE nullGLReadPixels(GrGLint x, GrGLint y, GrGLsizei wi dth, GrGLsizei height, GrGLenum format, GrGLenum type, GrGLvoid* pixels) {} 137 GrGLvoid GR_GL_FUNCTION_TYPE nullGLReadPixels(GrGLint x, GrGLint y, GrGLsizei wi dth, GrGLsizei height, GrGLenum format, GrGLenum type, GrGLvoid* pixels) {}
27 GrGLvoid GR_GL_FUNCTION_TYPE nullGLUseProgram(GrGLuint program) {} 138 GrGLvoid GR_GL_FUNCTION_TYPE nullGLUseProgram(GrGLuint program) {}
28 GrGLvoid GR_GL_FUNCTION_TYPE nullGLViewport(GrGLint x, GrGLint y, GrGLsizei widt h, GrGLsizei height) {} 139 GrGLvoid GR_GL_FUNCTION_TYPE nullGLViewport(GrGLint x, GrGLint y, GrGLsizei widt h, GrGLsizei height) {}
29 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindFramebuffer(GrGLenum target, GrGLuint fra mebuffer) {} 140 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindFramebuffer(GrGLenum target, GrGLuint fra mebuffer) {}
30 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindRenderbuffer(GrGLenum target, GrGLuint re nderbuffer) {} 141 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindRenderbuffer(GrGLenum target, GrGLuint re nderbuffer) {}
31 GrGLvoid GR_GL_FUNCTION_TYPE nullGLDeleteFramebuffers(GrGLsizei n, const GrGLuin t *framebuffers) {} 142 GrGLvoid GR_GL_FUNCTION_TYPE nullGLDeleteFramebuffers(GrGLsizei n, const GrGLuin t *framebuffers) {}
32 GrGLvoid GR_GL_FUNCTION_TYPE nullGLDeleteRenderbuffers(GrGLsizei n, const GrGLui nt *renderbuffers) {} 143 GrGLvoid GR_GL_FUNCTION_TYPE nullGLDeleteRenderbuffers(GrGLsizei n, const GrGLui nt *renderbuffers) {}
33 GrGLvoid GR_GL_FUNCTION_TYPE nullGLFramebufferRenderbuffer(GrGLenum target, GrGL enum attachment, GrGLenum renderbuffertarget, GrGLuint renderbuffer) {} 144 GrGLvoid GR_GL_FUNCTION_TYPE nullGLFramebufferRenderbuffer(GrGLenum target, GrGL enum attachment, GrGLenum renderbuffertarget, GrGLuint renderbuffer) {}
34 GrGLvoid GR_GL_FUNCTION_TYPE nullGLFramebufferTexture2D(GrGLenum target, GrGLenu m attachment, GrGLenum textarget, GrGLuint texture, GrGLint level) {} 145 GrGLvoid GR_GL_FUNCTION_TYPE nullGLFramebufferTexture2D(GrGLenum target, GrGLenu m attachment, GrGLenum textarget, GrGLuint texture, GrGLint level) {}
35 146
36 GrGLuint GR_GL_FUNCTION_TYPE nullGLCreateProgram() { 147 GrGLuint GR_GL_FUNCTION_TYPE nullGLCreateProgram() {
37 static int gCurrID = 0; 148 static GrGLuint gCurrID = 0;
38 return ++gCurrID; 149 return ++gCurrID;
39 } 150 }
40 151
41 GrGLuint GR_GL_FUNCTION_TYPE nullGLCreateShader(GrGLenum type) { 152 GrGLuint GR_GL_FUNCTION_TYPE nullGLCreateShader(GrGLenum type) {
42 static int gCurrID = 0; 153 static GrGLuint gCurrID = 0;
43 return ++gCurrID; 154 return ++gCurrID;
44 } 155 }
45 156
46 // same delete used for shaders and programs 157 // same delete used for shaders and programs
47 GrGLvoid GR_GL_FUNCTION_TYPE nullGLDelete(GrGLuint program) { 158 GrGLvoid GR_GL_FUNCTION_TYPE nullGLDelete(GrGLuint program) {
48 } 159 }
49 160
50 // In debug builds we do asserts that ensure we agree with GL about when a buffe r
51 // is mapped.
52 static SkTDArray<GrGLuint> gMappedBuffers;
53 static GrGLuint gCurrArrayBuffer;
54 static GrGLuint gCurrElementArrayBuffer;
55
56 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindBuffer(GrGLenum target, GrGLuint buffer) { 161 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindBuffer(GrGLenum target, GrGLuint buffer) {
57 switch (target) { 162 switch (target) {
58 case GR_GL_ARRAY_BUFFER: 163 case GR_GL_ARRAY_BUFFER:
59 gCurrArrayBuffer = buffer; 164 gCurrArrayBuffer = buffer;
60 break; 165 break;
61 case GR_GL_ELEMENT_ARRAY_BUFFER: 166 case GR_GL_ELEMENT_ARRAY_BUFFER:
62 gCurrElementArrayBuffer = buffer; 167 gCurrElementArrayBuffer = buffer;
63 break; 168 break;
64 } 169 }
65 } 170 }
66 171
67 // deleting a bound buffer has the side effect of binding 0 172 // deleting a bound buffer has the side effect of binding 0
68 GrGLvoid GR_GL_FUNCTION_TYPE nullGLDeleteBuffers(GrGLsizei n, const GrGLuint* id s) { 173 GrGLvoid GR_GL_FUNCTION_TYPE nullGLDeleteBuffers(GrGLsizei n, const GrGLuint* id s) {
69 for (int i = 0; i < n; ++i) { 174 for (int i = 0; i < n; ++i) {
70 if (ids[i] == gCurrArrayBuffer) { 175 if (ids[i] == gCurrArrayBuffer) {
71 gCurrArrayBuffer = 0; 176 gCurrArrayBuffer = 0;
72 } 177 }
73 if (ids[i] == gCurrElementArrayBuffer) { 178 if (ids[i] == gCurrElementArrayBuffer) {
74 gCurrElementArrayBuffer = 0; 179 gCurrElementArrayBuffer = 0;
75 } 180 }
76 for (int j = 0; j < gMappedBuffers.count(); ++j) { 181
77 if (gMappedBuffers[j] == ids[i]) { 182 GrBufferObj* buffer = look_up(ids[i]);
78 gMappedBuffers.remove(j); 183 delete_buffer(buffer);
79 // don't break b/c we didn't check for dupes on insert
80 --j;
81 }
82 }
83 } 184 }
84 } 185 }
85 186
86 GrGLvoid* GR_GL_FUNCTION_TYPE nullGLMapBuffer(GrGLenum target, GrGLenum access) { 187 GrGLvoid* GR_GL_FUNCTION_TYPE nullGLMapBuffer(GrGLenum target, GrGLenum access) {
87 // We just reserve 32MB of RAM for all locks and hope its big enough 188
88 static SkAutoMalloc gBufferData(32 * (1 << 20)); 189 GrGLuint id = 0;
89 GrGLuint buf = 0;
90 switch (target) { 190 switch (target) {
91 case GR_GL_ARRAY_BUFFER: 191 case GR_GL_ARRAY_BUFFER:
92 buf = gCurrArrayBuffer; 192 id = gCurrArrayBuffer;
93 break; 193 break;
94 case GR_GL_ELEMENT_ARRAY_BUFFER: 194 case GR_GL_ELEMENT_ARRAY_BUFFER:
95 buf = gCurrElementArrayBuffer; 195 id = gCurrElementArrayBuffer;
96 break; 196 break;
97 } 197 }
98 if (buf) { 198
99 *gMappedBuffers.append() = buf; 199 if (id > 0) {
200 GrBufferObj* buffer = look_up(id);
201 GrAssert(!buffer->mapped());
202 buffer->setMapped(true);
203 return buffer->dataPtr();
100 } 204 }
101 return gBufferData.get(); 205
206 GrAssert(false);
207 return NULL; // no buffer bound to target
102 } 208 }
103 209
104 GrGLboolean GR_GL_FUNCTION_TYPE nullGLUnmapBuffer(GrGLenum target) { 210 GrGLboolean GR_GL_FUNCTION_TYPE nullGLUnmapBuffer(GrGLenum target) {
105 GrGLuint buf = 0; 211 GrGLuint id = 0;
106 switch (target) { 212 switch (target) {
107 case GR_GL_ARRAY_BUFFER: 213 case GR_GL_ARRAY_BUFFER:
108 buf = gCurrArrayBuffer; 214 id = gCurrArrayBuffer;
109 break; 215 break;
110 case GR_GL_ELEMENT_ARRAY_BUFFER: 216 case GR_GL_ELEMENT_ARRAY_BUFFER:
111 buf = gCurrElementArrayBuffer; 217 id = gCurrElementArrayBuffer;
112 break; 218 break;
113 } 219 }
114 if (buf) { 220 if (id > 0) {
115 for (int i = 0; i < gMappedBuffers.count(); ++i) { 221 GrBufferObj* buffer = look_up(id);
116 if (gMappedBuffers[i] == buf) { 222 GrAssert(buffer->mapped());
117 gMappedBuffers.remove(i); 223 buffer->setMapped(false);
118 // don't break b/c we didn't check for dupes on insert 224 return GR_GL_TRUE;
119 --i;
120 }
121 }
122 } 225 }
123 return GR_GL_TRUE; 226
227 GrAlwaysAssert(false);
228 return GR_GL_FALSE; // GR_GL_INVALID_OPERATION;
124 } 229 }
125 230
126 GrGLvoid GR_GL_FUNCTION_TYPE nullGLGetBufferParameteriv(GrGLenum target, GrGLenu m pname, GrGLint* params) { 231 GrGLvoid GR_GL_FUNCTION_TYPE nullGLGetBufferParameteriv(GrGLenum target, GrGLenu m pname, GrGLint* params) {
127 switch (pname) { 232 switch (pname) {
128 case GR_GL_BUFFER_MAPPED: { 233 case GR_GL_BUFFER_MAPPED: {
129 *params = GR_GL_FALSE; 234 *params = GR_GL_FALSE;
130 GrGLuint buf = 0; 235 GrGLuint id = 0;
131 switch (target) { 236 switch (target) {
132 case GR_GL_ARRAY_BUFFER: 237 case GR_GL_ARRAY_BUFFER:
133 buf = gCurrArrayBuffer; 238 id = gCurrArrayBuffer;
134 break; 239 break;
135 case GR_GL_ELEMENT_ARRAY_BUFFER: 240 case GR_GL_ELEMENT_ARRAY_BUFFER:
136 buf = gCurrElementArrayBuffer; 241 id = gCurrElementArrayBuffer;
137 break; 242 break;
138 } 243 }
139 if (buf) { 244 if (id > 0) {
140 for (int i = 0; i < gMappedBuffers.count(); ++i) { 245 GrBufferObj* buffer = look_up(id);
141 if (gMappedBuffers[i] == buf) { 246 if (buffer->mapped()) {
142 *params = GR_GL_TRUE; 247 *params = GR_GL_TRUE;
143 break;
144 }
145 } 248 }
146 } 249 }
147 break; } 250 break; }
148 default: 251 default:
149 GrCrash("Unexpected pname to GetBufferParamateriv"); 252 GrCrash("Unexpected pname to GetBufferParamateriv");
150 break; 253 break;
151 } 254 }
152 }; 255 };
153 256
154 } // end anonymous namespace 257 } // end anonymous namespace
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
195 interface->fDrawArrays = noOpGLDrawArrays; 298 interface->fDrawArrays = noOpGLDrawArrays;
196 interface->fDrawBuffer = noOpGLDrawBuffer; 299 interface->fDrawBuffer = noOpGLDrawBuffer;
197 interface->fDrawBuffers = noOpGLDrawBuffers; 300 interface->fDrawBuffers = noOpGLDrawBuffers;
198 interface->fDrawElements = noOpGLDrawElements; 301 interface->fDrawElements = noOpGLDrawElements;
199 interface->fEnable = noOpGLEnable; 302 interface->fEnable = noOpGLEnable;
200 interface->fEnableVertexAttribArray = noOpGLEnableVertexAttribArray; 303 interface->fEnableVertexAttribArray = noOpGLEnableVertexAttribArray;
201 interface->fEndQuery = noOpGLEndQuery; 304 interface->fEndQuery = noOpGLEndQuery;
202 interface->fFinish = noOpGLFinish; 305 interface->fFinish = noOpGLFinish;
203 interface->fFlush = noOpGLFlush; 306 interface->fFlush = noOpGLFlush;
204 interface->fFrontFace = noOpGLFrontFace; 307 interface->fFrontFace = noOpGLFrontFace;
205 interface->fGenBuffers = noOpGLGenIds; 308 interface->fGenBuffers = nullGLGenBuffers;
206 interface->fGenQueries = noOpGLGenIds; 309 interface->fGenQueries = noOpGLGenIds;
207 interface->fGenTextures = noOpGLGenIds; 310 interface->fGenTextures = noOpGLGenIds;
208 interface->fGenVertexArrays = noOpGLGenIds; 311 interface->fGenVertexArrays = noOpGLGenIds;
209 interface->fGetBufferParameteriv = nullGLGetBufferParameteriv; 312 interface->fGetBufferParameteriv = nullGLGetBufferParameteriv;
210 interface->fGetError = noOpGLGetError; 313 interface->fGetError = noOpGLGetError;
211 interface->fGetIntegerv = noOpGLGetIntegerv; 314 interface->fGetIntegerv = noOpGLGetIntegerv;
212 interface->fGetQueryObjecti64v = noOpGLGetQueryObjecti64v; 315 interface->fGetQueryObjecti64v = noOpGLGetQueryObjecti64v;
213 interface->fGetQueryObjectiv = noOpGLGetQueryObjectiv; 316 interface->fGetQueryObjectiv = noOpGLGetQueryObjectiv;
214 interface->fGetQueryObjectui64v = noOpGLGetQueryObjectui64v; 317 interface->fGetQueryObjectui64v = noOpGLGetQueryObjectui64v;
215 interface->fGetQueryObjectuiv = noOpGLGetQueryObjectuiv; 318 interface->fGetQueryObjectuiv = noOpGLGetQueryObjectuiv;
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
280 interface->fRenderbufferStorageMultisample = noOpGLRenderbufferStorageMu ltisample; 383 interface->fRenderbufferStorageMultisample = noOpGLRenderbufferStorageMu ltisample;
281 interface->fBlitFramebuffer = noOpGLBlitFramebuffer; 384 interface->fBlitFramebuffer = noOpGLBlitFramebuffer;
282 interface->fResolveMultisampleFramebuffer = noOpGLResolveMultisampleFram ebuffer; 385 interface->fResolveMultisampleFramebuffer = noOpGLResolveMultisampleFram ebuffer;
283 interface->fMapBuffer = nullGLMapBuffer; 386 interface->fMapBuffer = nullGLMapBuffer;
284 interface->fUnmapBuffer = nullGLUnmapBuffer; 387 interface->fUnmapBuffer = nullGLUnmapBuffer;
285 interface->fBindFragDataLocationIndexed = noOpGLBindFragDataLocationInde xed; 388 interface->fBindFragDataLocationIndexed = noOpGLBindFragDataLocationInde xed;
286 } 389 }
287 glInterface.get()->ref(); 390 glInterface.get()->ref();
288 return glInterface.get(); 391 return glInterface.get();
289 } 392 }
OLDNEW
« no previous file with comments | « gm/gmmain.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698