2 * Copyright 2011 Google Inc.
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
9 #include "gl/GrGLInterface.h"
10 #include "GrGLDefines.h"
11 #include "SkTDArray.h"
12 #include "GrGLNoOpInterface.h"
14 // Functions not declared in GrGLBogusInterface.h (not common with the Debug GL interface).
16 namespace { // added to suppress 'no previous prototype' warning
20 GrBufferObj(GrGLuint id) : fID(id), fDataPtr(NULL), fSize(0), fMapped(false) {
22 ~GrBufferObj() { SkDELETE_ARRAY(fDataPtr); }
24 void allocate(GrGLsizeiptr size, const GrGLchar* dataPtr) {
25 if (NULL != fDataPtr) {
27 SkDELETE_ARRAY(fDataPtr);
31 fDataPtr = SkNEW_ARRAY(char, size);
34 GrGLuint id() const { return fID; }
35 GrGLchar* dataPtr() { return fDataPtr; }
36 GrGLsizeiptr size() const { return fSize; }
38 void setMapped(bool mapped) { fMapped = mapped; }
39 bool mapped() const { return fMapped; }
44 GrGLsizeiptr fSize; // size in bytes
48 // In debug builds we do asserts that ensure we agree with GL about when a buffer
50 static SkTDArray<GrBufferObj*> gBuffers; // slot 0 is reserved for head of free list
51 static GrGLuint gCurrArrayBuffer;
52 static GrGLuint gCurrElementArrayBuffer;
54 static GrBufferObj* look_up(GrGLuint id) {
55 GrBufferObj* buffer = gBuffers[id];
56 SkASSERT(NULL != buffer && buffer->id() == id);
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;
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);
75 // recycle a slot from the free list
76 id = SkTCast<GrGLuint>(gBuffers[0]);
77 gBuffers[0] = gBuffers[id];
79 buffer = SkNEW_ARGS(GrBufferObj, (id));
80 gBuffers[id] = buffer;
86 static void delete_buffer(GrBufferObj* buffer) {
87 SkASSERT(gBuffers.count() > 0);
89 GrGLuint id = buffer->id();
92 // Add this slot to the free list
93 gBuffers[id] = gBuffers[0];
94 gBuffers[0] = SkTCast<GrBufferObj*>((const void*)(intptr_t)id);
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 GrGLvoid GR_GL_FUNCTION_TYPE nullGLClientActiveTexture(GrGLenum) {}
105 GrGLvoid GR_GL_FUNCTION_TYPE nullGLGenBuffers(GrGLsizei n, GrGLuint* ids) {
107 for (int i = 0; i < n; ++i) {
108 GrBufferObj* buffer = create_buffer();
109 ids[i] = buffer->id();
113 GrGLvoid GR_GL_FUNCTION_TYPE nullGLGenerateMipmap(GrGLenum target) {}
115 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBufferData(GrGLenum target,
117 const GrGLvoid* data,
122 case GR_GL_ARRAY_BUFFER:
123 id = gCurrArrayBuffer;
125 case GR_GL_ELEMENT_ARRAY_BUFFER:
126 id = gCurrElementArrayBuffer;
129 GrCrash("Unexpected target to nullGLBufferData");
134 GrBufferObj* buffer = look_up(id);
135 buffer->allocate(size, (const GrGLchar*) data);
139 GrGLvoid GR_GL_FUNCTION_TYPE nullGLPixelStorei(GrGLenum pname, GrGLint param) {}
140 GrGLvoid GR_GL_FUNCTION_TYPE nullGLReadPixels(GrGLint x, GrGLint y, GrGLsizei width, GrGLsizei height, GrGLenum format, GrGLenum type, GrGLvoid* pixels) {}
141 GrGLvoid GR_GL_FUNCTION_TYPE nullGLUseProgram(GrGLuint program) {}
142 GrGLvoid GR_GL_FUNCTION_TYPE nullGLViewport(GrGLint x, GrGLint y, GrGLsizei width, GrGLsizei height) {}
143 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindFramebuffer(GrGLenum target, GrGLuint framebuffer) {}
144 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindRenderbuffer(GrGLenum target, GrGLuint renderbuffer) {}
145 GrGLvoid GR_GL_FUNCTION_TYPE nullGLDeleteFramebuffers(GrGLsizei n, const GrGLuint *framebuffers) {}
146 GrGLvoid GR_GL_FUNCTION_TYPE nullGLDeleteRenderbuffers(GrGLsizei n, const GrGLuint *renderbuffers) {}
147 GrGLvoid GR_GL_FUNCTION_TYPE nullGLFramebufferRenderbuffer(GrGLenum target, GrGLenum attachment, GrGLenum renderbuffertarget, GrGLuint renderbuffer) {}
148 GrGLvoid GR_GL_FUNCTION_TYPE nullGLFramebufferTexture2D(GrGLenum target, GrGLenum attachment, GrGLenum textarget, GrGLuint texture, GrGLint level) {}
150 GrGLuint GR_GL_FUNCTION_TYPE nullGLCreateProgram() {
151 static GrGLuint gCurrID = 0;
155 GrGLuint GR_GL_FUNCTION_TYPE nullGLCreateShader(GrGLenum type) {
156 static GrGLuint gCurrID = 0;
160 // same delete used for shaders and programs
161 GrGLvoid GR_GL_FUNCTION_TYPE nullGLDelete(GrGLuint program) {
164 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindBuffer(GrGLenum target, GrGLuint buffer) {
166 case GR_GL_ARRAY_BUFFER:
167 gCurrArrayBuffer = buffer;
169 case GR_GL_ELEMENT_ARRAY_BUFFER:
170 gCurrElementArrayBuffer = buffer;
175 // deleting a bound buffer has the side effect of binding 0
176 GrGLvoid GR_GL_FUNCTION_TYPE nullGLDeleteBuffers(GrGLsizei n, const GrGLuint* ids) {
177 for (int i = 0; i < n; ++i) {
178 if (ids[i] == gCurrArrayBuffer) {
179 gCurrArrayBuffer = 0;
181 if (ids[i] == gCurrElementArrayBuffer) {
182 gCurrElementArrayBuffer = 0;
185 GrBufferObj* buffer = look_up(ids[i]);
186 delete_buffer(buffer);
190 GrGLvoid* GR_GL_FUNCTION_TYPE nullGLMapBuffer(GrGLenum target, GrGLenum access) {
194 case GR_GL_ARRAY_BUFFER:
195 id = gCurrArrayBuffer;
197 case GR_GL_ELEMENT_ARRAY_BUFFER:
198 id = gCurrElementArrayBuffer;
203 GrBufferObj* buffer = look_up(id);
204 SkASSERT(!buffer->mapped());
205 buffer->setMapped(true);
206 return buffer->dataPtr();
210 return NULL; // no buffer bound to target
213 GrGLboolean GR_GL_FUNCTION_TYPE nullGLUnmapBuffer(GrGLenum target) {
216 case GR_GL_ARRAY_BUFFER:
217 id = gCurrArrayBuffer;
219 case GR_GL_ELEMENT_ARRAY_BUFFER:
220 id = gCurrElementArrayBuffer;
224 GrBufferObj* buffer = look_up(id);
225 SkASSERT(buffer->mapped());
226 buffer->setMapped(false);
230 GrAlwaysAssert(false);
231 return GR_GL_FALSE; // GR_GL_INVALID_OPERATION;
234 GrGLvoid GR_GL_FUNCTION_TYPE nullGLGetBufferParameteriv(GrGLenum target, GrGLenum pname, GrGLint* params) {
236 case GR_GL_BUFFER_MAPPED: {
237 *params = GR_GL_FALSE;
240 case GR_GL_ARRAY_BUFFER:
241 id = gCurrArrayBuffer;
243 case GR_GL_ELEMENT_ARRAY_BUFFER:
244 id = gCurrElementArrayBuffer;
248 GrBufferObj* buffer = look_up(id);
249 if (buffer->mapped()) {
250 *params = GR_GL_TRUE;
255 GrCrash("Unexpected pname to GetBufferParamateriv");
260 } // end anonymous namespace
262 const GrGLInterface* GrGLCreateNullInterface() {
263 // The gl functions are not context-specific so we create one global
265 static SkAutoTUnref<GrGLInterface> glInterface;
266 if (!glInterface.get()) {
267 GrGLInterface* interface = SkNEW(GrGLInterface);
268 glInterface.reset(interface);
270 interface->fStandard = kGL_GrGLStandard;
272 GrGLInterface::Functions* functions = &interface->fFunctions;
273 functions->fActiveTexture = nullGLActiveTexture;
274 functions->fAttachShader = nullGLAttachShader;
275 functions->fBeginQuery = nullGLBeginQuery;
276 functions->fBindAttribLocation = nullGLBindAttribLocation;
277 functions->fBindBuffer = nullGLBindBuffer;
278 functions->fBindFragDataLocation = noOpGLBindFragDataLocation;
279 functions->fBindTexture = nullGLBindTexture;
280 functions->fBindVertexArray = nullGLBindVertexArray;
281 functions->fBlendColor = noOpGLBlendColor;
282 functions->fBlendFunc = noOpGLBlendFunc;
283 functions->fBufferData = nullGLBufferData;
284 functions->fBufferSubData = noOpGLBufferSubData;
285 functions->fClear = noOpGLClear;
286 functions->fClearColor = noOpGLClearColor;
287 functions->fClearStencil = noOpGLClearStencil;
288 functions->fClientActiveTexture = nullGLClientActiveTexture;
289 functions->fColorMask = noOpGLColorMask;
290 functions->fCompileShader = noOpGLCompileShader;
291 functions->fCompressedTexImage2D = noOpGLCompressedTexImage2D;
292 functions->fCopyTexSubImage2D = noOpGLCopyTexSubImage2D;
293 functions->fCreateProgram = nullGLCreateProgram;
294 functions->fCreateShader = nullGLCreateShader;
295 functions->fCullFace = noOpGLCullFace;
296 functions->fDeleteBuffers = nullGLDeleteBuffers;
297 functions->fDeleteProgram = nullGLDelete;
298 functions->fDeleteQueries = noOpGLDeleteIds;
299 functions->fDeleteShader = nullGLDelete;
300 functions->fDeleteTextures = noOpGLDeleteIds;
301 functions->fDeleteVertexArrays = noOpGLDeleteIds;
302 functions->fDepthMask = noOpGLDepthMask;
303 functions->fDisable = noOpGLDisable;
304 functions->fDisableClientState = noOpGLDisableClientState;
305 functions->fDisableVertexAttribArray = noOpGLDisableVertexAttribArray;
306 functions->fDrawArrays = noOpGLDrawArrays;
307 functions->fDrawBuffer = noOpGLDrawBuffer;
308 functions->fDrawBuffers = noOpGLDrawBuffers;
309 functions->fDrawElements = noOpGLDrawElements;
310 functions->fEnable = noOpGLEnable;
311 functions->fEnableClientState = noOpGLEnableClientState;
312 functions->fEnableVertexAttribArray = noOpGLEnableVertexAttribArray;
313 functions->fEndQuery = noOpGLEndQuery;
314 functions->fFinish = noOpGLFinish;
315 functions->fFlush = noOpGLFlush;
316 functions->fFrontFace = noOpGLFrontFace;
317 functions->fGenBuffers = nullGLGenBuffers;
318 functions->fGenerateMipmap = nullGLGenerateMipmap;
319 functions->fGenQueries = noOpGLGenIds;
320 functions->fGenTextures = noOpGLGenIds;
321 functions->fGenVertexArrays = noOpGLGenIds;
322 functions->fGetBufferParameteriv = nullGLGetBufferParameteriv;
323 functions->fGetError = noOpGLGetError;
324 functions->fGetIntegerv = noOpGLGetIntegerv;
325 functions->fGetQueryObjecti64v = noOpGLGetQueryObjecti64v;
326 functions->fGetQueryObjectiv = noOpGLGetQueryObjectiv;
327 functions->fGetQueryObjectui64v = noOpGLGetQueryObjectui64v;
328 functions->fGetQueryObjectuiv = noOpGLGetQueryObjectuiv;
329 functions->fGetQueryiv = noOpGLGetQueryiv;
330 functions->fGetProgramInfoLog = noOpGLGetInfoLog;
331 functions->fGetProgramiv = noOpGLGetShaderOrProgramiv;
332 functions->fGetShaderInfoLog = noOpGLGetInfoLog;
333 functions->fGetShaderiv = noOpGLGetShaderOrProgramiv;
334 functions->fGetString = noOpGLGetString;
335 functions->fGetStringi = noOpGLGetStringi;
336 functions->fGetTexLevelParameteriv = noOpGLGetTexLevelParameteriv;
337 functions->fGetUniformLocation = noOpGLGetUniformLocation;
338 functions->fLoadIdentity = noOpGLLoadIdentity;
339 functions->fLoadMatrixf = noOpGLLoadMatrixf;
340 functions->fLineWidth = noOpGLLineWidth;
341 functions->fLinkProgram = noOpGLLinkProgram;
342 functions->fMatrixMode = noOpGLMatrixMode;
343 functions->fPixelStorei = nullGLPixelStorei;
344 functions->fQueryCounter = noOpGLQueryCounter;
345 functions->fReadBuffer = noOpGLReadBuffer;
346 functions->fReadPixels = nullGLReadPixels;
347 functions->fScissor = noOpGLScissor;
348 functions->fShaderSource = noOpGLShaderSource;
349 functions->fStencilFunc = noOpGLStencilFunc;
350 functions->fStencilFuncSeparate = noOpGLStencilFuncSeparate;
351 functions->fStencilMask = noOpGLStencilMask;
352 functions->fStencilMaskSeparate = noOpGLStencilMaskSeparate;
353 functions->fStencilOp = noOpGLStencilOp;
354 functions->fStencilOpSeparate = noOpGLStencilOpSeparate;
355 functions->fTexGenf = noOpGLTexGenf;
356 functions->fTexGenfv = noOpGLTexGenfv;
357 functions->fTexGeni = noOpGLTexGeni;
358 functions->fTexImage2D = noOpGLTexImage2D;
359 functions->fTexParameteri = noOpGLTexParameteri;
360 functions->fTexParameteriv = noOpGLTexParameteriv;
361 functions->fTexSubImage2D = noOpGLTexSubImage2D;
362 functions->fTexStorage2D = noOpGLTexStorage2D;
363 functions->fDiscardFramebuffer = noOpGLDiscardFramebuffer;
364 functions->fUniform1f = noOpGLUniform1f;
365 functions->fUniform1i = noOpGLUniform1i;
366 functions->fUniform1fv = noOpGLUniform1fv;
367 functions->fUniform1iv = noOpGLUniform1iv;
368 functions->fUniform2f = noOpGLUniform2f;
369 functions->fUniform2i = noOpGLUniform2i;
370 functions->fUniform2fv = noOpGLUniform2fv;
371 functions->fUniform2iv = noOpGLUniform2iv;
372 functions->fUniform3f = noOpGLUniform3f;
373 functions->fUniform3i = noOpGLUniform3i;
374 functions->fUniform3fv = noOpGLUniform3fv;
375 functions->fUniform3iv = noOpGLUniform3iv;
376 functions->fUniform4f = noOpGLUniform4f;
377 functions->fUniform4i = noOpGLUniform4i;
378 functions->fUniform4fv = noOpGLUniform4fv;
379 functions->fUniform4iv = noOpGLUniform4iv;
380 functions->fUniformMatrix2fv = noOpGLUniformMatrix2fv;
381 functions->fUniformMatrix3fv = noOpGLUniformMatrix3fv;
382 functions->fUniformMatrix4fv = noOpGLUniformMatrix4fv;
383 functions->fUseProgram = nullGLUseProgram;
384 functions->fVertexAttrib4fv = noOpGLVertexAttrib4fv;
385 functions->fVertexAttribPointer = noOpGLVertexAttribPointer;
386 functions->fVertexPointer = noOpGLVertexPointer;
387 functions->fViewport = nullGLViewport;
388 functions->fBindFramebuffer = nullGLBindFramebuffer;
389 functions->fBindRenderbuffer = nullGLBindRenderbuffer;
390 functions->fCheckFramebufferStatus = noOpGLCheckFramebufferStatus;
391 functions->fDeleteFramebuffers = nullGLDeleteFramebuffers;
392 functions->fDeleteRenderbuffers = nullGLDeleteRenderbuffers;
393 functions->fFramebufferRenderbuffer = nullGLFramebufferRenderbuffer;
394 functions->fFramebufferTexture2D = nullGLFramebufferTexture2D;
395 functions->fGenFramebuffers = noOpGLGenIds;
396 functions->fGenRenderbuffers = noOpGLGenIds;
397 functions->fGetFramebufferAttachmentParameteriv = noOpGLGetFramebufferAttachmentParameteriv;
398 functions->fGetRenderbufferParameteriv = noOpGLGetRenderbufferParameteriv;
399 functions->fRenderbufferStorage = noOpGLRenderbufferStorage;
400 functions->fRenderbufferStorageMultisample = noOpGLRenderbufferStorageMultisample;
401 functions->fBlitFramebuffer = noOpGLBlitFramebuffer;
402 functions->fResolveMultisampleFramebuffer = noOpGLResolveMultisampleFramebuffer;
403 functions->fMapBuffer = nullGLMapBuffer;
404 functions->fUnmapBuffer = nullGLUnmapBuffer;
405 functions->fBindFragDataLocationIndexed = noOpGLBindFragDataLocationIndexed;
407 glInterface.get()->ref();
408 return glInterface.get();