Home | History | Annotate | Download | only in gl
      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 
     13 namespace { // added to suppress 'no previous prototype' warning
     14 
     15 GrGLvoid GR_GL_FUNCTION_TYPE nullGLActiveTexture(GrGLenum texture) {}
     16 GrGLvoid GR_GL_FUNCTION_TYPE nullGLAttachShader(GrGLuint program, GrGLuint shader) {}
     17 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBeginQuery(GrGLenum target, GrGLuint id) {}
     18 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindAttribLocation(GrGLuint program, GrGLuint index, const char* name) {}
     19 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindTexture(GrGLenum target, GrGLuint texture) {}
     20 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBlendColor(GrGLclampf red, GrGLclampf green, GrGLclampf blue, GrGLclampf alpha) {}
     21 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindFragDataLocation(GrGLuint program, GrGLuint colorNumber, const GrGLchar* name) {}
     22 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBlendFunc(GrGLenum sfactor, GrGLenum dfactor) {}
     23 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBufferData(GrGLenum target, GrGLsizeiptr size, const GrGLvoid* data, GrGLenum usage) {}
     24 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBufferSubData(GrGLenum target, GrGLintptr offset, GrGLsizeiptr size, const GrGLvoid* data) {}
     25 GrGLvoid GR_GL_FUNCTION_TYPE nullGLClear(GrGLbitfield mask) {}
     26 GrGLvoid GR_GL_FUNCTION_TYPE nullGLClearColor(GrGLclampf red, GrGLclampf green, GrGLclampf blue, GrGLclampf alpha) {}
     27 GrGLvoid GR_GL_FUNCTION_TYPE nullGLClearStencil(GrGLint s) {}
     28 GrGLvoid GR_GL_FUNCTION_TYPE nullGLColorMask(GrGLboolean red, GrGLboolean green, GrGLboolean blue, GrGLboolean alpha) {}
     29 GrGLvoid GR_GL_FUNCTION_TYPE nullGLCompileShader(GrGLuint shader) {}
     30 GrGLvoid GR_GL_FUNCTION_TYPE nullGLCompressedTexImage2D(GrGLenum target, GrGLint level, GrGLenum internalformat, GrGLsizei width, GrGLsizei height, GrGLint border, GrGLsizei imageSize, const GrGLvoid* data) {}
     31 GrGLvoid GR_GL_FUNCTION_TYPE nullGLCullFace(GrGLenum mode) {}
     32 GrGLvoid GR_GL_FUNCTION_TYPE nullGLDepthMask(GrGLboolean flag) {}
     33 GrGLvoid GR_GL_FUNCTION_TYPE nullGLDisable(GrGLenum cap) {}
     34 GrGLvoid GR_GL_FUNCTION_TYPE nullGLDisableVertexAttribArray(GrGLuint index) {}
     35 GrGLvoid GR_GL_FUNCTION_TYPE nullGLDrawArrays(GrGLenum mode, GrGLint first, GrGLsizei count) {}
     36 GrGLvoid GR_GL_FUNCTION_TYPE nullGLDrawBuffer(GrGLenum mode) {}
     37 GrGLvoid GR_GL_FUNCTION_TYPE nullGLDrawBuffers(GrGLsizei n, const GrGLenum* bufs) {}
     38 GrGLvoid GR_GL_FUNCTION_TYPE nullGLDrawElements(GrGLenum mode, GrGLsizei count, GrGLenum type, const GrGLvoid* indices) {}
     39 GrGLvoid GR_GL_FUNCTION_TYPE nullGLEnable(GrGLenum cap) {}
     40 GrGLvoid GR_GL_FUNCTION_TYPE nullGLEnableVertexAttribArray(GrGLuint index) {}
     41 GrGLvoid GR_GL_FUNCTION_TYPE nullGLEndQuery(GrGLenum target) {}
     42 GrGLvoid GR_GL_FUNCTION_TYPE nullGLFinish() {}
     43 GrGLvoid GR_GL_FUNCTION_TYPE nullGLFlush() {}
     44 GrGLvoid GR_GL_FUNCTION_TYPE nullGLFrontFace(GrGLenum mode) {}
     45 GrGLvoid GR_GL_FUNCTION_TYPE nullGLLineWidth(GrGLfloat width) {}
     46 GrGLvoid GR_GL_FUNCTION_TYPE nullGLLinkProgram(GrGLuint program) {}
     47 GrGLvoid GR_GL_FUNCTION_TYPE nullGLPixelStorei(GrGLenum pname, GrGLint param) {}
     48 GrGLvoid GR_GL_FUNCTION_TYPE nullGLQueryCounter(GrGLuint id, GrGLenum target) {}
     49 GrGLvoid GR_GL_FUNCTION_TYPE nullGLReadBuffer(GrGLenum src) {}
     50 GrGLvoid GR_GL_FUNCTION_TYPE nullGLReadPixels(GrGLint x, GrGLint y, GrGLsizei width, GrGLsizei height, GrGLenum format, GrGLenum type, GrGLvoid* pixels) {}
     51 GrGLvoid GR_GL_FUNCTION_TYPE nullGLScissor(GrGLint x, GrGLint y, GrGLsizei width, GrGLsizei height) {}
     52 #if GR_USE_NEW_GL_SHADER_SOURCE_SIGNATURE
     53 GrGLvoid GR_GL_FUNCTION_TYPE nullGLShaderSource(GrGLuint shader, GrGLsizei count, const char* const * str, const GrGLint* length) {}
     54 #else
     55 GrGLvoid GR_GL_FUNCTION_TYPE nullGLShaderSource(GrGLuint shader, GrGLsizei count, const char** str, const GrGLint* length) {}
     56 #endif
     57 GrGLvoid GR_GL_FUNCTION_TYPE nullGLStencilFunc(GrGLenum func, GrGLint ref, GrGLuint mask) {}
     58 GrGLvoid GR_GL_FUNCTION_TYPE nullGLStencilFuncSeparate(GrGLenum face, GrGLenum func, GrGLint ref, GrGLuint mask) {}
     59 GrGLvoid GR_GL_FUNCTION_TYPE nullGLStencilMask(GrGLuint mask) {}
     60 GrGLvoid GR_GL_FUNCTION_TYPE nullGLStencilMaskSeparate(GrGLenum face, GrGLuint mask) {}
     61 GrGLvoid GR_GL_FUNCTION_TYPE nullGLStencilOp(GrGLenum fail, GrGLenum zfail, GrGLenum zpass) {}
     62 GrGLvoid GR_GL_FUNCTION_TYPE nullGLStencilOpSeparate(GrGLenum face, GrGLenum fail, GrGLenum zfail, GrGLenum zpass) {}
     63 GrGLvoid GR_GL_FUNCTION_TYPE nullGLTexImage2D(GrGLenum target, GrGLint level, GrGLint internalformat, GrGLsizei width, GrGLsizei height, GrGLint border, GrGLenum format, GrGLenum type, const GrGLvoid* pixels) {}
     64 GrGLvoid GR_GL_FUNCTION_TYPE nullGLTexParameteri(GrGLenum target, GrGLenum pname, GrGLint param) {}
     65 GrGLvoid GR_GL_FUNCTION_TYPE nullGLTexParameteriv(GrGLenum target, GrGLenum pname, const GrGLint* params) {}
     66 GrGLvoid GR_GL_FUNCTION_TYPE nullGLTexStorage2D(GrGLenum target, GrGLsizei levels, GrGLenum internalformat, GrGLsizei width, GrGLsizei height) {}
     67 GrGLvoid GR_GL_FUNCTION_TYPE nullGLTexSubImage2D(GrGLenum target, GrGLint level, GrGLint xoffset, GrGLint yoffset, GrGLsizei width, GrGLsizei height, GrGLenum format, GrGLenum type, const GrGLvoid* pixels) {}
     68 GrGLvoid GR_GL_FUNCTION_TYPE nullGLUniform1f(GrGLint location, GrGLfloat v0) {}
     69 GrGLvoid GR_GL_FUNCTION_TYPE nullGLUniform1i(GrGLint location, GrGLint v0) {}
     70 GrGLvoid GR_GL_FUNCTION_TYPE nullGLUniform1fv(GrGLint location, GrGLsizei count, const GrGLfloat* v) {}
     71 GrGLvoid GR_GL_FUNCTION_TYPE nullGLUniform1iv(GrGLint location, GrGLsizei count, const GrGLint* v) {}
     72 GrGLvoid GR_GL_FUNCTION_TYPE nullGLUniform2f(GrGLint location, GrGLfloat v0, GrGLfloat v1) {}
     73 GrGLvoid GR_GL_FUNCTION_TYPE nullGLUniform2i(GrGLint location, GrGLint v0, GrGLint v1) {}
     74 GrGLvoid GR_GL_FUNCTION_TYPE nullGLUniform2fv(GrGLint location, GrGLsizei count, const GrGLfloat* v) {}
     75 GrGLvoid GR_GL_FUNCTION_TYPE nullGLUniform2iv(GrGLint location, GrGLsizei count, const GrGLint* v) {}
     76 GrGLvoid GR_GL_FUNCTION_TYPE nullGLUniform3f(GrGLint location, GrGLfloat v0, GrGLfloat v1, GrGLfloat v2) {}
     77 GrGLvoid GR_GL_FUNCTION_TYPE nullGLUniform3i(GrGLint location, GrGLint v0, GrGLint v1, GrGLint v2) {}
     78 GrGLvoid GR_GL_FUNCTION_TYPE nullGLUniform3fv(GrGLint location, GrGLsizei count, const GrGLfloat* v) {}
     79 GrGLvoid GR_GL_FUNCTION_TYPE nullGLUniform3iv(GrGLint location, GrGLsizei count, const GrGLint* v) {}
     80 GrGLvoid GR_GL_FUNCTION_TYPE nullGLUniform4f(GrGLint location, GrGLfloat v0, GrGLfloat v1, GrGLfloat v2, GrGLfloat v3) {}
     81 GrGLvoid GR_GL_FUNCTION_TYPE nullGLUniform4i(GrGLint location, GrGLint v0, GrGLint v1, GrGLint v2, GrGLint v3) {}
     82 GrGLvoid GR_GL_FUNCTION_TYPE nullGLUniform4fv(GrGLint location, GrGLsizei count, const GrGLfloat* v) {}
     83 GrGLvoid GR_GL_FUNCTION_TYPE nullGLUniform4iv(GrGLint location, GrGLsizei count, const GrGLint* v) {}
     84 GrGLvoid GR_GL_FUNCTION_TYPE nullGLUniformMatrix2fv(GrGLint location, GrGLsizei count, GrGLboolean transpose, const GrGLfloat* value) {}
     85 GrGLvoid GR_GL_FUNCTION_TYPE nullGLUniformMatrix3fv(GrGLint location, GrGLsizei count, GrGLboolean transpose, const GrGLfloat* value) {}
     86 GrGLvoid GR_GL_FUNCTION_TYPE nullGLUniformMatrix4fv(GrGLint location, GrGLsizei count, GrGLboolean transpose, const GrGLfloat* value) {}
     87 GrGLvoid GR_GL_FUNCTION_TYPE nullGLUseProgram(GrGLuint program) {}
     88 GrGLvoid GR_GL_FUNCTION_TYPE nullGLVertexAttrib4fv(GrGLuint indx, const GrGLfloat* values) {}
     89 GrGLvoid GR_GL_FUNCTION_TYPE nullGLVertexAttribPointer(GrGLuint indx, GrGLint size, GrGLenum type, GrGLboolean normalized, GrGLsizei stride, const GrGLvoid* ptr) {}
     90 GrGLvoid GR_GL_FUNCTION_TYPE nullGLViewport(GrGLint x, GrGLint y, GrGLsizei width, GrGLsizei height) {}
     91 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindFramebuffer(GrGLenum target, GrGLuint framebuffer) {}
     92 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindRenderbuffer(GrGLenum target, GrGLuint renderbuffer) {}
     93 GrGLvoid GR_GL_FUNCTION_TYPE nullGLDeleteFramebuffers(GrGLsizei n, const GrGLuint *framebuffers) {}
     94 GrGLvoid GR_GL_FUNCTION_TYPE nullGLDeleteRenderbuffers(GrGLsizei n, const GrGLuint *renderbuffers) {}
     95 GrGLvoid GR_GL_FUNCTION_TYPE nullGLFramebufferRenderbuffer(GrGLenum target, GrGLenum attachment, GrGLenum renderbuffertarget, GrGLuint renderbuffer) {}
     96 GrGLvoid GR_GL_FUNCTION_TYPE nullGLFramebufferTexture2D(GrGLenum target, GrGLenum attachment, GrGLenum textarget, GrGLuint texture, GrGLint level) {}
     97 GrGLvoid GR_GL_FUNCTION_TYPE nullGLGetFramebufferAttachmentParameteriv(GrGLenum target, GrGLenum attachment, GrGLenum pname, GrGLint* params) {}
     98 GrGLvoid GR_GL_FUNCTION_TYPE nullGLGetRenderbufferParameteriv(GrGLenum target, GrGLenum pname, GrGLint* params) {}
     99 GrGLvoid GR_GL_FUNCTION_TYPE nullGLRenderbufferStorage(GrGLenum target, GrGLenum internalformat, GrGLsizei width, GrGLsizei height) {}
    100 GrGLvoid GR_GL_FUNCTION_TYPE nullGLRenderbufferStorageMultisample(GrGLenum target, GrGLsizei samples, GrGLenum internalformat, GrGLsizei width, GrGLsizei height) {}
    101 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBlitFramebuffer(GrGLint srcX0, GrGLint srcY0, GrGLint srcX1, GrGLint srcY1, GrGLint dstX0, GrGLint dstY0, GrGLint dstX1, GrGLint dstY1, GrGLbitfield mask, GrGLenum filter) {}
    102 GrGLvoid GR_GL_FUNCTION_TYPE nullGLResolveMultisampleFramebuffer() {}
    103 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindFragDataLocationIndexed(GrGLuint program, GrGLuint colorNumber, GrGLuint index, const GrGLchar * name) {}
    104 
    105 GrGLenum GR_GL_FUNCTION_TYPE nullGLCheckFramebufferStatus(GrGLenum target) {
    106     return GR_GL_FRAMEBUFFER_COMPLETE;
    107 }
    108 
    109 GrGLuint GR_GL_FUNCTION_TYPE nullGLCreateProgram() {
    110     static int gCurrID = 0;
    111     return ++gCurrID;
    112 }
    113 
    114 GrGLuint GR_GL_FUNCTION_TYPE nullGLCreateShader(GrGLenum type) {
    115     static int gCurrID = 0;
    116     return ++gCurrID;
    117 }
    118 
    119 // same delete used for shaders and programs
    120 GrGLvoid GR_GL_FUNCTION_TYPE nullGLDelete(GrGLuint program) {
    121 }
    122 
    123 // same function used for all glGen*(GLsize i, GLuint*) functions
    124 GrGLvoid GR_GL_FUNCTION_TYPE nullGLGenIds(GrGLsizei n, GrGLuint* ids) {
    125     static int gCurrID = 0;
    126     for (int i = 0; i < n; ++i) {
    127         ids[i] = ++gCurrID;
    128     }
    129 }
    130 // same delete function for all glDelete*(GLsize i, const GLuint*) except buffers
    131 GrGLvoid GR_GL_FUNCTION_TYPE nullGLDeleteIds(GrGLsizei n, const GrGLuint* ids) {}
    132 
    133 // In debug builds we do asserts that ensure we agree with GL about when a buffer
    134 // is mapped.
    135 static SkTDArray<GrGLuint> gMappedBuffers;
    136 static GrGLuint gCurrArrayBuffer;
    137 static GrGLuint gCurrElementArrayBuffer;
    138 
    139 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindBuffer(GrGLenum target, GrGLuint buffer) {
    140     switch (target) {
    141     case GR_GL_ARRAY_BUFFER:
    142         gCurrArrayBuffer = buffer;
    143         break;
    144     case GR_GL_ELEMENT_ARRAY_BUFFER:
    145         gCurrElementArrayBuffer = buffer;
    146         break;
    147     }
    148 }
    149 
    150 // deleting a bound buffer has the side effect of binding 0
    151 GrGLvoid GR_GL_FUNCTION_TYPE nullGLDeleteBuffers(GrGLsizei n, const GrGLuint* ids) {
    152     for (int i = 0; i < n; ++i) {
    153         if (ids[i] == gCurrArrayBuffer) {
    154             gCurrArrayBuffer = 0;
    155         }
    156         if (ids[i] == gCurrElementArrayBuffer) {
    157             gCurrElementArrayBuffer = 0;
    158         }
    159         for (int j = 0; j < gMappedBuffers.count(); ++j) {
    160             if (gMappedBuffers[j] == ids[i]) {
    161                 gMappedBuffers.remove(j);
    162                 // don't break b/c we didn't check for dupes on insert
    163                 --j;
    164             }
    165         }
    166     }
    167 }
    168 
    169 GrGLvoid* GR_GL_FUNCTION_TYPE nullGLMapBuffer(GrGLenum target, GrGLenum access) {
    170     // We just reserve 32MB of RAM for all locks and hope its big enough
    171     static SkAutoMalloc gBufferData(32 * (1 << 20));
    172     GrGLuint buf = 0;
    173     switch (target) {
    174         case GR_GL_ARRAY_BUFFER:
    175             buf = gCurrArrayBuffer;
    176             break;
    177         case GR_GL_ELEMENT_ARRAY_BUFFER:
    178             buf = gCurrElementArrayBuffer;
    179             break;
    180     }
    181     if (buf) {
    182         *gMappedBuffers.append() = buf;
    183     }
    184     return gBufferData.get();
    185 }
    186 
    187 GrGLboolean GR_GL_FUNCTION_TYPE nullGLUnmapBuffer(GrGLenum target) {
    188     GrGLuint buf = 0;
    189     switch (target) {
    190     case GR_GL_ARRAY_BUFFER:
    191         buf = gCurrArrayBuffer;
    192         break;
    193     case GR_GL_ELEMENT_ARRAY_BUFFER:
    194         buf = gCurrElementArrayBuffer;
    195         break;
    196     }
    197     if (buf) {
    198         for (int i = 0; i < gMappedBuffers.count(); ++i) {
    199             if (gMappedBuffers[i] == buf) {
    200                 gMappedBuffers.remove(i);
    201                 // don't break b/c we didn't check for dupes on insert
    202                 --i;
    203             }
    204         }
    205     }
    206     return GR_GL_TRUE;
    207 }
    208 
    209 GrGLvoid GR_GL_FUNCTION_TYPE nullGLGetBufferParameteriv(GrGLenum target, GrGLenum pname, GrGLint* params) {
    210     switch (pname) {
    211         case GR_GL_BUFFER_MAPPED: {
    212             *params = GR_GL_FALSE;
    213             GrGLuint buf = 0;
    214             switch (target) {
    215                 case GR_GL_ARRAY_BUFFER:
    216                     buf = gCurrArrayBuffer;
    217                     break;
    218                 case GR_GL_ELEMENT_ARRAY_BUFFER:
    219                     buf = gCurrElementArrayBuffer;
    220                     break;
    221             }
    222             if (buf) {
    223                 for (int i = 0; i < gMappedBuffers.count(); ++i) {
    224                     if (gMappedBuffers[i] == buf) {
    225                         *params = GR_GL_TRUE;
    226                         break;
    227                     }
    228                 }
    229             }
    230             break; }
    231         default:
    232             GrCrash("Unexpected pname to GetBufferParamateriv");
    233             break;
    234     }
    235 };
    236 
    237 GrGLenum GR_GL_FUNCTION_TYPE nullGLGetError() {
    238     return GR_GL_NO_ERROR;
    239 }
    240 
    241 GrGLvoid GR_GL_FUNCTION_TYPE nullGLGetIntegerv(GrGLenum pname, GrGLint* params) {
    242     switch (pname) {
    243         case GR_GL_STENCIL_BITS:
    244             *params = 8;
    245             break;
    246         case GR_GL_SAMPLES:
    247             *params = 1;
    248             break;
    249         case GR_GL_FRAMEBUFFER_BINDING:
    250             *params = 0;
    251             break;
    252         case GR_GL_VIEWPORT:
    253             params[0] = 0;
    254             params[1] = 0;
    255             params[2] = 800;
    256             params[3] = 600;
    257             break;
    258         case GR_GL_MAX_TEXTURE_IMAGE_UNITS:
    259             *params = 8;
    260             break;
    261         case GR_GL_MAX_FRAGMENT_UNIFORM_VECTORS:
    262             *params = 16;
    263             break;
    264         case GR_GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
    265             *params = 16 * 4;
    266             break;
    267         case GR_GL_NUM_COMPRESSED_TEXTURE_FORMATS:
    268             *params = 0;
    269             break;
    270         case GR_GL_COMPRESSED_TEXTURE_FORMATS:
    271             break;
    272         case GR_GL_MAX_TEXTURE_SIZE:
    273             *params = 8192;
    274             break;
    275         case GR_GL_MAX_RENDERBUFFER_SIZE:
    276             *params = 8192;
    277             break;
    278         case GR_GL_MAX_SAMPLES:
    279             *params = 32;
    280             break;
    281         case GR_GL_MAX_VERTEX_ATTRIBS:
    282             *params = 16;
    283             break;
    284         default:
    285             GrCrash("Unexpected pname to GetIntegerv");
    286     }
    287 }
    288 // used for both the program and shader info logs
    289 GrGLvoid GR_GL_FUNCTION_TYPE nullGLGetInfoLog(GrGLuint program, GrGLsizei bufsize, GrGLsizei* length, char* infolog) {
    290     if (length) {
    291         *length = 0;
    292     }
    293     if (bufsize > 0) {
    294         *infolog = 0;
    295     }
    296 }
    297 
    298 // used for both the program and shader params
    299 GrGLvoid GR_GL_FUNCTION_TYPE nullGLGetShaderOrProgramiv(GrGLuint program, GrGLenum pname, GrGLint* params) {
    300     switch (pname) {
    301         case GR_GL_LINK_STATUS:  // fallthru
    302         case GR_GL_COMPILE_STATUS:
    303             *params = GR_GL_TRUE;
    304             break;
    305         case GR_GL_INFO_LOG_LENGTH:
    306             *params = 0;
    307             break;
    308         // we don't expect any other pnames
    309         default:
    310             GrCrash("Unexpected pname to GetProgramiv");
    311             break;
    312     }
    313 }
    314 
    315 namespace {
    316 template <typename T>
    317 void query_result(GrGLenum GLtarget, GrGLenum pname, T *params) {
    318     switch (pname) {
    319         case GR_GL_QUERY_RESULT_AVAILABLE:
    320             *params = GR_GL_TRUE;
    321             break;
    322         case GR_GL_QUERY_RESULT:
    323             *params = 0;
    324             break;
    325         default:
    326             GrCrash("Unexpected pname passed to GetQueryObject.");
    327             break;
    328     }
    329 }
    330 }
    331 
    332 // Queries on the null GL just don't do anything at all. We could potentially make
    333 // the timers work.
    334 GrGLvoid GR_GL_FUNCTION_TYPE nullGLGetQueryiv(GrGLenum GLtarget, GrGLenum pname, GrGLint *params) {
    335     switch (pname) {
    336         case GR_GL_CURRENT_QUERY:
    337             *params = 0;
    338             break;
    339         case GR_GL_QUERY_COUNTER_BITS:
    340             *params = 32;
    341             break;
    342         default:
    343             GrCrash("Unexpected pname passed GetQueryiv.");
    344     }
    345 }
    346 GrGLvoid GR_GL_FUNCTION_TYPE nullGLGetQueryObjecti64v(GrGLuint id, GrGLenum pname, GrGLint64 *params) {
    347     query_result(id, pname, params);
    348 }
    349 GrGLvoid GR_GL_FUNCTION_TYPE nullGLGetQueryObjectiv(GrGLuint id, GrGLenum pname, GrGLint *params) {
    350     query_result(id, pname, params);
    351 }
    352 GrGLvoid GR_GL_FUNCTION_TYPE nullGLGetQueryObjectui64v(GrGLuint id, GrGLenum pname, GrGLuint64 *params) {
    353     query_result(id, pname, params);
    354 }
    355 GrGLvoid GR_GL_FUNCTION_TYPE nullGLGetQueryObjectuiv(GrGLuint id, GrGLenum pname, GrGLuint *params) {
    356     query_result(id, pname, params);
    357 }
    358 
    359 const GrGLubyte* GR_GL_FUNCTION_TYPE nullGLGetString(GrGLenum name) {
    360     switch (name) {
    361         case GR_GL_EXTENSIONS:
    362             return (const GrGLubyte*)"GL_ARB_framebuffer_object GL_ARB_blend_func_extended GL_ARB_timer_query GL_ARB_draw_buffers GL_ARB_occlusion_query GL_EXT_blend_color GL_EXT_stencil_wrap";
    363         case GR_GL_VERSION:
    364             return (const GrGLubyte*)"4.0 Null GL";
    365         case GR_GL_SHADING_LANGUAGE_VERSION:
    366             return (const GrGLubyte*)"4.20.8 Null GLSL";
    367         case GR_GL_VENDOR:
    368             return (const GrGLubyte*)"Null Vendor";
    369         case GR_GL_RENDERER:
    370             return (const GrGLubyte*)"The Null (Non-)Renderer";
    371         default:
    372             GrCrash("Unexpected name to GetString");
    373             return NULL;
    374     }
    375 }
    376 
    377 // we used to use this to query stuff about externally created textures, now we just
    378 // require clients to tell us everything about the texture.
    379 GrGLvoid GR_GL_FUNCTION_TYPE nullGLGetTexLevelParameteriv(GrGLenum target, GrGLint level, GrGLenum pname, GrGLint* params) {
    380     GrCrash("Should never query texture parameters.");
    381 }
    382 
    383 GrGLint GR_GL_FUNCTION_TYPE nullGLGetUniformLocation(GrGLuint program, const char* name) {
    384     static int gUniLocation = 0;
    385     return ++gUniLocation;
    386 }
    387 
    388 } // end anonymous namespace
    389 
    390 const GrGLInterface* GrGLCreateNullInterface() {
    391     // The gl functions are not context-specific so we create one global
    392     // interface
    393     static SkAutoTUnref<GrGLInterface> glInterface;
    394     if (!glInterface.get()) {
    395         GrGLInterface* interface = SkNEW(GrGLInterface);
    396         glInterface.reset(interface);
    397         interface->fBindingsExported = kDesktop_GrGLBinding;
    398         interface->fActiveTexture = nullGLActiveTexture;
    399         interface->fAttachShader = nullGLAttachShader;
    400         interface->fBeginQuery = nullGLBeginQuery;
    401         interface->fBindAttribLocation = nullGLBindAttribLocation;
    402         interface->fBindBuffer = nullGLBindBuffer;
    403         interface->fBindFragDataLocation = nullGLBindFragDataLocation;
    404         interface->fBindTexture = nullGLBindTexture;
    405         interface->fBlendColor = nullGLBlendColor;
    406         interface->fBlendFunc = nullGLBlendFunc;
    407         interface->fBufferData = nullGLBufferData;
    408         interface->fBufferSubData = nullGLBufferSubData;
    409         interface->fClear = nullGLClear;
    410         interface->fClearColor = nullGLClearColor;
    411         interface->fClearStencil = nullGLClearStencil;
    412         interface->fColorMask = nullGLColorMask;
    413         interface->fCompileShader = nullGLCompileShader;
    414         interface->fCompressedTexImage2D = nullGLCompressedTexImage2D;
    415         interface->fCreateProgram = nullGLCreateProgram;
    416         interface->fCreateShader = nullGLCreateShader;
    417         interface->fCullFace = nullGLCullFace;
    418         interface->fDeleteBuffers = nullGLDeleteBuffers;
    419         interface->fDeleteProgram = nullGLDelete;
    420         interface->fDeleteQueries = nullGLDeleteIds;
    421         interface->fDeleteShader = nullGLDelete;
    422         interface->fDeleteTextures = nullGLDeleteIds;
    423         interface->fDepthMask = nullGLDepthMask;
    424         interface->fDisable = nullGLDisable;
    425         interface->fDisableVertexAttribArray = nullGLDisableVertexAttribArray;
    426         interface->fDrawArrays = nullGLDrawArrays;
    427         interface->fDrawBuffer = nullGLDrawBuffer;
    428         interface->fDrawBuffers = nullGLDrawBuffers;
    429         interface->fDrawElements = nullGLDrawElements;
    430         interface->fEnable = nullGLEnable;
    431         interface->fEnableVertexAttribArray = nullGLEnableVertexAttribArray;
    432         interface->fEndQuery = nullGLEndQuery;
    433         interface->fFinish = nullGLFinish;
    434         interface->fFlush = nullGLFlush;
    435         interface->fFrontFace = nullGLFrontFace;
    436         interface->fGenBuffers = nullGLGenIds;
    437         interface->fGenQueries = nullGLGenIds;
    438         interface->fGenTextures = nullGLGenIds;
    439         interface->fGetBufferParameteriv = nullGLGetBufferParameteriv;
    440         interface->fGetError = nullGLGetError;
    441         interface->fGetIntegerv = nullGLGetIntegerv;
    442         interface->fGetQueryObjecti64v = nullGLGetQueryObjecti64v;
    443         interface->fGetQueryObjectiv = nullGLGetQueryObjectiv;
    444         interface->fGetQueryObjectui64v = nullGLGetQueryObjectui64v;
    445         interface->fGetQueryObjectuiv = nullGLGetQueryObjectuiv;
    446         interface->fGetQueryiv = nullGLGetQueryiv;
    447         interface->fGetProgramInfoLog = nullGLGetInfoLog;
    448         interface->fGetProgramiv = nullGLGetShaderOrProgramiv;
    449         interface->fGetShaderInfoLog = nullGLGetInfoLog;
    450         interface->fGetShaderiv = nullGLGetShaderOrProgramiv;
    451         interface->fGetString = nullGLGetString;
    452         interface->fGetTexLevelParameteriv = nullGLGetTexLevelParameteriv;
    453         interface->fGetUniformLocation = nullGLGetUniformLocation;
    454         interface->fLineWidth = nullGLLineWidth;
    455         interface->fLinkProgram = nullGLLinkProgram;
    456         interface->fPixelStorei = nullGLPixelStorei;
    457         interface->fQueryCounter = nullGLQueryCounter;
    458         interface->fReadBuffer = nullGLReadBuffer;
    459         interface->fReadPixels = nullGLReadPixels;
    460         interface->fScissor = nullGLScissor;
    461         interface->fShaderSource = nullGLShaderSource;
    462         interface->fStencilFunc = nullGLStencilFunc;
    463         interface->fStencilFuncSeparate = nullGLStencilFuncSeparate;
    464         interface->fStencilMask = nullGLStencilMask;
    465         interface->fStencilMaskSeparate = nullGLStencilMaskSeparate;
    466         interface->fStencilOp = nullGLStencilOp;
    467         interface->fStencilOpSeparate = nullGLStencilOpSeparate;
    468         interface->fTexImage2D = nullGLTexImage2D;
    469         interface->fTexParameteri = nullGLTexParameteri;
    470         interface->fTexParameteriv = nullGLTexParameteriv;
    471         interface->fTexSubImage2D = nullGLTexSubImage2D;
    472         interface->fTexStorage2D = nullGLTexStorage2D;
    473         interface->fUniform1f = nullGLUniform1f;
    474         interface->fUniform1i = nullGLUniform1i;
    475         interface->fUniform1fv = nullGLUniform1fv;
    476         interface->fUniform1iv = nullGLUniform1iv;
    477         interface->fUniform2f = nullGLUniform2f;
    478         interface->fUniform2i = nullGLUniform2i;
    479         interface->fUniform2fv = nullGLUniform2fv;
    480         interface->fUniform2iv = nullGLUniform2iv;
    481         interface->fUniform3f = nullGLUniform3f;
    482         interface->fUniform3i = nullGLUniform3i;
    483         interface->fUniform3fv = nullGLUniform3fv;
    484         interface->fUniform3iv = nullGLUniform3iv;
    485         interface->fUniform4f = nullGLUniform4f;
    486         interface->fUniform4i = nullGLUniform4i;
    487         interface->fUniform4fv = nullGLUniform4fv;
    488         interface->fUniform4iv = nullGLUniform4iv;
    489         interface->fUniformMatrix2fv = nullGLUniformMatrix2fv;
    490         interface->fUniformMatrix3fv = nullGLUniformMatrix3fv;
    491         interface->fUniformMatrix4fv = nullGLUniformMatrix4fv;
    492         interface->fUseProgram = nullGLUseProgram;
    493         interface->fVertexAttrib4fv = nullGLVertexAttrib4fv;
    494         interface->fVertexAttribPointer = nullGLVertexAttribPointer;
    495         interface->fViewport = nullGLViewport;
    496         interface->fBindFramebuffer = nullGLBindFramebuffer;
    497         interface->fBindRenderbuffer = nullGLBindRenderbuffer;
    498         interface->fCheckFramebufferStatus = nullGLCheckFramebufferStatus;
    499         interface->fDeleteFramebuffers = nullGLDeleteFramebuffers;
    500         interface->fDeleteRenderbuffers = nullGLDeleteRenderbuffers;
    501         interface->fFramebufferRenderbuffer = nullGLFramebufferRenderbuffer;
    502         interface->fFramebufferTexture2D = nullGLFramebufferTexture2D;
    503         interface->fGenFramebuffers = nullGLGenIds;
    504         interface->fGenRenderbuffers = nullGLGenIds;
    505         interface->fGetFramebufferAttachmentParameteriv = nullGLGetFramebufferAttachmentParameteriv;
    506         interface->fGetRenderbufferParameteriv = nullGLGetRenderbufferParameteriv;
    507         interface->fRenderbufferStorage = nullGLRenderbufferStorage;
    508         interface->fRenderbufferStorageMultisample = nullGLRenderbufferStorageMultisample;
    509         interface->fBlitFramebuffer = nullGLBlitFramebuffer;
    510         interface->fResolveMultisampleFramebuffer = nullGLResolveMultisampleFramebuffer;
    511         interface->fMapBuffer = nullGLMapBuffer;
    512         interface->fUnmapBuffer = nullGLUnmapBuffer;
    513         interface->fBindFragDataLocationIndexed = nullGLBindFragDataLocationIndexed;
    514     }
    515     glInterface.get()->ref();
    516     return glInterface.get();
    517 }
    518