blob: 80a7cfbd2cdba26465042be242be89925edf01e0 [file] [log] [blame]
bsalomon@google.com74913722011-10-27 20:44:19 +00001/*
2 * Copyright 2011 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8
tomhudson@google.com6bf38b52012-02-14 15:11:59 +00009#include "gl/GrGLInterface.h"
bsalomonb5a94e32016-03-18 12:07:24 -070010#include "GrGLTestInterface.h"
11#include "SkMutex.h"
bsalomon@google.com21cbec42013-01-07 17:23:00 +000012#include "SkTDArray.h"
bsalomon7e340072015-02-11 12:07:31 -080013
14// added to suppress 'no previous prototype' warning and because this code is duplicated in
15// SkNullGLContext.cpp
halcanary9d524f22016-03-29 09:03:52 -070016namespace {
bsalomon7e340072015-02-11 12:07:31 -080017
bsalomon776d3552014-08-14 08:13:27 -070018class BufferObj {
robertphillips@google.comd6543e52013-07-18 17:39:14 +000019public:
bsalomonb5a94e32016-03-18 12:07:24 -070020 BufferObj(GrGLuint id) : fID(id), fDataPtr(nullptr), fSize(0), fMapped(false) {}
halcanary385fe4d2015-08-26 13:07:48 -070021 ~BufferObj() { delete[] fDataPtr; }
robertphillips@google.comd6543e52013-07-18 17:39:14 +000022
robertphillips@google.comae6b7772013-07-18 18:07:39 +000023 void allocate(GrGLsizeiptr size, const GrGLchar* dataPtr) {
bsalomon49f085d2014-09-05 13:34:00 -070024 if (fDataPtr) {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +000025 SkASSERT(0 != fSize);
halcanary385fe4d2015-08-26 13:07:48 -070026 delete[] fDataPtr;
robertphillips@google.comd6543e52013-07-18 17:39:14 +000027 }
28
29 fSize = size;
halcanary385fe4d2015-08-26 13:07:48 -070030 fDataPtr = new char[size];
robertphillips@google.comd6543e52013-07-18 17:39:14 +000031 }
32
33 GrGLuint id() const { return fID; }
34 GrGLchar* dataPtr() { return fDataPtr; }
robertphillips@google.comae6b7772013-07-18 18:07:39 +000035 GrGLsizeiptr size() const { return fSize; }
robertphillips@google.comd6543e52013-07-18 17:39:14 +000036
37 void setMapped(bool mapped) { fMapped = mapped; }
38 bool mapped() const { return fMapped; }
39
40private:
41 GrGLuint fID;
42 GrGLchar* fDataPtr;
robertphillips@google.comae6b7772013-07-18 18:07:39 +000043 GrGLsizeiptr fSize; // size in bytes
robertphillips@google.comd6543e52013-07-18 17:39:14 +000044 bool fMapped;
45};
46
bsalomon776d3552014-08-14 08:13:27 -070047// This class maintains a sparsely populated array of buffer pointers.
48class BufferManager {
49public:
cdaltona957b8a2016-04-06 13:36:38 -070050 BufferManager() : fFreeListHead(kFreeListEnd) {
51 *fBuffers.append() = nullptr; // 0 is not a valid GL buffer id.
52 }
robertphillips@google.comd6543e52013-07-18 17:39:14 +000053
bsalomon776d3552014-08-14 08:13:27 -070054 ~BufferManager() {
halcanary96fcdcc2015-08-27 07:41:13 -070055 // nullptr out the entries that are really free list links rather than ptrs before deleting.
bsalomon776d3552014-08-14 08:13:27 -070056 intptr_t curr = fFreeListHead;
57 while (kFreeListEnd != curr) {
58 intptr_t next = reinterpret_cast<intptr_t>(fBuffers[SkToS32(curr)]);
halcanary96fcdcc2015-08-27 07:41:13 -070059 fBuffers[SkToS32(curr)] = nullptr;
bsalomon776d3552014-08-14 08:13:27 -070060 curr = next;
61 }
62
63 fBuffers.deleteAll();
robertphillips@google.comd6543e52013-07-18 17:39:14 +000064 }
65
bsalomon776d3552014-08-14 08:13:27 -070066 BufferObj* lookUp(GrGLuint id) {
67 BufferObj* buffer = fBuffers[id];
bsalomon49f085d2014-09-05 13:34:00 -070068 SkASSERT(buffer && buffer->id() == id);
bsalomon776d3552014-08-14 08:13:27 -070069 return buffer;
robertphillips@google.comd6543e52013-07-18 17:39:14 +000070 }
71
bsalomon776d3552014-08-14 08:13:27 -070072 BufferObj* create() {
73 GrGLuint id;
74 BufferObj* buffer;
robertphillips@google.comd6543e52013-07-18 17:39:14 +000075
bsalomon776d3552014-08-14 08:13:27 -070076 if (kFreeListEnd == fFreeListHead) {
77 // no free slots - create a new one
78 id = fBuffers.count();
halcanary385fe4d2015-08-26 13:07:48 -070079 buffer = new BufferObj(id);
bsalomon776d3552014-08-14 08:13:27 -070080 *fBuffers.append() = buffer;
81 } else {
82 // grab the head of the free list and advance the head to the next free slot.
83 id = static_cast<GrGLuint>(fFreeListHead);
84 fFreeListHead = reinterpret_cast<intptr_t>(fBuffers[id]);
robertphillips@google.comd6543e52013-07-18 17:39:14 +000085
halcanary385fe4d2015-08-26 13:07:48 -070086 buffer = new BufferObj(id);
bsalomon776d3552014-08-14 08:13:27 -070087 fBuffers[id] = buffer;
88 }
robertphillips@google.comd6543e52013-07-18 17:39:14 +000089
bsalomon776d3552014-08-14 08:13:27 -070090 return buffer;
91 }
92
93 void free(BufferObj* buffer) {
cdaltona957b8a2016-04-06 13:36:38 -070094 SkASSERT(buffer);
bsalomon776d3552014-08-14 08:13:27 -070095 SkASSERT(fBuffers.count() > 0);
96
97 GrGLuint id = buffer->id();
halcanary385fe4d2015-08-26 13:07:48 -070098 delete buffer;
bsalomon776d3552014-08-14 08:13:27 -070099
100 fBuffers[id] = reinterpret_cast<BufferObj*>(fFreeListHead);
101 fFreeListHead = id;
102 }
103
104private:
105 static const intptr_t kFreeListEnd = -1;
106 // Index of the first entry of fBuffers in the free list. Free slots in fBuffers are indices to
107 // the next free slot. The last free slot has a value of kFreeListEnd.
108 intptr_t fFreeListHead;
109 SkTDArray<BufferObj*> fBuffers;
110};
111
bsalomonb5a94e32016-03-18 12:07:24 -0700112/** Null interface implementation */
113class NullInterface : public GrGLTestInterface {
bsalomon776d3552014-08-14 08:13:27 -0700114public:
bsalomonb5a94e32016-03-18 12:07:24 -0700115 NullInterface()
116 : fCurrArrayBuffer(0)
117 , fCurrElementArrayBuffer(0)
118 , fCurrPixelPackBuffer(0)
119 , fCurrPixelUnpackBuffer(0)
fmalitaba73ad02016-03-19 13:07:13 -0700120 , fCurrProgramID(0)
bsalomonb5a94e32016-03-18 12:07:24 -0700121 , fCurrShaderID(0)
122 , fCurrGenericID(0)
123 , fCurrUniformLocation(0) {
124 this->init(kGL_GrGLStandard);
125 }
bsalomon776d3552014-08-14 08:13:27 -0700126
bsalomonb5a94e32016-03-18 12:07:24 -0700127 GrGLenum checkFramebufferStatus(GrGLenum target) override {
128 return GR_GL_FRAMEBUFFER_COMPLETE;
129 }
130
131 GrGLvoid genBuffers(GrGLsizei n, GrGLuint* ids) override {
132 for (int i = 0; i < n; ++i) {
133 BufferObj* buffer = fBufferManager.create();
134 ids[i] = buffer->id();
135 }
136 }
137
138 GrGLvoid bufferData(GrGLenum target, GrGLsizeiptr size, const GrGLvoid* data,
139 GrGLenum usage) override {
140 GrGLuint id = 0;
141
142 switch (target) {
143 case GR_GL_ARRAY_BUFFER:
144 id = fCurrArrayBuffer;
145 break;
146 case GR_GL_ELEMENT_ARRAY_BUFFER:
147 id = fCurrElementArrayBuffer;
148 break;
149 case GR_GL_PIXEL_PACK_BUFFER:
150 id = fCurrPixelPackBuffer;
151 break;
152 case GR_GL_PIXEL_UNPACK_BUFFER:
153 id = fCurrPixelUnpackBuffer;
154 break;
155 default:
156 SkFAIL("Unexpected target to nullGLBufferData");
157 break;
158 }
159
160 if (id > 0) {
161 BufferObj* buffer = fBufferManager.lookUp(id);
162 buffer->allocate(size, (const GrGLchar*) data);
163 }
164 }
165
166 GrGLuint createProgram() override {
167 return ++fCurrProgramID;
168 }
169
170 GrGLuint createShader(GrGLenum type) override {
171 return ++fCurrShaderID;
172 }
173
174 GrGLvoid bindBuffer(GrGLenum target, GrGLuint buffer) override {
175 switch (target) {
176 case GR_GL_ARRAY_BUFFER:
177 fCurrArrayBuffer = buffer;
178 break;
179 case GR_GL_ELEMENT_ARRAY_BUFFER:
180 fCurrElementArrayBuffer = buffer;
181 break;
182 case GR_GL_PIXEL_PACK_BUFFER:
183 fCurrPixelPackBuffer = buffer;
184 break;
185 case GR_GL_PIXEL_UNPACK_BUFFER:
186 fCurrPixelUnpackBuffer = buffer;
187 break;
188 }
189 }
190
191 // deleting a bound buffer has the side effect of binding 0
192 GrGLvoid deleteBuffers(GrGLsizei n, const GrGLuint* ids) override {
193 for (int i = 0; i < n; ++i) {
194 if (ids[i] == fCurrArrayBuffer) {
195 fCurrArrayBuffer = 0;
196 }
197 if (ids[i] == fCurrElementArrayBuffer) {
198 fCurrElementArrayBuffer = 0;
199 }
200 if (ids[i] == fCurrPixelPackBuffer) {
201 fCurrPixelPackBuffer = 0;
202 }
203 if (ids[i] == fCurrPixelUnpackBuffer) {
204 fCurrPixelUnpackBuffer = 0;
205 }
206
cdaltona957b8a2016-04-06 13:36:38 -0700207 if (ids[i] > 0) {
208 BufferObj* buffer = fBufferManager.lookUp(ids[i]);
209 fBufferManager.free(buffer);
210 }
bsalomonb5a94e32016-03-18 12:07:24 -0700211 }
212 }
213
214 GrGLvoid genFramebuffers(GrGLsizei n, GrGLuint *framebuffers) override {
215 this->genGenericIds(n, framebuffers);
216 }
217
218 GrGLvoid genQueries(GrGLsizei n, GrGLuint *ids) override { this->genGenericIds(n, ids); }
219
220 GrGLvoid genRenderbuffers(GrGLsizei n, GrGLuint *renderbuffers) override {
221 this->genGenericIds(n, renderbuffers);
222 }
223
224 GrGLvoid genTextures(GrGLsizei n, GrGLuint *textures) override {
225 this->genGenericIds(n, textures);
226 }
227
228 GrGLvoid genVertexArrays(GrGLsizei n, GrGLuint *arrays) override {
229 this->genGenericIds(n, arrays);
230 }
231
232 GrGLenum getError() override { return GR_GL_NO_ERROR; }
233
234 GrGLvoid getIntegerv(GrGLenum pname, GrGLint* params) override {
235 // TODO: remove from Ganesh the #defines for gets we don't use.
236 // We would like to minimize gets overall due to performance issues
237 switch (pname) {
238 case GR_GL_CONTEXT_PROFILE_MASK:
239 *params = GR_GL_CONTEXT_COMPATIBILITY_PROFILE_BIT;
240 break;
241 case GR_GL_STENCIL_BITS:
242 *params = 8;
243 break;
244 case GR_GL_SAMPLES:
245 *params = 1;
246 break;
247 case GR_GL_FRAMEBUFFER_BINDING:
248 *params = 0;
249 break;
250 case GR_GL_VIEWPORT:
251 params[0] = 0;
252 params[1] = 0;
253 params[2] = 800;
254 params[3] = 600;
255 break;
256 case GR_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
257 case GR_GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS:
258 case GR_GL_MAX_TEXTURE_IMAGE_UNITS:
259 case GR_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
260 *params = 8;
261 break;
262 case GR_GL_MAX_TEXTURE_COORDS:
263 *params = 8;
264 break;
265 case GR_GL_MAX_VERTEX_UNIFORM_VECTORS:
266 *params = kDefaultMaxVertexUniformVectors;
267 break;
268 case GR_GL_MAX_FRAGMENT_UNIFORM_VECTORS:
269 *params = kDefaultMaxFragmentUniformVectors;
270 break;
271 case GR_GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
272 *params = 16 * 4;
273 break;
274 case GR_GL_NUM_COMPRESSED_TEXTURE_FORMATS:
275 *params = 0;
276 break;
277 case GR_GL_COMPRESSED_TEXTURE_FORMATS:
278 break;
279 case GR_GL_MAX_TEXTURE_SIZE:
280 *params = 8192;
281 break;
282 case GR_GL_MAX_RENDERBUFFER_SIZE:
283 *params = 8192;
284 break;
285 case GR_GL_MAX_SAMPLES:
286 *params = 32;
287 break;
288 case GR_GL_MAX_VERTEX_ATTRIBS:
289 *params = kDefaultMaxVertexAttribs;
290 break;
291 case GR_GL_MAX_VARYING_VECTORS:
292 *params = kDefaultMaxVaryingVectors;
293 break;
294 case GR_GL_NUM_EXTENSIONS: {
295 GrGLint i = 0;
296 while (kExtensions[i++]);
297 *params = i;
298 break;
299 }
300 default:
301 SkFAIL("Unexpected pname to GetIntegerv");
302 }
303 }
304
305 GrGLvoid getProgramiv(GrGLuint program, GrGLenum pname, GrGLint* params) override {
306 this->getShaderOrProgramiv(program, pname, params);
307 }
308
309 GrGLvoid getProgramInfoLog(GrGLuint program, GrGLsizei bufsize, GrGLsizei* length,
310 char* infolog) override {
311 this->getInfoLog(program, bufsize, length, infolog);
312 }
313
314 GrGLvoid getMultisamplefv(GrGLenum pname, GrGLuint index, GrGLfloat* val) override {
315 val[0] = val[1] = 0.5f;
316 }
317
318 GrGLvoid getQueryiv(GrGLenum GLtarget, GrGLenum pname, GrGLint *params) override {
319 switch (pname) {
320 case GR_GL_CURRENT_QUERY:
321 *params = 0;
322 break;
323 case GR_GL_QUERY_COUNTER_BITS:
324 *params = 32;
325 break;
326 default:
327 SkFAIL("Unexpected pname passed GetQueryiv.");
328 }
329 }
330
331 GrGLvoid getQueryObjecti64v(GrGLuint id, GrGLenum pname, GrGLint64 *params) override {
bsalomon3c481002016-03-21 09:04:26 -0700332 this->queryResult(id, pname, params);
bsalomonb5a94e32016-03-18 12:07:24 -0700333 }
334
335 GrGLvoid getQueryObjectiv(GrGLuint id, GrGLenum pname, GrGLint *params) override {
bsalomon3c481002016-03-21 09:04:26 -0700336 this->queryResult(id, pname, params);
bsalomonb5a94e32016-03-18 12:07:24 -0700337 }
338
339 GrGLvoid getQueryObjectui64v(GrGLuint id, GrGLenum pname, GrGLuint64 *params) override {
bsalomon3c481002016-03-21 09:04:26 -0700340 this->queryResult(id, pname, params);
bsalomonb5a94e32016-03-18 12:07:24 -0700341 }
342
343 GrGLvoid getQueryObjectuiv(GrGLuint id, GrGLenum pname, GrGLuint *params) override {
bsalomon3c481002016-03-21 09:04:26 -0700344 this->queryResult(id, pname, params);
bsalomonb5a94e32016-03-18 12:07:24 -0700345 }
346
347 GrGLvoid getShaderiv(GrGLuint shader, GrGLenum pname, GrGLint* params) override {
348 this->getShaderOrProgramiv(shader, pname, params);
349 }
350
351 GrGLvoid getShaderInfoLog(GrGLuint shader, GrGLsizei bufsize, GrGLsizei* length,
352 char* infolog) override {
353 this->getInfoLog(shader, bufsize, length, infolog);
354 }
355
356 const GrGLubyte* getString(GrGLenum name) override {
357 switch (name) {
358 case GR_GL_EXTENSIONS:
359 return CombinedExtensionString();
360 case GR_GL_VERSION:
bsalomon3c481002016-03-21 09:04:26 -0700361 return (const GrGLubyte*)"4.0 Null GL";
bsalomonb5a94e32016-03-18 12:07:24 -0700362 case GR_GL_SHADING_LANGUAGE_VERSION:
bsalomon3c481002016-03-21 09:04:26 -0700363 return (const GrGLubyte*)"4.20.8 Null GLSL";
bsalomonb5a94e32016-03-18 12:07:24 -0700364 case GR_GL_VENDOR:
bsalomon3c481002016-03-21 09:04:26 -0700365 return (const GrGLubyte*)"Null Vendor";
bsalomonb5a94e32016-03-18 12:07:24 -0700366 case GR_GL_RENDERER:
bsalomon3c481002016-03-21 09:04:26 -0700367 return (const GrGLubyte*)"The Null (Non-)Renderer";
bsalomonb5a94e32016-03-18 12:07:24 -0700368 default:
369 SkFAIL("Unexpected name passed to GetString");
370 return nullptr;
371 }
372 }
373
374 const GrGLubyte* getStringi(GrGLenum name, GrGLuint i) override {
375 switch (name) {
376 case GR_GL_EXTENSIONS: {
377 GrGLint count;
378 this->getIntegerv(GR_GL_NUM_EXTENSIONS, &count);
379 if ((GrGLint)i <= count) {
380 return (const GrGLubyte*) kExtensions[i];
381 } else {
382 return nullptr;
383 }
384 }
385 default:
386 SkFAIL("Unexpected name passed to GetStringi");
387 return nullptr;
388 }
389 }
390
bsalomonb5a94e32016-03-18 12:07:24 -0700391 GrGLint getUniformLocation(GrGLuint program, const char* name) override {
392 return ++fCurrUniformLocation;
393 }
394
395 GrGLvoid* mapBufferRange(GrGLenum target, GrGLintptr offset, GrGLsizeiptr length,
396 GrGLbitfield access) override {
397 GrGLuint id = 0;
398 switch (target) {
399 case GR_GL_ARRAY_BUFFER:
400 id = fCurrArrayBuffer;
401 break;
402 case GR_GL_ELEMENT_ARRAY_BUFFER:
403 id = fCurrElementArrayBuffer;
404 break;
405 case GR_GL_PIXEL_PACK_BUFFER:
406 id = fCurrPixelPackBuffer;
407 break;
408 case GR_GL_PIXEL_UNPACK_BUFFER:
409 id = fCurrPixelUnpackBuffer;
410 break;
411 }
412
413 if (id > 0) {
414 // We just ignore the offset and length here.
415 BufferObj* buffer = fBufferManager.lookUp(id);
416 SkASSERT(!buffer->mapped());
417 buffer->setMapped(true);
418 return buffer->dataPtr();
419 }
420 return nullptr;
421 }
422
423 GrGLvoid* mapBuffer(GrGLenum target, GrGLenum access) override {
424 GrGLuint id = 0;
425 switch (target) {
426 case GR_GL_ARRAY_BUFFER:
427 id = fCurrArrayBuffer;
428 break;
429 case GR_GL_ELEMENT_ARRAY_BUFFER:
430 id = fCurrElementArrayBuffer;
431 break;
432 case GR_GL_PIXEL_PACK_BUFFER:
433 id = fCurrPixelPackBuffer;
434 break;
435 case GR_GL_PIXEL_UNPACK_BUFFER:
436 id = fCurrPixelUnpackBuffer;
437 break;
438 }
439
440 if (id > 0) {
441 BufferObj* buffer = fBufferManager.lookUp(id);
442 SkASSERT(!buffer->mapped());
443 buffer->setMapped(true);
444 return buffer->dataPtr();
445 }
446
447 SkASSERT(false);
448 return nullptr; // no buffer bound to target
449 }
450
451 GrGLboolean unmapBuffer(GrGLenum target) override {
452 GrGLuint id = 0;
453 switch (target) {
454 case GR_GL_ARRAY_BUFFER:
455 id = fCurrArrayBuffer;
456 break;
457 case GR_GL_ELEMENT_ARRAY_BUFFER:
458 id = fCurrElementArrayBuffer;
459 break;
460 case GR_GL_PIXEL_PACK_BUFFER:
461 id = fCurrPixelPackBuffer;
462 break;
463 case GR_GL_PIXEL_UNPACK_BUFFER:
464 id = fCurrPixelUnpackBuffer;
465 break;
466 }
467 if (id > 0) {
468 BufferObj* buffer = fBufferManager.lookUp(id);
469 SkASSERT(buffer->mapped());
470 buffer->setMapped(false);
471 return GR_GL_TRUE;
472 }
473
474 GrAlwaysAssert(false);
475 return GR_GL_FALSE; // GR_GL_INVALID_OPERATION;
476 }
477
478 GrGLvoid getBufferParameteriv(GrGLenum target, GrGLenum pname, GrGLint* params) override {
479 switch (pname) {
480 case GR_GL_BUFFER_MAPPED: {
481 *params = GR_GL_FALSE;
482 GrGLuint id = 0;
483 switch (target) {
484 case GR_GL_ARRAY_BUFFER:
485 id = fCurrArrayBuffer;
486 break;
487 case GR_GL_ELEMENT_ARRAY_BUFFER:
488 id = fCurrElementArrayBuffer;
489 break;
490 case GR_GL_PIXEL_PACK_BUFFER:
491 id = fCurrPixelPackBuffer;
492 break;
493 case GR_GL_PIXEL_UNPACK_BUFFER:
494 id = fCurrPixelUnpackBuffer;
495 break;
496 }
497 if (id > 0) {
498 BufferObj* buffer = fBufferManager.lookUp(id);
499 if (buffer->mapped()) {
500 *params = GR_GL_TRUE;
501 }
502 }
503 break; }
504 default:
505 SkFAIL("Unexpected pname to GetBufferParamateriv");
506 break;
507 }
508 };
509
510private:
bsalomon776d3552014-08-14 08:13:27 -0700511 BufferManager fBufferManager;
512 GrGLuint fCurrArrayBuffer;
513 GrGLuint fCurrElementArrayBuffer;
bsalomonb5a94e32016-03-18 12:07:24 -0700514 GrGLuint fCurrPixelPackBuffer;
515 GrGLuint fCurrPixelUnpackBuffer;
bsalomon776d3552014-08-14 08:13:27 -0700516 GrGLuint fCurrProgramID;
517 GrGLuint fCurrShaderID;
bsalomonb5a94e32016-03-18 12:07:24 -0700518 GrGLuint fCurrGenericID;
519 GrGLuint fCurrUniformLocation;
bsalomon776d3552014-08-14 08:13:27 -0700520
bsalomonb5a94e32016-03-18 12:07:24 -0700521 // the OpenGLES 2.0 spec says this must be >= 128
522 static const GrGLint kDefaultMaxVertexUniformVectors = 128;
bsalomon776d3552014-08-14 08:13:27 -0700523
bsalomonb5a94e32016-03-18 12:07:24 -0700524 // the OpenGLES 2.0 spec says this must be >=16
525 static const GrGLint kDefaultMaxFragmentUniformVectors = 16;
bsalomon776d3552014-08-14 08:13:27 -0700526
bsalomonb5a94e32016-03-18 12:07:24 -0700527 // the OpenGLES 2.0 spec says this must be >= 8
528 static const GrGLint kDefaultMaxVertexAttribs = 8;
bsalomon776d3552014-08-14 08:13:27 -0700529
bsalomonb5a94e32016-03-18 12:07:24 -0700530 // the OpenGLES 2.0 spec says this must be >= 8
531 static const GrGLint kDefaultMaxVaryingVectors = 8;
bsalomon776d3552014-08-14 08:13:27 -0700532
bsalomonb5a94e32016-03-18 12:07:24 -0700533 static const char* kExtensions[];
robertphillips@google.comd6543e52013-07-18 17:39:14 +0000534
bsalomonb5a94e32016-03-18 12:07:24 -0700535 static const GrGLubyte* CombinedExtensionString() {
536 static SkString gExtString;
537 static SkMutex gMutex;
538 gMutex.acquire();
539 if (0 == gExtString.size()) {
540 int i = 0;
541 while (kExtensions[i]) {
542 if (i > 0) {
543 gExtString.append(" ");
bsalomon@google.com74913722011-10-27 20:44:19 +0000544 }
bsalomonb5a94e32016-03-18 12:07:24 -0700545 gExtString.append(kExtensions[i]);
546 ++i;
bsalomon@google.com74913722011-10-27 20:44:19 +0000547 }
bsalomonb5a94e32016-03-18 12:07:24 -0700548 }
549 gMutex.release();
550 return (const GrGLubyte*) gExtString.c_str();
551 }
552
553 GrGLvoid genGenericIds(GrGLsizei n, GrGLuint* ids) {
554 for (int i = 0; i < n; ++i) {
555 ids[i] = ++fCurrGenericID;
556 }
557 }
558
559 GrGLvoid getInfoLog(GrGLuint object, GrGLsizei bufsize, GrGLsizei* length,
560 char* infolog) {
561 if (length) {
562 *length = 0;
563 }
564 if (bufsize > 0) {
565 *infolog = 0;
566 }
567 }
568
569 GrGLvoid getShaderOrProgramiv(GrGLuint object, GrGLenum pname, GrGLint* params) {
570 switch (pname) {
571 case GR_GL_LINK_STATUS: // fallthru
572 case GR_GL_COMPILE_STATUS:
573 *params = GR_GL_TRUE;
574 break;
575 case GR_GL_INFO_LOG_LENGTH:
576 *params = 0;
577 break;
578 // we don't expect any other pnames
579 default:
580 SkFAIL("Unexpected pname to GetProgramiv");
581 break;
582 }
583 }
584
585 template <typename T>
586 void queryResult(GrGLenum GLtarget, GrGLenum pname, T *params) {
587 switch (pname) {
588 case GR_GL_QUERY_RESULT_AVAILABLE:
589 *params = GR_GL_TRUE;
590 break;
591 case GR_GL_QUERY_RESULT:
592 *params = 0;
593 break;
594 default:
595 SkFAIL("Unexpected pname passed to GetQueryObject.");
596 break;
597 }
bsalomon@google.com74913722011-10-27 20:44:19 +0000598 }
bsalomon3c481002016-03-21 09:04:26 -0700599
600 typedef GrGLTestInterface INHERITED;
bsalomon@google.com74913722011-10-27 20:44:19 +0000601};
602
bsalomonb5a94e32016-03-18 12:07:24 -0700603const char* NullInterface::kExtensions[] = {
604 "GL_ARB_framebuffer_object",
605 "GL_ARB_blend_func_extended",
606 "GL_ARB_timer_query",
607 "GL_ARB_draw_buffers",
608 "GL_ARB_occlusion_query",
609 "GL_EXT_stencil_wrap",
610 nullptr, // signifies the end of the array.
611};
caryclark@google.comcf6285b2012-06-06 12:09:01 +0000612
bsalomonb5a94e32016-03-18 12:07:24 -0700613} // anonymous namespace
commit-bot@chromium.orgc72425a2014-01-21 16:09:18 +0000614
bsalomonb5a94e32016-03-18 12:07:24 -0700615const GrGLInterface* GrGLCreateNullInterface() { return new NullInterface; }