|
1 /* |
|
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 |
|
9 #include "gl/GrGLInterface.h" |
|
10 #include "GrGLDefines.h" |
|
11 #include "SkTDArray.h" |
|
12 #include "GrGLNoOpInterface.h" |
|
13 |
|
14 // Functions not declared in GrGLBogusInterface.h (not common with the Debug GL interface). |
|
15 |
|
16 namespace { // added to suppress 'no previous prototype' warning |
|
17 |
|
18 class GrBufferObj { |
|
19 public: |
|
20 GrBufferObj(GrGLuint id) : fID(id), fDataPtr(NULL), fSize(0), fMapped(false) { |
|
21 } |
|
22 ~GrBufferObj() { SkDELETE_ARRAY(fDataPtr); } |
|
23 |
|
24 void allocate(GrGLsizeiptr size, const GrGLchar* dataPtr) { |
|
25 if (NULL != fDataPtr) { |
|
26 SkASSERT(0 != fSize); |
|
27 SkDELETE_ARRAY(fDataPtr); |
|
28 } |
|
29 |
|
30 fSize = size; |
|
31 fDataPtr = SkNEW_ARRAY(char, size); |
|
32 } |
|
33 |
|
34 GrGLuint id() const { return fID; } |
|
35 GrGLchar* dataPtr() { return fDataPtr; } |
|
36 GrGLsizeiptr size() const { return fSize; } |
|
37 |
|
38 void setMapped(bool mapped) { fMapped = mapped; } |
|
39 bool mapped() const { return fMapped; } |
|
40 |
|
41 private: |
|
42 GrGLuint fID; |
|
43 GrGLchar* fDataPtr; |
|
44 GrGLsizeiptr fSize; // size in bytes |
|
45 bool fMapped; |
|
46 }; |
|
47 |
|
48 // In debug builds we do asserts that ensure we agree with GL about when a buffer |
|
49 // is mapped. |
|
50 static SkTDArray<GrBufferObj*> gBuffers; // slot 0 is reserved for head of free list |
|
51 static GrGLuint gCurrArrayBuffer; |
|
52 static GrGLuint gCurrElementArrayBuffer; |
|
53 |
|
54 static GrBufferObj* look_up(GrGLuint id) { |
|
55 GrBufferObj* buffer = gBuffers[id]; |
|
56 SkASSERT(NULL != buffer && buffer->id() == id); |
|
57 return buffer; |
|
58 } |
|
59 |
|
60 static GrBufferObj* create_buffer() { |
|
61 if (0 == gBuffers.count()) { |
|
62 // slot zero is reserved for the head of the free list |
|
63 *gBuffers.append() = NULL; |
|
64 } |
|
65 |
|
66 GrGLuint id; |
|
67 GrBufferObj* buffer; |
|
68 |
|
69 if (NULL == gBuffers[0]) { |
|
70 // no free slots - create a new one |
|
71 id = gBuffers.count(); |
|
72 buffer = SkNEW_ARGS(GrBufferObj, (id)); |
|
73 gBuffers.append(1, &buffer); |
|
74 } else { |
|
75 // recycle a slot from the free list |
|
76 id = SkTCast<GrGLuint>(gBuffers[0]); |
|
77 gBuffers[0] = gBuffers[id]; |
|
78 |
|
79 buffer = SkNEW_ARGS(GrBufferObj, (id)); |
|
80 gBuffers[id] = buffer; |
|
81 } |
|
82 |
|
83 return buffer; |
|
84 } |
|
85 |
|
86 static void delete_buffer(GrBufferObj* buffer) { |
|
87 SkASSERT(gBuffers.count() > 0); |
|
88 |
|
89 GrGLuint id = buffer->id(); |
|
90 SkDELETE(buffer); |
|
91 |
|
92 // Add this slot to the free list |
|
93 gBuffers[id] = gBuffers[0]; |
|
94 gBuffers[0] = SkTCast<GrBufferObj*>((const void*)(intptr_t)id); |
|
95 } |
|
96 |
|
97 GrGLvoid GR_GL_FUNCTION_TYPE nullGLActiveTexture(GrGLenum texture) {} |
|
98 GrGLvoid GR_GL_FUNCTION_TYPE nullGLAttachShader(GrGLuint program, GrGLuint shader) {} |
|
99 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBeginQuery(GrGLenum target, GrGLuint id) {} |
|
100 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindAttribLocation(GrGLuint program, GrGLuint index, const char* name) {} |
|
101 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindTexture(GrGLenum target, GrGLuint texture) {} |
|
102 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindVertexArray(GrGLuint id) {} |
|
103 |
|
104 GrGLvoid GR_GL_FUNCTION_TYPE nullGLGenBuffers(GrGLsizei n, GrGLuint* ids) { |
|
105 |
|
106 for (int i = 0; i < n; ++i) { |
|
107 GrBufferObj* buffer = create_buffer(); |
|
108 ids[i] = buffer->id(); |
|
109 } |
|
110 } |
|
111 |
|
112 GrGLvoid GR_GL_FUNCTION_TYPE nullGLGenerateMipmap(GrGLenum target) {} |
|
113 |
|
114 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBufferData(GrGLenum target, |
|
115 GrGLsizeiptr size, |
|
116 const GrGLvoid* data, |
|
117 GrGLenum usage) { |
|
118 GrGLuint id = 0; |
|
119 |
|
120 switch (target) { |
|
121 case GR_GL_ARRAY_BUFFER: |
|
122 id = gCurrArrayBuffer; |
|
123 break; |
|
124 case GR_GL_ELEMENT_ARRAY_BUFFER: |
|
125 id = gCurrElementArrayBuffer; |
|
126 break; |
|
127 default: |
|
128 GrCrash("Unexpected target to nullGLBufferData"); |
|
129 break; |
|
130 } |
|
131 |
|
132 if (id > 0) { |
|
133 GrBufferObj* buffer = look_up(id); |
|
134 buffer->allocate(size, (const GrGLchar*) data); |
|
135 } |
|
136 } |
|
137 |
|
138 GrGLvoid GR_GL_FUNCTION_TYPE nullGLPixelStorei(GrGLenum pname, GrGLint param) {} |
|
139 GrGLvoid GR_GL_FUNCTION_TYPE nullGLReadPixels(GrGLint x, GrGLint y, GrGLsizei width, GrGLsizei height, GrGLenum format, GrGLenum type, GrGLvoid* pixels) {} |
|
140 GrGLvoid GR_GL_FUNCTION_TYPE nullGLUseProgram(GrGLuint program) {} |
|
141 GrGLvoid GR_GL_FUNCTION_TYPE nullGLViewport(GrGLint x, GrGLint y, GrGLsizei width, GrGLsizei height) {} |
|
142 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindFramebuffer(GrGLenum target, GrGLuint framebuffer) {} |
|
143 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindRenderbuffer(GrGLenum target, GrGLuint renderbuffer) {} |
|
144 GrGLvoid GR_GL_FUNCTION_TYPE nullGLDeleteFramebuffers(GrGLsizei n, const GrGLuint *framebuffers) {} |
|
145 GrGLvoid GR_GL_FUNCTION_TYPE nullGLDeleteRenderbuffers(GrGLsizei n, const GrGLuint *renderbuffers) {} |
|
146 GrGLvoid GR_GL_FUNCTION_TYPE nullGLFramebufferRenderbuffer(GrGLenum target, GrGLenum attachment, GrGLenum renderbuffertarget, GrGLuint renderbuffer) {} |
|
147 GrGLvoid GR_GL_FUNCTION_TYPE nullGLFramebufferTexture2D(GrGLenum target, GrGLenum attachment, GrGLenum textarget, GrGLuint texture, GrGLint level) {} |
|
148 |
|
149 GrGLuint GR_GL_FUNCTION_TYPE nullGLCreateProgram() { |
|
150 static GrGLuint gCurrID = 0; |
|
151 return ++gCurrID; |
|
152 } |
|
153 |
|
154 GrGLuint GR_GL_FUNCTION_TYPE nullGLCreateShader(GrGLenum type) { |
|
155 static GrGLuint gCurrID = 0; |
|
156 return ++gCurrID; |
|
157 } |
|
158 |
|
159 // same delete used for shaders and programs |
|
160 GrGLvoid GR_GL_FUNCTION_TYPE nullGLDelete(GrGLuint program) { |
|
161 } |
|
162 |
|
163 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindBuffer(GrGLenum target, GrGLuint buffer) { |
|
164 switch (target) { |
|
165 case GR_GL_ARRAY_BUFFER: |
|
166 gCurrArrayBuffer = buffer; |
|
167 break; |
|
168 case GR_GL_ELEMENT_ARRAY_BUFFER: |
|
169 gCurrElementArrayBuffer = buffer; |
|
170 break; |
|
171 } |
|
172 } |
|
173 |
|
174 // deleting a bound buffer has the side effect of binding 0 |
|
175 GrGLvoid GR_GL_FUNCTION_TYPE nullGLDeleteBuffers(GrGLsizei n, const GrGLuint* ids) { |
|
176 for (int i = 0; i < n; ++i) { |
|
177 if (ids[i] == gCurrArrayBuffer) { |
|
178 gCurrArrayBuffer = 0; |
|
179 } |
|
180 if (ids[i] == gCurrElementArrayBuffer) { |
|
181 gCurrElementArrayBuffer = 0; |
|
182 } |
|
183 |
|
184 GrBufferObj* buffer = look_up(ids[i]); |
|
185 delete_buffer(buffer); |
|
186 } |
|
187 } |
|
188 |
|
189 GrGLvoid* GR_GL_FUNCTION_TYPE nullGLMapBuffer(GrGLenum target, GrGLenum access) { |
|
190 |
|
191 GrGLuint id = 0; |
|
192 switch (target) { |
|
193 case GR_GL_ARRAY_BUFFER: |
|
194 id = gCurrArrayBuffer; |
|
195 break; |
|
196 case GR_GL_ELEMENT_ARRAY_BUFFER: |
|
197 id = gCurrElementArrayBuffer; |
|
198 break; |
|
199 } |
|
200 |
|
201 if (id > 0) { |
|
202 GrBufferObj* buffer = look_up(id); |
|
203 SkASSERT(!buffer->mapped()); |
|
204 buffer->setMapped(true); |
|
205 return buffer->dataPtr(); |
|
206 } |
|
207 |
|
208 SkASSERT(false); |
|
209 return NULL; // no buffer bound to target |
|
210 } |
|
211 |
|
212 GrGLboolean GR_GL_FUNCTION_TYPE nullGLUnmapBuffer(GrGLenum target) { |
|
213 GrGLuint id = 0; |
|
214 switch (target) { |
|
215 case GR_GL_ARRAY_BUFFER: |
|
216 id = gCurrArrayBuffer; |
|
217 break; |
|
218 case GR_GL_ELEMENT_ARRAY_BUFFER: |
|
219 id = gCurrElementArrayBuffer; |
|
220 break; |
|
221 } |
|
222 if (id > 0) { |
|
223 GrBufferObj* buffer = look_up(id); |
|
224 SkASSERT(buffer->mapped()); |
|
225 buffer->setMapped(false); |
|
226 return GR_GL_TRUE; |
|
227 } |
|
228 |
|
229 GrAlwaysAssert(false); |
|
230 return GR_GL_FALSE; // GR_GL_INVALID_OPERATION; |
|
231 } |
|
232 |
|
233 GrGLvoid GR_GL_FUNCTION_TYPE nullGLGetBufferParameteriv(GrGLenum target, GrGLenum pname, GrGLint* params) { |
|
234 switch (pname) { |
|
235 case GR_GL_BUFFER_MAPPED: { |
|
236 *params = GR_GL_FALSE; |
|
237 GrGLuint id = 0; |
|
238 switch (target) { |
|
239 case GR_GL_ARRAY_BUFFER: |
|
240 id = gCurrArrayBuffer; |
|
241 break; |
|
242 case GR_GL_ELEMENT_ARRAY_BUFFER: |
|
243 id = gCurrElementArrayBuffer; |
|
244 break; |
|
245 } |
|
246 if (id > 0) { |
|
247 GrBufferObj* buffer = look_up(id); |
|
248 if (buffer->mapped()) { |
|
249 *params = GR_GL_TRUE; |
|
250 } |
|
251 } |
|
252 break; } |
|
253 default: |
|
254 GrCrash("Unexpected pname to GetBufferParamateriv"); |
|
255 break; |
|
256 } |
|
257 }; |
|
258 |
|
259 } // end anonymous namespace |
|
260 |
|
261 const GrGLInterface* GrGLCreateNullInterface() { |
|
262 GrGLInterface* interface = SkNEW(GrGLInterface); |
|
263 |
|
264 interface->fStandard = kGL_GrGLStandard; |
|
265 |
|
266 GrGLInterface::Functions* functions = &interface->fFunctions; |
|
267 functions->fActiveTexture = nullGLActiveTexture; |
|
268 functions->fAttachShader = nullGLAttachShader; |
|
269 functions->fBeginQuery = nullGLBeginQuery; |
|
270 functions->fBindAttribLocation = nullGLBindAttribLocation; |
|
271 functions->fBindBuffer = nullGLBindBuffer; |
|
272 functions->fBindFragDataLocation = noOpGLBindFragDataLocation; |
|
273 functions->fBindTexture = nullGLBindTexture; |
|
274 functions->fBindVertexArray = nullGLBindVertexArray; |
|
275 functions->fBlendColor = noOpGLBlendColor; |
|
276 functions->fBlendFunc = noOpGLBlendFunc; |
|
277 functions->fBufferData = nullGLBufferData; |
|
278 functions->fBufferSubData = noOpGLBufferSubData; |
|
279 functions->fClear = noOpGLClear; |
|
280 functions->fClearColor = noOpGLClearColor; |
|
281 functions->fClearStencil = noOpGLClearStencil; |
|
282 functions->fColorMask = noOpGLColorMask; |
|
283 functions->fCompileShader = noOpGLCompileShader; |
|
284 functions->fCompressedTexImage2D = noOpGLCompressedTexImage2D; |
|
285 functions->fCopyTexSubImage2D = noOpGLCopyTexSubImage2D; |
|
286 functions->fCreateProgram = nullGLCreateProgram; |
|
287 functions->fCreateShader = nullGLCreateShader; |
|
288 functions->fCullFace = noOpGLCullFace; |
|
289 functions->fDeleteBuffers = nullGLDeleteBuffers; |
|
290 functions->fDeleteProgram = nullGLDelete; |
|
291 functions->fDeleteQueries = noOpGLDeleteIds; |
|
292 functions->fDeleteShader = nullGLDelete; |
|
293 functions->fDeleteTextures = noOpGLDeleteIds; |
|
294 functions->fDeleteVertexArrays = noOpGLDeleteIds; |
|
295 functions->fDepthMask = noOpGLDepthMask; |
|
296 functions->fDisable = noOpGLDisable; |
|
297 functions->fDisableVertexAttribArray = noOpGLDisableVertexAttribArray; |
|
298 functions->fDrawArrays = noOpGLDrawArrays; |
|
299 functions->fDrawBuffer = noOpGLDrawBuffer; |
|
300 functions->fDrawBuffers = noOpGLDrawBuffers; |
|
301 functions->fDrawElements = noOpGLDrawElements; |
|
302 functions->fEnable = noOpGLEnable; |
|
303 functions->fEnableVertexAttribArray = noOpGLEnableVertexAttribArray; |
|
304 functions->fEndQuery = noOpGLEndQuery; |
|
305 functions->fFinish = noOpGLFinish; |
|
306 functions->fFlush = noOpGLFlush; |
|
307 functions->fFrontFace = noOpGLFrontFace; |
|
308 functions->fGenBuffers = nullGLGenBuffers; |
|
309 functions->fGenerateMipmap = nullGLGenerateMipmap; |
|
310 functions->fGenQueries = noOpGLGenIds; |
|
311 functions->fGenTextures = noOpGLGenIds; |
|
312 functions->fGenVertexArrays = noOpGLGenIds; |
|
313 functions->fGetBufferParameteriv = nullGLGetBufferParameteriv; |
|
314 functions->fGetError = noOpGLGetError; |
|
315 functions->fGetIntegerv = noOpGLGetIntegerv; |
|
316 functions->fGetQueryObjecti64v = noOpGLGetQueryObjecti64v; |
|
317 functions->fGetQueryObjectiv = noOpGLGetQueryObjectiv; |
|
318 functions->fGetQueryObjectui64v = noOpGLGetQueryObjectui64v; |
|
319 functions->fGetQueryObjectuiv = noOpGLGetQueryObjectuiv; |
|
320 functions->fGetQueryiv = noOpGLGetQueryiv; |
|
321 functions->fGetProgramInfoLog = noOpGLGetInfoLog; |
|
322 functions->fGetProgramiv = noOpGLGetShaderOrProgramiv; |
|
323 functions->fGetShaderInfoLog = noOpGLGetInfoLog; |
|
324 functions->fGetShaderiv = noOpGLGetShaderOrProgramiv; |
|
325 functions->fGetString = noOpGLGetString; |
|
326 functions->fGetStringi = noOpGLGetStringi; |
|
327 functions->fGetTexLevelParameteriv = noOpGLGetTexLevelParameteriv; |
|
328 functions->fGetUniformLocation = noOpGLGetUniformLocation; |
|
329 functions->fInsertEventMarker = noOpGLInsertEventMarker; |
|
330 functions->fLoadIdentity = noOpGLLoadIdentity; |
|
331 functions->fLoadMatrixf = noOpGLLoadMatrixf; |
|
332 functions->fLineWidth = noOpGLLineWidth; |
|
333 functions->fLinkProgram = noOpGLLinkProgram; |
|
334 functions->fMatrixMode = noOpGLMatrixMode; |
|
335 functions->fPixelStorei = nullGLPixelStorei; |
|
336 functions->fPopGroupMarker = noOpGLPopGroupMarker; |
|
337 functions->fPushGroupMarker = noOpGLPushGroupMarker; |
|
338 functions->fQueryCounter = noOpGLQueryCounter; |
|
339 functions->fReadBuffer = noOpGLReadBuffer; |
|
340 functions->fReadPixels = nullGLReadPixels; |
|
341 functions->fScissor = noOpGLScissor; |
|
342 functions->fShaderSource = noOpGLShaderSource; |
|
343 functions->fStencilFunc = noOpGLStencilFunc; |
|
344 functions->fStencilFuncSeparate = noOpGLStencilFuncSeparate; |
|
345 functions->fStencilMask = noOpGLStencilMask; |
|
346 functions->fStencilMaskSeparate = noOpGLStencilMaskSeparate; |
|
347 functions->fStencilOp = noOpGLStencilOp; |
|
348 functions->fStencilOpSeparate = noOpGLStencilOpSeparate; |
|
349 functions->fTexGenfv = noOpGLTexGenfv; |
|
350 functions->fTexGeni = noOpGLTexGeni; |
|
351 functions->fTexImage2D = noOpGLTexImage2D; |
|
352 functions->fTexParameteri = noOpGLTexParameteri; |
|
353 functions->fTexParameteriv = noOpGLTexParameteriv; |
|
354 functions->fTexSubImage2D = noOpGLTexSubImage2D; |
|
355 functions->fTexStorage2D = noOpGLTexStorage2D; |
|
356 functions->fDiscardFramebuffer = noOpGLDiscardFramebuffer; |
|
357 functions->fUniform1f = noOpGLUniform1f; |
|
358 functions->fUniform1i = noOpGLUniform1i; |
|
359 functions->fUniform1fv = noOpGLUniform1fv; |
|
360 functions->fUniform1iv = noOpGLUniform1iv; |
|
361 functions->fUniform2f = noOpGLUniform2f; |
|
362 functions->fUniform2i = noOpGLUniform2i; |
|
363 functions->fUniform2fv = noOpGLUniform2fv; |
|
364 functions->fUniform2iv = noOpGLUniform2iv; |
|
365 functions->fUniform3f = noOpGLUniform3f; |
|
366 functions->fUniform3i = noOpGLUniform3i; |
|
367 functions->fUniform3fv = noOpGLUniform3fv; |
|
368 functions->fUniform3iv = noOpGLUniform3iv; |
|
369 functions->fUniform4f = noOpGLUniform4f; |
|
370 functions->fUniform4i = noOpGLUniform4i; |
|
371 functions->fUniform4fv = noOpGLUniform4fv; |
|
372 functions->fUniform4iv = noOpGLUniform4iv; |
|
373 functions->fUniformMatrix2fv = noOpGLUniformMatrix2fv; |
|
374 functions->fUniformMatrix3fv = noOpGLUniformMatrix3fv; |
|
375 functions->fUniformMatrix4fv = noOpGLUniformMatrix4fv; |
|
376 functions->fUseProgram = nullGLUseProgram; |
|
377 functions->fVertexAttrib4fv = noOpGLVertexAttrib4fv; |
|
378 functions->fVertexAttribPointer = noOpGLVertexAttribPointer; |
|
379 functions->fViewport = nullGLViewport; |
|
380 functions->fBindFramebuffer = nullGLBindFramebuffer; |
|
381 functions->fBindRenderbuffer = nullGLBindRenderbuffer; |
|
382 functions->fCheckFramebufferStatus = noOpGLCheckFramebufferStatus; |
|
383 functions->fDeleteFramebuffers = nullGLDeleteFramebuffers; |
|
384 functions->fDeleteRenderbuffers = nullGLDeleteRenderbuffers; |
|
385 functions->fFramebufferRenderbuffer = nullGLFramebufferRenderbuffer; |
|
386 functions->fFramebufferTexture2D = nullGLFramebufferTexture2D; |
|
387 functions->fGenFramebuffers = noOpGLGenIds; |
|
388 functions->fGenRenderbuffers = noOpGLGenIds; |
|
389 functions->fGetFramebufferAttachmentParameteriv = noOpGLGetFramebufferAttachmentParameteriv; |
|
390 functions->fGetRenderbufferParameteriv = noOpGLGetRenderbufferParameteriv; |
|
391 functions->fRenderbufferStorage = noOpGLRenderbufferStorage; |
|
392 functions->fRenderbufferStorageMultisample = noOpGLRenderbufferStorageMultisample; |
|
393 functions->fBlitFramebuffer = noOpGLBlitFramebuffer; |
|
394 functions->fResolveMultisampleFramebuffer = noOpGLResolveMultisampleFramebuffer; |
|
395 functions->fMapBuffer = nullGLMapBuffer; |
|
396 functions->fUnmapBuffer = nullGLUnmapBuffer; |
|
397 functions->fBindFragDataLocationIndexed = noOpGLBindFragDataLocationIndexed; |
|
398 |
|
399 interface->fExtensions.init(kGL_GrGLStandard, functions->fGetString, functions->fGetStringi, |
|
400 functions->fGetIntegerv); |
|
401 return interface; |
|
402 } |