GrGLCreateNullInterface.cpp revision c72425ae368bfcb47de7d2532eb90d305ec0d1cf
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
16namespace { // added to suppress 'no previous prototype' warning
17
18class GrBufferObj {
19public:
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
41private:
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.
50static SkTDArray<GrBufferObj*> gBuffers;  // slot 0 is reserved for head of free list
51static GrGLuint gCurrArrayBuffer;
52static GrGLuint gCurrElementArrayBuffer;
53
54static GrBufferObj* look_up(GrGLuint id) {
55    GrBufferObj* buffer = gBuffers[id];
56    SkASSERT(NULL != buffer && buffer->id() == id);
57    return buffer;
58}
59
60static 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
86static 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
97GrGLvoid GR_GL_FUNCTION_TYPE nullGLActiveTexture(GrGLenum texture) {}
98GrGLvoid GR_GL_FUNCTION_TYPE nullGLAttachShader(GrGLuint program, GrGLuint shader) {}
99GrGLvoid GR_GL_FUNCTION_TYPE nullGLBeginQuery(GrGLenum target, GrGLuint id) {}
100GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindAttribLocation(GrGLuint program, GrGLuint index, const char* name) {}
101GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindTexture(GrGLenum target, GrGLuint texture) {}
102GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindVertexArray(GrGLuint id) {}
103GrGLvoid GR_GL_FUNCTION_TYPE nullGLClientActiveTexture(GrGLenum) {}
104
105GrGLvoid GR_GL_FUNCTION_TYPE nullGLGenBuffers(GrGLsizei n, GrGLuint* ids) {
106
107    for (int i = 0; i < n; ++i) {
108        GrBufferObj* buffer = create_buffer();
109        ids[i] = buffer->id();
110    }
111}
112
113GrGLvoid GR_GL_FUNCTION_TYPE nullGLGenerateMipmap(GrGLenum target) {}
114
115GrGLvoid GR_GL_FUNCTION_TYPE nullGLBufferData(GrGLenum target,
116                                              GrGLsizeiptr size,
117                                              const GrGLvoid* data,
118                                              GrGLenum usage) {
119    GrGLuint id = 0;
120
121    switch (target) {
122    case GR_GL_ARRAY_BUFFER:
123        id = gCurrArrayBuffer;
124        break;
125    case GR_GL_ELEMENT_ARRAY_BUFFER:
126        id = gCurrElementArrayBuffer;
127        break;
128    default:
129        GrCrash("Unexpected target to nullGLBufferData");
130        break;
131    }
132
133    if (id > 0) {
134        GrBufferObj* buffer = look_up(id);
135        buffer->allocate(size, (const GrGLchar*) data);
136    }
137}
138
139GrGLvoid GR_GL_FUNCTION_TYPE nullGLPixelStorei(GrGLenum pname, GrGLint param) {}
140GrGLvoid GR_GL_FUNCTION_TYPE nullGLReadPixels(GrGLint x, GrGLint y, GrGLsizei width, GrGLsizei height, GrGLenum format, GrGLenum type, GrGLvoid* pixels) {}
141GrGLvoid GR_GL_FUNCTION_TYPE nullGLUseProgram(GrGLuint program) {}
142GrGLvoid GR_GL_FUNCTION_TYPE nullGLViewport(GrGLint x, GrGLint y, GrGLsizei width, GrGLsizei height) {}
143GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindFramebuffer(GrGLenum target, GrGLuint framebuffer) {}
144GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindRenderbuffer(GrGLenum target, GrGLuint renderbuffer) {}
145GrGLvoid GR_GL_FUNCTION_TYPE nullGLDeleteFramebuffers(GrGLsizei n, const GrGLuint *framebuffers) {}
146GrGLvoid GR_GL_FUNCTION_TYPE nullGLDeleteRenderbuffers(GrGLsizei n, const GrGLuint *renderbuffers) {}
147GrGLvoid GR_GL_FUNCTION_TYPE nullGLFramebufferRenderbuffer(GrGLenum target, GrGLenum attachment, GrGLenum renderbuffertarget, GrGLuint renderbuffer) {}
148GrGLvoid GR_GL_FUNCTION_TYPE nullGLFramebufferTexture2D(GrGLenum target, GrGLenum attachment, GrGLenum textarget, GrGLuint texture, GrGLint level) {}
149
150GrGLuint GR_GL_FUNCTION_TYPE nullGLCreateProgram() {
151    static GrGLuint gCurrID = 0;
152    return ++gCurrID;
153}
154
155GrGLuint GR_GL_FUNCTION_TYPE nullGLCreateShader(GrGLenum type) {
156    static GrGLuint gCurrID = 0;
157    return ++gCurrID;
158}
159
160// same delete used for shaders and programs
161GrGLvoid GR_GL_FUNCTION_TYPE nullGLDelete(GrGLuint program) {
162}
163
164GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindBuffer(GrGLenum target, GrGLuint buffer) {
165    switch (target) {
166    case GR_GL_ARRAY_BUFFER:
167        gCurrArrayBuffer = buffer;
168        break;
169    case GR_GL_ELEMENT_ARRAY_BUFFER:
170        gCurrElementArrayBuffer = buffer;
171        break;
172    }
173}
174
175// deleting a bound buffer has the side effect of binding 0
176GrGLvoid 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;
180        }
181        if (ids[i] == gCurrElementArrayBuffer) {
182            gCurrElementArrayBuffer = 0;
183        }
184
185        GrBufferObj* buffer = look_up(ids[i]);
186        delete_buffer(buffer);
187    }
188}
189
190GrGLvoid* GR_GL_FUNCTION_TYPE nullGLMapBuffer(GrGLenum target, GrGLenum access) {
191
192    GrGLuint id = 0;
193    switch (target) {
194        case GR_GL_ARRAY_BUFFER:
195            id = gCurrArrayBuffer;
196            break;
197        case GR_GL_ELEMENT_ARRAY_BUFFER:
198            id = gCurrElementArrayBuffer;
199            break;
200    }
201
202    if (id > 0) {
203        GrBufferObj* buffer = look_up(id);
204        SkASSERT(!buffer->mapped());
205        buffer->setMapped(true);
206        return buffer->dataPtr();
207    }
208
209    SkASSERT(false);
210    return NULL;            // no buffer bound to target
211}
212
213GrGLboolean GR_GL_FUNCTION_TYPE nullGLUnmapBuffer(GrGLenum target) {
214    GrGLuint id = 0;
215    switch (target) {
216    case GR_GL_ARRAY_BUFFER:
217        id = gCurrArrayBuffer;
218        break;
219    case GR_GL_ELEMENT_ARRAY_BUFFER:
220        id = gCurrElementArrayBuffer;
221        break;
222    }
223    if (id > 0) {
224        GrBufferObj* buffer = look_up(id);
225        SkASSERT(buffer->mapped());
226        buffer->setMapped(false);
227        return GR_GL_TRUE;
228    }
229
230    GrAlwaysAssert(false);
231    return GR_GL_FALSE; // GR_GL_INVALID_OPERATION;
232}
233
234GrGLvoid GR_GL_FUNCTION_TYPE nullGLGetBufferParameteriv(GrGLenum target, GrGLenum pname, GrGLint* params) {
235    switch (pname) {
236        case GR_GL_BUFFER_MAPPED: {
237            *params = GR_GL_FALSE;
238            GrGLuint id = 0;
239            switch (target) {
240                case GR_GL_ARRAY_BUFFER:
241                    id = gCurrArrayBuffer;
242                    break;
243                case GR_GL_ELEMENT_ARRAY_BUFFER:
244                    id = gCurrElementArrayBuffer;
245                    break;
246            }
247            if (id > 0) {
248                GrBufferObj* buffer = look_up(id);
249                if (buffer->mapped()) {
250                    *params = GR_GL_TRUE;
251                }
252            }
253            break; }
254        default:
255            GrCrash("Unexpected pname to GetBufferParamateriv");
256            break;
257    }
258};
259
260} // end anonymous namespace
261
262const GrGLInterface* GrGLCreateNullInterface() {
263    // The gl functions are not context-specific so we create one global
264    // interface
265    static SkAutoTUnref<GrGLInterface> glInterface;
266    if (!glInterface.get()) {
267        GrGLInterface* interface = SkNEW(GrGLInterface);
268        glInterface.reset(interface);
269
270        interface->fStandard = kGL_GrGLStandard;
271
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;
406    }
407    glInterface.get()->ref();
408    return glInterface.get();
409}
410