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
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// Qt-Security score:critical reason:network-protocol
4
6
7#include <QtOpenGL/QOpenGLTexture>
8#include <QtGui/QOpenGLContext>
9
11
12DrmEglServerBuffer::DrmEglServerBuffer(DrmEglServerBufferIntegration *integration, const QImage &qimage, QtWayland::ServerBuffer::Format format)
13 : QtWayland::ServerBuffer(qimage.size(),format)
14 , m_integration(integration)
15{
16 m_format = format;
17
18 EGLint egl_format;
19 switch (m_format) {
20 case RGBA32:
21 m_drm_format = QtWaylandServer::qt_drm_egl_server_buffer::format_RGBA32;
22 egl_format = EGL_DRM_BUFFER_FORMAT_ARGB32_MESA;
23 break;
24#ifdef EGL_DRM_BUFFER_FORMAT_A8_MESA
25 case A8:
26 m_drm_format = QtWaylandServer::qt_drm_egl_server_buffer::format_A8;
27 egl_format = EGL_DRM_BUFFER_FORMAT_A8_MESA;
28 break;
29#endif
30 default:
31 qWarning("DrmEglServerBuffer: unsupported format");
32 m_drm_format = QtWaylandServer::qt_drm_egl_server_buffer::format_RGBA32;
33 egl_format = EGL_DRM_BUFFER_FORMAT_ARGB32_MESA;
34 break;
35 }
36 EGLint imageAttribs[] = {
37 EGL_WIDTH, m_size.width(),
38 EGL_HEIGHT, m_size.height(),
39 EGL_DRM_BUFFER_FORMAT_MESA, egl_format,
40 EGL_DRM_BUFFER_USE_MESA, EGL_DRM_BUFFER_USE_SHARE_MESA,
41 EGL_NONE
42 };
43
44 m_image = m_integration->eglCreateDRMImageMESA(imageAttribs);
45
46 EGLint handle;
47 if (!m_integration->eglExportDRMImageMESA(m_image, &m_name, &handle, &m_stride)) {
48 qWarning("DrmEglServerBuffer: Failed to export egl image");
49 }
50
51 m_texture = new QOpenGLTexture(QOpenGLTexture::Target2D);
52 m_texture->create();
53 m_texture->bind();
54
55 m_integration->glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, m_image);
56
57 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, qimage.width(), qimage.height(), GL_RGBA, GL_UNSIGNED_BYTE, qimage.constBits());
58
59 m_texture->release();
60 m_texture->setSize(m_size.width(), m_size.height());
61}
62
63struct ::wl_resource *DrmEglServerBuffer::resourceForClient(struct ::wl_client *client)
64{
65 auto *bufferResource = resourceMap().value(client);
66 if (!bufferResource) {
67 auto integrationResource = m_integration->resourceMap().value(client);
68 if (!integrationResource) {
69 qWarning("DrmEglServerBuffer::resourceForClient: Trying to get resource for ServerBuffer. But client is not bound to the drm_egl interface");
70 return nullptr;
71 }
72 struct ::wl_resource *drm_egl_integration_resource = integrationResource->handle;
73 Resource *resource = add(client, 1);
74 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);
75 return resource->handle;
76 }
77 return bufferResource->handle;
78}
79
80
82{
83 if (!m_texture) {
84 qWarning("DrmEglServerBuffer::toOpenGlTexture: no texture defined");
85 }
86 return m_texture;
87}
88
90{
91 return resourceMap().size() > 0;
92}
93
97
101
102bool DrmEglServerBufferIntegration::initializeHardware(QWaylandCompositor *compositor)
103{
104 Q_ASSERT(QGuiApplication::platformNativeInterface());
105
106 m_egl_display = static_cast<EGLDisplay>(QGuiApplication::platformNativeInterface()->nativeResourceForIntegration("egldisplay"));
107 if (!m_egl_display) {
108 qWarning("Can't initialize drm egl server buffer integration. Missing egl display from platform plugin");
109 return false;
110 }
111
112 const char *extensionString = eglQueryString(m_egl_display, EGL_EXTENSIONS);
113 if (!extensionString || !strstr(extensionString, "EGL_KHR_image")) {
114 qWarning("Failed to initialize drm egl server buffer integration. There is no EGL_KHR_image extension.\n");
115 return false;
116 }
117 m_egl_create_image = reinterpret_cast<PFNEGLCREATEIMAGEKHRPROC>(eglGetProcAddress("eglCreateImageKHR"));
118 m_egl_destroy_image = reinterpret_cast<PFNEGLDESTROYIMAGEKHRPROC>(eglGetProcAddress("eglDestroyImageKHR"));
119 if (!m_egl_create_image || !m_egl_destroy_image) {
120 qWarning("Failed to initialize drm egl server buffer integration. Could not resolve eglCreateImageKHR or eglDestroyImageKHR");
121 return false;
122 }
123
124 if (!extensionString || !strstr(extensionString, "EGL_MESA_drm_image")) {
125 qWarning("Failed to initialize drm egl server buffer integration. There is no EGL_MESA_drm_image extension.\n");
126 return false;
127 }
128
129 m_egl_create_drm_image = reinterpret_cast<PFNEGLCREATEDRMIMAGEMESAPROC>(eglGetProcAddress("eglCreateDRMImageMESA"));
130 m_egl_export_drm_image = reinterpret_cast<PFNEGLEXPORTDRMIMAGEMESAPROC>(eglGetProcAddress("eglExportDRMImageMESA"));
131 if (!m_egl_create_drm_image || !m_egl_export_drm_image) {
132 qWarning("Failed to initialize drm egl server buffer integration. Could not find eglCreateDRMImageMESA or eglExportDRMImageMESA.\n");
133 return false;
134 }
135
136 m_gl_egl_image_target_texture_2d = reinterpret_cast<PFNGLEGLIMAGETARGETTEXTURE2DOESPROC>(eglGetProcAddress("glEGLImageTargetTexture2DOES"));
137 if (!m_gl_egl_image_target_texture_2d) {
138 qWarning("Failed to initialize drm egl server buffer integration. Could not find glEGLImageTargetTexture2DOES.\n");
139 return false;
140 }
141
142 QtWaylandServer::qt_drm_egl_server_buffer::init(compositor->display(), 1);
143 return true;
144}
145
146bool DrmEglServerBufferIntegration::supportsFormat(QtWayland::ServerBuffer::Format format) const
147{
148 switch (format) {
149 case QtWayland::ServerBuffer::RGBA32:
150 return true;
151 case QtWayland::ServerBuffer::A8:
152#ifdef EGL_DRM_BUFFER_FORMAT_A8_MESA
153 return true;
154#else
155 return false;
156#endif
157 default:
158 return false;
159 }
160}
161
162QtWayland::ServerBuffer *DrmEglServerBufferIntegration::createServerBufferFromImage(const QImage &qimage, QtWayland::ServerBuffer::Format format)
163{
164 return new DrmEglServerBuffer(this, qimage, format);
165}
166
167QT_END_NAMESPACE
bool supportsFormat(QtWayland::ServerBuffer::Format format) const override
QtWayland::ServerBuffer * createServerBufferFromImage(const QImage &qimage, QtWayland::ServerBuffer::Format format) override
bool initializeHardware(QWaylandCompositor *) override
QOpenGLTexture * toOpenGlTexture() override
Combined button and popup list for selecting options.