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 GrGLvoid GR_GL_FUNCTION_TYPE nullGLClientActiveTexture(GrGLenum) {} 104 105 GrGLvoid 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 113 GrGLvoid GR_GL_FUNCTION_TYPE nullGLGenerateMipmap(GrGLenum target) {} 114 115 GrGLvoid 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 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) {} 149 150 GrGLuint GR_GL_FUNCTION_TYPE nullGLCreateProgram() { 151 static GrGLuint gCurrID = 0; 152 return ++gCurrID; 153 } 154 155 GrGLuint 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 161 GrGLvoid GR_GL_FUNCTION_TYPE nullGLDelete(GrGLuint program) { 162 } 163 164 GrGLvoid 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 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; 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 190 GrGLvoid* 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 213 GrGLboolean 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 234 GrGLvoid 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 262 const 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 interface->fBindingsExported = kDesktop_GrGLBinding; 270 interface->fActiveTexture = nullGLActiveTexture; 271 interface->fAttachShader = nullGLAttachShader; 272 interface->fBeginQuery = nullGLBeginQuery; 273 interface->fBindAttribLocation = nullGLBindAttribLocation; 274 interface->fBindBuffer = nullGLBindBuffer; 275 interface->fBindFragDataLocation = noOpGLBindFragDataLocation; 276 interface->fBindTexture = nullGLBindTexture; 277 interface->fBindVertexArray = nullGLBindVertexArray; 278 interface->fBlendColor = noOpGLBlendColor; 279 interface->fBlendFunc = noOpGLBlendFunc; 280 interface->fBufferData = nullGLBufferData; 281 interface->fBufferSubData = noOpGLBufferSubData; 282 interface->fClear = noOpGLClear; 283 interface->fClearColor = noOpGLClearColor; 284 interface->fClearStencil = noOpGLClearStencil; 285 interface->fClientActiveTexture = nullGLClientActiveTexture; 286 interface->fColorMask = noOpGLColorMask; 287 interface->fCompileShader = noOpGLCompileShader; 288 interface->fCompressedTexImage2D = noOpGLCompressedTexImage2D; 289 interface->fCopyTexSubImage2D = noOpGLCopyTexSubImage2D; 290 interface->fCreateProgram = nullGLCreateProgram; 291 interface->fCreateShader = nullGLCreateShader; 292 interface->fCullFace = noOpGLCullFace; 293 interface->fDeleteBuffers = nullGLDeleteBuffers; 294 interface->fDeleteProgram = nullGLDelete; 295 interface->fDeleteQueries = noOpGLDeleteIds; 296 interface->fDeleteShader = nullGLDelete; 297 interface->fDeleteTextures = noOpGLDeleteIds; 298 interface->fDeleteVertexArrays = noOpGLDeleteIds; 299 interface->fDepthMask = noOpGLDepthMask; 300 interface->fDisable = noOpGLDisable; 301 interface->fDisableClientState = noOpGLDisableClientState; 302 interface->fDisableVertexAttribArray = noOpGLDisableVertexAttribArray; 303 interface->fDrawArrays = noOpGLDrawArrays; 304 interface->fDrawBuffer = noOpGLDrawBuffer; 305 interface->fDrawBuffers = noOpGLDrawBuffers; 306 interface->fDrawElements = noOpGLDrawElements; 307 interface->fEnable = noOpGLEnable; 308 interface->fEnableClientState = noOpGLEnableClientState; 309 interface->fEnableVertexAttribArray = noOpGLEnableVertexAttribArray; 310 interface->fEndQuery = noOpGLEndQuery; 311 interface->fFinish = noOpGLFinish; 312 interface->fFlush = noOpGLFlush; 313 interface->fFrontFace = noOpGLFrontFace; 314 interface->fGenBuffers = nullGLGenBuffers; 315 interface->fGenerateMipmap = nullGLGenerateMipmap; 316 interface->fGenQueries = noOpGLGenIds; 317 interface->fGenTextures = noOpGLGenIds; 318 interface->fGenVertexArrays = noOpGLGenIds; 319 interface->fGetBufferParameteriv = nullGLGetBufferParameteriv; 320 interface->fGetError = noOpGLGetError; 321 interface->fGetIntegerv = noOpGLGetIntegerv; 322 interface->fGetQueryObjecti64v = noOpGLGetQueryObjecti64v; 323 interface->fGetQueryObjectiv = noOpGLGetQueryObjectiv; 324 interface->fGetQueryObjectui64v = noOpGLGetQueryObjectui64v; 325 interface->fGetQueryObjectuiv = noOpGLGetQueryObjectuiv; 326 interface->fGetQueryiv = noOpGLGetQueryiv; 327 interface->fGetProgramInfoLog = noOpGLGetInfoLog; 328 interface->fGetProgramiv = noOpGLGetShaderOrProgramiv; 329 interface->fGetShaderInfoLog = noOpGLGetInfoLog; 330 interface->fGetShaderiv = noOpGLGetShaderOrProgramiv; 331 interface->fGetString = noOpGLGetString; 332 interface->fGetStringi = noOpGLGetStringi; 333 interface->fGetTexLevelParameteriv = noOpGLGetTexLevelParameteriv; 334 interface->fGetUniformLocation = noOpGLGetUniformLocation; 335 interface->fLoadIdentity = noOpGLLoadIdentity; 336 interface->fLoadMatrixf = noOpGLLoadMatrixf; 337 interface->fLineWidth = noOpGLLineWidth; 338 interface->fLinkProgram = noOpGLLinkProgram; 339 interface->fMatrixMode = noOpGLMatrixMode; 340 interface->fPixelStorei = nullGLPixelStorei; 341 interface->fQueryCounter = noOpGLQueryCounter; 342 interface->fReadBuffer = noOpGLReadBuffer; 343 interface->fReadPixels = nullGLReadPixels; 344 interface->fScissor = noOpGLScissor; 345 interface->fShaderSource = noOpGLShaderSource; 346 interface->fStencilFunc = noOpGLStencilFunc; 347 interface->fStencilFuncSeparate = noOpGLStencilFuncSeparate; 348 interface->fStencilMask = noOpGLStencilMask; 349 interface->fStencilMaskSeparate = noOpGLStencilMaskSeparate; 350 interface->fStencilOp = noOpGLStencilOp; 351 interface->fStencilOpSeparate = noOpGLStencilOpSeparate; 352 interface->fTexGenf = noOpGLTexGenf; 353 interface->fTexGenfv = noOpGLTexGenfv; 354 interface->fTexGeni = noOpGLTexGeni; 355 interface->fTexImage2D = noOpGLTexImage2D; 356 interface->fTexParameteri = noOpGLTexParameteri; 357 interface->fTexParameteriv = noOpGLTexParameteriv; 358 interface->fTexSubImage2D = noOpGLTexSubImage2D; 359 interface->fTexStorage2D = noOpGLTexStorage2D; 360 interface->fDiscardFramebuffer = noOpGLDiscardFramebuffer; 361 interface->fUniform1f = noOpGLUniform1f; 362 interface->fUniform1i = noOpGLUniform1i; 363 interface->fUniform1fv = noOpGLUniform1fv; 364 interface->fUniform1iv = noOpGLUniform1iv; 365 interface->fUniform2f = noOpGLUniform2f; 366 interface->fUniform2i = noOpGLUniform2i; 367 interface->fUniform2fv = noOpGLUniform2fv; 368 interface->fUniform2iv = noOpGLUniform2iv; 369 interface->fUniform3f = noOpGLUniform3f; 370 interface->fUniform3i = noOpGLUniform3i; 371 interface->fUniform3fv = noOpGLUniform3fv; 372 interface->fUniform3iv = noOpGLUniform3iv; 373 interface->fUniform4f = noOpGLUniform4f; 374 interface->fUniform4i = noOpGLUniform4i; 375 interface->fUniform4fv = noOpGLUniform4fv; 376 interface->fUniform4iv = noOpGLUniform4iv; 377 interface->fUniformMatrix2fv = noOpGLUniformMatrix2fv; 378 interface->fUniformMatrix3fv = noOpGLUniformMatrix3fv; 379 interface->fUniformMatrix4fv = noOpGLUniformMatrix4fv; 380 interface->fUseProgram = nullGLUseProgram; 381 interface->fVertexAttrib4fv = noOpGLVertexAttrib4fv; 382 interface->fVertexAttribPointer = noOpGLVertexAttribPointer; 383 interface->fVertexPointer = noOpGLVertexPointer; 384 interface->fViewport = nullGLViewport; 385 interface->fBindFramebuffer = nullGLBindFramebuffer; 386 interface->fBindRenderbuffer = nullGLBindRenderbuffer; 387 interface->fCheckFramebufferStatus = noOpGLCheckFramebufferStatus; 388 interface->fDeleteFramebuffers = nullGLDeleteFramebuffers; 389 interface->fDeleteRenderbuffers = nullGLDeleteRenderbuffers; 390 interface->fFramebufferRenderbuffer = nullGLFramebufferRenderbuffer; 391 interface->fFramebufferTexture2D = nullGLFramebufferTexture2D; 392 interface->fGenFramebuffers = noOpGLGenIds; 393 interface->fGenRenderbuffers = noOpGLGenIds; 394 interface->fGetFramebufferAttachmentParameteriv = noOpGLGetFramebufferAttachmentParameteriv; 395 interface->fGetRenderbufferParameteriv = noOpGLGetRenderbufferParameteriv; 396 interface->fRenderbufferStorage = noOpGLRenderbufferStorage; 397 interface->fRenderbufferStorageMultisample = noOpGLRenderbufferStorageMultisample; 398 interface->fBlitFramebuffer = noOpGLBlitFramebuffer; 399 interface->fResolveMultisampleFramebuffer = noOpGLResolveMultisampleFramebuffer; 400 interface->fMapBuffer = nullGLMapBuffer; 401 interface->fUnmapBuffer = nullGLUnmapBuffer; 402 interface->fBindFragDataLocationIndexed = noOpGLBindFragDataLocationIndexed; 403 } 404 glInterface.get()->ref(); 405 return glInterface.get(); 406 } 407