Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
drmeglserverbufferintegration.cpp
Go to the documentation of this file.
1// Copyright (C) 2017 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
5
6#include <QtOpenGL/QOpenGLTexture>
7#include <QtGui/QOpenGLContext>
8
10
12 : QtWayland::ServerBuffer(qimage.size(),format)
13 , m_integration(integration)
14{
16
17 EGLint egl_format;
18 switch (m_format) {
19 case RGBA32:
20 m_drm_format = QtWaylandServer::qt_drm_egl_server_buffer::format_RGBA32;
21 egl_format = EGL_DRM_BUFFER_FORMAT_ARGB32_MESA;
22 break;
23#ifdef EGL_DRM_BUFFER_FORMAT_A8_MESA
24 case A8:
25 m_drm_format = QtWaylandServer::qt_drm_egl_server_buffer::format_A8;
26 egl_format = EGL_DRM_BUFFER_FORMAT_A8_MESA;
27 break;
28#endif
29 default:
30 qWarning("DrmEglServerBuffer: unsupported format");
31 m_drm_format = QtWaylandServer::qt_drm_egl_server_buffer::format_RGBA32;
32 egl_format = EGL_DRM_BUFFER_FORMAT_ARGB32_MESA;
33 break;
34 }
35 EGLint imageAttribs[] = {
36 EGL_WIDTH, m_size.width(),
37 EGL_HEIGHT, m_size.height(),
38 EGL_DRM_BUFFER_FORMAT_MESA, egl_format,
39 EGL_DRM_BUFFER_USE_MESA, EGL_DRM_BUFFER_USE_SHARE_MESA,
40 EGL_NONE
41 };
42
43 m_image = m_integration->eglCreateDRMImageMESA(imageAttribs);
44
45 EGLint handle;
46 if (!m_integration->eglExportDRMImageMESA(m_image, &m_name, &handle, &m_stride)) {
47 qWarning("DrmEglServerBuffer: Failed to export egl image");
48 }
49
51 m_texture->create();
52 m_texture->bind();
53
54 m_integration->glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, m_image);
55
56 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, qimage.width(), qimage.height(), GL_RGBA, GL_UNSIGNED_BYTE, qimage.constBits());
57
58 m_texture->release();
59 m_texture->setSize(m_size.width(), m_size.height());
60}
61
62struct ::wl_resource *DrmEglServerBuffer::resourceForClient(struct ::wl_client *client)
63{
64 auto *bufferResource = resourceMap().value(client);
65 if (!bufferResource) {
66 auto integrationResource = m_integration->resourceMap().value(client);
67 if (!integrationResource) {
68 qWarning("DrmEglServerBuffer::resourceForClient: Trying to get resource for ServerBuffer. But client is not bound to the drm_egl interface");
69 return nullptr;
70 }
71 struct ::wl_resource *drm_egl_integration_resource = integrationResource->handle;
72 Resource *resource = add(client, 1);
73 m_integration->send_server_buffer_created(drm_egl_integration_resource, resource->handle, m_name, m_size.width(), m_size.height(), m_stride, m_drm_format);
74 return resource->handle;
75 }
76 return bufferResource->handle;
77}
78
79
81{
82 if (!m_texture) {
83 qWarning("DrmEglServerBuffer::toOpenGlTexture: no texture defined");
84 }
85 return m_texture;
86}
87
89{
90 return resourceMap().size() > 0;
91}
92
96
100
102{
104
105 m_egl_display = static_cast<EGLDisplay>(QGuiApplication::platformNativeInterface()->nativeResourceForIntegration("egldisplay"));
106 if (!m_egl_display) {
107 qWarning("Can't initialize drm egl server buffer integration. Missing egl display from platform plugin");
108 return false;
109 }
110
111 const char *extensionString = eglQueryString(m_egl_display, EGL_EXTENSIONS);
112 if (!extensionString || !strstr(extensionString, "EGL_KHR_image")) {
113 qWarning("Failed to initialize drm egl server buffer integration. There is no EGL_KHR_image extension.\n");
114 return false;
115 }
116 m_egl_create_image = reinterpret_cast<PFNEGLCREATEIMAGEKHRPROC>(eglGetProcAddress("eglCreateImageKHR"));
117 m_egl_destroy_image = reinterpret_cast<PFNEGLDESTROYIMAGEKHRPROC>(eglGetProcAddress("eglDestroyImageKHR"));
118 if (!m_egl_create_image || !m_egl_destroy_image) {
119 qWarning("Failed to initialize drm egl server buffer integration. Could not resolve eglCreateImageKHR or eglDestroyImageKHR");
120 return false;
121 }
122
123 if (!extensionString || !strstr(extensionString, "EGL_MESA_drm_image")) {
124 qWarning("Failed to initialize drm egl server buffer integration. There is no EGL_MESA_drm_image extension.\n");
125 return false;
126 }
127
128 m_egl_create_drm_image = reinterpret_cast<PFNEGLCREATEDRMIMAGEMESAPROC>(eglGetProcAddress("eglCreateDRMImageMESA"));
129 m_egl_export_drm_image = reinterpret_cast<PFNEGLEXPORTDRMIMAGEMESAPROC>(eglGetProcAddress("eglExportDRMImageMESA"));
130 if (!m_egl_create_drm_image || !m_egl_export_drm_image) {
131 qWarning("Failed to initialize drm egl server buffer integration. Could not find eglCreateDRMImageMESA or eglExportDRMImageMESA.\n");
132 return false;
133 }
134
135 m_gl_egl_image_target_texture_2d = reinterpret_cast<PFNGLEGLIMAGETARGETTEXTURE2DOESPROC>(eglGetProcAddress("glEGLImageTargetTexture2DOES"));
136 if (!m_gl_egl_image_target_texture_2d) {
137 qWarning("Failed to initialize drm egl server buffer integration. Could not find glEGLImageTargetTexture2DOES.\n");
138 return false;
139 }
140
141 QtWaylandServer::qt_drm_egl_server_buffer::init(compositor->display(), 1);
142 return true;
143}
144
146{
147 switch (format) {
149 return true;
151#ifdef EGL_DRM_BUFFER_FORMAT_A8_MESA
152 return true;
153#else
154 return false;
155#endif
156 default:
157 return false;
158 }
159}
160
165
bool supportsFormat(QtWayland::ServerBuffer::Format format) const override
EGLBoolean eglExportDRMImageMESA(EGLImageKHR image, EGLint *name, EGLint *handle, EGLint *stride)
QtWayland::ServerBuffer * createServerBufferFromImage(const QImage &qimage, QtWayland::ServerBuffer::Format format) override
void glEGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image)
bool initializeHardware(QWaylandCompositor *) override
EGLImageKHR eglCreateDRMImageMESA(const EGLint *attrib_list)
struct::wl_resource * resourceForClient(struct ::wl_client *) override
QOpenGLTexture * toOpenGlTexture() override
DrmEglServerBuffer(DrmEglServerBufferIntegration *integration, const QImage &qimage, QtWayland::ServerBuffer::Format format)
static QPlatformNativeInterface * platformNativeInterface()
\inmodule QtGui
Definition qimage.h:37
\inmodule QtGui
void release()
Unbinds this texture from the currently active texture unit.
bool create()
Creates the underlying OpenGL texture object.
void bind()
Binds this texture to the currently active texture unit ready for rendering.
void setSize(int width, int height=1, int depth=1)
Sets the dimensions of this texture object to width, height, and depth.
constexpr int height() const noexcept
Returns the height.
Definition qsize.h:133
constexpr int width() const noexcept
Returns the width.
Definition qsize.h:130
\qmltype WaylandCompositor \instantiates QWaylandCompositor \inqmlmodule QtWayland....
EGLImageKHR EGLint EGLint * handle
Combined button and popup list for selecting options.
typedef EGLDisplay(EGLAPIENTRYP PFNEGLGETPLATFORMDISPLAYEXTPROC)(EGLenum platform
#define qWarning
Definition qlogging.h:166
static QOpenGLCompositor * compositor
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLint GLsizei GLsizei GLenum format
static void add(QPainterPath &path, const QWingedEdge &list, int edge, QPathEdge::Traversal traversal)
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
#define GL_UNSIGNED_BYTE
#define GL_RGBA