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