OLD | NEW |
| (Empty) |
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 #include "DebugGLContext.h" | |
10 | |
11 #include "GrBufferObj.h" | |
12 #include "GrFrameBufferObj.h" | |
13 #include "GrProgramObj.h" | |
14 #include "GrRenderBufferObj.h" | |
15 #include "GrShaderObj.h" | |
16 #include "GrTextureObj.h" | |
17 #include "GrTextureUnitObj.h" | |
18 #include "GrVertexArrayObj.h" | |
19 #include "gl/GrGLTestInterface.h" | |
20 | |
21 #include "SkMutex.h" | |
22 | |
23 namespace { | |
24 | |
25 // Helper macro to make creating an object (where you need to get back a derived
type) easier | |
26 #define CREATE(className, classEnum) \ | |
27 reinterpret_cast<className *>(this->createObj(classEnum)) | |
28 | |
29 // Helper macro to make creating an object (where you need to get back a derived
type) easier | |
30 #define FIND(id, className, classEnum) \ | |
31 reinterpret_cast<className *>(this->findObject(id, classEnum)) | |
32 | |
33 class DebugInterface : public GrGLTestInterface { | |
34 public: | |
35 DebugInterface() | |
36 : fCurrGenericID(0) | |
37 , fCurrTextureUnit(0) | |
38 , fArrayBuffer(nullptr) | |
39 , fElementArrayBuffer(nullptr) | |
40 , fVertexArray(nullptr) | |
41 , fPackRowLength(0) | |
42 , fUnpackRowLength(0) | |
43 , fPackAlignment(4) | |
44 , fFrameBuffer(nullptr) | |
45 , fRenderBuffer(nullptr) | |
46 , fProgram(nullptr) | |
47 , fAbandoned(false) { | |
48 for (int i = 0; i < kDefaultMaxTextureUnits; ++i) { | |
49 fTextureUnits[i] = | |
50 reinterpret_cast<GrTextureUnitObj*>(this->createObj(kTextureUnit
_ObjTypes)); | |
51 fTextureUnits[i]->ref(); | |
52 fTextureUnits[i]->setNumber(i); | |
53 } | |
54 this->init(kGL_GrGLStandard); | |
55 } | |
56 | |
57 ~DebugInterface() override { | |
58 // unref & delete the texture units first so they don't show up on the l
eak report | |
59 for (int i = 0; i < kDefaultMaxTextureUnits; ++i) { | |
60 fTextureUnits[i]->unref(); | |
61 fTextureUnits[i]->deleteAction(); | |
62 } | |
63 for (int i = 0; i < fObjects.count(); ++i) { | |
64 delete fObjects[i]; | |
65 } | |
66 fObjects.reset(); | |
67 | |
68 fArrayBuffer = nullptr; | |
69 fElementArrayBuffer = nullptr; | |
70 fVertexArray = nullptr; | |
71 | |
72 this->report(); | |
73 } | |
74 | |
75 void abandon() const override { fAbandoned = true; } | |
76 | |
77 GrGLvoid activeTexture(GrGLenum texture) override { | |
78 // Ganesh offsets the texture unit indices | |
79 texture -= GR_GL_TEXTURE0; | |
80 GrAlwaysAssert(texture < kDefaultMaxTextureUnits); | |
81 fCurrTextureUnit = texture; | |
82 } | |
83 | |
84 GrGLvoid attachShader(GrGLuint programID, GrGLuint shaderID) override { | |
85 | |
86 GrProgramObj *program = FIND(programID, GrProgramObj, kProgram_ObjTypes)
; | |
87 GrAlwaysAssert(program); | |
88 | |
89 GrShaderObj *shader = FIND(shaderID, GrShaderObj, kShader_ObjTypes); | |
90 GrAlwaysAssert(shader); | |
91 | |
92 program->AttachShader(shader); | |
93 } | |
94 | |
95 ////////////////////////////////////////////////////////////////////////////
//// | |
96 GrGLvoid bindTexture(GrGLenum target, GrGLuint textureID) override { | |
97 GrAlwaysAssert(target == GR_GL_TEXTURE_2D || | |
98 target == GR_GL_TEXTURE_RECTANGLE || | |
99 target == GR_GL_TEXTURE_EXTERNAL); | |
100 | |
101 // a textureID of 0 is acceptable - it binds to the default texture targ
et | |
102 GrTextureObj *texture = FIND(textureID, GrTextureObj, kTexture_ObjTypes)
; | |
103 | |
104 this->setTexture(texture); | |
105 } | |
106 | |
107 ////////////////////////////////////////////////////////////////////////////
//// | |
108 GrGLvoid bufferData(GrGLenum target, GrGLsizeiptr size, const GrGLvoid* data
, | |
109 GrGLenum usage) override { | |
110 GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || | |
111 GR_GL_ELEMENT_ARRAY_BUFFER == target); | |
112 GrAlwaysAssert(size >= 0); | |
113 GrAlwaysAssert(GR_GL_STREAM_DRAW == usage || | |
114 GR_GL_STATIC_DRAW == usage || | |
115 GR_GL_DYNAMIC_DRAW == usage); | |
116 | |
117 GrBufferObj *buffer = nullptr; | |
118 switch (target) { | |
119 case GR_GL_ARRAY_BUFFER: | |
120 buffer = this->getArrayBuffer(); | |
121 break; | |
122 case GR_GL_ELEMENT_ARRAY_BUFFER: | |
123 buffer = this->getElementArrayBuffer(); | |
124 break; | |
125 default: | |
126 SkFAIL("Unexpected target to glBufferData"); | |
127 break; | |
128 } | |
129 | |
130 GrAlwaysAssert(buffer); | |
131 GrAlwaysAssert(buffer->getBound()); | |
132 | |
133 buffer->allocate(size, reinterpret_cast<const GrGLchar *>(data)); | |
134 buffer->setUsage(usage); | |
135 } | |
136 | |
137 | |
138 GrGLvoid pixelStorei(GrGLenum pname, GrGLint param) override { | |
139 | |
140 switch (pname) { | |
141 case GR_GL_UNPACK_ROW_LENGTH: | |
142 fUnpackRowLength = param; | |
143 break; | |
144 case GR_GL_PACK_ROW_LENGTH: | |
145 fPackRowLength = param; | |
146 break; | |
147 case GR_GL_UNPACK_ALIGNMENT: | |
148 break; | |
149 case GR_GL_PACK_ALIGNMENT: | |
150 fPackAlignment = param; | |
151 break; | |
152 default: | |
153 GrAlwaysAssert(false); | |
154 break; | |
155 } | |
156 } | |
157 | |
158 GrGLvoid readPixels(GrGLint x, | |
159 GrGLint y, | |
160 GrGLsizei width, | |
161 GrGLsizei height, | |
162 GrGLenum format, | |
163 GrGLenum type, | |
164 GrGLvoid* pixels) override { | |
165 | |
166 GrGLint pixelsInRow = width; | |
167 if (fPackRowLength > 0) { | |
168 pixelsInRow = fPackRowLength; | |
169 } | |
170 | |
171 GrGLint componentsPerPixel = 0; | |
172 | |
173 switch (format) { | |
174 case GR_GL_RGBA: | |
175 // fallthrough | |
176 case GR_GL_BGRA: | |
177 componentsPerPixel = 4; | |
178 break; | |
179 case GR_GL_RGB: | |
180 componentsPerPixel = 3; | |
181 break; | |
182 case GR_GL_RED: | |
183 componentsPerPixel = 1; | |
184 break; | |
185 default: | |
186 GrAlwaysAssert(false); | |
187 break; | |
188 } | |
189 | |
190 GrGLint alignment = fPackAlignment; | |
191 | |
192 GrGLint componentSize = 0; // size (in bytes) of a single component | |
193 | |
194 switch (type) { | |
195 case GR_GL_UNSIGNED_BYTE: | |
196 componentSize = 1; | |
197 break; | |
198 default: | |
199 GrAlwaysAssert(false); | |
200 break; | |
201 } | |
202 | |
203 GrGLint rowStride = 0; // number of components (not bytes) to skip | |
204 if (componentSize >= alignment) { | |
205 rowStride = componentsPerPixel * pixelsInRow; | |
206 } else { | |
207 float fTemp = | |
208 sk_float_ceil(componentSize * componentsPerPixel * pixelsInRow / | |
209 static_cast<float>(alignment)); | |
210 rowStride = static_cast<GrGLint>(alignment * fTemp / componentSize); | |
211 } | |
212 | |
213 GrGLchar *scanline = static_cast<GrGLchar *>(pixels); | |
214 for (int y = 0; y < height; ++y) { | |
215 memset(scanline, 0, componentsPerPixel * componentSize * width); | |
216 scanline += rowStride; | |
217 } | |
218 } | |
219 | |
220 GrGLvoid useProgram(GrGLuint programID) override { | |
221 | |
222 // A programID of 0 is legal | |
223 GrProgramObj *program = FIND(programID, GrProgramObj, kProgram_ObjTypes)
; | |
224 | |
225 this->useProgram(program); | |
226 } | |
227 | |
228 GrGLvoid bindFramebuffer(GrGLenum target, GrGLuint frameBufferID) override { | |
229 | |
230 GrAlwaysAssert(GR_GL_FRAMEBUFFER == target || | |
231 GR_GL_READ_FRAMEBUFFER == target || | |
232 GR_GL_DRAW_FRAMEBUFFER); | |
233 | |
234 // a frameBufferID of 0 is acceptable - it binds to the default | |
235 // frame buffer | |
236 GrFrameBufferObj *frameBuffer = FIND(frameBufferID, GrFrameBufferObj, | |
237 kFrameBuffer_ObjTypes); | |
238 | |
239 this->setFrameBuffer(frameBuffer); | |
240 } | |
241 | |
242 GrGLvoid bindRenderbuffer(GrGLenum target, GrGLuint renderBufferID) override
{ | |
243 | |
244 GrAlwaysAssert(GR_GL_RENDERBUFFER == target); | |
245 | |
246 // a renderBufferID of 0 is acceptable - it unbinds the bound render buf
fer | |
247 GrRenderBufferObj *renderBuffer = FIND(renderBufferID, GrRenderBufferObj
, | |
248 kRenderBuffer_ObjTypes); | |
249 | |
250 this->setRenderBuffer(renderBuffer); | |
251 } | |
252 | |
253 GrGLvoid deleteTextures(GrGLsizei n, const GrGLuint* textures) override { | |
254 // first potentially unbind the texture | |
255 for (unsigned int i = 0; i < kDefaultMaxTextureUnits; ++i) { | |
256 GrTextureUnitObj *pTU = this->getTextureUnit(i); | |
257 | |
258 if (pTU->getTexture()) { | |
259 for (int j = 0; j < n; ++j) { | |
260 | |
261 if (textures[j] == pTU->getTexture()->getID()) { | |
262 // this ID is the current texture - revert the binding t
o 0 | |
263 pTU->setTexture(nullptr); | |
264 } | |
265 } | |
266 } | |
267 } | |
268 | |
269 // TODO: fuse the following block with DeleteRenderBuffers? | |
270 // Open GL will remove a deleted render buffer from the active | |
271 // frame buffer but not from any other frame buffer | |
272 if (this->getFrameBuffer()) { | |
273 | |
274 GrFrameBufferObj *frameBuffer = this->getFrameBuffer(); | |
275 | |
276 for (int i = 0; i < n; ++i) { | |
277 | |
278 if (frameBuffer->getColor() && | |
279 textures[i] == frameBuffer->getColor()->getID()) { | |
280 frameBuffer->setColor(nullptr); | |
281 } | |
282 if (frameBuffer->getDepth() && | |
283 textures[i] == frameBuffer->getDepth()->getID()) { | |
284 frameBuffer->setDepth(nullptr); | |
285 } | |
286 if (frameBuffer->getStencil() && | |
287 textures[i] == frameBuffer->getStencil()->getID()) { | |
288 frameBuffer->setStencil(nullptr); | |
289 } | |
290 } | |
291 } | |
292 | |
293 // then actually "delete" the buffers | |
294 for (int i = 0; i < n; ++i) { | |
295 GrTextureObj *buffer = FIND(textures[i], GrTextureObj, kTexture_ObjT
ypes); | |
296 GrAlwaysAssert(buffer); | |
297 | |
298 // OpenGL gives no guarantees if a texture is deleted while attached
to | |
299 // something other than the currently bound frame buffer | |
300 GrAlwaysAssert(!buffer->getBound()); | |
301 | |
302 GrAlwaysAssert(!buffer->getDeleted()); | |
303 buffer->deleteAction(); | |
304 } | |
305 | |
306 } | |
307 | |
308 GrGLvoid deleteFramebuffers(GrGLsizei n, const GrGLuint *frameBuffers) overr
ide { | |
309 | |
310 // first potentially unbind the buffers | |
311 if (this->getFrameBuffer()) { | |
312 for (int i = 0; i < n; ++i) { | |
313 | |
314 if (frameBuffers[i] == | |
315 this->getFrameBuffer()->getID()) { | |
316 // this ID is the current frame buffer - rebind to the defau
lt | |
317 this->setFrameBuffer(nullptr); | |
318 } | |
319 } | |
320 } | |
321 | |
322 // then actually "delete" the buffers | |
323 for (int i = 0; i < n; ++i) { | |
324 GrFrameBufferObj *buffer = FIND(frameBuffers[i], GrFrameBufferObj, | |
325 kFrameBuffer_ObjTypes); | |
326 GrAlwaysAssert(buffer); | |
327 | |
328 GrAlwaysAssert(!buffer->getDeleted()); | |
329 buffer->deleteAction(); | |
330 } | |
331 } | |
332 | |
333 GrGLvoid deleteRenderbuffers(GrGLsizei n,const GrGLuint *renderBuffers) over
ride { | |
334 | |
335 // first potentially unbind the buffers | |
336 if (this->getRenderBuffer()) { | |
337 for (int i = 0; i < n; ++i) { | |
338 | |
339 if (renderBuffers[i] == | |
340 this->getRenderBuffer()->getID()) { | |
341 // this ID is the current render buffer - make no | |
342 // render buffer be bound | |
343 this->setRenderBuffer(nullptr); | |
344 } | |
345 } | |
346 } | |
347 | |
348 // TODO: fuse the following block with DeleteTextures? | |
349 // Open GL will remove a deleted render buffer from the active frame | |
350 // buffer but not from any other frame buffer | |
351 if (this->getFrameBuffer()) { | |
352 | |
353 GrFrameBufferObj *frameBuffer = this->getFrameBuffer(); | |
354 | |
355 for (int i = 0; i < n; ++i) { | |
356 | |
357 if (frameBuffer->getColor() && | |
358 renderBuffers[i] == frameBuffer->getColor()->getID()) { | |
359 frameBuffer->setColor(nullptr); | |
360 } | |
361 if (frameBuffer->getDepth() && | |
362 renderBuffers[i] == frameBuffer->getDepth()->getID()) { | |
363 frameBuffer->setDepth(nullptr); | |
364 } | |
365 if (frameBuffer->getStencil() && | |
366 renderBuffers[i] == frameBuffer->getStencil()->getID()) { | |
367 frameBuffer->setStencil(nullptr); | |
368 } | |
369 } | |
370 } | |
371 | |
372 // then actually "delete" the buffers | |
373 for (int i = 0; i < n; ++i) { | |
374 GrRenderBufferObj *buffer = FIND(renderBuffers[i], GrRenderBufferObj
, | |
375 kRenderBuffer_ObjTypes); | |
376 GrAlwaysAssert(buffer); | |
377 | |
378 // OpenGL gives no guarantees if a render buffer is deleted | |
379 // while attached to something other than the currently | |
380 // bound frame buffer | |
381 GrAlwaysAssert(!buffer->getColorBound()); | |
382 GrAlwaysAssert(!buffer->getDepthBound()); | |
383 // However, at GrContext destroy time we release all GrRsources and
so stencil buffers | |
384 // may get deleted before FBOs that refer to them. | |
385 //GrAlwaysAssert(!buffer->getStencilBound()); | |
386 | |
387 GrAlwaysAssert(!buffer->getDeleted()); | |
388 buffer->deleteAction(); | |
389 } | |
390 } | |
391 | |
392 GrGLvoid framebufferRenderbuffer(GrGLenum target, | |
393 GrGLenum attachment, | |
394 GrGLenum renderbuffertarget, | |
395 GrGLuint renderBufferID) override { | |
396 | |
397 GrAlwaysAssert(GR_GL_FRAMEBUFFER == target); | |
398 GrAlwaysAssert(GR_GL_COLOR_ATTACHMENT0 == attachment || | |
399 GR_GL_DEPTH_ATTACHMENT == attachment || | |
400 GR_GL_STENCIL_ATTACHMENT == attachment); | |
401 GrAlwaysAssert(GR_GL_RENDERBUFFER == renderbuffertarget); | |
402 | |
403 GrFrameBufferObj *framebuffer = this->getFrameBuffer(); | |
404 // A render buffer cannot be attached to the default framebuffer | |
405 GrAlwaysAssert(framebuffer); | |
406 | |
407 // a renderBufferID of 0 is acceptable - it unbinds the current | |
408 // render buffer | |
409 GrRenderBufferObj *renderbuffer = FIND(renderBufferID, GrRenderBufferObj
, | |
410 kRenderBuffer_ObjTypes); | |
411 | |
412 switch (attachment) { | |
413 case GR_GL_COLOR_ATTACHMENT0: | |
414 framebuffer->setColor(renderbuffer); | |
415 break; | |
416 case GR_GL_DEPTH_ATTACHMENT: | |
417 framebuffer->setDepth(renderbuffer); | |
418 break; | |
419 case GR_GL_STENCIL_ATTACHMENT: | |
420 framebuffer->setStencil(renderbuffer); | |
421 break; | |
422 default: | |
423 GrAlwaysAssert(false); | |
424 break; | |
425 }; | |
426 | |
427 } | |
428 | |
429 ////////////////////////////////////////////////////////////////////////////
//// | |
430 GrGLvoid framebufferTexture2D(GrGLenum target, GrGLenum attachment, GrGLenum
textarget, | |
431 GrGLuint textureID, GrGLint level) override { | |
432 | |
433 GrAlwaysAssert(GR_GL_FRAMEBUFFER == target); | |
434 GrAlwaysAssert(GR_GL_COLOR_ATTACHMENT0 == attachment || | |
435 GR_GL_DEPTH_ATTACHMENT == attachment || | |
436 GR_GL_STENCIL_ATTACHMENT == attachment); | |
437 GrAlwaysAssert(GR_GL_TEXTURE_2D == textarget); | |
438 | |
439 GrFrameBufferObj *framebuffer = this->getFrameBuffer(); | |
440 // A texture cannot be attached to the default framebuffer | |
441 GrAlwaysAssert(framebuffer); | |
442 | |
443 // A textureID of 0 is allowed - it unbinds the currently bound texture | |
444 GrTextureObj *texture = FIND(textureID, GrTextureObj, kTexture_ObjTypes)
; | |
445 if (texture) { | |
446 // The texture shouldn't be bound to a texture unit - this | |
447 // could lead to a feedback loop | |
448 GrAlwaysAssert(!texture->getBound()); | |
449 } | |
450 | |
451 GrAlwaysAssert(0 == level); | |
452 | |
453 switch (attachment) { | |
454 case GR_GL_COLOR_ATTACHMENT0: | |
455 framebuffer->setColor(texture); | |
456 break; | |
457 case GR_GL_DEPTH_ATTACHMENT: | |
458 framebuffer->setDepth(texture); | |
459 break; | |
460 case GR_GL_STENCIL_ATTACHMENT: | |
461 framebuffer->setStencil(texture); | |
462 break; | |
463 default: | |
464 GrAlwaysAssert(false); | |
465 break; | |
466 }; | |
467 } | |
468 | |
469 GrGLuint createProgram() override { | |
470 | |
471 GrProgramObj *program = CREATE(GrProgramObj, kProgram_ObjTypes); | |
472 | |
473 return program->getID(); | |
474 } | |
475 | |
476 GrGLuint createShader(GrGLenum type) override { | |
477 | |
478 GrAlwaysAssert(GR_GL_VERTEX_SHADER == type || | |
479 GR_GL_FRAGMENT_SHADER == type); | |
480 | |
481 GrShaderObj *shader = CREATE(GrShaderObj, kShader_ObjTypes); | |
482 shader->setType(type); | |
483 | |
484 return shader->getID(); | |
485 } | |
486 | |
487 GrGLenum checkFramebufferStatus(GrGLenum target) override { return GR_GL_FRA
MEBUFFER_COMPLETE; } | |
488 | |
489 GrGLvoid deleteProgram(GrGLuint programID) override { | |
490 | |
491 GrProgramObj *program = FIND(programID, GrProgramObj, kProgram_ObjTypes)
; | |
492 GrAlwaysAssert(program); | |
493 | |
494 if (program->getRefCount()) { | |
495 // someone is still using this program so we can't delete it here | |
496 program->setMarkedForDeletion(); | |
497 } else { | |
498 program->deleteAction(); | |
499 } | |
500 } | |
501 | |
502 GrGLvoid deleteShader(GrGLuint shaderID) override { | |
503 | |
504 GrShaderObj *shader = FIND(shaderID, GrShaderObj, kShader_ObjTypes); | |
505 GrAlwaysAssert(shader); | |
506 | |
507 if (shader->getRefCount()) { | |
508 // someone is still using this shader so we can't delete it here | |
509 shader->setMarkedForDeletion(); | |
510 } else { | |
511 shader->deleteAction(); | |
512 } | |
513 } | |
514 | |
515 GrGLvoid genBuffers(GrGLsizei n, GrGLuint* ids) override { | |
516 this->genObjs(kBuffer_ObjTypes, n, ids); | |
517 } | |
518 | |
519 GrGLvoid genFramebuffers(GrGLsizei n, GrGLuint* ids) override { | |
520 this->genObjs(kFrameBuffer_ObjTypes, n, ids); | |
521 } | |
522 | |
523 GrGLvoid genRenderbuffers(GrGLsizei n, GrGLuint* ids) override { | |
524 this->genObjs(kRenderBuffer_ObjTypes, n, ids); | |
525 } | |
526 | |
527 GrGLvoid genTextures(GrGLsizei n, GrGLuint* ids) override { | |
528 this->genObjs(kTexture_ObjTypes, n, ids); | |
529 } | |
530 | |
531 GrGLvoid genVertexArrays(GrGLsizei n, GrGLuint* ids) override { | |
532 this->genObjs(kVertexArray_ObjTypes, n, ids); | |
533 } | |
534 | |
535 GrGLvoid genQueries(GrGLsizei n, GrGLuint *ids) override { this->genGenericI
ds(n, ids); } | |
536 | |
537 GrGLenum getError() override { return GR_GL_NO_ERROR; } | |
538 | |
539 GrGLvoid getIntegerv(GrGLenum pname, GrGLint* params) override { | |
540 // TODO: remove from Ganesh the #defines for gets we don't use. | |
541 // We would like to minimize gets overall due to performance issues | |
542 switch (pname) { | |
543 case GR_GL_CONTEXT_PROFILE_MASK: | |
544 *params = GR_GL_CONTEXT_COMPATIBILITY_PROFILE_BIT; | |
545 break; | |
546 case GR_GL_STENCIL_BITS: | |
547 *params = 8; | |
548 break; | |
549 case GR_GL_SAMPLES: | |
550 *params = 1; | |
551 break; | |
552 case GR_GL_FRAMEBUFFER_BINDING: | |
553 *params = 0; | |
554 break; | |
555 case GR_GL_VIEWPORT: | |
556 params[0] = 0; | |
557 params[1] = 0; | |
558 params[2] = 800; | |
559 params[3] = 600; | |
560 break; | |
561 case GR_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: | |
562 case GR_GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS: | |
563 case GR_GL_MAX_TEXTURE_IMAGE_UNITS: | |
564 case GR_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: | |
565 *params = 8; | |
566 break; | |
567 case GR_GL_MAX_TEXTURE_COORDS: | |
568 *params = 8; | |
569 break; | |
570 case GR_GL_MAX_VERTEX_UNIFORM_VECTORS: | |
571 *params = kDefaultMaxVertexUniformVectors; | |
572 break; | |
573 case GR_GL_MAX_FRAGMENT_UNIFORM_VECTORS: | |
574 *params = kDefaultMaxFragmentUniformVectors; | |
575 break; | |
576 case GR_GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: | |
577 *params = 16 * 4; | |
578 break; | |
579 case GR_GL_NUM_COMPRESSED_TEXTURE_FORMATS: | |
580 *params = 0; | |
581 break; | |
582 case GR_GL_COMPRESSED_TEXTURE_FORMATS: | |
583 break; | |
584 case GR_GL_MAX_TEXTURE_SIZE: | |
585 *params = 8192; | |
586 break; | |
587 case GR_GL_MAX_RENDERBUFFER_SIZE: | |
588 *params = 8192; | |
589 break; | |
590 case GR_GL_MAX_SAMPLES: | |
591 *params = 32; | |
592 break; | |
593 case GR_GL_MAX_VERTEX_ATTRIBS: | |
594 *params = kDefaultMaxVertexAttribs; | |
595 break; | |
596 case GR_GL_MAX_VARYING_VECTORS: | |
597 *params = kDefaultMaxVaryingVectors; | |
598 break; | |
599 case GR_GL_NUM_EXTENSIONS: { | |
600 GrGLint i = 0; | |
601 while (kExtensions[i++]); | |
602 *params = i; | |
603 break; | |
604 } | |
605 default: | |
606 SkFAIL("Unexpected pname to GetIntegerv"); | |
607 } | |
608 } | |
609 | |
610 GrGLvoid getMultisamplefv(GrGLenum pname, GrGLuint index, GrGLfloat* val) ov
erride { | |
611 val[0] = val[1] = 0.5f; | |
612 } | |
613 | |
614 GrGLvoid getProgramiv(GrGLuint program, GrGLenum pname, GrGLint* params) ove
rride { | |
615 this->getShaderOrProgramiv(program, pname, params); | |
616 } | |
617 | |
618 GrGLvoid getProgramInfoLog(GrGLuint program, GrGLsizei bufsize, GrGLsizei* l
ength, | |
619 char* infolog) override { | |
620 this->getInfoLog(program, bufsize, length, infolog); | |
621 } | |
622 | |
623 GrGLvoid getQueryiv(GrGLenum GLtarget, GrGLenum pname, GrGLint *params) over
ride { | |
624 switch (pname) { | |
625 case GR_GL_CURRENT_QUERY: | |
626 *params = 0; | |
627 break; | |
628 case GR_GL_QUERY_COUNTER_BITS: | |
629 *params = 32; | |
630 break; | |
631 default: | |
632 SkFAIL("Unexpected pname passed GetQueryiv."); | |
633 } | |
634 } | |
635 | |
636 GrGLvoid getQueryObjecti64v(GrGLuint id, GrGLenum pname, GrGLint64 *params)
override { | |
637 this->queryResult(id, pname, params); | |
638 } | |
639 | |
640 GrGLvoid getQueryObjectiv(GrGLuint id, GrGLenum pname, GrGLint *params) over
ride { | |
641 this->queryResult(id, pname, params); | |
642 } | |
643 | |
644 GrGLvoid getQueryObjectui64v(GrGLuint id, GrGLenum pname, GrGLuint64 *params
) override { | |
645 this->queryResult(id, pname, params); | |
646 } | |
647 | |
648 GrGLvoid getQueryObjectuiv(GrGLuint id, GrGLenum pname, GrGLuint *params) ov
erride { | |
649 this->queryResult(id, pname, params); | |
650 } | |
651 | |
652 GrGLvoid getShaderiv(GrGLuint shader, GrGLenum pname, GrGLint* params) overr
ide { | |
653 this->getShaderOrProgramiv(shader, pname, params); | |
654 } | |
655 | |
656 GrGLvoid getShaderInfoLog(GrGLuint shader, GrGLsizei bufsize, GrGLsizei* len
gth, | |
657 char* infolog) override { | |
658 this->getInfoLog(shader, bufsize, length, infolog); | |
659 } | |
660 | |
661 const GrGLubyte* getString(GrGLenum name) override { | |
662 switch (name) { | |
663 case GR_GL_EXTENSIONS: | |
664 return CombinedExtensionString(); | |
665 case GR_GL_VERSION: | |
666 return (const GrGLubyte*)"4.0 Debug GL"; | |
667 case GR_GL_SHADING_LANGUAGE_VERSION: | |
668 return (const GrGLubyte*)"4.20.8 Debug GLSL"; | |
669 case GR_GL_VENDOR: | |
670 return (const GrGLubyte*)"Debug Vendor"; | |
671 case GR_GL_RENDERER: | |
672 return (const GrGLubyte*)"The Debug (Non-)Renderer"; | |
673 default: | |
674 SkFAIL("Unexpected name passed to GetString"); | |
675 return nullptr; | |
676 } | |
677 } | |
678 | |
679 const GrGLubyte* getStringi(GrGLenum name, GrGLuint i) override { | |
680 switch (name) { | |
681 case GR_GL_EXTENSIONS: { | |
682 GrGLint count; | |
683 this->getIntegerv(GR_GL_NUM_EXTENSIONS, &count); | |
684 if ((GrGLint)i <= count) { | |
685 return (const GrGLubyte*) kExtensions[i]; | |
686 } else { | |
687 return nullptr; | |
688 } | |
689 } | |
690 default: | |
691 SkFAIL("Unexpected name passed to GetStringi"); | |
692 return nullptr; | |
693 } | |
694 } | |
695 | |
696 GrGLvoid getTexLevelParameteriv(GrGLenum target, GrGLint level, GrGLenum pna
me, | |
697 GrGLint* params) override { | |
698 // we used to use this to query stuff about externally created textures, | |
699 // now we just require clients to tell us everything about the texture. | |
700 SkFAIL("Should never query texture parameters."); | |
701 } | |
702 | |
703 GrGLvoid deleteVertexArrays(GrGLsizei n, const GrGLuint* ids) override { | |
704 for (GrGLsizei i = 0; i < n; ++i) { | |
705 GrVertexArrayObj* array = FIND(ids[i], GrVertexArrayObj, kVertexArra
y_ObjTypes); | |
706 GrAlwaysAssert(array); | |
707 | |
708 // Deleting the current vertex array binds object 0 | |
709 if (this->getVertexArray() == array) { | |
710 this->setVertexArray(nullptr); | |
711 } | |
712 | |
713 if (array->getRefCount()) { | |
714 // someone is still using this vertex array so we can't delete i
t here | |
715 array->setMarkedForDeletion(); | |
716 } else { | |
717 array->deleteAction(); | |
718 } | |
719 } | |
720 } | |
721 | |
722 GrGLvoid bindVertexArray(GrGLuint id) override { | |
723 GrVertexArrayObj* array = FIND(id, GrVertexArrayObj, kVertexArray_ObjTyp
es); | |
724 GrAlwaysAssert((0 == id) || array); | |
725 this->setVertexArray(array); | |
726 } | |
727 | |
728 GrGLvoid bindBuffer(GrGLenum target, GrGLuint bufferID) override { | |
729 GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || GR_GL_ELEMENT_ARRAY_BUFFE
R == target); | |
730 | |
731 GrBufferObj *buffer = FIND(bufferID, GrBufferObj, kBuffer_ObjTypes); | |
732 // 0 is a permissible bufferID - it unbinds the current buffer | |
733 | |
734 switch (target) { | |
735 case GR_GL_ARRAY_BUFFER: | |
736 this->setArrayBuffer(buffer); | |
737 break; | |
738 case GR_GL_ELEMENT_ARRAY_BUFFER: | |
739 this->setElementArrayBuffer(buffer); | |
740 break; | |
741 default: | |
742 SkFAIL("Unexpected target to glBindBuffer"); | |
743 break; | |
744 } | |
745 } | |
746 | |
747 // deleting a bound buffer has the side effect of binding 0 | |
748 GrGLvoid deleteBuffers(GrGLsizei n, const GrGLuint* ids) override { | |
749 // first potentially unbind the buffers | |
750 for (int i = 0; i < n; ++i) { | |
751 | |
752 if (this->getArrayBuffer() && | |
753 ids[i] == this->getArrayBuffer()->getID()) { | |
754 // this ID is the current array buffer | |
755 this->setArrayBuffer(nullptr); | |
756 } | |
757 if (this->getElementArrayBuffer() && | |
758 ids[i] == this->getElementArrayBuffer()->getID()) { | |
759 // this ID is the current element array buffer | |
760 this->setElementArrayBuffer(nullptr); | |
761 } | |
762 } | |
763 | |
764 // then actually "delete" the buffers | |
765 for (int i = 0; i < n; ++i) { | |
766 GrBufferObj *buffer = FIND(ids[i], GrBufferObj, kBuffer_ObjTypes); | |
767 GrAlwaysAssert(buffer); | |
768 | |
769 GrAlwaysAssert(!buffer->getDeleted()); | |
770 buffer->deleteAction(); | |
771 } | |
772 } | |
773 | |
774 // map a buffer to the caller's address space | |
775 GrGLvoid* mapBufferRange(GrGLenum target, GrGLintptr offset, GrGLsizeiptr le
ngth, | |
776 GrGLbitfield access) override { | |
777 GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || | |
778 GR_GL_ELEMENT_ARRAY_BUFFER == target); | |
779 | |
780 // We only expect read access and we expect that the buffer or range is
always invalidated. | |
781 GrAlwaysAssert(!SkToBool(GR_GL_MAP_READ_BIT & access)); | |
782 GrAlwaysAssert((GR_GL_MAP_INVALIDATE_BUFFER_BIT | GR_GL_MAP_INVALIDATE_R
ANGE_BIT) & access); | |
783 | |
784 GrBufferObj *buffer = nullptr; | |
785 switch (target) { | |
786 case GR_GL_ARRAY_BUFFER: | |
787 buffer = this->getArrayBuffer(); | |
788 break; | |
789 case GR_GL_ELEMENT_ARRAY_BUFFER: | |
790 buffer = this->getElementArrayBuffer(); | |
791 break; | |
792 default: | |
793 SkFAIL("Unexpected target to glMapBufferRange"); | |
794 break; | |
795 } | |
796 | |
797 if (buffer) { | |
798 GrAlwaysAssert(offset >= 0 && offset + length <= buffer->getSize()); | |
799 GrAlwaysAssert(!buffer->getMapped()); | |
800 buffer->setMapped(offset, length); | |
801 return buffer->getDataPtr() + offset; | |
802 } | |
803 | |
804 GrAlwaysAssert(false); | |
805 return nullptr; // no buffer bound to the target | |
806 } | |
807 | |
808 GrGLvoid* mapBuffer(GrGLenum target, GrGLenum access) override { | |
809 GrAlwaysAssert(GR_GL_WRITE_ONLY == access); | |
810 | |
811 GrBufferObj *buffer = nullptr; | |
812 switch (target) { | |
813 case GR_GL_ARRAY_BUFFER: | |
814 buffer = this->getArrayBuffer(); | |
815 break; | |
816 case GR_GL_ELEMENT_ARRAY_BUFFER: | |
817 buffer = this->getElementArrayBuffer(); | |
818 break; | |
819 default: | |
820 SkFAIL("Unexpected target to glMapBuffer"); | |
821 break; | |
822 } | |
823 | |
824 return this->mapBufferRange(target, 0, buffer->getSize(), | |
825 GR_GL_MAP_WRITE_BIT | GR_GL_MAP_INVALIDATE_B
UFFER_BIT); | |
826 } | |
827 | |
828 // remove a buffer from the caller's address space | |
829 // TODO: check if the "access" method from "glMapBuffer" was honored | |
830 GrGLboolean unmapBuffer(GrGLenum target) override { | |
831 GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || | |
832 GR_GL_ELEMENT_ARRAY_BUFFER == target); | |
833 | |
834 GrBufferObj *buffer = nullptr; | |
835 switch (target) { | |
836 case GR_GL_ARRAY_BUFFER: | |
837 buffer = this->getArrayBuffer(); | |
838 break; | |
839 case GR_GL_ELEMENT_ARRAY_BUFFER: | |
840 buffer = this->getElementArrayBuffer(); | |
841 break; | |
842 default: | |
843 SkFAIL("Unexpected target to glUnmapBuffer"); | |
844 break; | |
845 } | |
846 | |
847 if (buffer) { | |
848 GrAlwaysAssert(buffer->getMapped()); | |
849 buffer->resetMapped(); | |
850 return GR_GL_TRUE; | |
851 } | |
852 | |
853 GrAlwaysAssert(false); | |
854 return GR_GL_FALSE; // GR_GL_INVALID_OPERATION; | |
855 } | |
856 | |
857 GrGLvoid flushMappedBufferRange(GrGLenum target, GrGLintptr offset, | |
858 GrGLsizeiptr length) override { | |
859 GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || | |
860 GR_GL_ELEMENT_ARRAY_BUFFER == target); | |
861 | |
862 GrBufferObj *buffer = nullptr; | |
863 switch (target) { | |
864 case GR_GL_ARRAY_BUFFER: | |
865 buffer = this->getArrayBuffer(); | |
866 break; | |
867 case GR_GL_ELEMENT_ARRAY_BUFFER: | |
868 buffer = this->getElementArrayBuffer(); | |
869 break; | |
870 default: | |
871 SkFAIL("Unexpected target to glUnmapBuffer"); | |
872 break; | |
873 } | |
874 | |
875 if (buffer) { | |
876 GrAlwaysAssert(buffer->getMapped()); | |
877 GrAlwaysAssert(offset >= 0 && (offset + length) <= buffer->getMapped
Length()); | |
878 } else { | |
879 GrAlwaysAssert(false); | |
880 } | |
881 } | |
882 | |
883 GrGLvoid getBufferParameteriv(GrGLenum target, GrGLenum value, GrGLint* para
ms) override { | |
884 | |
885 GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || | |
886 GR_GL_ELEMENT_ARRAY_BUFFER == target); | |
887 GrAlwaysAssert(GR_GL_BUFFER_SIZE == value || | |
888 GR_GL_BUFFER_USAGE == value); | |
889 | |
890 GrBufferObj *buffer = nullptr; | |
891 switch (target) { | |
892 case GR_GL_ARRAY_BUFFER: | |
893 buffer = this->getArrayBuffer(); | |
894 break; | |
895 case GR_GL_ELEMENT_ARRAY_BUFFER: | |
896 buffer = this->getElementArrayBuffer(); | |
897 break; | |
898 } | |
899 | |
900 GrAlwaysAssert(buffer); | |
901 | |
902 switch (value) { | |
903 case GR_GL_BUFFER_MAPPED: | |
904 *params = GR_GL_FALSE; | |
905 if (buffer) | |
906 *params = buffer->getMapped() ? GR_GL_TRUE : GR_GL_FALSE; | |
907 break; | |
908 case GR_GL_BUFFER_SIZE: | |
909 *params = 0; | |
910 if (buffer) | |
911 *params = SkToInt(buffer->getSize()); | |
912 break; | |
913 case GR_GL_BUFFER_USAGE: | |
914 *params = GR_GL_STATIC_DRAW; | |
915 if (buffer) | |
916 *params = buffer->getUsage(); | |
917 break; | |
918 default: | |
919 SkFAIL("Unexpected value to glGetBufferParamateriv"); | |
920 break; | |
921 } | |
922 } | |
923 | |
924 private: | |
925 // the OpenGLES 2.0 spec says this must be >= 128 | |
926 static const GrGLint kDefaultMaxVertexUniformVectors = 128; | |
927 | |
928 // the OpenGLES 2.0 spec says this must be >=16 | |
929 static const GrGLint kDefaultMaxFragmentUniformVectors = 16; | |
930 | |
931 // the OpenGLES 2.0 spec says this must be >= 8 | |
932 static const GrGLint kDefaultMaxVertexAttribs = 8; | |
933 | |
934 // the OpenGLES 2.0 spec says this must be >= 8 | |
935 static const GrGLint kDefaultMaxVaryingVectors = 8; | |
936 | |
937 // the OpenGLES 2.0 spec says this must be >= 2 | |
938 static const GrGLint kDefaultMaxTextureUnits = 8; | |
939 | |
940 static const char* kExtensions[]; | |
941 | |
942 GrGLuint fCurrGenericID; | |
943 GrGLuint fCurrTextureUnit; | |
944 GrTextureUnitObj* fTextureUnits[kDefaultMaxTextureUnits]; | |
945 GrBufferObj* fArrayBuffer; | |
946 GrBufferObj* fElementArrayBuffer; | |
947 GrVertexArrayObj* fVertexArray; | |
948 GrGLint fPackRowLength; | |
949 GrGLint fUnpackRowLength; | |
950 GrGLint fPackAlignment; | |
951 GrFrameBufferObj* fFrameBuffer; | |
952 GrRenderBufferObj* fRenderBuffer; | |
953 GrProgramObj* fProgram; | |
954 mutable bool fAbandoned; | |
955 // global store of all objects | |
956 SkTArray<GrFakeRefObj *> fObjects; | |
957 | |
958 static const GrGLubyte* CombinedExtensionString() { | |
959 static SkString gExtString; | |
960 static SkMutex gMutex; | |
961 gMutex.acquire(); | |
962 if (0 == gExtString.size()) { | |
963 int i = 0; | |
964 while (kExtensions[i]) { | |
965 if (i > 0) { | |
966 gExtString.append(" "); | |
967 } | |
968 gExtString.append(kExtensions[i]); | |
969 ++i; | |
970 } | |
971 } | |
972 gMutex.release(); | |
973 return (const GrGLubyte*) gExtString.c_str(); | |
974 } | |
975 | |
976 GrGLvoid genGenericIds(GrGLsizei n, GrGLuint* ids) { | |
977 for (int i = 0; i < n; ++i) { | |
978 ids[i] = ++fCurrGenericID; | |
979 } | |
980 } | |
981 | |
982 GrGLvoid getInfoLog(GrGLuint object, GrGLsizei bufsize, GrGLsizei* length, | |
983 char* infolog) { | |
984 if (length) { | |
985 *length = 0; | |
986 } | |
987 if (bufsize > 0) { | |
988 *infolog = 0; | |
989 } | |
990 } | |
991 | |
992 GrGLvoid getShaderOrProgramiv(GrGLuint object, GrGLenum pname, GrGLint* par
ams) { | |
993 switch (pname) { | |
994 case GR_GL_LINK_STATUS: // fallthru | |
995 case GR_GL_COMPILE_STATUS: | |
996 *params = GR_GL_TRUE; | |
997 break; | |
998 case GR_GL_INFO_LOG_LENGTH: | |
999 *params = 0; | |
1000 break; | |
1001 // we don't expect any other pnames | |
1002 default: | |
1003 SkFAIL("Unexpected pname to GetProgramiv"); | |
1004 break; | |
1005 } | |
1006 } | |
1007 | |
1008 template <typename T> | |
1009 void queryResult(GrGLenum GLtarget, GrGLenum pname, T *params) { | |
1010 switch (pname) { | |
1011 case GR_GL_QUERY_RESULT_AVAILABLE: | |
1012 *params = GR_GL_TRUE; | |
1013 break; | |
1014 case GR_GL_QUERY_RESULT: | |
1015 *params = 0; | |
1016 break; | |
1017 default: | |
1018 SkFAIL("Unexpected pname passed to GetQueryObject."); | |
1019 break; | |
1020 } | |
1021 } | |
1022 | |
1023 enum ObjTypes { | |
1024 kTexture_ObjTypes = 0, | |
1025 kBuffer_ObjTypes, | |
1026 kRenderBuffer_ObjTypes, | |
1027 kFrameBuffer_ObjTypes, | |
1028 kShader_ObjTypes, | |
1029 kProgram_ObjTypes, | |
1030 kTextureUnit_ObjTypes, | |
1031 kVertexArray_ObjTypes, | |
1032 kObjTypeCount | |
1033 }; | |
1034 | |
1035 typedef GrFakeRefObj *(*Create)(); | |
1036 | |
1037 static Create gFactoryFunc[kObjTypeCount]; | |
1038 | |
1039 GrGLvoid genObjs(ObjTypes type, GrGLsizei n, GrGLuint* ids) { | |
1040 for (int i = 0; i < n; ++i) { | |
1041 GrAlwaysAssert(ids[i] == 0); | |
1042 GrFakeRefObj *obj = this->createObj(type); | |
1043 GrAlwaysAssert(obj); | |
1044 ids[i] = obj->getID(); | |
1045 } | |
1046 } | |
1047 | |
1048 GrFakeRefObj* createObj(ObjTypes type) { | |
1049 GrFakeRefObj *temp = (*gFactoryFunc[type])(); | |
1050 | |
1051 fObjects.push_back(temp); | |
1052 | |
1053 return temp; | |
1054 } | |
1055 | |
1056 GrFakeRefObj* findObject(GrGLuint ID, ObjTypes type) { | |
1057 for (int i = 0; i < fObjects.count(); ++i) { | |
1058 if (fObjects[i]->getID() == ID) { // && fObjects[i]->getType() == ty
pe) { | |
1059 // The application shouldn't be accessing objects | |
1060 // that (as far as OpenGL knows) were already deleted | |
1061 GrAlwaysAssert(!fObjects[i]->getDeleted()); | |
1062 GrAlwaysAssert(!fObjects[i]->getMarkedForDeletion()); | |
1063 return fObjects[i]; | |
1064 } | |
1065 } | |
1066 return nullptr; | |
1067 } | |
1068 | |
1069 GrTextureUnitObj* getTextureUnit(int unit) { | |
1070 GrAlwaysAssert(0 <= unit && kDefaultMaxTextureUnits > unit); | |
1071 | |
1072 return fTextureUnits[unit]; | |
1073 } | |
1074 | |
1075 void setArrayBuffer(GrBufferObj *arrayBuffer) { | |
1076 if (fArrayBuffer) { | |
1077 // automatically break the binding of the old buffer | |
1078 GrAlwaysAssert(fArrayBuffer->getBound()); | |
1079 fArrayBuffer->resetBound(); | |
1080 | |
1081 GrAlwaysAssert(!fArrayBuffer->getDeleted()); | |
1082 fArrayBuffer->unref(); | |
1083 } | |
1084 | |
1085 fArrayBuffer = arrayBuffer; | |
1086 | |
1087 if (fArrayBuffer) { | |
1088 GrAlwaysAssert(!fArrayBuffer->getDeleted()); | |
1089 fArrayBuffer->ref(); | |
1090 | |
1091 GrAlwaysAssert(!fArrayBuffer->getBound()); | |
1092 fArrayBuffer->setBound(); | |
1093 } | |
1094 } | |
1095 | |
1096 GrBufferObj* getArrayBuffer() { return fArrayBuffer; } | |
1097 void setElementArrayBuffer(GrBufferObj *elementArrayBuffer) { | |
1098 if (fElementArrayBuffer) { | |
1099 // automatically break the binding of the old buffer | |
1100 GrAlwaysAssert(fElementArrayBuffer->getBound()); | |
1101 fElementArrayBuffer->resetBound(); | |
1102 | |
1103 GrAlwaysAssert(!fElementArrayBuffer->getDeleted()); | |
1104 fElementArrayBuffer->unref(); | |
1105 } | |
1106 | |
1107 fElementArrayBuffer = elementArrayBuffer; | |
1108 | |
1109 if (fElementArrayBuffer) { | |
1110 GrAlwaysAssert(!fElementArrayBuffer->getDeleted()); | |
1111 fElementArrayBuffer->ref(); | |
1112 | |
1113 GrAlwaysAssert(!fElementArrayBuffer->getBound()); | |
1114 fElementArrayBuffer->setBound(); | |
1115 } | |
1116 } | |
1117 | |
1118 GrBufferObj *getElementArrayBuffer() { return fElementArrayBuffer; } | |
1119 | |
1120 void setVertexArray(GrVertexArrayObj* vertexArray) { | |
1121 if (vertexArray) { | |
1122 SkASSERT(!vertexArray->getDeleted()); | |
1123 } | |
1124 SkRefCnt_SafeAssign(fVertexArray, vertexArray); | |
1125 } | |
1126 | |
1127 GrVertexArrayObj* getVertexArray() { return fVertexArray; } | |
1128 | |
1129 void setTexture(GrTextureObj *texture) { | |
1130 fTextureUnits[fCurrTextureUnit]->setTexture(texture); | |
1131 } | |
1132 | |
1133 void setFrameBuffer(GrFrameBufferObj *frameBuffer) { | |
1134 if (fFrameBuffer) { | |
1135 GrAlwaysAssert(fFrameBuffer->getBound()); | |
1136 fFrameBuffer->resetBound(); | |
1137 | |
1138 GrAlwaysAssert(!fFrameBuffer->getDeleted()); | |
1139 fFrameBuffer->unref(); | |
1140 } | |
1141 | |
1142 fFrameBuffer = frameBuffer; | |
1143 | |
1144 if (fFrameBuffer) { | |
1145 GrAlwaysAssert(!fFrameBuffer->getDeleted()); | |
1146 fFrameBuffer->ref(); | |
1147 | |
1148 GrAlwaysAssert(!fFrameBuffer->getBound()); | |
1149 fFrameBuffer->setBound(); | |
1150 } | |
1151 } | |
1152 | |
1153 GrFrameBufferObj *getFrameBuffer() { return fFrameBuffer; } | |
1154 | |
1155 void setRenderBuffer(GrRenderBufferObj *renderBuffer) { | |
1156 if (fRenderBuffer) { | |
1157 GrAlwaysAssert(fRenderBuffer->getBound()); | |
1158 fRenderBuffer->resetBound(); | |
1159 | |
1160 GrAlwaysAssert(!fRenderBuffer->getDeleted()); | |
1161 fRenderBuffer->unref(); | |
1162 } | |
1163 | |
1164 fRenderBuffer = renderBuffer; | |
1165 | |
1166 if (fRenderBuffer) { | |
1167 GrAlwaysAssert(!fRenderBuffer->getDeleted()); | |
1168 fRenderBuffer->ref(); | |
1169 | |
1170 GrAlwaysAssert(!fRenderBuffer->getBound()); | |
1171 fRenderBuffer->setBound(); | |
1172 } | |
1173 } | |
1174 GrRenderBufferObj *getRenderBuffer() { return fRenderBuffer; } | |
1175 | |
1176 void useProgram(GrProgramObj *program) { | |
1177 if (fProgram) { | |
1178 GrAlwaysAssert(fProgram->getInUse()); | |
1179 fProgram->resetInUse(); | |
1180 | |
1181 GrAlwaysAssert(!fProgram->getDeleted()); | |
1182 fProgram->unref(); | |
1183 } | |
1184 | |
1185 fProgram = program; | |
1186 | |
1187 if (fProgram) { | |
1188 GrAlwaysAssert(!fProgram->getDeleted()); | |
1189 fProgram->ref(); | |
1190 | |
1191 GrAlwaysAssert(!fProgram->getInUse()); | |
1192 fProgram->setInUse(); | |
1193 } | |
1194 } | |
1195 | |
1196 void report() const { | |
1197 for (int i = 0; i < fObjects.count(); ++i) { | |
1198 if (!fAbandoned) { | |
1199 GrAlwaysAssert(0 == fObjects[i]->getRefCount()); | |
1200 GrAlwaysAssert(fObjects[i]->getDeleted()); | |
1201 } | |
1202 } | |
1203 } | |
1204 | |
1205 typedef GrGLTestInterface INHERITED; | |
1206 }; | |
1207 | |
1208 #undef CREATE | |
1209 #undef FIND | |
1210 | |
1211 DebugInterface::Create DebugInterface::gFactoryFunc[kObjTypeCount] = { | |
1212 GrTextureObj::createGrTextureObj, | |
1213 GrBufferObj::createGrBufferObj, | |
1214 GrRenderBufferObj::createGrRenderBufferObj, | |
1215 GrFrameBufferObj::createGrFrameBufferObj, | |
1216 GrShaderObj::createGrShaderObj, | |
1217 GrProgramObj::createGrProgramObj, | |
1218 GrTextureUnitObj::createGrTextureUnitObj, | |
1219 GrVertexArrayObj::createGrVertexArrayObj, | |
1220 }; | |
1221 | |
1222 const char* DebugInterface::kExtensions[] = { | |
1223 "GL_ARB_framebuffer_object", | |
1224 "GL_ARB_blend_func_extended", | |
1225 "GL_ARB_timer_query", | |
1226 "GL_ARB_draw_buffers", | |
1227 "GL_ARB_occlusion_query", | |
1228 "GL_EXT_stencil_wrap", | |
1229 nullptr, // signifies the end of the array. | |
1230 }; | |
1231 | |
1232 class DebugGLContext : public sk_gpu_test::GLContext { | |
1233 public: | |
1234 DebugGLContext() { | |
1235 this->init(new DebugInterface()); | |
1236 } | |
1237 | |
1238 ~DebugGLContext() override { this->teardown(); } | |
1239 | |
1240 private: | |
1241 void onPlatformMakeCurrent() const override {} | |
1242 void onPlatformSwapBuffers() const override {} | |
1243 GrGLFuncPtr onPlatformGetProcAddress(const char*) const override { return nu
llptr; } | |
1244 }; | |
1245 } // anonymous namespace | |
1246 | |
1247 namespace sk_gpu_test { | |
1248 GLContext* CreateDebugGLContext() { | |
1249 GLContext* ctx = new DebugGLContext(); | |
1250 if (ctx->isValid()) { | |
1251 return ctx; | |
1252 } | |
1253 delete ctx; | |
1254 return nullptr; | |
1255 } | |
1256 } | |
OLD | NEW |