OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 | 8 |
9 #include "gl/GrGLInterface.h" | 9 #include "gl/GrGLInterface.h" |
10 #include "GrGLDefines.h" | 10 #include "GrGLTestInterface.h" |
| 11 #include "SkMutex.h" |
11 #include "SkTDArray.h" | 12 #include "SkTDArray.h" |
12 #include "GrGLNoOpInterface.h" | |
13 #include "SkTLS.h" | |
14 | |
15 // TODO: Delete this file after chrome starts using SkNullGLContext. | |
16 | 13 |
17 // added to suppress 'no previous prototype' warning and because this code is du
plicated in | 14 // added to suppress 'no previous prototype' warning and because this code is du
plicated in |
18 // SkNullGLContext.cpp | 15 // SkNullGLContext.cpp |
19 namespace { | 16 namespace { |
20 | 17 |
21 class BufferObj { | 18 class BufferObj { |
22 public: | 19 public: |
23 | 20 BufferObj(GrGLuint id) : fID(id), fDataPtr(nullptr), fSize(0), fMapped(false
) {} |
24 | |
25 BufferObj(GrGLuint id) : fID(id), fDataPtr(nullptr), fSize(0), fMapped(false
) { | |
26 } | |
27 ~BufferObj() { delete[] fDataPtr; } | 21 ~BufferObj() { delete[] fDataPtr; } |
28 | 22 |
29 void allocate(GrGLsizeiptr size, const GrGLchar* dataPtr) { | 23 void allocate(GrGLsizeiptr size, const GrGLchar* dataPtr) { |
30 if (fDataPtr) { | 24 if (fDataPtr) { |
31 SkASSERT(0 != fSize); | 25 SkASSERT(0 != fSize); |
32 delete[] fDataPtr; | 26 delete[] fDataPtr; |
33 } | 27 } |
34 | 28 |
35 fSize = size; | 29 fSize = size; |
36 fDataPtr = new char[size]; | 30 fDataPtr = new char[size]; |
37 } | 31 } |
38 | 32 |
39 GrGLuint id() const { return fID; } | 33 GrGLuint id() const { return fID; } |
40 GrGLchar* dataPtr() { return fDataPtr; } | 34 GrGLchar* dataPtr() { return fDataPtr; } |
41 GrGLsizeiptr size() const { return fSize; } | 35 GrGLsizeiptr size() const { return fSize; } |
42 | 36 |
43 void setMapped(bool mapped) { fMapped = mapped; } | 37 void setMapped(bool mapped) { fMapped = mapped; } |
44 bool mapped() const { return fMapped; } | 38 bool mapped() const { return fMapped; } |
45 | 39 |
46 private: | 40 private: |
47 GrGLuint fID; | 41 GrGLuint fID; |
48 GrGLchar* fDataPtr; | 42 GrGLchar* fDataPtr; |
49 GrGLsizeiptr fSize; // size in bytes | 43 GrGLsizeiptr fSize; // size in bytes |
50 bool fMapped; | 44 bool fMapped; |
51 }; | 45 }; |
52 | 46 |
53 // This class maintains a sparsely populated array of buffer pointers. | 47 // This class maintains a sparsely populated array of buffer pointers. |
54 class BufferManager { | 48 class BufferManager { |
55 public: | 49 public: |
56 | |
57 | |
58 BufferManager() : fFreeListHead(kFreeListEnd) {} | 50 BufferManager() : fFreeListHead(kFreeListEnd) {} |
59 | 51 |
60 ~BufferManager() { | 52 ~BufferManager() { |
61 // nullptr out the entries that are really free list links rather than p
trs before deleting. | 53 // nullptr out the entries that are really free list links rather than p
trs before deleting. |
62 intptr_t curr = fFreeListHead; | 54 intptr_t curr = fFreeListHead; |
63 while (kFreeListEnd != curr) { | 55 while (kFreeListEnd != curr) { |
64 intptr_t next = reinterpret_cast<intptr_t>(fBuffers[SkToS32(curr)]); | 56 intptr_t next = reinterpret_cast<intptr_t>(fBuffers[SkToS32(curr)]); |
65 fBuffers[SkToS32(curr)] = nullptr; | 57 fBuffers[SkToS32(curr)] = nullptr; |
66 curr = next; | 58 curr = next; |
67 } | 59 } |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
107 } | 99 } |
108 | 100 |
109 private: | 101 private: |
110 static const intptr_t kFreeListEnd = -1; | 102 static const intptr_t kFreeListEnd = -1; |
111 // Index of the first entry of fBuffers in the free list. Free slots in fBuf
fers are indices to | 103 // Index of the first entry of fBuffers in the free list. Free slots in fBuf
fers are indices to |
112 // the next free slot. The last free slot has a value of kFreeListEnd. | 104 // the next free slot. The last free slot has a value of kFreeListEnd. |
113 intptr_t fFreeListHead; | 105 intptr_t fFreeListHead; |
114 SkTDArray<BufferObj*> fBuffers; | 106 SkTDArray<BufferObj*> fBuffers; |
115 }; | 107 }; |
116 | 108 |
117 /** | 109 /** Null interface implementation */ |
118 * The global-to-thread state object for the null interface. All null interfaces
on the | 110 class NullInterface : public GrGLTestInterface { |
119 * same thread currently share one of these. This means two null contexts on the
same thread | |
120 * can interfere with each other. It may make sense to more integrate this into
SkNullGLContext | |
121 * and use it's makeCurrent mechanism. | |
122 */ | |
123 struct ThreadContext { | |
124 public: | 111 public: |
125 | 112 NullInterface() |
126 | 113 : fCurrArrayBuffer(0) |
| 114 , fCurrElementArrayBuffer(0) |
| 115 , fCurrPixelPackBuffer(0) |
| 116 , fCurrPixelUnpackBuffer(0) |
| 117 , fCurrShaderID(0) |
| 118 , fCurrGenericID(0) |
| 119 , fCurrUniformLocation(0) { |
| 120 this->init(kGL_GrGLStandard); |
| 121 } |
| 122 |
| 123 GrGLenum checkFramebufferStatus(GrGLenum target) override { |
| 124 return GR_GL_FRAMEBUFFER_COMPLETE; |
| 125 } |
| 126 |
| 127 GrGLvoid genBuffers(GrGLsizei n, GrGLuint* ids) override { |
| 128 for (int i = 0; i < n; ++i) { |
| 129 BufferObj* buffer = fBufferManager.create(); |
| 130 ids[i] = buffer->id(); |
| 131 } |
| 132 } |
| 133 |
| 134 GrGLvoid bufferData(GrGLenum target, GrGLsizeiptr size, const GrGLvoid* data
, |
| 135 GrGLenum usage) override { |
| 136 GrGLuint id = 0; |
| 137 |
| 138 switch (target) { |
| 139 case GR_GL_ARRAY_BUFFER: |
| 140 id = fCurrArrayBuffer; |
| 141 break; |
| 142 case GR_GL_ELEMENT_ARRAY_BUFFER: |
| 143 id = fCurrElementArrayBuffer; |
| 144 break; |
| 145 case GR_GL_PIXEL_PACK_BUFFER: |
| 146 id = fCurrPixelPackBuffer; |
| 147 break; |
| 148 case GR_GL_PIXEL_UNPACK_BUFFER: |
| 149 id = fCurrPixelUnpackBuffer; |
| 150 break; |
| 151 default: |
| 152 SkFAIL("Unexpected target to nullGLBufferData"); |
| 153 break; |
| 154 } |
| 155 |
| 156 if (id > 0) { |
| 157 BufferObj* buffer = fBufferManager.lookUp(id); |
| 158 buffer->allocate(size, (const GrGLchar*) data); |
| 159 } |
| 160 } |
| 161 |
| 162 GrGLuint createProgram() override { |
| 163 return ++fCurrProgramID; |
| 164 } |
| 165 |
| 166 GrGLuint createShader(GrGLenum type) override { |
| 167 return ++fCurrShaderID; |
| 168 } |
| 169 |
| 170 GrGLvoid bindBuffer(GrGLenum target, GrGLuint buffer) override { |
| 171 switch (target) { |
| 172 case GR_GL_ARRAY_BUFFER: |
| 173 fCurrArrayBuffer = buffer; |
| 174 break; |
| 175 case GR_GL_ELEMENT_ARRAY_BUFFER: |
| 176 fCurrElementArrayBuffer = buffer; |
| 177 break; |
| 178 case GR_GL_PIXEL_PACK_BUFFER: |
| 179 fCurrPixelPackBuffer = buffer; |
| 180 break; |
| 181 case GR_GL_PIXEL_UNPACK_BUFFER: |
| 182 fCurrPixelUnpackBuffer = buffer; |
| 183 break; |
| 184 } |
| 185 } |
| 186 |
| 187 // deleting a bound buffer has the side effect of binding 0 |
| 188 GrGLvoid deleteBuffers(GrGLsizei n, const GrGLuint* ids) override { |
| 189 for (int i = 0; i < n; ++i) { |
| 190 if (ids[i] == fCurrArrayBuffer) { |
| 191 fCurrArrayBuffer = 0; |
| 192 } |
| 193 if (ids[i] == fCurrElementArrayBuffer) { |
| 194 fCurrElementArrayBuffer = 0; |
| 195 } |
| 196 if (ids[i] == fCurrPixelPackBuffer) { |
| 197 fCurrPixelPackBuffer = 0; |
| 198 } |
| 199 if (ids[i] == fCurrPixelUnpackBuffer) { |
| 200 fCurrPixelUnpackBuffer = 0; |
| 201 } |
| 202 |
| 203 BufferObj* buffer = fBufferManager.lookUp(ids[i]); |
| 204 fBufferManager.free(buffer); |
| 205 } |
| 206 } |
| 207 |
| 208 GrGLvoid genFramebuffers(GrGLsizei n, GrGLuint *framebuffers) override { |
| 209 this->genGenericIds(n, framebuffers); |
| 210 } |
| 211 |
| 212 GrGLvoid genQueries(GrGLsizei n, GrGLuint *ids) override { this->genGenericI
ds(n, ids); } |
| 213 |
| 214 GrGLvoid genRenderbuffers(GrGLsizei n, GrGLuint *renderbuffers) override { |
| 215 this->genGenericIds(n, renderbuffers); |
| 216 } |
| 217 |
| 218 GrGLvoid genTextures(GrGLsizei n, GrGLuint *textures) override { |
| 219 this->genGenericIds(n, textures); |
| 220 } |
| 221 |
| 222 GrGLvoid genVertexArrays(GrGLsizei n, GrGLuint *arrays) override { |
| 223 this->genGenericIds(n, arrays); |
| 224 } |
| 225 |
| 226 GrGLenum getError() override { return GR_GL_NO_ERROR; } |
| 227 |
| 228 GrGLvoid getIntegerv(GrGLenum pname, GrGLint* params) override { |
| 229 // TODO: remove from Ganesh the #defines for gets we don't use. |
| 230 // We would like to minimize gets overall due to performance issues |
| 231 switch (pname) { |
| 232 case GR_GL_CONTEXT_PROFILE_MASK: |
| 233 *params = GR_GL_CONTEXT_COMPATIBILITY_PROFILE_BIT; |
| 234 break; |
| 235 case GR_GL_STENCIL_BITS: |
| 236 *params = 8; |
| 237 break; |
| 238 case GR_GL_SAMPLES: |
| 239 *params = 1; |
| 240 break; |
| 241 case GR_GL_FRAMEBUFFER_BINDING: |
| 242 *params = 0; |
| 243 break; |
| 244 case GR_GL_VIEWPORT: |
| 245 params[0] = 0; |
| 246 params[1] = 0; |
| 247 params[2] = 800; |
| 248 params[3] = 600; |
| 249 break; |
| 250 case GR_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: |
| 251 case GR_GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS: |
| 252 case GR_GL_MAX_TEXTURE_IMAGE_UNITS: |
| 253 case GR_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: |
| 254 *params = 8; |
| 255 break; |
| 256 case GR_GL_MAX_TEXTURE_COORDS: |
| 257 *params = 8; |
| 258 break; |
| 259 case GR_GL_MAX_VERTEX_UNIFORM_VECTORS: |
| 260 *params = kDefaultMaxVertexUniformVectors; |
| 261 break; |
| 262 case GR_GL_MAX_FRAGMENT_UNIFORM_VECTORS: |
| 263 *params = kDefaultMaxFragmentUniformVectors; |
| 264 break; |
| 265 case GR_GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: |
| 266 *params = 16 * 4; |
| 267 break; |
| 268 case GR_GL_NUM_COMPRESSED_TEXTURE_FORMATS: |
| 269 *params = 0; |
| 270 break; |
| 271 case GR_GL_COMPRESSED_TEXTURE_FORMATS: |
| 272 break; |
| 273 case GR_GL_MAX_TEXTURE_SIZE: |
| 274 *params = 8192; |
| 275 break; |
| 276 case GR_GL_MAX_RENDERBUFFER_SIZE: |
| 277 *params = 8192; |
| 278 break; |
| 279 case GR_GL_MAX_SAMPLES: |
| 280 *params = 32; |
| 281 break; |
| 282 case GR_GL_MAX_VERTEX_ATTRIBS: |
| 283 *params = kDefaultMaxVertexAttribs; |
| 284 break; |
| 285 case GR_GL_MAX_VARYING_VECTORS: |
| 286 *params = kDefaultMaxVaryingVectors; |
| 287 break; |
| 288 case GR_GL_NUM_EXTENSIONS: { |
| 289 GrGLint i = 0; |
| 290 while (kExtensions[i++]); |
| 291 *params = i; |
| 292 break; |
| 293 } |
| 294 default: |
| 295 SkFAIL("Unexpected pname to GetIntegerv"); |
| 296 } |
| 297 } |
| 298 |
| 299 GrGLvoid getProgramiv(GrGLuint program, GrGLenum pname, GrGLint* params) ove
rride { |
| 300 this->getShaderOrProgramiv(program, pname, params); |
| 301 } |
| 302 |
| 303 GrGLvoid getProgramInfoLog(GrGLuint program, GrGLsizei bufsize, GrGLsizei* l
ength, |
| 304 char* infolog) override { |
| 305 this->getInfoLog(program, bufsize, length, infolog); |
| 306 } |
| 307 |
| 308 GrGLvoid getMultisamplefv(GrGLenum pname, GrGLuint index, GrGLfloat* val) ov
erride { |
| 309 val[0] = val[1] = 0.5f; |
| 310 } |
| 311 |
| 312 GrGLvoid getQueryiv(GrGLenum GLtarget, GrGLenum pname, GrGLint *params) over
ride { |
| 313 switch (pname) { |
| 314 case GR_GL_CURRENT_QUERY: |
| 315 *params = 0; |
| 316 break; |
| 317 case GR_GL_QUERY_COUNTER_BITS: |
| 318 *params = 32; |
| 319 break; |
| 320 default: |
| 321 SkFAIL("Unexpected pname passed GetQueryiv."); |
| 322 } |
| 323 } |
| 324 |
| 325 GrGLvoid getQueryObjecti64v(GrGLuint id, GrGLenum pname, GrGLint64 *params)
override { |
| 326 queryResult(id, pname, params); |
| 327 } |
| 328 |
| 329 GrGLvoid getQueryObjectiv(GrGLuint id, GrGLenum pname, GrGLint *params) over
ride { |
| 330 queryResult(id, pname, params); |
| 331 } |
| 332 |
| 333 GrGLvoid getQueryObjectui64v(GrGLuint id, GrGLenum pname, GrGLuint64 *params
) override { |
| 334 queryResult(id, pname, params); |
| 335 } |
| 336 |
| 337 GrGLvoid getQueryObjectuiv(GrGLuint id, GrGLenum pname, GrGLuint *params) ov
erride { |
| 338 queryResult(id, pname, params); |
| 339 } |
| 340 |
| 341 GrGLvoid getShaderiv(GrGLuint shader, GrGLenum pname, GrGLint* params) overr
ide { |
| 342 this->getShaderOrProgramiv(shader, pname, params); |
| 343 } |
| 344 |
| 345 GrGLvoid getShaderInfoLog(GrGLuint shader, GrGLsizei bufsize, GrGLsizei* len
gth, |
| 346 char* infolog) override { |
| 347 this->getInfoLog(shader, bufsize, length, infolog); |
| 348 } |
| 349 |
| 350 const GrGLubyte* getString(GrGLenum name) override { |
| 351 switch (name) { |
| 352 case GR_GL_EXTENSIONS: |
| 353 return CombinedExtensionString(); |
| 354 case GR_GL_VERSION: |
| 355 return (const GrGLubyte*)"4.0 Debug GL"; |
| 356 case GR_GL_SHADING_LANGUAGE_VERSION: |
| 357 return (const GrGLubyte*)"4.20.8 Debug GLSL"; |
| 358 case GR_GL_VENDOR: |
| 359 return (const GrGLubyte*)"Debug Vendor"; |
| 360 case GR_GL_RENDERER: |
| 361 return (const GrGLubyte*)"The Debug (Non-)Renderer"; |
| 362 default: |
| 363 SkFAIL("Unexpected name passed to GetString"); |
| 364 return nullptr; |
| 365 } |
| 366 } |
| 367 |
| 368 const GrGLubyte* getStringi(GrGLenum name, GrGLuint i) override { |
| 369 switch (name) { |
| 370 case GR_GL_EXTENSIONS: { |
| 371 GrGLint count; |
| 372 this->getIntegerv(GR_GL_NUM_EXTENSIONS, &count); |
| 373 if ((GrGLint)i <= count) { |
| 374 return (const GrGLubyte*) kExtensions[i]; |
| 375 } else { |
| 376 return nullptr; |
| 377 } |
| 378 } |
| 379 default: |
| 380 SkFAIL("Unexpected name passed to GetStringi"); |
| 381 return nullptr; |
| 382 } |
| 383 } |
| 384 |
| 385 GrGLvoid getTexLevelParameteriv(GrGLenum target, GrGLint level, GrGLenum pna
me, |
| 386 GrGLint* params) override { |
| 387 // we used to use this to query stuff about externally created textures, |
| 388 // now we just require clients to tell us everything about the texture. |
| 389 SkFAIL("Should never query texture parameters."); |
| 390 } |
| 391 |
| 392 GrGLint getUniformLocation(GrGLuint program, const char* name) override { |
| 393 return ++fCurrUniformLocation; |
| 394 } |
| 395 |
| 396 GrGLvoid* mapBufferRange(GrGLenum target, GrGLintptr offset, GrGLsizeiptr le
ngth, |
| 397 GrGLbitfield access) override { |
| 398 GrGLuint id = 0; |
| 399 switch (target) { |
| 400 case GR_GL_ARRAY_BUFFER: |
| 401 id = fCurrArrayBuffer; |
| 402 break; |
| 403 case GR_GL_ELEMENT_ARRAY_BUFFER: |
| 404 id = fCurrElementArrayBuffer; |
| 405 break; |
| 406 case GR_GL_PIXEL_PACK_BUFFER: |
| 407 id = fCurrPixelPackBuffer; |
| 408 break; |
| 409 case GR_GL_PIXEL_UNPACK_BUFFER: |
| 410 id = fCurrPixelUnpackBuffer; |
| 411 break; |
| 412 } |
| 413 |
| 414 if (id > 0) { |
| 415 // We just ignore the offset and length here. |
| 416 BufferObj* buffer = fBufferManager.lookUp(id); |
| 417 SkASSERT(!buffer->mapped()); |
| 418 buffer->setMapped(true); |
| 419 return buffer->dataPtr(); |
| 420 } |
| 421 return nullptr; |
| 422 } |
| 423 |
| 424 GrGLvoid* mapBuffer(GrGLenum target, GrGLenum access) override { |
| 425 GrGLuint id = 0; |
| 426 switch (target) { |
| 427 case GR_GL_ARRAY_BUFFER: |
| 428 id = fCurrArrayBuffer; |
| 429 break; |
| 430 case GR_GL_ELEMENT_ARRAY_BUFFER: |
| 431 id = fCurrElementArrayBuffer; |
| 432 break; |
| 433 case GR_GL_PIXEL_PACK_BUFFER: |
| 434 id = fCurrPixelPackBuffer; |
| 435 break; |
| 436 case GR_GL_PIXEL_UNPACK_BUFFER: |
| 437 id = fCurrPixelUnpackBuffer; |
| 438 break; |
| 439 } |
| 440 |
| 441 if (id > 0) { |
| 442 BufferObj* buffer = fBufferManager.lookUp(id); |
| 443 SkASSERT(!buffer->mapped()); |
| 444 buffer->setMapped(true); |
| 445 return buffer->dataPtr(); |
| 446 } |
| 447 |
| 448 SkASSERT(false); |
| 449 return nullptr; // no buffer bound to target |
| 450 } |
| 451 |
| 452 GrGLboolean unmapBuffer(GrGLenum target) override { |
| 453 GrGLuint id = 0; |
| 454 switch (target) { |
| 455 case GR_GL_ARRAY_BUFFER: |
| 456 id = fCurrArrayBuffer; |
| 457 break; |
| 458 case GR_GL_ELEMENT_ARRAY_BUFFER: |
| 459 id = fCurrElementArrayBuffer; |
| 460 break; |
| 461 case GR_GL_PIXEL_PACK_BUFFER: |
| 462 id = fCurrPixelPackBuffer; |
| 463 break; |
| 464 case GR_GL_PIXEL_UNPACK_BUFFER: |
| 465 id = fCurrPixelUnpackBuffer; |
| 466 break; |
| 467 } |
| 468 if (id > 0) { |
| 469 BufferObj* buffer = fBufferManager.lookUp(id); |
| 470 SkASSERT(buffer->mapped()); |
| 471 buffer->setMapped(false); |
| 472 return GR_GL_TRUE; |
| 473 } |
| 474 |
| 475 GrAlwaysAssert(false); |
| 476 return GR_GL_FALSE; // GR_GL_INVALID_OPERATION; |
| 477 } |
| 478 |
| 479 GrGLvoid getBufferParameteriv(GrGLenum target, GrGLenum pname, GrGLint* para
ms) override { |
| 480 switch (pname) { |
| 481 case GR_GL_BUFFER_MAPPED: { |
| 482 *params = GR_GL_FALSE; |
| 483 GrGLuint id = 0; |
| 484 switch (target) { |
| 485 case GR_GL_ARRAY_BUFFER: |
| 486 id = fCurrArrayBuffer; |
| 487 break; |
| 488 case GR_GL_ELEMENT_ARRAY_BUFFER: |
| 489 id = fCurrElementArrayBuffer; |
| 490 break; |
| 491 case GR_GL_PIXEL_PACK_BUFFER: |
| 492 id = fCurrPixelPackBuffer; |
| 493 break; |
| 494 case GR_GL_PIXEL_UNPACK_BUFFER: |
| 495 id = fCurrPixelUnpackBuffer; |
| 496 break; |
| 497 } |
| 498 if (id > 0) { |
| 499 BufferObj* buffer = fBufferManager.lookUp(id); |
| 500 if (buffer->mapped()) { |
| 501 *params = GR_GL_TRUE; |
| 502 } |
| 503 } |
| 504 break; } |
| 505 default: |
| 506 SkFAIL("Unexpected pname to GetBufferParamateriv"); |
| 507 break; |
| 508 } |
| 509 }; |
| 510 |
| 511 private: |
127 BufferManager fBufferManager; | 512 BufferManager fBufferManager; |
128 GrGLuint fCurrArrayBuffer; | 513 GrGLuint fCurrArrayBuffer; |
129 GrGLuint fCurrElementArrayBuffer; | 514 GrGLuint fCurrElementArrayBuffer; |
| 515 GrGLuint fCurrPixelPackBuffer; |
| 516 GrGLuint fCurrPixelUnpackBuffer; |
130 GrGLuint fCurrProgramID; | 517 GrGLuint fCurrProgramID; |
131 GrGLuint fCurrShaderID; | 518 GrGLuint fCurrShaderID; |
132 | 519 GrGLuint fCurrGenericID; |
133 static ThreadContext* Get() { | 520 GrGLuint fCurrUniformLocation; |
134 return reinterpret_cast<ThreadContext*>(SkTLS::Get(Create, Delete)); | 521 |
135 } | 522 // the OpenGLES 2.0 spec says this must be >= 128 |
136 | 523 static const GrGLint kDefaultMaxVertexUniformVectors = 128; |
137 ThreadContext() | 524 |
138 : fCurrArrayBuffer(0) | 525 // the OpenGLES 2.0 spec says this must be >=16 |
139 , fCurrElementArrayBuffer(0) | 526 static const GrGLint kDefaultMaxFragmentUniformVectors = 16; |
140 , fCurrProgramID(0) | 527 |
141 , fCurrShaderID(0) {} | 528 // the OpenGLES 2.0 spec says this must be >= 8 |
142 | 529 static const GrGLint kDefaultMaxVertexAttribs = 8; |
143 private: | 530 |
144 static void* Create() { return new ThreadContext; } | 531 // the OpenGLES 2.0 spec says this must be >= 8 |
145 static void Delete(void* context) { delete reinterpret_cast<ThreadContext*>(
context); } | 532 static const GrGLint kDefaultMaxVaryingVectors = 8; |
| 533 |
| 534 static const char* kExtensions[]; |
| 535 |
| 536 static const GrGLubyte* CombinedExtensionString() { |
| 537 static SkString gExtString; |
| 538 static SkMutex gMutex; |
| 539 gMutex.acquire(); |
| 540 if (0 == gExtString.size()) { |
| 541 int i = 0; |
| 542 while (kExtensions[i]) { |
| 543 if (i > 0) { |
| 544 gExtString.append(" "); |
| 545 } |
| 546 gExtString.append(kExtensions[i]); |
| 547 ++i; |
| 548 } |
| 549 } |
| 550 gMutex.release(); |
| 551 return (const GrGLubyte*) gExtString.c_str(); |
| 552 } |
| 553 |
| 554 GrGLvoid genGenericIds(GrGLsizei n, GrGLuint* ids) { |
| 555 for (int i = 0; i < n; ++i) { |
| 556 ids[i] = ++fCurrGenericID; |
| 557 } |
| 558 } |
| 559 |
| 560 GrGLvoid getInfoLog(GrGLuint object, GrGLsizei bufsize, GrGLsizei* length, |
| 561 char* infolog) { |
| 562 if (length) { |
| 563 *length = 0; |
| 564 } |
| 565 if (bufsize > 0) { |
| 566 *infolog = 0; |
| 567 } |
| 568 } |
| 569 |
| 570 GrGLvoid getShaderOrProgramiv(GrGLuint object, GrGLenum pname, GrGLint* par
ams) { |
| 571 switch (pname) { |
| 572 case GR_GL_LINK_STATUS: // fallthru |
| 573 case GR_GL_COMPILE_STATUS: |
| 574 *params = GR_GL_TRUE; |
| 575 break; |
| 576 case GR_GL_INFO_LOG_LENGTH: |
| 577 *params = 0; |
| 578 break; |
| 579 // we don't expect any other pnames |
| 580 default: |
| 581 SkFAIL("Unexpected pname to GetProgramiv"); |
| 582 break; |
| 583 } |
| 584 } |
| 585 |
| 586 template <typename T> |
| 587 void queryResult(GrGLenum GLtarget, GrGLenum pname, T *params) { |
| 588 switch (pname) { |
| 589 case GR_GL_QUERY_RESULT_AVAILABLE: |
| 590 *params = GR_GL_TRUE; |
| 591 break; |
| 592 case GR_GL_QUERY_RESULT: |
| 593 *params = 0; |
| 594 break; |
| 595 default: |
| 596 SkFAIL("Unexpected pname passed to GetQueryObject."); |
| 597 break; |
| 598 } |
| 599 } |
146 }; | 600 }; |
147 | 601 |
148 // Functions not declared in GrGLBogusInterface.h (not common with the Debug GL
interface). | 602 const char* NullInterface::kExtensions[] = { |
149 | 603 "GL_ARB_framebuffer_object", |
150 GrGLvoid GR_GL_FUNCTION_TYPE nullGLActiveTexture(GrGLenum texture) {} | 604 "GL_ARB_blend_func_extended", |
151 GrGLvoid GR_GL_FUNCTION_TYPE nullGLAttachShader(GrGLuint program, GrGLuint shade
r) {} | 605 "GL_ARB_timer_query", |
152 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBeginQuery(GrGLenum target, GrGLuint id) {} | 606 "GL_ARB_draw_buffers", |
153 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindAttribLocation(GrGLuint program, GrGLuint
index, const char* name) {} | 607 "GL_ARB_occlusion_query", |
154 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindTexture(GrGLenum target, GrGLuint texture
) {} | 608 "GL_EXT_stencil_wrap", |
155 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindVertexArray(GrGLuint id) {} | 609 nullptr, // signifies the end of the array. |
156 | |
157 GrGLvoid GR_GL_FUNCTION_TYPE nullGLGenBuffers(GrGLsizei n, GrGLuint* ids) { | |
158 ThreadContext* ctx = ThreadContext::Get(); | |
159 for (int i = 0; i < n; ++i) { | |
160 BufferObj* buffer = ctx->fBufferManager.create(); | |
161 ids[i] = buffer->id(); | |
162 } | |
163 } | |
164 | |
165 GrGLvoid GR_GL_FUNCTION_TYPE nullGLGenerateMipmap(GrGLenum target) {} | |
166 | |
167 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBufferData(GrGLenum target, | |
168 GrGLsizeiptr size, | |
169 const GrGLvoid* data, | |
170 GrGLenum usage) { | |
171 ThreadContext* ctx = ThreadContext::Get(); | |
172 GrGLuint id = 0; | |
173 | |
174 switch (target) { | |
175 case GR_GL_ARRAY_BUFFER: | |
176 id = ctx->fCurrArrayBuffer; | |
177 break; | |
178 case GR_GL_ELEMENT_ARRAY_BUFFER: | |
179 id = ctx->fCurrElementArrayBuffer; | |
180 break; | |
181 default: | |
182 SkFAIL("Unexpected target to nullGLBufferData"); | |
183 break; | |
184 } | |
185 | |
186 if (id > 0) { | |
187 BufferObj* buffer = ctx->fBufferManager.lookUp(id); | |
188 buffer->allocate(size, (const GrGLchar*) data); | |
189 } | |
190 } | |
191 | |
192 GrGLvoid GR_GL_FUNCTION_TYPE nullGLPixelStorei(GrGLenum pname, GrGLint param) {} | |
193 GrGLvoid GR_GL_FUNCTION_TYPE nullGLReadPixels(GrGLint x, GrGLint y, GrGLsizei wi
dth, GrGLsizei height, GrGLenum format, GrGLenum type, GrGLvoid* pixels) {} | |
194 GrGLvoid GR_GL_FUNCTION_TYPE nullGLUseProgram(GrGLuint program) {} | |
195 GrGLvoid GR_GL_FUNCTION_TYPE nullGLViewport(GrGLint x, GrGLint y, GrGLsizei widt
h, GrGLsizei height) {} | |
196 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindFramebuffer(GrGLenum target, GrGLuint fra
mebuffer) {} | |
197 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindRenderbuffer(GrGLenum target, GrGLuint re
nderbuffer) {} | |
198 GrGLvoid GR_GL_FUNCTION_TYPE nullGLDeleteFramebuffers(GrGLsizei n, const GrGLuin
t *framebuffers) {} | |
199 GrGLvoid GR_GL_FUNCTION_TYPE nullGLDeleteRenderbuffers(GrGLsizei n, const GrGLui
nt *renderbuffers) {} | |
200 GrGLvoid GR_GL_FUNCTION_TYPE nullGLFramebufferRenderbuffer(GrGLenum target, GrGL
enum attachment, GrGLenum renderbuffertarget, GrGLuint renderbuffer) {} | |
201 GrGLvoid GR_GL_FUNCTION_TYPE nullGLFramebufferTexture2D(GrGLenum target, GrGLenu
m attachment, GrGLenum textarget, GrGLuint texture, GrGLint level) {} | |
202 | |
203 GrGLuint GR_GL_FUNCTION_TYPE nullGLCreateProgram() { | |
204 return ++ThreadContext::Get()->fCurrProgramID; | |
205 } | |
206 | |
207 GrGLuint GR_GL_FUNCTION_TYPE nullGLCreateShader(GrGLenum type) { | |
208 return ++ThreadContext::Get()->fCurrShaderID; | |
209 } | |
210 | |
211 // same delete used for shaders and programs | |
212 GrGLvoid GR_GL_FUNCTION_TYPE nullGLDelete(GrGLuint program) { | |
213 } | |
214 | |
215 GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindBuffer(GrGLenum target, GrGLuint buffer)
{ | |
216 ThreadContext* ctx = ThreadContext::Get(); | |
217 switch (target) { | |
218 case GR_GL_ARRAY_BUFFER: | |
219 ctx->fCurrArrayBuffer = buffer; | |
220 break; | |
221 case GR_GL_ELEMENT_ARRAY_BUFFER: | |
222 ctx->fCurrElementArrayBuffer = buffer; | |
223 break; | |
224 } | |
225 } | |
226 | |
227 // deleting a bound buffer has the side effect of binding 0 | |
228 GrGLvoid GR_GL_FUNCTION_TYPE nullGLDeleteBuffers(GrGLsizei n, const GrGLuint* id
s) { | |
229 ThreadContext* ctx = ThreadContext::Get(); | |
230 for (int i = 0; i < n; ++i) { | |
231 if (ids[i] == ctx->fCurrArrayBuffer) { | |
232 ctx->fCurrArrayBuffer = 0; | |
233 } | |
234 if (ids[i] == ctx->fCurrElementArrayBuffer) { | |
235 ctx->fCurrElementArrayBuffer = 0; | |
236 } | |
237 | |
238 BufferObj* buffer = ctx->fBufferManager.lookUp(ids[i]); | |
239 ctx->fBufferManager.free(buffer); | |
240 } | |
241 } | |
242 | |
243 GrGLvoid* GR_GL_FUNCTION_TYPE nullGLMapBufferRange(GrGLenum target, GrGLintptr o
ffset, | |
244 GrGLsizeiptr length, GrGLbitf
ield access) { | |
245 ThreadContext* ctx = ThreadContext::Get(); | |
246 GrGLuint id = 0; | |
247 switch (target) { | |
248 case GR_GL_ARRAY_BUFFER: | |
249 id = ctx->fCurrArrayBuffer; | |
250 break; | |
251 case GR_GL_ELEMENT_ARRAY_BUFFER: | |
252 id = ctx->fCurrElementArrayBuffer; | |
253 break; | |
254 } | |
255 | |
256 if (id > 0) { | |
257 // We just ignore the offset and length here. | |
258 BufferObj* buffer = ctx->fBufferManager.lookUp(id); | |
259 SkASSERT(!buffer->mapped()); | |
260 buffer->setMapped(true); | |
261 return buffer->dataPtr(); | |
262 } | |
263 return nullptr; | |
264 } | |
265 | |
266 GrGLvoid* GR_GL_FUNCTION_TYPE nullGLMapBuffer(GrGLenum target, GrGLenum access)
{ | |
267 ThreadContext* ctx = ThreadContext::Get(); | |
268 GrGLuint id = 0; | |
269 switch (target) { | |
270 case GR_GL_ARRAY_BUFFER: | |
271 id = ctx->fCurrArrayBuffer; | |
272 break; | |
273 case GR_GL_ELEMENT_ARRAY_BUFFER: | |
274 id = ctx->fCurrElementArrayBuffer; | |
275 break; | |
276 } | |
277 | |
278 if (id > 0) { | |
279 BufferObj* buffer = ctx->fBufferManager.lookUp(id); | |
280 SkASSERT(!buffer->mapped()); | |
281 buffer->setMapped(true); | |
282 return buffer->dataPtr(); | |
283 } | |
284 | |
285 SkASSERT(false); | |
286 return nullptr; // no buffer bound to target | |
287 } | |
288 | |
289 GrGLvoid GR_GL_FUNCTION_TYPE nullGLFlushMappedBufferRange(GrGLenum target, | |
290 GrGLintptr offset, | |
291 GrGLsizeiptr length) {
} | |
292 | |
293 | |
294 GrGLboolean GR_GL_FUNCTION_TYPE nullGLUnmapBuffer(GrGLenum target) { | |
295 ThreadContext* ctx = ThreadContext::Get(); | |
296 GrGLuint id = 0; | |
297 switch (target) { | |
298 case GR_GL_ARRAY_BUFFER: | |
299 id = ctx->fCurrArrayBuffer; | |
300 break; | |
301 case GR_GL_ELEMENT_ARRAY_BUFFER: | |
302 id = ctx->fCurrElementArrayBuffer; | |
303 break; | |
304 } | |
305 if (id > 0) { | |
306 BufferObj* buffer = ctx->fBufferManager.lookUp(id); | |
307 SkASSERT(buffer->mapped()); | |
308 buffer->setMapped(false); | |
309 return GR_GL_TRUE; | |
310 } | |
311 | |
312 GrAlwaysAssert(false); | |
313 return GR_GL_FALSE; // GR_GL_INVALID_OPERATION; | |
314 } | |
315 | |
316 GrGLvoid GR_GL_FUNCTION_TYPE nullGLGetBufferParameteriv(GrGLenum target, GrGLenu
m pname, GrGLint* params) { | |
317 ThreadContext* ctx = ThreadContext::Get(); | |
318 switch (pname) { | |
319 case GR_GL_BUFFER_MAPPED: { | |
320 *params = GR_GL_FALSE; | |
321 GrGLuint id = 0; | |
322 switch (target) { | |
323 case GR_GL_ARRAY_BUFFER: | |
324 id = ctx->fCurrArrayBuffer; | |
325 break; | |
326 case GR_GL_ELEMENT_ARRAY_BUFFER: | |
327 id = ctx->fCurrElementArrayBuffer; | |
328 break; | |
329 } | |
330 if (id > 0) { | |
331 BufferObj* buffer = ctx->fBufferManager.lookUp(id); | |
332 if (buffer->mapped()) { | |
333 *params = GR_GL_TRUE; | |
334 } | |
335 } | |
336 break; } | |
337 default: | |
338 SkFAIL("Unexpected pname to GetBufferParamateriv"); | |
339 break; | |
340 } | |
341 }; | 610 }; |
342 | 611 |
343 } // end anonymous namespace | 612 } // anonymous namespace |
344 | 613 |
345 const GrGLInterface* GrGLCreateNullInterface() { | 614 const GrGLInterface* GrGLCreateNullInterface() { return new NullInterface; } |
346 GrGLInterface* interface = new GrGLInterface; | |
347 | |
348 interface->fStandard = kGL_GrGLStandard; | |
349 | |
350 GrGLInterface::Functions* functions = &interface->fFunctions; | |
351 functions->fActiveTexture = nullGLActiveTexture; | |
352 functions->fAttachShader = nullGLAttachShader; | |
353 functions->fBeginQuery = nullGLBeginQuery; | |
354 functions->fBindAttribLocation = nullGLBindAttribLocation; | |
355 functions->fBindBuffer = nullGLBindBuffer; | |
356 functions->fBindFragDataLocation = noOpGLBindFragDataLocation; | |
357 functions->fBindTexture = nullGLBindTexture; | |
358 functions->fBindVertexArray = nullGLBindVertexArray; | |
359 functions->fBlendColor = noOpGLBlendColor; | |
360 functions->fBlendEquation = noOpGLBlendEquation; | |
361 functions->fBlendFunc = noOpGLBlendFunc; | |
362 functions->fBufferData = nullGLBufferData; | |
363 functions->fBufferSubData = noOpGLBufferSubData; | |
364 functions->fClear = noOpGLClear; | |
365 functions->fClearColor = noOpGLClearColor; | |
366 functions->fClearStencil = noOpGLClearStencil; | |
367 functions->fColorMask = noOpGLColorMask; | |
368 functions->fCompileShader = noOpGLCompileShader; | |
369 functions->fCompressedTexImage2D = noOpGLCompressedTexImage2D; | |
370 functions->fCompressedTexSubImage2D = noOpGLCompressedTexSubImage2D; | |
371 functions->fCopyTexSubImage2D = noOpGLCopyTexSubImage2D; | |
372 functions->fCreateProgram = nullGLCreateProgram; | |
373 functions->fCreateShader = nullGLCreateShader; | |
374 functions->fCullFace = noOpGLCullFace; | |
375 functions->fDeleteBuffers = nullGLDeleteBuffers; | |
376 functions->fDeleteProgram = nullGLDelete; | |
377 functions->fDeleteQueries = noOpGLDeleteIds; | |
378 functions->fDeleteShader = nullGLDelete; | |
379 functions->fDeleteTextures = noOpGLDeleteIds; | |
380 functions->fDeleteVertexArrays = noOpGLDeleteIds; | |
381 functions->fDepthMask = noOpGLDepthMask; | |
382 functions->fDisable = noOpGLDisable; | |
383 functions->fDisableVertexAttribArray = noOpGLDisableVertexAttribArray; | |
384 functions->fDrawArrays = noOpGLDrawArrays; | |
385 functions->fDrawArraysInstanced = noOpGLDrawArraysInstanced; | |
386 functions->fDrawBuffer = noOpGLDrawBuffer; | |
387 functions->fDrawBuffers = noOpGLDrawBuffers; | |
388 functions->fDrawElements = noOpGLDrawElements; | |
389 functions->fDrawElementsInstanced = noOpGLDrawElementsInstanced; | |
390 functions->fEnable = noOpGLEnable; | |
391 functions->fEnableVertexAttribArray = noOpGLEnableVertexAttribArray; | |
392 functions->fEndQuery = noOpGLEndQuery; | |
393 functions->fFinish = noOpGLFinish; | |
394 functions->fFlush = noOpGLFlush; | |
395 functions->fFlushMappedBufferRange = nullGLFlushMappedBufferRange; | |
396 functions->fFrontFace = noOpGLFrontFace; | |
397 functions->fGenBuffers = nullGLGenBuffers; | |
398 functions->fGenerateMipmap = nullGLGenerateMipmap; | |
399 functions->fGenQueries = noOpGLGenIds; | |
400 functions->fGenTextures = noOpGLGenIds; | |
401 functions->fGenVertexArrays = noOpGLGenIds; | |
402 functions->fGetBufferParameteriv = nullGLGetBufferParameteriv; | |
403 functions->fGetError = noOpGLGetError; | |
404 functions->fGetIntegerv = noOpGLGetIntegerv; | |
405 functions->fGetMultisamplefv = noOpGLGetMultisamplefv; | |
406 functions->fGetQueryObjecti64v = noOpGLGetQueryObjecti64v; | |
407 functions->fGetQueryObjectiv = noOpGLGetQueryObjectiv; | |
408 functions->fGetQueryObjectui64v = noOpGLGetQueryObjectui64v; | |
409 functions->fGetQueryObjectuiv = noOpGLGetQueryObjectuiv; | |
410 functions->fGetQueryiv = noOpGLGetQueryiv; | |
411 functions->fGetProgramInfoLog = noOpGLGetInfoLog; | |
412 functions->fGetProgramiv = noOpGLGetShaderOrProgramiv; | |
413 functions->fGetShaderInfoLog = noOpGLGetInfoLog; | |
414 functions->fGetShaderiv = noOpGLGetShaderOrProgramiv; | |
415 functions->fGetString = noOpGLGetString; | |
416 functions->fGetStringi = noOpGLGetStringi; | |
417 functions->fGetTexLevelParameteriv = noOpGLGetTexLevelParameteriv; | |
418 functions->fGetUniformLocation = noOpGLGetUniformLocation; | |
419 functions->fInsertEventMarker = noOpGLInsertEventMarker; | |
420 functions->fLineWidth = noOpGLLineWidth; | |
421 functions->fLinkProgram = noOpGLLinkProgram; | |
422 functions->fMapBuffer = nullGLMapBuffer; | |
423 functions->fMapBufferRange = nullGLMapBufferRange; | |
424 functions->fPixelStorei = nullGLPixelStorei; | |
425 functions->fPopGroupMarker = noOpGLPopGroupMarker; | |
426 functions->fPushGroupMarker = noOpGLPushGroupMarker; | |
427 functions->fQueryCounter = noOpGLQueryCounter; | |
428 functions->fReadBuffer = noOpGLReadBuffer; | |
429 functions->fReadPixels = nullGLReadPixels; | |
430 functions->fScissor = noOpGLScissor; | |
431 functions->fShaderSource = noOpGLShaderSource; | |
432 functions->fStencilFunc = noOpGLStencilFunc; | |
433 functions->fStencilFuncSeparate = noOpGLStencilFuncSeparate; | |
434 functions->fStencilMask = noOpGLStencilMask; | |
435 functions->fStencilMaskSeparate = noOpGLStencilMaskSeparate; | |
436 functions->fStencilOp = noOpGLStencilOp; | |
437 functions->fStencilOpSeparate = noOpGLStencilOpSeparate; | |
438 functions->fTexBuffer = noOpGLTexBuffer; | |
439 functions->fTexImage2D = noOpGLTexImage2D; | |
440 functions->fTexParameteri = noOpGLTexParameteri; | |
441 functions->fTexParameteriv = noOpGLTexParameteriv; | |
442 functions->fTexSubImage2D = noOpGLTexSubImage2D; | |
443 functions->fTexStorage2D = noOpGLTexStorage2D; | |
444 functions->fDiscardFramebuffer = noOpGLDiscardFramebuffer; | |
445 functions->fUniform1f = noOpGLUniform1f; | |
446 functions->fUniform1i = noOpGLUniform1i; | |
447 functions->fUniform1fv = noOpGLUniform1fv; | |
448 functions->fUniform1iv = noOpGLUniform1iv; | |
449 functions->fUniform2f = noOpGLUniform2f; | |
450 functions->fUniform2i = noOpGLUniform2i; | |
451 functions->fUniform2fv = noOpGLUniform2fv; | |
452 functions->fUniform2iv = noOpGLUniform2iv; | |
453 functions->fUniform3f = noOpGLUniform3f; | |
454 functions->fUniform3i = noOpGLUniform3i; | |
455 functions->fUniform3fv = noOpGLUniform3fv; | |
456 functions->fUniform3iv = noOpGLUniform3iv; | |
457 functions->fUniform4f = noOpGLUniform4f; | |
458 functions->fUniform4i = noOpGLUniform4i; | |
459 functions->fUniform4fv = noOpGLUniform4fv; | |
460 functions->fUniform4iv = noOpGLUniform4iv; | |
461 functions->fUniformMatrix2fv = noOpGLUniformMatrix2fv; | |
462 functions->fUniformMatrix3fv = noOpGLUniformMatrix3fv; | |
463 functions->fUniformMatrix4fv = noOpGLUniformMatrix4fv; | |
464 functions->fUnmapBuffer = nullGLUnmapBuffer; | |
465 functions->fUseProgram = nullGLUseProgram; | |
466 functions->fVertexAttrib1f = noOpGLVertexAttrib1f; | |
467 functions->fVertexAttrib2fv = noOpGLVertexAttrib2fv; | |
468 functions->fVertexAttrib3fv = noOpGLVertexAttrib3fv; | |
469 functions->fVertexAttrib4fv = noOpGLVertexAttrib4fv; | |
470 functions->fVertexAttribDivisor = noOpGLVertexAttribDivisor; | |
471 functions->fVertexAttribIPointer = noOpGLVertexAttribIPointer; | |
472 functions->fVertexAttribPointer = noOpGLVertexAttribPointer; | |
473 functions->fViewport = nullGLViewport; | |
474 functions->fBindFramebuffer = nullGLBindFramebuffer; | |
475 functions->fBindRenderbuffer = nullGLBindRenderbuffer; | |
476 functions->fCheckFramebufferStatus = noOpGLCheckFramebufferStatus; | |
477 functions->fDeleteFramebuffers = nullGLDeleteFramebuffers; | |
478 functions->fDeleteRenderbuffers = nullGLDeleteRenderbuffers; | |
479 functions->fFramebufferRenderbuffer = nullGLFramebufferRenderbuffer; | |
480 functions->fFramebufferTexture2D = nullGLFramebufferTexture2D; | |
481 functions->fGenFramebuffers = noOpGLGenIds; | |
482 functions->fGenRenderbuffers = noOpGLGenIds; | |
483 functions->fGetFramebufferAttachmentParameteriv = noOpGLGetFramebufferAttach
mentParameteriv; | |
484 functions->fGetRenderbufferParameteriv = noOpGLGetRenderbufferParameteriv; | |
485 functions->fRenderbufferStorage = noOpGLRenderbufferStorage; | |
486 functions->fRenderbufferStorageMultisample = noOpGLRenderbufferStorageMultis
ample; | |
487 functions->fBlitFramebuffer = noOpGLBlitFramebuffer; | |
488 functions->fResolveMultisampleFramebuffer = noOpGLResolveMultisampleFramebuf
fer; | |
489 functions->fMatrixLoadf = noOpGLMatrixLoadf; | |
490 functions->fMatrixLoadIdentity = noOpGLMatrixLoadIdentity; | |
491 functions->fBindFragDataLocationIndexed = noOpGLBindFragDataLocationIndexed; | |
492 | |
493 interface->fExtensions.init(kGL_GrGLStandard, functions->fGetString, functio
ns->fGetStringi, | |
494 functions->fGetIntegerv, nullptr, GR_EGL_NO_DISP
LAY); | |
495 return interface; | |
496 } | |
OLD | NEW |