Skip to content

Commit 2ed5f96

Browse files
committed
Create EGLImage with eglCreateDRMImageMESA() for exporting dma_buf
This simplifies the code because it is not needed to create OpenGL texture to allocate buffer. This way we can get rid of creating a temporary OpenGL context and swapping EGLSurface. Moreover, eglCreateImage() does not guarantee that the buffer is shareable thus certain GPU drivers may fail to export. Pick-to: 6.9 Fixes: QTBUG-136257 Done-with: Jan Palus Change-Id: Ie72d052a2a8b1a41bebf0eab8a4928d38c8fc864 Reviewed-by: Allan Sandfeld Jensen <[email protected]> Reviewed-by: Jan Palus <[email protected]>
1 parent 782efdf commit 2ed5f96

File tree

2 files changed

+16
-91
lines changed

2 files changed

+16
-91
lines changed

src/core/ozone/egl_helper.cpp

Lines changed: 14 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -58,90 +58,14 @@ static const char *getEGLErrorString(uint32_t error)
5858

5959
QT_BEGIN_NAMESPACE
6060

61-
class ScopedGLContext
62-
{
63-
public:
64-
ScopedGLContext(QOffscreenSurface *surface, EGLHelper::EGLFunctions *eglFun)
65-
: m_context(new QOpenGLContext()), m_eglFun(eglFun)
66-
{
67-
if ((m_previousEGLContext = m_eglFun->eglGetCurrentContext())) {
68-
m_previousEGLDrawSurface = m_eglFun->eglGetCurrentSurface(EGL_DRAW);
69-
m_previousEGLReadSurface = m_eglFun->eglGetCurrentSurface(EGL_READ);
70-
m_previousEGLDisplay = m_eglFun->eglGetCurrentDisplay();
71-
}
72-
73-
if (!m_context->create()) {
74-
qWarning("Failed to create OpenGL context.");
75-
return;
76-
}
77-
78-
Q_ASSERT(surface->isValid());
79-
if (!m_context->makeCurrent(surface)) {
80-
qWarning("Failed to make OpenGL context current.");
81-
return;
82-
}
83-
}
84-
85-
~ScopedGLContext()
86-
{
87-
if (!m_textures.empty()) {
88-
auto *glFun = m_context->functions();
89-
glFun->glDeleteTextures(m_textures.size(), m_textures.data());
90-
}
91-
92-
if (m_previousEGLContext) {
93-
// Make sure the scoped context is not current when restoring the previous
94-
// EGL context otherwise the QOpenGLContext destructor resets the restored
95-
// current context.
96-
m_context->doneCurrent();
97-
98-
m_eglFun->eglMakeCurrent(m_previousEGLDisplay, m_previousEGLDrawSurface,
99-
m_previousEGLReadSurface, m_previousEGLContext);
100-
if (m_eglFun->eglGetError() != EGL_SUCCESS)
101-
qWarning("Failed to restore EGL context.");
102-
}
103-
}
104-
105-
bool isValid() const { return m_context->isValid() && (m_context->surface() != nullptr); }
106-
107-
EGLContext eglContext() const
108-
{
109-
QNativeInterface::QEGLContext *nativeInterface =
110-
m_context->nativeInterface<QNativeInterface::QEGLContext>();
111-
return nativeInterface->nativeContext();
112-
}
113-
114-
uint createTexture(int width, int height)
115-
{
116-
auto *glFun = m_context->functions();
117-
118-
uint glTexture;
119-
glFun->glGenTextures(1, &glTexture);
120-
glFun->glBindTexture(GL_TEXTURE_2D, glTexture);
121-
glFun->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE,
122-
NULL);
123-
glFun->glBindTexture(GL_TEXTURE_2D, 0);
124-
125-
m_textures.push_back(glTexture);
126-
return glTexture;
127-
}
128-
129-
private:
130-
QScopedPointer<QOpenGLContext> m_context;
131-
EGLHelper::EGLFunctions *m_eglFun;
132-
EGLContext m_previousEGLContext = nullptr;
133-
EGLSurface m_previousEGLDrawSurface = nullptr;
134-
EGLSurface m_previousEGLReadSurface = nullptr;
135-
EGLDisplay m_previousEGLDisplay = nullptr;
136-
std::vector<uint> m_textures;
137-
};
138-
13961
EGLHelper::EGLFunctions::EGLFunctions()
14062
{
14163
QOpenGLContext *context = OzoneUtilQt::getQOpenGLContext();
14264

14365
eglCreateImage =
14466
reinterpret_cast<PFNEGLCREATEIMAGEPROC>(context->getProcAddress("eglCreateImage"));
67+
eglCreateDRMImageMESA = reinterpret_cast<PFNEGLCREATEDRMIMAGEMESAPROC>(
68+
context->getProcAddress("eglCreateDRMImageMESA"));
14569
eglDestroyImage =
14670
reinterpret_cast<PFNEGLDESTROYIMAGEPROC>(context->getProcAddress("eglDestroyImage"));
14771
eglExportDMABUFImageMESA = reinterpret_cast<PFNEGLEXPORTDMABUFIMAGEMESAPROC>(
@@ -198,6 +122,7 @@ EGLHelper::EGLHelper()
198122
const char *displayExtensions = m_functions->eglQueryString(m_eglDisplay, EGL_EXTENSIONS);
199123
m_isDmaBufSupported = strstr(displayExtensions, "EGL_EXT_image_dma_buf_import")
200124
&& strstr(displayExtensions, "EGL_EXT_image_dma_buf_import_modifiers")
125+
&& strstr(displayExtensions, "EGL_MESA_drm_image")
201126
&& strstr(displayExtensions, "EGL_MESA_image_dma_buf_export");
202127
}
203128

@@ -218,19 +143,17 @@ void EGLHelper::queryDmaBuf(const int width, const int height, int *fd, int *str
218143
if (!m_isDmaBufSupported)
219144
return;
220145

221-
ScopedGLContext context(m_offscreenSurface.get(), m_functions.get());
222-
if (!context.isValid())
223-
return;
224-
225-
EGLContext eglContext = context.eglContext();
226-
if (!eglContext) {
227-
qWarning("EGL: No EGLContext.");
228-
return;
229-
}
230-
231-
uint64_t textureId = context.createTexture(width, height);
232-
EGLImage eglImage = m_functions->eglCreateImage(m_eglDisplay, eglContext, EGL_GL_TEXTURE_2D,
233-
(EGLClientBuffer)textureId, NULL);
146+
// clang-format off
147+
EGLint attribs[] = {
148+
EGL_WIDTH, width,
149+
EGL_HEIGHT, height,
150+
EGL_DRM_BUFFER_FORMAT_MESA, EGL_DRM_BUFFER_FORMAT_ARGB32_MESA,
151+
EGL_DRM_BUFFER_USE_MESA, EGL_DRM_BUFFER_USE_SHARE_MESA,
152+
EGL_NONE
153+
};
154+
// clang-format on
155+
156+
EGLImage eglImage = m_functions->eglCreateDRMImageMESA(m_eglDisplay, attribs);
234157
if (eglImage == EGL_NO_IMAGE) {
235158
qWarning("EGL: Failed to create EGLImage: %s", getLastEGLErrorString());
236159
return;

src/core/ozone/egl_helper.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <EGL/eglext.h>
1212

1313
#undef eglCreateImage
14+
#undef eglCreateDRMImageMESA
1415
#undef eglDestroyImage
1516
#undef eglExportDMABUFImageMESA
1617
#undef eglExportDMABUFImageQueryMESA
@@ -33,6 +34,7 @@ class EGLHelper
3334
EGLFunctions();
3435

3536
PFNEGLCREATEIMAGEPROC eglCreateImage;
37+
PFNEGLCREATEDRMIMAGEMESAPROC eglCreateDRMImageMESA;
3638
PFNEGLDESTROYIMAGEPROC eglDestroyImage;
3739
PFNEGLEXPORTDMABUFIMAGEMESAPROC eglExportDMABUFImageMESA;
3840
PFNEGLEXPORTDMABUFIMAGEQUERYMESAPROC eglExportDMABUFImageQueryMESA;

0 commit comments

Comments
 (0)