blob: 43fc8dfad9c3eba7138fe4a1b94eaa844eeb5d52 [file] [log] [blame]
robertphillips@google.com0da37192012-03-19 14:42:13 +00001
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"
bsalomon3c481002016-03-21 09:04:26 -070011
robertphillips@google.comdd743fe2012-04-05 14:40:53 +000012#include "GrBufferObj.h"
robertphillips@google.comdd743fe2012-04-05 14:40:53 +000013#include "GrFrameBufferObj.h"
bsalomon3c481002016-03-21 09:04:26 -070014#include "GrProgramObj.h"
robertphillips@google.comdd743fe2012-04-05 14:40:53 +000015#include "GrRenderBufferObj.h"
bsalomon3c481002016-03-21 09:04:26 -070016#include "GrShaderObj.h"
17#include "GrTextureObj.h"
18#include "GrTextureUnitObj.h"
bsalomon@google.comecd84842013-03-01 15:36:02 +000019#include "GrVertexArrayObj.h"
bsalomon3c481002016-03-21 09:04:26 -070020#include "gl/GrGLTestInterface.h"
robertphillips@google.com0da37192012-03-19 14:42:13 +000021
bsalomon3c481002016-03-21 09:04:26 -070022#include "SkMutex.h"
caryclark@google.comcf6285b2012-06-06 12:09:01 +000023
bsalomon3c481002016-03-21 09:04:26 -070024namespace {
rmistry@google.comfbfcd562012-08-23 18:09:54 +000025
bsalomon3c481002016-03-21 09:04:26 -070026// 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))
robertphillips@google.com0da37192012-03-19 14:42:13 +000029
bsalomon3c481002016-03-21 09:04:26 -070030// 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))
robertphillips@google.com0da37192012-03-19 14:42:13 +000033
bsalomon3c481002016-03-21 09:04:26 -070034class DebugInterface : public GrGLTestInterface {
35public:
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);
robertphillips@google.com0da37192012-03-19 14:42:13 +000056 }
57
bsalomon3c481002016-03-21 09:04:26 -070058 ~DebugInterface() override {
59 // unref & delete the texture units first so they don't show up on the leak 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();
robertphillips@google.com0da37192012-03-19 14:42:13 +000068
bsalomon3c481002016-03-21 09:04:26 -070069 fArrayBuffer = nullptr;
70 fElementArrayBuffer = nullptr;
71 fVertexArray = nullptr;
robertphillips@google.com0da37192012-03-19 14:42:13 +000072
bsalomon3c481002016-03-21 09:04:26 -070073 this->report();
robertphillips@google.com670ff9a2012-04-12 19:53:31 +000074 }
75
bsalomon3c481002016-03-21 09:04:26 -070076 void abandon() const override { fAbandoned = true; }
robertphillips@google.com670ff9a2012-04-12 19:53:31 +000077
bsalomon3c481002016-03-21 09:04:26 -070078 GrGLvoid activeTexture(GrGLenum texture) override {
79 // Ganesh offsets the texture unit indices
80 texture -= GR_GL_TEXTURE0;
81 GrAlwaysAssert(texture < kDefaultMaxTextureUnits);
82 fCurrTextureUnit = texture;
robertphillips@google.com670ff9a2012-04-12 19:53:31 +000083 }
84
bsalomon3c481002016-03-21 09:04:26 -070085 GrGLvoid attachShader(GrGLuint programID, GrGLuint shaderID) override {
robertphillips@google.com670ff9a2012-04-12 19:53:31 +000086
bsalomon3c481002016-03-21 09:04:26 -070087 GrProgramObj *program = FIND(programID, GrProgramObj, kProgram_ObjTypes);
88 GrAlwaysAssert(program);
robertphillips@google.com670ff9a2012-04-12 19:53:31 +000089
bsalomon3c481002016-03-21 09:04:26 -070090 GrShaderObj *shader = FIND(shaderID, GrShaderObj, kShader_ObjTypes);
91 GrAlwaysAssert(shader);
92
93 program->AttachShader(shader);
robertphillips@google.com670ff9a2012-04-12 19:53:31 +000094 }
95
bsalomon3c481002016-03-21 09:04:26 -070096 ////////////////////////////////////////////////////////////////////////////////
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 target
103 GrTextureObj *texture = FIND(textureID, GrTextureObj, kTexture_ObjTypes);
104
105 this->setTexture(texture);
robertphillips@google.com670ff9a2012-04-12 19:53:31 +0000106 }
107
bsalomon3c481002016-03-21 09:04:26 -0700108 ////////////////////////////////////////////////////////////////////////////////
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);
robertphillips@google.com670ff9a2012-04-12 19:53:31 +0000136 }
robertphillips@google.com0da37192012-03-19 14:42:13 +0000137
robertphillips@google.comebde3e02012-07-13 17:45:17 +0000138
bsalomon3c481002016-03-21 09:04:26 -0700139 GrGLvoid pixelStorei(GrGLenum pname, GrGLint param) override {
robertphillips@google.comebde3e02012-07-13 17:45:17 +0000140
bsalomon3c481002016-03-21 09:04:26 -0700141 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 }
robertphillips@google.comebde3e02012-07-13 17:45:17 +0000158
bsalomon3c481002016-03-21 09:04:26 -0700159 GrGLvoid readPixels(GrGLint x,
160 GrGLint y,
161 GrGLsizei width,
162 GrGLsizei height,
163 GrGLenum format,
164 GrGLenum type,
165 GrGLvoid* pixels) override {
robertphillips@google.comebde3e02012-07-13 17:45:17 +0000166
bsalomon3c481002016-03-21 09:04:26 -0700167 GrGLint pixelsInRow = width;
168 if (fPackRowLength > 0) {
169 pixelsInRow = fPackRowLength;
170 }
robertphillips@google.comebde3e02012-07-13 17:45:17 +0000171
bsalomon3c481002016-03-21 09:04:26 -0700172 GrGLint componentsPerPixel = 0;
robertphillips@google.comebde3e02012-07-13 17:45:17 +0000173
bsalomon3c481002016-03-21 09:04:26 -0700174 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 }
robertphillips@google.comebde3e02012-07-13 17:45:17 +0000190
bsalomon3c481002016-03-21 09:04:26 -0700191 GrGLint alignment = fPackAlignment;
robertphillips@google.comebde3e02012-07-13 17:45:17 +0000192
bsalomon3c481002016-03-21 09:04:26 -0700193 GrGLint componentSize = 0; // size (in bytes) of a single component
robertphillips@google.comebde3e02012-07-13 17:45:17 +0000194
bsalomon3c481002016-03-21 09:04:26 -0700195 switch (type) {
196 case GR_GL_UNSIGNED_BYTE:
197 componentSize = 1;
198 break;
199 default:
200 GrAlwaysAssert(false);
201 break;
202 }
robertphillips@google.comebde3e02012-07-13 17:45:17 +0000203
bsalomon3c481002016-03-21 09:04:26 -0700204 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 }
robertphillips@google.comebde3e02012-07-13 17:45:17 +0000213
bsalomon3c481002016-03-21 09:04:26 -0700214 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 }
robertphillips@google.comebde3e02012-07-13 17:45:17 +0000220
bsalomon3c481002016-03-21 09:04:26 -0700221 GrGLvoid useProgram(GrGLuint programID) override {
robertphillips@google.comebde3e02012-07-13 17:45:17 +0000222
bsalomon3c481002016-03-21 09:04:26 -0700223 // A programID of 0 is legal
224 GrProgramObj *program = FIND(programID, GrProgramObj, kProgram_ObjTypes);
robertphillips@google.comebde3e02012-07-13 17:45:17 +0000225
bsalomon3c481002016-03-21 09:04:26 -0700226 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) override {
244
245 GrAlwaysAssert(GR_GL_RENDERBUFFER == target);
246
247 // a renderBufferID of 0 is acceptable - it unbinds the bound render buffer
248 GrRenderBufferObj *renderBuffer = FIND(renderBufferID, GrRenderBufferObj,
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 }
robertphillips@google.comebde3e02012-07-13 17:45:17 +0000266 }
267 }
268 }
bsalomon3c481002016-03-21 09:04:26 -0700269
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_ObjTypes);
297 GrAlwaysAssert(buffer);
298
299 // OpenGL gives no guarantees if a texture is deleted while attached to
300 // something other than the currently bound frame buffer
301 GrAlwaysAssert(!buffer->getBound());
302
303 GrAlwaysAssert(!buffer->getDeleted());
304 buffer->deleteAction();
305 }
306
robertphillips@google.comebde3e02012-07-13 17:45:17 +0000307 }
308
bsalomon3c481002016-03-21 09:04:26 -0700309 GrGLvoid deleteFramebuffers(GrGLsizei n, const GrGLuint *frameBuffers) override {
robertphillips@google.comebde3e02012-07-13 17:45:17 +0000310
bsalomon3c481002016-03-21 09:04:26 -0700311 // first potentially unbind the buffers
312 if (this->getFrameBuffer()) {
313 for (int i = 0; i < n; ++i) {
robertphillips@google.comebde3e02012-07-13 17:45:17 +0000314
bsalomon3c481002016-03-21 09:04:26 -0700315 if (frameBuffers[i] ==
316 this->getFrameBuffer()->getID()) {
317 // this ID is the current frame buffer - rebind to the default
318 this->setFrameBuffer(nullptr);
319 }
320 }
321 }
322
323 // then actually "delete" the buffers
robertphillips@google.comebde3e02012-07-13 17:45:17 +0000324 for (int i = 0; i < n; ++i) {
bsalomon3c481002016-03-21 09:04:26 -0700325 GrFrameBufferObj *buffer = FIND(frameBuffers[i], GrFrameBufferObj,
326 kFrameBuffer_ObjTypes);
327 GrAlwaysAssert(buffer);
robertphillips@google.comebde3e02012-07-13 17:45:17 +0000328
bsalomon3c481002016-03-21 09:04:26 -0700329 GrAlwaysAssert(!buffer->getDeleted());
330 buffer->deleteAction();
robertphillips@google.comebde3e02012-07-13 17:45:17 +0000331 }
332 }
333
bsalomon3c481002016-03-21 09:04:26 -0700334 GrGLvoid deleteRenderbuffers(GrGLsizei n,const GrGLuint *renderBuffers) override {
robertphillips@google.comebde3e02012-07-13 17:45:17 +0000335
bsalomon3c481002016-03-21 09:04:26 -0700336 // first potentially unbind the buffers
337 if (this->getRenderBuffer()) {
338 for (int i = 0; i < n; ++i) {
robertphillips@google.comebde3e02012-07-13 17:45:17 +0000339
bsalomon3c481002016-03-21 09:04:26 -0700340 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 }
robertphillips@google.comebde3e02012-07-13 17:45:17 +0000346 }
347 }
bsalomon3c481002016-03-21 09:04:26 -0700348
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], GrRenderBufferObj,
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 }
robertphillips@google.comebde3e02012-07-13 17:45:17 +0000391 }
392
bsalomon3c481002016-03-21 09:04:26 -0700393 GrGLvoid framebufferRenderbuffer(GrGLenum target,
394 GrGLenum attachment,
395 GrGLenum renderbuffertarget,
396 GrGLuint renderBufferID) override {
robertphillips@google.comebde3e02012-07-13 17:45:17 +0000397
bsalomon3c481002016-03-21 09:04:26 -0700398 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, GrRenderBufferObj,
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
robertphillips@google.comebde3e02012-07-13 17:45:17 +0000428 }
robertphillips@google.comebde3e02012-07-13 17:45:17 +0000429
bsalomon3c481002016-03-21 09:04:26 -0700430 ////////////////////////////////////////////////////////////////////////////////
431 GrGLvoid framebufferTexture2D(GrGLenum target, GrGLenum attachment, GrGLenum textarget,
432 GrGLuint textureID, GrGLint level) override {
robertphillips@google.comebde3e02012-07-13 17:45:17 +0000433
bsalomon3c481002016-03-21 09:04:26 -0700434 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);
robertphillips@google.comebde3e02012-07-13 17:45:17 +0000439
bsalomon3c481002016-03-21 09:04:26 -0700440 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());
robertphillips@google.comebde3e02012-07-13 17:45:17 +0000450 }
bsalomon3c481002016-03-21 09:04:26 -0700451
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 };
robertphillips@google.comebde3e02012-07-13 17:45:17 +0000468 }
469
bsalomon3c481002016-03-21 09:04:26 -0700470 GrGLuint createProgram() override {
robertphillips@google.comebde3e02012-07-13 17:45:17 +0000471
bsalomon3c481002016-03-21 09:04:26 -0700472 GrProgramObj *program = CREATE(GrProgramObj, kProgram_ObjTypes);
robertphillips@google.comebde3e02012-07-13 17:45:17 +0000473
bsalomon3c481002016-03-21 09:04:26 -0700474 return program->getID();
robertphillips@google.com0da37192012-03-19 14:42:13 +0000475 }
robertphillips@google.com0da37192012-03-19 14:42:13 +0000476
bsalomon3c481002016-03-21 09:04:26 -0700477 GrGLuint createShader(GrGLenum type) override {
robertphillips@google.com0da37192012-03-19 14:42:13 +0000478
bsalomon3c481002016-03-21 09:04:26 -0700479 GrAlwaysAssert(GR_GL_VERTEX_SHADER == type ||
480 GR_GL_FRAGMENT_SHADER == type);
robertphillips@google.com0da37192012-03-19 14:42:13 +0000481
bsalomon3c481002016-03-21 09:04:26 -0700482 GrShaderObj *shader = CREATE(GrShaderObj, kShader_ObjTypes);
483 shader->setType(type);
484
485 return shader->getID();
robertphillips@google.com0da37192012-03-19 14:42:13 +0000486 }
robertphillips@google.com0da37192012-03-19 14:42:13 +0000487
bsalomon3c481002016-03-21 09:04:26 -0700488 GrGLenum checkFramebufferStatus(GrGLenum target) override { return GR_GL_FRAMEBUFFER_COMPLETE; }
robertphillips@google.comba0cc3e2012-03-26 17:58:35 +0000489
bsalomon3c481002016-03-21 09:04:26 -0700490 GrGLvoid deleteProgram(GrGLuint programID) override {
robertphillips@google.comba0cc3e2012-03-26 17:58:35 +0000491
bsalomon3c481002016-03-21 09:04:26 -0700492 GrProgramObj *program = FIND(programID, GrProgramObj, kProgram_ObjTypes);
493 GrAlwaysAssert(program);
robertphillips@google.com0da37192012-03-19 14:42:13 +0000494
bsalomon3c481002016-03-21 09:04:26 -0700495 if (program->getRefCount()) {
496 // someone is still using this program so we can't delete it here
497 program->setMarkedForDeletion();
bsalomon@google.comecd84842013-03-01 15:36:02 +0000498 } else {
bsalomon3c481002016-03-21 09:04:26 -0700499 program->deleteAction();
robertphillips@google.com0da37192012-03-19 14:42:13 +0000500 }
501 }
502
bsalomon3c481002016-03-21 09:04:26 -0700503 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->genGenericIds(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) override {
612 val[0] = val[1] = 0.5f;
613 }
614
615 GrGLvoid getProgramiv(GrGLuint program, GrGLenum pname, GrGLint* params) override {
616 this->getShaderOrProgramiv(program, pname, params);
617 }
618
619 GrGLvoid getProgramInfoLog(GrGLuint program, GrGLsizei bufsize, GrGLsizei* length,
620 char* infolog) override {
621 this->getInfoLog(program, bufsize, length, infolog);
622 }
623
624 GrGLvoid getQueryiv(GrGLenum GLtarget, GrGLenum pname, GrGLint *params) override {
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) override {
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) override {
650 this->queryResult(id, pname, params);
651 }
652
653 GrGLvoid getShaderiv(GrGLuint shader, GrGLenum pname, GrGLint* params) override {
654 this->getShaderOrProgramiv(shader, pname, params);
655 }
656
657 GrGLvoid getShaderInfoLog(GrGLuint shader, GrGLsizei bufsize, GrGLsizei* length,
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 pname,
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, kVertexArray_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 it 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_ObjTypes);
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_BUFFER == 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 length,
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_RANGE_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_BUFFER_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->getMappedLength());
879 } else {
880 GrAlwaysAssert(false);
881 }
882 }
883
884 GrGLvoid getBufferParameteriv(GrGLenum target, GrGLenum value, GrGLint* params) 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
robertphillips@google.com0da37192012-03-19 14:42:13 +0000901 GrAlwaysAssert(buffer);
902
bsalomon3c481002016-03-21 09:04:26 -0700903 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 }
commit-bot@chromium.org160b4782014-05-05 12:32:37 +0000923 }
924
robertphillips@google.comba0cc3e2012-03-26 17:58:35 +0000925private:
bsalomon3c481002016-03-21 09:04:26 -0700926 // the OpenGLES 2.0 spec says this must be >= 128
927 static const GrGLint kDefaultMaxVertexUniformVectors = 128;
robertphillips@google.comba0cc3e2012-03-26 17:58:35 +0000928
bsalomon3c481002016-03-21 09:04:26 -0700929 // the OpenGLES 2.0 spec says this must be >=16
930 static const GrGLint kDefaultMaxFragmentUniformVectors = 16;
robertphillips@google.comba0cc3e2012-03-26 17:58:35 +0000931
bsalomon3c481002016-03-21 09:04:26 -0700932 // 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* params) {
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() == type) {
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;
robertphillips@google.comba0cc3e2012-03-26 17:58:35 +00001207};
1208
bsalomon3c481002016-03-21 09:04:26 -07001209#undef CREATE
1210#undef FIND
1211
1212DebugInterface::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
1223const 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
robertphillips@google.comba0cc3e2012-03-26 17:58:35 +00001235////////////////////////////////////////////////////////////////////////////////
robertphillips@google.com409566a2012-06-26 20:19:41 +00001236
bsalomon3c481002016-03-21 09:04:26 -07001237const GrGLInterface* GrGLCreateDebugInterface() { return new DebugInterface; }