OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 | 8 |
9 #include "gl/GrGLInterface.h" | 9 #include "gl/GrGLInterface.h" |
10 #include "GrGLDefines.h" | 10 #include "GrGLTestInterface.h" |
11 #include "SkMutex.h" | |
11 #include "SkTDArray.h" | 12 #include "SkTDArray.h" |
12 #include "GrGLNoOpInterface.h" | |
13 #include "SkTLS.h" | |
14 | |
15 // TODO: Delete this file after chrome starts using SkNullGLContext. | |
16 | 13 |
17 // added to suppress 'no previous prototype' warning and because this code is du plicated in | 14 // added to suppress 'no previous prototype' warning and because this code is du plicated in |
18 // SkNullGLContext.cpp | 15 // SkNullGLContext.cpp |
19 namespace { | 16 namespace { |
20 | 17 |
21 class BufferObj { | 18 class BufferObj { |
22 public: | 19 public: |
23 | 20 BufferObj(GrGLuint id) : fID(id), fDataPtr(nullptr), fSize(0), fMapped(false ) {} |
24 | |
25 BufferObj(GrGLuint id) : fID(id), fDataPtr(nullptr), fSize(0), fMapped(false ) { | |
26 } | |
27 ~BufferObj() { delete[] fDataPtr; } | 21 ~BufferObj() { delete[] fDataPtr; } |
28 | 22 |
29 void allocate(GrGLsizeiptr size, const GrGLchar* dataPtr) { | 23 void allocate(GrGLsizeiptr size, const GrGLchar* dataPtr) { |
30 if (fDataPtr) { | 24 if (fDataPtr) { |
31 SkASSERT(0 != fSize); | 25 SkASSERT(0 != fSize); |
32 delete[] fDataPtr; | 26 delete[] fDataPtr; |
33 } | 27 } |
34 | 28 |
35 fSize = size; | 29 fSize = size; |
36 fDataPtr = new char[size]; | 30 fDataPtr = new char[size]; |
37 } | 31 } |
38 | 32 |
39 GrGLuint id() const { return fID; } | 33 GrGLuint id() const { return fID; } |
40 GrGLchar* dataPtr() { return fDataPtr; } | 34 GrGLchar* dataPtr() { return fDataPtr; } |
41 GrGLsizeiptr size() const { return fSize; } | 35 GrGLsizeiptr size() const { return fSize; } |
42 | 36 |
43 void setMapped(bool mapped) { fMapped = mapped; } | 37 void setMapped(bool mapped) { fMapped = mapped; } |
44 bool mapped() const { return fMapped; } | 38 bool mapped() const { return fMapped; } |
45 | 39 |
46 private: | 40 private: |
47 GrGLuint fID; | 41 GrGLuint fID; |
48 GrGLchar* fDataPtr; | 42 GrGLchar* fDataPtr; |
49 GrGLsizeiptr fSize; // size in bytes | 43 GrGLsizeiptr fSize; // size in bytes |
50 bool fMapped; | 44 bool fMapped; |
51 }; | 45 }; |
52 | 46 |
53 // This class maintains a sparsely populated array of buffer pointers. | 47 // This class maintains a sparsely populated array of buffer pointers. |
54 class BufferManager { | 48 class BufferManager { |
55 public: | 49 public: |
56 | |
57 | |
58 BufferManager() : fFreeListHead(kFreeListEnd) {} | 50 BufferManager() : fFreeListHead(kFreeListEnd) {} |
59 | 51 |
60 ~BufferManager() { | 52 ~BufferManager() { |
61 // nullptr out the entries that are really free list links rather than p trs before deleting. | 53 // nullptr out the entries that are really free list links rather than p trs before deleting. |
62 intptr_t curr = fFreeListHead; | 54 intptr_t curr = fFreeListHead; |
63 while (kFreeListEnd != curr) { | 55 while (kFreeListEnd != curr) { |
64 intptr_t next = reinterpret_cast<intptr_t>(fBuffers[SkToS32(curr)]); | 56 intptr_t next = reinterpret_cast<intptr_t>(fBuffers[SkToS32(curr)]); |
65 fBuffers[SkToS32(curr)] = nullptr; | 57 fBuffers[SkToS32(curr)] = nullptr; |
66 curr = next; | 58 curr = next; |
67 } | 59 } |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
107 } | 99 } |
108 | 100 |
109 private: | 101 private: |
110 static const intptr_t kFreeListEnd = -1; | 102 static const intptr_t kFreeListEnd = -1; |
111 // Index of the first entry of fBuffers in the free list. Free slots in fBuf fers are indices to | 103 // Index of the first entry of fBuffers in the free list. Free slots in fBuf fers are indices to |
112 // the next free slot. The last free slot has a value of kFreeListEnd. | 104 // the next free slot. The last free slot has a value of kFreeListEnd. |
113 intptr_t fFreeListHead; | 105 intptr_t fFreeListHead; |
114 SkTDArray<BufferObj*> fBuffers; | 106 SkTDArray<BufferObj*> fBuffers; |
115 }; | 107 }; |
116 | 108 |
117 /** | 109 /** Null interface implementation */ |
118 * The global-to-thread state object for the null interface. All null interfaces on the | 110 class NullInterface : public GrGLTestInterface { |
119 * same thread currently share one of these. This means two null contexts on the same thread | |
120 * can interfere with each other. It may make sense to more integrate this into SkNullGLContext | |
121 * and use it's makeCurrent mechanism. | |
122 */ | |
123 struct ThreadContext { | |
124 public: | 111 public: |
125 | 112 NullInterface() |
126 | 113 : fCurrArrayBuffer(0) |
114 , fCurrElementArrayBuffer(0) | |
115 , fCurrPixelPackBuffer(0) | |
116 , fCurrPixelUnpackBuffer(0) | |
117 , fCurrShaderID(0) | |
118 , fCurrGenericID(0) | |
119 , fCurrUniformLocation(0) { | |
120 this->init(kGL_GrGLStandard); | |
121 } | |
122 | |
123 GrGLenum checkFramebufferStatus(GrGLenum target) override { | |
124 return GR_GL_FRAMEBUFFER_COMPLETE; | |
125 } | |
126 | |
127 GrGLvoid genBuffers(GrGLsizei n, GrGLuint* ids) override { | |
128 for (int i = 0; i < n; ++i) { | |
129 BufferObj* buffer = fBufferManager.create(); | |
130 ids[i] = buffer->id(); | |
131 } | |
132 } | |
133 | |
134 GrGLvoid bufferData(GrGLenum target, GrGLsizeiptr size, const GrGLvoid* data , GrGLenum usage) { | |
135 GrGLuint id = 0; | |
136 | |
137 switch (target) { | |
138 case GR_GL_ARRAY_BUFFER: | |
139 id = fCurrArrayBuffer; | |
140 break; | |
141 case GR_GL_ELEMENT_ARRAY_BUFFER: | |
142 id = fCurrElementArrayBuffer; | |
143 break; | |
144 case GR_GL_PIXEL_PACK_BUFFER: | |
145 id = fCurrPixelPackBuffer; | |
146 break; | |
147 case GR_GL_PIXEL_UNPACK_BUFFER: | |
148 id = fCurrPixelUnpackBuffer; | |
149 break; | |
150 default: | |
151 SkFAIL("Unexpected target to nullGLBufferData"); | |
152 break; | |
153 } | |
154 | |
155 if (id > 0) { | |
156 BufferObj* buffer = fBufferManager.lookUp(id); | |
157 buffer->allocate(size, (const GrGLchar*) data); | |
158 } | |
159 } | |
160 | |
161 GrGLuint createProgram() override { | |
162 return ++fCurrProgramID; | |
163 } | |
164 | |
165 GrGLuint createShader(GrGLenum type) override { | |
166 return ++fCurrShaderID; | |
167 } | |
168 | |
169 GrGLvoid bindBuffer(GrGLenum target, GrGLuint buffer) override { | |
170 switch (target) { | |
171 case GR_GL_ARRAY_BUFFER: | |
172 fCurrArrayBuffer = buffer; | |
173 break; | |
174 case GR_GL_ELEMENT_ARRAY_BUFFER: | |
175 fCurrElementArrayBuffer = buffer; | |
176 break; | |
177 case GR_GL_PIXEL_PACK_BUFFER: | |
178 fCurrPixelPackBuffer = buffer; | |
179 break; | |
180 case GR_GL_PIXEL_UNPACK_BUFFER: | |
181 fCurrPixelUnpackBuffer = buffer; | |
182 break; | |
183 } | |
184 } | |
185 | |
robertphillips
2016/03/18 17:49:20
space this over ?
bsalomon
2016/03/18 18:04:06
Done.
| |
186 // deleting a bound buffer has the side effect of binding 0 | |
187 GrGLvoid deleteBuffers(GrGLsizei n, const GrGLuint* ids) override { | |
188 for (int i = 0; i < n; ++i) { | |
189 if (ids[i] == fCurrArrayBuffer) { | |
190 fCurrArrayBuffer = 0; | |
191 } | |
192 if (ids[i] == fCurrElementArrayBuffer) { | |
193 fCurrElementArrayBuffer = 0; | |
194 } | |
195 if (ids[i] == fCurrPixelPackBuffer) { | |
196 fCurrPixelPackBuffer = 0; | |
197 } | |
198 if (ids[i] == fCurrPixelUnpackBuffer) { | |
199 fCurrPixelUnpackBuffer = 0; | |
200 } | |
201 | |
202 BufferObj* buffer = fBufferManager.lookUp(ids[i]); | |
203 fBufferManager.free(buffer); | |
204 } | |
205 } | |
206 | |
207 GrGLvoid genFramebuffers(GrGLsizei n, GrGLuint *framebuffers) override { | |
208 this->genGenericIds(n, framebuffers); | |
209 } | |
210 | |
211 GrGLvoid genQueries(GrGLsizei n, GrGLuint *ids) override { this->genGenericI ds(n, ids); } | |
212 | |
213 GrGLvoid genRenderbuffers(GrGLsizei n, GrGLuint *renderbuffers) override { | |
214 this->genGenericIds(n, renderbuffers); | |
215 } | |
216 | |
217 GrGLvoid genTextures(GrGLsizei n, GrGLuint *textures) override { | |
218 this->genGenericIds(n, textures); | |
219 } | |
220 | |
221 GrGLvoid genVertexArrays(GrGLsizei n, GrGLuint *arrays) override { | |
222 this->genGenericIds(n, arrays); | |
223 } | |
224 | |
225 GrGLenum getError() override { return GR_GL_NO_ERROR; } | |
226 | |
227 GrGLvoid getIntegerv(GrGLenum pname, GrGLint* params) override { | |
228 // TODO: remove from Ganesh the #defines for gets we don't use. | |
229 // We would like to minimize gets overall due to performance issues | |
230 switch (pname) { | |
231 case GR_GL_CONTEXT_PROFILE_MASK: | |
232 *params = GR_GL_CONTEXT_COMPATIBILITY_PROFILE_BIT; | |
233 break; | |
234 case GR_GL_STENCIL_BITS: | |
235 *params = 8; | |
236 break; | |
237 case GR_GL_SAMPLES: | |
238 *params = 1; | |
239 break; | |
240 case GR_GL_FRAMEBUFFER_BINDING: | |
241 *params = 0; | |
242 break; | |
243 case GR_GL_VIEWPORT: | |
244 params[0] = 0; | |
245 params[1] = 0; | |
246 params[2] = 800; | |
247 params[3] = 600; | |
248 break; | |
249 case GR_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: | |
250 case GR_GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS: | |
251 case GR_GL_MAX_TEXTURE_IMAGE_UNITS: | |
252 case GR_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: | |
253 *params = 8; | |
254 break; | |
255 case GR_GL_MAX_TEXTURE_COORDS: | |
256 *params = 8; | |
257 break; | |
258 case GR_GL_MAX_VERTEX_UNIFORM_VECTORS: | |
259 *params = kDefaultMaxVertexUniformVectors; | |
260 break; | |
261 case GR_GL_MAX_FRAGMENT_UNIFORM_VECTORS: | |
262 *params = kDefaultMaxFragmentUniformVectors; | |
263 break; | |
264 case GR_GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: | |
265 *params = 16 * 4; | |
266 break; | |
267 case GR_GL_NUM_COMPRESSED_TEXTURE_FORMATS: | |
268 *params = 0; | |
269 break; | |
270 case GR_GL_COMPRESSED_TEXTURE_FORMATS: | |
271 break; | |
272 case GR_GL_MAX_TEXTURE_SIZE: | |
273 *params = 8192; | |
274 break; | |
275 case GR_GL_MAX_RENDERBUFFER_SIZE: | |
276 *params = 8192; | |
277 break; | |
278 case GR_GL_MAX_SAMPLES: | |
279 *params = 32; | |
280 break; | |
281 case GR_GL_MAX_VERTEX_ATTRIBS: | |
282 *params = kDefaultMaxVertexAttribs; | |
283 break; | |
284 case GR_GL_MAX_VARYING_VECTORS: | |
285 *params = kDefaultMaxVaryingVectors; | |
286 break; | |
287 case GR_GL_NUM_EXTENSIONS: { | |
288 GrGLint i = 0; | |
289 while (kExtensions[i++]); | |
290 *params = i; | |
291 break; | |
292 } | |
293 default: | |
294 SkFAIL("Unexpected pname to GetIntegerv"); | |
295 } | |
296 } | |
297 | |
298 GrGLvoid getProgramiv(GrGLuint program, GrGLenum pname, GrGLint* params) ove rride { | |
299 this->getShaderOrProgramiv(program, pname, params); | |
300 } | |
301 | |
302 GrGLvoid getProgramInfoLog(GrGLuint program, GrGLsizei bufsize, GrGLsizei* l ength, | |
robertphillips
2016/03/18 17:49:20
line up ?
bsalomon
2016/03/18 18:04:06
Done.
| |
303 char* infolog) override { | |
304 this->getInfoLog(program, bufsize, length, infolog); | |
305 } | |
306 | |
307 GrGLvoid getMultisamplefv(GrGLenum pname, GrGLuint index, GrGLfloat* val) ov erride { | |
308 val[0] = val[1] = 0.5f; | |
309 } | |
310 | |
311 GrGLvoid getQueryiv(GrGLenum GLtarget, GrGLenum pname, GrGLint *params) over ride { | |
312 switch (pname) { | |
313 case GR_GL_CURRENT_QUERY: | |
314 *params = 0; | |
315 break; | |
316 case GR_GL_QUERY_COUNTER_BITS: | |
317 *params = 32; | |
318 break; | |
319 default: | |
320 SkFAIL("Unexpected pname passed GetQueryiv."); | |
321 } | |
322 } | |
323 | |
324 GrGLvoid getQueryObjecti64v(GrGLuint id, GrGLenum pname, GrGLint64 *params) override { | |
325 queryResult(id, pname, params); | |
326 } | |
327 | |
328 GrGLvoid getQueryObjectiv(GrGLuint id, GrGLenum pname, GrGLint *params) over ride { | |
329 queryResult(id, pname, params); | |
330 } | |
331 | |
332 GrGLvoid getQueryObjectui64v(GrGLuint id, GrGLenum pname, GrGLuint64 *params ) override { | |
333 queryResult(id, pname, params); | |
334 } | |
335 | |
336 GrGLvoid getQueryObjectuiv(GrGLuint id, GrGLenum pname, GrGLuint *params) { | |
337 queryResult(id, pname, params); | |
338 } | |
339 | |
340 GrGLvoid getShaderiv(GrGLuint shader, GrGLenum pname, GrGLint* params) overr ide { | |
341 this->getShaderOrProgramiv(shader, pname, params); | |
342 } | |
343 | |
344 GrGLvoid getShaderInfoLog(GrGLuint shader, GrGLsizei bufsize, GrGLsizei* len gth, | |
345 char* infolog) { | |
346 this->getInfoLog(shader, bufsize, length, infolog); | |
347 } | |
348 | |
349 const GrGLubyte* getString(GrGLenum name) override { | |
350 switch (name) { | |
351 case GR_GL_EXTENSIONS: | |
352 return CombinedExtensionString(); | |
353 case GR_GL_VERSION: | |
354 return (const GrGLubyte*)"4.0 Debug GL"; | |
355 case GR_GL_SHADING_LANGUAGE_VERSION: | |
356 return (const GrGLubyte*)"4.20.8 Debug GLSL"; | |
357 case GR_GL_VENDOR: | |
358 return (const GrGLubyte*)"Debug Vendor"; | |
359 case GR_GL_RENDERER: | |
360 return (const GrGLubyte*)"The Debug (Non-)Renderer"; | |
361 default: | |
362 SkFAIL("Unexpected name passed to GetString"); | |
363 return nullptr; | |
364 } | |
365 } | |
366 | |
367 const GrGLubyte* getStringi(GrGLenum name, GrGLuint i) override { | |
368 switch (name) { | |
369 case GR_GL_EXTENSIONS: { | |
370 GrGLint count; | |
371 this->getIntegerv(GR_GL_NUM_EXTENSIONS, &count); | |
372 if ((GrGLint)i <= count) { | |
373 return (const GrGLubyte*) kExtensions[i]; | |
374 } else { | |
375 return nullptr; | |
376 } | |
377 } | |
378 default: | |
379 SkFAIL("Unexpected name passed to GetStringi"); | |
380 return nullptr; | |
381 } | |
382 } | |
383 | |
384 GrGLvoid getTexLevelParameteriv(GrGLenum target, GrGLint level, GrGLenum pna me, | |
385 GrGLint* params) override { | |
386 // we used to use this to query stuff about externally created textures, | |
387 // now we just require clients to tell us everything about the texture. | |
388 SkFAIL("Should never query texture parameters."); | |
389 } | |
390 | |
391 GrGLint getUniformLocation(GrGLuint program, const char* name) override { | |
392 return ++fCurrUniformLocation; | |
393 } | |
394 | |
395 GrGLvoid* mapBufferRange(GrGLenum target, GrGLintptr offset, GrGLsizeiptr le ngth, | |
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* para ms) 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 | |
510 private: | |
127 BufferManager fBufferManager; | 511 BufferManager fBufferManager; |
128 GrGLuint fCurrArrayBuffer; | 512 GrGLuint fCurrArrayBuffer; |
129 GrGLuint fCurrElementArrayBuffer; | 513 GrGLuint fCurrElementArrayBuffer; |
514 GrGLuint fCurrPixelPackBuffer; | |
515 GrGLuint fCurrPixelUnpackBuffer; | |
130 GrGLuint fCurrProgramID; | 516 GrGLuint fCurrProgramID; |
131 GrGLuint fCurrShaderID; | 517 GrGLuint fCurrShaderID; |
132 | 518 GrGLuint fCurrGenericID; |
133 static ThreadContext* Get() { | 519 GrGLuint fCurrUniformLocation; |
134 return reinterpret_cast<ThreadContext*>(SkTLS::Get(Create, Delete)); | 520 |
135 } | 521 // the OpenGLES 2.0 spec says this must be >= 128 |
136 | 522 static const GrGLint kDefaultMaxVertexUniformVectors = 128; |
137 ThreadContext() | 523 |
138 : fCurrArrayBuffer(0) | 524 // the OpenGLES 2.0 spec says this must be >=16 |
139 , fCurrElementArrayBuffer(0) | 525 static const GrGLint kDefaultMaxFragmentUniformVectors = 16; |
140 , fCurrProgramID(0) | 526 |
141 , fCurrShaderID(0) {} | 527 // the OpenGLES 2.0 spec says this must be >= 8 |
142 | 528 static const GrGLint kDefaultMaxVertexAttribs = 8; |
143 private: | 529 |
144 static void* Create() { return new ThreadContext; } | 530 // the OpenGLES 2.0 spec says this must be >= 8 |
145 static void Delete(void* context) { delete reinterpret_cast<ThreadContext*>( context); } | 531 static const GrGLint kDefaultMaxVaryingVectors = 8; |
532 | |
533 static const char* kExtensions[]; | |
534 | |
535 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(" "); | |
544 } | |
545 gExtString.append(kExtensions[i]); | |
546 ++i; | |
547 } | |
548 } | |
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* par ams) { | |
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 } | |
598 } | |
146 }; | 599 }; |
147 | 600 |
148 // Functions not declared in GrGLBogusInterface.h (not common with the Debug GL interface). | 601 const char* NullInterface::kExtensions[] = { |
149 | 602 "GL_ARB_framebuffer_object", |
150 GrGLvoid GR_GL_FUNCTION_TYPE nullGLActiveTexture(GrGLenum texture) {} | 603 "GL_ARB_blend_func_extended", |
151 GrGLvoid GR_GL_FUNCTION_TYPE nullGLAttachShader(GrGLuint program, GrGLuint shade r) {} | 604 "GL_ARB_timer_query", |
152 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBeginQuery(GrGLenum target, GrGLuint id) {} | 605 "GL_ARB_draw_buffers", |
153 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindAttribLocation(GrGLuint program, GrGLuint index, const char* name) {} | 606 "GL_ARB_occlusion_query", |
154 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindTexture(GrGLenum target, GrGLuint texture ) {} | 607 "GL_EXT_stencil_wrap", |
155 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindVertexArray(GrGLuint id) {} | 608 nullptr, // signifies the end of the array. |
156 | |
157 GrGLvoid GR_GL_FUNCTION_TYPE nullGLGenBuffers(GrGLsizei n, GrGLuint* ids) { | |
158 ThreadContext* ctx = ThreadContext::Get(); | |
159 for (int i = 0; i < n; ++i) { | |
160 BufferObj* buffer = ctx->fBufferManager.create(); | |
161 ids[i] = buffer->id(); | |
162 } | |
163 } | |
164 | |
165 GrGLvoid GR_GL_FUNCTION_TYPE nullGLGenerateMipmap(GrGLenum target) {} | |
166 | |
167 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBufferData(GrGLenum target, | |
168 GrGLsizeiptr size, | |
169 const GrGLvoid* data, | |
170 GrGLenum usage) { | |
171 ThreadContext* ctx = ThreadContext::Get(); | |
172 GrGLuint id = 0; | |
173 | |
174 switch (target) { | |
175 case GR_GL_ARRAY_BUFFER: | |
176 id = ctx->fCurrArrayBuffer; | |
177 break; | |
178 case GR_GL_ELEMENT_ARRAY_BUFFER: | |
179 id = ctx->fCurrElementArrayBuffer; | |
180 break; | |
181 default: | |
182 SkFAIL("Unexpected target to nullGLBufferData"); | |
183 break; | |
184 } | |
185 | |
186 if (id > 0) { | |
187 BufferObj* buffer = ctx->fBufferManager.lookUp(id); | |
188 buffer->allocate(size, (const GrGLchar*) data); | |
189 } | |
190 } | |
191 | |
192 GrGLvoid GR_GL_FUNCTION_TYPE nullGLPixelStorei(GrGLenum pname, GrGLint param) {} | |
193 GrGLvoid GR_GL_FUNCTION_TYPE nullGLReadPixels(GrGLint x, GrGLint y, GrGLsizei wi dth, GrGLsizei height, GrGLenum format, GrGLenum type, GrGLvoid* pixels) {} | |
194 GrGLvoid GR_GL_FUNCTION_TYPE nullGLUseProgram(GrGLuint program) {} | |
195 GrGLvoid GR_GL_FUNCTION_TYPE nullGLViewport(GrGLint x, GrGLint y, GrGLsizei widt h, GrGLsizei height) {} | |
196 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindFramebuffer(GrGLenum target, GrGLuint fra mebuffer) {} | |
197 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindRenderbuffer(GrGLenum target, GrGLuint re nderbuffer) {} | |
198 GrGLvoid GR_GL_FUNCTION_TYPE nullGLDeleteFramebuffers(GrGLsizei n, const GrGLuin t *framebuffers) {} | |
199 GrGLvoid GR_GL_FUNCTION_TYPE nullGLDeleteRenderbuffers(GrGLsizei n, const GrGLui nt *renderbuffers) {} | |
200 GrGLvoid GR_GL_FUNCTION_TYPE nullGLFramebufferRenderbuffer(GrGLenum target, GrGL enum attachment, GrGLenum renderbuffertarget, GrGLuint renderbuffer) {} | |
201 GrGLvoid GR_GL_FUNCTION_TYPE nullGLFramebufferTexture2D(GrGLenum target, GrGLenu m attachment, GrGLenum textarget, GrGLuint texture, GrGLint level) {} | |
202 | |
203 GrGLuint GR_GL_FUNCTION_TYPE nullGLCreateProgram() { | |
204 return ++ThreadContext::Get()->fCurrProgramID; | |
205 } | |
206 | |
207 GrGLuint GR_GL_FUNCTION_TYPE nullGLCreateShader(GrGLenum type) { | |
208 return ++ThreadContext::Get()->fCurrShaderID; | |
209 } | |
210 | |
211 // same delete used for shaders and programs | |
212 GrGLvoid GR_GL_FUNCTION_TYPE nullGLDelete(GrGLuint program) { | |
213 } | |
214 | |
215 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindBuffer(GrGLenum target, GrGLuint buffer) { | |
216 ThreadContext* ctx = ThreadContext::Get(); | |
217 switch (target) { | |
218 case GR_GL_ARRAY_BUFFER: | |
219 ctx->fCurrArrayBuffer = buffer; | |
220 break; | |
221 case GR_GL_ELEMENT_ARRAY_BUFFER: | |
222 ctx->fCurrElementArrayBuffer = buffer; | |
223 break; | |
224 } | |
225 } | |
226 | |
227 // deleting a bound buffer has the side effect of binding 0 | |
228 GrGLvoid GR_GL_FUNCTION_TYPE nullGLDeleteBuffers(GrGLsizei n, const GrGLuint* id s) { | |
229 ThreadContext* ctx = ThreadContext::Get(); | |
230 for (int i = 0; i < n; ++i) { | |
231 if (ids[i] == ctx->fCurrArrayBuffer) { | |
232 ctx->fCurrArrayBuffer = 0; | |
233 } | |
234 if (ids[i] == ctx->fCurrElementArrayBuffer) { | |
235 ctx->fCurrElementArrayBuffer = 0; | |
236 } | |
237 | |
238 BufferObj* buffer = ctx->fBufferManager.lookUp(ids[i]); | |
239 ctx->fBufferManager.free(buffer); | |
240 } | |
241 } | |
242 | |
243 GrGLvoid* GR_GL_FUNCTION_TYPE nullGLMapBufferRange(GrGLenum target, GrGLintptr o ffset, | |
244 GrGLsizeiptr length, GrGLbitf ield access) { | |
245 ThreadContext* ctx = ThreadContext::Get(); | |
246 GrGLuint id = 0; | |
247 switch (target) { | |
248 case GR_GL_ARRAY_BUFFER: | |
249 id = ctx->fCurrArrayBuffer; | |
250 break; | |
251 case GR_GL_ELEMENT_ARRAY_BUFFER: | |
252 id = ctx->fCurrElementArrayBuffer; | |
253 break; | |
254 } | |
255 | |
256 if (id > 0) { | |
257 // We just ignore the offset and length here. | |
258 BufferObj* buffer = ctx->fBufferManager.lookUp(id); | |
259 SkASSERT(!buffer->mapped()); | |
260 buffer->setMapped(true); | |
261 return buffer->dataPtr(); | |
262 } | |
263 return nullptr; | |
264 } | |
265 | |
266 GrGLvoid* GR_GL_FUNCTION_TYPE nullGLMapBuffer(GrGLenum target, GrGLenum access) { | |
267 ThreadContext* ctx = ThreadContext::Get(); | |
268 GrGLuint id = 0; | |
269 switch (target) { | |
270 case GR_GL_ARRAY_BUFFER: | |
271 id = ctx->fCurrArrayBuffer; | |
272 break; | |
273 case GR_GL_ELEMENT_ARRAY_BUFFER: | |
274 id = ctx->fCurrElementArrayBuffer; | |
275 break; | |
276 } | |
277 | |
278 if (id > 0) { | |
279 BufferObj* buffer = ctx->fBufferManager.lookUp(id); | |
280 SkASSERT(!buffer->mapped()); | |
281 buffer->setMapped(true); | |
282 return buffer->dataPtr(); | |
283 } | |
284 | |
285 SkASSERT(false); | |
286 return nullptr; // no buffer bound to target | |
287 } | |
288 | |
289 GrGLvoid GR_GL_FUNCTION_TYPE nullGLFlushMappedBufferRange(GrGLenum target, | |
290 GrGLintptr offset, | |
291 GrGLsizeiptr length) { } | |
292 | |
293 | |
294 GrGLboolean GR_GL_FUNCTION_TYPE nullGLUnmapBuffer(GrGLenum target) { | |
295 ThreadContext* ctx = ThreadContext::Get(); | |
296 GrGLuint id = 0; | |
297 switch (target) { | |
298 case GR_GL_ARRAY_BUFFER: | |
299 id = ctx->fCurrArrayBuffer; | |
300 break; | |
301 case GR_GL_ELEMENT_ARRAY_BUFFER: | |
302 id = ctx->fCurrElementArrayBuffer; | |
303 break; | |
304 } | |
305 if (id > 0) { | |
306 BufferObj* buffer = ctx->fBufferManager.lookUp(id); | |
307 SkASSERT(buffer->mapped()); | |
308 buffer->setMapped(false); | |
309 return GR_GL_TRUE; | |
310 } | |
311 | |
312 GrAlwaysAssert(false); | |
313 return GR_GL_FALSE; // GR_GL_INVALID_OPERATION; | |
314 } | |
315 | |
316 GrGLvoid GR_GL_FUNCTION_TYPE nullGLGetBufferParameteriv(GrGLenum target, GrGLenu m pname, GrGLint* params) { | |
317 ThreadContext* ctx = ThreadContext::Get(); | |
318 switch (pname) { | |
319 case GR_GL_BUFFER_MAPPED: { | |
320 *params = GR_GL_FALSE; | |
321 GrGLuint id = 0; | |
322 switch (target) { | |
323 case GR_GL_ARRAY_BUFFER: | |
324 id = ctx->fCurrArrayBuffer; | |
325 break; | |
326 case GR_GL_ELEMENT_ARRAY_BUFFER: | |
327 id = ctx->fCurrElementArrayBuffer; | |
328 break; | |
329 } | |
330 if (id > 0) { | |
331 BufferObj* buffer = ctx->fBufferManager.lookUp(id); | |
332 if (buffer->mapped()) { | |
333 *params = GR_GL_TRUE; | |
334 } | |
335 } | |
336 break; } | |
337 default: | |
338 SkFAIL("Unexpected pname to GetBufferParamateriv"); | |
339 break; | |
340 } | |
341 }; | 609 }; |
342 | 610 |
343 } // end anonymous namespace | 611 } // anonymous namespace |
344 | 612 |
345 const GrGLInterface* GrGLCreateNullInterface() { | 613 const GrGLInterface* GrGLCreateNullInterface() { return new NullInterface; } |
346 GrGLInterface* interface = new GrGLInterface; | |
347 | |
348 interface->fStandard = kGL_GrGLStandard; | |
349 | |
350 GrGLInterface::Functions* functions = &interface->fFunctions; | |
351 functions->fActiveTexture = nullGLActiveTexture; | |
352 functions->fAttachShader = nullGLAttachShader; | |
353 functions->fBeginQuery = nullGLBeginQuery; | |
354 functions->fBindAttribLocation = nullGLBindAttribLocation; | |
355 functions->fBindBuffer = nullGLBindBuffer; | |
356 functions->fBindFragDataLocation = noOpGLBindFragDataLocation; | |
357 functions->fBindTexture = nullGLBindTexture; | |
358 functions->fBindVertexArray = nullGLBindVertexArray; | |
359 functions->fBlendColor = noOpGLBlendColor; | |
360 functions->fBlendEquation = noOpGLBlendEquation; | |
361 functions->fBlendFunc = noOpGLBlendFunc; | |
362 functions->fBufferData = nullGLBufferData; | |
363 functions->fBufferSubData = noOpGLBufferSubData; | |
364 functions->fClear = noOpGLClear; | |
365 functions->fClearColor = noOpGLClearColor; | |
366 functions->fClearStencil = noOpGLClearStencil; | |
367 functions->fColorMask = noOpGLColorMask; | |
368 functions->fCompileShader = noOpGLCompileShader; | |
369 functions->fCompressedTexImage2D = noOpGLCompressedTexImage2D; | |
370 functions->fCompressedTexSubImage2D = noOpGLCompressedTexSubImage2D; | |
371 functions->fCopyTexSubImage2D = noOpGLCopyTexSubImage2D; | |
372 functions->fCreateProgram = nullGLCreateProgram; | |
373 functions->fCreateShader = nullGLCreateShader; | |
374 functions->fCullFace = noOpGLCullFace; | |
375 functions->fDeleteBuffers = nullGLDeleteBuffers; | |
376 functions->fDeleteProgram = nullGLDelete; | |
377 functions->fDeleteQueries = noOpGLDeleteIds; | |
378 functions->fDeleteShader = nullGLDelete; | |
379 functions->fDeleteTextures = noOpGLDeleteIds; | |
380 functions->fDeleteVertexArrays = noOpGLDeleteIds; | |
381 functions->fDepthMask = noOpGLDepthMask; | |
382 functions->fDisable = noOpGLDisable; | |
383 functions->fDisableVertexAttribArray = noOpGLDisableVertexAttribArray; | |
384 functions->fDrawArrays = noOpGLDrawArrays; | |
385 functions->fDrawArraysInstanced = noOpGLDrawArraysInstanced; | |
386 functions->fDrawBuffer = noOpGLDrawBuffer; | |
387 functions->fDrawBuffers = noOpGLDrawBuffers; | |
388 functions->fDrawElements = noOpGLDrawElements; | |
389 functions->fDrawElementsInstanced = noOpGLDrawElementsInstanced; | |
390 functions->fEnable = noOpGLEnable; | |
391 functions->fEnableVertexAttribArray = noOpGLEnableVertexAttribArray; | |
392 functions->fEndQuery = noOpGLEndQuery; | |
393 functions->fFinish = noOpGLFinish; | |
394 functions->fFlush = noOpGLFlush; | |
395 functions->fFlushMappedBufferRange = nullGLFlushMappedBufferRange; | |
396 functions->fFrontFace = noOpGLFrontFace; | |
397 functions->fGenBuffers = nullGLGenBuffers; | |
398 functions->fGenerateMipmap = nullGLGenerateMipmap; | |
399 functions->fGenQueries = noOpGLGenIds; | |
400 functions->fGenTextures = noOpGLGenIds; | |
401 functions->fGenVertexArrays = noOpGLGenIds; | |
402 functions->fGetBufferParameteriv = nullGLGetBufferParameteriv; | |
403 functions->fGetError = noOpGLGetError; | |
404 functions->fGetIntegerv = noOpGLGetIntegerv; | |
405 functions->fGetMultisamplefv = noOpGLGetMultisamplefv; | |
406 functions->fGetQueryObjecti64v = noOpGLGetQueryObjecti64v; | |
407 functions->fGetQueryObjectiv = noOpGLGetQueryObjectiv; | |
408 functions->fGetQueryObjectui64v = noOpGLGetQueryObjectui64v; | |
409 functions->fGetQueryObjectuiv = noOpGLGetQueryObjectuiv; | |
410 functions->fGetQueryiv = noOpGLGetQueryiv; | |
411 functions->fGetProgramInfoLog = noOpGLGetInfoLog; | |
412 functions->fGetProgramiv = noOpGLGetShaderOrProgramiv; | |
413 functions->fGetShaderInfoLog = noOpGLGetInfoLog; | |
414 functions->fGetShaderiv = noOpGLGetShaderOrProgramiv; | |
415 functions->fGetString = noOpGLGetString; | |
416 functions->fGetStringi = noOpGLGetStringi; | |
417 functions->fGetTexLevelParameteriv = noOpGLGetTexLevelParameteriv; | |
418 functions->fGetUniformLocation = noOpGLGetUniformLocation; | |
419 functions->fInsertEventMarker = noOpGLInsertEventMarker; | |
420 functions->fLineWidth = noOpGLLineWidth; | |
421 functions->fLinkProgram = noOpGLLinkProgram; | |
422 functions->fMapBuffer = nullGLMapBuffer; | |
423 functions->fMapBufferRange = nullGLMapBufferRange; | |
424 functions->fPixelStorei = nullGLPixelStorei; | |
425 functions->fPopGroupMarker = noOpGLPopGroupMarker; | |
426 functions->fPushGroupMarker = noOpGLPushGroupMarker; | |
427 functions->fQueryCounter = noOpGLQueryCounter; | |
428 functions->fReadBuffer = noOpGLReadBuffer; | |
429 functions->fReadPixels = nullGLReadPixels; | |
430 functions->fScissor = noOpGLScissor; | |
431 functions->fShaderSource = noOpGLShaderSource; | |
432 functions->fStencilFunc = noOpGLStencilFunc; | |
433 functions->fStencilFuncSeparate = noOpGLStencilFuncSeparate; | |
434 functions->fStencilMask = noOpGLStencilMask; | |
435 functions->fStencilMaskSeparate = noOpGLStencilMaskSeparate; | |
436 functions->fStencilOp = noOpGLStencilOp; | |
437 functions->fStencilOpSeparate = noOpGLStencilOpSeparate; | |
438 functions->fTexBuffer = noOpGLTexBuffer; | |
439 functions->fTexImage2D = noOpGLTexImage2D; | |
440 functions->fTexParameteri = noOpGLTexParameteri; | |
441 functions->fTexParameteriv = noOpGLTexParameteriv; | |
442 functions->fTexSubImage2D = noOpGLTexSubImage2D; | |
443 functions->fTexStorage2D = noOpGLTexStorage2D; | |
444 functions->fDiscardFramebuffer = noOpGLDiscardFramebuffer; | |
445 functions->fUniform1f = noOpGLUniform1f; | |
446 functions->fUniform1i = noOpGLUniform1i; | |
447 functions->fUniform1fv = noOpGLUniform1fv; | |
448 functions->fUniform1iv = noOpGLUniform1iv; | |
449 functions->fUniform2f = noOpGLUniform2f; | |
450 functions->fUniform2i = noOpGLUniform2i; | |
451 functions->fUniform2fv = noOpGLUniform2fv; | |
452 functions->fUniform2iv = noOpGLUniform2iv; | |
453 functions->fUniform3f = noOpGLUniform3f; | |
454 functions->fUniform3i = noOpGLUniform3i; | |
455 functions->fUniform3fv = noOpGLUniform3fv; | |
456 functions->fUniform3iv = noOpGLUniform3iv; | |
457 functions->fUniform4f = noOpGLUniform4f; | |
458 functions->fUniform4i = noOpGLUniform4i; | |
459 functions->fUniform4fv = noOpGLUniform4fv; | |
460 functions->fUniform4iv = noOpGLUniform4iv; | |
461 functions->fUniformMatrix2fv = noOpGLUniformMatrix2fv; | |
462 functions->fUniformMatrix3fv = noOpGLUniformMatrix3fv; | |
463 functions->fUniformMatrix4fv = noOpGLUniformMatrix4fv; | |
464 functions->fUnmapBuffer = nullGLUnmapBuffer; | |
465 functions->fUseProgram = nullGLUseProgram; | |
466 functions->fVertexAttrib1f = noOpGLVertexAttrib1f; | |
467 functions->fVertexAttrib2fv = noOpGLVertexAttrib2fv; | |
468 functions->fVertexAttrib3fv = noOpGLVertexAttrib3fv; | |
469 functions->fVertexAttrib4fv = noOpGLVertexAttrib4fv; | |
470 functions->fVertexAttribDivisor = noOpGLVertexAttribDivisor; | |
471 functions->fVertexAttribIPointer = noOpGLVertexAttribIPointer; | |
472 functions->fVertexAttribPointer = noOpGLVertexAttribPointer; | |
473 functions->fViewport = nullGLViewport; | |
474 functions->fBindFramebuffer = nullGLBindFramebuffer; | |
475 functions->fBindRenderbuffer = nullGLBindRenderbuffer; | |
476 functions->fCheckFramebufferStatus = noOpGLCheckFramebufferStatus; | |
477 functions->fDeleteFramebuffers = nullGLDeleteFramebuffers; | |
478 functions->fDeleteRenderbuffers = nullGLDeleteRenderbuffers; | |
479 functions->fFramebufferRenderbuffer = nullGLFramebufferRenderbuffer; | |
480 functions->fFramebufferTexture2D = nullGLFramebufferTexture2D; | |
481 functions->fGenFramebuffers = noOpGLGenIds; | |
482 functions->fGenRenderbuffers = noOpGLGenIds; | |
483 functions->fGetFramebufferAttachmentParameteriv = noOpGLGetFramebufferAttach mentParameteriv; | |
484 functions->fGetRenderbufferParameteriv = noOpGLGetRenderbufferParameteriv; | |
485 functions->fRenderbufferStorage = noOpGLRenderbufferStorage; | |
486 functions->fRenderbufferStorageMultisample = noOpGLRenderbufferStorageMultis ample; | |
487 functions->fBlitFramebuffer = noOpGLBlitFramebuffer; | |
488 functions->fResolveMultisampleFramebuffer = noOpGLResolveMultisampleFramebuf fer; | |
489 functions->fMatrixLoadf = noOpGLMatrixLoadf; | |
490 functions->fMatrixLoadIdentity = noOpGLMatrixLoadIdentity; | |
491 functions->fBindFragDataLocationIndexed = noOpGLBindFragDataLocationIndexed; | |
492 | |
493 interface->fExtensions.init(kGL_GrGLStandard, functions->fGetString, functio ns->fGetStringi, | |
494 functions->fGetIntegerv, nullptr, GR_EGL_NO_DISP LAY); | |
495 return interface; | |
496 } | |
OLD | NEW |