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 type,
     44              GrGLsizei stride,
     45              size_t offsetInBytes,
     46              int divisor = 0);
     47 
     48     enum class EnablePrimitiveRestart : bool {
     49         kYes = true,
     50         kNo = false
     51     };
     52 
     53     /**
     54      * This function enables the first 'enabledCount' vertex arrays and disables the rest.
     55      */
     56     void enableVertexArrays(const GrGLGpu*, int enabledCount,
     57                             EnablePrimitiveRestart = EnablePrimitiveRestart::kNo);
     58 
     59     void invalidate() {
     60         int count = fAttribArrayStates.count();
     61         for (int i = 0; i < count; ++i) {
     62             fAttribArrayStates[i].invalidate();
     63         }
     64         fEnableStateIsValid = false;
     65     }
     66 
     67     /**
     68      * The number of attrib arrays that this object is configured to track.
     69      */
     70     int count() const { return fAttribArrayStates.count(); }
     71 
     72 private:
     73     static constexpr int kInvalidDivisor = -1;
     74 
     75     /**
     76      * Tracks the state of glVertexAttribArray for an attribute index.
     77      */
     78     struct AttribArrayState {
     79         void invalidate() {
     80             fVertexBufferUniqueID.makeInvalid();
     81             fDivisor = kInvalidDivisor;
     82         }
     83 
     84         GrGpuResource::UniqueID   fVertexBufferUniqueID;
     85         GrVertexAttribType        fType;
     86         GrGLsizei                 fStride;
     87         size_t                    fOffset;
     88         int                       fDivisor;
     89     };
     90 
     91     SkSTArray<16, AttribArrayState, true> fAttribArrayStates;
     92     int fNumEnabledArrays;
     93     EnablePrimitiveRestart fPrimitiveRestartEnabled;
     94     bool fEnableStateIsValid = false;
     95 };
     96 
     97 /**
     98  * This class represents an OpenGL vertex array object. It manages the lifetime of the vertex array
     99  * and is used to track the state of the vertex array to avoid redundant GL calls.
    100  */
    101 class GrGLVertexArray {
    102 public:
    103     GrGLVertexArray(GrGLint id, int attribCount);
    104 
    105     /**
    106      * Binds this vertex array. If the ID has been deleted or abandoned then nullptr is returned.
    107      * Otherwise, the GrGLAttribArrayState that is tracking this vertex array's attrib bindings is
    108      * returned.
    109      */
    110     GrGLAttribArrayState* bind(GrGLGpu*);
    111 
    112     /**
    113      * This is a version of the above function that also binds an index buffer to the vertex
    114      * array object.
    115      */
    116     GrGLAttribArrayState* bindWithIndexBuffer(GrGLGpu* gpu, const GrBuffer* indexBuffer);
    117 
    118     GrGLuint arrayID() const { return fID; }
    119 
    120     void invalidateCachedState();
    121 
    122 private:
    123     GrGLuint                  fID;
    124     GrGLAttribArrayState      fAttribArrays;
    125     GrGpuResource::UniqueID   fIndexBufferUniqueID;
    126 };
    127 
    128 #endif
    129