Home | History | Annotate | Download | only in debug
      1 
      2 /*
      3  * Copyright 2012 Google Inc.
      4  *
      5  * Use of this source code is governed by a BSD-style license that can be
      6  * found in the LICENSE file.
      7  */
      8 
      9 
     10 #include "gl/GrGLInterface.h"
     11 #include "GrDebugGL.h"
     12 #include "GrShaderObj.h"
     13 #include "GrProgramObj.h"
     14 #include "GrBufferObj.h"
     15 #include "GrTextureUnitObj.h"
     16 #include "GrTextureObj.h"
     17 #include "GrFrameBufferObj.h"
     18 #include "GrRenderBufferObj.h"
     19 #include "GrVertexArrayObj.h"
     20 #include "SkFloatingPoint.h"
     21 #include "../GrGLNoOpInterface.h"
     22 
     23 namespace { // suppress no previous prototype warning
     24 
     25 ////////////////////////////////////////////////////////////////////////////////
     26 GrGLvoid GR_GL_FUNCTION_TYPE debugGLActiveTexture(GrGLenum texture) {
     27 
     28     // Ganesh offsets the texture unit indices
     29     texture -= GR_GL_TEXTURE0;
     30     GrAlwaysAssert(texture < GrDebugGL::getInstance()->getMaxTextureUnits());
     31 
     32     GrDebugGL::getInstance()->setCurTextureUnit(texture);
     33 }
     34 
     35 ////////////////////////////////////////////////////////////////////////////////
     36 GrGLvoid GR_GL_FUNCTION_TYPE debugGLAttachShader(GrGLuint programID,
     37                                                  GrGLuint shaderID) {
     38 
     39     GrProgramObj *program = GR_FIND(programID, GrProgramObj,
     40                                     GrDebugGL::kProgram_ObjTypes);
     41     GrAlwaysAssert(program);
     42 
     43     GrShaderObj *shader = GR_FIND(shaderID,
     44                                   GrShaderObj,
     45                                   GrDebugGL::kShader_ObjTypes);
     46     GrAlwaysAssert(shader);
     47 
     48     program->AttachShader(shader);
     49 }
     50 
     51 GrGLvoid GR_GL_FUNCTION_TYPE debugGLBeginQuery(GrGLenum target, GrGLuint id) {
     52 }
     53 
     54 GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindAttribLocation(GrGLuint program,
     55                                                        GrGLuint index,
     56                                                        const char* name) {
     57 }
     58 
     59 ////////////////////////////////////////////////////////////////////////////////
     60 GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindTexture(GrGLenum target,
     61                                                 GrGLuint textureID) {
     62 
     63     // we don't use cube maps
     64     GrAlwaysAssert(target == GR_GL_TEXTURE_2D);
     65                                     // || target == GR_GL_TEXTURE_CUBE_MAP);
     66 
     67     // a textureID of 0 is acceptable - it binds to the default texture target
     68     GrTextureObj *texture = GR_FIND(textureID, GrTextureObj,
     69                                     GrDebugGL::kTexture_ObjTypes);
     70 
     71     GrDebugGL::getInstance()->setTexture(texture);
     72 }
     73 
     74 
     75 ////////////////////////////////////////////////////////////////////////////////
     76 GrGLvoid GR_GL_FUNCTION_TYPE debugGLBufferData(GrGLenum target,
     77                                                GrGLsizeiptr size,
     78                                                const GrGLvoid* data,
     79                                                GrGLenum usage) {
     80     GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target ||
     81                    GR_GL_ELEMENT_ARRAY_BUFFER == target);
     82     GrAlwaysAssert(size >= 0);
     83     GrAlwaysAssert(GR_GL_STREAM_DRAW == usage ||
     84                    GR_GL_STATIC_DRAW == usage ||
     85                    GR_GL_DYNAMIC_DRAW == usage);
     86 
     87     GrBufferObj *buffer = nullptr;
     88     switch (target) {
     89         case GR_GL_ARRAY_BUFFER:
     90             buffer = GrDebugGL::getInstance()->getArrayBuffer();
     91             break;
     92         case GR_GL_ELEMENT_ARRAY_BUFFER:
     93             buffer = GrDebugGL::getInstance()->getElementArrayBuffer();
     94             break;
     95         default:
     96             SkFAIL("Unexpected target to glBufferData");
     97             break;
     98     }
     99 
    100     GrAlwaysAssert(buffer);
    101     GrAlwaysAssert(buffer->getBound());
    102 
    103     buffer->allocate(size, reinterpret_cast<const GrGLchar *>(data));
    104     buffer->setUsage(usage);
    105 }
    106 
    107 
    108 GrGLvoid GR_GL_FUNCTION_TYPE debugGLPixelStorei(GrGLenum pname,
    109                                                 GrGLint param) {
    110 
    111     switch (pname) {
    112         case GR_GL_UNPACK_ROW_LENGTH:
    113             GrDebugGL::getInstance()->setUnPackRowLength(param);
    114             break;
    115         case GR_GL_PACK_ROW_LENGTH:
    116             GrDebugGL::getInstance()->setPackRowLength(param);
    117             break;
    118         case GR_GL_UNPACK_ALIGNMENT:
    119             break;
    120         case GR_GL_PACK_ALIGNMENT:
    121             GrAlwaysAssert(false);
    122             break;
    123         default:
    124             GrAlwaysAssert(false);
    125             break;
    126     }
    127 }
    128 
    129 GrGLvoid GR_GL_FUNCTION_TYPE debugGLReadPixels(GrGLint x,
    130                                                GrGLint y,
    131                                                GrGLsizei width,
    132                                                GrGLsizei height,
    133                                                GrGLenum format,
    134                                                GrGLenum type,
    135                                                GrGLvoid* pixels) {
    136 
    137     GrGLint pixelsInRow = width;
    138     if (0 < GrDebugGL::getInstance()->getPackRowLength()) {
    139         pixelsInRow = GrDebugGL::getInstance()->getPackRowLength();
    140     }
    141 
    142     GrGLint componentsPerPixel = 0;
    143 
    144     switch (format) {
    145         case GR_GL_RGBA:
    146             // fallthrough
    147         case GR_GL_BGRA:
    148             componentsPerPixel = 4;
    149             break;
    150         case GR_GL_RGB:
    151             componentsPerPixel = 3;
    152             break;
    153         case GR_GL_RED:
    154             componentsPerPixel = 1;
    155             break;
    156         default:
    157             GrAlwaysAssert(false);
    158             break;
    159     }
    160 
    161     GrGLint alignment = 4;  // the pack alignment (one of 1, 2, 4 or 8)
    162     // Ganesh currently doesn't support setting GR_GL_PACK_ALIGNMENT
    163 
    164     GrGLint componentSize = 0;  // size (in bytes) of a single component
    165 
    166     switch (type) {
    167         case GR_GL_UNSIGNED_BYTE:
    168             componentSize = 1;
    169             break;
    170         default:
    171             GrAlwaysAssert(false);
    172             break;
    173     }
    174 
    175     GrGLint rowStride = 0;  // number of components (not bytes) to skip
    176     if (componentSize >= alignment) {
    177         rowStride = componentsPerPixel * pixelsInRow;
    178     } else {
    179         float fTemp =
    180             sk_float_ceil(componentSize * componentsPerPixel * pixelsInRow /
    181                           static_cast<float>(alignment));
    182         rowStride = static_cast<GrGLint>(alignment * fTemp / componentSize);
    183     }
    184 
    185     GrGLchar *scanline = static_cast<GrGLchar *>(pixels);
    186     for (int y = 0; y < height; ++y) {
    187         memset(scanline, 0, componentsPerPixel * componentSize * width);
    188         scanline += rowStride;
    189     }
    190 }
    191 
    192  GrGLvoid GR_GL_FUNCTION_TYPE debugGLUseProgram(GrGLuint programID) {
    193 
    194      // A programID of 0 is legal
    195      GrProgramObj *program = GR_FIND(programID,
    196                                      GrProgramObj,
    197                                      GrDebugGL::kProgram_ObjTypes);
    198 
    199      GrDebugGL::getInstance()->useProgram(program);
    200  }
    201 
    202  GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindFramebuffer(GrGLenum target,
    203                                                      GrGLuint frameBufferID) {
    204 
    205      GrAlwaysAssert(GR_GL_FRAMEBUFFER == target ||
    206                     GR_GL_READ_FRAMEBUFFER == target ||
    207                     GR_GL_DRAW_FRAMEBUFFER);
    208 
    209      // a frameBufferID of 0 is acceptable - it binds to the default
    210      // frame buffer
    211      GrFrameBufferObj *frameBuffer = GR_FIND(frameBufferID,
    212                                              GrFrameBufferObj,
    213                                              GrDebugGL::kFrameBuffer_ObjTypes);
    214 
    215      GrDebugGL::getInstance()->setFrameBuffer(frameBuffer);
    216  }
    217 
    218  GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindRenderbuffer(GrGLenum target, GrGLuint renderBufferID) {
    219 
    220      GrAlwaysAssert(GR_GL_RENDERBUFFER == target);
    221 
    222      // a renderBufferID of 0 is acceptable - it unbinds the bound render buffer
    223      GrRenderBufferObj *renderBuffer = GR_FIND(renderBufferID,
    224                                                GrRenderBufferObj,
    225                                                GrDebugGL::kRenderBuffer_ObjTypes);
    226 
    227      GrDebugGL::getInstance()->setRenderBuffer(renderBuffer);
    228  }
    229 
    230  GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteTextures(GrGLsizei n, const GrGLuint* textures) {
    231 
    232      // first potentially unbind the texture
    233      // TODO: move this into GrDebugGL as unBindTexture?
    234      for (unsigned int i = 0;
    235           i < GrDebugGL::getInstance()->getMaxTextureUnits();
    236           ++i) {
    237          GrTextureUnitObj *pTU = GrDebugGL::getInstance()->getTextureUnit(i);
    238 
    239          if (pTU->getTexture()) {
    240              for (int j = 0; j < n; ++j) {
    241 
    242                  if (textures[j] == pTU->getTexture()->getID()) {
    243                      // this ID is the current texture - revert the binding to 0
    244                      pTU->setTexture(nullptr);
    245                  }
    246              }
    247          }
    248      }
    249 
    250      // TODO: fuse the following block with DeleteRenderBuffers?
    251      // Open GL will remove a deleted render buffer from the active
    252      // frame buffer but not from any other frame buffer
    253      if (GrDebugGL::getInstance()->getFrameBuffer()) {
    254 
    255          GrFrameBufferObj *frameBuffer = GrDebugGL::getInstance()->getFrameBuffer();
    256 
    257          for (int i = 0; i < n; ++i) {
    258 
    259              if (frameBuffer->getColor() &&
    260                  textures[i] == frameBuffer->getColor()->getID()) {
    261                  frameBuffer->setColor(nullptr);
    262              }
    263              if (frameBuffer->getDepth() &&
    264                  textures[i] == frameBuffer->getDepth()->getID()) {
    265                  frameBuffer->setDepth(nullptr);
    266              }
    267              if (frameBuffer->getStencil() &&
    268                  textures[i] == frameBuffer->getStencil()->getID()) {
    269                  frameBuffer->setStencil(nullptr);
    270              }
    271          }
    272      }
    273 
    274      // then actually "delete" the buffers
    275      for (int i = 0; i < n; ++i) {
    276          GrTextureObj *buffer = GR_FIND(textures[i],
    277                                         GrTextureObj,
    278                                         GrDebugGL::kTexture_ObjTypes);
    279          GrAlwaysAssert(buffer);
    280 
    281          // OpenGL gives no guarantees if a texture is deleted while attached to
    282          // something other than the currently bound frame buffer
    283          GrAlwaysAssert(!buffer->getBound());
    284 
    285          GrAlwaysAssert(!buffer->getDeleted());
    286          buffer->deleteAction();
    287      }
    288 
    289  }
    290 
    291  GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteFramebuffers(GrGLsizei n,
    292                                                         const GrGLuint *frameBuffers) {
    293 
    294      // first potentially unbind the buffers
    295      if (GrDebugGL::getInstance()->getFrameBuffer()) {
    296          for (int i = 0; i < n; ++i) {
    297 
    298              if (frameBuffers[i] ==
    299                  GrDebugGL::getInstance()->getFrameBuffer()->getID()) {
    300                  // this ID is the current frame buffer - rebind to the default
    301                  GrDebugGL::getInstance()->setFrameBuffer(nullptr);
    302              }
    303          }
    304      }
    305 
    306      // then actually "delete" the buffers
    307      for (int i = 0; i < n; ++i) {
    308          GrFrameBufferObj *buffer = GR_FIND(frameBuffers[i],
    309                                             GrFrameBufferObj,
    310                                             GrDebugGL::kFrameBuffer_ObjTypes);
    311          GrAlwaysAssert(buffer);
    312 
    313          GrAlwaysAssert(!buffer->getDeleted());
    314          buffer->deleteAction();
    315      }
    316  }
    317 
    318  GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteRenderbuffers(GrGLsizei n,
    319                                                          const GrGLuint *renderBuffers) {
    320 
    321      // first potentially unbind the buffers
    322      if (GrDebugGL::getInstance()->getRenderBuffer()) {
    323          for (int i = 0; i < n; ++i) {
    324 
    325              if (renderBuffers[i] ==
    326                  GrDebugGL::getInstance()->getRenderBuffer()->getID()) {
    327                  // this ID is the current render buffer - make no
    328                  // render buffer be bound
    329                  GrDebugGL::getInstance()->setRenderBuffer(nullptr);
    330              }
    331          }
    332      }
    333 
    334      // TODO: fuse the following block with DeleteTextures?
    335      // Open GL will remove a deleted render buffer from the active frame
    336      // buffer but not from any other frame buffer
    337      if (GrDebugGL::getInstance()->getFrameBuffer()) {
    338 
    339          GrFrameBufferObj *frameBuffer =
    340                                GrDebugGL::getInstance()->getFrameBuffer();
    341 
    342          for (int i = 0; i < n; ++i) {
    343 
    344              if (frameBuffer->getColor() &&
    345                  renderBuffers[i] == frameBuffer->getColor()->getID()) {
    346                  frameBuffer->setColor(nullptr);
    347              }
    348              if (frameBuffer->getDepth() &&
    349                  renderBuffers[i] == frameBuffer->getDepth()->getID()) {
    350                  frameBuffer->setDepth(nullptr);
    351              }
    352              if (frameBuffer->getStencil() &&
    353                  renderBuffers[i] == frameBuffer->getStencil()->getID()) {
    354                  frameBuffer->setStencil(nullptr);
    355              }
    356          }
    357      }
    358 
    359      // then actually "delete" the buffers
    360      for (int i = 0; i < n; ++i) {
    361          GrRenderBufferObj *buffer = GR_FIND(renderBuffers[i],
    362                                              GrRenderBufferObj,
    363                                              GrDebugGL::kRenderBuffer_ObjTypes);
    364          GrAlwaysAssert(buffer);
    365 
    366          // OpenGL gives no guarantees if a render buffer is deleted
    367          // while attached to something other than the currently
    368          // bound frame buffer
    369          GrAlwaysAssert(!buffer->getColorBound());
    370          GrAlwaysAssert(!buffer->getDepthBound());
    371          // However, at GrContext destroy time we release all GrRsources and so stencil buffers
    372          // may get deleted before FBOs that refer to them.
    373          //GrAlwaysAssert(!buffer->getStencilBound());
    374 
    375          GrAlwaysAssert(!buffer->getDeleted());
    376          buffer->deleteAction();
    377      }
    378  }
    379 
    380  GrGLvoid GR_GL_FUNCTION_TYPE debugGLFramebufferRenderbuffer(GrGLenum target,
    381                                                              GrGLenum attachment,
    382                                                              GrGLenum renderbuffertarget,
    383                                                              GrGLuint renderBufferID) {
    384 
    385      GrAlwaysAssert(GR_GL_FRAMEBUFFER == target);
    386      GrAlwaysAssert(GR_GL_COLOR_ATTACHMENT0 == attachment ||
    387                     GR_GL_DEPTH_ATTACHMENT == attachment ||
    388                     GR_GL_STENCIL_ATTACHMENT == attachment);
    389      GrAlwaysAssert(GR_GL_RENDERBUFFER == renderbuffertarget);
    390 
    391      GrFrameBufferObj *framebuffer = GrDebugGL::getInstance()->getFrameBuffer();
    392      // A render buffer cannot be attached to the default framebuffer
    393      GrAlwaysAssert(framebuffer);
    394 
    395      // a renderBufferID of 0 is acceptable - it unbinds the current
    396      // render buffer
    397      GrRenderBufferObj *renderbuffer = GR_FIND(renderBufferID,
    398                                                GrRenderBufferObj,
    399                                                GrDebugGL::kRenderBuffer_ObjTypes);
    400 
    401      switch (attachment) {
    402      case GR_GL_COLOR_ATTACHMENT0:
    403          framebuffer->setColor(renderbuffer);
    404          break;
    405      case GR_GL_DEPTH_ATTACHMENT:
    406          framebuffer->setDepth(renderbuffer);
    407          break;
    408      case GR_GL_STENCIL_ATTACHMENT:
    409          framebuffer->setStencil(renderbuffer);
    410          break;
    411      default:
    412          GrAlwaysAssert(false);
    413          break;
    414      };
    415 
    416  }
    417 
    418  ////////////////////////////////////////////////////////////////////////////////
    419  GrGLvoid GR_GL_FUNCTION_TYPE debugGLFramebufferTexture2D(GrGLenum target,
    420                                                           GrGLenum attachment,
    421                                                           GrGLenum textarget,
    422                                                           GrGLuint textureID,
    423                                                           GrGLint level) {
    424 
    425      GrAlwaysAssert(GR_GL_FRAMEBUFFER == target);
    426      GrAlwaysAssert(GR_GL_COLOR_ATTACHMENT0 == attachment ||
    427                     GR_GL_DEPTH_ATTACHMENT == attachment ||
    428                     GR_GL_STENCIL_ATTACHMENT == attachment);
    429      GrAlwaysAssert(GR_GL_TEXTURE_2D == textarget);
    430 
    431      GrFrameBufferObj *framebuffer = GrDebugGL::getInstance()->getFrameBuffer();
    432      // A texture cannot be attached to the default framebuffer
    433      GrAlwaysAssert(framebuffer);
    434 
    435      // A textureID of 0 is allowed - it unbinds the currently bound texture
    436      GrTextureObj *texture = GR_FIND(textureID, GrTextureObj,
    437                                      GrDebugGL::kTexture_ObjTypes);
    438      if (texture) {
    439          // The texture shouldn't be bound to a texture unit - this
    440          // could lead to a feedback loop
    441          GrAlwaysAssert(!texture->getBound());
    442      }
    443 
    444      GrAlwaysAssert(0 == level);
    445 
    446      switch (attachment) {
    447      case GR_GL_COLOR_ATTACHMENT0:
    448          framebuffer->setColor(texture);
    449          break;
    450      case GR_GL_DEPTH_ATTACHMENT:
    451          framebuffer->setDepth(texture);
    452          break;
    453      case GR_GL_STENCIL_ATTACHMENT:
    454          framebuffer->setStencil(texture);
    455          break;
    456      default:
    457          GrAlwaysAssert(false);
    458          break;
    459      };
    460  }
    461 
    462 GrGLuint GR_GL_FUNCTION_TYPE debugGLCreateProgram() {
    463 
    464     GrProgramObj *program = GR_CREATE(GrProgramObj,
    465                                       GrDebugGL::kProgram_ObjTypes);
    466 
    467     return program->getID();
    468 }
    469 
    470 GrGLuint GR_GL_FUNCTION_TYPE debugGLCreateShader(GrGLenum type) {
    471 
    472     GrAlwaysAssert(GR_GL_VERTEX_SHADER == type ||
    473                    GR_GL_FRAGMENT_SHADER == type);
    474 
    475     GrShaderObj *shader = GR_CREATE(GrShaderObj, GrDebugGL::kShader_ObjTypes);
    476     shader->setType(type);
    477 
    478     return shader->getID();
    479 }
    480 
    481 GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteProgram(GrGLuint programID) {
    482 
    483     GrProgramObj *program = GR_FIND(programID,
    484                                     GrProgramObj,
    485                                     GrDebugGL::kProgram_ObjTypes);
    486     GrAlwaysAssert(program);
    487 
    488     if (program->getRefCount()) {
    489         // someone is still using this program so we can't delete it here
    490         program->setMarkedForDeletion();
    491     } else {
    492         program->deleteAction();
    493     }
    494 }
    495 
    496 GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteShader(GrGLuint shaderID) {
    497 
    498     GrShaderObj *shader = GR_FIND(shaderID,
    499                                   GrShaderObj,
    500                                   GrDebugGL::kShader_ObjTypes);
    501     GrAlwaysAssert(shader);
    502 
    503     if (shader->getRefCount()) {
    504         // someone is still using this shader so we can't delete it here
    505         shader->setMarkedForDeletion();
    506     } else {
    507         shader->deleteAction();
    508     }
    509 }
    510 
    511 GrGLvoid debugGenObjs(GrDebugGL::GrObjTypes type,
    512                       GrGLsizei n,
    513                       GrGLuint* ids) {
    514 
    515    for (int i = 0; i < n; ++i) {
    516        GrAlwaysAssert(ids[i] == 0);
    517        GrFakeRefObj *obj = GrDebugGL::getInstance()->createObj(type);
    518        GrAlwaysAssert(obj);
    519        ids[i] = obj->getID();
    520     }
    521 }
    522 
    523 GrGLvoid GR_GL_FUNCTION_TYPE debugGLGenBuffers(GrGLsizei n, GrGLuint* ids) {
    524     debugGenObjs(GrDebugGL::kBuffer_ObjTypes, n, ids);
    525 }
    526 
    527 GrGLvoid GR_GL_FUNCTION_TYPE debugGLGenerateMipmap(GrGLenum level) {
    528 }
    529 
    530 GrGLvoid GR_GL_FUNCTION_TYPE debugGLGenFramebuffers(GrGLsizei n,
    531                                                     GrGLuint* ids) {
    532     debugGenObjs(GrDebugGL::kFrameBuffer_ObjTypes, n, ids);
    533 }
    534 
    535 GrGLvoid GR_GL_FUNCTION_TYPE debugGLGenRenderbuffers(GrGLsizei n,
    536                                                      GrGLuint* ids) {
    537     debugGenObjs(GrDebugGL::kRenderBuffer_ObjTypes, n, ids);
    538 }
    539 
    540 GrGLvoid GR_GL_FUNCTION_TYPE debugGLGenTextures(GrGLsizei n, GrGLuint* ids) {
    541     debugGenObjs(GrDebugGL::kTexture_ObjTypes, n, ids);
    542 }
    543 
    544 GrGLvoid GR_GL_FUNCTION_TYPE debugGLGenVertexArrays(GrGLsizei n, GrGLuint* ids) {
    545     debugGenObjs(GrDebugGL::kVertexArray_ObjTypes, n, ids);
    546 }
    547 
    548 GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteVertexArrays(GrGLsizei n, const GrGLuint* ids) {
    549     for (GrGLsizei i = 0; i < n; ++i) {
    550         GrVertexArrayObj* array =
    551             GR_FIND(ids[i], GrVertexArrayObj, GrDebugGL::kVertexArray_ObjTypes);
    552         GrAlwaysAssert(array);
    553 
    554         // Deleting the current vertex array binds object 0
    555         if (GrDebugGL::getInstance()->getVertexArray() == array) {
    556             GrDebugGL::getInstance()->setVertexArray(nullptr);
    557         }
    558 
    559         if (array->getRefCount()) {
    560             // someone is still using this vertex array so we can't delete it here
    561             array->setMarkedForDeletion();
    562         } else {
    563             array->deleteAction();
    564         }
    565     }
    566 }
    567 
    568 GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindVertexArray(GrGLuint id) {
    569     GrVertexArrayObj* array = GR_FIND(id, GrVertexArrayObj, GrDebugGL::kVertexArray_ObjTypes);
    570     GrAlwaysAssert((0 == id) || array);
    571     GrDebugGL::getInstance()->setVertexArray(array);
    572 }
    573 
    574 GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindBuffer(GrGLenum target, GrGLuint bufferID) {
    575     GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || GR_GL_ELEMENT_ARRAY_BUFFER == target);
    576 
    577     GrBufferObj *buffer = GR_FIND(bufferID,
    578                                   GrBufferObj,
    579                                   GrDebugGL::kBuffer_ObjTypes);
    580     // 0 is a permissible bufferID - it unbinds the current buffer
    581 
    582     switch (target) {
    583         case GR_GL_ARRAY_BUFFER:
    584             GrDebugGL::getInstance()->setArrayBuffer(buffer);
    585             break;
    586         case GR_GL_ELEMENT_ARRAY_BUFFER:
    587             GrDebugGL::getInstance()->setElementArrayBuffer(buffer);
    588             break;
    589         default:
    590             SkFAIL("Unexpected target to glBindBuffer");
    591             break;
    592     }
    593 }
    594 
    595 // deleting a bound buffer has the side effect of binding 0
    596 GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteBuffers(GrGLsizei n, const GrGLuint* ids) {
    597     // first potentially unbind the buffers
    598     for (int i = 0; i < n; ++i) {
    599 
    600         if (GrDebugGL::getInstance()->getArrayBuffer() &&
    601             ids[i] == GrDebugGL::getInstance()->getArrayBuffer()->getID()) {
    602             // this ID is the current array buffer
    603             GrDebugGL::getInstance()->setArrayBuffer(nullptr);
    604         }
    605         if (GrDebugGL::getInstance()->getElementArrayBuffer() &&
    606             ids[i] ==
    607                 GrDebugGL::getInstance()->getElementArrayBuffer()->getID()) {
    608             // this ID is the current element array buffer
    609             GrDebugGL::getInstance()->setElementArrayBuffer(nullptr);
    610         }
    611     }
    612 
    613     // then actually "delete" the buffers
    614     for (int i = 0; i < n; ++i) {
    615         GrBufferObj *buffer = GR_FIND(ids[i],
    616                                       GrBufferObj,
    617                                       GrDebugGL::kBuffer_ObjTypes);
    618         GrAlwaysAssert(buffer);
    619 
    620         GrAlwaysAssert(!buffer->getDeleted());
    621         buffer->deleteAction();
    622     }
    623 }
    624 
    625 // map a buffer to the caller's address space
    626 GrGLvoid* GR_GL_FUNCTION_TYPE debugGLMapBufferRange(GrGLenum target, GrGLintptr offset,
    627                                                     GrGLsizeiptr length, GrGLbitfield access) {
    628     GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target ||
    629                    GR_GL_ELEMENT_ARRAY_BUFFER == target);
    630 
    631     // We only expect read access and we expect that the buffer or range is always invalidated.
    632     GrAlwaysAssert(!SkToBool(GR_GL_MAP_READ_BIT & access));
    633     GrAlwaysAssert((GR_GL_MAP_INVALIDATE_BUFFER_BIT | GR_GL_MAP_INVALIDATE_RANGE_BIT) & access);
    634 
    635     GrBufferObj *buffer = nullptr;
    636     switch (target) {
    637         case GR_GL_ARRAY_BUFFER:
    638             buffer = GrDebugGL::getInstance()->getArrayBuffer();
    639             break;
    640         case GR_GL_ELEMENT_ARRAY_BUFFER:
    641             buffer = GrDebugGL::getInstance()->getElementArrayBuffer();
    642             break;
    643         default:
    644             SkFAIL("Unexpected target to glMapBufferRange");
    645             break;
    646     }
    647 
    648     if (buffer) {
    649         GrAlwaysAssert(offset >= 0 && offset + length <= buffer->getSize());
    650         GrAlwaysAssert(!buffer->getMapped());
    651         buffer->setMapped(offset, length);
    652         return buffer->getDataPtr() + offset;
    653     }
    654 
    655     GrAlwaysAssert(false);
    656     return nullptr;        // no buffer bound to the target
    657 }
    658 
    659 GrGLvoid* GR_GL_FUNCTION_TYPE debugGLMapBuffer(GrGLenum target, GrGLenum access) {
    660     GrAlwaysAssert(GR_GL_WRITE_ONLY == access);
    661 
    662     GrBufferObj *buffer = nullptr;
    663     switch (target) {
    664         case GR_GL_ARRAY_BUFFER:
    665             buffer = GrDebugGL::getInstance()->getArrayBuffer();
    666             break;
    667         case GR_GL_ELEMENT_ARRAY_BUFFER:
    668             buffer = GrDebugGL::getInstance()->getElementArrayBuffer();
    669             break;
    670         default:
    671             SkFAIL("Unexpected target to glMapBuffer");
    672             break;
    673     }
    674 
    675     return debugGLMapBufferRange(target, 0, buffer->getSize(),
    676                                  GR_GL_MAP_WRITE_BIT | GR_GL_MAP_INVALIDATE_BUFFER_BIT);
    677 }
    678 
    679 // remove a buffer from the caller's address space
    680 // TODO: check if the "access" method from "glMapBuffer" was honored
    681 GrGLboolean GR_GL_FUNCTION_TYPE debugGLUnmapBuffer(GrGLenum target) {
    682 
    683     GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target ||
    684                    GR_GL_ELEMENT_ARRAY_BUFFER == target);
    685 
    686     GrBufferObj *buffer = nullptr;
    687     switch (target) {
    688         case GR_GL_ARRAY_BUFFER:
    689             buffer = GrDebugGL::getInstance()->getArrayBuffer();
    690             break;
    691         case GR_GL_ELEMENT_ARRAY_BUFFER:
    692             buffer = GrDebugGL::getInstance()->getElementArrayBuffer();
    693             break;
    694         default:
    695             SkFAIL("Unexpected target to glUnmapBuffer");
    696             break;
    697     }
    698 
    699     if (buffer) {
    700         GrAlwaysAssert(buffer->getMapped());
    701         buffer->resetMapped();
    702         return GR_GL_TRUE;
    703     }
    704 
    705     GrAlwaysAssert(false);
    706     return GR_GL_FALSE; // GR_GL_INVALID_OPERATION;
    707 }
    708 
    709 GrGLvoid GR_GL_FUNCTION_TYPE debugGLFlushMappedBufferRange(GrGLenum target,
    710                                                            GrGLintptr offset,
    711                                                            GrGLsizeiptr length) {
    712     GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target ||
    713                    GR_GL_ELEMENT_ARRAY_BUFFER == target);
    714 
    715     GrBufferObj *buffer = nullptr;
    716     switch (target) {
    717         case GR_GL_ARRAY_BUFFER:
    718             buffer = GrDebugGL::getInstance()->getArrayBuffer();
    719             break;
    720         case GR_GL_ELEMENT_ARRAY_BUFFER:
    721             buffer = GrDebugGL::getInstance()->getElementArrayBuffer();
    722             break;
    723         default:
    724             SkFAIL("Unexpected target to glUnmapBuffer");
    725             break;
    726     }
    727 
    728     if (buffer) {
    729         GrAlwaysAssert(buffer->getMapped());
    730         GrAlwaysAssert(offset >= 0 && (offset + length) <= buffer->getMappedLength());
    731     } else {
    732         GrAlwaysAssert(false);
    733     }
    734 }
    735 
    736 
    737 GrGLvoid GR_GL_FUNCTION_TYPE debugGLGetBufferParameteriv(GrGLenum target,
    738                                                          GrGLenum value,
    739                                                          GrGLint* params) {
    740 
    741     GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target ||
    742                    GR_GL_ELEMENT_ARRAY_BUFFER == target);
    743     GrAlwaysAssert(GR_GL_BUFFER_SIZE == value ||
    744                    GR_GL_BUFFER_USAGE == value);
    745 
    746     GrBufferObj *buffer = nullptr;
    747     switch (target) {
    748         case GR_GL_ARRAY_BUFFER:
    749             buffer = GrDebugGL::getInstance()->getArrayBuffer();
    750             break;
    751         case GR_GL_ELEMENT_ARRAY_BUFFER:
    752             buffer = GrDebugGL::getInstance()->getElementArrayBuffer();
    753             break;
    754     }
    755 
    756     GrAlwaysAssert(buffer);
    757 
    758     switch (value) {
    759         case GR_GL_BUFFER_MAPPED:
    760             *params = GR_GL_FALSE;
    761             if (buffer)
    762                 *params = buffer->getMapped() ? GR_GL_TRUE : GR_GL_FALSE;
    763             break;
    764         case GR_GL_BUFFER_SIZE:
    765             *params = 0;
    766             if (buffer)
    767                 *params = SkToInt(buffer->getSize());
    768             break;
    769         case GR_GL_BUFFER_USAGE:
    770             *params = GR_GL_STATIC_DRAW;
    771             if (buffer)
    772                 *params = buffer->getUsage();
    773             break;
    774         default:
    775             SkFAIL("Unexpected value to glGetBufferParamateriv");
    776             break;
    777     }
    778 };
    779 } // end of namespace
    780 
    781 ////////////////////////////////////////////////////////////////////////////////
    782 struct GrDebugGLInterface : public GrGLInterface {
    783 
    784 public:
    785 
    786 
    787     GrDebugGLInterface()
    788         : fWrapped(nullptr) {
    789         GrDebugGL::staticRef();
    790     }
    791 
    792     virtual ~GrDebugGLInterface() {
    793         GrDebugGL::staticUnRef();
    794     }
    795 
    796     void setWrapped(GrGLInterface *interface) {
    797         fWrapped.reset(interface);
    798     }
    799 
    800     void abandon() const override {
    801         GrDebugGL::abandon();
    802     }
    803 
    804     // TODO: there are some issues w/ wrapping another GL interface inside the
    805     // debug interface:
    806     //      Since none of the "gl" methods are member functions they don't get
    807     //      a "this" pointer through which to access "fWrapped"
    808     //      This could be worked around by having all of them access the
    809     //      "glInterface" pointer - i.e., treating the debug interface as a
    810     //      true singleton
    811     //
    812     //      The problem with this is that we also want to handle OpenGL
    813     //      contexts. The natural way to do this is to have multiple debug
    814     //      interfaces. Each of which represents a separate context. The
    815     //      static ID count would still uniquify IDs across all of them.
    816     //      The problem then is that we couldn't treat the debug GL
    817     //      interface as a singleton (since there would be one for each
    818     //      context).
    819     //
    820     //      The solution to this is probably to alter SkDebugGlContext's
    821     //      "makeCurrent" method to make a call like "makeCurrent(this)" to
    822     //      the debug GL interface (assuming that the application will create
    823     //      multiple SkGLContext's) to let it switch between the active
    824     //      context. Everything in the GrDebugGL object would then need to be
    825     //      moved to a GrContextObj and the GrDebugGL object would just switch
    826     //      between them. Note that this approach would also require that
    827     //      SkDebugGLContext wrap an arbitrary other context
    828     //      and then pass the wrapped interface to the debug GL interface.
    829 
    830 protected:
    831 private:
    832 
    833     SkAutoTUnref<GrGLInterface> fWrapped;
    834 
    835     typedef GrGLInterface INHERITED;
    836 };
    837 
    838 ////////////////////////////////////////////////////////////////////////////////
    839 const GrGLInterface* GrGLCreateDebugInterface() {
    840     GrGLInterface *interface = new GrDebugGLInterface;
    841 
    842     interface->fStandard = kGL_GrGLStandard;
    843 
    844     GrGLInterface::Functions* functions = &interface->fFunctions;
    845     functions->fActiveTexture = debugGLActiveTexture;
    846     functions->fAttachShader = debugGLAttachShader;
    847     functions->fBeginQuery = debugGLBeginQuery;
    848     functions->fBindAttribLocation = debugGLBindAttribLocation;
    849     functions->fBindBuffer = debugGLBindBuffer;
    850     functions->fBindFragDataLocation = noOpGLBindFragDataLocation;
    851     functions->fBindTexture = debugGLBindTexture;
    852     functions->fBindVertexArray = debugGLBindVertexArray;
    853     functions->fBlendColor = noOpGLBlendColor;
    854     functions->fBlendEquation = noOpGLBlendEquation;
    855     functions->fBlendFunc = noOpGLBlendFunc;
    856     functions->fBufferData = debugGLBufferData;
    857     functions->fBufferSubData = noOpGLBufferSubData;
    858     functions->fClear = noOpGLClear;
    859     functions->fClearColor = noOpGLClearColor;
    860     functions->fClearStencil = noOpGLClearStencil;
    861     functions->fColorMask = noOpGLColorMask;
    862     functions->fCompileShader = noOpGLCompileShader;
    863     functions->fCompressedTexImage2D = noOpGLCompressedTexImage2D;
    864     functions->fCompressedTexSubImage2D = noOpGLCompressedTexSubImage2D;
    865     functions->fCopyTexSubImage2D = noOpGLCopyTexSubImage2D;
    866     functions->fCreateProgram = debugGLCreateProgram;
    867     functions->fCreateShader = debugGLCreateShader;
    868     functions->fCullFace = noOpGLCullFace;
    869     functions->fDeleteBuffers = debugGLDeleteBuffers;
    870     functions->fDeleteProgram = debugGLDeleteProgram;
    871     functions->fDeleteQueries = noOpGLDeleteIds;
    872     functions->fDeleteShader = debugGLDeleteShader;
    873     functions->fDeleteTextures = debugGLDeleteTextures;
    874     functions->fDeleteVertexArrays = debugGLDeleteVertexArrays;
    875     functions->fDepthMask = noOpGLDepthMask;
    876     functions->fDisable = noOpGLDisable;
    877     functions->fDisableVertexAttribArray = noOpGLDisableVertexAttribArray;
    878     functions->fDrawArrays = noOpGLDrawArrays;
    879     functions->fDrawArraysInstanced = noOpGLDrawArraysInstanced;
    880     functions->fDrawBuffer = noOpGLDrawBuffer;
    881     functions->fDrawBuffers = noOpGLDrawBuffers;
    882     functions->fDrawElements = noOpGLDrawElements;
    883     functions->fDrawElementsInstanced = noOpGLDrawElementsInstanced;
    884     functions->fEnable = noOpGLEnable;
    885     functions->fEnableVertexAttribArray = noOpGLEnableVertexAttribArray;
    886     functions->fEndQuery = noOpGLEndQuery;
    887     functions->fFinish = noOpGLFinish;
    888     functions->fFlush = noOpGLFlush;
    889     functions->fFlushMappedBufferRange = debugGLFlushMappedBufferRange;
    890     functions->fFrontFace = noOpGLFrontFace;
    891     functions->fGenerateMipmap = debugGLGenerateMipmap;
    892     functions->fGenBuffers = debugGLGenBuffers;
    893     functions->fGenQueries = noOpGLGenIds;
    894     functions->fGenTextures = debugGLGenTextures;
    895     functions->fGetBufferParameteriv = debugGLGetBufferParameteriv;
    896     functions->fGetError = noOpGLGetError;
    897     functions->fGetIntegerv = noOpGLGetIntegerv;
    898     functions->fGetQueryObjecti64v = noOpGLGetQueryObjecti64v;
    899     functions->fGetQueryObjectiv = noOpGLGetQueryObjectiv;
    900     functions->fGetQueryObjectui64v = noOpGLGetQueryObjectui64v;
    901     functions->fGetQueryObjectuiv = noOpGLGetQueryObjectuiv;
    902     functions->fGetQueryiv = noOpGLGetQueryiv;
    903     functions->fGetProgramInfoLog = noOpGLGetInfoLog;
    904     functions->fGetProgramiv = noOpGLGetShaderOrProgramiv;
    905     functions->fGetShaderInfoLog = noOpGLGetInfoLog;
    906     functions->fGetShaderiv = noOpGLGetShaderOrProgramiv;
    907     functions->fGetString = noOpGLGetString;
    908     functions->fGetStringi = noOpGLGetStringi;
    909     functions->fGetTexLevelParameteriv = noOpGLGetTexLevelParameteriv;
    910     functions->fGetUniformLocation = noOpGLGetUniformLocation;
    911     functions->fGenVertexArrays = debugGLGenVertexArrays;
    912     functions->fLineWidth = noOpGLLineWidth;
    913     functions->fLinkProgram = noOpGLLinkProgram;
    914     functions->fMapBuffer = debugGLMapBuffer;
    915     functions->fMapBufferRange = debugGLMapBufferRange;
    916     functions->fPixelStorei = debugGLPixelStorei;
    917     functions->fQueryCounter = noOpGLQueryCounter;
    918     functions->fReadBuffer = noOpGLReadBuffer;
    919     functions->fReadPixels = debugGLReadPixels;
    920     functions->fScissor = noOpGLScissor;
    921     functions->fShaderSource = noOpGLShaderSource;
    922     functions->fStencilFunc = noOpGLStencilFunc;
    923     functions->fStencilFuncSeparate = noOpGLStencilFuncSeparate;
    924     functions->fStencilMask = noOpGLStencilMask;
    925     functions->fStencilMaskSeparate = noOpGLStencilMaskSeparate;
    926     functions->fStencilOp = noOpGLStencilOp;
    927     functions->fStencilOpSeparate = noOpGLStencilOpSeparate;
    928     functions->fTexImage2D = noOpGLTexImage2D;
    929     functions->fTexParameteri = noOpGLTexParameteri;
    930     functions->fTexParameteriv = noOpGLTexParameteriv;
    931     functions->fTexSubImage2D = noOpGLTexSubImage2D;
    932     functions->fTexStorage2D = noOpGLTexStorage2D;
    933     functions->fDiscardFramebuffer = noOpGLDiscardFramebuffer;
    934     functions->fUniform1f = noOpGLUniform1f;
    935     functions->fUniform1i = noOpGLUniform1i;
    936     functions->fUniform1fv = noOpGLUniform1fv;
    937     functions->fUniform1iv = noOpGLUniform1iv;
    938     functions->fUniform2f = noOpGLUniform2f;
    939     functions->fUniform2i = noOpGLUniform2i;
    940     functions->fUniform2fv = noOpGLUniform2fv;
    941     functions->fUniform2iv = noOpGLUniform2iv;
    942     functions->fUniform3f = noOpGLUniform3f;
    943     functions->fUniform3i = noOpGLUniform3i;
    944     functions->fUniform3fv = noOpGLUniform3fv;
    945     functions->fUniform3iv = noOpGLUniform3iv;
    946     functions->fUniform4f = noOpGLUniform4f;
    947     functions->fUniform4i = noOpGLUniform4i;
    948     functions->fUniform4fv = noOpGLUniform4fv;
    949     functions->fUniform4iv = noOpGLUniform4iv;
    950     functions->fUniformMatrix2fv = noOpGLUniformMatrix2fv;
    951     functions->fUniformMatrix3fv = noOpGLUniformMatrix3fv;
    952     functions->fUniformMatrix4fv = noOpGLUniformMatrix4fv;
    953     functions->fUnmapBuffer = debugGLUnmapBuffer;
    954     functions->fUseProgram = debugGLUseProgram;
    955     functions->fVertexAttrib1f = noOpGLVertexAttrib1f;
    956     functions->fVertexAttrib2fv = noOpGLVertexAttrib2fv;
    957     functions->fVertexAttrib3fv = noOpGLVertexAttrib3fv;
    958     functions->fVertexAttrib4fv = noOpGLVertexAttrib4fv;
    959     functions->fVertexAttribDivisor = noOpGLVertexAttribDivisor;
    960     functions->fVertexAttribIPointer = noOpGLVertexAttribIPointer;
    961     functions->fVertexAttribPointer = noOpGLVertexAttribPointer;
    962     functions->fViewport = noOpGLViewport;
    963     functions->fBindFramebuffer = debugGLBindFramebuffer;
    964     functions->fBindRenderbuffer = debugGLBindRenderbuffer;
    965     functions->fCheckFramebufferStatus = noOpGLCheckFramebufferStatus;
    966     functions->fDeleteFramebuffers = debugGLDeleteFramebuffers;
    967     functions->fDeleteRenderbuffers = debugGLDeleteRenderbuffers;
    968     functions->fFramebufferRenderbuffer = debugGLFramebufferRenderbuffer;
    969     functions->fFramebufferTexture2D = debugGLFramebufferTexture2D;
    970     functions->fGenFramebuffers = debugGLGenFramebuffers;
    971     functions->fGenRenderbuffers = debugGLGenRenderbuffers;
    972     functions->fGetFramebufferAttachmentParameteriv =
    973                                     noOpGLGetFramebufferAttachmentParameteriv;
    974     functions->fGetRenderbufferParameteriv = noOpGLGetRenderbufferParameteriv;
    975     functions->fRenderbufferStorage = noOpGLRenderbufferStorage;
    976     functions->fRenderbufferStorageMultisample =
    977                                     noOpGLRenderbufferStorageMultisample;
    978     functions->fBlitFramebuffer = noOpGLBlitFramebuffer;
    979     functions->fResolveMultisampleFramebuffer =
    980                                     noOpGLResolveMultisampleFramebuffer;
    981     functions->fMatrixLoadf = noOpGLMatrixLoadf;
    982     functions->fMatrixLoadIdentity = noOpGLMatrixLoadIdentity;
    983 
    984     functions->fBindFragDataLocationIndexed =
    985                                     noOpGLBindFragDataLocationIndexed;
    986 
    987     interface->fExtensions.init(kGL_GrGLStandard, functions->fGetString, functions->fGetStringi,
    988                                 functions->fGetIntegerv, nullptr, GR_EGL_NO_DISPLAY);
    989 
    990     return interface;
    991 }
    992