GrGLCreateNullInterface.cpp revision 160b478eed1dd4924a86a87fd60c91139e08ff71
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) {} 103 104GrGLvoid 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 112GrGLvoid GR_GL_FUNCTION_TYPE nullGLGenerateMipmap(GrGLenum target) {} 113 114GrGLvoid 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 138GrGLvoid GR_GL_FUNCTION_TYPE nullGLPixelStorei(GrGLenum pname, GrGLint param) {} 139GrGLvoid GR_GL_FUNCTION_TYPE nullGLReadPixels(GrGLint x, GrGLint y, GrGLsizei width, GrGLsizei height, GrGLenum format, GrGLenum type, GrGLvoid* pixels) {} 140GrGLvoid GR_GL_FUNCTION_TYPE nullGLUseProgram(GrGLuint program) {} 141GrGLvoid GR_GL_FUNCTION_TYPE nullGLViewport(GrGLint x, GrGLint y, GrGLsizei width, GrGLsizei height) {} 142GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindFramebuffer(GrGLenum target, GrGLuint framebuffer) {} 143GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindRenderbuffer(GrGLenum target, GrGLuint renderbuffer) {} 144GrGLvoid GR_GL_FUNCTION_TYPE nullGLDeleteFramebuffers(GrGLsizei n, const GrGLuint *framebuffers) {} 145GrGLvoid GR_GL_FUNCTION_TYPE nullGLDeleteRenderbuffers(GrGLsizei n, const GrGLuint *renderbuffers) {} 146GrGLvoid GR_GL_FUNCTION_TYPE nullGLFramebufferRenderbuffer(GrGLenum target, GrGLenum attachment, GrGLenum renderbuffertarget, GrGLuint renderbuffer) {} 147GrGLvoid GR_GL_FUNCTION_TYPE nullGLFramebufferTexture2D(GrGLenum target, GrGLenum attachment, GrGLenum textarget, GrGLuint texture, GrGLint level) {} 148 149GrGLuint GR_GL_FUNCTION_TYPE nullGLCreateProgram() { 150 static GrGLuint gCurrID = 0; 151 return ++gCurrID; 152} 153 154GrGLuint 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 160GrGLvoid GR_GL_FUNCTION_TYPE nullGLDelete(GrGLuint program) { 161} 162 163GrGLvoid 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 175GrGLvoid 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 189GrGLvoid* 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 211GrGLvoid* 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 233GrGLvoid GR_GL_FUNCTION_TYPE nullGLFlushMappedBufferRange(GrGLenum target, 234 GrGLintptr offset, 235 GrGLsizeiptr length) {} 236 237 238GrGLboolean 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 259GrGLvoid 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 287const 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->fCopyTexSubImage2D = noOpGLCopyTexSubImage2D; 312 functions->fCreateProgram = nullGLCreateProgram; 313 functions->fCreateShader = nullGLCreateShader; 314 functions->fCullFace = noOpGLCullFace; 315 functions->fDeleteBuffers = nullGLDeleteBuffers; 316 functions->fDeleteProgram = nullGLDelete; 317 functions->fDeleteQueries = noOpGLDeleteIds; 318 functions->fDeleteShader = nullGLDelete; 319 functions->fDeleteTextures = noOpGLDeleteIds; 320 functions->fDeleteVertexArrays = noOpGLDeleteIds; 321 functions->fDepthMask = noOpGLDepthMask; 322 functions->fDisable = noOpGLDisable; 323 functions->fDisableVertexAttribArray = noOpGLDisableVertexAttribArray; 324 functions->fDrawArrays = noOpGLDrawArrays; 325 functions->fDrawBuffer = noOpGLDrawBuffer; 326 functions->fDrawBuffers = noOpGLDrawBuffers; 327 functions->fDrawElements = noOpGLDrawElements; 328 functions->fEnable = noOpGLEnable; 329 functions->fEnableVertexAttribArray = noOpGLEnableVertexAttribArray; 330 functions->fEndQuery = noOpGLEndQuery; 331 functions->fFinish = noOpGLFinish; 332 functions->fFlush = noOpGLFlush; 333 functions->fFlushMappedBufferRange = nullGLFlushMappedBufferRange; 334 functions->fFrontFace = noOpGLFrontFace; 335 functions->fGenBuffers = nullGLGenBuffers; 336 functions->fGenerateMipmap = nullGLGenerateMipmap; 337 functions->fGenQueries = noOpGLGenIds; 338 functions->fGenTextures = noOpGLGenIds; 339 functions->fGenVertexArrays = noOpGLGenIds; 340 functions->fGetBufferParameteriv = nullGLGetBufferParameteriv; 341 functions->fGetError = noOpGLGetError; 342 functions->fGetIntegerv = noOpGLGetIntegerv; 343 functions->fGetQueryObjecti64v = noOpGLGetQueryObjecti64v; 344 functions->fGetQueryObjectiv = noOpGLGetQueryObjectiv; 345 functions->fGetQueryObjectui64v = noOpGLGetQueryObjectui64v; 346 functions->fGetQueryObjectuiv = noOpGLGetQueryObjectuiv; 347 functions->fGetQueryiv = noOpGLGetQueryiv; 348 functions->fGetProgramInfoLog = noOpGLGetInfoLog; 349 functions->fGetProgramiv = noOpGLGetShaderOrProgramiv; 350 functions->fGetShaderInfoLog = noOpGLGetInfoLog; 351 functions->fGetShaderiv = noOpGLGetShaderOrProgramiv; 352 functions->fGetString = noOpGLGetString; 353 functions->fGetStringi = noOpGLGetStringi; 354 functions->fGetTexLevelParameteriv = noOpGLGetTexLevelParameteriv; 355 functions->fGetUniformLocation = noOpGLGetUniformLocation; 356 functions->fInsertEventMarker = noOpGLInsertEventMarker; 357 functions->fLineWidth = noOpGLLineWidth; 358 functions->fLinkProgram = noOpGLLinkProgram; 359 functions->fMapBuffer = nullGLMapBuffer; 360 functions->fMapBufferRange = nullGLMapBufferRange; 361 functions->fPixelStorei = nullGLPixelStorei; 362 functions->fPopGroupMarker = noOpGLPopGroupMarker; 363 functions->fPushGroupMarker = noOpGLPushGroupMarker; 364 functions->fQueryCounter = noOpGLQueryCounter; 365 functions->fReadBuffer = noOpGLReadBuffer; 366 functions->fReadPixels = nullGLReadPixels; 367 functions->fScissor = noOpGLScissor; 368 functions->fShaderSource = noOpGLShaderSource; 369 functions->fStencilFunc = noOpGLStencilFunc; 370 functions->fStencilFuncSeparate = noOpGLStencilFuncSeparate; 371 functions->fStencilMask = noOpGLStencilMask; 372 functions->fStencilMaskSeparate = noOpGLStencilMaskSeparate; 373 functions->fStencilOp = noOpGLStencilOp; 374 functions->fStencilOpSeparate = noOpGLStencilOpSeparate; 375 functions->fTexImage2D = noOpGLTexImage2D; 376 functions->fTexParameteri = noOpGLTexParameteri; 377 functions->fTexParameteriv = noOpGLTexParameteriv; 378 functions->fTexSubImage2D = noOpGLTexSubImage2D; 379 functions->fTexStorage2D = noOpGLTexStorage2D; 380 functions->fDiscardFramebuffer = noOpGLDiscardFramebuffer; 381 functions->fUniform1f = noOpGLUniform1f; 382 functions->fUniform1i = noOpGLUniform1i; 383 functions->fUniform1fv = noOpGLUniform1fv; 384 functions->fUniform1iv = noOpGLUniform1iv; 385 functions->fUniform2f = noOpGLUniform2f; 386 functions->fUniform2i = noOpGLUniform2i; 387 functions->fUniform2fv = noOpGLUniform2fv; 388 functions->fUniform2iv = noOpGLUniform2iv; 389 functions->fUniform3f = noOpGLUniform3f; 390 functions->fUniform3i = noOpGLUniform3i; 391 functions->fUniform3fv = noOpGLUniform3fv; 392 functions->fUniform3iv = noOpGLUniform3iv; 393 functions->fUniform4f = noOpGLUniform4f; 394 functions->fUniform4i = noOpGLUniform4i; 395 functions->fUniform4fv = noOpGLUniform4fv; 396 functions->fUniform4iv = noOpGLUniform4iv; 397 functions->fUniformMatrix2fv = noOpGLUniformMatrix2fv; 398 functions->fUniformMatrix3fv = noOpGLUniformMatrix3fv; 399 functions->fUniformMatrix4fv = noOpGLUniformMatrix4fv; 400 functions->fUnmapBuffer = nullGLUnmapBuffer; 401 functions->fUseProgram = nullGLUseProgram; 402 functions->fVertexAttrib4fv = noOpGLVertexAttrib4fv; 403 functions->fVertexAttribPointer = noOpGLVertexAttribPointer; 404 functions->fViewport = nullGLViewport; 405 functions->fBindFramebuffer = nullGLBindFramebuffer; 406 functions->fBindRenderbuffer = nullGLBindRenderbuffer; 407 functions->fCheckFramebufferStatus = noOpGLCheckFramebufferStatus; 408 functions->fDeleteFramebuffers = nullGLDeleteFramebuffers; 409 functions->fDeleteRenderbuffers = nullGLDeleteRenderbuffers; 410 functions->fFramebufferRenderbuffer = nullGLFramebufferRenderbuffer; 411 functions->fFramebufferTexture2D = nullGLFramebufferTexture2D; 412 functions->fGenFramebuffers = noOpGLGenIds; 413 functions->fGenRenderbuffers = noOpGLGenIds; 414 functions->fGetFramebufferAttachmentParameteriv = noOpGLGetFramebufferAttachmentParameteriv; 415 functions->fGetRenderbufferParameteriv = noOpGLGetRenderbufferParameteriv; 416 functions->fRenderbufferStorage = noOpGLRenderbufferStorage; 417 functions->fRenderbufferStorageMultisample = noOpGLRenderbufferStorageMultisample; 418 functions->fBlitFramebuffer = noOpGLBlitFramebuffer; 419 functions->fResolveMultisampleFramebuffer = noOpGLResolveMultisampleFramebuffer; 420 functions->fMatrixLoadf = noOpGLMatrixLoadf; 421 functions->fMatrixLoadIdentity = noOpGLMatrixLoadIdentity; 422 functions->fBindFragDataLocationIndexed = noOpGLBindFragDataLocationIndexed; 423 424 interface->fExtensions.init(kGL_GrGLStandard, functions->fGetString, functions->fGetStringi, 425 functions->fGetIntegerv); 426 return interface; 427} 428