From 9b657f70101951239b6af94afedcedffe65e5f10 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=B8rgen=20Lind?= Date: Mon, 13 Feb 2012 14:19:22 +0100 Subject: [PATCH] Removing Wayland::SurfacePrivate MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit And moving Wayland::SurfaceBuffer into its own file. Also remove the extra functions in Wayland::Surface which just relayed down to extended surface. The pattern is that WaylandSurface is the entry point so we check there is the Wayland::Surface has the extension we'r looking for, then calling it directly from WaylandSurface. Last, the data of an extension is suppose to be members of the extension, so I moved the properties to be members of ExtendedSurface Change-Id: I5877671a17ee873b7644094f695fcd3e4677964a Reviewed-by: Samuel Rødal --- .../compositor_api/waylandcompositor.cpp | 2 +- src/compositor/compositor_api/waylandinput.cpp | 6 +- src/compositor/compositor_api/waylandsurface.cpp | 46 +- src/compositor/wayland_wrapper/wayland_wrapper.pri | 6 +- src/compositor/wayland_wrapper/wlcompositor.cpp | 4 +- src/compositor/wayland_wrapper/wlcompositor.h | 3 +- .../wayland_wrapper/wlextendedsurface.cpp | 22 +- src/compositor/wayland_wrapper/wlextendedsurface.h | 14 +- src/compositor/wayland_wrapper/wlinputdevice.cpp | 2 +- src/compositor/wayland_wrapper/wlsubsurface.cpp | 14 +- src/compositor/wayland_wrapper/wlsubsurface.h | 2 +- src/compositor/wayland_wrapper/wlsurface.cpp | 711 ++++++--------------- src/compositor/wayland_wrapper/wlsurface.h | 57 +- src/compositor/wayland_wrapper/wlsurfacebuffer.cpp | 135 ++++ src/compositor/wayland_wrapper/wlsurfacebuffer.h | 132 ++++ 15 files changed, 601 insertions(+), 555 deletions(-) create mode 100644 src/compositor/wayland_wrapper/wlsurfacebuffer.cpp create mode 100644 src/compositor/wayland_wrapper/wlsurfacebuffer.h diff --git a/src/compositor/compositor_api/waylandcompositor.cpp b/src/compositor/compositor_api/waylandcompositor.cpp index 03c0b81..b1388cb 100644 --- a/src/compositor/compositor_api/waylandcompositor.cpp +++ b/src/compositor/compositor_api/waylandcompositor.cpp @@ -101,7 +101,7 @@ void WaylandCompositor::setDirectRenderSurface(WaylandSurface *surface) WaylandSurface *WaylandCompositor::directRenderSurface() const { Wayland::Surface *surf = m_compositor->directRenderSurface(); - return surf ? surf->handle() : 0; + return surf ? surf->waylandSurface() : 0; } QWindow * WaylandCompositor::window() const diff --git a/src/compositor/compositor_api/waylandinput.cpp b/src/compositor/compositor_api/waylandinput.cpp index a6371ed..d0c45e9 100644 --- a/src/compositor/compositor_api/waylandinput.cpp +++ b/src/compositor/compositor_api/waylandinput.cpp @@ -108,7 +108,7 @@ WaylandSurface *WaylandInputDevice::keyboardFocus() const { Wayland::Surface *wlsurface = d->keyboardFocus(); if (wlsurface) - return wlsurface->handle(); + return wlsurface->waylandSurface(); return 0; } @@ -122,7 +122,7 @@ WaylandSurface *WaylandInputDevice::mouseFocus() const { Wayland::Surface *wlsurface = d->mouseFocus(); if (wlsurface) - return wlsurface->handle(); + return wlsurface->waylandSurface(); return 0; } @@ -134,7 +134,7 @@ void WaylandInputDevice::setMouseFocus(WaylandSurface *surface, const QPoint &lo WaylandCompositor *WaylandInputDevice::compositor() const { - return d->compositor()->qtCompositor(); + return d->compositor()->waylandCompositor(); } Wayland::InputDevice *WaylandInputDevice::handle() const diff --git a/src/compositor/compositor_api/waylandsurface.cpp b/src/compositor/compositor_api/waylandsurface.cpp index 596dee8..e9be748 100644 --- a/src/compositor/compositor_api/waylandsurface.cpp +++ b/src/compositor/compositor_api/waylandsurface.cpp @@ -47,6 +47,8 @@ #include "wayland_wrapper/wlsubsurface.h" #include "wayland_wrapper/wlcompositor.h" +#include "waylandwindowmanagerintegration.h" + #ifdef QT_COMPOSITOR_QUICK #include "waylandsurfaceitem.h" #endif @@ -144,13 +146,17 @@ void WaylandSurface::setSize(const QSize &size) Qt::ScreenOrientation WaylandSurface::contentOrientation() const { Q_D(const WaylandSurface); - return d->surface->contentOrientation(); + if (!d->surface->extendedSurface()) + return Qt::PrimaryOrientation; + return d->surface->extendedSurface()->contentOrientation(); } Qt::ScreenOrientation WaylandSurface::windowOrientation() const { Q_D(const WaylandSurface); - return d->surface->windowOrientation(); + if (!d->surface->extendedSurface()) + return Qt::PrimaryOrientation; + return d->surface->extendedSurface()->windowOrientation(); } @@ -158,7 +164,9 @@ Qt::ScreenOrientation WaylandSurface::windowOrientation() const WaylandSurface::WindowFlags WaylandSurface::windowFlags() const { Q_D(const WaylandSurface); - return d->surface->windowFlags(); + if (!d->surface->extendedSurface()) + return WaylandSurface::WindowFlags(0); + return d->surface->extendedSurface()->windowFlags(); } @@ -204,25 +212,43 @@ void WaylandSurface::setSurfaceItem(WaylandSurfaceItem *surfaceItem) qint64 WaylandSurface::processId() const { Q_D(const WaylandSurface); - return d->surface->processId(); + WindowManagerServerIntegration *wmIntegration = d->surface->compositor()->windowManagerIntegration(); + if (!wmIntegration) { + return 0; + } + + WaylandManagedClient *mcl = wmIntegration->managedClient(d->surface->base()->resource.client); + return mcl ? mcl->processId() : 0; } QByteArray WaylandSurface::authenticationToken() const { Q_D(const WaylandSurface); - return d->surface->authenticationToken(); + WindowManagerServerIntegration *wmIntegration = d->surface->compositor()->windowManagerIntegration(); + if (!wmIntegration) { + return QByteArray(); + } + + WaylandManagedClient *mcl = wmIntegration->managedClient(d->surface->base()->resource.client); + return mcl ? mcl->authenticationToken() : QByteArray(); } QVariantMap WaylandSurface::windowProperties() const { Q_D(const WaylandSurface); - return d->surface->windowProperties(); + if (!d->surface->extendedSurface()) + return QVariantMap(); + + return d->surface->extendedSurface()->windowProperties(); } void WaylandSurface::setWindowProperty(const QString &name, const QVariant &value) { Q_D(WaylandSurface); - d->surface->setWindowProperty(name, value); + if (!d->surface->extendedSurface()) + return; + + d->surface->extendedSurface()->setWindowProperty(name, value); } QPointF WaylandSurface::mapToParent(const QPointF &pos) const @@ -243,13 +269,12 @@ QPointF WaylandSurface::mapTo(WaylandSurface *parent, const QPointF &pos) const } } return p; - } WaylandCompositor *WaylandSurface::compositor() const { Q_D(const WaylandSurface); - return d->surface->compositor()->qtCompositor(); + return d->surface->compositor()->waylandCompositor(); } void WaylandSurface::frameFinished() @@ -261,5 +286,6 @@ void WaylandSurface::frameFinished() void WaylandSurface::sendOnScreenVisibilityChange(bool visible) { Q_D(WaylandSurface); - d->surface->sendOnScreenVisibilityChange(visible); + if (d->surface->extendedSurface()) + d->surface->extendedSurface()->sendOnScreenVisibllity(visible); } diff --git a/src/compositor/wayland_wrapper/wayland_wrapper.pri b/src/compositor/wayland_wrapper/wayland_wrapper.pri index 817dedb..9e4f99e 100644 --- a/src/compositor/wayland_wrapper/wayland_wrapper.pri +++ b/src/compositor/wayland_wrapper/wayland_wrapper.pri @@ -21,7 +21,8 @@ HEADERS += \ $$PWD/wlextendedoutput.h \ $$PWD/wlsubsurface.h \ $$PWD/wltouch.h \ - $$PWD/../../shared/qwaylandmimehelper.h + $$PWD/../../shared/qwaylandmimehelper.h \ + $$PWD/wlsurfacebuffer.h SOURCES += \ $$PWD/wlcompositor.cpp \ @@ -39,7 +40,8 @@ SOURCES += \ $$PWD/wlextendedoutput.cpp \ $$PWD/wlsubsurface.cpp \ $$PWD/wltouch.cpp \ - $$PWD/../../shared/qwaylandmimehelper.cpp + $$PWD/../../shared/qwaylandmimehelper.cpp \ + $$PWD/wlsurfacebuffer.cpp INCLUDEPATH += $$PWD INCLUDEPATH += $$PWD/../../shared diff --git a/src/compositor/wayland_wrapper/wlcompositor.cpp b/src/compositor/wayland_wrapper/wlcompositor.cpp index 75e5eb9..545d14e 100644 --- a/src/compositor/wayland_wrapper/wlcompositor.cpp +++ b/src/compositor/wayland_wrapper/wlcompositor.cpp @@ -185,7 +185,7 @@ void Compositor::createSurface(struct wl_client *client, uint32_t id) m_surfaces << surface; - m_qt_compositor->surfaceCreated(surface->handle()); + m_qt_compositor->surfaceCreated(surface->waylandSurface()); } struct wl_client *Compositor::getClientFromWinId(uint winId) const @@ -314,7 +314,7 @@ void Compositor::enableSubSurfaceExtension() bool Compositor::setDirectRenderSurface(Surface *surface) { #ifdef QT_COMPOSITOR_WAYLAND_GL - if (m_graphics_hw_integration && m_graphics_hw_integration->setDirectRenderSurface(surface ? surface->handle() : 0)) { + if (m_graphics_hw_integration && m_graphics_hw_integration->setDirectRenderSurface(surface ? surface->waylandSurface() : 0)) { m_directRenderSurface = surface; return true; } diff --git a/src/compositor/wayland_wrapper/wlcompositor.h b/src/compositor/wayland_wrapper/wlcompositor.h index 3d4185f..03cd1db 100644 --- a/src/compositor/wayland_wrapper/wlcompositor.h +++ b/src/compositor/wayland_wrapper/wlcompositor.h @@ -77,6 +77,7 @@ public: void frameFinished(Surface *surface = 0); + //these 3 functions will be removed if noone steps up soon. Surface *getSurfaceFromWinId(uint winId) const; struct wl_client *getClientFromWinId(uint winId) const; QImage image(uint winId) const; @@ -103,7 +104,7 @@ public: QList surfacesForClient(wl_client* client); - WaylandCompositor *qtCompositor() const { return m_qt_compositor; } + WaylandCompositor *waylandCompositor() const { return m_qt_compositor; } struct wl_display *wl_display() const { return m_display->handle(); } diff --git a/src/compositor/wayland_wrapper/wlextendedsurface.cpp b/src/compositor/wayland_wrapper/wlextendedsurface.cpp index a386b59..c5bde25 100644 --- a/src/compositor/wayland_wrapper/wlextendedsurface.cpp +++ b/src/compositor/wayland_wrapper/wlextendedsurface.cpp @@ -123,7 +123,7 @@ void ExtendedSurface::update_generic_property(wl_client *client, wl_resource *ex QByteArray byteValue((const char*)value->data, value->size); QDataStream ds(&byteValue, QIODevice::ReadOnly); ds >> variantValue; - extended_surface->m_surface->setWindowProperty(QString::fromLatin1(name),variantValue,false); + extended_surface->setWindowProperty(QString::fromLatin1(name),variantValue,false); } @@ -171,7 +171,25 @@ void ExtendedSurface::setWindowFlags(WaylandSurface::WindowFlags flags) if (flags == m_windowFlags) return; m_windowFlags = flags; - emit m_surface->handle()->windowFlagsChanged(flags); + emit m_surface->waylandSurface()->windowFlagsChanged(flags); +} + +QVariantMap ExtendedSurface::windowProperties() const +{ + return m_windowProperties; +} + +QVariant ExtendedSurface::windowProperty(const QString &propertyName) const +{ + QVariantMap props = m_windowProperties; + return props.value(propertyName); +} + +void ExtendedSurface::setWindowProperty(const QString &name, const QVariant &value, bool writeUpdateToClient) +{ + m_windowProperties.insert(name, value); + m_surface->waylandSurface()->windowPropertyChanged(name,value); + sendGenericProperty(name, value); } void ExtendedSurface::set_window_flags(wl_client *client, wl_resource *resource, int32_t flags) diff --git a/src/compositor/wayland_wrapper/wlextendedsurface.h b/src/compositor/wayland_wrapper/wlextendedsurface.h index cd27489..0a28a91 100644 --- a/src/compositor/wayland_wrapper/wlextendedsurface.h +++ b/src/compositor/wayland_wrapper/wlextendedsurface.h @@ -44,6 +44,7 @@ #include "wayland-surface-extension-server-protocol.h" #include "wlsurface.h" +#include "waylandsurface.h" #include #include @@ -90,9 +91,15 @@ public: Qt::ScreenOrientation windowOrientation() const; Qt::ScreenOrientation contentOrientation() const; - void setWindowFlags(WaylandSurface::WindowFlags flags); WaylandSurface::WindowFlags windowFlags() const { return m_windowFlags; } + qint64 processId() const; + void setProcessId(qint64 processId); + + QVariantMap windowProperties() const; + QVariant windowProperty(const QString &propertyName) const; + void setWindowProperty(const QString &name, const QVariant &value, bool writeUpdateToClient = true); + private: struct wl_resource *m_extended_surface_resource; Surface *m_surface; @@ -102,6 +109,10 @@ private: WaylandSurface::WindowFlags m_windowFlags; + QByteArray m_authenticationToken; + QVariantMap m_windowProperties; + + static void update_generic_property(struct wl_client *client, struct wl_resource *resource, const char *name, @@ -118,6 +129,7 @@ private: static void set_window_flags(struct wl_client *client, struct wl_resource *resource, int32_t flags); + void setWindowFlags(WaylandSurface::WindowFlags flags); static const struct wl_extended_surface_interface extended_surface_interface; }; diff --git a/src/compositor/wayland_wrapper/wlinputdevice.cpp b/src/compositor/wayland_wrapper/wlinputdevice.cpp index 2863356..b1c5cb7 100644 --- a/src/compositor/wayland_wrapper/wlinputdevice.cpp +++ b/src/compositor/wayland_wrapper/wlinputdevice.cpp @@ -317,7 +317,7 @@ void InputDevice::input_device_attach(struct wl_client *client, if (wl_buffer_is_shm(buffer)) { ShmBuffer *shmBuffer = static_cast(buffer->user_data); if (shmBuffer) { - inputDevice->m_compositor->qtCompositor()->changeCursor(shmBuffer->image(), x, y); + inputDevice->m_compositor->waylandCompositor()->changeCursor(shmBuffer->image(), x, y); currentCursor = shmBuffer; } } diff --git a/src/compositor/wayland_wrapper/wlsubsurface.cpp b/src/compositor/wayland_wrapper/wlsubsurface.cpp index 6569710..d60d5cc 100644 --- a/src/compositor/wayland_wrapper/wlsubsurface.cpp +++ b/src/compositor/wayland_wrapper/wlsubsurface.cpp @@ -91,16 +91,16 @@ SubSurface::~SubSurface() void SubSurface::setSubSurface(SubSurface *subSurface, int x, int y) { - Q_ASSERT(!m_sub_surfaces.contains(subSurface->m_surface->handle())); - m_sub_surfaces.append(subSurface->m_surface->handle()); + Q_ASSERT(!m_sub_surfaces.contains(subSurface->m_surface->waylandSurface())); + m_sub_surfaces.append(subSurface->m_surface->waylandSurface()); subSurface->setParent(this); subSurface->m_surface->setPos(QPointF(x,y)); } void SubSurface::removeSubSurface(SubSurface *subSurfaces) { - Q_ASSERT(m_sub_surfaces.contains(subSurfaces->m_surface->handle())); - m_sub_surfaces.removeOne(subSurfaces->m_surface->handle()); + Q_ASSERT(m_sub_surfaces.contains(subSurfaces->m_surface->waylandSurface())); + m_sub_surfaces.removeOne(subSurfaces->m_surface->waylandSurface()); } SubSurface *SubSurface::parent() const @@ -117,15 +117,15 @@ void SubSurface::setParent(SubSurface *parent) WaylandSurface *newParent = 0; if (m_parent) { - oldParent = m_parent->m_surface->handle(); + oldParent = m_parent->m_surface->waylandSurface(); m_parent->removeSubSurface(this); } if (parent) { - newParent = parent->m_surface->handle(); + newParent = parent->m_surface->waylandSurface(); } m_parent = parent; - m_surface->handle()->parentChanged(newParent,oldParent); + m_surface->waylandSurface()->parentChanged(newParent,oldParent); } QLinkedList SubSurface::subSurfaces() const diff --git a/src/compositor/wayland_wrapper/wlsubsurface.h b/src/compositor/wayland_wrapper/wlsubsurface.h index 0ae2b5e..ab4f205 100644 --- a/src/compositor/wayland_wrapper/wlsubsurface.h +++ b/src/compositor/wayland_wrapper/wlsubsurface.h @@ -120,7 +120,7 @@ inline Surface *SubSurface::surface() const inline WaylandSurface *SubSurface::waylandSurface() const { - return m_surface->handle(); + return m_surface->waylandSurface(); } diff --git a/src/compositor/wayland_wrapper/wlsurface.cpp b/src/compositor/wayland_wrapper/wlsurface.cpp index d516e1d..72cc45a 100644 --- a/src/compositor/wayland_wrapper/wlsurface.cpp +++ b/src/compositor/wayland_wrapper/wlsurface.cpp @@ -47,16 +47,13 @@ #include "wlinputdevice.h" #include "wlextendedsurface.h" #include "wlsubsurface.h" +#include "wlsurfacebuffer.h" #include #include #include -#ifdef Q_OS_LINUX -#include -#endif - #ifdef QT_COMPOSITOR_WAYLAND_GL #include "hardware_integration/graphicshardwareintegration.h" #include @@ -68,358 +65,39 @@ namespace Wayland { -static const int buffer_pool_size = 3; - -struct surface_buffer_destroy_listener -{ - struct wl_listener listener; - class SurfaceBuffer *surfaceBuffer; -}; - - -class SurfaceBuffer -{ -public: - SurfaceBuffer() - : m_buffer(0) - , m_is_released_sent(false) - , m_is_registered_for_buffer(false) - , m_is_posted(false) - , m_is_frame_finished(false) - , m_texture(0) - { - } - - ~SurfaceBuffer() - { - if (m_is_registered_for_buffer) - destructBufferState(); - } - - void initialize(struct wl_buffer *buffer) - { - m_buffer = buffer; - m_texture = 0; - m_is_released_sent = false; - m_is_registered_for_buffer = true; - m_is_posted = false; - m_is_frame_finished = false; - m_destroy_listener.surfaceBuffer = this; - m_destroy_listener.listener.func = destroy_listener_callback; - wl_list_insert(&buffer->resource.destroy_listener_list,&m_destroy_listener.listener.link); - m_damageRect = QRect(); - } - - void destructBufferState() - { - destroyTexture(); - if (m_buffer) { - wl_list_remove(&m_destroy_listener.listener.link); - sendRelease(); - } - m_buffer = 0; - m_is_registered_for_buffer = false; - m_is_posted = 0; - } - - inline int32_t width() const { return m_buffer->width; } - inline int32_t height() const { return m_buffer->height; } - - - inline bool bufferIsDestroyed() const { return m_is_registered_for_buffer &&!m_buffer; } - inline bool isShmBuffer() const { return wl_buffer_is_shm(m_buffer); } - - inline bool isReleasedSent() const { return m_is_released_sent; } - inline bool isRegisteredWithBuffer() const { return m_is_registered_for_buffer; } - - void sendRelease() - { - Q_ASSERT(m_buffer); - wl_resource_post_event(&m_buffer->resource, WL_BUFFER_RELEASE); - m_buffer = 0; - m_is_released_sent = true; - } - - void setPosted() { - m_is_posted = true; - if (m_buffer) { - wl_list_remove(&m_destroy_listener.listener.link); - } - m_buffer = 0; - } - - void setFinished() { m_is_frame_finished = true; } - - inline bool isPosted() const { return m_is_posted; } - inline bool isDisplayed() const { return m_texture || m_is_posted || wl_buffer_is_shm(m_buffer); } - inline bool isFinished() const { return m_is_frame_finished; } - - inline QRect damageRect() const { return m_damageRect; } - - inline void setDamage(const QRect &rect) { m_damageRect = rect; } - - inline bool textureCreated() const - { - return m_texture; - } - - inline GLuint texture() - { - if (m_buffer) - return m_texture; - return 0; - } - - inline void setTexture(GLuint texId) - { - m_texture = texId; - } - - inline void destroyTexture() - { -#ifdef QT_COMPOSITOR_WAYLAND_GL - if (m_texture) { - glDeleteTextures(1,&m_texture); - m_texture = 0; - } -#endif - } - - inline struct wl_buffer *handle() const { return m_buffer; } -private: - struct wl_buffer *m_buffer; - struct surface_buffer_destroy_listener m_destroy_listener; - QRect m_damageRect; - bool m_is_released_sent; - bool m_is_registered_for_buffer; - bool m_is_posted; - bool m_is_frame_finished; -#ifdef QT_COMPOSITOR_WAYLAND_GL - GLuint m_texture; -#else - uint m_texture; -#endif - - static void destroy_listener_callback(struct wl_listener *listener, - struct wl_resource *resource, uint32_t time) - { - Q_UNUSED(resource); - Q_UNUSED(time); - struct surface_buffer_destroy_listener *destroy_listener = - reinterpret_cast(listener); - SurfaceBuffer *d = destroy_listener->surfaceBuffer; - d->destroyTexture(); - d->m_buffer = 0; - } -}; - - -const struct wl_surface_interface Surface::surface_interface = { - Surface::surface_destroy, - Surface::surface_attach, - Surface::surface_damage, - Surface::surface_frame -}; - -class SurfacePrivate -{ - Q_DECLARE_PUBLIC(Surface) -public: - SurfacePrivate(Surface *surface, Compositor *compositor) - : compositor(compositor) - , qtSurface(new WaylandSurface(surface)) - , surfaceBuffer(0) - , textureBuffer(0) - , surfaceMapped(false) - , processId(0) - , extendedSurface(0) - , subSurface(0) - , shellSurface(0) - , q_ptr(surface) - - { - wl_list_init(&frame_callback_list); - } - - static void destroy_frame_callback(struct wl_resource *resource) - { - delete resource; - } - - void doUpdate(const QRect &rect) { - if (postBuffer()) { - surfaceBuffer->setPosted(); // disown buffer.... - if (textureBuffer) { - textureBuffer->destructBufferState(); - textureBuffer = 0; - } - if (!bufferQueue.isEmpty()) { - qDebug() << "++++++++++++++++++++++++++++++++++++++++ recursive damage :-)"; - newCurrentBuffer(); - doUpdate(rect); - } - } else { - compositor->markSurfaceAsDirty(q_ptr); - emit qtSurface->damaged(rect); - } - } - - void newCurrentBuffer() { - //TODO release SHM buffer.... - if (surfaceBuffer && surfaceBuffer->isPosted()) { - surfaceBuffer->destructBufferState(); - } else if (surfaceBuffer && !surfaceBuffer->isDisplayed()) { - qDebug() << "### not skipping undisplayed buffer"; - return; - } - - surfaceBuffer = bufferQueue.takeFirst(); - - int width = 0; - int height = 0; - if (surfaceBuffer) { - width = surfaceBuffer->width(); - height = surfaceBuffer->height(); - } - q_ptr->setSize(QSize(width,height)); - - if (surfaceBuffer && (!subSurface || !subSurface->parent()) && !surfaceMapped) { - emit qtSurface->mapped(); - surfaceMapped = true; - } else if (!surfaceBuffer && surfaceMapped) { - emit qtSurface->unmapped(); - surfaceMapped = false; - } - } - - SurfaceBuffer *createSurfaceBuffer(struct wl_buffer *buffer) - { - SurfaceBuffer *newBuffer = 0; - for (int i = 0; i < buffer_pool_size; i++) { - if (!bufferPool[i].isRegisteredWithBuffer()) { - newBuffer = &bufferPool[i]; - newBuffer->initialize(buffer); - break; - } - } - - Q_ASSERT(newBuffer); - return newBuffer; - } - - void frameFinished() { - if (surfaceBuffer) - surfaceBuffer->setFinished(); - - if (!bufferQueue.isEmpty()) { - newCurrentBuffer(); - if (surfaceBuffer) - doUpdate(surfaceBuffer->damageRect()); - } - } - - bool postBuffer() { -#ifdef QT_COMPOSITOR_WAYLAND_GL - if (compositor->graphicsHWIntegration() && qtSurface->handle() == compositor->directRenderSurface()) { -// qDebug() << "posting...." << bufferQueue; - if (surfaceBuffer && surfaceBuffer->handle() && compositor->graphicsHWIntegration()->postBuffer(surfaceBuffer->handle())) { - return true; - } else { - qDebug() << "could not post buffer"; - } - } -#endif - return false; - } - - Compositor *compositor; - WaylandSurface *qtSurface; - - SurfaceBuffer *surfaceBuffer; - SurfaceBuffer *textureBuffer; - QList bufferQueue; - bool surfaceMapped; - - qint64 processId; - QByteArray authenticationToken; - QVariantMap windowProperties; - - QPoint lastLocalMousePos; - QPoint lastGlobalMousePos; - - struct wl_list frame_callback_list; - - ExtendedSurface *extendedSurface; - SubSurface *subSurface; - ShellSurface *shellSurface; - - SurfaceBuffer bufferPool[buffer_pool_size]; - - QPointF position; - QSize size; - -private: - Surface *q_ptr; -}; - void destroy_surface(struct wl_resource *resource) { Surface *surface = wayland_cast((wl_surface *)resource); delete surface; } -void Surface::surface_destroy(struct wl_client *, struct wl_resource *surface_resource) -{ - wl_resource_destroy(surface_resource,Compositor::currentTimeMsecs()); -} - -void Surface::surface_attach(struct wl_client *client, struct wl_resource *surface, - struct wl_resource *buffer, int x, int y) -{ - Q_UNUSED(client); - Q_UNUSED(x); - Q_UNUSED(y); - reinterpret_cast(surface)->attach(reinterpret_cast(buffer)); -} - -void Surface::surface_damage(struct wl_client *client, struct wl_resource *surface, - int32_t x, int32_t y, int32_t width, int32_t height) -{ - Q_UNUSED(client); - reinterpret_cast(surface)->damage(QRect(x, y, width, height)); -} -void Surface::surface_frame(struct wl_client *client, - struct wl_resource *resource, - uint32_t callback) -{ - Surface *surface = reinterpret_cast(resource); - SurfacePrivate *d = surface->d_func(); - struct wl_resource *frame_callback = wl_client_add_object(client,&wl_callback_interface,0,callback,d); - wl_list_insert(&d->frame_callback_list,&frame_callback->link); -} - Surface::Surface(struct wl_client *client, uint32_t id, Compositor *compositor) - : d_ptr(new SurfacePrivate(this,compositor)) -{ + : m_compositor(compositor) + , m_waylandSurface(new WaylandSurface(this)) + , m_surfaceBuffer(0) + , m_textureBuffer(0) + , m_surfaceMapped(false) + , m_extendedSurface(0) + , m_subSurface(0) + , m_shellSurface(0) +{ + wl_list_init(&m_frame_callback_list); addClientResource(client, &base()->resource, id, &wl_surface_interface, &Surface::surface_interface, destroy_surface); } Surface::~Surface() { - Q_D(Surface); - d->compositor->surfaceDestroyed(this); - - delete d->qtSurface; + m_compositor->surfaceDestroyed(this); + delete m_waylandSurface; } WaylandSurface::Type Surface::type() const { - Q_D(const Surface); - if (d->surfaceBuffer && d->surfaceBuffer->handle()) { - if (d->surfaceBuffer && d->surfaceBuffer->isShmBuffer()) { + if (m_surfaceBuffer && m_surfaceBuffer->handle()) { + if (m_surfaceBuffer && m_surfaceBuffer->isShmBuffer()) { return WaylandSurface::Shm; - } else if (d->surfaceBuffer){ + } else if (m_surfaceBuffer){ return WaylandSurface::Texture; } } @@ -432,12 +110,10 @@ bool Surface::isYInverted() const static bool negateReturn = qgetenv("QT_COMPOSITOR_NEGATE_INVERTED_Y").toInt(); #ifdef QT_COMPOSITOR_WAYLAND_GL - Q_D(const Surface); - - if (!d->surfaceBuffer) { + if (!m_surfaceBuffer) { ret = false; - } else if (d->compositor->graphicsHWIntegration() && d->surfaceBuffer->handle() && type() != WaylandSurface::Shm) { - ret = d->compositor->graphicsHWIntegration()->isYInverted(d->surfaceBuffer->handle()); + } else if (m_compositor->graphicsHWIntegration() && m_surfaceBuffer->handle() && type() != WaylandSurface::Shm) { + ret = m_compositor->graphicsHWIntegration()->isYInverted(m_surfaceBuffer->handle()); } else #endif ret = true; @@ -447,37 +123,14 @@ bool Surface::isYInverted() const bool Surface::visible() const { - Q_D(const Surface); - return d->surfaceBuffer && d->surfaceBuffer->handle(); -} - -void Surface::damage(const QRect &rect) -{ - Q_D(Surface); - - if (!d->bufferQueue.isEmpty() && (!d->surfaceBuffer || d->surfaceBuffer->isFinished() || !d->surfaceBuffer->handle())) { - // Handle the "slow" case where we've finished the previous frame before the next damage comes. - d->newCurrentBuffer(); - d->doUpdate(rect); - } else if (d->bufferQueue.isEmpty()) { - // we've receicved a second damage for the same buffer - d->doUpdate(rect); - } else { - // we're still composing the previous buffer, so just store the damage rect for later - SurfaceBuffer *b = d->bufferQueue.last(); - if (b) - b->setDamage(rect); - else - qWarning() << "Surface::damage() null buffer"; - } + return m_surfaceBuffer && m_surfaceBuffer->handle(); } QImage Surface::image() const { - Q_D(const Surface); - if (type() == WaylandSurface::Shm && d->surfaceBuffer && d->surfaceBuffer->handle()) { - ShmBuffer *shmBuffer = static_cast(d->surfaceBuffer->handle()->user_data); - //TODO SHM: d->surfaceBuffer->bufferHandled = true; + if (type() == WaylandSurface::Shm && m_surfaceBuffer && m_surfaceBuffer->handle()) { + ShmBuffer *shmBuffer = static_cast(m_surfaceBuffer->handle()->user_data); + //TODO SHM: m_surfaceBuffer->bufferHandled = true; return shmBuffer->image(); } return QImage(); @@ -485,225 +138,279 @@ QImage Surface::image() const QPointF Surface::pos() const { - Q_D(const Surface); - return d->position; + return m_position; } void Surface::setPos(const QPointF &pos) { - Q_D(Surface); - bool emitChange = pos != d->position; - d->position = pos; + bool emitChange = pos != m_position; + m_position = pos; if (emitChange) - d->qtSurface->posChanged(); + m_waylandSurface->posChanged(); } QSize Surface::size() const { - Q_D(const Surface); - return d->size; + return m_size; } void Surface::setSize(const QSize &size) { - Q_D(Surface); - bool emitChange = size != d->size; - d->size = size; + bool emitChange = size != m_size; + m_size = size; if (emitChange) - d->qtSurface->sizeChanged(); + m_waylandSurface->sizeChanged(); } #ifdef QT_COMPOSITOR_WAYLAND_GL GLuint Surface::textureId(QOpenGLContext *context) const { - Q_D(const Surface); - - if (!d->surfaceBuffer) { + if (!m_surfaceBuffer) { return 0; } - if (d->compositor->graphicsHWIntegration() && type() == WaylandSurface::Texture - && !d->surfaceBuffer->textureCreated()) { + if (m_compositor->graphicsHWIntegration() && type() == WaylandSurface::Texture + && !m_surfaceBuffer->textureCreated()) { Surface *that = const_cast(this); - if (d->textureBuffer) { - d->textureBuffer->destructBufferState(); - that->d_func()->textureBuffer = 0; + if (m_textureBuffer) { + m_textureBuffer->destructBufferState(); + that->m_textureBuffer = 0; } - GraphicsHardwareIntegration *hwIntegration = d->compositor->graphicsHWIntegration(); - that->d_func()->textureBuffer = d->surfaceBuffer; - that->d_func()->textureBuffer->setTexture(hwIntegration->createTextureFromBuffer(d->textureBuffer->handle(), context)); + GraphicsHardwareIntegration *hwIntegration = m_compositor->graphicsHWIntegration(); + that->m_textureBuffer = m_surfaceBuffer; + that->m_textureBuffer->setTexture(hwIntegration->createTextureFromBuffer(m_textureBuffer->handle(), context)); } - return d->textureBuffer->texture(); + return m_textureBuffer->texture(); } #endif // QT_COMPOSITOR_WAYLAND_GL -void Surface::attach(struct wl_buffer *buffer) +WaylandSurface * Surface::waylandSurface() const { - Q_D(Surface); - static bool no_serverside_buffer_queue = qgetenv("QT_NO_SERVERSIDE_BUFFER_QUEUE").toInt(); - - SurfaceBuffer *newBuffer = 0; - if (no_serverside_buffer_queue) { - if (d->surfaceBuffer && !d->surfaceBuffer->textureCreated()) { - qDebug() << "releasing undisplayed buffer"; - d->surfaceBuffer->destructBufferState(); - d->surfaceBuffer = 0; - } - } - if (buffer) { - newBuffer = d->createSurfaceBuffer(buffer); - } - - SurfaceBuffer *last = d->bufferQueue.size()?d->bufferQueue.last():0; - if (last && !last->damageRect().isValid()) { - last->destructBufferState(); - d->bufferQueue.takeLast(); - } - d->bufferQueue << newBuffer; + return m_waylandSurface; } -WaylandSurface * Surface::handle() const +QPoint Surface::lastMousePos() const { - Q_D(const Surface); - return d->qtSurface; + return m_lastLocalMousePos; } -qint64 Surface::processId() const +void Surface::setExtendedSurface(ExtendedSurface *extendedSurface) { - Q_D(const Surface); - return d->processId; + m_extendedSurface = extendedSurface; } -void Surface::setProcessId(qint64 processId) +ExtendedSurface *Surface::extendedSurface() const { - Q_D(Surface); - d->processId = processId; + return m_extendedSurface; } -QByteArray Surface::authenticationToken() const +void Surface::setSubSurface(SubSurface *subSurface) { - Q_D(const Surface); - WaylandManagedClient *mcl = d->compositor->windowManagerIntegration()->managedClient(base()->resource.client); - return mcl ? mcl->authenticationToken() : QByteArray(); + m_subSurface = subSurface; } -QVariantMap Surface::windowProperties() const +SubSurface *Surface::subSurface() const { - Q_D(const Surface); - return d->windowProperties; + return m_subSurface; } -QVariant Surface::windowProperty(const QString &propertyName) const +void Surface::setShellSurface(ShellSurface *shellSurface) { - Q_D(const Surface); - QVariantMap props = d->windowProperties; - return props.value(propertyName); + m_shellSurface = shellSurface; } -void Surface::setWindowProperty(const QString &name, const QVariant &value, bool writeUpdateToClient) +ShellSurface *Surface::shellSurface() const { - Q_D(Surface); - d->windowProperties.insert(name, value); - handle()->windowPropertyChanged(name,value); - if (writeUpdateToClient && d->extendedSurface) { - d->extendedSurface->sendGenericProperty(name, value); - } + return m_shellSurface; } -Qt::ScreenOrientation Surface::windowOrientation() const +Compositor *Surface::compositor() const { - Q_D(const Surface); - return d->extendedSurface ? d->extendedSurface->windowOrientation() : Qt::PrimaryOrientation; + return m_compositor; } -Qt::ScreenOrientation Surface::contentOrientation() const +void Surface::sendFrameCallback() { - Q_D(const Surface); - return d->extendedSurface ? d->extendedSurface->contentOrientation() : Qt::PrimaryOrientation; + frameFinished(); + + uint time = Compositor::currentTimeMsecs(); + struct wl_resource *frame_callback; + wl_list_for_each(frame_callback, &m_frame_callback_list, link) { + wl_resource_post_event(frame_callback,WL_CALLBACK_DONE,time); + wl_resource_destroy(frame_callback,Compositor::currentTimeMsecs()); + } + + wl_list_init(&m_frame_callback_list); } -WaylandSurface::WindowFlags Surface::windowFlags() const +void Surface::frameFinished() { - Q_D(const Surface); - return d->extendedSurface ? d->extendedSurface->windowFlags() : WaylandSurface::WindowFlags(0); + m_compositor->frameFinished(this); } -QPoint Surface::lastMousePos() const -{ - Q_D(const Surface); - return d->lastLocalMousePos; +void Surface::doUpdate(const QRect &rect) { + if (postBuffer()) { + m_surfaceBuffer->setPosted(); // disown buffer.... + if (m_textureBuffer) { + m_textureBuffer->destructBufferState(); + m_textureBuffer = 0; + } + if (!m_bufferQueue.isEmpty()) { + qDebug() << "++++++++++++++++++++++++++++++++++++++++ recursive damage :-)"; + newCurrentBuffer(); + doUpdate(rect); + } + } else { + m_compositor->markSurfaceAsDirty(this); + emit m_waylandSurface->damaged(rect); + } } -void Surface::setExtendedSurface(ExtendedSurface *extendedSurface) -{ - Q_D(Surface); - d->extendedSurface = extendedSurface; +void Surface::newCurrentBuffer() { + //TODO release SHM buffer.... + if (m_surfaceBuffer && m_surfaceBuffer->isPosted()) { + m_surfaceBuffer->destructBufferState(); + } else if (m_surfaceBuffer && !m_surfaceBuffer->isDisplayed()) { + qDebug() << "### not skipping undisplayed buffer"; + return; + } + + m_surfaceBuffer = m_bufferQueue.takeFirst(); + + int width = 0; + int height = 0; + if (m_surfaceBuffer) { + width = m_surfaceBuffer->width(); + height = m_surfaceBuffer->height(); + } + setSize(QSize(width,height)); + + if (m_surfaceBuffer && (!m_subSurface || !m_subSurface->parent()) && !m_surfaceMapped) { + emit m_waylandSurface->mapped(); + m_surfaceMapped = true; + } else if (!m_surfaceBuffer && m_surfaceMapped) { + emit m_waylandSurface->unmapped(); + m_surfaceMapped = false; + } } -ExtendedSurface *Surface::extendedSurface() const +SurfaceBuffer *Surface::createSurfaceBuffer(struct wl_buffer *buffer) { - Q_D(const Surface); - return d->extendedSurface; + SurfaceBuffer *newBuffer = 0; + for (int i = 0; i < Surface::buffer_pool_size; i++) { + if (!m_bufferPool[i].isRegisteredWithBuffer()) { + newBuffer = &m_bufferPool[i]; + newBuffer->initialize(buffer); + break; + } + } + + Q_ASSERT(newBuffer); + return newBuffer; } -void Surface::setSubSurface(SubSurface *subSurface) -{ - Q_D(Surface); - d->subSurface = subSurface; +void Surface::frameFinishedInternal() { + if (m_surfaceBuffer) + m_surfaceBuffer->setFinished(); + + if (!m_bufferQueue.isEmpty()) { + newCurrentBuffer(); + if (m_surfaceBuffer) + doUpdate(m_surfaceBuffer->damageRect()); + } } -SubSurface *Surface::subSurface() const -{ - Q_D(const Surface); - return d->subSurface; +bool Surface::postBuffer() { +#ifdef QT_COMPOSITOR_WAYLAND_GL + if (m_compositor->graphicsHWIntegration() && m_waylandSurface->handle() == m_compositor->directRenderSurface()) { + // qDebug() << "posting...." << bufferQueue; + if (m_surfaceBuffer && m_surfaceBuffer->handle() && m_compositor->graphicsHWIntegration()->postBuffer(m_surfaceBuffer->handle())) { + return true; + } else { + qDebug() << "could not post buffer"; + } + } +#endif + return false; } -void Surface::setShellSurface(ShellSurface *shellSurface) +void Surface::attach(struct wl_buffer *buffer) { - Q_D(Surface); - d->shellSurface = shellSurface; + static bool no_serverside_buffer_queue = qgetenv("QT_NO_SERVERSIDE_BUFFER_QUEUE").toInt(); + + SurfaceBuffer *newBuffer = 0; + if (no_serverside_buffer_queue) { + if (m_surfaceBuffer && !m_surfaceBuffer->textureCreated()) { + qDebug() << "releasing undisplayed buffer"; + m_surfaceBuffer->destructBufferState(); + m_surfaceBuffer = 0; + } + } + if (buffer) { + newBuffer = createSurfaceBuffer(buffer); + } + + SurfaceBuffer *last = m_bufferQueue.size()?m_bufferQueue.last():0; + if (last && !last->damageRect().isValid()) { + last->destructBufferState(); + m_bufferQueue.takeLast(); + } + m_bufferQueue << newBuffer; } -ShellSurface *Surface::shellSurface() const +void Surface::damage(const QRect &rect) { - Q_D(const Surface); - return d->shellSurface; + if (!m_bufferQueue.isEmpty() && (!m_surfaceBuffer || m_surfaceBuffer->isFinished() || !m_surfaceBuffer->handle())) { + // Handle the "slow" case where we've finished the previous frame before the next damage comes. + newCurrentBuffer(); + doUpdate(rect); + } else if (m_bufferQueue.isEmpty()) { + // we've receicved a second damage for the same buffer + doUpdate(rect); + } else { + // we're still composing the previous buffer, so just store the damage rect for later + SurfaceBuffer *b = m_bufferQueue.last(); + if (b) + b->setDamage(rect); + else + qWarning() << "Surface::damage() null buffer"; + } } -Compositor *Surface::compositor() const +const struct wl_surface_interface Surface::surface_interface = { + Surface::surface_destroy, + Surface::surface_attach, + Surface::surface_damage, + Surface::surface_frame +}; + +void Surface::surface_destroy(struct wl_client *, struct wl_resource *surface_resource) { - Q_D(const Surface); - return d->compositor; + wl_resource_destroy(surface_resource,Compositor::currentTimeMsecs()); } -void Surface::sendFrameCallback() +void Surface::surface_attach(struct wl_client *client, struct wl_resource *surface, + struct wl_resource *buffer, int x, int y) { - Q_D(Surface); - - d->frameFinished(); - - uint time = Compositor::currentTimeMsecs(); - struct wl_resource *frame_callback; - wl_list_for_each(frame_callback, &d->frame_callback_list, link) { - wl_resource_post_event(frame_callback,WL_CALLBACK_DONE,time); - wl_resource_destroy(frame_callback,Compositor::currentTimeMsecs()); - } - - wl_list_init(&d->frame_callback_list); + Q_UNUSED(client); + Q_UNUSED(x); + Q_UNUSED(y); + reinterpret_cast(surface)->attach(reinterpret_cast(buffer)); } -void Surface::frameFinished() +void Surface::surface_damage(struct wl_client *client, struct wl_resource *surface, + int32_t x, int32_t y, int32_t width, int32_t height) { - Q_D(Surface); - d->compositor->frameFinished(this); + Q_UNUSED(client); + reinterpret_cast(surface)->damage(QRect(x, y, width, height)); } - -void Surface::sendOnScreenVisibilityChange(bool visible) +void Surface::surface_frame(struct wl_client *client, + struct wl_resource *resource, + uint32_t callback) { - Q_D(Surface); - if (d->extendedSurface) { - d->extendedSurface->sendOnScreenVisibllity(visible); - } + Surface *surface = reinterpret_cast(resource); + struct wl_resource *frame_callback = wl_client_add_object(client,&wl_callback_interface,0,callback,surface); + wl_list_insert(&surface->m_frame_callback_list,&frame_callback->link); } } // namespace Wayland diff --git a/src/compositor/wayland_wrapper/wlsurface.h b/src/compositor/wayland_wrapper/wlsurface.h index ecb4b5f..99476c8 100644 --- a/src/compositor/wayland_wrapper/wlsurface.h +++ b/src/compositor/wayland_wrapper/wlsurface.h @@ -44,6 +44,7 @@ #include "waylandexport.h" #include "wlshmbuffer.h" +#include "wlsurfacebuffer.h" #include "waylandsurface.h" #include "waylandobject.h" @@ -59,6 +60,8 @@ #include #endif +#include + class QTouchEvent; namespace Wayland { @@ -69,11 +72,8 @@ class ExtendedSurface; class SubSurface; class ShellSurface; -class SurfacePrivate; - class Q_COMPOSITOR_EXPORT Surface : public Object { - Q_DECLARE_PRIVATE(Surface) public: Surface(struct wl_client *client, uint32_t id, Compositor *compositor); ~Surface(); @@ -101,23 +101,7 @@ public: void frameFinished(); - void sendOnScreenVisibilityChange(bool visible); - - WaylandSurface *handle() const; - - qint64 processId() const; - void setProcessId(qint64 processId); - QByteArray authenticationToken() const; - void setAuthenticationToken(const QByteArray &authenticationToken); - - QVariantMap windowProperties() const; - QVariant windowProperty(const QString &propertyName) const; - void setWindowProperty(const QString &name, const QVariant &value, bool writeUpdateToClient = true); - - Qt::ScreenOrientation contentOrientation() const; - Qt::ScreenOrientation windowOrientation() const; - - WaylandSurface::WindowFlags windowFlags() const; + WaylandSurface *waylandSurface() const; QPoint lastMousePos() const; @@ -133,10 +117,39 @@ public: Compositor *compositor() const; static const struct wl_surface_interface surface_interface; -protected: - QScopedPointer d_ptr; + private: Q_DISABLE_COPY(Surface) + + Compositor *m_compositor; + WaylandSurface *m_waylandSurface; + + SurfaceBuffer *m_surfaceBuffer; + SurfaceBuffer *m_textureBuffer; + QList m_bufferQueue; + bool m_surfaceMapped; + + QPoint m_lastLocalMousePos; + QPoint m_lastGlobalMousePos; + + struct wl_list m_frame_callback_list; + + ExtendedSurface *m_extendedSurface; + SubSurface *m_subSurface; + ShellSurface *m_shellSurface; + + static const int buffer_pool_size = 3; + SurfaceBuffer m_bufferPool[buffer_pool_size]; + + QPointF m_position; + QSize m_size; + + void doUpdate(const QRect &rect); + void newCurrentBuffer(); + SurfaceBuffer *createSurfaceBuffer(struct wl_buffer *buffer); + void frameFinishedInternal(); + bool postBuffer(); + void attach(struct wl_buffer *buffer); void damage(const QRect &rect); diff --git a/src/compositor/wayland_wrapper/wlsurfacebuffer.cpp b/src/compositor/wayland_wrapper/wlsurfacebuffer.cpp new file mode 100644 index 0000000..240c58c --- /dev/null +++ b/src/compositor/wayland_wrapper/wlsurfacebuffer.cpp @@ -0,0 +1,135 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the Qt Compositor. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "wlsurfacebuffer.h" + +namespace Wayland { + +SurfaceBuffer::SurfaceBuffer() + : m_buffer(0) + , m_is_released_sent(false) + , m_is_registered_for_buffer(false) + , m_is_posted(false) + , m_is_frame_finished(false) + , m_texture(0) +{ +} + +SurfaceBuffer::~SurfaceBuffer() +{ + if (m_is_registered_for_buffer) + destructBufferState(); +} + +void SurfaceBuffer::initialize(wl_buffer *buffer) +{ + m_buffer = buffer; + m_texture = 0; + m_is_released_sent = false; + m_is_registered_for_buffer = true; + m_is_posted = false; + m_is_frame_finished = false; + m_destroy_listener.surfaceBuffer = this; + m_destroy_listener.listener.func = destroy_listener_callback; + wl_list_insert(&buffer->resource.destroy_listener_list,&m_destroy_listener.listener.link); + m_damageRect = QRect(); +} + +void SurfaceBuffer::destructBufferState() +{ + destroyTexture(); + if (m_buffer) { + wl_list_remove(&m_destroy_listener.listener.link); + sendRelease(); + } + m_buffer = 0; + m_is_registered_for_buffer = false; + m_is_posted = 0; +} + +void SurfaceBuffer::sendRelease() +{ + Q_ASSERT(m_buffer); + wl_resource_post_event(&m_buffer->resource, WL_BUFFER_RELEASE); + m_buffer = 0; + m_is_released_sent = true; +} + +void SurfaceBuffer::setPosted() +{ + m_is_posted = true; + if (m_buffer) { + wl_list_remove(&m_destroy_listener.listener.link); + } + m_buffer = 0; +} + +void SurfaceBuffer::setFinished() +{ + m_is_frame_finished = true; +} + +void SurfaceBuffer::destroyTexture() +{ +#ifdef QT_COMPOSITOR_WAYLAND_GL + if (m_texture) { + glDeleteTextures(1,&m_texture); + m_texture = 0; + } +#endif +} + +void SurfaceBuffer::destroy_listener_callback(wl_listener *listener, wl_resource *resource, uint32_t time) +{ + Q_UNUSED(resource); + Q_UNUSED(time); + struct surface_buffer_destroy_listener *destroy_listener = + reinterpret_cast(listener); + SurfaceBuffer *d = destroy_listener->surfaceBuffer; + d->destroyTexture(); + d->m_buffer = 0; +} + +void SurfaceBuffer::setTexture(GLuint texId) +{ + m_texture = texId; +} + +} diff --git a/src/compositor/wayland_wrapper/wlsurfacebuffer.h b/src/compositor/wayland_wrapper/wlsurfacebuffer.h new file mode 100644 index 0000000..00f1937 --- /dev/null +++ b/src/compositor/wayland_wrapper/wlsurfacebuffer.h @@ -0,0 +1,132 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the Qt Compositor. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef SURFACEBUFFER_H +#define SURFACEBUFFER_H + +#include +#include + +#include + +namespace Wayland { + +struct surface_buffer_destroy_listener +{ + struct wl_listener listener; + class SurfaceBuffer *surfaceBuffer; +}; + +class SurfaceBuffer +{ +public: + SurfaceBuffer(); + + + ~SurfaceBuffer(); + + + void initialize(struct wl_buffer *buffer); + void destructBufferState(); + inline bool bufferIsDestroyed() const { return m_is_registered_for_buffer &&!m_buffer; } + + inline int32_t width() const { return m_buffer->width; } + inline int32_t height() const { return m_buffer->height; } + + inline bool isShmBuffer() const { return wl_buffer_is_shm(m_buffer); } + + inline bool isReleasedSent() const { return m_is_released_sent; } + inline bool isRegisteredWithBuffer() const { return m_is_registered_for_buffer; } + + void sendRelease(); + + void setPosted(); + + void setFinished(); + + inline bool isPosted() const { return m_is_posted; } + + //this is wrong. Should have a frameSent function; + inline bool isDisplayed() const { return m_texture || m_is_posted || wl_buffer_is_shm(m_buffer); } + + //I don't know understand isFinished. + inline bool isFinished() const { return m_is_frame_finished; } + + inline QRect damageRect() const { return m_damageRect; } + + inline void setDamage(const QRect &rect) { m_damageRect = rect; } + + inline bool textureCreated() const { return m_texture; } + + void setTexture(GLuint texId); + inline GLuint texture(); + + void destroyTexture(); + + inline struct wl_buffer *handle() const { return m_buffer; } +private: + struct wl_buffer *m_buffer; + struct surface_buffer_destroy_listener m_destroy_listener; + QRect m_damageRect; + bool m_is_released_sent; + bool m_is_registered_for_buffer; + bool m_is_posted; + bool m_is_frame_finished; +#ifdef QT_COMPOSITOR_WAYLAND_GL + GLuint m_texture; +#else + uint m_texture; +#endif + + static void destroy_listener_callback(struct wl_listener *listener, + struct wl_resource *resource, uint32_t time); + +}; + +GLuint SurfaceBuffer::texture() +{ + if (m_buffer) + return m_texture; + return 0; +} + +} + +#endif // SURFACEBUFFER_H -- 2.7.4