Untangle SurfaceInterface and BufferInterface

A wl_buffer object can be bound to multiple surfaces or none at all. So
the BufferInterface::surface() property makes very little sense.
This commit is contained in:
Vlad Zahorodnii 2020-09-21 14:31:08 +03:00
parent 0b3cca4ae0
commit e727dc2fa9
5 changed files with 28 additions and 34 deletions

View file

@ -7,7 +7,6 @@
#include "compositor_interface.h" #include "compositor_interface.h"
#include "display.h" #include "display.h"
#include "logging.h" #include "logging.h"
#include "surface_interface.h"
#include "linuxdmabuf_v1_interface.h" #include "linuxdmabuf_v1_interface.h"
// Wayland // Wayland
#include <wayland-server.h> #include <wayland-server.h>
@ -29,14 +28,13 @@ eglQueryWaylandBufferWL_func eglQueryWaylandBufferWL = nullptr;
class BufferInterface::Private class BufferInterface::Private
{ {
public: public:
Private(BufferInterface *q, wl_resource *resource, SurfaceInterface *parent); Private(BufferInterface *q, Display *display, wl_resource *resource);
~Private(); ~Private();
QImage::Format format() const; QImage::Format format() const;
QImage createImage(); QImage createImage();
wl_resource *buffer; wl_resource *buffer;
wl_shm_buffer *shmBuffer; wl_shm_buffer *shmBuffer;
LinuxDmabufBuffer *dmabufBuffer; LinuxDmabufBuffer *dmabufBuffer;
SurfaceInterface *surface;
int refCount; int refCount;
QSize size; QSize size;
bool alpha; bool alpha;
@ -89,11 +87,10 @@ void BufferInterface::Private::imageBufferCleanupHandler(void *info)
wl_shm_buffer_end_access(p->shmBuffer); wl_shm_buffer_end_access(p->shmBuffer);
} }
BufferInterface::Private::Private(BufferInterface *q, wl_resource *resource, SurfaceInterface *parent) BufferInterface::Private::Private(BufferInterface *q, Display *display, wl_resource *resource)
: buffer(resource) : buffer(resource)
, shmBuffer(wl_shm_buffer_get(resource)) , shmBuffer(wl_shm_buffer_get(resource))
, dmabufBuffer(nullptr) , dmabufBuffer(nullptr)
, surface(parent)
, refCount(0) , refCount(0)
, alpha(false) , alpha(false)
, q(q) , q(q)
@ -155,8 +152,8 @@ BufferInterface::Private::Private(BufferInterface *q, wl_resource *resource, Sur
break; break;
} }
size = dmabufBuffer->size(); size = dmabufBuffer->size();
} else if (parent) { } else {
EGLDisplay eglDisplay = parent->compositor()->display()->eglDisplay(); EGLDisplay eglDisplay = display->eglDisplay();
static bool resolved = false; static bool resolved = false;
using namespace EGL; using namespace EGL;
if (!resolved && eglDisplay != EGL_NO_DISPLAY) { if (!resolved && eglDisplay != EGL_NO_DISPLAY) {
@ -194,7 +191,7 @@ BufferInterface::Private::~Private()
s_buffers.removeAll(this); s_buffers.removeAll(this);
} }
BufferInterface *BufferInterface::get(wl_resource *r) BufferInterface *BufferInterface::get(Display *display, wl_resource *r)
{ {
if (!r) { if (!r) {
return nullptr; return nullptr;
@ -204,12 +201,12 @@ BufferInterface *BufferInterface::get(wl_resource *r)
if (b) { if (b) {
return b; return b;
} }
return new BufferInterface(r, nullptr); return new BufferInterface(display, r);
} }
BufferInterface::BufferInterface(wl_resource *resource, SurfaceInterface *parent) BufferInterface::BufferInterface(Display *display, wl_resource *resource)
: QObject() : QObject()
, d(new Private(this, resource, parent)) , d(new Private(this, display, resource))
{ {
} }
@ -295,11 +292,6 @@ bool BufferInterface::isReferenced() const
return d->refCount > 0; return d->refCount > 0;
} }
SurfaceInterface *BufferInterface::surface() const
{
return d->surface;
}
wl_shm_buffer *BufferInterface::shmBuffer() wl_shm_buffer *BufferInterface::shmBuffer()
{ {
return d->shmBuffer; return d->shmBuffer;

View file

@ -16,7 +16,7 @@ struct wl_shm_buffer;
namespace KWaylandServer namespace KWaylandServer
{ {
class SurfaceInterface; class Display;
class LinuxDmabufBuffer; class LinuxDmabufBuffer;
/** /**
@ -51,7 +51,7 @@ class KWAYLANDSERVER_EXPORT BufferInterface : public QObject
Q_OBJECT Q_OBJECT
public: public:
explicit BufferInterface(wl_resource *resource, SurfaceInterface *parent); BufferInterface(Display *display, wl_resource *resource);
virtual ~BufferInterface(); virtual ~BufferInterface();
/** /**
* Reference the BufferInterface. * Reference the BufferInterface.
@ -67,8 +67,7 @@ public:
* Unreference the BufferInterface. * Unreference the BufferInterface.
* *
* If the reference counting reached @c 0 the BufferInterface is released, so that the * If the reference counting reached @c 0 the BufferInterface is released, so that the
* client can use it again. The instance of this BufferInterface will be automatically * client can use it again.
* deleted.
* *
* @see ref * @see ref
* @see isReferenced * @see isReferenced
@ -82,10 +81,6 @@ public:
**/ **/
bool isReferenced() const; bool isReferenced() const;
/**
* @returns The SurfaceInterface this BufferInterface is attached to.
**/
SurfaceInterface *surface() const;
/** /**
* @returns The native wl_shm_buffer if the BufferInterface represents a shared memory buffer, otherwise @c nullptr. * @returns The native wl_shm_buffer if the BufferInterface represents a shared memory buffer, otherwise @c nullptr.
**/ **/
@ -162,7 +157,7 @@ public:
**/ **/
bool hasAlphaChannel() const; bool hasAlphaChannel() const;
static BufferInterface *get(wl_resource *r); static BufferInterface *get(Display *display, wl_resource *r);
Q_SIGNALS: Q_SIGNALS:
void aboutToBeDestroyed(KWaylandServer::BufferInterface*); void aboutToBeDestroyed(KWaylandServer::BufferInterface*);

View file

@ -19,6 +19,7 @@ public:
ShadowManagerInterfacePrivate(ShadowManagerInterface *_q, Display *display); ShadowManagerInterfacePrivate(ShadowManagerInterface *_q, Display *display);
ShadowManagerInterface *q; ShadowManagerInterface *q;
Display *display;
static const quint32 s_version; static const quint32 s_version;
protected: protected:
@ -32,6 +33,7 @@ const quint32 ShadowManagerInterfacePrivate::s_version = 2;
ShadowManagerInterfacePrivate::ShadowManagerInterfacePrivate(ShadowManagerInterface *_q, Display *display) ShadowManagerInterfacePrivate::ShadowManagerInterfacePrivate(ShadowManagerInterface *_q, Display *display)
: QtWaylandServer::org_kde_kwin_shadow_manager(*display, s_version) : QtWaylandServer::org_kde_kwin_shadow_manager(*display, s_version)
, q(_q) , q(_q)
, display(display)
{ {
} }
@ -54,7 +56,7 @@ void ShadowManagerInterfacePrivate::org_kde_kwin_shadow_manager_create(Resource
return; return;
} }
auto shadow = new ShadowInterface(shadow_resource); auto shadow = new ShadowInterface(q, shadow_resource);
SurfaceInterfacePrivate *surfacePrivate = SurfaceInterfacePrivate::get(s); SurfaceInterfacePrivate *surfacePrivate = SurfaceInterfacePrivate::get(s);
surfacePrivate->setShadow(QPointer<ShadowInterface>(shadow)); surfacePrivate->setShadow(QPointer<ShadowInterface>(shadow));
@ -80,6 +82,11 @@ ShadowManagerInterface::ShadowManagerInterface(Display *display, QObject *parent
ShadowManagerInterface::~ShadowManagerInterface() = default; ShadowManagerInterface::~ShadowManagerInterface() = default;
Display *ShadowManagerInterface::display() const
{
return d->display;
}
class ShadowInterfacePrivate : public QtWaylandServer::org_kde_kwin_shadow class ShadowInterfacePrivate : public QtWaylandServer::org_kde_kwin_shadow
{ {
public: public:
@ -114,6 +121,7 @@ public:
void commit(); void commit();
void attach(State::Flags flag, wl_resource *buffer); void attach(State::Flags flag, wl_resource *buffer);
ShadowManagerInterface *manager;
State current; State current;
State pending; State pending;
ShadowInterface *q; ShadowInterface *q;
@ -168,7 +176,7 @@ void ShadowInterfacePrivate::org_kde_kwin_shadow_commit(Resource *resource)
void ShadowInterfacePrivate::attach(ShadowInterfacePrivate::State::Flags flag, wl_resource *buffer) void ShadowInterfacePrivate::attach(ShadowInterfacePrivate::State::Flags flag, wl_resource *buffer)
{ {
BufferInterface *b = BufferInterface::get(buffer); BufferInterface *b = BufferInterface::get(manager->display(), buffer);
if (b) { if (b) {
QObject::connect(b, &BufferInterface::aboutToBeDestroyed, q, QObject::connect(b, &BufferInterface::aboutToBeDestroyed, q,
[this](BufferInterface *buffer) { [this](BufferInterface *buffer) {
@ -345,10 +353,11 @@ ShadowInterfacePrivate::~ShadowInterfacePrivate()
#undef CURRENT #undef CURRENT
} }
ShadowInterface::ShadowInterface(wl_resource *resource) ShadowInterface::ShadowInterface(ShadowManagerInterface *manager, wl_resource *resource)
: QObject() : QObject()
, d(new ShadowInterfacePrivate(this, resource)) , d(new ShadowInterfacePrivate(this, resource))
{ {
d->manager = manager;
} }
ShadowInterface::~ShadowInterface() = default; ShadowInterface::~ShadowInterface() = default;

View file

@ -27,6 +27,8 @@ class KWAYLANDSERVER_EXPORT ShadowManagerInterface : public QObject
public: public:
~ShadowManagerInterface() override; ~ShadowManagerInterface() override;
Display *display() const;
private: private:
explicit ShadowManagerInterface(Display *display, QObject *parent = nullptr); explicit ShadowManagerInterface(Display *display, QObject *parent = nullptr);
friend class Display; friend class Display;
@ -51,7 +53,7 @@ public:
QMarginsF offset() const; QMarginsF offset() const;
private: private:
explicit ShadowInterface(wl_resource *resource); explicit ShadowInterface(ShadowManagerInterface *manager, wl_resource *resource);
friend class ShadowManagerInterfacePrivate; friend class ShadowManagerInterfacePrivate;
QScopedPointer<ShadowInterfacePrivate> d; QScopedPointer<ShadowInterfacePrivate> d;

View file

@ -298,9 +298,6 @@ void SurfaceInterfacePrivate::surface_attach(Resource *resource, struct ::wl_res
Q_UNUSED(resource) Q_UNUSED(resource)
pending.bufferIsSet = true; pending.bufferIsSet = true;
pending.offset = QPoint(x, y); pending.offset = QPoint(x, y);
if (pending.buffer) {
delete pending.buffer;
}
if (!buffer) { if (!buffer) {
// got a null buffer, deletes content in next frame // got a null buffer, deletes content in next frame
pending.buffer = nullptr; pending.buffer = nullptr;
@ -308,7 +305,7 @@ void SurfaceInterfacePrivate::surface_attach(Resource *resource, struct ::wl_res
pending.bufferDamage = QRegion(); pending.bufferDamage = QRegion();
return; return;
} }
pending.buffer = new BufferInterface(buffer, q); pending.buffer = BufferInterface::get(compositor->display(), buffer);
QObject::connect(pending.buffer, &BufferInterface::aboutToBeDestroyed, q, QObject::connect(pending.buffer, &BufferInterface::aboutToBeDestroyed, q,
[this](BufferInterface *buffer) { [this](BufferInterface *buffer) {
if (pending.buffer == buffer) { if (pending.buffer == buffer) {
@ -524,7 +521,6 @@ void SurfaceInterfacePrivate::swapStates(State *source, State *target, bool emit
if (emitChanged) { if (emitChanged) {
target->buffer->unref(); target->buffer->unref();
} else { } else {
delete target->buffer;
target->buffer = nullptr; target->buffer = nullptr;
} }
} }