1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #ifndef WEBGL_VERTEX_ARRAY_H_
7 #define WEBGL_VERTEX_ARRAY_H_
13 #include "mozilla/IntegerRange.h"
15 #include "CacheInvalidator.h"
16 #include "WebGLObjectModel.h"
17 #include "WebGLStrongTypes.h"
22 class WebGLVertexArrayFake
;
25 struct LinkedProgramInfo
;
27 struct VertAttribLayoutData final
{
28 // Keep this packed tightly!
32 uint8_t byteStride
= 1; // Non-zero, at-most 255
33 webgl::AttribBaseType baseType
= webgl::AttribBaseType::Float
;
34 uint64_t byteOffset
= 0;
37 struct VertAttribBindingData final
{
38 VertAttribLayoutData layout
;
39 RefPtr
<WebGLBuffer
> buffer
;
44 void DoVertexAttribPointer(gl::GLContext
&, uint32_t index
,
45 const webgl::VertAttribPointerDesc
&);
47 class WebGLVertexArray
: public WebGLContextBoundObject
{
48 friend class ScopedDrawHelper
;
49 friend class WebGLContext
;
50 friend class WebGLVertexArrayFake
;
51 friend class WebGL2Context
;
52 friend struct webgl::LinkedProgramInfo
;
54 static constexpr size_t kMaxAttribs
= 32; // gpuinfo.org says so
56 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(WebGLVertexArray
, override
)
58 RefPtr
<WebGLBuffer
> mElementArrayBuffer
;
60 std::array
<webgl::VertAttribBindingData
, kMaxAttribs
> mBindings
; // Hot data.
61 std::array
<webgl::VertAttribPointerDesc
, kMaxAttribs
>
62 mDescs
; // cold data, parallel to mBindings.
64 std::bitset
<kMaxAttribs
> mAttribIsArrayWithNullBuffer
;
65 bool mHasBeenBound
= false;
68 static WebGLVertexArray
* Create(WebGLContext
* webgl
);
71 explicit WebGLVertexArray(WebGLContext
* webgl
);
75 virtual void BindVertexArray() = 0;
77 void SetAttribIsArray(const uint32_t index
, const bool val
) {
78 auto& binding
= mBindings
.at(index
);
79 binding
.layout
.isArray
= val
;
80 mAttribIsArrayWithNullBuffer
[index
] =
81 binding
.layout
.isArray
&& !binding
.buffer
;
84 void AttribDivisor(const uint32_t index
, const uint32_t val
) {
85 auto& binding
= mBindings
.at(index
);
86 binding
.layout
.divisor
= val
;
89 void AttribPointer(const uint32_t index
, WebGLBuffer
* const buffer
,
90 const webgl::VertAttribPointerDesc
& desc
,
91 const webgl::VertAttribPointerCalculated
& calc
) {
94 auto& binding
= mBindings
.at(index
);
95 binding
.buffer
= buffer
;
96 binding
.layout
.byteSize
= calc
.byteSize
;
97 binding
.layout
.byteStride
= calc
.byteStride
;
98 binding
.layout
.baseType
= calc
.baseType
;
99 binding
.layout
.byteOffset
= desc
.byteOffset
;
101 mAttribIsArrayWithNullBuffer
[index
] =
102 binding
.layout
.isArray
&& !binding
.buffer
;
105 const auto& AttribBinding(const uint32_t index
) const {
106 return mBindings
.at(index
);
108 const auto& AttribDesc(const uint32_t index
) const {
109 return mDescs
.at(index
);
112 Maybe
<uint32_t> GetAttribIsArrayWithNullBuffer() const {
113 const auto& bitset
= mAttribIsArrayWithNullBuffer
;
114 if (MOZ_LIKELY(bitset
.none())) return {};
115 for (const auto i
: IntegerRange(bitset
.size())) {
116 if (bitset
[i
]) return Some(i
);
121 Maybe
<double> GetVertexAttrib(uint32_t index
, GLenum pname
) const;
122 void DoVertexAttrib(uint32_t index
, uint32_t vertOffset
= 0) const;
125 } // namespace mozilla
127 #endif // WEBGL_VERTEX_ARRAY_H_