From 6d3f23feb9b1ca1392d018702b62387d773a7be4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Wed, 29 Feb 2012 16:15:49 +0100 Subject: Make SurfaceBuffer a QPlatformScreenBuffer And refactor to make it fit Done with: Paul Change-Id: I2bd28abb4ac256a336cd6c2c90e67104d8c27cc5 Reviewed-by: Andy Nichols --- .../graphicshardwareintegration.h | 3 +- .../wayland_egl/waylandeglintegration.cpp | 8 --- .../wayland_egl/waylandeglintegration.h | 2 +- src/compositor/wayland_wrapper/wlcompositor.cpp | 24 +++++--- src/compositor/wayland_wrapper/wlcompositor.h | 13 +++- src/compositor/wayland_wrapper/wlsurface.cpp | 51 ++++++++++------ src/compositor/wayland_wrapper/wlsurface.h | 2 +- src/compositor/wayland_wrapper/wlsurfacebuffer.cpp | 71 ++++++++++++++++++---- src/compositor/wayland_wrapper/wlsurfacebuffer.h | 31 +++++++--- 9 files changed, 143 insertions(+), 62 deletions(-) (limited to 'src') diff --git a/src/compositor/hardware_integration/graphicshardwareintegration.h b/src/compositor/hardware_integration/graphicshardwareintegration.h index cad28822e..bc1ec4223 100644 --- a/src/compositor/hardware_integration/graphicshardwareintegration.h +++ b/src/compositor/hardware_integration/graphicshardwareintegration.h @@ -63,7 +63,8 @@ public: virtual bool isYInverted(struct wl_buffer *) const { return true; } virtual bool setDirectRenderSurface(WaylandSurface *) {return false;} - virtual bool postBuffer(struct wl_buffer *) {return false;} + + virtual void *toNativeBufferHandle(struct wl_buffer *) { return 0; } static GraphicsHardwareIntegration *createGraphicsHardwareIntegration(WaylandCompositor *compositor); diff --git a/src/compositor/hardware_integration/wayland_egl/waylandeglintegration.cpp b/src/compositor/hardware_integration/wayland_egl/waylandeglintegration.cpp index 1d7d2e682..f8dfa398a 100644 --- a/src/compositor/hardware_integration/wayland_egl/waylandeglintegration.cpp +++ b/src/compositor/hardware_integration/wayland_egl/waylandeglintegration.cpp @@ -219,11 +219,3 @@ bool WaylandEglIntegration::setDirectRenderSurface(WaylandSurface *surface) return flipper; } - -bool WaylandEglIntegration::postBuffer(struct wl_buffer *buffer) -{ - QPlatformScreen *screen = QPlatformScreen::platformScreenForWindow(m_compositor->window()); - QPlatformScreenPageFlipper *flipper = screen->pageFlipper(); - - return flipper ? flipper->displayBuffer(buffer) : false; -} diff --git a/src/compositor/hardware_integration/wayland_egl/waylandeglintegration.h b/src/compositor/hardware_integration/wayland_egl/waylandeglintegration.h index 0f78e1d59..77f728180 100644 --- a/src/compositor/hardware_integration/wayland_egl/waylandeglintegration.h +++ b/src/compositor/hardware_integration/wayland_egl/waylandeglintegration.h @@ -58,7 +58,6 @@ public: bool isYInverted(struct wl_buffer *) const; bool setDirectRenderSurface(WaylandSurface *); - bool postBuffer(struct wl_buffer *); private: Q_DISABLE_COPY(WaylandEglIntegration) @@ -66,3 +65,4 @@ private: }; #endif // WAYLANDEGLINTEGRATION_H + diff --git a/src/compositor/wayland_wrapper/wlcompositor.cpp b/src/compositor/wayland_wrapper/wlcompositor.cpp index 41445b6ca..b6941d2a1 100644 --- a/src/compositor/wayland_wrapper/wlcompositor.cpp +++ b/src/compositor/wayland_wrapper/wlcompositor.cpp @@ -56,6 +56,10 @@ #include #include +#include +#include +#include +#include #include #include @@ -154,6 +158,12 @@ Compositor::Compositor(WaylandCompositor *qt_compositor) QSocketNotifier *sockNot = new QSocketNotifier(fd, QSocketNotifier::Read, this); connect(sockNot, SIGNAL(activated(int)), this, SLOT(processWaylandEvents())); + m_pageFlipper = QGuiApplication::primaryScreen()->handle()->pageFlipper(); + if (m_pageFlipper) { + connect(m_pageFlipper,SIGNAL(bufferReleased(QPlatformScreenBuffer*)),this,SLOT(releaseBuffer(QPlatformScreenBuffer*))); + } + + //initialize distancefieldglyphcache here } @@ -239,14 +249,9 @@ uint Compositor::currentTimeMsecs() return 0; } -void Compositor::releaseBuffer(void *bufferHandle) +void Compositor::releaseBuffer(SurfaceBuffer *screenBuffer) { - struct wl_buffer *buffer = static_cast(bufferHandle); - if (buffer) { - //qDebug() << "WL_BUFFER_RELEASE" << buffer<< buffer->resource.client; - wl_resource_post_event(&buffer->resource, WL_BUFFER_RELEASE); - } - + screenBuffer->scheduledRelease(); } void Compositor::processWaylandEvents() @@ -429,6 +434,11 @@ void Compositor::feedRetainedSelectionData(QMimeData *data) } } +void Compositor::scheduleReleaseBuffer(SurfaceBuffer *screenBuffer) +{ + QMetaObject::invokeMethod(this,"releaseBuffer",Q_ARG(SurfaceBuffer *,screenBuffer)); +} + void Compositor::overrideSelection(QMimeData *data) { m_data_device_manager->overrideSelection(*data); diff --git a/src/compositor/wayland_wrapper/wlcompositor.h b/src/compositor/wayland_wrapper/wlcompositor.h index be9b10927..d1263ec37 100644 --- a/src/compositor/wayland_wrapper/wlcompositor.h +++ b/src/compositor/wayland_wrapper/wlcompositor.h @@ -56,10 +56,13 @@ class WaylandInputDevice; class GraphicsHardwareIntegration; class WindowManagerServerIntegration; class QMimeData; +class QPlatformScreenPageFlipper; +class QPlatformScreenBuffer; namespace Wayland { class Surface; +class SurfaceBuffer; class InputDevice; class DataDeviceManager; class OutputExtensionGlobal; @@ -102,6 +105,7 @@ public: void enableSubSurfaceExtension(); bool setDirectRenderSurface(Surface *surface); Surface *directRenderSurface() const {return m_directRenderSurface;} + QPlatformScreenPageFlipper *pageFlipper() const { return m_pageFlipper; } QList surfacesForClient(wl_client* client); @@ -137,10 +141,10 @@ public: bool wantsRetainedSelection() const; void feedRetainedSelectionData(QMimeData *data); -public slots: - void releaseBuffer(void*); - + void scheduleReleaseBuffer(SurfaceBuffer *screenBuffer); private slots: + + void releaseBuffer(SurfaceBuffer *screenBuffer); void processWaylandEvents(); private: @@ -153,6 +157,9 @@ private: /* Output */ //make this a list of the available screens OutputGlobal m_output_global; + //This one should be part of the outputs + QPlatformScreenPageFlipper *m_pageFlipper; + /* shm/*/ ShmHandler m_shm; diff --git a/src/compositor/wayland_wrapper/wlsurface.cpp b/src/compositor/wayland_wrapper/wlsurface.cpp index 0b17e6010..fd06a5bfc 100644 --- a/src/compositor/wayland_wrapper/wlsurface.cpp +++ b/src/compositor/wayland_wrapper/wlsurface.cpp @@ -86,6 +86,9 @@ Surface::Surface(struct wl_client *client, uint32_t id, Compositor *compositor) wl_list_init(&m_frame_callback_list); addClientResource(client, &base()->resource, id, &wl_surface_interface, &Surface::surface_interface, destroy_surface); + for (int i = 0; i < buffer_pool_size; i++) { + m_bufferPool[i] = new SurfaceBuffer(this); + } } Surface::~Surface() @@ -94,12 +97,17 @@ Surface::~Surface() delete m_extendedSurface; delete m_subSurface; delete m_shellSurface; + + for (int i = 0; i < buffer_pool_size; i++) { + if (!m_bufferPool[i]->pageFlipperHasBuffer()) + delete m_bufferPool[i]; + } } WaylandSurface::Type Surface::type() const { SurfaceBuffer *surfaceBuffer = currentSurfaceBuffer(); - if (surfaceBuffer && surfaceBuffer->handle()) { + if (surfaceBuffer && surfaceBuffer->waylandBufferHandle()) { if (surfaceBuffer->isShmBuffer()) { return WaylandSurface::Shm; } else { @@ -119,8 +127,8 @@ bool Surface::isYInverted() const SurfaceBuffer *surfacebuffer = currentSurfaceBuffer(); if (!surfacebuffer) { ret = false; - } else if (graphicsHWIntegration && surfacebuffer->handle() && type() != WaylandSurface::Shm) { - ret = graphicsHWIntegration->isYInverted(surfacebuffer->handle()); + } else if (graphicsHWIntegration && surfacebuffer->waylandBufferHandle() && type() != WaylandSurface::Shm) { + ret = graphicsHWIntegration->isYInverted(surfacebuffer->waylandBufferHandle()); } else #endif ret = true; @@ -132,7 +140,7 @@ bool Surface::visible() const { SurfaceBuffer *surfacebuffer = currentSurfaceBuffer(); - return surfacebuffer->handle(); + return surfacebuffer->waylandBufferHandle(); } QPointF Surface::pos() const @@ -164,8 +172,8 @@ void Surface::setSize(const QSize &size) QImage Surface::image() const { SurfaceBuffer *surfacebuffer = currentSurfaceBuffer(); - if (surfacebuffer && !surfacebuffer->bufferIsDestroyed() && type() == WaylandSurface::Shm) { - ShmBuffer *shmBuffer = static_cast(surfacebuffer->handle()->user_data); + if (surfacebuffer && !surfacebuffer->isDestroyed() && type() == WaylandSurface::Shm) { + ShmBuffer *shmBuffer = static_cast(surfacebuffer->waylandBufferHandle()->user_data); return shmBuffer->image(); } return QImage(); @@ -191,7 +199,7 @@ void Surface::sendFrameCallback() surfacebuffer->setDisplayed(); if (m_backBuffer) { if (m_frontBuffer) - m_frontBuffer->destructBufferState(); + m_frontBuffer->disown(); m_frontBuffer = m_backBuffer; } @@ -274,8 +282,8 @@ void Surface::advanceBufferQueue() } m_backBuffer = m_bufferQueue.takeFirst(); - while (m_backBuffer && m_backBuffer->bufferIsDestroyed()) { - m_backBuffer->destructBufferState(); + while (m_backBuffer && m_backBuffer->isDestroyed()) { + m_backBuffer->disown(); m_bufferQueue.takeFirst(); m_backBuffer = m_bufferQueue.size() ? m_bufferQueue.first():0; } @@ -283,7 +291,7 @@ void Surface::advanceBufferQueue() if (!m_backBuffer) return; //we have no new backbuffer; - if (m_backBuffer->handle()) { + if (m_backBuffer->waylandBufferHandle()) { if (width != m_backBuffer->width() || height != m_backBuffer->height()) { width = m_backBuffer->width(); @@ -296,7 +304,7 @@ void Surface::advanceBufferQueue() if (m_backBuffer && (!m_subSurface || !m_subSurface->parent()) && !m_surfaceMapped) { m_surfaceMapped = true; emit m_waylandSurface->mapped(); - } else if (!m_backBuffer->handle() && m_surfaceMapped) { + } else if (m_backBuffer && !m_backBuffer->waylandBufferHandle() && m_surfaceMapped) { m_surfaceMapped = false; emit m_waylandSurface->unmapped(); } @@ -326,8 +334,8 @@ SurfaceBuffer *Surface::createSurfaceBuffer(struct wl_buffer *buffer) { SurfaceBuffer *newBuffer = 0; for (int i = 0; i < Surface::buffer_pool_size; i++) { - if (!m_bufferPool[i].isRegisteredWithBuffer()) { - newBuffer = &m_bufferPool[i]; + if (!m_bufferPool[i]->isRegisteredWithBuffer()) { + newBuffer = m_bufferPool[i]; newBuffer->initialize(buffer); break; } @@ -339,12 +347,15 @@ SurfaceBuffer *Surface::createSurfaceBuffer(struct wl_buffer *buffer) bool Surface::postBuffer() { #ifdef QT_COMPOSITOR_WAYLAND_GL - if (m_compositor->graphicsHWIntegration() && m_waylandSurface->handle() == m_compositor->directRenderSurface()) { + if (m_waylandSurface->handle() == m_compositor->directRenderSurface()) { SurfaceBuffer *surfaceBuffer = m_backBuffer? m_backBuffer : m_frontBuffer; - if (surfaceBuffer && m_compositor->graphicsHWIntegration()->postBuffer(surfaceBuffer->handle())) { - return true; - } else { - qDebug() << "could not post buffer"; + if (surfaceBuffer && m_compositor->pageFlipper()) { + if (m_compositor->pageFlipper()->displayBuffer(surfaceBuffer)) { + surfaceBuffer->setPageFlipperHasBuffer(true); + return true; + } else { + qDebug() << "could not post buffer"; + } } } #endif @@ -355,10 +366,10 @@ void Surface::attach(struct wl_buffer *buffer) { SurfaceBuffer *last = m_bufferQueue.size()?m_bufferQueue.last():0; if (last) { - if (last->handle() == buffer) + if (last->waylandBufferHandle() == buffer) return; if (!last->damageRect().isValid()) { - last->destructBufferState(); + last->disown(); m_bufferQueue.takeLast(); } } diff --git a/src/compositor/wayland_wrapper/wlsurface.h b/src/compositor/wayland_wrapper/wlsurface.h index b79691662..86f8d33a2 100644 --- a/src/compositor/wayland_wrapper/wlsurface.h +++ b/src/compositor/wayland_wrapper/wlsurface.h @@ -139,7 +139,7 @@ private: ShellSurface *m_shellSurface; static const int buffer_pool_size = 3; - SurfaceBuffer m_bufferPool[buffer_pool_size]; + SurfaceBuffer *m_bufferPool[buffer_pool_size]; QPointF m_position; QSize m_size; diff --git a/src/compositor/wayland_wrapper/wlsurfacebuffer.cpp b/src/compositor/wayland_wrapper/wlsurfacebuffer.cpp index 0a3527993..9c83925df 100644 --- a/src/compositor/wayland_wrapper/wlsurfacebuffer.cpp +++ b/src/compositor/wayland_wrapper/wlsurfacebuffer.cpp @@ -40,19 +40,27 @@ #include "wlsurfacebuffer.h" +#include "wlsurface.h" +#include "wlcompositor.h" + #ifdef QT_COMPOSITOR_WAYLAND_GL #include "hardware_integration/graphicshardwareintegration.h" #include #endif +#include + namespace Wayland { -SurfaceBuffer::SurfaceBuffer() - : m_buffer(0) - , m_dont_send_release(false) +SurfaceBuffer::SurfaceBuffer(Surface *surface) + : QPlatformScreenBuffer() + , m_surface(surface) + , m_compositor(surface->compositor()) + , m_buffer(0) , m_is_registered_for_buffer(false) + , m_surface_has_buffer(false) + , m_page_flipper_has_buffer(false) , m_is_displayed(false) - , m_is_destroyed(false) , m_texture(0) { } @@ -67,10 +75,11 @@ void SurfaceBuffer::initialize(wl_buffer *buffer) { m_buffer = buffer; m_texture = 0; - m_dont_send_release = false; m_is_registered_for_buffer = true; + m_surface_has_buffer = true; + m_page_flipper_has_buffer = false; m_is_displayed = false; - m_is_destroyed = false; + m_destroyed = false; m_destroy_listener.surfaceBuffer = this; m_destroy_listener.listener.func = destroy_listener_callback; if (buffer) @@ -80,6 +89,7 @@ void SurfaceBuffer::initialize(wl_buffer *buffer) void SurfaceBuffer::destructBufferState() { + Q_ASSERT(!m_page_flipper_has_buffer); destroyTexture(); if (m_buffer) { wl_list_remove(&m_destroy_listener.listener.link); @@ -93,15 +103,37 @@ void SurfaceBuffer::destructBufferState() void SurfaceBuffer::sendRelease() { Q_ASSERT(m_buffer); - if (m_dont_send_release) - return; wl_resource_post_event(&m_buffer->resource, WL_BUFFER_RELEASE); - m_dont_send_release = true; } -void SurfaceBuffer::dontSendRelease() +void SurfaceBuffer::setPageFlipperHasBuffer(bool owns) { - m_dont_send_release = true; + m_page_flipper_has_buffer = owns; +} + +void SurfaceBuffer::release() +{ + m_compositor->scheduleReleaseBuffer(this); +} + +void SurfaceBuffer::scheduledRelease() +{ + qDebug() << Q_FUNC_INFO; + m_page_flipper_has_buffer = false; + if (!m_surface_has_buffer) + destructBufferState(); + if (!m_surface) { + delete this; + } +} + +void SurfaceBuffer::disown() +{ + m_surface_has_buffer = false; + + if (!m_page_flipper_has_buffer) { + destructBufferState(); + } } void SurfaceBuffer::setDisplayed() @@ -128,6 +160,21 @@ void SurfaceBuffer::destroyTexture() #endif } +void SurfaceBuffer::handleAboutToBeDisplayed() +{ + qDebug() << Q_FUNC_INFO; +} + +void SurfaceBuffer::handleDisplayed() +{ + qDebug() << Q_FUNC_INFO; +} + +void *SurfaceBuffer::handle() const +{ + return m_buffer->user_data; +} + void SurfaceBuffer::destroy_listener_callback(wl_listener *listener, wl_resource *resource, uint32_t time) { Q_UNUSED(resource); @@ -136,7 +183,7 @@ void SurfaceBuffer::destroy_listener_callback(wl_listener *listener, wl_resource reinterpret_cast(listener); SurfaceBuffer *d = destroy_listener->surfaceBuffer; d->destroyTexture(); - d->m_is_destroyed = true; + d->m_destroyed = true; d->m_buffer = 0; } diff --git a/src/compositor/wayland_wrapper/wlsurfacebuffer.h b/src/compositor/wayland_wrapper/wlsurfacebuffer.h index 33a248ff8..43dac543a 100644 --- a/src/compositor/wayland_wrapper/wlsurfacebuffer.h +++ b/src/compositor/wayland_wrapper/wlsurfacebuffer.h @@ -43,6 +43,7 @@ #include #include +#include #include @@ -51,24 +52,24 @@ class QOpenGLContext; namespace Wayland { +class Surface; +class Compositor; + struct surface_buffer_destroy_listener { struct wl_listener listener; class SurfaceBuffer *surfaceBuffer; }; -class SurfaceBuffer +class SurfaceBuffer : public QPlatformScreenBuffer { public: - SurfaceBuffer(); - + SurfaceBuffer(Surface *surface); ~SurfaceBuffer(); - void initialize(struct wl_buffer *buffer); void destructBufferState(); - inline bool bufferIsDestroyed() const { return m_is_destroyed; } inline int32_t width() const { return m_buffer->width; } inline int32_t height() const { return m_buffer->height; } @@ -78,7 +79,11 @@ public: inline bool isRegisteredWithBuffer() const { return m_is_registered_for_buffer; } void sendRelease(); - void dontSendRelease(); + void setPageFlipperHasBuffer(bool owns); + bool pageFlipperHasBuffer() const { return m_page_flipper_has_buffer; } + void release(); + void scheduledRelease(); + void disown(); void setDisplayed(); @@ -93,15 +98,23 @@ public: inline GLuint texture() const; void destroyTexture(); - inline struct wl_buffer *handle() const { return m_buffer; } + inline struct wl_buffer *waylandBufferHandle() const { return m_buffer; } + + void handleAboutToBeDisplayed(); + void handleDisplayed(); + + void *handle() const; private: + Surface *m_surface; + Compositor *m_compositor; struct wl_buffer *m_buffer; struct surface_buffer_destroy_listener m_destroy_listener; QRect m_damageRect; - bool m_dont_send_release; bool m_is_registered_for_buffer; + bool m_surface_has_buffer; + bool m_page_flipper_has_buffer; + bool m_is_displayed; - bool m_is_destroyed; #ifdef QT_COMPOSITOR_WAYLAND_GL GLuint m_texture; #else -- cgit v1.2.3