[kwin_wayland] Create a dedicated Surface class

A Surface class is split out which holds a wl_surface and supports
attaching a buffer, setting the damage and emitting a signal when the
frame callback got called.

It doesn't come with a unit test yet as it first needs the ShmPool
and Buffer properly split out to easily set it up.
This commit is contained in:
Martin Gräßlin 2014-08-20 14:06:58 +02:00
parent bd8ed3cd70
commit ce8c4240f7
14 changed files with 263 additions and 79 deletions

View file

@ -431,6 +431,7 @@ if(Wayland_Client_FOUND AND XKB_FOUND)
wayland_client/fullscreen_shell.cpp wayland_client/fullscreen_shell.cpp
wayland_client/output.cpp wayland_client/output.cpp
wayland_client/shell.cpp wayland_client/shell.cpp
wayland_client/surface.cpp
${CMAKE_BINARY_DIR}/wayland_protocols/wayland-client-fullscreen-shell.c ${CMAKE_BINARY_DIR}/wayland_protocols/wayland-client-fullscreen-shell.c
) )
if(KWIN_HAVE_EGL AND Wayland_Egl_FOUND) if(KWIN_HAVE_EGL AND Wayland_Egl_FOUND)

View file

@ -66,10 +66,11 @@ set( testWaylandShell_SRCS
${KWIN_SOURCE_DIR}/wayland_client/registry.cpp ${KWIN_SOURCE_DIR}/wayland_client/registry.cpp
${KWIN_SOURCE_DIR}/wayland_client/fullscreen_shell.cpp ${KWIN_SOURCE_DIR}/wayland_client/fullscreen_shell.cpp
${KWIN_SOURCE_DIR}/wayland_client/shell.cpp ${KWIN_SOURCE_DIR}/wayland_client/shell.cpp
${KWIN_SOURCE_DIR}/wayland_client/surface.cpp
${CMAKE_BINARY_DIR}/wayland_protocols/wayland-client-fullscreen-shell.c ${CMAKE_BINARY_DIR}/wayland_protocols/wayland-client-fullscreen-shell.c
) )
add_executable(testWaylandShell ${testWaylandShell_SRCS}) add_executable(testWaylandShell ${testWaylandShell_SRCS})
add_dependencies(testWaylandShell wayland-client-fullscreen-shell) add_dependencies(testWaylandShell wayland-client-fullscreen-shell)
target_link_libraries( testWaylandShell Qt5::Test Wayland::Client) target_link_libraries( testWaylandShell Qt5::Test Qt5::Gui Wayland::Client)
add_test(kwin-testWaylandShell testWaylandShell) add_test(kwin-testWaylandShell testWaylandShell)
ecm_mark_as_test(testWaylandShell) ecm_mark_as_test(testWaylandShell)

View file

@ -22,6 +22,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
// KWin // KWin
#include "../../wayland_client/connection_thread.h" #include "../../wayland_client/connection_thread.h"
#include "../../wayland_client/shell.h" #include "../../wayland_client/shell.h"
#include "../../wayland_client/surface.h"
#include "../../wayland_client/registry.h" #include "../../wayland_client/registry.h"
// Wayland // Wayland
#include <wayland-client-protocol.h> #include <wayland-client-protocol.h>
@ -151,7 +152,9 @@ void TestWaylandShell::testShell()
KWin::Wayland::Shell shell; KWin::Wayland::Shell shell;
shell.setup(registry.bindShell(announced.first().first().value<quint32>(), announced.first().last().value<quint32>())); shell.setup(registry.bindShell(announced.first().first().value<quint32>(), announced.first().last().value<quint32>()));
wl_display_flush(connection.display()); wl_display_flush(connection.display());
KWin::Wayland::ShellSurface *surface = shell.createSurface(wl_compositor_create_surface(compositor), &shell); KWin::Wayland::Surface s;
s.setup(wl_compositor_create_surface(compositor));
KWin::Wayland::ShellSurface *surface = shell.createSurface(&s, &shell);
QSignalSpy sizeSpy(surface, SIGNAL(sizeChanged(QSize))); QSignalSpy sizeSpy(surface, SIGNAL(sizeChanged(QSize)));
QVERIFY(sizeSpy.isValid()); QVERIFY(sizeSpy.isValid());
QCOMPARE(surface->size(), QSize()); QCOMPARE(surface->size(), QSize());
@ -167,6 +170,7 @@ void TestWaylandShell::testShell()
shell.release(); shell.release();
QVERIFY(!surface->isValid()); QVERIFY(!surface->isValid());
s.release();
wl_compositor_destroy(compositor); wl_compositor_destroy(compositor);
} }

View file

@ -23,6 +23,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "composite.h" #include "composite.h"
#include "options.h" #include "options.h"
#include "wayland_backend.h" #include "wayland_backend.h"
#include "wayland_client/surface.h"
#include "xcbutils.h" #include "xcbutils.h"
// kwin libs // kwin libs
#include <kwinglplatform.h> #include <kwinglplatform.h>
@ -33,21 +34,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
namespace KWin namespace KWin
{ {
static void handleFrameCallback(void *data, wl_callback *callback, uint32_t time)
{
Q_UNUSED(data)
Q_UNUSED(time)
reinterpret_cast<EglWaylandBackend*>(data)->lastFrameRendered();
if (callback) {
wl_callback_destroy(callback);
}
}
static const struct wl_callback_listener s_surfaceFrameListener = {
handleFrameCallback
};
EglWaylandBackend::EglWaylandBackend() EglWaylandBackend::EglWaylandBackend()
: QObject(NULL) : QObject(NULL)
, OpenGLBackend() , OpenGLBackend()
@ -186,7 +172,9 @@ bool EglWaylandBackend::initRenderingContext()
} }
const QSize &size = m_wayland->shellSurfaceSize(); const QSize &size = m_wayland->shellSurfaceSize();
m_overlay = wl_egl_window_create(m_wayland->surface(), size.width(), size.height()); Wayland::Surface *s = m_wayland->surface();
connect(s, &Wayland::Surface::frameRendered, this, &EglWaylandBackend::lastFrameRendered);
m_overlay = wl_egl_window_create(*s, size.width(), size.height());
if (!m_overlay) { if (!m_overlay) {
qCritical() << "Creating Wayland Egl window failed"; qCritical() << "Creating Wayland Egl window failed";
return false; return false;
@ -251,8 +239,7 @@ bool EglWaylandBackend::initBufferConfigs()
void EglWaylandBackend::present() void EglWaylandBackend::present()
{ {
m_lastFrameRendered = false; m_lastFrameRendered = false;
wl_callback *callback = wl_surface_frame(m_wayland->surface()); m_wayland->surface()->setupFrameCallback();
wl_callback_add_listener(callback, &s_surfaceFrameListener, this);
if (supportsBufferAge()) { if (supportsBufferAge()) {
eglSwapBuffers(m_display, m_surface); eglSwapBuffers(m_display, m_surface);
eglQuerySurface(m_display, m_surface, EGL_BUFFER_AGE_EXT, &m_bufferAge); eglQuerySurface(m_display, m_surface, EGL_BUFFER_AGE_EXT, &m_bufferAge);

View file

@ -28,6 +28,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "toplevel.h" #include "toplevel.h"
#if HAVE_WAYLAND #if HAVE_WAYLAND
#include "wayland_backend.h" #include "wayland_backend.h"
#include "wayland_client/surface.h"
#endif #endif
#include "workspace.h" #include "workspace.h"
#include "xcbutils.h" #include "xcbutils.h"
@ -79,20 +80,6 @@ void QPainterBackend::setFailed(const QString &reason)
//**************************************** //****************************************
// WaylandQPainterBackend // WaylandQPainterBackend
//**************************************** //****************************************
static void handleFrameCallback(void *data, wl_callback *callback, uint32_t time)
{
Q_UNUSED(data)
Q_UNUSED(time)
reinterpret_cast<WaylandQPainterBackend*>(data)->lastFrameRendered();
if (callback) {
wl_callback_destroy(callback);
}
}
static const struct wl_callback_listener s_surfaceFrameListener = {
handleFrameCallback
};
WaylandQPainterBackend::WaylandQPainterBackend() WaylandQPainterBackend::WaylandQPainterBackend()
: QPainterBackend() : QPainterBackend()
@ -104,6 +91,8 @@ WaylandQPainterBackend::WaylandQPainterBackend()
connect(Wayland::WaylandBackend::self()->shmPool(), SIGNAL(poolResized()), SLOT(remapBuffer())); connect(Wayland::WaylandBackend::self()->shmPool(), SIGNAL(poolResized()), SLOT(remapBuffer()));
connect(Wayland::WaylandBackend::self(), &Wayland::WaylandBackend::shellSurfaceSizeChanged, connect(Wayland::WaylandBackend::self(), &Wayland::WaylandBackend::shellSurfaceSizeChanged,
this, &WaylandQPainterBackend::screenGeometryChanged); this, &WaylandQPainterBackend::screenGeometryChanged);
connect(Wayland::WaylandBackend::self()->surface(), &Wayland::Surface::frameRendered,
this, &WaylandQPainterBackend::lastFrameRendered);
} }
WaylandQPainterBackend::~WaylandQPainterBackend() WaylandQPainterBackend::~WaylandQPainterBackend()
@ -126,20 +115,15 @@ bool WaylandQPainterBackend::usesOverlayWindow() const
void WaylandQPainterBackend::present(int mask, const QRegion &damage) void WaylandQPainterBackend::present(int mask, const QRegion &damage)
{ {
Q_UNUSED(mask) Q_UNUSED(mask)
Wayland::WaylandBackend *wl = Wayland::WaylandBackend::self();
if (m_backBuffer.isNull()) { if (m_backBuffer.isNull()) {
return; return;
} }
m_lastFrameRendered = false; m_lastFrameRendered = false;
m_needsFullRepaint = false; m_needsFullRepaint = false;
wl_surface *surface = wl->surface(); Wayland::Surface *s = Wayland::WaylandBackend::self()->surface();
wl_callback *callback = wl_surface_frame(surface); s->attachBuffer(m_buffer->buffer());
wl_callback_add_listener(callback, &s_surfaceFrameListener, this); s->damage(damage);
wl_surface_attach(surface, m_buffer->buffer(), 0, 0); s->commit();
Q_FOREACH (const QRect &rect, damage.rects()) {
wl_surface_damage(surface, rect.x(), rect.y(), rect.width(), rect.height());
}
wl_surface_commit(surface);
} }
void WaylandQPainterBackend::lastFrameRendered() void WaylandQPainterBackend::lastFrameRendered()

View file

@ -37,6 +37,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "kwinxrenderutils.h" #include "kwinxrenderutils.h"
#if HAVE_WAYLAND #if HAVE_WAYLAND
#include "wayland_backend.h" #include "wayland_backend.h"
#include "wayland_client/surface.h"
#endif #endif
#include <xcb/xfixes.h> #include <xcb/xfixes.h>
@ -257,20 +258,6 @@ bool X11XRenderBackend::usesOverlayWindow() const
// WaylandXRenderBackend // WaylandXRenderBackend
//**************************************** //****************************************
#if HAVE_WAYLAND #if HAVE_WAYLAND
static void handleFrameCallback(void *data, wl_callback *callback, uint32_t time)
{
Q_UNUSED(data)
Q_UNUSED(time)
reinterpret_cast<WaylandXRenderBackend*>(data)->lastFrameRendered();
if (callback) {
wl_callback_destroy(callback);
}
}
static const struct wl_callback_listener s_surfaceFrameListener = {
handleFrameCallback
};
WaylandXRenderBackend::WaylandXRenderBackend() WaylandXRenderBackend::WaylandXRenderBackend()
: m_shm(new Xcb::Shm) : m_shm(new Xcb::Shm)
@ -286,6 +273,8 @@ WaylandXRenderBackend::WaylandXRenderBackend()
init(); init();
connect(Wayland::WaylandBackend::self(), &Wayland::WaylandBackend::shellSurfaceSizeChanged, connect(Wayland::WaylandBackend::self(), &Wayland::WaylandBackend::shellSurfaceSizeChanged,
this, &WaylandXRenderBackend::createBuffer); this, &WaylandXRenderBackend::createBuffer);
connect(Wayland::WaylandBackend::self()->surface(), &Wayland::Surface::frameRendered,
this, &WaylandXRenderBackend::lastFrameRendered);
} }
WaylandXRenderBackend::~WaylandXRenderBackend() WaylandXRenderBackend::~WaylandXRenderBackend()
@ -341,14 +330,10 @@ void WaylandXRenderBackend::present(int mask, const QRegion &damage)
return; return;
} }
m_lastFrameRendered = false; m_lastFrameRendered = false;
wl_surface *surface = wl->surface(); Wayland::Surface *s = wl->surface();
wl_callback *callback = wl_surface_frame(surface); s->attachBuffer(buffer);
wl_callback_add_listener(callback, &s_surfaceFrameListener, this); s->damage(damage);
wl_surface_attach(surface, buffer, 0, 0); s->commit();
Q_FOREACH (const QRect &rect, damage.rects()) {
wl_surface_damage(surface, rect.x(), rect.y(), rect.width(), rect.height());
}
wl_surface_commit(surface);
} }
bool WaylandXRenderBackend::isLastFrameRendered() const bool WaylandXRenderBackend::isLastFrameRendered() const

View file

@ -27,6 +27,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "wayland_client/output.h" #include "wayland_client/output.h"
#include "wayland_client/registry.h" #include "wayland_client/registry.h"
#include "wayland_client/shell.h" #include "wayland_client/shell.h"
#include "wayland_client/surface.h"
// Qt // Qt
#include <QAbstractEventDispatcher> #include <QAbstractEventDispatcher>
#include <QCoreApplication> #include <QCoreApplication>
@ -565,7 +566,7 @@ WaylandBackend::WaylandBackend(QObject *parent)
, m_registry(new Registry(this)) , m_registry(new Registry(this))
, m_compositor(NULL) , m_compositor(NULL)
, m_shell(new Shell(this)) , m_shell(new Shell(this))
, m_surface(NULL) , m_surface(new Surface(this))
, m_shellSurface(NULL) , m_shellSurface(NULL)
, m_seat() , m_seat()
, m_shm() , m_shm()
@ -617,9 +618,7 @@ WaylandBackend::~WaylandBackend()
m_shellSurface->release(); m_shellSurface->release();
} }
m_fullscreenShell->release(); m_fullscreenShell->release();
if (m_surface) { m_surface->release();
wl_surface_destroy(m_surface);
}
m_shell->release(); m_shell->release();
if (m_compositor) { if (m_compositor) {
wl_compositor_destroy(m_compositor); wl_compositor_destroy(m_compositor);
@ -677,10 +676,7 @@ void WaylandBackend::initConnection()
m_shellSurface = nullptr; m_shellSurface = nullptr;
} }
m_fullscreenShell->destroy(); m_fullscreenShell->destroy();
if (m_surface) { m_surface->destroy();
free(m_surface);
m_surface = nullptr;
}
if (m_shell) { if (m_shell) {
m_shell->destroy(); m_shell->destroy();
} }
@ -718,14 +714,14 @@ void WaylandBackend::installCursorImage(Qt::CursorShape shape)
void WaylandBackend::createSurface() void WaylandBackend::createSurface()
{ {
m_surface = wl_compositor_create_surface(m_compositor); m_surface->setup(wl_compositor_create_surface(m_compositor));
if (!m_surface) { if (!m_surface->isValid()) {
qCritical() << "Creating Wayland Surface failed"; qCritical() << "Creating Wayland Surface failed";
return; return;
} }
if (m_fullscreenShell->isValid()) { if (m_fullscreenShell->isValid()) {
Output *o = m_outputs.first(); Output *o = m_outputs.first();
m_fullscreenShell->present(m_surface, o->output()); m_fullscreenShell->present(m_surface, o);
if (o->pixelSize().isValid()) { if (o->pixelSize().isValid()) {
emit shellSurfaceSizeChanged(o->pixelSize()); emit shellSurfaceSizeChanged(o->pixelSize());
} }

View file

@ -52,6 +52,7 @@ class Output;
class Registry; class Registry;
class Shell; class Shell;
class ShellSurface; class ShellSurface;
class Surface;
class CursorData class CursorData
{ {
@ -187,7 +188,7 @@ public:
void createSeat(uint32_t name); void createSeat(uint32_t name);
void createShm(uint32_t name); void createShm(uint32_t name);
wl_surface *surface() const; Surface *surface() const;
QSize shellSurfaceSize() const; QSize shellSurfaceSize() const;
void installCursorImage(Qt::CursorShape shape); void installCursorImage(Qt::CursorShape shape);
Q_SIGNALS: Q_SIGNALS:
@ -206,7 +207,7 @@ private:
Registry *m_registry; Registry *m_registry;
wl_compositor *m_compositor; wl_compositor *m_compositor;
Shell *m_shell; Shell *m_shell;
wl_surface *m_surface; Surface *m_surface;
ShellSurface *m_shellSurface; ShellSurface *m_shellSurface;
QScopedPointer<WaylandSeat> m_seat; QScopedPointer<WaylandSeat> m_seat;
QScopedPointer<ShmPool> m_shm; QScopedPointer<ShmPool> m_shm;
@ -285,7 +286,7 @@ ShmPool* WaylandBackend::shmPool()
} }
inline inline
wl_surface *WaylandBackend::surface() const Surface *WaylandBackend::surface() const
{ {
return m_surface; return m_surface;
} }

View file

@ -18,6 +18,8 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*********************************************************************/ *********************************************************************/
#include "fullscreen_shell.h" #include "fullscreen_shell.h"
#include "surface.h"
#include "output.h"
#include <QDebug> #include <QDebug>
@ -92,5 +94,12 @@ void FullscreenShell::present(wl_surface *surface, wl_output *output)
_wl_fullscreen_shell_present_surface(m_shell, surface, _WL_FULLSCREEN_SHELL_PRESENT_METHOD_DEFAULT, output); _wl_fullscreen_shell_present_surface(m_shell, surface, _WL_FULLSCREEN_SHELL_PRESENT_METHOD_DEFAULT, output);
} }
void FullscreenShell::present(Surface *surface, Output *output)
{
Q_ASSERT(surface);
Q_ASSERT(output);
present(*surface, *output);
}
} }
} }

View file

@ -30,6 +30,9 @@ namespace KWin
namespace Wayland namespace Wayland
{ {
class Surface;
class Output;
class FullscreenShell : public QObject class FullscreenShell : public QObject
{ {
Q_OBJECT Q_OBJECT
@ -52,6 +55,7 @@ public:
} }
void setup(_wl_fullscreen_shell *shell); void setup(_wl_fullscreen_shell *shell);
void present(wl_surface *surface, wl_output *output); void present(wl_surface *surface, wl_output *output);
void present(Surface *surface, Output *output);
static void capabilitiesAnnounce(void *data, struct _wl_fullscreen_shell *shell, uint32_t capability); static void capabilitiesAnnounce(void *data, struct _wl_fullscreen_shell *shell, uint32_t capability);

View file

@ -19,6 +19,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*********************************************************************/ *********************************************************************/
#include "shell.h" #include "shell.h"
#include "output.h" #include "output.h"
#include "surface.h"
namespace KWin namespace KWin
{ {
@ -73,6 +74,12 @@ ShellSurface *Shell::createSurface(wl_surface *surface, QObject *parent)
return s; return s;
} }
ShellSurface *Shell::createSurface(Surface *surface, QObject *parent)
{
Q_ASSERT(surface);
return createSurface(*surface, parent);
}
ShellSurface::ShellSurface(QObject *parent) ShellSurface::ShellSurface(QObject *parent)
: QObject(parent) : QObject(parent)
, m_surface(nullptr) , m_surface(nullptr)

View file

@ -31,6 +31,7 @@ namespace Wayland
{ {
class ShellSurface; class ShellSurface;
class Output; class Output;
class Surface;
class Shell : public QObject class Shell : public QObject
{ {
@ -47,6 +48,7 @@ public:
void setup(wl_shell *shell); void setup(wl_shell *shell);
ShellSurface *createSurface(wl_surface *surface, QObject *parent = nullptr); ShellSurface *createSurface(wl_surface *surface, QObject *parent = nullptr);
ShellSurface *createSurface(Surface *surface, QObject *parent = nullptr);
operator wl_shell*() { operator wl_shell*() {
return m_shell; return m_shell;

125
wayland_client/surface.cpp Normal file
View file

@ -0,0 +1,125 @@
/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2014 Martin Gräßlin <mgraesslin@kde.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*********************************************************************/
#include "surface.h"
#include <QRegion>
#include <QVector>
namespace KWin
{
namespace Wayland
{
Surface::Surface(QObject *parent)
: QObject(parent)
, m_surface(nullptr)
, m_frameCallbackInstalled(false)
{
}
Surface::~Surface()
{
release();
}
void Surface::release()
{
if (!m_surface) {
return;
}
wl_surface_destroy(m_surface);
m_surface = nullptr;
}
void Surface::destroy()
{
if (!m_surface) {
return;
}
free(m_surface);
m_surface = nullptr;
}
void Surface::setup(wl_surface *surface)
{
Q_ASSERT(surface);
Q_ASSERT(!m_surface);
m_surface = surface;
}
void Surface::frameCallback(void *data, wl_callback *callback, uint32_t time)
{
Q_UNUSED(time)
Surface *s = reinterpret_cast<Surface*>(data);
if (callback) {
wl_callback_destroy(callback);
}
s->handleFrameCallback();
}
void Surface::handleFrameCallback()
{
m_frameCallbackInstalled = false;
frameRendered();
}
const struct wl_callback_listener Surface::s_listener = {
Surface::frameCallback
};
void Surface::setupFrameCallback()
{
Q_ASSERT(isValid());
Q_ASSERT(!m_frameCallbackInstalled);
wl_callback *callback = wl_surface_frame(m_surface);
wl_callback_add_listener(callback, &s_listener, this);
m_frameCallbackInstalled = true;
}
void Surface::commit(Surface::CommitFlag flag)
{
Q_ASSERT(isValid());
if (flag == CommitFlag::FrameCallback) {
setupFrameCallback();
}
wl_surface_commit(m_surface);
}
void Surface::damage(const QRegion &region)
{
for (const QRect &r : region.rects()) {
damage(r);
}
}
void Surface::damage(const QRect &rect)
{
Q_ASSERT(isValid());
wl_surface_damage(m_surface, rect.x(), rect.y(), rect.width(), rect.height());
}
void Surface::attachBuffer(wl_buffer *buffer, const QPoint &offset)
{
Q_ASSERT(isValid());
wl_surface_attach(m_surface, buffer, offset.x(), offset.y());
}
}
}

78
wayland_client/surface.h Normal file
View file

@ -0,0 +1,78 @@
/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2014 Martin Gräßlin <mgraesslin@kde.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*********************************************************************/
#ifndef KWIN_WAYLAND_SURFACE_H
#define KWIN_WAYLAND_SURFACE_H
#include <QObject>
#include <QPoint>
#include <wayland-client-protocol.h>
namespace KWin
{
namespace Wayland
{
class Surface : public QObject
{
Q_OBJECT
public:
explicit Surface(QObject *parent = nullptr);
virtual ~Surface();
void setup(wl_surface *surface);
void release();
void destroy();
bool isValid() const {
return m_surface != nullptr;
}
void setupFrameCallback();
enum class CommitFlag {
None,
FrameCallback
};
void commit(CommitFlag flag = CommitFlag::FrameCallback);
void damage(const QRect &rect);
void damage(const QRegion &region);
void attachBuffer(wl_buffer *buffer, const QPoint &offset = QPoint());
operator wl_surface*() {
return m_surface;
}
operator wl_surface*() const {
return m_surface;
}
static void frameCallback(void *data, wl_callback *callback, uint32_t time);
Q_SIGNALS:
void frameRendered();
private:
void handleFrameCallback();
static const wl_callback_listener s_listener;
wl_surface *m_surface;
bool m_frameCallbackInstalled;
};
}
}
#endif