summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJørgen Lind <jorgen.lind@nokia.com>2012-02-29 16:15:49 +0100
committerAndy Nichols <andy.nichols@nokia.com>2012-03-01 17:35:21 +0100
commit6d3f23feb9b1ca1392d018702b62387d773a7be4 (patch)
tree261bfd20dae3c45e581a9bd48d8425d860a64774
parent36818145a95924712adfcb2d0f72d914e80596f3 (diff)
downloadqtwayland-6d3f23feb9b1ca1392d018702b62387d773a7be4.tar.gz
Make SurfaceBuffer a QPlatformScreenBuffer
And refactor to make it fit Done with: Paul Change-Id: I2bd28abb4ac256a336cd6c2c90e67104d8c27cc5 Reviewed-by: Andy Nichols <andy.nichols@nokia.com>
-rw-r--r--src/compositor/hardware_integration/graphicshardwareintegration.h3
-rw-r--r--src/compositor/hardware_integration/wayland_egl/waylandeglintegration.cpp8
-rw-r--r--src/compositor/hardware_integration/wayland_egl/waylandeglintegration.h2
-rw-r--r--src/compositor/wayland_wrapper/wlcompositor.cpp24
-rw-r--r--src/compositor/wayland_wrapper/wlcompositor.h13
-rw-r--r--src/compositor/wayland_wrapper/wlsurface.cpp51
-rw-r--r--src/compositor/wayland_wrapper/wlsurface.h2
-rw-r--r--src/compositor/wayland_wrapper/wlsurfacebuffer.cpp71
-rw-r--r--src/compositor/wayland_wrapper/wlsurfacebuffer.h31
9 files changed, 143 insertions, 62 deletions
diff --git a/src/compositor/hardware_integration/graphicshardwareintegration.h b/src/compositor/hardware_integration/graphicshardwareintegration.h
index cad28822..bc1ec422 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 1d7d2e68..f8dfa398 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 0f78e1d5..77f72818 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 41445b6c..b6941d2a 100644
--- a/src/compositor/wayland_wrapper/wlcompositor.cpp
+++ b/src/compositor/wayland_wrapper/wlcompositor.cpp
@@ -56,6 +56,10 @@
#include <QWindow>
#include <QSocketNotifier>
+#include <QScreen>
+#include <QPlatformScreen>
+#include <QGuiApplication>
+#include <QPlatformScreenPageFlipper>
#include <QDebug>
#include <stdio.h>
@@ -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<struct wl_buffer*>(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 be9b1092..d1263ec3 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<Surface*> 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 0b17e601..fd06a5bf 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<ShmBuffer *>(surfacebuffer->handle()->user_data);
+ if (surfacebuffer && !surfacebuffer->isDestroyed() && type() == WaylandSurface::Shm) {
+ ShmBuffer *shmBuffer = static_cast<ShmBuffer *>(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 b7969166..86f8d33a 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 0a352799..9c83925d 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 <QtGui/QPlatformOpenGLContext>
#endif
+#include <QtCore/QDebug>
+
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<struct surface_buffer_destroy_listener *>(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 33a248ff..43dac543 100644
--- a/src/compositor/wayland_wrapper/wlsurfacebuffer.h
+++ b/src/compositor/wayland_wrapper/wlsurfacebuffer.h
@@ -43,6 +43,7 @@
#include <QtCore/QRect>
#include <QtGui/qopengl.h>
+#include <QtGui/QPlatformScreenBuffer>
#include <wayland-server.h>
@@ -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