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
= 0; // 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::bitset
<kMaxAttribs
> mAttribIsArray
;
61 std::array
<webgl::VertAttribBindingData
, kMaxAttribs
> mBindings
; // Hot data.
62 std::array
<webgl::VertAttribPointerDesc
, kMaxAttribs
>
63 mDescs
; // cold data, parallel to mBindings.
65 std::bitset
<kMaxAttribs
> mAttribIsArrayWithNullBuffer
;
66 bool mHasBeenBound
= false;
69 static WebGLVertexArray
* Create(WebGLContext
* webgl
);
72 explicit WebGLVertexArray(WebGLContext
* webgl
);
76 virtual void BindVertexArray() = 0;
78 void SetAttribIsArray(const uint32_t index
, const bool val
) {
79 auto& binding
= mBindings
[index
];
80 binding
.layout
.isArray
= val
;
81 mAttribIsArrayWithNullBuffer
[index
] =
82 binding
.layout
.isArray
&& !binding
.buffer
;
85 void AttribDivisor(const uint32_t index
, const uint32_t val
) {
86 auto& binding
= mBindings
[index
];
87 binding
.layout
.divisor
= val
;
90 void AttribPointer(const uint32_t index
, WebGLBuffer
* const buffer
,
91 const webgl::VertAttribPointerDesc
& desc
,
92 const webgl::VertAttribPointerCalculated
& calc
) {
95 auto& binding
= mBindings
[index
];
96 binding
.buffer
= buffer
;
97 binding
.layout
.byteSize
= calc
.byteSize
;
98 binding
.layout
.byteStride
= calc
.byteStride
;
99 binding
.layout
.baseType
= calc
.baseType
;
100 binding
.layout
.byteOffset
= desc
.byteOffset
;
102 mAttribIsArrayWithNullBuffer
[index
] =
103 binding
.layout
.isArray
&& !binding
.buffer
;
106 const auto& AttribBinding(const uint32_t index
) const {
107 return mBindings
[index
];
109 const auto& AttribDesc(const uint32_t index
) const { return mDescs
[index
]; }
111 Maybe
<uint32_t> GetAttribIsArrayWithNullBuffer() const {
112 const auto& bitset
= mAttribIsArrayWithNullBuffer
;
113 if (MOZ_LIKELY(bitset
.none())) return {};
114 for (const auto i
: IntegerRange(bitset
.size())) {
115 if (bitset
[i
]) return Some(i
);
120 Maybe
<double> GetVertexAttrib(uint32_t index
, GLenum pname
) const;
123 } // namespace mozilla
125 #endif // WEBGL_VERTEX_ARRAY_H_