Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qvivantetextureimporter.cpp
Go to the documentation of this file.
1// Copyright (C) 2026 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
5
6#include <QtMultimedia/private/qvideotexturehelper_p.h>
7
8#include <QtGui/rhi/qrhi.h>
9#include <QtCore/qloggingcategory.h>
10#include <QtCore/qscopeguard.h>
11
12#include <EGL/egl.h>
13
14static_assert(QT_CONFIG(gpu_vivante));
15
17
18Q_STATIC_LOGGING_CATEGORY(qLVivante, "qt.multimedia.vivante");
19
20namespace QtMultimediaPrivate {
21
23{
25 eglGetProcAddress("glTexDirectVIVMap"));
27 eglGetProcAddress("glTexDirectInvalidateVIV"));
28}
29
35
40
47
52
54{
55 if (!rhi || rhi->backend() != QRhi::OpenGLES2) {
56 qCDebug(qLVivante) << "VivanteContext: no rhi or non OpenGLES2 based RHI";
57 return;
58 }
59
60 auto *nativeHandles = static_cast<const QRhiGles2NativeHandles *>(rhi->nativeHandles());
62 if (!m_glContext) {
63 qCDebug(qLVivante) << " no GL context, disabling";
64 return;
65 }
66
69 << " glTexDirectVIVMap/glTexDirectInvalidateVIV not resolved, disabling";
70 return;
71 }
72
73 m_valid = true;
74}
75
87
95
97{
101 m_released = true;
102}
103
105importVivanteTexture(QRhi &rhi, const VivanteContext &context, quint32 physicalAddress,
106 void *logicalAddr, QSize size, GLenum vivFormatToken,
107 std::shared_ptr<void> parentKeepAlive)
108{
109 qCDebug(qLVivante) << "Importing texture from Vivante phys-mem buffer";
110 QOpenGLContext *glContext = context.glContext();
111 QOpenGLFunctions functions(glContext);
112 const auto &vivFunctions = QVivanteGLFunctions::instance();
113
114 rhi.makeThreadLocalNativeContextCurrent();
115
116 GLuint texture = 0;
117 functions.glGenTextures(1, &texture);
118
119 auto releaseTexture = qScopeGuard([&] {
120 functions.glDeleteTextures(1, &texture);
121 });
122
123 functions.glActiveTexture(GL_TEXTURE0);
124 functions.glBindTexture(GL_TEXTURE_2D, texture);
125
126 // Each QVideoFrame maps a fresh address, so glTexDirectVIVMap (map the
127 // address into the texture) and glTexDirectInvalidateVIV (tell the
128 // driver the content changed) are both called unconditionally on every
129 // import.
130 const GLuint physical = physicalAddress;
131 vivFunctions.glTexDirectVIVMap(GL_TEXTURE_2D, size.width(), size.height(), vivFormatToken,
132 &logicalAddr, &physical);
133 if (const GLenum error = functions.glGetError(); error != GL_NO_ERROR) {
134 qCWarning(qLVivante) << "glTexDirectVIVMap failed with GL error" << Qt::hex << error
135 << "for format token" << vivFormatToken << Qt::dec << "size" << size;
136 functions.glBindTexture(GL_TEXTURE_2D, 0);
137 return q23::unexpected{ FailureSeverity::recoverable };
138 }
139
140 vivFunctions.glTexDirectInvalidateVIV(GL_TEXTURE_2D);
141 if (const GLenum error = functions.glGetError(); error != GL_NO_ERROR) {
142 qCWarning(qLVivante) << "glTexDirectInvalidateVIV failed with GL error" << Qt::hex
143 << error;
144 functions.glBindTexture(GL_TEXTURE_2D, 0);
145 return q23::unexpected{ FailureSeverity::recoverable };
146 }
147
148 functions.glBindTexture(GL_TEXTURE_2D, 0);
149 releaseTexture.dismiss();
150
151 return std::make_unique<VivanteTextureHandles>(rhi, glContext, texture,
152 std::move(parentKeepAlive));
153}
154
155} // namespace QtMultimediaPrivate
156
157QT_END_NAMESPACE
q23::expected< QVideoFrameTexturesHandlesUPtr, FailureSeverity > importVivanteTexture(QRhi &rhi, const VivanteContext &context, quint32 physicalAddress, void *logicalAddr, QSize size, GLenum vivFormatToken, std::shared_ptr< void > parentKeepAlive)
QT_BEGIN_NAMESPACE Q_STATIC_LOGGING_CATEGORY(lcSynthesizedIterableAccess, "qt.iterable.synthesized", QtWarningMsg)