5#include <QtWaylandClient/private/qwaylanddisplay_p.h>
7#include <QtOpenGL/QOpenGLTexture>
8#include <QtGui/QOpenGLContext>
11#include <EGL/eglext.h>
18 ,
struct ::qt_server_buffer *id
24 , int32_t fourcc_format)
25 : m_integration(integration)
28 m_size = QSize(width, height);
31 EGLint import_attribs[] = {
34 EGL_LINUX_DRM_FOURCC_EXT, fourcc_format,
35 EGL_DMA_BUF_PLANE0_FD_EXT, fd,
36 EGL_DMA_BUF_PLANE0_OFFSET_EXT, offset,
37 EGL_DMA_BUF_PLANE0_PITCH_EXT, stride,
43 EGL_LINUX_DMA_BUF_EXT
,
44 (EGLClientBuffer)
nullptr,
47 int err = eglGetError();
48 qCDebug(lcQpaWayland) <<
"imported egl image" << m_image;
49 if (m_image == EGL_NO_IMAGE_KHR || err != EGL_SUCCESS)
50 qCWarning(lcQpaWayland) <<
"DmaBufServerBuffer error importing image. EGL error code" << Qt::hex << err;
52 qt_server_buffer_set_user_data(id,
this);
59 if (err != EGL_SUCCESS)
60 qCWarning(lcQpaWayland) <<
"~DmaBufServerBuffer error destroying image" << m_image <<
"error code " << Qt::hex << err;
61 qt_server_buffer_release(m_server_buffer);
62 qt_server_buffer_destroy(m_server_buffer);
67 if (!QOpenGLContext::currentContext())
68 qCWarning(lcQpaWayland) <<
"DmaBufServerBuffer: creating texture with no current context";
71 m_texture =
new QOpenGLTexture(QOpenGLTexture::Target2D);
76 m_integration->glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, m_image);
77 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
78 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
79 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
80 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
82 m_texture->setSize(m_size.width(), m_size.height());
88 if (m_egl_initialized)
90 m_egl_initialized =
true;
92 m_egl_display = eglGetDisplay((EGLNativeDisplayType) m_display->wl_display());
93 if (m_egl_display == EGL_NO_DISPLAY) {
94 qCWarning(lcQpaWayland) <<
"Failed to initialize drm egl server buffer integration. Could not get egl display from wl_display.";
98 const char *extensionString = eglQueryString(m_egl_display, EGL_EXTENSIONS);
101 if (!extensionString || !strstr(extensionString,
"EGL_KHR_image")) {
102 qCWarning(lcQpaWayland) <<
"Failed to initialize dmabuf server buffer integration. There is no EGL_KHR_image extension.\n";
105 m_egl_create_image =
reinterpret_cast<PFNEGLCREATEIMAGEKHRPROC>(eglGetProcAddress(
"eglCreateImageKHR"));
106 m_egl_destroy_image =
reinterpret_cast<PFNEGLDESTROYIMAGEKHRPROC>(eglGetProcAddress(
"eglDestroyImageKHR"));
107 if (!m_egl_create_image || !m_egl_destroy_image) {
108 qCWarning(lcQpaWayland) <<
"Failed to initialize dmabuf server buffer integration. Could not resolve eglCreateImageKHR or eglDestroyImageKHR";
112 m_gl_egl_image_target_texture =
reinterpret_cast<PFNGLEGLIMAGETARGETTEXTURE2DOESPROC>(eglGetProcAddress(
"glEGLImageTargetTexture2DOES"));
113 if (!m_gl_egl_image_target_texture) {
114 qCWarning(lcQpaWayland) <<
"Failed to initialize dmabuf server buffer integration. Could not resolve glEGLImageTargetTexture2DOES";
122 display->addRegistryListener(&wlDisplayHandleGlobal,
this);
127 return static_cast<QWaylandServerBuffer *>(qt_server_buffer_get_user_data(buffer));
130void DmaBufServerBufferIntegration::wlDisplayHandleGlobal(
void *data, ::wl_registry *registry, uint32_t id,
const QString &interface, uint32_t version)
133 if (interface == QStringLiteral(
"qt_dmabuf_server_buffer")) {
135 integration->QtWayland::qt_dmabuf_server_buffer::init(registry, id, 1);
EGLImageKHR eglCreateImageKHR(EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list)
EGLBoolean eglDestroyImageKHR(EGLImageKHR image)
void initialize(QWaylandDisplay *display) override
QOpenGLTexture * toOpenGlTexture() override
~DmaBufServerBuffer() override
Combined button and popup list for selecting options.