diff options
author | Laszlo Agocs <laszlo.agocs@theqtcompany.com> | 2015-10-27 18:03:44 +0100 |
---|---|---|
committer | Laszlo Agocs <laszlo.agocs@theqtcompany.com> | 2015-10-27 18:31:47 +0100 |
commit | 8cac11fd8398b91300af6b40d16fcfebafade622 (patch) | |
tree | 556717d1c8624fd691d52c441ff11bdda7cea731 | |
parent | 699c44e3dc2d7099fdd87060c39309e318c55616 (diff) | |
parent | f242587cbf3ee8ade683414aaa95158a1149db4c (diff) |
Merge branch '5.6' into wip-compositor-api
qwindow-compositor changes from 5.6 will be adapted separately.
The traditional wayland-egl path is tested and is functional like before.
The EGLStream support will be verified separately once the qwindow-compositor
changes are ready.
Conflicts:
examples/wayland/qwindow-compositor/qwindowcompositor.cpp
examples/wayland/qwindow-compositor/textureblitter.cpp
examples/wayland/qwindow-compositor/textureblitter.h
examples/wayland/server-buffer/client/client.pro
examples/wayland/server-buffer/compositor/compositor.pro
src/compositor/compositor_api/qwaylandbufferref.cpp
src/compositor/compositor_api/qwaylandbufferref.h
src/compositor/hardware_integration/qwlclientbufferintegration_p.h
src/compositor/wayland_wrapper/qwlkeyboard.cpp
src/compositor/wayland_wrapper/qwlkeyboard_p.h
src/compositor/wayland_wrapper/qwlsurfacebuffer.cpp
src/compositor/wayland_wrapper/qwlsurfacebuffer_p.h
src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.cpp
src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.h
src/plugins/hardwareintegration/compositor/wayland-egl/wayland-egl.pro
Change-Id: Ic2e3a6e8f74606c35b1e27cd4016fa133527d7ba
12 files changed, 315 insertions, 58 deletions
diff --git a/src/compositor/compositor_api/qwaylandbufferref.cpp b/src/compositor/compositor_api/qwaylandbufferref.cpp index cff9bc35d..d0fe7ca40 100644 --- a/src/compositor/compositor_api/qwaylandbufferref.cpp +++ b/src/compositor/compositor_api/qwaylandbufferref.cpp @@ -235,4 +235,20 @@ void QWaylandBufferRef::bindToTexture() const } +int QWaylandBufferRef::textureTarget() const +{ + if (d->nullOrDestroyed()) + return 0x0DE1; // GL_TEXTURE_2D + + return d->buffer->textureTarget(); +} + +void QWaylandBufferRef::updateTexture() const +{ + if (d->nullOrDestroyed() || d->buffer->isShm()) + return; + + d->buffer->updateTexture(); +} + QT_END_NAMESPACE diff --git a/src/compositor/compositor_api/qwaylandbufferref.h b/src/compositor/compositor_api/qwaylandbufferref.h index d67d8178c..5683a0b31 100644 --- a/src/compositor/compositor_api/qwaylandbufferref.h +++ b/src/compositor/compositor_api/qwaylandbufferref.h @@ -79,6 +79,8 @@ public: QImage image() const; void bindToTexture() const; + int textureTarget() const; + void updateTexture() const; private: class QWaylandBufferRefPrivate *const d; diff --git a/src/compositor/compositor_api/qwaylandkeyboard.cpp b/src/compositor/compositor_api/qwaylandkeyboard.cpp index d7aa76e60..238a059a5 100644 --- a/src/compositor/compositor_api/qwaylandkeyboard.cpp +++ b/src/compositor/compositor_api/qwaylandkeyboard.cpp @@ -94,24 +94,47 @@ QWaylandKeyboardPrivate *QWaylandKeyboardPrivate::get(QWaylandKeyboard *keyboard return keyboard->d_func(); } +void QWaylandKeyboardPrivate::checkFocusResource(Resource *keyboardResource) +{ + if (!keyboardResource || !focus) + return; + + // this is already the current resource, do no send enter twice + if (focusResource == keyboardResource) + return; + + // check if new wl_keyboard resource is from the client owning the focus surface + if (focus->resource()->client == keyboardResource->client()) { + sendEnter(focus, keyboardResource); + focusResource = keyboardResource; + } +} + +void QWaylandKeyboardPrivate::sendEnter(QWaylandSurface *surface, Resource *keyboardResource) +{ + uint32_t serial = compositor()->nextSerial(); + send_modifiers(keyboardResource->handle, serial, modsDepressed, modsLatched, modsLocked, group); + send_enter(keyboardResource->handle, serial, surface->resource(), QByteArray::fromRawData((char *)keys.data(), keys.size() * sizeof(uint32_t))); +} + void QWaylandKeyboardPrivate::focused(QWaylandSurface *surface) { if (surface && surface->isCursorSurface()) surface = Q_NULLPTR; - if (focusResource && focus != surface) { - uint32_t serial = compositor()->nextSerial(); - send_leave(focusResource->handle, serial, focus->resource()); + if (focus != surface) { + if (focusResource) { + uint32_t serial = compositor()->nextSerial(); + send_leave(focusResource->handle, serial, focus->resource()); + } focusDestroyListener.reset(); + if (surface) + focusDestroyListener.listenForDestruction(surface->resource()); } Resource *resource = surface ? resourceMap().value(surface->waylandClient()) : 0; - if (resource && (focus != surface || focusResource != resource)) { - uint32_t serial = compositor()->nextSerial(); - send_modifiers(resource->handle, serial, modsDepressed, modsLatched, modsLocked, group); - send_enter(resource->handle, serial, surface->resource(), QByteArray::fromRawData((char *)keys.data(), keys.size() * sizeof(uint32_t))); - focusDestroyListener.listenForDestruction(surface->resource()); - } + if (resource && (focus != surface || focusResource != resource)) + sendEnter(surface, resource); focusResource = resource; focus = surface; @@ -125,13 +148,15 @@ void QWaylandKeyboardPrivate::keyboard_bind_resource(wl_keyboard::Resource *reso if (xkb_context) { send_keymap(resource->handle, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, keymap_fd, keymap_size); - return; - } + } else #endif - int null_fd = open("/dev/null", O_RDONLY); - send_keymap(resource->handle, 0 /* WL_KEYBOARD_KEYMAP_FORMAT_NO_KEYMAP */, - null_fd, 0); - close(null_fd); + { + int null_fd = open("/dev/null", O_RDONLY); + send_keymap(resource->handle, 0 /* WL_KEYBOARD_KEYMAP_FORMAT_NO_KEYMAP */, + null_fd, 0); + close(null_fd); + } + checkFocusResource(resource); } void QWaylandKeyboardPrivate::keyboard_destroy_resource(wl_keyboard::Resource *resource) diff --git a/src/compositor/compositor_api/qwaylandkeyboard_p.h b/src/compositor/compositor_api/qwaylandkeyboard_p.h index 9e5b7ee46..3ee6966b9 100644 --- a/src/compositor/compositor_api/qwaylandkeyboard_p.h +++ b/src/compositor/compositor_api/qwaylandkeyboard_p.h @@ -93,6 +93,9 @@ public: void updateModifierState(uint code, uint32_t state); void updateKeymap(); + void checkFocusResource(Resource *resource); + void sendEnter(QWaylandSurface *surface, Resource *resource); + protected: void keyboard_bind_resource(Resource *resource); void keyboard_destroy_resource(Resource *resource); diff --git a/src/compositor/hardware_integration/qwlclientbufferintegration_p.h b/src/compositor/hardware_integration/qwlclientbufferintegration_p.h index 20aa2075b..e5c6c108f 100644 --- a/src/compositor/hardware_integration/qwlclientbufferintegration_p.h +++ b/src/compositor/hardware_integration/qwlclientbufferintegration_p.h @@ -51,8 +51,6 @@ #include <QtWaylandCompositor/qwaylandexport.h> #include <QtWaylandCompositor/qwaylandsurface.h> #include <QtCore/QSize> -#include <QtGui/qopengl.h> -#include <QtGui/QOpenGLContext> #include <wayland-server.h> QT_BEGIN_NAMESPACE @@ -72,13 +70,11 @@ public: virtual void initializeHardware(struct ::wl_display *display) = 0; - // Used when the hardware integration wants to provide its own texture for a given buffer. - // In most cases the compositor creates and manages the texture so this is not needed. - virtual GLuint textureForBuffer(struct ::wl_resource *buffer) { Q_UNUSED(buffer); return 0; } - virtual void destroyTextureForBuffer(struct ::wl_resource *buffer) { Q_UNUSED(buffer); } + virtual void initializeBuffer(struct ::wl_resource *buffer) { Q_UNUSED(buffer); } + virtual int textureTargetForBuffer(struct ::wl_resource *buffer) const { Q_UNUSED(buffer); return 0x0DE1; } - // Called with the texture bound. virtual void bindTextureToBuffer(struct ::wl_resource *buffer) = 0; + virtual void updateTextureForBuffer(struct ::wl_resource *buffer) { Q_UNUSED(buffer); } virtual QWaylandSurface::Origin origin(struct ::wl_resource *) const { return QWaylandSurface::OriginBottomLeft; } diff --git a/src/compositor/wayland_wrapper/qwldatadevice.cpp b/src/compositor/wayland_wrapper/qwldatadevice.cpp index 56f24db95..e8e96a7d6 100644 --- a/src/compositor/wayland_wrapper/qwldatadevice.cpp +++ b/src/compositor/wayland_wrapper/qwldatadevice.cpp @@ -159,6 +159,7 @@ void DataDevice::data_device_start_drag(Resource *resource, struct ::wl_resource Q_EMIT m_inputDevice->drag()->dragStarted(); Q_UNUSED(serial); + Q_UNUSED(origin); //### need to verify that we have an implicit grab with this serial } diff --git a/src/compositor/wayland_wrapper/qwlsurfacebuffer.cpp b/src/compositor/wayland_wrapper/qwlsurfacebuffer.cpp index ae0451592..f48dd3400 100644 --- a/src/compositor/wayland_wrapper/qwlsurfacebuffer.cpp +++ b/src/compositor/wayland_wrapper/qwlsurfacebuffer.cpp @@ -82,8 +82,11 @@ void SurfaceBuffer::initialize(struct ::wl_resource *buffer) m_destroyed = false; m_destroy_listener.surfaceBuffer = this; m_destroy_listener.listener.notify = destroy_listener_callback; - if (buffer) + if (buffer) { + if (ClientBufferIntegration *integration = QWaylandCompositorPrivate::get(m_compositor)->clientBufferIntegration()) + integration->initializeBuffer(buffer); wl_signal_add(&buffer->destroy_signal, &m_destroy_listener.listener); + } } void SurfaceBuffer::destructBufferState() @@ -120,7 +123,7 @@ void SurfaceBuffer::destroy_listener_callback(wl_listener *listener, void *data) { Q_UNUSED(data); struct surface_buffer_destroy_listener *destroy_listener = - reinterpret_cast<struct surface_buffer_destroy_listener *>(listener); + reinterpret_cast<struct surface_buffer_destroy_listener *>(listener); SurfaceBuffer *d = destroy_listener->surfaceBuffer; // Mark the buffer as destroyed and clear m_buffer right away to avoid @@ -218,6 +221,20 @@ void SurfaceBuffer::bindToTexture() const } } +int SurfaceBuffer::textureTarget() const +{ + if (QtWayland::ClientBufferIntegration *clientInt = QWaylandCompositorPrivate::get(m_compositor)->clientBufferIntegration()) + return clientInt->textureTargetForBuffer(m_buffer); + + return 0; +} + +void SurfaceBuffer::updateTexture() const +{ + if (QtWayland::ClientBufferIntegration *clientInt = QWaylandCompositorPrivate::get(m_compositor)->clientBufferIntegration()) + clientInt->updateTextureForBuffer(m_buffer); +} + } QT_END_NAMESPACE diff --git a/src/compositor/wayland_wrapper/qwlsurfacebuffer_p.h b/src/compositor/wayland_wrapper/qwlsurfacebuffer_p.h index 24624cf8d..4f97ca1b2 100644 --- a/src/compositor/wayland_wrapper/qwlsurfacebuffer_p.h +++ b/src/compositor/wayland_wrapper/qwlsurfacebuffer_p.h @@ -103,7 +103,9 @@ public: bool isShm() const { return wl_shm_buffer_get(m_buffer); } QImage image() const; + int textureTarget() const; void bindToTexture() const; + void updateTexture() const; static bool hasContent(SurfaceBuffer *buffer) { return buffer && buffer->waylandBufferHandle(); } private: diff --git a/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.cpp b/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.cpp index d0e66362d..5cea48a43 100644 --- a/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.cpp +++ b/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.cpp @@ -43,11 +43,16 @@ #include <qpa/qplatformscreen.h> #include <QtGui/QWindow> #include <QtCore/QPointer> - #include <QDebug> -#include <EGL/egl.h> -#include <EGL/eglext.h> +#include <QMutex> +#include <QMutexLocker> +#include <QtCore/private/qcore_unix_p.h> +#include <QtPlatformSupport/private/qeglstreamconvenience_p.h> + +#ifndef GL_TEXTURE_EXTERNAL_OES +#define GL_TEXTURE_EXTERNAL_OES 0x8D65 +#endif /* Needed for compatibility with Mesa older than 10.0. */ typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYWAYLANDBUFFERWL_compat) (EGLDisplay dpy, struct wl_resource *buffer, EGLint attribute, EGLint *value); @@ -69,6 +74,28 @@ typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC) (GLenu QT_BEGIN_NAMESPACE +struct BufferState +{ + BufferState() + : gl_texture(0) + , gl_texture_target(GL_TEXTURE_2D) + , egl_stream(EGL_NO_STREAM_KHR) + , isYInverted(true) + {} + + GLuint gl_texture; + GLenum gl_texture_target; + EGLStreamKHR egl_stream; + bool isYInverted; + QSize size; +}; + +struct buffer_destroy_listener +{ + struct wl_listener listener; + class WaylandEglClientBufferIntegrationPrivate *d; +}; + class WaylandEglClientBufferIntegrationPrivate { public: @@ -82,10 +109,40 @@ public: , egl_create_image(0) , egl_destroy_image(0) , gl_egl_image_target_texture_2d(0) - { } + , funcs(Q_NULLPTR) + { + destroy_listener.d = this; + destroy_listener.listener.notify = destroy_listener_callback; + } + + static void destroy_listener_callback(wl_listener *listener, void *data) { + static QMutex mutex; + QMutexLocker locker(&mutex); + + buffer_destroy_listener *destroy_listener = reinterpret_cast<buffer_destroy_listener *>(listener); + WaylandEglClientBufferIntegrationPrivate *self = destroy_listener->d; + struct ::wl_resource *buffer = static_cast<struct ::wl_resource *>(data); + if (!self->buffers.contains(buffer)) + return; + + Q_ASSERT(self); + Q_ASSERT(buffer); + + BufferState state = self->buffers.take(buffer); + + if (state.gl_texture != 0) + glDeleteTextures(1, &state.gl_texture); + + if (state.egl_stream != EGL_NO_STREAM_KHR) + self->funcs->destroy_stream(self->egl_display, state.egl_stream); + } + EGLDisplay egl_display; bool valid; bool display_bound; + QHash<struct ::wl_resource *, BufferState> buffers; + buffer_destroy_listener destroy_listener; + PFNEGLBINDWAYLANDDISPLAYWL egl_bind_wayland_display; PFNEGLUNBINDWAYLANDDISPLAYWL egl_unbind_wayland_display; PFNEGLQUERYWAYLANDBUFFERWL_compat egl_query_wayland_buffer; @@ -94,6 +151,8 @@ public: PFNEGLDESTROYIMAGEKHRPROC egl_destroy_image; PFNGLEGLIMAGETARGETTEXTURE2DOESPROC gl_egl_image_target_texture_2d; + + QEGLStreamConvenience *funcs; }; WaylandEglClientBufferIntegration::WaylandEglClientBufferIntegration() @@ -158,52 +217,156 @@ void WaylandEglClientBufferIntegration::initializeHardware(struct wl_display *di } } + d->funcs = new QEGLStreamConvenience; + d->funcs->initialize(d->egl_display); + d->valid = true; } -void WaylandEglClientBufferIntegration::bindTextureToBuffer(struct ::wl_resource *buffer) +static GLuint make_texture(GLenum target) +{ + GLuint texture; + + glGenTextures(1, &texture); + glBindTexture(target, texture); + + return texture; +} + +static void set_texture_params(GLenum target) +{ + glTexParameterf(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameterf(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameterf(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameterf(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); +} + +void WaylandEglClientBufferIntegration::initializeBuffer(struct ::wl_resource *buffer) { Q_D(WaylandEglClientBufferIntegration); + if (wl_shm_buffer_get(buffer)) + return; + + if (!buffer || d->buffers.contains(buffer)) + return; + + wl_signal_add(&buffer->destroy_signal, &d->destroy_listener.listener); +} + +int WaylandEglClientBufferIntegration::textureTargetForBuffer(struct ::wl_resource *buffer) const +{ + Q_D(const WaylandEglClientBufferIntegration); + + return d->buffers.value(buffer).gl_texture_target; +} + +void WaylandEglClientBufferIntegration::bindTextureToBuffer(struct ::wl_resource *buffer) +{ + Q_D(WaylandEglClientBufferIntegration); if (!d->valid) { qWarning("QtCompositor: bindTextureToBuffer() failed"); return; } - // Vivante drivers on the iMX6 don't resolve this function early enough for us, they seem to require the EGL/GLES setup to be further - // along than they are in initializeHardware(), so do the lookup here instead. - if (!d->gl_egl_image_target_texture_2d) - d->gl_egl_image_target_texture_2d = reinterpret_cast<PFNGLEGLIMAGETARGETTEXTURE2DOESPROC>(eglGetProcAddress("glEGLImageTargetTexture2DOES")); - - if (!d->gl_egl_image_target_texture_2d) { - qWarning("QtCompositor: bindTextureToBuffer() failed. Could not find glEGLImageTargetTexture2DOES."); + if (!buffer) return; + + BufferState state = d->buffers.value(buffer); + + if (state.egl_stream != EGL_NO_STREAM_KHR) { + d->funcs->stream_consumer_acquire(d->egl_display, state.egl_stream); + } else { + Q_ASSERT(QOpenGLContext::currentContext()); + + EGLint format; + EGLNativeFileDescriptorKHR streamFd = EGL_NO_FILE_DESCRIPTOR_KHR; + + EGLint width, height; + d->egl_query_wayland_buffer(d->egl_display, buffer, EGL_WIDTH, &width); + d->egl_query_wayland_buffer(d->egl_display, buffer, EGL_HEIGHT, &height); + state.size = QSize(width, height); + +#if defined(EGL_WAYLAND_Y_INVERTED_WL) + EGLint isYInverted; + EGLBoolean ret = d->egl_query_wayland_buffer(d->egl_display, buffer, EGL_WAYLAND_Y_INVERTED_WL, &isYInverted); + // Yes, this looks strange, but the specification says that EGL_FALSE return + // value (not supported) should be treated the same as EGL_TRUE return value + // and EGL_TRUE in value. + state.isYInverted = (ret == EGL_FALSE || isYInverted == EGL_TRUE); +#endif + + if (d->egl_query_wayland_buffer(d->egl_display, buffer, EGL_TEXTURE_FORMAT, &format)) { + // Resolving GL functions may need a context current, so do it only here. + if (!d->gl_egl_image_target_texture_2d) + d->gl_egl_image_target_texture_2d = reinterpret_cast<PFNGLEGLIMAGETARGETTEXTURE2DOESPROC>(eglGetProcAddress("glEGLImageTargetTexture2DOES")); + + if (!d->gl_egl_image_target_texture_2d) { + qWarning("QtCompositor: bindTextureToBuffer() failed. Could not find glEGLImageTargetTexture2DOES."); + return; + } + + EGLImageKHR image = d->egl_create_image(d->egl_display, EGL_NO_CONTEXT, + EGL_WAYLAND_BUFFER_WL, + buffer, NULL); + + d->gl_egl_image_target_texture_2d(GL_TEXTURE_2D, image); + set_texture_params(GL_TEXTURE_2D); + d->egl_destroy_image(d->egl_display, image); + } else if (d->egl_query_wayland_buffer(d->egl_display, buffer, EGL_WAYLAND_BUFFER_WL, &streamFd)) { + state.egl_stream = d->funcs->create_stream_from_file_descriptor(d->egl_display, streamFd); + close(streamFd); + + if (state.egl_stream == EGL_NO_STREAM_KHR) { + qWarning("%s:%d: eglCreateStreamFromFileDescriptorKHR failed: 0x%x", Q_FUNC_INFO, __LINE__, eglGetError()); + return; + } + + state.isYInverted = false; + state.gl_texture_target = GL_TEXTURE_EXTERNAL_OES; + state.gl_texture = make_texture(state.gl_texture_target); + set_texture_params(state.gl_texture_target); + + if (d->funcs->stream_consumer_gltexture(d->egl_display, state.egl_stream) != EGL_TRUE) + qWarning("%s:%d: eglStreamConsumerGLTextureExternalKHR failed: 0x%x", Q_FUNC_INFO, __LINE__, eglGetError()); + } + + d->buffers[buffer] = state; } +} - EGLImageKHR image = d->egl_create_image(d->egl_display, EGL_NO_CONTEXT, - EGL_WAYLAND_BUFFER_WL, - buffer, NULL); +// Update is only needed for the EGLStream path as that requires calling acquire +// on every frame. bindTextureToBuffer() is typically invoked only upon attach +// so that is insufficient. +void WaylandEglClientBufferIntegration::updateTextureForBuffer(struct ::wl_resource *buffer) +{ + Q_D(WaylandEglClientBufferIntegration); + if (!d->valid) { + qWarning("QtCompositor: updateTextureForBuffer() failed"); + return; + } - d->gl_egl_image_target_texture_2d(GL_TEXTURE_2D, image); + if (!buffer) + return; - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + const BufferState state = d->buffers.value(buffer); - d->egl_destroy_image(d->egl_display, image); + if (state.egl_stream != EGL_NO_STREAM_KHR) + d->funcs->stream_consumer_acquire(d->egl_display, state.egl_stream); } QWaylandSurface::Origin WaylandEglClientBufferIntegration::origin(struct ::wl_resource *buffer) const { -#if defined(EGL_WAYLAND_Y_INVERTED_WL) Q_D(const WaylandEglClientBufferIntegration); + if (d->buffers.contains(buffer)) + return d->buffers[buffer].isYInverted ? QWaylandSurface::OriginTopLeft : QWaylandSurface::OriginBottomLeft; + +#if defined(EGL_WAYLAND_Y_INVERTED_WL) EGLint isYInverted; EGLBoolean ret = EGL_FALSE; if (buffer) ret = d->egl_query_wayland_buffer(d->egl_display, buffer, EGL_WAYLAND_Y_INVERTED_WL, &isYInverted); - // Yes, this looks strange, but the specification says that EGL_FALSE return // value (not supported) should be treated the same as EGL_TRUE return value // and EGL_TRUE in value. @@ -220,6 +383,9 @@ void *WaylandEglClientBufferIntegration::lockNativeBuffer(struct ::wl_resource * { Q_D(const WaylandEglClientBufferIntegration); + if (d->buffers.contains(buffer) && d->buffers[buffer].egl_stream != EGL_NO_STREAM_KHR) + return 0; + EGLImageKHR image = d->egl_create_image(d->egl_display, EGL_NO_CONTEXT, EGL_WAYLAND_BUFFER_WL, buffer, NULL); @@ -229,8 +395,11 @@ void *WaylandEglClientBufferIntegration::lockNativeBuffer(struct ::wl_resource * void WaylandEglClientBufferIntegration::unlockNativeBuffer(void *native_buffer) const { Q_D(const WaylandEglClientBufferIntegration); - EGLImageKHR image = static_cast<EGLImageKHR>(native_buffer); + if (!native_buffer) + return; + + EGLImageKHR image = static_cast<EGLImageKHR>(native_buffer); d->egl_destroy_image(d->egl_display, image); } @@ -238,11 +407,15 @@ QSize WaylandEglClientBufferIntegration::bufferSize(struct ::wl_resource *buffer { Q_D(const WaylandEglClientBufferIntegration); - int width, height; - d->egl_query_wayland_buffer(d->egl_display, buffer, EGL_WIDTH, &width); - d->egl_query_wayland_buffer(d->egl_display, buffer, EGL_HEIGHT, &height); + if (d->buffers.contains(buffer)) { + return d->buffers[buffer].size; + } else { + int width, height; + d->egl_query_wayland_buffer(d->egl_display, buffer, EGL_WIDTH, &width); + d->egl_query_wayland_buffer(d->egl_display, buffer, EGL_HEIGHT, &height); - return QSize(width, height); + return QSize(width, height); + } } QT_END_NAMESPACE diff --git a/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.h b/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.h index effde284a..18893645a 100644 --- a/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.h +++ b/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.h @@ -52,7 +52,11 @@ public: void initializeHardware(struct ::wl_display *display) Q_DECL_OVERRIDE; + void initializeBuffer(struct ::wl_resource *buffer) Q_DECL_OVERRIDE; + int textureTargetForBuffer(struct ::wl_resource *buffer) const Q_DECL_OVERRIDE; void bindTextureToBuffer(struct ::wl_resource *buffer) Q_DECL_OVERRIDE; + void updateTextureForBuffer(struct ::wl_resource *buffer) Q_DECL_OVERRIDE; + QWaylandSurface::Origin origin(struct ::wl_resource *) const Q_DECL_OVERRIDE; void *lockNativeBuffer(struct ::wl_resource *buffer) const Q_DECL_OVERRIDE; @@ -68,4 +72,3 @@ private: QT_END_NAMESPACE #endif // WAYLANDEGLINTEGRATION_H - diff --git a/src/plugins/hardwareintegration/compositor/wayland-egl/wayland-egl.pro b/src/plugins/hardwareintegration/compositor/wayland-egl/wayland-egl.pro index 614c1cfef..5704663b0 100644 --- a/src/plugins/hardwareintegration/compositor/wayland-egl/wayland-egl.pro +++ b/src/plugins/hardwareintegration/compositor/wayland-egl/wayland-egl.pro @@ -1,7 +1,7 @@ PLUGIN_TYPE = wayland-graphics-integration-server load(qt_plugin) -QT = waylandcompositor waylandcompositor-private core-private gui-private +QT = waylandcompositor waylandcompositor-private core-private gui-private platformsupport-private OTHER_FILES += wayland-egl.json diff --git a/src/qtwaylandscanner/qtwaylandscanner.cpp b/src/qtwaylandscanner/qtwaylandscanner.cpp index 0c8f91b62..11a713c8b 100644 --- a/src/qtwaylandscanner/qtwaylandscanner.cpp +++ b/src/qtwaylandscanner/qtwaylandscanner.cpp @@ -196,8 +196,13 @@ QByteArray waylandToCType(const QByteArray &waylandType, const QByteArray &inter return "int32_t"; else if (waylandType == "array") return "wl_array *"; - else if (waylandType == "object" || waylandType == "new_id") - return isServerSide() ? "struct ::wl_resource *" : interface.isEmpty() ? "struct ::wl_object *" : "struct ::" + interface + " *"; + else if (waylandType == "object" || waylandType == "new_id") { + if (isServerSide()) + return "struct ::wl_resource *"; + if (interface.isEmpty()) + return "struct ::wl_object *"; + return "struct ::" + interface + " *"; + } return waylandType; } @@ -850,7 +855,14 @@ void process(QXmlStreamReader &xml, const QByteArray &headerPath, const QByteArr printf("\n"); foreach (const WaylandEvent &e, interface.requests) { const WaylandArgument *new_id = newIdArgument(e.arguments); - printf(" %s", new_id ? (new_id->interface.isEmpty() ? "void *" : "struct ::" + new_id->interface + " *").constData() : "void "); + QByteArray new_id_str = "void "; + if (new_id) { + if (new_id->interface.isEmpty()) + new_id_str = "void *"; + else + new_id_str = "struct ::" + new_id->interface + " *"; + } + printf(" %s", new_id_str.constData()); printEvent(e); printf(";\n"); } @@ -966,7 +978,14 @@ void process(QXmlStreamReader &xml, const QByteArray &headerPath, const QByteArr printf("\n"); const WaylandEvent &e = interface.requests.at(i); const WaylandArgument *new_id = newIdArgument(e.arguments); - printf(" %s%s::", new_id ? (new_id->interface.isEmpty() ? "void *" : "struct ::" + new_id->interface + " *").constData() : "void ", interfaceName); + QByteArray new_id_str = "void "; + if (new_id) { + if (new_id->interface.isEmpty()) + new_id_str = "void *"; + else + new_id_str = "struct ::" + new_id->interface + " *"; + } + printf(" %s%s::", new_id_str.constData(), interfaceName); printEvent(e); printf("\n"); printf(" {\n"); |