From cf8fd0dec1593d063be36774a1a6bd3ac336c053 Mon Sep 17 00:00:00 2001 From: Paul Olav Tvete Date: Mon, 26 Jun 2017 12:27:19 +0200 Subject: Update server buffer integration Fix crashes, and change the (private) API to be more usable. The libhybris code compiles without warnings, but is untested. Change-Id: I1433daf1ba76d7869d1dfe260642199ce5a1b849 Reviewed-by: Johan Helsing --- .../drmeglserverbufferintegration.cpp | 36 +++++++++--- .../drm-egl-server/drmeglserverbufferintegration.h | 13 ++++- .../libhybriseglserverbufferintegration.cpp | 37 +++++++++--- .../libhybriseglserverbufferintegration.h | 14 ++++- .../drmeglserverbufferintegration.cpp | 54 +++++++++-------- .../drm-egl-server/drmeglserverbufferintegration.h | 8 ++- .../libhybriseglserverbufferintegration.cpp | 67 ++++++++++++---------- .../libhybriseglserverbufferintegration.h | 8 +-- 8 files changed, 153 insertions(+), 84 deletions(-) (limited to 'src/hardwareintegration') diff --git a/src/hardwareintegration/client/drm-egl-server/drmeglserverbufferintegration.cpp b/src/hardwareintegration/client/drm-egl-server/drmeglserverbufferintegration.cpp index 5ded6ff0d..fe2adbf56 100644 --- a/src/hardwareintegration/client/drm-egl-server/drmeglserverbufferintegration.cpp +++ b/src/hardwareintegration/client/drm-egl-server/drmeglserverbufferintegration.cpp @@ -41,6 +41,7 @@ #include #include #include +#include #include @@ -98,23 +99,35 @@ DrmServerBuffer::~DrmServerBuffer() m_integration->eglDestroyImageKHR(m_image); } -void DrmServerBuffer::bindTextureToBuffer() +QOpenGLTexture *DrmServerBuffer::toOpenGlTexture() { if (!QOpenGLContext::currentContext()) qWarning("DrmServerBuffer: creating texture with no current context"); - m_integration->glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, m_image); + if (!m_texture) { + m_texture = new QOpenGLTexture(QOpenGLTexture::Target2D); + m_texture->create(); + } + m_texture->bind(); + m_integration->glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, m_image); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + m_texture->release(); + m_texture->setSize(m_size.width(), m_size.height()); + return m_texture; } -void DrmEglServerBufferIntegration::initialize(QWaylandDisplay *display) +void DrmEglServerBufferIntegration::initializeEgl() { - m_egl_display = eglGetDisplay((EGLNativeDisplayType) display->wl_display()); - if (EGL_NO_DISPLAY) { + if (m_egl_initialized) + return; + m_egl_initialized = true; + + m_egl_display = eglGetDisplay((EGLNativeDisplayType) m_display->wl_display()); + if (m_egl_display == EGL_NO_DISPLAY) { qWarning("Failed to initialize drm egl server buffer integration. Could not get egl display from wl_display."); return; } @@ -136,8 +149,13 @@ void DrmEglServerBufferIntegration::initialize(QWaylandDisplay *display) qWarning("Failed to initialize drm egl server buffer integration. Could not resolve glEGLImageTargetTexture2DOES"); return; } + m_egl_initialized = true; +} - QtWayland::wl_registry::init(wl_display_get_registry(display->wl_display())); +void DrmEglServerBufferIntegration::initialize(QWaylandDisplay *display) +{ + m_display = display; + display->addRegistryListener(&wlDisplayHandleGlobal, this); } QWaylandServerBuffer *DrmEglServerBufferIntegration::serverBuffer(struct qt_server_buffer *buffer) @@ -145,12 +163,12 @@ QWaylandServerBuffer *DrmEglServerBufferIntegration::serverBuffer(struct qt_serv return static_cast(qt_server_buffer_get_user_data(buffer)); } -void DrmEglServerBufferIntegration::registry_global(uint32_t name, const QString &interface, uint32_t version) +void DrmEglServerBufferIntegration::wlDisplayHandleGlobal(void *data, ::wl_registry *registry, uint32_t id, const QString &interface, uint32_t version) { Q_UNUSED(version); if (interface == QStringLiteral("qt_drm_egl_server_buffer")) { - struct ::wl_registry *registry = QtWayland::wl_registry::object(); - QtWayland::qt_drm_egl_server_buffer::init(registry, name, 1); + auto *integration = static_cast(data); + integration->QtWayland::qt_drm_egl_server_buffer::init(registry, id, 1); } } diff --git a/src/hardwareintegration/client/drm-egl-server/drmeglserverbufferintegration.h b/src/hardwareintegration/client/drm-egl-server/drmeglserverbufferintegration.h index f848f190e..f1b722997 100644 --- a/src/hardwareintegration/client/drm-egl-server/drmeglserverbufferintegration.h +++ b/src/hardwareintegration/client/drm-egl-server/drmeglserverbufferintegration.h @@ -71,15 +71,15 @@ class DrmServerBuffer : public QWaylandServerBuffer public: DrmServerBuffer(DrmEglServerBufferIntegration *integration, int32_t name, int32_t width, int32_t height, int32_t stride, int32_t format); ~DrmServerBuffer(); - void bindTextureToBuffer() override; + QOpenGLTexture* toOpenGlTexture() override; private: DrmEglServerBufferIntegration *m_integration; EGLImageKHR m_image; + QOpenGLTexture *m_texture = nullptr; }; class DrmEglServerBufferIntegration : public QWaylandServerBufferIntegration - , public QtWayland::wl_registry , public QtWayland::qt_drm_egl_server_buffer { public: @@ -91,17 +91,24 @@ public: inline EGLBoolean eglDestroyImageKHR (EGLImageKHR image); inline void glEGLImageTargetTexture2DOES (GLenum target, GLeglImageOES image); protected: - void registry_global(uint32_t name, const QString &interface, uint32_t version) override; void drm_egl_server_buffer_server_buffer_created(struct ::qt_server_buffer *id, int32_t name, int32_t width, int32_t height, int32_t stride, int32_t format) override; private: + static void wlDisplayHandleGlobal(void *data, struct ::wl_registry *registry, uint32_t id, + const QString &interface, uint32_t version); + void initializeEgl(); + PFNEGLCREATEIMAGEKHRPROC m_egl_create_image; PFNEGLDESTROYIMAGEKHRPROC m_egl_destroy_image; PFNGLEGLIMAGETARGETTEXTURE2DOESPROC m_gl_egl_image_target_texture; + QWaylandDisplay *m_display = nullptr; EGLDisplay m_egl_display; + bool m_egl_initialized = false; }; EGLImageKHR DrmEglServerBufferIntegration::eglCreateImageKHR(EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list) { + if (!m_egl_initialized) + initializeEgl(); if (!m_egl_create_image) { qWarning("DrmEglServerBufferIntegration: Trying to used unresolved function eglCreateImageKHR"); return EGL_NO_IMAGE_KHR; diff --git a/src/hardwareintegration/client/libhybris-egl-server/libhybriseglserverbufferintegration.cpp b/src/hardwareintegration/client/libhybris-egl-server/libhybriseglserverbufferintegration.cpp index 21af476fd..51b904e75 100644 --- a/src/hardwareintegration/client/libhybris-egl-server/libhybriseglserverbufferintegration.cpp +++ b/src/hardwareintegration/client/libhybris-egl-server/libhybriseglserverbufferintegration.cpp @@ -41,6 +41,7 @@ #include #include #include +#include #include #include @@ -59,6 +60,7 @@ LibHybrisServerBuffer::LibHybrisServerBuffer(LibHybrisEglServerBufferIntegration , int32_t format) : QWaylandServerBuffer() , m_integration(integration) + , m_texture(nullptr) , m_stride(stride) , m_hybrisFormat(format) { @@ -76,18 +78,28 @@ LibHybrisServerBuffer::~LibHybrisServerBuffer() m_integration->eglDestroyImageKHR(m_image); } -void LibHybrisServerBuffer::bindTextureToBuffer() +QOpenGLTexture * LibHybrisServerBuffer::toOpenGlTexture() { if (!QOpenGLContext::currentContext()) { qWarning("LibHybrisServerBuffer: creating texture with no current context"); } + if (!m_texture) { + m_texture = new QOpenGLTexture(QOpenGLTexture::Target2D); + m_texture->create(); + } + + m_texture->bind(); m_integration->glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, m_image); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + m_texture->release(); + m_texture->setSize(m_size.width(), m_size.height()); + + return m_texture; } void LibHybrisServerBuffer::libhybris_buffer_add_fd(int32_t fd) @@ -114,10 +126,14 @@ void LibHybrisServerBuffer::libhybris_buffer_add_fd(int32_t fd) } } -void LibHybrisEglServerBufferIntegration::initialize(QWaylandDisplay *display) +void LibHybrisEglServerBufferIntegration::initializeEgl() { - m_egl_display = eglGetDisplay((EGLNativeDisplayType) display->wl_display()); - if (EGL_NO_DISPLAY) { + if (m_egl_initialized) + return; + m_egl_initialized = true; + + m_egl_display = eglGetDisplay((EGLNativeDisplayType) m_display->wl_display()); + if (m_egl_display == EGL_NO_DISPLAY) { qWarning("Failed to initialize libhybris egl server buffer integration. Could not get egl display from wl_display."); return; } @@ -145,8 +161,13 @@ void LibHybrisEglServerBufferIntegration::initialize(QWaylandDisplay *display) qWarning("Failed to initialize libhybris egl server buffer integration. Could not resolve eglHybrisCreateRemoteBuffer"); return; } + m_egl_initialized = true; +} - QtWayland::wl_registry::init(wl_display_get_registry(display->wl_display())); +void LibHybrisEglServerBufferIntegration::initialize(QWaylandDisplay *display) +{ + m_display = display; + display->addRegistryListener(&wlDisplayHandleGlobal, this); } QWaylandServerBuffer *LibHybrisEglServerBufferIntegration::serverBuffer(struct qt_server_buffer *buffer) @@ -154,12 +175,12 @@ QWaylandServerBuffer *LibHybrisEglServerBufferIntegration::serverBuffer(struct q return static_cast(qt_server_buffer_get_user_data(buffer)); } -void LibHybrisEglServerBufferIntegration::registry_global(uint32_t name, const QString &interface, uint32_t version) +void LibHybrisEglServerBufferIntegration::wlDisplayHandleGlobal(void *data, ::wl_registry *registry, uint32_t id, const QString &interface, uint32_t version) { Q_UNUSED(version); if (interface == QStringLiteral("qt_libhybris_egl_server_buffer")) { - struct ::wl_registry *registry = QtWayland::wl_registry::object(); - QtWayland::qt_libhybris_egl_server_buffer::init(registry, name, 1); + auto *integration = static_cast(data); + integration->QtWayland::qt_libhybris_egl_server_buffer::init(registry, id, 1); } } diff --git a/src/hardwareintegration/client/libhybris-egl-server/libhybriseglserverbufferintegration.h b/src/hardwareintegration/client/libhybris-egl-server/libhybriseglserverbufferintegration.h index e9f0689a2..b3c9c464d 100644 --- a/src/hardwareintegration/client/libhybris-egl-server/libhybriseglserverbufferintegration.h +++ b/src/hardwareintegration/client/libhybris-egl-server/libhybriseglserverbufferintegration.h @@ -75,7 +75,7 @@ class LibHybrisServerBuffer : public QWaylandServerBuffer, public QtWayland::qt_ public: LibHybrisServerBuffer(LibHybrisEglServerBufferIntegration *integration, int32_t numFds, wl_array *ints, int32_t name, int32_t width, int32_t height, int32_t stride, int32_t format); ~LibHybrisServerBuffer(); - void bindTextureToBuffer() override; + QOpenGLTexture* toOpenGlTexture() override; protected: void libhybris_buffer_add_fd(int32_t fd) override; @@ -83,6 +83,7 @@ protected: private: LibHybrisEglServerBufferIntegration *m_integration; EGLImageKHR m_image; + QOpenGLTexture *m_texture; int m_numFds; QVector m_ints; QVector m_fds; @@ -92,7 +93,6 @@ private: class LibHybrisEglServerBufferIntegration : public QWaylandServerBufferIntegration - , public QtWayland::wl_registry , public QtWayland::qt_libhybris_egl_server_buffer { public: @@ -106,19 +106,27 @@ public: inline EGLBoolean eglHybrisCreateRemoteBuffer(EGLint width, EGLint height, EGLint usage, EGLint format, EGLint stride, int num_ints, int *ints, int num_fds, int *fds, EGLClientBuffer *buffer); protected: - void registry_global(uint32_t name, const QString &interface, uint32_t version) override; void libhybris_egl_server_buffer_server_buffer_created(struct ::qt_libhybris_buffer *id, struct ::qt_server_buffer *qid, int32_t numFds, wl_array *ints, int32_t name, int32_t width, int32_t height, int32_t stride, int32_t format) override; private: + static void wlDisplayHandleGlobal(void *data, struct ::wl_registry *registry, uint32_t id, + const QString &interface, uint32_t version); + void initializeEgl(); + PFNEGLCREATEIMAGEKHRPROC m_egl_create_image; PFNEGLDESTROYIMAGEKHRPROC m_egl_destroy_image; PFNGLEGLIMAGETARGETTEXTURE2DOESPROC m_gl_egl_image_target_texture; PFNEGLHYBRISCREATEREMOTEBUFFERPROC m_egl_create_buffer; + QWaylandDisplay *m_display = nullptr; EGLDisplay m_egl_display; + bool m_egl_initialized = false; }; EGLImageKHR LibHybrisEglServerBufferIntegration::eglCreateImageKHR(EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list) { + if (!m_egl_initialized) + initializeEgl(); + if (!m_egl_create_image) { qWarning("LibHybrisEglServerBufferIntegration: Trying to used unresolved function eglCreateImageKHR"); return EGL_NO_IMAGE_KHR; diff --git a/src/hardwareintegration/compositor/drm-egl-server/drmeglserverbufferintegration.cpp b/src/hardwareintegration/compositor/drm-egl-server/drmeglserverbufferintegration.cpp index fe7f12fd0..35fdc8277 100644 --- a/src/hardwareintegration/compositor/drm-egl-server/drmeglserverbufferintegration.cpp +++ b/src/hardwareintegration/compositor/drm-egl-server/drmeglserverbufferintegration.cpp @@ -40,12 +40,14 @@ #include "drmeglserverbufferintegration.h" #include +#include QT_BEGIN_NAMESPACE -DrmEglServerBuffer::DrmEglServerBuffer(DrmEglServerBufferIntegration *integration, const QSize &size, QtWayland::ServerBuffer::Format format) - : QtWayland::ServerBuffer(size,format) +DrmEglServerBuffer::DrmEglServerBuffer(DrmEglServerBufferIntegration *integration, const QImage &qimage, QtWayland::ServerBuffer::Format format) + : QtWayland::ServerBuffer(qimage.size(),format) , m_integration(integration) + , m_texture(nullptr) { m_format = format; @@ -82,38 +84,42 @@ DrmEglServerBuffer::DrmEglServerBuffer(DrmEglServerBufferIntegration *integratio qWarning("DrmEglServerBuffer: Failed to export egl image"); } + m_texture = new QOpenGLTexture(QOpenGLTexture::Target2D); + m_texture->create(); + m_texture->bind(); + + m_integration->glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, m_image); + + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, qimage.width(), qimage.height(), GL_RGBA, GL_UNSIGNED_BYTE, qimage.constBits()); + + m_texture->release(); + m_texture->setSize(m_size.width(), m_size.height()); } struct ::wl_resource *DrmEglServerBuffer::resourceForClient(struct ::wl_client *client) { - QMultiMap::iterator it = resourceMap().find(client); - if (it == resourceMap().end()) { - QMultiMap::iterator drm_egl_it = m_integration->resourceMap().find(client); - if (drm_egl_it == m_integration->resourceMap().end()) { + auto *bufferResource = resourceMap().value(client); + if (!bufferResource) { + auto integrationResource = m_integration->resourceMap().value(client); + if (!integrationResource) { qWarning("DrmEglServerBuffer::resourceForClient: Trying to get resource for ServerBuffer. But client is not bound to the drm_egl interface"); return 0; } - struct ::wl_resource *drm_egl_resource = (*drm_egl_it)->handle; - Resource *resource = add(client, 1, 1); - m_integration->send_server_buffer_created(drm_egl_resource, resource->handle, m_name, m_size.width(), m_size.height(), m_stride, m_drm_format); + struct ::wl_resource *drm_egl_integration_resource = integrationResource->handle; + Resource *resource = add(client, 1); + 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); return resource->handle; } - return (*it)->handle; + return bufferResource->handle; } -void DrmEglServerBuffer::bindTextureToBuffer() + +QOpenGLTexture *DrmEglServerBuffer::toOpenGlTexture() { - if (!QOpenGLContext::currentContext()) { - qWarning("DrmEglServerBuffer: No current context when creating buffer. Texture loading will fail"); - return; + if (!m_texture) { + qWarning("DrmEglServerBuffer::toOpenGlTexture: no texture defined"); } - - m_integration->glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, m_image); - - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + return m_texture; } DrmEglServerBufferIntegration::DrmEglServerBufferIntegration() @@ -130,7 +136,7 @@ void DrmEglServerBufferIntegration::initializeHardware(QWaylandCompositor *compo m_egl_display = static_cast(QGuiApplication::platformNativeInterface()->nativeResourceForIntegration("egldisplay")); if (!m_egl_display) { - qWarning("Cant initialize drm egl server buffer integration. Missing egl display from platformplugin"); + qWarning("Can't initialize drm egl server buffer integration. Missing egl display from platform plugin"); return; } @@ -183,9 +189,9 @@ bool DrmEglServerBufferIntegration::supportsFormat(QtWayland::ServerBuffer::Form } } -QtWayland::ServerBuffer *DrmEglServerBufferIntegration::createServerBuffer(const QSize &size, QtWayland::ServerBuffer::Format format) +QtWayland::ServerBuffer *DrmEglServerBufferIntegration::createServerBufferFromImage(const QImage &qimage, QtWayland::ServerBuffer::Format format) { - return new DrmEglServerBuffer(this, size, format); + return new DrmEglServerBuffer(this, qimage, format); } QT_END_NAMESPACE diff --git a/src/hardwareintegration/compositor/drm-egl-server/drmeglserverbufferintegration.h b/src/hardwareintegration/compositor/drm-egl-server/drmeglserverbufferintegration.h index 239a1f7d1..e1cc8768f 100644 --- a/src/hardwareintegration/compositor/drm-egl-server/drmeglserverbufferintegration.h +++ b/src/hardwareintegration/compositor/drm-egl-server/drmeglserverbufferintegration.h @@ -72,14 +72,15 @@ typedef EGLBoolean (EGLAPIENTRYP PFNEGLEXPORTDRMIMAGEMESAPROC) (EGLDisplay dpy, QT_BEGIN_NAMESPACE class DrmEglServerBufferIntegration; +class QImage; class DrmEglServerBuffer : public QtWayland::ServerBuffer, public QtWaylandServer::qt_server_buffer { public: - DrmEglServerBuffer(DrmEglServerBufferIntegration *integration, const QSize &size, QtWayland::ServerBuffer::Format format); + DrmEglServerBuffer(DrmEglServerBufferIntegration *integration, const QImage &qimage, QtWayland::ServerBuffer::Format format); struct ::wl_resource *resourceForClient(struct ::wl_client *) override; - void bindTextureToBuffer() override; + QOpenGLTexture *toOpenGlTexture() override; private: DrmEglServerBufferIntegration *m_integration; @@ -88,6 +89,7 @@ private: int32_t m_name; int32_t m_stride; + QOpenGLTexture *m_texture; QtWaylandServer::qt_drm_egl_server_buffer::format m_drm_format; }; @@ -102,7 +104,7 @@ public: void initializeHardware(QWaylandCompositor *) override; bool supportsFormat(QtWayland::ServerBuffer::Format format) const override; - QtWayland::ServerBuffer *createServerBuffer(const QSize &size, QtWayland::ServerBuffer::Format format) override; + QtWayland::ServerBuffer *createServerBufferFromImage(const QImage &qimage, QtWayland::ServerBuffer::Format format) override; EGLDisplay display() const { return m_egl_display; } diff --git a/src/hardwareintegration/compositor/libhybris-egl-server/libhybriseglserverbufferintegration.cpp b/src/hardwareintegration/compositor/libhybris-egl-server/libhybriseglserverbufferintegration.cpp index 2312a468b..de9e1cf6e 100644 --- a/src/hardwareintegration/compositor/libhybris-egl-server/libhybriseglserverbufferintegration.cpp +++ b/src/hardwareintegration/compositor/libhybris-egl-server/libhybriseglserverbufferintegration.cpp @@ -40,13 +40,15 @@ #include "libhybriseglserverbufferintegration.h" #include +#include #include #include QT_BEGIN_NAMESPACE -LibHybrisEglServerBuffer::LibHybrisEglServerBuffer(LibHybrisEglServerBufferIntegration *integration, const QSize &size, QtWayland::ServerBuffer::Format format) - : QtWayland::ServerBuffer(size,format) +LibHybrisEglServerBuffer::LibHybrisEglServerBuffer(LibHybrisEglServerBufferIntegration *integration, const QImage &qimage, QtWayland::ServerBuffer::Format format) + : QtWayland::ServerBuffer(qimage.size(),format) , m_integration(integration) + , m_texture(nullptr) { m_format = format; @@ -63,7 +65,7 @@ LibHybrisEglServerBuffer::LibHybrisEglServerBuffer(LibHybrisEglServerBufferInteg break; } - if (!m_integration->eglHybrisCreateNativeBuffer(size.width(), size.height(), HYBRIS_USAGE_HW_TEXTURE, egl_format, &m_stride, &m_buffer)) { + if (!m_integration->eglHybrisCreateNativeBuffer(m_size.width(), m_size.height(), HYBRIS_USAGE_HW_TEXTURE, egl_format, &m_stride, &m_buffer)) { qWarning("LibHybrisEglServerBuffer: Failed to create egl buffer"); return; } @@ -76,48 +78,53 @@ LibHybrisEglServerBuffer::LibHybrisEglServerBuffer(LibHybrisEglServerBufferInteg m_integration->eglHybrisSerializeNativeBuffer(m_buffer, m_ints.data(), m_fds.data()); m_image = m_integration->eglCreateImageKHR(EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID, m_buffer, 0); + + if (!QOpenGLContext::currentContext()) { + qWarning("LibHybrisEglServerBuffer: No current context when creating buffer. Texture loading will fail"); + return; + } + + m_texture = new QOpenGLTexture(QOpenGLTexture::Target2D); + m_texture->create(); + + m_texture->bind(); + + m_integration->glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, m_image); + + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, qimage.width(), qimage.height(), GL_RGBA, GL_UNSIGNED_BYTE, qimage.constBits()); + + m_texture->release(); + m_texture->setSize(m_size.width(), m_size.height()); } struct ::wl_resource *LibHybrisEglServerBuffer::resourceForClient(struct ::wl_client *client) { - QMultiMap::iterator it = resourceMap().find(client); - if (it == resourceMap().end()) { - QMultiMap::iterator egl_it = m_integration->resourceMap().find(client); - if (egl_it == m_integration->resourceMap().end()) { + auto *bufferResource = resourceMap().value(client); + if (!bufferResource) { + auto integrationResource = m_integration->resourceMap().value(client); + if (!integrationResource) { qWarning("LibHybrisEglServerBuffer::resourceForClient: Trying to get resource for ServerBuffer. But client is not bound to the libhybris_egl interface"); return 0; } - struct ::wl_resource *egl_resource = (*egl_it)->handle; - Resource *resource = add(client, 1, 1); - wl_resource *bufRes = wl_client_new_object(client, &qt_libhybris_buffer_interface, 0, 0); + struct ::wl_resource *egl_integration_resource = integrationResource->handle; + Resource *resource = add(client, 1); + wl_resource *bufRes = wl_resource_create(client, &qt_libhybris_buffer_interface,-1, 0); - m_integration->send_server_buffer_created(egl_resource, resource->handle, bufRes, m_fds.size(), QByteArray((char *)m_ints.data(), m_ints.size() * sizeof(int32_t)), + 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)), m_name, m_size.width(), m_size.height(), m_stride, m_format); - m_qtbuffers.insert(resource, bufRes); - for (int i = 0; i < m_fds.size(); ++i) { send_add_fd(resource->handle, m_fds.at(i)); } - return bufRes; + return resource->handle; } - return m_qtbuffers.value(*it); + return bufferResource->handle; } -void LibHybrisEglServerBuffer::bindTextureToBuffer() +QOpenGLTexture *LibHybrisEglServerBuffer::toOpenGlTexture() { - if (!QOpenGLContext::currentContext()) { - qWarning("LibHybrisEglServerBuffer: No current context when creating buffer. Texture loading will fail"); - return; - } - - m_integration->glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, m_image); - - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + return m_texture; } LibHybrisEglServerBufferIntegration::LibHybrisEglServerBufferIntegration() @@ -134,7 +141,7 @@ void LibHybrisEglServerBufferIntegration::initializeHardware(QWaylandCompositor m_egl_display = static_cast(QGuiApplication::platformNativeInterface()->nativeResourceForIntegration("egldisplay")); if (!m_egl_display) { - qWarning("Cant initialize libhybris egl server buffer integration. Missing egl display from platformplugin"); + qWarning("Can't initialize libhybris egl server buffer integration. Missing egl display from platform plugin"); return; } @@ -187,9 +194,9 @@ bool LibHybrisEglServerBufferIntegration::supportsFormat(QtWayland::ServerBuffer } } -QtWayland::ServerBuffer *LibHybrisEglServerBufferIntegration::createServerBuffer(const QSize &size, QtWayland::ServerBuffer::Format format) +QtWayland::ServerBuffer *LibHybrisEglServerBufferIntegration::createServerBufferFromImage(const QImage &qimage, QtWayland::ServerBuffer::Format format) { - return new LibHybrisEglServerBuffer(this, size, format); + return new LibHybrisEglServerBuffer(this, qimage, format); } QT_END_NAMESPACE diff --git a/src/hardwareintegration/compositor/libhybris-egl-server/libhybriseglserverbufferintegration.h b/src/hardwareintegration/compositor/libhybris-egl-server/libhybriseglserverbufferintegration.h index e874e416b..0e1593447 100644 --- a/src/hardwareintegration/compositor/libhybris-egl-server/libhybriseglserverbufferintegration.h +++ b/src/hardwareintegration/compositor/libhybris-egl-server/libhybriseglserverbufferintegration.h @@ -78,10 +78,10 @@ class LibHybrisEglServerBufferIntegration; class LibHybrisEglServerBuffer : public QtWayland::ServerBuffer, public QtWaylandServer::qt_libhybris_buffer { public: - LibHybrisEglServerBuffer(LibHybrisEglServerBufferIntegration *integration, const QSize &size, QtWayland::ServerBuffer::Format format); + LibHybrisEglServerBuffer(LibHybrisEglServerBufferIntegration *integration, const QImage &qimage, QtWayland::ServerBuffer::Format format); struct ::wl_resource *resourceForClient(struct ::wl_client *) override; - void bindTextureToBuffer() override; + QOpenGLTexture *toOpenGlTexture() override; private: LibHybrisEglServerBufferIntegration *m_integration; @@ -91,10 +91,10 @@ private: int32_t m_name; int32_t m_stride; + QOpenGLTexture *m_texture; QtWaylandServer::qt_libhybris_egl_server_buffer::format m_hybris_format; QVector m_ints; QVector m_fds; - QHash m_qtbuffers; }; class LibHybrisEglServerBufferIntegration : @@ -108,7 +108,7 @@ public: void initializeHardware(QWaylandCompositor *); bool supportsFormat(QtWayland::ServerBuffer::Format format) const override; - QtWayland::ServerBuffer *createServerBuffer(const QSize &size, QtWayland::ServerBuffer::Format format) override; + QtWayland::ServerBuffer *createServerBufferFromImage(const QImage &qimage, QtWayland::ServerBuffer::Format format) override; EGLDisplay display() const { return m_egl_display; } -- cgit v1.2.3