GrGLVertexArray.h revision 6918d482d64f045a4c980b2fb267bc939953638e
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 "GrResource.h"
12#include "gl/GrGLFunctions.h"
13
14#include "SkTArray.h"
15
16class GrGLVertexBuffer;
17class GrGLIndexBuffer;
18class GrGpuGL;
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 */
24class GrGLAttribArrayState {
25public:
26    explicit GrGLAttribArrayState(int arrayCount = 0) { this->resize(arrayCount); }
27
28    void resize(int newCount) {
29        fAttribArrayStates.resize_back(newCount);
30        for (int i = 0; i < newCount; ++i) {
31            fAttribArrayStates[i].invalidate();
32        }
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(const GrGpuGL*,
41             int index,
42             GrGLVertexBuffer*,
43             GrGLint size,
44             GrGLenum type,
45             GrGLboolean normalized,
46             GrGLsizei stride,
47             GrGLvoid* offset);
48
49    /**
50     * This function disables vertex attribs not present in the mask. It is assumed that the
51     * GrGLAttribArrayState is tracking the state of the currently bound vertex array object.
52     */
53    void disableUnusedAttribArrays(const GrGpuGL*, uint64_t usedAttribArrayMask);
54
55    void invalidate() {
56        int count = fAttribArrayStates.count();
57        for (int i = 0; i < count; ++i) {
58            fAttribArrayStates[i].invalidate();
59        }
60    }
61
62    void notifyVertexBufferDelete(GrGLuint id) {
63        int count = fAttribArrayStates.count();
64        for (int i = 0; i < count; ++i) {
65            if (id == fAttribArrayStates[i].fVertexBufferID) {
66                fAttribArrayStates[i].invalidate();
67            }
68        }
69    }
70
71    /**
72     * The number of attrib arrays that this object is configured to track.
73     */
74    int count() const { return fAttribArrayStates.count(); }
75
76private:
77    /**
78     * Tracks the state of glVertexAttribArray for an attribute index.
79     */
80    struct AttribArrayState {
81            void invalidate() {
82                fEnableIsValid = false;
83                fAttribPointerIsValid = false;
84            }
85
86            bool        fEnableIsValid;
87            bool        fAttribPointerIsValid;
88            bool        fEnabled;
89            GrGLuint    fVertexBufferID;
90            GrGLint     fSize;
91            GrGLenum    fType;
92            GrGLboolean fNormalized;
93            GrGLsizei   fStride;
94            GrGLvoid*   fOffset;
95    };
96
97    SkSTArray<16, AttribArrayState, true> fAttribArrayStates;
98};
99
100/**
101 * This class represents an OpenGL vertex array object. It manages the lifetime of the vertex array
102 * and is used to track the state of the vertex array to avoid redundant GL calls.
103 */
104class GrGLVertexArray : public GrResource {
105public:
106    GrGLVertexArray(GrGpuGL* gpu, GrGLint id, int attribCount);
107
108    /**
109     * Binds this vertex array. If the ID has been deleted or abandoned then NULL is returned.
110     * Otherwise, the GrGLAttribArrayState that is tracking this vertex array's attrib bindings is
111     * returned.
112     */
113    GrGLAttribArrayState* bind();
114
115    /**
116     * This is a version of the above function that also binds an index buffer to the vertex
117     * array object.
118     */
119    GrGLAttribArrayState* bindWithIndexBuffer(const GrGLIndexBuffer* indexBuffer);
120
121    void notifyIndexBufferDelete(GrGLuint bufferID);
122
123    void notifyVertexBufferDelete(GrGLuint id) {
124        fAttribArrays.notifyVertexBufferDelete(id);
125    }
126
127    GrGLuint arrayID() const { return fID; }
128
129    void invalidateCachedState();
130
131    virtual size_t sizeInBytes() const SK_OVERRIDE { return 0; }
132
133protected:
134    virtual void onAbandon() SK_OVERRIDE;
135
136    virtual void onRelease() SK_OVERRIDE;
137
138private:
139    GrGLuint                fID;
140    GrGLAttribArrayState    fAttribArrays;
141    GrGLuint                fIndexBufferID;
142    bool                    fIndexBufferIDIsValid;
143
144    typedef GrResource INHERITED;
145};
146
147#endif
148