Update rive-cpp to 2.0 version
[platform/core/uifw/rive-tizen.git] / submodule / skia / src / gpu / ganesh / gl / GrGLVertexArray.cpp
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 "src/gpu/ganesh/GrCpuBuffer.h"
9 #include "src/gpu/ganesh/gl/GrGLBuffer.h"
10 #include "src/gpu/ganesh/gl/GrGLGpu.h"
11 #include "src/gpu/ganesh/gl/GrGLVertexArray.h"
12
13 struct AttribLayout {
14     bool        fNormalized;  // Only used by floating point types.
15     uint8_t     fCount;
16     uint16_t    fType;
17 };
18
19 static_assert(4 == sizeof(AttribLayout));
20
21 static AttribLayout attrib_layout(GrVertexAttribType type) {
22     switch (type) {
23         case kFloat_GrVertexAttribType:
24             return {false, 1, GR_GL_FLOAT};
25         case kFloat2_GrVertexAttribType:
26             return {false, 2, GR_GL_FLOAT};
27         case kFloat3_GrVertexAttribType:
28             return {false, 3, GR_GL_FLOAT};
29         case kFloat4_GrVertexAttribType:
30             return {false, 4, GR_GL_FLOAT};
31         case kHalf_GrVertexAttribType:
32             return {false, 1, GR_GL_HALF_FLOAT};
33         case kHalf2_GrVertexAttribType:
34             return {false, 2, GR_GL_HALF_FLOAT};
35         case kHalf4_GrVertexAttribType:
36             return {false, 4, GR_GL_HALF_FLOAT};
37         case kInt2_GrVertexAttribType:
38             return {false, 2, GR_GL_INT};
39         case kInt3_GrVertexAttribType:
40             return {false, 3, GR_GL_INT};
41         case kInt4_GrVertexAttribType:
42             return {false, 4, GR_GL_INT};
43         case kByte_GrVertexAttribType:
44             return {false, 1, GR_GL_BYTE};
45         case kByte2_GrVertexAttribType:
46             return {false, 2, GR_GL_BYTE};
47         case kByte4_GrVertexAttribType:
48             return {false, 4, GR_GL_BYTE};
49         case kUByte_GrVertexAttribType:
50             return {false, 1, GR_GL_UNSIGNED_BYTE};
51         case kUByte2_GrVertexAttribType:
52             return {false, 2, GR_GL_UNSIGNED_BYTE};
53         case kUByte4_GrVertexAttribType:
54             return {false, 4, GR_GL_UNSIGNED_BYTE};
55         case kUByte_norm_GrVertexAttribType:
56             return {true, 1, GR_GL_UNSIGNED_BYTE};
57         case kUByte4_norm_GrVertexAttribType:
58             return {true, 4, GR_GL_UNSIGNED_BYTE};
59         case kShort2_GrVertexAttribType:
60             return {false, 2, GR_GL_SHORT};
61         case kShort4_GrVertexAttribType:
62             return {false, 4, GR_GL_SHORT};
63         case kUShort2_GrVertexAttribType:
64             return {false, 2, GR_GL_UNSIGNED_SHORT};
65         case kUShort2_norm_GrVertexAttribType:
66             return {true, 2, GR_GL_UNSIGNED_SHORT};
67         case kInt_GrVertexAttribType:
68             return {false, 1, GR_GL_INT};
69         case kUInt_GrVertexAttribType:
70             return {false, 1, GR_GL_UNSIGNED_INT};
71         case kUShort_norm_GrVertexAttribType:
72             return {true, 1, GR_GL_UNSIGNED_SHORT};
73         case kUShort4_norm_GrVertexAttribType:
74             return {true, 4, GR_GL_UNSIGNED_SHORT};
75     }
76     SK_ABORT("Unknown vertex attrib type");
77 };
78
79 void GrGLAttribArrayState::set(GrGLGpu* gpu,
80                                int index,
81                                const GrBuffer* vertexBuffer,
82                                GrVertexAttribType cpuType,
83                                SkSLType gpuType,
84                                GrGLsizei stride,
85                                size_t offsetInBytes,
86                                int divisor) {
87     SkASSERT(index >= 0 && index < fAttribArrayStates.count());
88     SkASSERT(0 == divisor || gpu->caps()->drawInstancedSupport());
89     AttribArrayState* array = &fAttribArrayStates[index];
90     const char* offsetAsPtr;
91     bool bufferChanged = false;
92     if (vertexBuffer->isCpuBuffer()) {
93         if (!array->fUsingCpuBuffer) {
94             bufferChanged = true;
95             array->fUsingCpuBuffer = true;
96         }
97         offsetAsPtr = static_cast<const GrCpuBuffer*>(vertexBuffer)->data() + offsetInBytes;
98     } else {
99         auto gpuBuffer = static_cast<const GrGpuBuffer*>(vertexBuffer);
100         if (array->fUsingCpuBuffer || array->fVertexBufferUniqueID != gpuBuffer->uniqueID()) {
101             bufferChanged = true;
102             array->fVertexBufferUniqueID = gpuBuffer->uniqueID();
103         }
104         offsetAsPtr = reinterpret_cast<const char*>(offsetInBytes);
105     }
106     if (bufferChanged ||
107         array->fCPUType != cpuType ||
108         array->fGPUType != gpuType ||
109         array->fStride != stride ||
110         array->fOffset != offsetAsPtr) {
111         // We always have to call this if we're going to change the array pointer. 'array' is
112         // tracking the last buffer used to setup attrib pointers, not the last buffer bound.
113         // GrGLGpu will avoid redundant binds.
114         gpu->bindBuffer(GrGpuBufferType::kVertex, vertexBuffer);
115         const AttribLayout& layout = attrib_layout(cpuType);
116         if (SkSLTypeIsFloatType(gpuType)) {
117             GR_GL_CALL(gpu->glInterface(), VertexAttribPointer(index,
118                                                                layout.fCount,
119                                                                layout.fType,
120                                                                layout.fNormalized,
121                                                                stride,
122                                                                offsetAsPtr));
123         } else {
124             SkASSERT(gpu->caps()->shaderCaps()->integerSupport());
125             SkASSERT(!layout.fNormalized);
126             GR_GL_CALL(gpu->glInterface(), VertexAttribIPointer(index,
127                                                                 layout.fCount,
128                                                                 layout.fType,
129                                                                 stride,
130                                                                 offsetAsPtr));
131         }
132         array->fCPUType = cpuType;
133         array->fGPUType = gpuType;
134         array->fStride = stride;
135         array->fOffset = offsetAsPtr;
136     }
137     if (gpu->caps()->drawInstancedSupport() && array->fDivisor != divisor) {
138         SkASSERT(0 == divisor || 1 == divisor); // not necessarily a requirement but what we expect.
139         GR_GL_CALL(gpu->glInterface(), VertexAttribDivisor(index, divisor));
140         array->fDivisor = divisor;
141     }
142 }
143
144 void GrGLAttribArrayState::enableVertexArrays(const GrGLGpu* gpu, int enabledCount,
145                                               GrPrimitiveRestart enablePrimitiveRestart) {
146     SkASSERT(enabledCount <= fAttribArrayStates.count());
147
148     if (!fEnableStateIsValid || enabledCount != fNumEnabledArrays) {
149         int firstIdxToEnable = fEnableStateIsValid ? fNumEnabledArrays : 0;
150         for (int i = firstIdxToEnable; i < enabledCount; ++i) {
151             GR_GL_CALL(gpu->glInterface(), EnableVertexAttribArray(i));
152         }
153
154         int endIdxToDisable = fEnableStateIsValid ? fNumEnabledArrays : fAttribArrayStates.count();
155         for (int i = enabledCount; i < endIdxToDisable; ++i) {
156             GR_GL_CALL(gpu->glInterface(), DisableVertexAttribArray(i));
157         }
158
159         fNumEnabledArrays = enabledCount;
160     }
161
162     SkASSERT(GrPrimitiveRestart::kNo == enablePrimitiveRestart ||
163              gpu->caps()->usePrimitiveRestart());
164
165     if (gpu->caps()->usePrimitiveRestart() &&
166         (!fEnableStateIsValid || enablePrimitiveRestart != fPrimitiveRestartEnabled)) {
167         if (GrPrimitiveRestart::kYes == enablePrimitiveRestart) {
168             GR_GL_CALL(gpu->glInterface(), Enable(GR_GL_PRIMITIVE_RESTART_FIXED_INDEX));
169         } else {
170             GR_GL_CALL(gpu->glInterface(), Disable(GR_GL_PRIMITIVE_RESTART_FIXED_INDEX));
171         }
172
173         fPrimitiveRestartEnabled = enablePrimitiveRestart;
174     }
175
176     fEnableStateIsValid = true;
177 }
178
179 ///////////////////////////////////////////////////////////////////////////////////////////////////
180
181 GrGLVertexArray::GrGLVertexArray(GrGLint id, int attribCount)
182     : fID(id)
183     , fAttribArrays(attribCount)
184     , fIndexBufferUniqueID(SK_InvalidUniqueID) {
185 }
186
187 GrGLAttribArrayState* GrGLVertexArray::bind(GrGLGpu* gpu) {
188     if (0 == fID) {
189         return nullptr;
190     }
191     gpu->bindVertexArray(fID);
192     return &fAttribArrays;
193 }
194
195 GrGLAttribArrayState* GrGLVertexArray::bindWithIndexBuffer(GrGLGpu* gpu, const GrBuffer* ibuff) {
196     GrGLAttribArrayState* state = this->bind(gpu);
197     if (!state) {
198         return nullptr;
199     }
200     if (ibuff->isCpuBuffer()) {
201         GR_GL_CALL(gpu->glInterface(), BindBuffer(GR_GL_ELEMENT_ARRAY_BUFFER, 0));
202     } else {
203         const GrGLBuffer* glBuffer = static_cast<const GrGLBuffer*>(ibuff);
204         if (fIndexBufferUniqueID != glBuffer->uniqueID()) {
205             GR_GL_CALL(gpu->glInterface(),
206                        BindBuffer(GR_GL_ELEMENT_ARRAY_BUFFER, glBuffer->bufferID()));
207             fIndexBufferUniqueID = glBuffer->uniqueID();
208         }
209     }
210     return state;
211 }
212
213 void GrGLVertexArray::invalidateCachedState() {
214     fAttribArrays.invalidate();
215     fIndexBufferUniqueID.makeInvalid();
216 }