[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:
parent
bd8ed3cd70
commit
ce8c4240f7
14 changed files with 263 additions and 79 deletions
|
@ -431,6 +431,7 @@ if(Wayland_Client_FOUND AND XKB_FOUND)
|
|||
wayland_client/fullscreen_shell.cpp
|
||||
wayland_client/output.cpp
|
||||
wayland_client/shell.cpp
|
||||
wayland_client/surface.cpp
|
||||
${CMAKE_BINARY_DIR}/wayland_protocols/wayland-client-fullscreen-shell.c
|
||||
)
|
||||
if(KWIN_HAVE_EGL AND Wayland_Egl_FOUND)
|
||||
|
|
|
@ -66,10 +66,11 @@ set( testWaylandShell_SRCS
|
|||
${KWIN_SOURCE_DIR}/wayland_client/registry.cpp
|
||||
${KWIN_SOURCE_DIR}/wayland_client/fullscreen_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
|
||||
)
|
||||
add_executable(testWaylandShell ${testWaylandShell_SRCS})
|
||||
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)
|
||||
ecm_mark_as_test(testWaylandShell)
|
||||
|
|
|
@ -22,6 +22,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
// KWin
|
||||
#include "../../wayland_client/connection_thread.h"
|
||||
#include "../../wayland_client/shell.h"
|
||||
#include "../../wayland_client/surface.h"
|
||||
#include "../../wayland_client/registry.h"
|
||||
// Wayland
|
||||
#include <wayland-client-protocol.h>
|
||||
|
@ -151,7 +152,9 @@ void TestWaylandShell::testShell()
|
|||
KWin::Wayland::Shell shell;
|
||||
shell.setup(registry.bindShell(announced.first().first().value<quint32>(), announced.first().last().value<quint32>()));
|
||||
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)));
|
||||
QVERIFY(sizeSpy.isValid());
|
||||
QCOMPARE(surface->size(), QSize());
|
||||
|
@ -167,6 +170,7 @@ void TestWaylandShell::testShell()
|
|||
shell.release();
|
||||
QVERIFY(!surface->isValid());
|
||||
|
||||
s.release();
|
||||
wl_compositor_destroy(compositor);
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include "composite.h"
|
||||
#include "options.h"
|
||||
#include "wayland_backend.h"
|
||||
#include "wayland_client/surface.h"
|
||||
#include "xcbutils.h"
|
||||
// kwin libs
|
||||
#include <kwinglplatform.h>
|
||||
|
@ -33,21 +34,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
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()
|
||||
: QObject(NULL)
|
||||
, OpenGLBackend()
|
||||
|
@ -186,7 +172,9 @@ bool EglWaylandBackend::initRenderingContext()
|
|||
}
|
||||
|
||||
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) {
|
||||
qCritical() << "Creating Wayland Egl window failed";
|
||||
return false;
|
||||
|
@ -251,8 +239,7 @@ bool EglWaylandBackend::initBufferConfigs()
|
|||
void EglWaylandBackend::present()
|
||||
{
|
||||
m_lastFrameRendered = false;
|
||||
wl_callback *callback = wl_surface_frame(m_wayland->surface());
|
||||
wl_callback_add_listener(callback, &s_surfaceFrameListener, this);
|
||||
m_wayland->surface()->setupFrameCallback();
|
||||
if (supportsBufferAge()) {
|
||||
eglSwapBuffers(m_display, m_surface);
|
||||
eglQuerySurface(m_display, m_surface, EGL_BUFFER_AGE_EXT, &m_bufferAge);
|
||||
|
|
|
@ -28,6 +28,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include "toplevel.h"
|
||||
#if HAVE_WAYLAND
|
||||
#include "wayland_backend.h"
|
||||
#include "wayland_client/surface.h"
|
||||
#endif
|
||||
#include "workspace.h"
|
||||
#include "xcbutils.h"
|
||||
|
@ -79,20 +80,6 @@ void QPainterBackend::setFailed(const QString &reason)
|
|||
//****************************************
|
||||
// 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()
|
||||
: QPainterBackend()
|
||||
|
@ -104,6 +91,8 @@ WaylandQPainterBackend::WaylandQPainterBackend()
|
|||
connect(Wayland::WaylandBackend::self()->shmPool(), SIGNAL(poolResized()), SLOT(remapBuffer()));
|
||||
connect(Wayland::WaylandBackend::self(), &Wayland::WaylandBackend::shellSurfaceSizeChanged,
|
||||
this, &WaylandQPainterBackend::screenGeometryChanged);
|
||||
connect(Wayland::WaylandBackend::self()->surface(), &Wayland::Surface::frameRendered,
|
||||
this, &WaylandQPainterBackend::lastFrameRendered);
|
||||
}
|
||||
|
||||
WaylandQPainterBackend::~WaylandQPainterBackend()
|
||||
|
@ -126,20 +115,15 @@ bool WaylandQPainterBackend::usesOverlayWindow() const
|
|||
void WaylandQPainterBackend::present(int mask, const QRegion &damage)
|
||||
{
|
||||
Q_UNUSED(mask)
|
||||
Wayland::WaylandBackend *wl = Wayland::WaylandBackend::self();
|
||||
if (m_backBuffer.isNull()) {
|
||||
return;
|
||||
}
|
||||
m_lastFrameRendered = false;
|
||||
m_needsFullRepaint = false;
|
||||
wl_surface *surface = wl->surface();
|
||||
wl_callback *callback = wl_surface_frame(surface);
|
||||
wl_callback_add_listener(callback, &s_surfaceFrameListener, this);
|
||||
wl_surface_attach(surface, m_buffer->buffer(), 0, 0);
|
||||
Q_FOREACH (const QRect &rect, damage.rects()) {
|
||||
wl_surface_damage(surface, rect.x(), rect.y(), rect.width(), rect.height());
|
||||
}
|
||||
wl_surface_commit(surface);
|
||||
Wayland::Surface *s = Wayland::WaylandBackend::self()->surface();
|
||||
s->attachBuffer(m_buffer->buffer());
|
||||
s->damage(damage);
|
||||
s->commit();
|
||||
}
|
||||
|
||||
void WaylandQPainterBackend::lastFrameRendered()
|
||||
|
|
|
@ -37,6 +37,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include "kwinxrenderutils.h"
|
||||
#if HAVE_WAYLAND
|
||||
#include "wayland_backend.h"
|
||||
#include "wayland_client/surface.h"
|
||||
#endif
|
||||
|
||||
#include <xcb/xfixes.h>
|
||||
|
@ -257,20 +258,6 @@ bool X11XRenderBackend::usesOverlayWindow() const
|
|||
// WaylandXRenderBackend
|
||||
//****************************************
|
||||
#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()
|
||||
: m_shm(new Xcb::Shm)
|
||||
|
@ -286,6 +273,8 @@ WaylandXRenderBackend::WaylandXRenderBackend()
|
|||
init();
|
||||
connect(Wayland::WaylandBackend::self(), &Wayland::WaylandBackend::shellSurfaceSizeChanged,
|
||||
this, &WaylandXRenderBackend::createBuffer);
|
||||
connect(Wayland::WaylandBackend::self()->surface(), &Wayland::Surface::frameRendered,
|
||||
this, &WaylandXRenderBackend::lastFrameRendered);
|
||||
}
|
||||
|
||||
WaylandXRenderBackend::~WaylandXRenderBackend()
|
||||
|
@ -341,14 +330,10 @@ void WaylandXRenderBackend::present(int mask, const QRegion &damage)
|
|||
return;
|
||||
}
|
||||
m_lastFrameRendered = false;
|
||||
wl_surface *surface = wl->surface();
|
||||
wl_callback *callback = wl_surface_frame(surface);
|
||||
wl_callback_add_listener(callback, &s_surfaceFrameListener, this);
|
||||
wl_surface_attach(surface, buffer, 0, 0);
|
||||
Q_FOREACH (const QRect &rect, damage.rects()) {
|
||||
wl_surface_damage(surface, rect.x(), rect.y(), rect.width(), rect.height());
|
||||
}
|
||||
wl_surface_commit(surface);
|
||||
Wayland::Surface *s = wl->surface();
|
||||
s->attachBuffer(buffer);
|
||||
s->damage(damage);
|
||||
s->commit();
|
||||
}
|
||||
|
||||
bool WaylandXRenderBackend::isLastFrameRendered() const
|
||||
|
|
|
@ -27,6 +27,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include "wayland_client/output.h"
|
||||
#include "wayland_client/registry.h"
|
||||
#include "wayland_client/shell.h"
|
||||
#include "wayland_client/surface.h"
|
||||
// Qt
|
||||
#include <QAbstractEventDispatcher>
|
||||
#include <QCoreApplication>
|
||||
|
@ -565,7 +566,7 @@ WaylandBackend::WaylandBackend(QObject *parent)
|
|||
, m_registry(new Registry(this))
|
||||
, m_compositor(NULL)
|
||||
, m_shell(new Shell(this))
|
||||
, m_surface(NULL)
|
||||
, m_surface(new Surface(this))
|
||||
, m_shellSurface(NULL)
|
||||
, m_seat()
|
||||
, m_shm()
|
||||
|
@ -617,9 +618,7 @@ WaylandBackend::~WaylandBackend()
|
|||
m_shellSurface->release();
|
||||
}
|
||||
m_fullscreenShell->release();
|
||||
if (m_surface) {
|
||||
wl_surface_destroy(m_surface);
|
||||
}
|
||||
m_surface->release();
|
||||
m_shell->release();
|
||||
if (m_compositor) {
|
||||
wl_compositor_destroy(m_compositor);
|
||||
|
@ -677,10 +676,7 @@ void WaylandBackend::initConnection()
|
|||
m_shellSurface = nullptr;
|
||||
}
|
||||
m_fullscreenShell->destroy();
|
||||
if (m_surface) {
|
||||
free(m_surface);
|
||||
m_surface = nullptr;
|
||||
}
|
||||
m_surface->destroy();
|
||||
if (m_shell) {
|
||||
m_shell->destroy();
|
||||
}
|
||||
|
@ -718,14 +714,14 @@ void WaylandBackend::installCursorImage(Qt::CursorShape shape)
|
|||
|
||||
void WaylandBackend::createSurface()
|
||||
{
|
||||
m_surface = wl_compositor_create_surface(m_compositor);
|
||||
if (!m_surface) {
|
||||
m_surface->setup(wl_compositor_create_surface(m_compositor));
|
||||
if (!m_surface->isValid()) {
|
||||
qCritical() << "Creating Wayland Surface failed";
|
||||
return;
|
||||
}
|
||||
if (m_fullscreenShell->isValid()) {
|
||||
Output *o = m_outputs.first();
|
||||
m_fullscreenShell->present(m_surface, o->output());
|
||||
m_fullscreenShell->present(m_surface, o);
|
||||
if (o->pixelSize().isValid()) {
|
||||
emit shellSurfaceSizeChanged(o->pixelSize());
|
||||
}
|
||||
|
|
|
@ -52,6 +52,7 @@ class Output;
|
|||
class Registry;
|
||||
class Shell;
|
||||
class ShellSurface;
|
||||
class Surface;
|
||||
|
||||
class CursorData
|
||||
{
|
||||
|
@ -187,7 +188,7 @@ public:
|
|||
void createSeat(uint32_t name);
|
||||
void createShm(uint32_t name);
|
||||
|
||||
wl_surface *surface() const;
|
||||
Surface *surface() const;
|
||||
QSize shellSurfaceSize() const;
|
||||
void installCursorImage(Qt::CursorShape shape);
|
||||
Q_SIGNALS:
|
||||
|
@ -206,7 +207,7 @@ private:
|
|||
Registry *m_registry;
|
||||
wl_compositor *m_compositor;
|
||||
Shell *m_shell;
|
||||
wl_surface *m_surface;
|
||||
Surface *m_surface;
|
||||
ShellSurface *m_shellSurface;
|
||||
QScopedPointer<WaylandSeat> m_seat;
|
||||
QScopedPointer<ShmPool> m_shm;
|
||||
|
@ -285,7 +286,7 @@ ShmPool* WaylandBackend::shmPool()
|
|||
}
|
||||
|
||||
inline
|
||||
wl_surface *WaylandBackend::surface() const
|
||||
Surface *WaylandBackend::surface() const
|
||||
{
|
||||
return m_surface;
|
||||
}
|
||||
|
|
|
@ -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/>.
|
||||
*********************************************************************/
|
||||
#include "fullscreen_shell.h"
|
||||
#include "surface.h"
|
||||
#include "output.h"
|
||||
|
||||
#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);
|
||||
}
|
||||
|
||||
void FullscreenShell::present(Surface *surface, Output *output)
|
||||
{
|
||||
Q_ASSERT(surface);
|
||||
Q_ASSERT(output);
|
||||
present(*surface, *output);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,6 +30,9 @@ namespace KWin
|
|||
namespace Wayland
|
||||
{
|
||||
|
||||
class Surface;
|
||||
class Output;
|
||||
|
||||
class FullscreenShell : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
@ -52,6 +55,7 @@ public:
|
|||
}
|
||||
void setup(_wl_fullscreen_shell *shell);
|
||||
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);
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
*********************************************************************/
|
||||
#include "shell.h"
|
||||
#include "output.h"
|
||||
#include "surface.h"
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
@ -73,6 +74,12 @@ ShellSurface *Shell::createSurface(wl_surface *surface, QObject *parent)
|
|||
return s;
|
||||
}
|
||||
|
||||
ShellSurface *Shell::createSurface(Surface *surface, QObject *parent)
|
||||
{
|
||||
Q_ASSERT(surface);
|
||||
return createSurface(*surface, parent);
|
||||
}
|
||||
|
||||
ShellSurface::ShellSurface(QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_surface(nullptr)
|
||||
|
|
|
@ -31,6 +31,7 @@ namespace Wayland
|
|||
{
|
||||
class ShellSurface;
|
||||
class Output;
|
||||
class Surface;
|
||||
|
||||
class Shell : public QObject
|
||||
{
|
||||
|
@ -47,6 +48,7 @@ public:
|
|||
void setup(wl_shell *shell);
|
||||
|
||||
ShellSurface *createSurface(wl_surface *surface, QObject *parent = nullptr);
|
||||
ShellSurface *createSurface(Surface *surface, QObject *parent = nullptr);
|
||||
|
||||
operator wl_shell*() {
|
||||
return m_shell;
|
||||
|
|
125
wayland_client/surface.cpp
Normal file
125
wayland_client/surface.cpp
Normal 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 ®ion)
|
||||
{
|
||||
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
78
wayland_client/surface.h
Normal 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 ®ion);
|
||||
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
|
Loading…
Reference in a new issue