[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/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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
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