Home | History | Annotate | Download | only in gl
      1 /*
      2  * Copyright 2013 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 "GrGLVertexArray.h"
      9 #include "GrGpuGL.h"
     10 
     11 #define GPUGL static_cast<GrGpuGL*>(this->getGpu())
     12 #define GL_CALL(X) GR_GL_CALL(GPUGL->glInterface(), X);
     13 
     14 void GrGLAttribArrayState::set(const GrGpuGL* gpu,
     15                                int index,
     16                                GrGLVertexBuffer* buffer,
     17                                GrGLint size,
     18                                GrGLenum type,
     19                                GrGLboolean normalized,
     20                                GrGLsizei stride,
     21                                GrGLvoid* offset) {
     22     SkASSERT(index >= 0 && index < fAttribArrayStates.count());
     23     AttribArrayState* array = &fAttribArrayStates[index];
     24     if (!array->fEnableIsValid || !array->fEnabled) {
     25         GR_GL_CALL(gpu->glInterface(), EnableVertexAttribArray(index));
     26         array->fEnableIsValid = true;
     27         array->fEnabled = true;
     28     }
     29     if (!array->fAttribPointerIsValid ||
     30         array->fVertexBufferID != buffer->bufferID() ||
     31         array->fSize != size ||
     32         array->fNormalized != normalized ||
     33         array->fStride != stride ||
     34         array->fOffset != offset) {
     35 
     36         buffer->bind();
     37         GR_GL_CALL(gpu->glInterface(), VertexAttribPointer(index,
     38                                                            size,
     39                                                            type,
     40                                                            normalized,
     41                                                            stride,
     42                                                            offset));
     43         array->fAttribPointerIsValid = true;
     44         array->fVertexBufferID = buffer->bufferID();
     45         array->fSize = size;
     46         array->fNormalized = normalized;
     47         array->fStride = stride;
     48         array->fOffset = offset;
     49     }
     50 }
     51 
     52 void GrGLAttribArrayState::disableUnusedArrays(const GrGpuGL* gpu, uint64_t usedMask) {
     53     int count = fAttribArrayStates.count();
     54     for (int i = 0; i < count; ++i) {
     55         if (!(usedMask & 0x1)) {
     56             if (!fAttribArrayStates[i].fEnableIsValid || fAttribArrayStates[i].fEnabled) {
     57                 GR_GL_CALL(gpu->glInterface(), DisableVertexAttribArray(i));
     58                 fAttribArrayStates[i].fEnableIsValid = true;
     59                 fAttribArrayStates[i].fEnabled = false;
     60             }
     61         } else {
     62             SkASSERT(fAttribArrayStates[i].fEnableIsValid && fAttribArrayStates[i].fEnabled);
     63         }
     64         // if the count is greater than 64 then this will become 0 and we will disable arrays 64+.
     65         usedMask >>= 1;
     66     }
     67 }
     68 
     69 ///////////////////////////////////////////////////////////////////////////////////////////////////
     70 
     71 GrGLVertexArray::GrGLVertexArray(GrGpuGL* gpu, GrGLint id, int attribCount)
     72     : INHERITED(gpu, false)
     73     , fID(id)
     74     , fAttribArrays(attribCount)
     75     , fIndexBufferIDIsValid(false) {
     76 }
     77 
     78 void GrGLVertexArray::onAbandon() {
     79     fID = 0;
     80     INHERITED::onAbandon();
     81 }
     82 
     83 void GrGLVertexArray::onRelease() {
     84     if (0 != fID) {
     85         GL_CALL(DeleteVertexArrays(1, &fID));
     86         GPUGL->notifyVertexArrayDelete(fID);
     87         fID = 0;
     88     }
     89     INHERITED::onRelease();
     90 }
     91 
     92 GrGLAttribArrayState* GrGLVertexArray::bind() {
     93     if (0 == fID) {
     94         return NULL;
     95     }
     96     GPUGL->bindVertexArray(fID);
     97     return &fAttribArrays;
     98 }
     99 
    100 GrGLAttribArrayState* GrGLVertexArray::bindWithIndexBuffer(const GrGLIndexBuffer* buffer) {
    101     GrGLAttribArrayState* state = this->bind();
    102     if (NULL != state && NULL != buffer) {
    103         GrGLuint bufferID = buffer->bufferID();
    104         if (!fIndexBufferIDIsValid || bufferID != fIndexBufferID) {
    105             GL_CALL(BindBuffer(GR_GL_ELEMENT_ARRAY_BUFFER, bufferID));
    106             fIndexBufferIDIsValid = true;
    107             fIndexBufferID = bufferID;
    108         }
    109     }
    110     return state;
    111 }
    112 
    113 void GrGLVertexArray::notifyIndexBufferDelete(GrGLuint bufferID) {
    114     if (fIndexBufferIDIsValid && bufferID == fIndexBufferID) {
    115         fIndexBufferID = 0;
    116     }
    117  }
    118 
    119 void GrGLVertexArray::invalidateCachedState() {
    120     fAttribArrays.invalidate();
    121     fIndexBufferIDIsValid = false;
    122 }
    123