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 #include "GrGLTestInterface.h" 9 #include "GrNonAtomicRef.h" 10 #include "SkMutex.h" 11 #include "SkTDArray.h" 12 #include "SkTo.h" 13 #include "gl/GrGLInterface.h" 14 15 #include <type_traits> 16 17 // added to suppress 'no previous prototype' warning and because this code is duplicated in 18 // SkNullGLContext.cpp 19 namespace { 20 21 class GLObject : public GrNonAtomicRef<GLObject> { 22 public: 23 GLObject(GrGLuint id) : fID(id) {} 24 virtual ~GLObject() {} 25 26 GrGLuint id() const { return fID; } 27 28 private: 29 GrGLuint fID; 30 }; 31 32 // This class maintains a sparsely populated array of object pointers. 33 template<typename T> class TGLObjectManager { 34 static_assert(std::is_convertible<T*, GLObject*>::value, "T must be a subclass of GLObject"); 35 36 public: 37 TGLObjectManager() : fFreeListHead(kFreeListEnd) { 38 *fGLObjects.append() = nullptr; // 0 is not a valid GL object id. 39 } 40 41 ~TGLObjectManager() { 42 // nullptr out the entries that are really free list links rather than ptrs before deleting. 43 intptr_t curr = fFreeListHead; 44 while (kFreeListEnd != curr) { 45 intptr_t next = reinterpret_cast<intptr_t>(fGLObjects[SkToS32(curr)]); 46 fGLObjects[SkToS32(curr)] = nullptr; 47 curr = next; 48 } 49 50 fGLObjects.safeUnrefAll(); 51 } 52 53 T* lookUp(GrGLuint id) { 54 T* object = fGLObjects[id]; 55 SkASSERT(object && object->id() == id); 56 return object; 57 } 58 59 T* create() { 60 GrGLuint id; 61 T* object; 62 63 if (kFreeListEnd == fFreeListHead) { 64 // no free slots - create a new one 65 id = fGLObjects.count(); 66 object = new T(id); 67 *fGLObjects.append() = object; 68 } else { 69 // grab the head of the free list and advance the head to the next free slot. 70 id = static_cast<GrGLuint>(fFreeListHead); 71 fFreeListHead = reinterpret_cast<intptr_t>(fGLObjects[id]); 72 73 object = new T(id); 74 fGLObjects[id] = object; 75 } 76 77 return object; 78 } 79 80 void free(T* object) { 81 SkASSERT(object); 82 SkASSERT(fGLObjects.count() > 0); 83 84 GrGLuint id = object->id(); 85 object->unref(); 86 87 fGLObjects[id] = reinterpret_cast<T*>(fFreeListHead); 88 fFreeListHead = id; 89 } 90 91 private: 92 static const intptr_t kFreeListEnd = -1; 93 // Index of the first entry of fGLObjects in the free list. Free slots in fGLObjects are indices 94 // to the next free slot. The last free slot has a value of kFreeListEnd. 95 intptr_t fFreeListHead; 96 SkTDArray<T*> fGLObjects; 97 }; 98 99 class Buffer : public GLObject { 100 public: 101 Buffer(GrGLuint id) : INHERITED(id), fDataPtr(nullptr), fSize(0), fMapped(false) {} 102 ~Buffer() { delete[] fDataPtr; } 103 104 void allocate(GrGLsizeiptr size, const GrGLchar* dataPtr) { 105 if (fDataPtr) { 106 SkASSERT(0 != fSize); 107 delete[] fDataPtr; 108 } 109 110 fSize = size; 111 fDataPtr = new char[size]; 112 } 113 114 GrGLchar* dataPtr() { return fDataPtr; } 115 GrGLsizeiptr size() const { return fSize; } 116 117 void setMapped(bool mapped) { fMapped = mapped; } 118 bool mapped() const { return fMapped; } 119 120 private: 121 GrGLchar* fDataPtr; 122 GrGLsizeiptr fSize; // size in bytes 123 bool fMapped; 124 125 typedef GLObject INHERITED; 126 }; 127 128 class FramebufferAttachment : public GLObject { 129 public: 130 int numSamples() const { return fNumSamples; } 131 132 protected: 133 FramebufferAttachment(int id) : INHERITED(id), fNumSamples(1) {} 134 135 int fNumSamples; 136 137 typedef GLObject INHERITED; 138 }; 139 140 class Renderbuffer : public FramebufferAttachment { 141 public: 142 Renderbuffer(int id) : INHERITED(id) {} 143 void setNumSamples(int numSamples) { fNumSamples = numSamples; } 144 145 private: 146 typedef FramebufferAttachment INHERITED; 147 }; 148 149 class Texture : public FramebufferAttachment { 150 public: 151 Texture() : INHERITED(1) {} 152 153 private: 154 typedef FramebufferAttachment INHERITED; 155 }; 156 157 class Framebuffer : public GLObject { 158 public: 159 Framebuffer(int id) : INHERITED(id) {} 160 161 void setAttachment(GrGLenum attachmentPoint, const FramebufferAttachment* attachment) { 162 switch (attachmentPoint) { 163 default: 164 SK_ABORT("Invalid framebuffer attachment."); 165 break; 166 case GR_GL_STENCIL_ATTACHMENT: 167 fAttachments[(int)AttachmentPoint::kStencil].reset(SkRef(attachment)); 168 break; 169 case GR_GL_DEPTH_ATTACHMENT: 170 fAttachments[(int)AttachmentPoint::kDepth].reset(SkRef(attachment)); 171 break; 172 case GR_GL_COLOR_ATTACHMENT0: 173 fAttachments[(int)AttachmentPoint::kColor].reset(SkRef(attachment)); 174 break; 175 } 176 } 177 178 void notifyAttachmentDeleteWhileBound(const FramebufferAttachment* deleted) { 179 for (auto& attachment : fAttachments) { 180 if (attachment.get() == deleted) { 181 attachment.reset(nullptr); 182 } 183 } 184 } 185 186 int numSamples() const { 187 int numSamples = 0; 188 for (auto& attachment : fAttachments) { 189 if (!attachment) { 190 continue; 191 } 192 if (numSamples) { 193 GrAlwaysAssert(attachment->numSamples() == numSamples); 194 continue; 195 } 196 numSamples = attachment->numSamples(); 197 } 198 GrAlwaysAssert(numSamples); 199 return numSamples; 200 } 201 202 private: 203 enum AttachmentPoint { 204 kStencil, 205 kDepth, 206 kColor 207 }; 208 constexpr int static kNumAttachmentPoints = 1 + (int)AttachmentPoint::kColor; 209 210 sk_sp<const FramebufferAttachment> fAttachments[kNumAttachmentPoints]; 211 212 typedef GLObject INHERITED; 213 }; 214 215 /** Null interface implementation */ 216 class NullInterface : public GrGLTestInterface { 217 public: 218 NullInterface(bool enableNVPR) 219 : fCurrDrawFramebuffer(0) 220 , fCurrReadFramebuffer(0) 221 , fCurrRenderbuffer(0) 222 , fCurrProgramID(0) 223 , fCurrShaderID(0) 224 , fCurrGenericID(0) 225 , fCurrUniformLocation(0) 226 , fCurrPathID(0) { 227 memset(fBoundBuffers, 0, sizeof(fBoundBuffers)); 228 fAdvertisedExtensions.push_back("GL_ARB_framebuffer_object"); 229 fAdvertisedExtensions.push_back("GL_ARB_blend_func_extended"); 230 fAdvertisedExtensions.push_back("GL_ARB_timer_query"); 231 fAdvertisedExtensions.push_back("GL_ARB_draw_buffers"); 232 fAdvertisedExtensions.push_back("GL_ARB_occlusion_query"); 233 fAdvertisedExtensions.push_back("GL_EXT_stencil_wrap"); 234 if (enableNVPR) { 235 fAdvertisedExtensions.push_back("GL_NV_path_rendering"); 236 fAdvertisedExtensions.push_back("GL_ARB_program_interface_query"); 237 } 238 fAdvertisedExtensions.push_back(nullptr); 239 240 this->init(kGL_GrGLStandard); 241 } 242 243 GrGLenum checkFramebufferStatus(GrGLenum target) override { 244 return GR_GL_FRAMEBUFFER_COMPLETE; 245 } 246 247 GrGLvoid genBuffers(GrGLsizei n, GrGLuint* ids) override { 248 for (int i = 0; i < n; ++i) { 249 Buffer* buffer = fBufferManager.create(); 250 ids[i] = buffer->id(); 251 } 252 } 253 254 GrGLvoid bufferData(GrGLenum target, GrGLsizeiptr size, const GrGLvoid* data, 255 GrGLenum usage) override { 256 GrGLuint id = fBoundBuffers[GetBufferIndex(target)]; 257 if (id > 0) { 258 Buffer* buffer = fBufferManager.lookUp(id); 259 buffer->allocate(size, (const GrGLchar*) data); 260 } 261 } 262 263 GrGLuint createProgram() override { 264 return ++fCurrProgramID; 265 } 266 267 GrGLuint createShader(GrGLenum type) override { 268 return ++fCurrShaderID; 269 } 270 271 GrGLvoid bindBuffer(GrGLenum target, GrGLuint buffer) override { 272 fBoundBuffers[GetBufferIndex(target)] = buffer; 273 } 274 275 // deleting a bound buffer has the side effect of binding 0 276 GrGLvoid deleteBuffers(GrGLsizei n, const GrGLuint* ids) override { 277 // First potentially unbind the buffers. 278 for (int buffIdx = 0; buffIdx < kNumBufferTargets; ++buffIdx) { 279 if (!fBoundBuffers[buffIdx]) { 280 continue; 281 } 282 for (int i = 0; i < n; ++i) { 283 if (ids[i] == fBoundBuffers[buffIdx]) { 284 fBoundBuffers[buffIdx] = 0; 285 break; 286 } 287 } 288 } 289 290 // Then actually "delete" the buffers. 291 for (int i = 0; i < n; ++i) { 292 if (ids[i] > 0) { 293 Buffer* buffer = fBufferManager.lookUp(ids[i]); 294 fBufferManager.free(buffer); 295 } 296 } 297 } 298 299 GrGLvoid genFramebuffers(GrGLsizei n, GrGLuint *framebuffers) override { 300 for (int i = 0; i < n; ++i) { 301 Framebuffer* framebuffer = fFramebufferManager.create(); 302 framebuffers[i] = framebuffer->id(); 303 } 304 } 305 306 GrGLvoid bindFramebuffer(GrGLenum target, GrGLuint framebuffer) override { 307 SkASSERT(GR_GL_FRAMEBUFFER == target || GR_GL_DRAW_FRAMEBUFFER == target || 308 GR_GL_READ_FRAMEBUFFER == target); 309 if (GR_GL_READ_FRAMEBUFFER != target) { 310 fCurrDrawFramebuffer = framebuffer; 311 } 312 if (GR_GL_DRAW_FRAMEBUFFER != target) { 313 fCurrReadFramebuffer = framebuffer; 314 } 315 } 316 317 GrGLvoid deleteFramebuffers(GrGLsizei n, const GrGLuint* ids) override { 318 for (int i = 0; i < n; ++i) { 319 if (ids[i] == fCurrDrawFramebuffer) { 320 fCurrDrawFramebuffer = 0; 321 } 322 if (ids[i] == fCurrReadFramebuffer) { 323 fCurrReadFramebuffer = 0; 324 } 325 326 if (ids[i] > 0) { 327 Framebuffer* framebuffer = fFramebufferManager.lookUp(ids[i]); 328 fFramebufferManager.free(framebuffer); 329 } 330 } 331 } 332 333 GrGLvoid genQueries(GrGLsizei n, GrGLuint *ids) override { this->genGenericIds(n, ids); } 334 335 GrGLvoid genRenderbuffers(GrGLsizei n, GrGLuint *renderbuffers) override { 336 for (int i = 0; i < n; ++i) { 337 Renderbuffer* renderbuffer = fRenderbufferManager.create(); 338 renderbuffers[i] = renderbuffer->id(); 339 } 340 } 341 342 GrGLvoid bindRenderbuffer(GrGLenum target, GrGLuint renderbuffer) override { 343 SkASSERT(GR_GL_RENDERBUFFER == target); 344 fCurrRenderbuffer = renderbuffer; 345 } 346 347 GrGLvoid deleteRenderbuffers(GrGLsizei n, const GrGLuint* ids) override { 348 for (int i = 0; i < n; ++i) { 349 if (ids[i] <= 0) { 350 continue; 351 } 352 if (ids[i] == fCurrRenderbuffer) { 353 fCurrRenderbuffer = 0; 354 } 355 Renderbuffer* renderbuffer = fRenderbufferManager.lookUp(ids[i]); 356 357 if (fCurrDrawFramebuffer) { 358 Framebuffer* drawFramebuffer = fFramebufferManager.lookUp(fCurrDrawFramebuffer); 359 drawFramebuffer->notifyAttachmentDeleteWhileBound(renderbuffer); 360 } 361 if (fCurrReadFramebuffer) { 362 Framebuffer* readFramebuffer = fFramebufferManager.lookUp(fCurrReadFramebuffer); 363 readFramebuffer->notifyAttachmentDeleteWhileBound(renderbuffer); 364 } 365 366 fRenderbufferManager.free(renderbuffer); 367 } 368 } 369 370 GrGLvoid renderbufferStorage(GrGLenum target, GrGLenum internalformat, GrGLsizei width, 371 GrGLsizei height) override { 372 GrAlwaysAssert(GR_GL_RENDERBUFFER == target); 373 GrAlwaysAssert(fCurrRenderbuffer); 374 Renderbuffer* renderbuffer = fRenderbufferManager.lookUp(fCurrRenderbuffer); 375 renderbuffer->setNumSamples(1); 376 } 377 378 GrGLvoid renderbufferStorageMultisample(GrGLenum target, GrGLsizei samples, 379 GrGLenum internalformat, GrGLsizei width, 380 GrGLsizei height) override { 381 GrAlwaysAssert(GR_GL_RENDERBUFFER == target); 382 GrAlwaysAssert(samples > 0); 383 GrAlwaysAssert(fCurrRenderbuffer); 384 Renderbuffer* renderbuffer = fRenderbufferManager.lookUp(fCurrRenderbuffer); 385 renderbuffer->setNumSamples(samples); 386 } 387 388 GrGLvoid namedRenderbufferStorage(GrGLuint renderbuffer, GrGLenum GrGLinternalformat, 389 GrGLsizei width, GrGLsizei height) override { 390 SK_ABORT("Not implemented"); 391 } 392 393 GrGLvoid namedRenderbufferStorageMultisample(GrGLuint renderbuffer, GrGLsizei samples, 394 GrGLenum GrGLinternalformat, GrGLsizei width, 395 GrGLsizei height) override { 396 SK_ABORT("Not implemented"); 397 } 398 399 GrGLvoid framebufferRenderbuffer(GrGLenum target, GrGLenum attachment, 400 GrGLenum renderbuffertarget, 401 GrGLuint renderBufferID) override { 402 GrGLuint id = this->getBoundFramebufferID(target); 403 GrAlwaysAssert(id); 404 Framebuffer* framebuffer = fFramebufferManager.lookUp(id); 405 406 GrAlwaysAssert(GR_GL_RENDERBUFFER == renderbuffertarget); 407 if (!renderBufferID && !fCurrRenderbuffer) { 408 return; 409 } 410 GrAlwaysAssert(fCurrRenderbuffer); 411 Renderbuffer* renderbuffer = fRenderbufferManager.lookUp(fCurrRenderbuffer); 412 413 framebuffer->setAttachment(attachment, renderbuffer); 414 } 415 416 GrGLvoid namedFramebufferRenderbuffer(GrGLuint framebuffer, GrGLenum attachment, 417 GrGLenum renderbuffertarget, 418 GrGLuint renderbuffer) override { 419 SK_ABORT("Not implemented"); 420 } 421 422 GrGLvoid genSamplers(GrGLsizei n, GrGLuint* samplers) override { 423 this->genGenericIds(n, samplers); 424 } 425 426 GrGLvoid genTextures(GrGLsizei n, GrGLuint *textures) override { 427 this->genGenericIds(n, textures); 428 } 429 430 GrGLvoid framebufferTexture2D(GrGLenum target, GrGLenum attachment, GrGLenum textarget, 431 GrGLuint textureID, GrGLint level) override { 432 GrGLuint id = this->getBoundFramebufferID(target); 433 GrAlwaysAssert(id); 434 Framebuffer* framebuffer = fFramebufferManager.lookUp(id); 435 framebuffer->setAttachment(attachment, this->getSingleTextureObject()); 436 } 437 438 GrGLvoid framebufferTexture2DMultisample(GrGLenum target, GrGLenum attachment, 439 GrGLenum textarget, GrGLuint texture, GrGLint level, 440 GrGLsizei samples) override { 441 SK_ABORT("Not implemented"); 442 } 443 444 GrGLvoid namedFramebufferTexture1D(GrGLuint framebuffer, GrGLenum attachment, 445 GrGLenum textarget, GrGLuint texture, 446 GrGLint level) override { 447 SK_ABORT("Not implemented"); 448 } 449 450 GrGLvoid namedFramebufferTexture2D(GrGLuint framebuffer, GrGLenum attachment, 451 GrGLenum textarget, GrGLuint texture, 452 GrGLint level) override { 453 SK_ABORT("Not implemented"); 454 } 455 456 GrGLvoid namedFramebufferTexture3D(GrGLuint framebuffer, GrGLenum attachment, 457 GrGLenum textarget, GrGLuint texture, GrGLint level, 458 GrGLint zoffset) override { 459 SK_ABORT("Not implemented"); 460 } 461 462 GrGLvoid genVertexArrays(GrGLsizei n, GrGLuint *arrays) override { 463 this->genGenericIds(n, arrays); 464 } 465 466 GrGLenum getError() override { return GR_GL_NO_ERROR; } 467 468 GrGLvoid getIntegerv(GrGLenum pname, GrGLint* params) override { 469 // TODO: remove from Ganesh the #defines for gets we don't use. 470 // We would like to minimize gets overall due to performance issues 471 switch (pname) { 472 case GR_GL_CONTEXT_PROFILE_MASK: 473 *params = GR_GL_CONTEXT_COMPATIBILITY_PROFILE_BIT; 474 break; 475 case GR_GL_STENCIL_BITS: 476 *params = 8; 477 break; 478 case GR_GL_SAMPLES: { 479 GrAlwaysAssert(fCurrDrawFramebuffer); 480 Framebuffer* framebuffer = fFramebufferManager.lookUp(fCurrDrawFramebuffer); 481 *params = framebuffer->numSamples(); 482 break; 483 } 484 case GR_GL_FRAMEBUFFER_BINDING: 485 *params = 0; 486 break; 487 case GR_GL_VIEWPORT: 488 params[0] = 0; 489 params[1] = 0; 490 params[2] = 800; 491 params[3] = 600; 492 break; 493 case GR_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: 494 case GR_GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS: 495 case GR_GL_MAX_TEXTURE_IMAGE_UNITS: 496 case GR_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: 497 *params = 8; 498 break; 499 case GR_GL_MAX_TEXTURE_COORDS: 500 *params = 8; 501 break; 502 case GR_GL_MAX_VERTEX_UNIFORM_VECTORS: 503 *params = kDefaultMaxVertexUniformVectors; 504 break; 505 case GR_GL_MAX_FRAGMENT_UNIFORM_VECTORS: 506 *params = kDefaultMaxFragmentUniformVectors; 507 break; 508 case GR_GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: 509 *params = 16 * 4; 510 break; 511 case GR_GL_NUM_COMPRESSED_TEXTURE_FORMATS: 512 *params = 0; 513 break; 514 case GR_GL_COMPRESSED_TEXTURE_FORMATS: 515 break; 516 case GR_GL_MAX_TEXTURE_SIZE: 517 *params = 8192; 518 break; 519 case GR_GL_MAX_RENDERBUFFER_SIZE: 520 *params = 8192; 521 break; 522 case GR_GL_MAX_SAMPLES: 523 *params = 32; 524 break; 525 case GR_GL_MAX_VERTEX_ATTRIBS: 526 *params = kDefaultMaxVertexAttribs; 527 break; 528 case GR_GL_MAX_VARYING_VECTORS: 529 *params = kDefaultMaxVaryingVectors; 530 break; 531 case GR_GL_NUM_EXTENSIONS: { 532 GrGLint i = 0; 533 while (fAdvertisedExtensions[i++]); 534 *params = i; 535 break; 536 } 537 default: 538 SK_ABORT("Unexpected pname to GetIntegerv"); 539 } 540 } 541 542 GrGLvoid getProgramiv(GrGLuint program, GrGLenum pname, GrGLint* params) override { 543 this->getShaderOrProgramiv(program, pname, params); 544 } 545 546 GrGLvoid getProgramInfoLog(GrGLuint program, GrGLsizei bufsize, GrGLsizei* length, 547 char* infolog) override { 548 this->getInfoLog(program, bufsize, length, infolog); 549 } 550 551 GrGLvoid getMultisamplefv(GrGLenum pname, GrGLuint index, GrGLfloat* val) override { 552 val[0] = val[1] = 0.5f; 553 } 554 555 GrGLvoid getQueryiv(GrGLenum GLtarget, GrGLenum pname, GrGLint *params) override { 556 switch (pname) { 557 case GR_GL_CURRENT_QUERY: 558 *params = 0; 559 break; 560 case GR_GL_QUERY_COUNTER_BITS: 561 *params = 32; 562 break; 563 default: 564 SK_ABORT("Unexpected pname passed GetQueryiv."); 565 } 566 } 567 568 GrGLvoid getQueryObjecti64v(GrGLuint id, GrGLenum pname, GrGLint64 *params) override { 569 this->queryResult(id, pname, params); 570 } 571 572 GrGLvoid getQueryObjectiv(GrGLuint id, GrGLenum pname, GrGLint *params) override { 573 this->queryResult(id, pname, params); 574 } 575 576 GrGLvoid getQueryObjectui64v(GrGLuint id, GrGLenum pname, GrGLuint64 *params) override { 577 this->queryResult(id, pname, params); 578 } 579 580 GrGLvoid getQueryObjectuiv(GrGLuint id, GrGLenum pname, GrGLuint *params) override { 581 this->queryResult(id, pname, params); 582 } 583 584 GrGLvoid getShaderiv(GrGLuint shader, GrGLenum pname, GrGLint* params) override { 585 this->getShaderOrProgramiv(shader, pname, params); 586 } 587 588 GrGLvoid getShaderInfoLog(GrGLuint shader, GrGLsizei bufsize, GrGLsizei* length, 589 char* infolog) override { 590 this->getInfoLog(shader, bufsize, length, infolog); 591 } 592 593 const GrGLubyte* getString(GrGLenum name) override { 594 switch (name) { 595 case GR_GL_EXTENSIONS: 596 return CombinedExtensionString(); 597 case GR_GL_VERSION: 598 return (const GrGLubyte*)"4.0 Null GL"; 599 case GR_GL_SHADING_LANGUAGE_VERSION: 600 return (const GrGLubyte*)"4.20.8 Null GLSL"; 601 case GR_GL_VENDOR: 602 return (const GrGLubyte*)"Null Vendor"; 603 case GR_GL_RENDERER: 604 return (const GrGLubyte*)"The Null (Non-)Renderer"; 605 default: 606 SK_ABORT("Unexpected name passed to GetString"); 607 return nullptr; 608 } 609 } 610 611 const GrGLubyte* getStringi(GrGLenum name, GrGLuint i) override { 612 switch (name) { 613 case GR_GL_EXTENSIONS: { 614 GrGLint count; 615 this->getIntegerv(GR_GL_NUM_EXTENSIONS, &count); 616 if ((GrGLint)i <= count) { 617 return (const GrGLubyte*) fAdvertisedExtensions[i]; 618 } else { 619 return nullptr; 620 } 621 } 622 default: 623 SK_ABORT("Unexpected name passed to GetStringi"); 624 return nullptr; 625 } 626 } 627 628 GrGLint getUniformLocation(GrGLuint program, const char* name) override { 629 return ++fCurrUniformLocation; 630 } 631 632 GrGLvoid* mapBufferRange(GrGLenum target, GrGLintptr offset, GrGLsizeiptr length, 633 GrGLbitfield access) override { 634 GrGLuint id = fBoundBuffers[GetBufferIndex(target)]; 635 if (id > 0) { 636 // We just ignore the offset and length here. 637 Buffer* buffer = fBufferManager.lookUp(id); 638 SkASSERT(!buffer->mapped()); 639 buffer->setMapped(true); 640 return buffer->dataPtr(); 641 } 642 return nullptr; 643 } 644 645 GrGLvoid* mapBuffer(GrGLenum target, GrGLenum access) override { 646 GrGLuint id = fBoundBuffers[GetBufferIndex(target)]; 647 if (id > 0) { 648 Buffer* buffer = fBufferManager.lookUp(id); 649 SkASSERT(!buffer->mapped()); 650 buffer->setMapped(true); 651 return buffer->dataPtr(); 652 } 653 654 SkASSERT(false); 655 return nullptr; // no buffer bound to target 656 } 657 658 GrGLboolean unmapBuffer(GrGLenum target) override { 659 GrGLuint id = fBoundBuffers[GetBufferIndex(target)]; 660 if (id > 0) { 661 Buffer* buffer = fBufferManager.lookUp(id); 662 SkASSERT(buffer->mapped()); 663 buffer->setMapped(false); 664 return GR_GL_TRUE; 665 } 666 667 GrAlwaysAssert(false); 668 return GR_GL_FALSE; // GR_GL_INVALID_OPERATION; 669 } 670 671 GrGLvoid getBufferParameteriv(GrGLenum target, GrGLenum pname, GrGLint* params) override { 672 switch (pname) { 673 case GR_GL_BUFFER_MAPPED: { 674 *params = GR_GL_FALSE; 675 GrGLuint id = fBoundBuffers[GetBufferIndex(target)]; 676 if (id > 0) { 677 Buffer* buffer = fBufferManager.lookUp(id); 678 if (buffer->mapped()) { 679 *params = GR_GL_TRUE; 680 } 681 } 682 break; } 683 default: 684 SK_ABORT("Unexpected pname to GetBufferParamateriv"); 685 break; 686 } 687 } 688 689 // NV_path_rendering 690 GrGLuint genPaths(GrGLsizei range) override { 691 return ++fCurrPathID; 692 } 693 694 695 private: 696 inline int static GetBufferIndex(GrGLenum glTarget) { 697 switch (glTarget) { 698 default: SK_ABORT("Unexpected GL target to GetBufferIndex"); 699 case GR_GL_ARRAY_BUFFER: return 0; 700 case GR_GL_ELEMENT_ARRAY_BUFFER: return 1; 701 case GR_GL_TEXTURE_BUFFER: return 2; 702 case GR_GL_DRAW_INDIRECT_BUFFER: return 3; 703 case GR_GL_PIXEL_PACK_BUFFER: return 4; 704 case GR_GL_PIXEL_UNPACK_BUFFER: return 5; 705 } 706 } 707 constexpr int static kNumBufferTargets = 6; 708 709 TGLObjectManager<Buffer> fBufferManager; 710 GrGLuint fBoundBuffers[kNumBufferTargets]; 711 TGLObjectManager<Framebuffer> fFramebufferManager; 712 GrGLuint fCurrDrawFramebuffer; 713 GrGLuint fCurrReadFramebuffer; 714 TGLObjectManager<Renderbuffer> fRenderbufferManager; 715 GrGLuint fCurrRenderbuffer; 716 GrGLuint fCurrProgramID; 717 GrGLuint fCurrShaderID; 718 GrGLuint fCurrGenericID; 719 GrGLuint fCurrUniformLocation; 720 GrGLuint fCurrPathID; 721 sk_sp<const Texture> fSingleTextureObject; 722 SkTArray<const char*> fAdvertisedExtensions; 723 724 // the OpenGLES 2.0 spec says this must be >= 128 725 static const GrGLint kDefaultMaxVertexUniformVectors = 128; 726 727 // the OpenGLES 2.0 spec says this must be >=16 728 static const GrGLint kDefaultMaxFragmentUniformVectors = 16; 729 730 // the OpenGLES 2.0 spec says this must be >= 8 731 static const GrGLint kDefaultMaxVertexAttribs = 8; 732 733 // the OpenGLES 2.0 spec says this must be >= 8 734 static const GrGLint kDefaultMaxVaryingVectors = 8; 735 736 GrGLuint getBoundFramebufferID(GrGLenum target) { 737 switch (target) { 738 case GR_GL_FRAMEBUFFER: 739 case GR_GL_DRAW_FRAMEBUFFER: 740 return fCurrDrawFramebuffer; 741 case GR_GL_READ_FRAMEBUFFER: 742 return fCurrReadFramebuffer; 743 default: 744 SK_ABORT("Invalid framebuffer target."); 745 return 0; 746 } 747 } 748 749 const Texture* getSingleTextureObject() { 750 // We currently only use FramebufferAttachment objects for a sample count, and all textures 751 // in Skia have one sample, so there is no need as of yet to track individual textures. This 752 // also works around a bug in chromium's cc_unittests where they send us texture IDs that 753 // were generated by cc::TestGLES2Interface. 754 if (!fSingleTextureObject) { 755 fSingleTextureObject.reset(new Texture); 756 } 757 return fSingleTextureObject.get(); 758 } 759 760 const GrGLubyte* CombinedExtensionString() { 761 static SkString gExtString; 762 static SkMutex gMutex; 763 gMutex.acquire(); 764 if (0 == gExtString.size()) { 765 int i = 0; 766 while (fAdvertisedExtensions[i]) { 767 if (i > 0) { 768 gExtString.append(" "); 769 } 770 gExtString.append(fAdvertisedExtensions[i]); 771 ++i; 772 } 773 } 774 gMutex.release(); 775 return (const GrGLubyte*) gExtString.c_str(); 776 } 777 778 GrGLvoid genGenericIds(GrGLsizei n, GrGLuint* ids) { 779 for (int i = 0; i < n; ++i) { 780 ids[i] = ++fCurrGenericID; 781 } 782 } 783 784 GrGLvoid getInfoLog(GrGLuint object, GrGLsizei bufsize, GrGLsizei* length, 785 char* infolog) { 786 if (length) { 787 *length = 0; 788 } 789 if (bufsize > 0) { 790 *infolog = 0; 791 } 792 } 793 794 GrGLvoid getShaderOrProgramiv(GrGLuint object, GrGLenum pname, GrGLint* params) { 795 switch (pname) { 796 case GR_GL_LINK_STATUS: // fallthru 797 case GR_GL_COMPILE_STATUS: 798 *params = GR_GL_TRUE; 799 break; 800 case GR_GL_INFO_LOG_LENGTH: // fallthru 801 case GL_PROGRAM_BINARY_LENGTH: 802 *params = 0; 803 break; 804 // we don't expect any other pnames 805 default: 806 SK_ABORT("Unexpected pname to GetProgramiv"); 807 break; 808 } 809 } 810 811 template <typename T> 812 void queryResult(GrGLenum GLtarget, GrGLenum pname, T *params) { 813 switch (pname) { 814 case GR_GL_QUERY_RESULT_AVAILABLE: 815 *params = GR_GL_TRUE; 816 break; 817 case GR_GL_QUERY_RESULT: 818 *params = 0; 819 break; 820 default: 821 SK_ABORT("Unexpected pname passed to GetQueryObject."); 822 break; 823 } 824 } 825 826 typedef GrGLTestInterface INHERITED; 827 }; 828 829 } // anonymous namespace 830 831 const GrGLInterface* GrGLCreateNullInterface(bool enableNVPR) { return new NullInterface(enableNVPR); } 832