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 #ifndef GrGLVertexArray_DEFINED
      9 #define GrGLVertexArray_DEFINED
     10 
     11 #include "GrGpuResource.h"
     12 #include "GrTypesPriv.h"
     13 #include "gl/GrGLDefines.h"
     14 #include "gl/GrGLTypes.h"
     15 #include "SkTArray.h"
     16 
     17 class GrBuffer;
     18 class GrGLGpu;
     19 
     20 /**
     21  * This sets and tracks the vertex attribute array state. It is used internally by GrGLVertexArray
     22  * (below) but is separate because it is also used to track the state of vertex array object 0.
     23  */
     24 class GrGLAttribArrayState {
     25 public:
     26     explicit GrGLAttribArrayState(int arrayCount = 0) {
     27         this->resize(arrayCount);
     28     }
     29 
     30     void resize(int newCount) {
     31         fAttribArrayStates.resize_back(newCount);
     32         this->invalidate();
     33     }
     34 
     35     /**
     36      * This function enables and sets vertex attrib state for the specified attrib index. It is
     37      * assumed that the GrGLAttribArrayState is tracking the state of the currently bound vertex
     38      * array object.
     39      */
     40     void set(GrGLGpu*,
     41              int attribIndex,
     42              const GrBuffer* vertexBuffer,
     43              GrVertexAttribType cpuType,
     44              GrSLType gpuType,
     45              GrGLsizei stride,
     46              size_t offsetInBytes,
     47              int divisor = 0);
     48 
     49     /**
     50      * This function enables the first 'enabledCount' vertex arrays and disables the rest.
     51      */
     52     void enableVertexArrays(const GrGLGpu*, int enabledCount,
     53                             GrPrimitiveRestart = GrPrimitiveRestart::kNo);
     54 
     55     void invalidate() {
     56         int count = fAttribArrayStates.count();
     57         for (int i = 0; i < count; ++i) {
     58             fAttribArrayStates[i].invalidate();
     59         }
     60         fEnableStateIsValid = false;
     61     }
     62 
     63     /**
     64      * The number of attrib arrays that this object is configured to track.
     65      */
     66     int count() const { return fAttribArrayStates.count(); }
     67 
     68 private:
     69     static constexpr int kInvalidDivisor = -1;
     70 
     71     /**
     72      * Tracks the state of glVertexAttribArray for an attribute index.
     73      */
     74     struct AttribArrayState {
     75         void invalidate() {
     76             fVertexBufferUniqueID.makeInvalid();
     77             fDivisor = kInvalidDivisor;
     78             fUsingCpuBuffer = false;
     79         }
     80 
     81         GrGpuResource::UniqueID   fVertexBufferUniqueID;
     82         bool                      fUsingCpuBuffer;
     83         GrVertexAttribType        fCPUType;
     84         GrSLType                  fGPUType;
     85         GrGLsizei                 fStride;
     86         const GrGLvoid*           fOffset;
     87         int                       fDivisor;
     88     };
     89 
     90     SkSTArray<16, AttribArrayState, true> fAttribArrayStates;
     91     int fNumEnabledArrays;
     92     GrPrimitiveRestart fPrimitiveRestartEnabled;
     93     bool fEnableStateIsValid = false;
     94 };
     95 
     96 /**
     97  * This class represents an OpenGL vertex array object. It manages the lifetime of the vertex array
     98  * and is used to track the state of the vertex array to avoid redundant GL calls.
     99  */
    100 class GrGLVertexArray {
    101 public:
    102     GrGLVertexArray(GrGLint id, int attribCount);
    103 
    104     /**
    105      * Binds this vertex array. If the ID has been deleted or abandoned then nullptr is returned.
    106      * Otherwise, the GrGLAttribArrayState that is tracking this vertex array's attrib bindings is
    107      * returned.
    108      */
    109     GrGLAttribArrayState* bind(GrGLGpu*);
    110 
    111     /**
    112      * This is a version of the above function that also binds an index buffer to the vertex
    113      * array object.
    114      */
    115     GrGLAttribArrayState* bindWithIndexBuffer(GrGLGpu* gpu, const GrBuffer* indexBuffer);
    116 
    117     GrGLuint arrayID() const { return fID; }
    118 
    119     void invalidateCachedState();
    120 
    121 private:
    122     GrGLuint                  fID;
    123     GrGLAttribArrayState      fAttribArrays;
    124     GrGpuResource::UniqueID   fIndexBufferUniqueID;
    125 };
    126 
    127 #endif
    128