• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
GrBufferObj(GrGLuint id)20     GrBufferObj(GrGLuint id) : fID(id), fDataPtr(NULL), fSize(0), fMapped(false) {
21     }
~GrBufferObj()22     ~GrBufferObj() { SkDELETE_ARRAY(fDataPtr); }
23 
allocate(GrGLsizeiptr size,const GrGLchar * dataPtr)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 
id() const34     GrGLuint id() const          { return fID; }
dataPtr()35     GrGLchar* dataPtr()          { return fDataPtr; }
size() const36     GrGLsizeiptr size() const    { return fSize; }
37 
setMapped(bool mapped)38     void setMapped(bool mapped)  { fMapped = mapped; }
mapped() const39     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 
look_up(GrGLuint id)54 static GrBufferObj* look_up(GrGLuint id) {
55     GrBufferObj* buffer = gBuffers[id];
56     SkASSERT(NULL != buffer && buffer->id() == id);
57     return buffer;
58 }
59 
create_buffer()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 
delete_buffer(GrBufferObj * buffer)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 
nullGLActiveTexture(GrGLenum texture)97 GrGLvoid GR_GL_FUNCTION_TYPE nullGLActiveTexture(GrGLenum texture) {}
nullGLAttachShader(GrGLuint program,GrGLuint shader)98 GrGLvoid GR_GL_FUNCTION_TYPE nullGLAttachShader(GrGLuint program, GrGLuint shader) {}
nullGLBeginQuery(GrGLenum target,GrGLuint id)99 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBeginQuery(GrGLenum target, GrGLuint id) {}
nullGLBindAttribLocation(GrGLuint program,GrGLuint index,const char * name)100 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindAttribLocation(GrGLuint program, GrGLuint index, const char* name) {}
nullGLBindTexture(GrGLenum target,GrGLuint texture)101 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindTexture(GrGLenum target, GrGLuint texture) {}
nullGLBindVertexArray(GrGLuint id)102 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindVertexArray(GrGLuint id) {}
103 
nullGLGenBuffers(GrGLsizei n,GrGLuint * ids)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 
nullGLGenerateMipmap(GrGLenum target)112 GrGLvoid GR_GL_FUNCTION_TYPE nullGLGenerateMipmap(GrGLenum target) {}
113 
nullGLBufferData(GrGLenum target,GrGLsizeiptr size,const GrGLvoid * data,GrGLenum usage)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         SkFAIL("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 
nullGLPixelStorei(GrGLenum pname,GrGLint param)138 GrGLvoid GR_GL_FUNCTION_TYPE nullGLPixelStorei(GrGLenum pname, GrGLint param) {}
nullGLReadPixels(GrGLint x,GrGLint y,GrGLsizei width,GrGLsizei height,GrGLenum format,GrGLenum type,GrGLvoid * pixels)139 GrGLvoid GR_GL_FUNCTION_TYPE nullGLReadPixels(GrGLint x, GrGLint y, GrGLsizei width, GrGLsizei height, GrGLenum format, GrGLenum type, GrGLvoid* pixels) {}
nullGLUseProgram(GrGLuint program)140 GrGLvoid GR_GL_FUNCTION_TYPE nullGLUseProgram(GrGLuint program) {}
nullGLViewport(GrGLint x,GrGLint y,GrGLsizei width,GrGLsizei height)141 GrGLvoid GR_GL_FUNCTION_TYPE nullGLViewport(GrGLint x, GrGLint y, GrGLsizei width, GrGLsizei height) {}
nullGLBindFramebuffer(GrGLenum target,GrGLuint framebuffer)142 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindFramebuffer(GrGLenum target, GrGLuint framebuffer) {}
nullGLBindRenderbuffer(GrGLenum target,GrGLuint renderbuffer)143 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindRenderbuffer(GrGLenum target, GrGLuint renderbuffer) {}
nullGLDeleteFramebuffers(GrGLsizei n,const GrGLuint * framebuffers)144 GrGLvoid GR_GL_FUNCTION_TYPE nullGLDeleteFramebuffers(GrGLsizei n, const GrGLuint *framebuffers) {}
nullGLDeleteRenderbuffers(GrGLsizei n,const GrGLuint * renderbuffers)145 GrGLvoid GR_GL_FUNCTION_TYPE nullGLDeleteRenderbuffers(GrGLsizei n, const GrGLuint *renderbuffers) {}
nullGLFramebufferRenderbuffer(GrGLenum target,GrGLenum attachment,GrGLenum renderbuffertarget,GrGLuint renderbuffer)146 GrGLvoid GR_GL_FUNCTION_TYPE nullGLFramebufferRenderbuffer(GrGLenum target, GrGLenum attachment, GrGLenum renderbuffertarget, GrGLuint renderbuffer) {}
nullGLFramebufferTexture2D(GrGLenum target,GrGLenum attachment,GrGLenum textarget,GrGLuint texture,GrGLint level)147 GrGLvoid GR_GL_FUNCTION_TYPE nullGLFramebufferTexture2D(GrGLenum target, GrGLenum attachment, GrGLenum textarget, GrGLuint texture, GrGLint level) {}
148 
nullGLCreateProgram()149 GrGLuint GR_GL_FUNCTION_TYPE nullGLCreateProgram() {
150     static GrGLuint gCurrID = 0;
151     return ++gCurrID;
152 }
153 
nullGLCreateShader(GrGLenum type)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
nullGLDelete(GrGLuint program)160 GrGLvoid GR_GL_FUNCTION_TYPE nullGLDelete(GrGLuint program) {
161 }
162 
nullGLBindBuffer(GrGLenum target,GrGLuint buffer)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
nullGLDeleteBuffers(GrGLsizei n,const GrGLuint * ids)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 
nullGLMapBufferRange(GrGLenum target,GrGLintptr offset,GrGLsizeiptr length,GrGLbitfield access)189 GrGLvoid* GR_GL_FUNCTION_TYPE nullGLMapBufferRange(GrGLenum target, GrGLintptr offset,
190                                                    GrGLsizeiptr length, GrGLbitfield access) {
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         // We just ignore the offset and length here.
203         GrBufferObj* buffer = look_up(id);
204         SkASSERT(!buffer->mapped());
205         buffer->setMapped(true);
206         return buffer->dataPtr();
207     }
208     return NULL;
209 }
210 
nullGLMapBuffer(GrGLenum target,GrGLenum access)211 GrGLvoid* GR_GL_FUNCTION_TYPE nullGLMapBuffer(GrGLenum target, GrGLenum access) {
212     GrGLuint id = 0;
213     switch (target) {
214         case GR_GL_ARRAY_BUFFER:
215             id = gCurrArrayBuffer;
216             break;
217         case GR_GL_ELEMENT_ARRAY_BUFFER:
218             id = gCurrElementArrayBuffer;
219             break;
220     }
221 
222     if (id > 0) {
223         GrBufferObj* buffer = look_up(id);
224         SkASSERT(!buffer->mapped());
225         buffer->setMapped(true);
226         return buffer->dataPtr();
227     }
228 
229     SkASSERT(false);
230     return NULL;            // no buffer bound to target
231 }
232 
nullGLFlushMappedBufferRange(GrGLenum target,GrGLintptr offset,GrGLsizeiptr length)233 GrGLvoid GR_GL_FUNCTION_TYPE nullGLFlushMappedBufferRange(GrGLenum target,
234                                                           GrGLintptr offset,
235                                                           GrGLsizeiptr length) {}
236 
237 
nullGLUnmapBuffer(GrGLenum target)238 GrGLboolean GR_GL_FUNCTION_TYPE nullGLUnmapBuffer(GrGLenum target) {
239     GrGLuint id = 0;
240     switch (target) {
241     case GR_GL_ARRAY_BUFFER:
242         id = gCurrArrayBuffer;
243         break;
244     case GR_GL_ELEMENT_ARRAY_BUFFER:
245         id = gCurrElementArrayBuffer;
246         break;
247     }
248     if (id > 0) {
249         GrBufferObj* buffer = look_up(id);
250         SkASSERT(buffer->mapped());
251         buffer->setMapped(false);
252         return GR_GL_TRUE;
253     }
254 
255     GrAlwaysAssert(false);
256     return GR_GL_FALSE; // GR_GL_INVALID_OPERATION;
257 }
258 
nullGLGetBufferParameteriv(GrGLenum target,GrGLenum pname,GrGLint * params)259 GrGLvoid GR_GL_FUNCTION_TYPE nullGLGetBufferParameteriv(GrGLenum target, GrGLenum pname, GrGLint* params) {
260     switch (pname) {
261         case GR_GL_BUFFER_MAPPED: {
262             *params = GR_GL_FALSE;
263             GrGLuint id = 0;
264             switch (target) {
265                 case GR_GL_ARRAY_BUFFER:
266                     id = gCurrArrayBuffer;
267                     break;
268                 case GR_GL_ELEMENT_ARRAY_BUFFER:
269                     id = gCurrElementArrayBuffer;
270                     break;
271             }
272             if (id > 0) {
273                 GrBufferObj* buffer = look_up(id);
274                 if (buffer->mapped()) {
275                     *params = GR_GL_TRUE;
276                 }
277             }
278             break; }
279         default:
280             SkFAIL("Unexpected pname to GetBufferParamateriv");
281             break;
282     }
283 };
284 
285 } // end anonymous namespace
286 
GrGLCreateNullInterface()287 const GrGLInterface* GrGLCreateNullInterface() {
288     GrGLInterface* interface = SkNEW(GrGLInterface);
289 
290     interface->fStandard = kGL_GrGLStandard;
291 
292     GrGLInterface::Functions* functions = &interface->fFunctions;
293     functions->fActiveTexture = nullGLActiveTexture;
294     functions->fAttachShader = nullGLAttachShader;
295     functions->fBeginQuery = nullGLBeginQuery;
296     functions->fBindAttribLocation = nullGLBindAttribLocation;
297     functions->fBindBuffer = nullGLBindBuffer;
298     functions->fBindFragDataLocation = noOpGLBindFragDataLocation;
299     functions->fBindTexture = nullGLBindTexture;
300     functions->fBindVertexArray = nullGLBindVertexArray;
301     functions->fBlendColor = noOpGLBlendColor;
302     functions->fBlendFunc = noOpGLBlendFunc;
303     functions->fBufferData = nullGLBufferData;
304     functions->fBufferSubData = noOpGLBufferSubData;
305     functions->fClear = noOpGLClear;
306     functions->fClearColor = noOpGLClearColor;
307     functions->fClearStencil = noOpGLClearStencil;
308     functions->fColorMask = noOpGLColorMask;
309     functions->fCompileShader = noOpGLCompileShader;
310     functions->fCompressedTexImage2D = noOpGLCompressedTexImage2D;
311     functions->fCompressedTexSubImage2D = noOpGLCompressedTexSubImage2D;
312     functions->fCopyTexSubImage2D = noOpGLCopyTexSubImage2D;
313     functions->fCreateProgram = nullGLCreateProgram;
314     functions->fCreateShader = nullGLCreateShader;
315     functions->fCullFace = noOpGLCullFace;
316     functions->fDeleteBuffers = nullGLDeleteBuffers;
317     functions->fDeleteProgram = nullGLDelete;
318     functions->fDeleteQueries = noOpGLDeleteIds;
319     functions->fDeleteShader = nullGLDelete;
320     functions->fDeleteTextures = noOpGLDeleteIds;
321     functions->fDeleteVertexArrays = noOpGLDeleteIds;
322     functions->fDepthMask = noOpGLDepthMask;
323     functions->fDisable = noOpGLDisable;
324     functions->fDisableVertexAttribArray = noOpGLDisableVertexAttribArray;
325     functions->fDrawArrays = noOpGLDrawArrays;
326     functions->fDrawBuffer = noOpGLDrawBuffer;
327     functions->fDrawBuffers = noOpGLDrawBuffers;
328     functions->fDrawElements = noOpGLDrawElements;
329     functions->fEnable = noOpGLEnable;
330     functions->fEnableVertexAttribArray = noOpGLEnableVertexAttribArray;
331     functions->fEndQuery = noOpGLEndQuery;
332     functions->fFinish = noOpGLFinish;
333     functions->fFlush = noOpGLFlush;
334     functions->fFlushMappedBufferRange = nullGLFlushMappedBufferRange;
335     functions->fFrontFace = noOpGLFrontFace;
336     functions->fGenBuffers = nullGLGenBuffers;
337     functions->fGenerateMipmap = nullGLGenerateMipmap;
338     functions->fGenQueries = noOpGLGenIds;
339     functions->fGenTextures = noOpGLGenIds;
340     functions->fGenVertexArrays = noOpGLGenIds;
341     functions->fGetBufferParameteriv = nullGLGetBufferParameteriv;
342     functions->fGetError = noOpGLGetError;
343     functions->fGetIntegerv = noOpGLGetIntegerv;
344     functions->fGetQueryObjecti64v = noOpGLGetQueryObjecti64v;
345     functions->fGetQueryObjectiv = noOpGLGetQueryObjectiv;
346     functions->fGetQueryObjectui64v = noOpGLGetQueryObjectui64v;
347     functions->fGetQueryObjectuiv = noOpGLGetQueryObjectuiv;
348     functions->fGetQueryiv = noOpGLGetQueryiv;
349     functions->fGetProgramInfoLog = noOpGLGetInfoLog;
350     functions->fGetProgramiv = noOpGLGetShaderOrProgramiv;
351     functions->fGetShaderInfoLog = noOpGLGetInfoLog;
352     functions->fGetShaderiv = noOpGLGetShaderOrProgramiv;
353     functions->fGetString = noOpGLGetString;
354     functions->fGetStringi = noOpGLGetStringi;
355     functions->fGetTexLevelParameteriv = noOpGLGetTexLevelParameteriv;
356     functions->fGetUniformLocation = noOpGLGetUniformLocation;
357     functions->fInsertEventMarker = noOpGLInsertEventMarker;
358     functions->fLineWidth = noOpGLLineWidth;
359     functions->fLinkProgram = noOpGLLinkProgram;
360     functions->fMapBuffer = nullGLMapBuffer;
361     functions->fMapBufferRange = nullGLMapBufferRange;
362     functions->fPixelStorei = nullGLPixelStorei;
363     functions->fPopGroupMarker = noOpGLPopGroupMarker;
364     functions->fPushGroupMarker = noOpGLPushGroupMarker;
365     functions->fQueryCounter = noOpGLQueryCounter;
366     functions->fReadBuffer = noOpGLReadBuffer;
367     functions->fReadPixels = nullGLReadPixels;
368     functions->fScissor = noOpGLScissor;
369     functions->fShaderSource = noOpGLShaderSource;
370     functions->fStencilFunc = noOpGLStencilFunc;
371     functions->fStencilFuncSeparate = noOpGLStencilFuncSeparate;
372     functions->fStencilMask = noOpGLStencilMask;
373     functions->fStencilMaskSeparate = noOpGLStencilMaskSeparate;
374     functions->fStencilOp = noOpGLStencilOp;
375     functions->fStencilOpSeparate = noOpGLStencilOpSeparate;
376     functions->fTexImage2D = noOpGLTexImage2D;
377     functions->fTexParameteri = noOpGLTexParameteri;
378     functions->fTexParameteriv = noOpGLTexParameteriv;
379     functions->fTexSubImage2D = noOpGLTexSubImage2D;
380     functions->fTexStorage2D = noOpGLTexStorage2D;
381     functions->fDiscardFramebuffer = noOpGLDiscardFramebuffer;
382     functions->fUniform1f = noOpGLUniform1f;
383     functions->fUniform1i = noOpGLUniform1i;
384     functions->fUniform1fv = noOpGLUniform1fv;
385     functions->fUniform1iv = noOpGLUniform1iv;
386     functions->fUniform2f = noOpGLUniform2f;
387     functions->fUniform2i = noOpGLUniform2i;
388     functions->fUniform2fv = noOpGLUniform2fv;
389     functions->fUniform2iv = noOpGLUniform2iv;
390     functions->fUniform3f = noOpGLUniform3f;
391     functions->fUniform3i = noOpGLUniform3i;
392     functions->fUniform3fv = noOpGLUniform3fv;
393     functions->fUniform3iv = noOpGLUniform3iv;
394     functions->fUniform4f = noOpGLUniform4f;
395     functions->fUniform4i = noOpGLUniform4i;
396     functions->fUniform4fv = noOpGLUniform4fv;
397     functions->fUniform4iv = noOpGLUniform4iv;
398     functions->fUniformMatrix2fv = noOpGLUniformMatrix2fv;
399     functions->fUniformMatrix3fv = noOpGLUniformMatrix3fv;
400     functions->fUniformMatrix4fv = noOpGLUniformMatrix4fv;
401     functions->fUnmapBuffer = nullGLUnmapBuffer;
402     functions->fUseProgram = nullGLUseProgram;
403     functions->fVertexAttrib4fv = noOpGLVertexAttrib4fv;
404     functions->fVertexAttribPointer = noOpGLVertexAttribPointer;
405     functions->fViewport = nullGLViewport;
406     functions->fBindFramebuffer = nullGLBindFramebuffer;
407     functions->fBindRenderbuffer = nullGLBindRenderbuffer;
408     functions->fCheckFramebufferStatus = noOpGLCheckFramebufferStatus;
409     functions->fDeleteFramebuffers = nullGLDeleteFramebuffers;
410     functions->fDeleteRenderbuffers = nullGLDeleteRenderbuffers;
411     functions->fFramebufferRenderbuffer = nullGLFramebufferRenderbuffer;
412     functions->fFramebufferTexture2D = nullGLFramebufferTexture2D;
413     functions->fGenFramebuffers = noOpGLGenIds;
414     functions->fGenRenderbuffers = noOpGLGenIds;
415     functions->fGetFramebufferAttachmentParameteriv = noOpGLGetFramebufferAttachmentParameteriv;
416     functions->fGetRenderbufferParameteriv = noOpGLGetRenderbufferParameteriv;
417     functions->fRenderbufferStorage = noOpGLRenderbufferStorage;
418     functions->fRenderbufferStorageMultisample = noOpGLRenderbufferStorageMultisample;
419     functions->fBlitFramebuffer = noOpGLBlitFramebuffer;
420     functions->fResolveMultisampleFramebuffer = noOpGLResolveMultisampleFramebuffer;
421     functions->fMatrixLoadf = noOpGLMatrixLoadf;
422     functions->fMatrixLoadIdentity = noOpGLMatrixLoadIdentity;
423     functions->fBindFragDataLocationIndexed = noOpGLBindFragDataLocationIndexed;
424 
425     interface->fExtensions.init(kGL_GrGLStandard, functions->fGetString, functions->fGetStringi,
426                                 functions->fGetIntegerv);
427     return interface;
428 }
429