OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2011 Google Inc. | 3 * Copyright 2011 Google Inc. |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 #include "gl/SkNullGLContext.h" | 9 #include "gl/SkNullGLContext.h" |
10 #include "gl/GrGLInterface.h" | 10 #include "gl/GrGLInterface.h" |
11 #include "GrGLDefines.h" | |
12 #include "GrGLNoOpInterface.h" | |
13 #include "SkTDArray.h" | |
14 #include "SkTLS.h" | |
15 | |
16 static SkNullGLContext::ContextState* current_context(); | |
17 | |
18 ////////////////////////////////////////////////////////////////////////////////
///////////////// | |
19 | |
20 class BufferObj { | |
21 public: | |
22 | |
23 | |
24 BufferObj(GrGLuint id) : fID(id), fDataPtr(nullptr), fSize(0), fMapped(false
) {} | |
25 ~BufferObj() { delete[] fDataPtr; } | |
26 | |
27 void allocate(GrGLsizeiptr size, const GrGLchar* dataPtr) { | |
28 if (fDataPtr) { | |
29 SkASSERT(0 != fSize); | |
30 delete[] fDataPtr; | |
31 } | |
32 | |
33 fSize = size; | |
34 fDataPtr = new char[size]; | |
35 } | |
36 | |
37 GrGLuint id() const { return fID; } | |
38 GrGLchar* dataPtr() { return fDataPtr; } | |
39 GrGLsizeiptr size() const { return fSize; } | |
40 | |
41 void setMapped(bool mapped) { fMapped = mapped; } | |
42 bool mapped() const { return fMapped; } | |
43 | |
44 private: | |
45 GrGLuint fID; | |
46 GrGLchar* fDataPtr; | |
47 GrGLsizeiptr fSize; // size in bytes | |
48 bool fMapped; | |
49 }; | |
50 | |
51 // This class maintains a sparsely populated array of buffer pointers. | |
52 class BufferManager { | |
53 public: | |
54 | |
55 | |
56 BufferManager() : fFreeListHead(kFreeListEnd) {} | |
57 | |
58 ~BufferManager() { | |
59 // nullptr out the entries that are really free list links rather than p
trs before deleting. | |
60 intptr_t curr = fFreeListHead; | |
61 while (kFreeListEnd != curr) { | |
62 intptr_t next = reinterpret_cast<intptr_t>(fBuffers[SkToS32(curr)]); | |
63 fBuffers[SkToS32(curr)] = nullptr; | |
64 curr = next; | |
65 } | |
66 | |
67 fBuffers.deleteAll(); | |
68 } | |
69 | |
70 BufferObj* lookUp(GrGLuint id) { | |
71 BufferObj* buffer = fBuffers[id]; | |
72 SkASSERT(buffer && buffer->id() == id); | |
73 return buffer; | |
74 } | |
75 | |
76 BufferObj* create() { | |
77 GrGLuint id; | |
78 BufferObj* buffer; | |
79 | |
80 if (kFreeListEnd == fFreeListHead) { | |
81 // no free slots - create a new one | |
82 id = fBuffers.count(); | |
83 buffer = new BufferObj(id); | |
84 *fBuffers.append() = buffer; | |
85 } else { | |
86 // grab the head of the free list and advance the head to the next f
ree slot. | |
87 id = static_cast<GrGLuint>(fFreeListHead); | |
88 fFreeListHead = reinterpret_cast<intptr_t>(fBuffers[id]); | |
89 | |
90 buffer = new BufferObj(id); | |
91 fBuffers[id] = buffer; | |
92 } | |
93 | |
94 return buffer; | |
95 } | |
96 | |
97 void free(BufferObj* buffer) { | |
98 SkASSERT(fBuffers.count() > 0); | |
99 | |
100 GrGLuint id = buffer->id(); | |
101 delete buffer; | |
102 | |
103 fBuffers[id] = reinterpret_cast<BufferObj*>(fFreeListHead); | |
104 fFreeListHead = id; | |
105 } | |
106 | |
107 private: | |
108 static const intptr_t kFreeListEnd = -1; | |
109 // Index of the first entry of fBuffers in the free list. Free slots in fBuf
fers are indices to | |
110 // the next free slot. The last free slot has a value of kFreeListEnd. | |
111 intptr_t fFreeListHead; | |
112 SkTDArray<BufferObj*> fBuffers; | |
113 }; | |
114 | |
115 /** | |
116 * The state object for the null interface. | |
117 */ | |
118 class SkNullGLContext::ContextState : public SkRefCnt { | |
119 public: | |
120 | |
121 | |
122 BufferManager fBufferManager; | |
123 GrGLuint fCurrArrayBuffer; | |
124 GrGLuint fCurrElementArrayBuffer; | |
125 GrGLuint fCurrPixelPackBuffer; | |
126 GrGLuint fCurrPixelUnpackBuffer; | |
127 GrGLuint fCurrProgramID; | |
128 GrGLuint fCurrShaderID; | |
129 | |
130 | |
131 ContextState() | |
132 : fCurrArrayBuffer(0) | |
133 , fCurrElementArrayBuffer(0) | |
134 , fCurrPixelPackBuffer(0) | |
135 , fCurrPixelUnpackBuffer(0) | |
136 , fCurrProgramID(0) | |
137 , fCurrShaderID(0) {} | |
138 | |
139 static ContextState* Get() { return current_context(); } | |
140 }; | |
141 | |
142 typedef SkNullGLContext::ContextState State; | |
143 | |
144 // Functions not declared in GrGLBogusInterface.h (not common with the Debug GL
interface). | |
145 | |
146 namespace { // added to suppress 'no previous prototype' warning | |
147 | |
148 GrGLvoid GR_GL_FUNCTION_TYPE nullGLActiveTexture(GrGLenum texture) {} | |
149 GrGLvoid GR_GL_FUNCTION_TYPE nullGLAttachShader(GrGLuint program, GrGLuint shade
r) {} | |
150 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBeginQuery(GrGLenum target, GrGLuint id) {} | |
151 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindAttribLocation(GrGLuint program, GrGLuint
index, const char* name) {} | |
152 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindTexture(GrGLenum target, GrGLuint texture
) {} | |
153 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindVertexArray(GrGLuint id) {} | |
154 | |
155 GrGLvoid GR_GL_FUNCTION_TYPE nullGLGenBuffers(GrGLsizei n, GrGLuint* ids) { | |
156 State* state = State::Get(); | |
157 for (int i = 0; i < n; ++i) { | |
158 BufferObj* buffer = state->fBufferManager.create(); | |
159 ids[i] = buffer->id(); | |
160 } | |
161 } | |
162 | |
163 GrGLvoid GR_GL_FUNCTION_TYPE nullGLGenerateMipmap(GrGLenum target) {} | |
164 | |
165 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBufferData(GrGLenum target, | |
166 GrGLsizeiptr size, | |
167 const GrGLvoid* data, | |
168 GrGLenum usage) { | |
169 State* state = State::Get(); | |
170 GrGLuint id = 0; | |
171 | |
172 switch (target) { | |
173 case GR_GL_ARRAY_BUFFER: | |
174 id = state->fCurrArrayBuffer; | |
175 break; | |
176 case GR_GL_ELEMENT_ARRAY_BUFFER: | |
177 id = state->fCurrElementArrayBuffer; | |
178 break; | |
179 case GR_GL_PIXEL_PACK_BUFFER: | |
180 id = state->fCurrPixelPackBuffer; | |
181 break; | |
182 case GR_GL_PIXEL_UNPACK_BUFFER: | |
183 id = state->fCurrPixelUnpackBuffer; | |
184 break; | |
185 default: | |
186 SkFAIL("Unexpected target to nullGLBufferData"); | |
187 break; | |
188 } | |
189 | |
190 if (id > 0) { | |
191 BufferObj* buffer = state->fBufferManager.lookUp(id); | |
192 buffer->allocate(size, (const GrGLchar*) data); | |
193 } | |
194 } | |
195 | |
196 GrGLvoid GR_GL_FUNCTION_TYPE nullGLPixelStorei(GrGLenum pname, GrGLint param) {} | |
197 GrGLvoid GR_GL_FUNCTION_TYPE nullGLReadPixels(GrGLint x, GrGLint y, GrGLsizei wi
dth, GrGLsizei height, GrGLenum format, GrGLenum type, GrGLvoid* pixels) {} | |
198 GrGLvoid GR_GL_FUNCTION_TYPE nullGLUseProgram(GrGLuint program) {} | |
199 GrGLvoid GR_GL_FUNCTION_TYPE nullGLViewport(GrGLint x, GrGLint y, GrGLsizei widt
h, GrGLsizei height) {} | |
200 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindFramebuffer(GrGLenum target, GrGLuint fra
mebuffer) {} | |
201 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindRenderbuffer(GrGLenum target, GrGLuint re
nderbuffer) {} | |
202 GrGLvoid GR_GL_FUNCTION_TYPE nullGLDeleteFramebuffers(GrGLsizei n, const GrGLuin
t *framebuffers) {} | |
203 GrGLvoid GR_GL_FUNCTION_TYPE nullGLDeleteRenderbuffers(GrGLsizei n, const GrGLui
nt *renderbuffers) {} | |
204 GrGLvoid GR_GL_FUNCTION_TYPE nullGLFramebufferRenderbuffer(GrGLenum target, GrGL
enum attachment, GrGLenum renderbuffertarget, GrGLuint renderbuffer) {} | |
205 GrGLvoid GR_GL_FUNCTION_TYPE nullGLFramebufferTexture2D(GrGLenum target, GrGLenu
m attachment, GrGLenum textarget, GrGLuint texture, GrGLint level) {} | |
206 | |
207 GrGLuint GR_GL_FUNCTION_TYPE nullGLCreateProgram() { | |
208 return ++State::Get()->fCurrProgramID; | |
209 } | |
210 | |
211 GrGLuint GR_GL_FUNCTION_TYPE nullGLCreateShader(GrGLenum type) { | |
212 return ++State::Get()->fCurrShaderID; | |
213 } | |
214 | |
215 // same delete used for shaders and programs | |
216 GrGLvoid GR_GL_FUNCTION_TYPE nullGLDelete(GrGLuint program) { | |
217 } | |
218 | |
219 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindBuffer(GrGLenum target, GrGLuint buffer)
{ | |
220 State* state = State::Get(); | |
221 switch (target) { | |
222 case GR_GL_ARRAY_BUFFER: | |
223 state->fCurrArrayBuffer = buffer; | |
224 break; | |
225 case GR_GL_ELEMENT_ARRAY_BUFFER: | |
226 state->fCurrElementArrayBuffer = buffer; | |
227 break; | |
228 case GR_GL_PIXEL_PACK_BUFFER: | |
229 state->fCurrPixelPackBuffer = buffer; | |
230 break; | |
231 case GR_GL_PIXEL_UNPACK_BUFFER: | |
232 state->fCurrPixelUnpackBuffer = buffer; | |
233 break; | |
234 } | |
235 } | |
236 | |
237 // deleting a bound buffer has the side effect of binding 0 | |
238 GrGLvoid GR_GL_FUNCTION_TYPE nullGLDeleteBuffers(GrGLsizei n, const GrGLuint* id
s) { | |
239 State* state = State::Get(); | |
240 for (int i = 0; i < n; ++i) { | |
241 if (ids[i] == state->fCurrArrayBuffer) { | |
242 state->fCurrArrayBuffer = 0; | |
243 } | |
244 if (ids[i] == state->fCurrElementArrayBuffer) { | |
245 state->fCurrElementArrayBuffer = 0; | |
246 } | |
247 if (ids[i] == state->fCurrPixelPackBuffer) { | |
248 state->fCurrPixelPackBuffer = 0; | |
249 } | |
250 if (ids[i] == state->fCurrPixelUnpackBuffer) { | |
251 state->fCurrPixelUnpackBuffer = 0; | |
252 } | |
253 | |
254 BufferObj* buffer = state->fBufferManager.lookUp(ids[i]); | |
255 state->fBufferManager.free(buffer); | |
256 } | |
257 } | |
258 | |
259 GrGLvoid* GR_GL_FUNCTION_TYPE nullGLMapBufferRange(GrGLenum target, GrGLintptr o
ffset, | |
260 GrGLsizeiptr length, GrGLbitf
ield access) { | |
261 State* state = State::Get(); | |
262 GrGLuint id = 0; | |
263 switch (target) { | |
264 case GR_GL_ARRAY_BUFFER: | |
265 id = state->fCurrArrayBuffer; | |
266 break; | |
267 case GR_GL_ELEMENT_ARRAY_BUFFER: | |
268 id = state->fCurrElementArrayBuffer; | |
269 break; | |
270 case GR_GL_PIXEL_PACK_BUFFER: | |
271 id = state->fCurrPixelPackBuffer; | |
272 break; | |
273 case GR_GL_PIXEL_UNPACK_BUFFER: | |
274 id = state->fCurrPixelUnpackBuffer; | |
275 break; | |
276 } | |
277 | |
278 if (id > 0) { | |
279 // We just ignore the offset and length here. | |
280 BufferObj* buffer = state->fBufferManager.lookUp(id); | |
281 SkASSERT(!buffer->mapped()); | |
282 buffer->setMapped(true); | |
283 return buffer->dataPtr(); | |
284 } | |
285 return nullptr; | |
286 } | |
287 | |
288 GrGLvoid* GR_GL_FUNCTION_TYPE nullGLMapBuffer(GrGLenum target, GrGLenum access)
{ | |
289 State* state = State::Get(); | |
290 GrGLuint id = 0; | |
291 switch (target) { | |
292 case GR_GL_ARRAY_BUFFER: | |
293 id = state->fCurrArrayBuffer; | |
294 break; | |
295 case GR_GL_ELEMENT_ARRAY_BUFFER: | |
296 id = state->fCurrElementArrayBuffer; | |
297 break; | |
298 case GR_GL_PIXEL_PACK_BUFFER: | |
299 id = state->fCurrPixelPackBuffer; | |
300 break; | |
301 case GR_GL_PIXEL_UNPACK_BUFFER: | |
302 id = state->fCurrPixelUnpackBuffer; | |
303 break; | |
304 } | |
305 | |
306 if (id > 0) { | |
307 BufferObj* buffer = state->fBufferManager.lookUp(id); | |
308 SkASSERT(!buffer->mapped()); | |
309 buffer->setMapped(true); | |
310 return buffer->dataPtr(); | |
311 } | |
312 | |
313 SkASSERT(false); | |
314 return nullptr; // no buffer bound to target | |
315 } | |
316 | |
317 GrGLvoid GR_GL_FUNCTION_TYPE nullGLFlushMappedBufferRange(GrGLenum target, | |
318 GrGLintptr offset, | |
319 GrGLsizeiptr length) {
} | |
320 | |
321 | |
322 GrGLboolean GR_GL_FUNCTION_TYPE nullGLUnmapBuffer(GrGLenum target) { | |
323 State* state = State::Get(); | |
324 GrGLuint id = 0; | |
325 switch (target) { | |
326 case GR_GL_ARRAY_BUFFER: | |
327 id = state->fCurrArrayBuffer; | |
328 break; | |
329 case GR_GL_ELEMENT_ARRAY_BUFFER: | |
330 id = state->fCurrElementArrayBuffer; | |
331 break; | |
332 case GR_GL_PIXEL_PACK_BUFFER: | |
333 id = state->fCurrPixelPackBuffer; | |
334 break; | |
335 case GR_GL_PIXEL_UNPACK_BUFFER: | |
336 id = state->fCurrPixelUnpackBuffer; | |
337 break; | |
338 } | |
339 if (id > 0) { | |
340 BufferObj* buffer = state->fBufferManager.lookUp(id); | |
341 SkASSERT(buffer->mapped()); | |
342 buffer->setMapped(false); | |
343 return GR_GL_TRUE; | |
344 } | |
345 | |
346 GrAlwaysAssert(false); | |
347 return GR_GL_FALSE; // GR_GL_INVALID_OPERATION; | |
348 } | |
349 | |
350 GrGLvoid GR_GL_FUNCTION_TYPE nullGLGetBufferParameteriv(GrGLenum target, GrGLenu
m pname, GrGLint* params) { | |
351 State* state = State::Get(); | |
352 switch (pname) { | |
353 case GR_GL_BUFFER_MAPPED: { | |
354 *params = GR_GL_FALSE; | |
355 GrGLuint id = 0; | |
356 switch (target) { | |
357 case GR_GL_ARRAY_BUFFER: | |
358 id = state->fCurrArrayBuffer; | |
359 break; | |
360 case GR_GL_ELEMENT_ARRAY_BUFFER: | |
361 id = state->fCurrElementArrayBuffer; | |
362 break; | |
363 case GR_GL_PIXEL_PACK_BUFFER: | |
364 id = state->fCurrPixelPackBuffer; | |
365 break; | |
366 case GR_GL_PIXEL_UNPACK_BUFFER: | |
367 id = state->fCurrPixelUnpackBuffer; | |
368 break; | |
369 } | |
370 if (id > 0) { | |
371 BufferObj* buffer = state->fBufferManager.lookUp(id); | |
372 if (buffer->mapped()) { | |
373 *params = GR_GL_TRUE; | |
374 } | |
375 } | |
376 break; } | |
377 default: | |
378 SkFAIL("Unexpected pname to GetBufferParamateriv"); | |
379 break; | |
380 } | |
381 }; | |
382 | |
383 class NullInterface : public GrGLInterface { | |
384 public: | |
385 NullInterface(State* state) : fState(SkRef(state)) {} | |
386 ~NullInterface() override { | |
387 fState->unref(); | |
388 } | |
389 State* fState; | |
390 }; | |
391 | |
392 } // end anonymous namespace | |
393 | |
394 static GrGLInterface* create_null_interface(State* state) { | |
395 GrGLInterface* interface = new NullInterface(state); | |
396 | |
397 interface->fStandard = kGL_GrGLStandard; | |
398 | |
399 GrGLInterface::Functions* functions = &interface->fFunctions; | |
400 functions->fActiveTexture = nullGLActiveTexture; | |
401 functions->fAttachShader = nullGLAttachShader; | |
402 functions->fBeginQuery = nullGLBeginQuery; | |
403 functions->fBindAttribLocation = nullGLBindAttribLocation; | |
404 functions->fBindBuffer = nullGLBindBuffer; | |
405 functions->fBindFragDataLocation = noOpGLBindFragDataLocation; | |
406 functions->fBindTexture = nullGLBindTexture; | |
407 functions->fBindVertexArray = nullGLBindVertexArray; | |
408 functions->fBlendColor = noOpGLBlendColor; | |
409 functions->fBlendEquation = noOpGLBlendEquation; | |
410 functions->fBlendFunc = noOpGLBlendFunc; | |
411 functions->fBufferData = nullGLBufferData; | |
412 functions->fBufferSubData = noOpGLBufferSubData; | |
413 functions->fClear = noOpGLClear; | |
414 functions->fClearColor = noOpGLClearColor; | |
415 functions->fClearStencil = noOpGLClearStencil; | |
416 functions->fColorMask = noOpGLColorMask; | |
417 functions->fCompileShader = noOpGLCompileShader; | |
418 functions->fCompressedTexImage2D = noOpGLCompressedTexImage2D; | |
419 functions->fCompressedTexSubImage2D = noOpGLCompressedTexSubImage2D; | |
420 functions->fCopyTexSubImage2D = noOpGLCopyTexSubImage2D; | |
421 functions->fCreateProgram = nullGLCreateProgram; | |
422 functions->fCreateShader = nullGLCreateShader; | |
423 functions->fCullFace = noOpGLCullFace; | |
424 functions->fDeleteBuffers = nullGLDeleteBuffers; | |
425 functions->fDeleteProgram = nullGLDelete; | |
426 functions->fDeleteQueries = noOpGLDeleteIds; | |
427 functions->fDeleteShader = nullGLDelete; | |
428 functions->fDeleteTextures = noOpGLDeleteIds; | |
429 functions->fDeleteVertexArrays = noOpGLDeleteIds; | |
430 functions->fDepthMask = noOpGLDepthMask; | |
431 functions->fDisable = noOpGLDisable; | |
432 functions->fDisableVertexAttribArray = noOpGLDisableVertexAttribArray; | |
433 functions->fDrawArrays = noOpGLDrawArrays; | |
434 functions->fDrawArraysInstanced = noOpGLDrawArraysInstanced; | |
435 functions->fDrawBuffer = noOpGLDrawBuffer; | |
436 functions->fDrawBuffers = noOpGLDrawBuffers; | |
437 functions->fDrawElements = noOpGLDrawElements; | |
438 functions->fDrawElementsInstanced = noOpGLDrawElementsInstanced; | |
439 functions->fEnable = noOpGLEnable; | |
440 functions->fEnableVertexAttribArray = noOpGLEnableVertexAttribArray; | |
441 functions->fEndQuery = noOpGLEndQuery; | |
442 functions->fFinish = noOpGLFinish; | |
443 functions->fFlush = noOpGLFlush; | |
444 functions->fFlushMappedBufferRange = nullGLFlushMappedBufferRange; | |
445 functions->fFrontFace = noOpGLFrontFace; | |
446 functions->fGenBuffers = nullGLGenBuffers; | |
447 functions->fGenerateMipmap = nullGLGenerateMipmap; | |
448 functions->fGenQueries = noOpGLGenIds; | |
449 functions->fGenTextures = noOpGLGenIds; | |
450 functions->fGenVertexArrays = noOpGLGenIds; | |
451 functions->fGetBufferParameteriv = nullGLGetBufferParameteriv; | |
452 functions->fGetError = noOpGLGetError; | |
453 functions->fGetIntegerv = noOpGLGetIntegerv; | |
454 functions->fGetMultisamplefv = noOpGLGetMultisamplefv; | |
455 functions->fGetQueryObjecti64v = noOpGLGetQueryObjecti64v; | |
456 functions->fGetQueryObjectiv = noOpGLGetQueryObjectiv; | |
457 functions->fGetQueryObjectui64v = noOpGLGetQueryObjectui64v; | |
458 functions->fGetQueryObjectuiv = noOpGLGetQueryObjectuiv; | |
459 functions->fGetQueryiv = noOpGLGetQueryiv; | |
460 functions->fGetProgramInfoLog = noOpGLGetInfoLog; | |
461 functions->fGetProgramiv = noOpGLGetShaderOrProgramiv; | |
462 functions->fGetShaderInfoLog = noOpGLGetInfoLog; | |
463 functions->fGetShaderiv = noOpGLGetShaderOrProgramiv; | |
464 functions->fGetString = noOpGLGetString; | |
465 functions->fGetStringi = noOpGLGetStringi; | |
466 functions->fGetTexLevelParameteriv = noOpGLGetTexLevelParameteriv; | |
467 functions->fGetUniformLocation = noOpGLGetUniformLocation; | |
468 functions->fInsertEventMarker = noOpGLInsertEventMarker; | |
469 functions->fLineWidth = noOpGLLineWidth; | |
470 functions->fLinkProgram = noOpGLLinkProgram; | |
471 functions->fMapBuffer = nullGLMapBuffer; | |
472 functions->fMapBufferRange = nullGLMapBufferRange; | |
473 functions->fPixelStorei = nullGLPixelStorei; | |
474 functions->fPopGroupMarker = noOpGLPopGroupMarker; | |
475 functions->fPushGroupMarker = noOpGLPushGroupMarker; | |
476 functions->fQueryCounter = noOpGLQueryCounter; | |
477 functions->fReadBuffer = noOpGLReadBuffer; | |
478 functions->fReadPixels = nullGLReadPixels; | |
479 functions->fScissor = noOpGLScissor; | |
480 functions->fShaderSource = noOpGLShaderSource; | |
481 functions->fStencilFunc = noOpGLStencilFunc; | |
482 functions->fStencilFuncSeparate = noOpGLStencilFuncSeparate; | |
483 functions->fStencilMask = noOpGLStencilMask; | |
484 functions->fStencilMaskSeparate = noOpGLStencilMaskSeparate; | |
485 functions->fStencilOp = noOpGLStencilOp; | |
486 functions->fStencilOpSeparate = noOpGLStencilOpSeparate; | |
487 functions->fTexBuffer = noOpGLTexBuffer; | |
488 functions->fTexImage2D = noOpGLTexImage2D; | |
489 functions->fTexParameteri = noOpGLTexParameteri; | |
490 functions->fTexParameteriv = noOpGLTexParameteriv; | |
491 functions->fTexSubImage2D = noOpGLTexSubImage2D; | |
492 functions->fTexStorage2D = noOpGLTexStorage2D; | |
493 functions->fDiscardFramebuffer = noOpGLDiscardFramebuffer; | |
494 functions->fUniform1f = noOpGLUniform1f; | |
495 functions->fUniform1i = noOpGLUniform1i; | |
496 functions->fUniform1fv = noOpGLUniform1fv; | |
497 functions->fUniform1iv = noOpGLUniform1iv; | |
498 functions->fUniform2f = noOpGLUniform2f; | |
499 functions->fUniform2i = noOpGLUniform2i; | |
500 functions->fUniform2fv = noOpGLUniform2fv; | |
501 functions->fUniform2iv = noOpGLUniform2iv; | |
502 functions->fUniform3f = noOpGLUniform3f; | |
503 functions->fUniform3i = noOpGLUniform3i; | |
504 functions->fUniform3fv = noOpGLUniform3fv; | |
505 functions->fUniform3iv = noOpGLUniform3iv; | |
506 functions->fUniform4f = noOpGLUniform4f; | |
507 functions->fUniform4i = noOpGLUniform4i; | |
508 functions->fUniform4fv = noOpGLUniform4fv; | |
509 functions->fUniform4iv = noOpGLUniform4iv; | |
510 functions->fUniformMatrix2fv = noOpGLUniformMatrix2fv; | |
511 functions->fUniformMatrix3fv = noOpGLUniformMatrix3fv; | |
512 functions->fUniformMatrix4fv = noOpGLUniformMatrix4fv; | |
513 functions->fUnmapBuffer = nullGLUnmapBuffer; | |
514 functions->fUseProgram = nullGLUseProgram; | |
515 functions->fVertexAttrib1f = noOpGLVertexAttrib1f; | |
516 functions->fVertexAttrib2fv = noOpGLVertexAttrib2fv; | |
517 functions->fVertexAttrib3fv = noOpGLVertexAttrib3fv; | |
518 functions->fVertexAttrib4fv = noOpGLVertexAttrib4fv; | |
519 functions->fVertexAttribDivisor = noOpGLVertexAttribDivisor; | |
520 functions->fVertexAttribIPointer = noOpGLVertexAttribIPointer; | |
521 functions->fVertexAttribPointer = noOpGLVertexAttribPointer; | |
522 functions->fViewport = nullGLViewport; | |
523 functions->fBindFramebuffer = nullGLBindFramebuffer; | |
524 functions->fBindRenderbuffer = nullGLBindRenderbuffer; | |
525 functions->fCheckFramebufferStatus = noOpGLCheckFramebufferStatus; | |
526 functions->fDeleteFramebuffers = nullGLDeleteFramebuffers; | |
527 functions->fDeleteRenderbuffers = nullGLDeleteRenderbuffers; | |
528 functions->fFramebufferRenderbuffer = nullGLFramebufferRenderbuffer; | |
529 functions->fFramebufferTexture2D = nullGLFramebufferTexture2D; | |
530 functions->fGenFramebuffers = noOpGLGenIds; | |
531 functions->fGenRenderbuffers = noOpGLGenIds; | |
532 functions->fGetFramebufferAttachmentParameteriv = noOpGLGetFramebufferAttach
mentParameteriv; | |
533 functions->fGetRenderbufferParameteriv = noOpGLGetRenderbufferParameteriv; | |
534 functions->fRenderbufferStorage = noOpGLRenderbufferStorage; | |
535 functions->fRenderbufferStorageMultisample = noOpGLRenderbufferStorageMultis
ample; | |
536 functions->fBlitFramebuffer = noOpGLBlitFramebuffer; | |
537 functions->fResolveMultisampleFramebuffer = noOpGLResolveMultisampleFramebuf
fer; | |
538 functions->fMatrixLoadf = noOpGLMatrixLoadf; | |
539 functions->fMatrixLoadIdentity = noOpGLMatrixLoadIdentity; | |
540 functions->fBindFragDataLocationIndexed = noOpGLBindFragDataLocationIndexed; | |
541 | |
542 interface->fExtensions.init(kGL_GrGLStandard, functions->fGetString, functio
ns->fGetStringi, | |
543 functions->fGetIntegerv, nullptr, GR_EGL_NO_DISP
LAY); | |
544 return interface; | |
545 } | |
546 | |
547 ////////////////////////////////////////////////////////////////////////////// | |
548 | |
549 static void* create_tls() { | |
550 State** current = new State*; | |
551 *current = nullptr; | |
552 return current; | |
553 } | |
554 | |
555 static void delete_tls(void* ctx) { | |
556 State** current = static_cast<State**>(ctx); | |
557 if (*current) { | |
558 (*current)->unref(); | |
559 } | |
560 delete current; | |
561 } | |
562 | |
563 static State* current_context() { | |
564 return *static_cast<State**>(SkTLS::Get(create_tls, delete_tls)); | |
565 } | |
566 | |
567 static void set_current_context(State* state) { | |
568 State** current = static_cast<State**>(SkTLS::Get(create_tls, delete_tls)); | |
569 if (*current) { | |
570 (*current)->unref(); | |
571 } | |
572 *current = state; | |
573 if (state) { | |
574 state->ref(); | |
575 } | |
576 } | |
577 | |
578 #if GR_GL_PER_GL_FUNC_CALLBACK | |
579 static void set_current_context_from_interface(const GrGLInterface* interface) { | |
580 set_current_context(reinterpret_cast<State*>(interface->fCallbackData)); | |
581 } | |
582 #endif | |
583 | 11 |
584 SkNullGLContext* SkNullGLContext::Create() { | 12 SkNullGLContext* SkNullGLContext::Create() { |
585 SkNullGLContext* ctx = new SkNullGLContext; | 13 SkNullGLContext* ctx = new SkNullGLContext; |
586 if (!ctx->isValid()) { | 14 if (!ctx->isValid()) { |
587 delete ctx; | 15 delete ctx; |
588 return nullptr; | 16 return nullptr; |
589 } | 17 } |
590 return ctx; | 18 return ctx; |
591 } | 19 } |
592 | 20 |
593 SkNullGLContext::SkNullGLContext() { | 21 SkNullGLContext::SkNullGLContext() { |
594 fState = new ContextState; | 22 this->init(GrGLCreateNullInterface()); |
595 GrGLInterface* interface = create_null_interface(fState); | |
596 this->init(interface); | |
597 #if GR_GL_PER_GL_FUNC_CALLBACK | |
598 interface->fCallback = set_current_context_from_interface; | |
599 interface->fCallbackData = reinterpret_cast<GrGLInterfaceCallbackData>(fStat
e); | |
600 #endif | |
601 } | 23 } |
602 | 24 |
603 SkNullGLContext::~SkNullGLContext() { | 25 SkNullGLContext::~SkNullGLContext() { |
604 this->teardown(); | 26 this->teardown(); |
605 fState->unref(); | |
606 } | 27 } |
607 | |
608 void SkNullGLContext::onPlatformMakeCurrent() const { set_current_context(fState
); } | |
OLD | NEW |