1 | // Copyright (C) 2016 Klaralvdalens Datakonsult AB (KDAB). |
---|---|
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
3 | |
4 | #include "openglvertexarrayobject_p.h" |
5 | #include <submissioncontext_p.h> |
6 | #include <renderer_p.h> |
7 | #include <glresourcemanagers_p.h> |
8 | #include <Qt3DRender/private/managers_p.h> |
9 | |
10 | QT_BEGIN_NAMESPACE |
11 | |
12 | namespace Qt3DRender { |
13 | namespace Render { |
14 | namespace OpenGL { |
15 | |
16 | OpenGLVertexArrayObject::OpenGLVertexArrayObject() |
17 | : m_ctx(nullptr) |
18 | , m_specified(false) |
19 | , m_supportsVao(false) |
20 | {} |
21 | |
22 | void OpenGLVertexArrayObject::bind() |
23 | { |
24 | Q_ASSERT(m_ctx); |
25 | if (m_supportsVao) { |
26 | Q_ASSERT(!m_vao.isNull()); |
27 | Q_ASSERT(m_vao->isCreated()); |
28 | m_vao->bind(); |
29 | } else { |
30 | // Unbind any other VAO that may have been bound and not released correctly |
31 | if (m_ctx->m_currentVAO != nullptr && m_ctx->m_currentVAO != this) |
32 | m_ctx->m_currentVAO->release(); |
33 | |
34 | m_ctx->m_currentVAO = this; |
35 | // We need to specify array and vertex attributes |
36 | for (const SubmissionContext::VAOVertexAttribute &attr : m_vertexAttributes) |
37 | m_ctx->enableAttribute(attr); |
38 | if (!m_indexAttribute.isNull()) |
39 | m_ctx->bindGLBuffer(buffer: m_ctx->m_renderer->glResourceManagers()->glBufferManager()->data(handle: m_indexAttribute), |
40 | type: GLBuffer::IndexBuffer); |
41 | } |
42 | } |
43 | |
44 | void OpenGLVertexArrayObject::release() |
45 | { |
46 | Q_ASSERT(m_ctx); |
47 | if (m_supportsVao) { |
48 | Q_ASSERT(!m_vao.isNull()); |
49 | Q_ASSERT(m_vao->isCreated()); |
50 | m_vao->release(); |
51 | } else { |
52 | if (m_ctx->m_currentVAO == this) { |
53 | for (const SubmissionContext::VAOVertexAttribute &attr : m_vertexAttributes) |
54 | m_ctx->disableAttribute(attr); |
55 | m_ctx->m_currentVAO = nullptr; |
56 | } |
57 | } |
58 | } |
59 | |
60 | // called from Render thread |
61 | void OpenGLVertexArrayObject::create(SubmissionContext *ctx, const VAOIdentifier &key) |
62 | { |
63 | QMutexLocker lock(&m_mutex); |
64 | |
65 | Q_ASSERT(!m_ctx && !m_vao); |
66 | |
67 | m_ctx = ctx; |
68 | m_supportsVao = m_ctx->supportsVAO(); |
69 | if (m_supportsVao) { |
70 | m_vao.reset(other: new QOpenGLVertexArrayObject()); |
71 | m_vao->create(); |
72 | } |
73 | m_owners = key; |
74 | } |
75 | |
76 | VAOIdentifier OpenGLVertexArrayObject::key() const |
77 | { |
78 | return m_owners; |
79 | } |
80 | |
81 | // called from Render thread |
82 | void OpenGLVertexArrayObject::destroy() |
83 | { |
84 | QMutexLocker locker(&m_mutex); |
85 | |
86 | Q_ASSERT(m_ctx); |
87 | cleanup(); |
88 | } |
89 | |
90 | void OpenGLVertexArrayObject::cleanup() |
91 | { |
92 | m_vao.reset(); |
93 | m_ctx = nullptr; |
94 | m_specified = false; |
95 | m_supportsVao = false; |
96 | m_indexAttribute = SubmissionContext::VAOIndexAttribute(); |
97 | m_vertexAttributes.clear(); |
98 | } |
99 | |
100 | // called from job |
101 | bool OpenGLVertexArrayObject::isAbandoned(GeometryManager *geomMgr, GLShaderManager *shaderMgr) |
102 | { |
103 | QMutexLocker lock(&m_mutex); |
104 | |
105 | if (!m_ctx) |
106 | return false; |
107 | |
108 | const bool geometryExists = (geomMgr->data(handle: m_owners.first) != nullptr); |
109 | const bool shaderExists = (shaderMgr->lookupResource(shaderId: m_owners.second) != nullptr); |
110 | |
111 | return !geometryExists || !shaderExists; |
112 | } |
113 | |
114 | void OpenGLVertexArrayObject::saveVertexAttribute(const SubmissionContext::VAOVertexAttribute &attr) |
115 | { |
116 | // Remove any vertexAttribute already at location |
117 | m_vertexAttributes.erase(first: std::remove_if(first: m_vertexAttributes.begin(), |
118 | last: m_vertexAttributes.end(), |
119 | pred: [attr](const SubmissionContext::VAOVertexAttribute &a) { |
120 | return a.location == attr.location; |
121 | }), |
122 | last: m_vertexAttributes.end()); |
123 | m_vertexAttributes.push_back(x: attr); |
124 | } |
125 | |
126 | |
127 | } // namespace OpenGL |
128 | } // namespace Render |
129 | } // namespace Qt3DRender |
130 | |
131 | QT_END_NAMESPACE |
132 |