Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
libhybriseglserverbufferintegration.cpp
Go to the documentation of this file.
1// Copyright (C) 2017 Jolla Ltd, author: <giulio.camuffo@jollamobile.com>
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
5
6#include <QtGui/QOpenGLContext>
7#include <QtGui/QOpenGLTexture>
8#include <hybris/eglplatformcommon/hybris_nativebufferext.h>
9#include <wayland-server-core.h>
10
13 : QtWayland::ServerBuffer(qimage.size(),format)
14 , m_integration(integration)
15{
17
18 EGLint egl_format;
19 switch (m_format) {
20 case RGBA32:
21 m_hybris_format = QtWaylandServer::qt_libhybris_egl_server_buffer::format_RGBA32;
22 egl_format = HYBRIS_PIXEL_FORMAT_RGBA_8888;
23 break;
24 default:
25 qWarning("LibHybrisEglServerBuffer: unsupported format");
26 m_hybris_format = QtWaylandServer::qt_libhybris_egl_server_buffer::format_RGBA32;
27 egl_format = HYBRIS_PIXEL_FORMAT_RGBA_8888;
28 break;
29 }
30
31 if (!m_integration->eglHybrisCreateNativeBuffer(m_size.width(), m_size.height(), HYBRIS_USAGE_HW_TEXTURE, egl_format, &m_stride, &m_buffer)) {
32 qWarning("LibHybrisEglServerBuffer: Failed to create egl buffer");
33 return;
34 }
35
36 int numInts;
37 int numFds;
38 m_integration->eglHybrisGetNativeBufferInfo(m_buffer, &numInts, &numFds);
39 m_ints.resize(numInts);
40 m_fds.resize(numFds);
41 m_integration->eglHybrisSerializeNativeBuffer(m_buffer, m_ints.data(), m_fds.data());
42
43 m_image = m_integration->eglCreateImageKHR(EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID, m_buffer, 0);
44
46 qWarning("LibHybrisEglServerBuffer: No current context when creating buffer. Texture loading will fail");
47 return;
48 }
49
51 m_texture->create();
52
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 *LibHybrisEglServerBuffer::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("LibHybrisEglServerBuffer::resourceForClient: Trying to get resource for ServerBuffer. But client is not bound to the libhybris_egl interface");
70 return 0;
71 }
72 struct ::wl_resource *egl_integration_resource = integrationResource->handle;
73 Resource *resource = add(client, 1);
74 wl_resource *bufRes = wl_resource_create(client, &qt_libhybris_buffer_interface,-1, 0);
75
76 m_integration->send_server_buffer_created(egl_integration_resource, resource->handle, bufRes, m_fds.size(), QByteArray((char *)m_ints.data(), m_ints.size() * sizeof(int32_t)),
77 m_name, m_size.width(), m_size.height(), m_stride, m_format);
78
79 for (int i = 0; i < m_fds.size(); ++i) {
80 send_add_fd(resource->handle, m_fds.at(i));
81 }
82
83 return resource->handle;
84 }
85 return bufferResource->handle;
86}
87
89{
90 return m_texture;
91}
92
94{
95}
96
98{
99}
100
102{
104
105 m_egl_display = static_cast<EGLDisplay>(QGuiApplication::platformNativeInterface()->nativeResourceForIntegration("egldisplay"));
106 if (!m_egl_display) {
107 qWarning("Can't initialize libhybris egl server buffer integration. Missing egl display from platform plugin");
108 return false;
109 }
110
111 m_egl_create_buffer = reinterpret_cast<PFNEGLHYBRISCREATENATIVEBUFFERPROC>(eglGetProcAddress("eglHybrisCreateNativeBuffer"));
112 if (!m_egl_create_buffer) {
113 qWarning("Failed to initialize libhybris egl server buffer integration. Could not find eglHybrisCreateNativeBuffer.\n");
114 return false;
115 }
116 m_egl_get_buffer_info = reinterpret_cast<PFNEGLHYBRISGETNATIVEBUFFERINFOPROC>(eglGetProcAddress("eglHybrisGetNativeBufferInfo"));
117 if (!m_egl_get_buffer_info) {
118 qWarning("Failed to initialize libhybris egl server buffer integration. Could not find eglHybrisGetNativeBufferInfo.\n");
119 return false;
120 }
121 m_egl_serialize_buffer = reinterpret_cast<PFNEGLHYBRISSERIALIZENATIVEBUFFERPROC>(eglGetProcAddress("eglHybrisSerializeNativeBuffer"));
122 if (!m_egl_serialize_buffer) {
123 qWarning("Failed to initialize libhybris egl server buffer integration. Could not find eglHybrisSerializeNativeBuffer.\n");
124 return false;
125 }
126
127 const char *extensionString = eglQueryString(m_egl_display, EGL_EXTENSIONS);
128 if (!extensionString || !strstr(extensionString, "EGL_KHR_image")) {
129 qWarning("Failed to initialize libhybris egl server buffer integration. There is no EGL_KHR_image extension.\n");
130 return false;
131 }
132 m_egl_create_image = reinterpret_cast<PFNEGLCREATEIMAGEKHRPROC>(eglGetProcAddress("eglCreateImageKHR"));
133 m_egl_destroy_image = reinterpret_cast<PFNEGLDESTROYIMAGEKHRPROC>(eglGetProcAddress("eglDestroyImageKHR"));
134 if (!m_egl_create_image || !m_egl_destroy_image) {
135 qWarning("Failed to initialize libhybris egl server buffer integration. Could not resolve eglCreateImageKHR or eglDestroyImageKHR");
136 return false;
137 }
138
139 m_gl_egl_image_target_texture_2d = reinterpret_cast<PFNGLEGLIMAGETARGETTEXTURE2DOESPROC>(eglGetProcAddress("glEGLImageTargetTexture2DOES"));
140 if (!m_gl_egl_image_target_texture_2d) {
141 qWarning("Failed to initialize libhybris egl server buffer integration. Could not find glEGLImageTargetTexture2DOES.\n");
142 return false;
143 }
144
145 QtWaylandServer::qt_libhybris_egl_server_buffer::init(compositor->display(), 1);
146 return true;
147}
148
150{
151 switch (format) {
153 return true;
155 return false;
156 default:
157 return false;
158 }
159}
160
162{
163 return new LibHybrisEglServerBuffer(this, qimage, format);
164}
165
EGLBoolean eglHybrisCreateNativeBuffer(EGLint width, EGLint height, EGLint usage, EGLint format, EGLint *stride, EGLClientBuffer *buffer)
void eglHybrisSerializeNativeBuffer(EGLClientBuffer buffer, int *ints, int *fds)
EGLImageKHR eglCreateImageKHR(EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list)
bool supportsFormat(QtWayland::ServerBuffer::Format format) const override
void eglHybrisGetNativeBufferInfo(EGLClientBuffer buffer, int *num_ints, int *num_fds)
QtWayland::ServerBuffer * createServerBufferFromImage(const QImage &qimage, QtWayland::ServerBuffer::Format format) override
void glEGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image)
LibHybrisEglServerBuffer(LibHybrisEglServerBufferIntegration *integration, const QImage &qimage, QtWayland::ServerBuffer::Format format)
struct::wl_resource * resourceForClient(struct ::wl_client *) override
\inmodule QtCore
Definition qbytearray.h:57
static QPlatformNativeInterface * platformNativeInterface()
\inmodule QtGui
Definition qimage.h:37
int width() const
Returns the width of the image.
int height() const
Returns the height of the image.
const uchar * constBits() const
Returns a pointer to the first pixel data.
Definition qimage.cpp:1713
qsizetype size() const noexcept
Definition qlist.h:386
const_reference at(qsizetype i) const noexcept
Definition qlist.h:429
pointer data()
Definition qlist.h:414
void resize(qsizetype size)
Definition qlist.h:392
static QOpenGLContext * currentContext()
Returns the last context which called makeCurrent in the current thread, or \nullptr,...
\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.
virtual void * nativeResourceForIntegration(const QByteArray &resource)
constexpr int height() const noexcept
Returns the height.
Definition qsize.h:132
constexpr int width() const noexcept
Returns the width.
Definition qsize.h:129
\qmltype WaylandCompositor \instantiates QWaylandCompositor \inqmlmodule QtWayland....
EGLint EGLint EGLint format
Combined button and popup list for selecting options.
typedef EGLDisplay(EGLAPIENTRYP PFNEGLGETPLATFORMDISPLAYEXTPROC)(EGLenum platform
#define qWarning
Definition qlogging.h:162
static QOpenGLCompositor * compositor
GLenum GLuint GLintptr GLsizeiptr size
[1]
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