Dmabuf recovery on EGL reset
Summary: The EGL platform might go away at any time through reconfiguration or because of a graphic error. KWin then resets the graphics. The dmabuf implementation must respect that and recover from a graphics reset by recreating all EGL images for existing buffer. This assumes that we won't change our graphics API mid-session and that supported plane and modifier configuration stays constant. In practise we remember all current dmabufs in a single map and only remove them if the client did destroy the resource. BUG: 411980 CCBUG: 413403 FIXED-IN: 5.17.2 Test Plan: Applied screenedge configuration without crash. Reviewers: #kwin, zzag Reviewed By: #kwin, zzag Subscribers: fvogt, kwin Tags: #kwin Differential Revision: https://phabricator.kde.org/D24954
This commit is contained in:
parent
a151edd29b
commit
7459aabcac
9 changed files with 270 additions and 100 deletions
|
@ -441,6 +441,7 @@ set(kwin_KDEINIT_SRCS
|
||||||
libinput/device.cpp
|
libinput/device.cpp
|
||||||
libinput/events.cpp
|
libinput/events.cpp
|
||||||
libinput/libinput_logging.cpp
|
libinput/libinput_logging.cpp
|
||||||
|
linux_dmabuf.cpp
|
||||||
logind.cpp
|
logind.cpp
|
||||||
main.cpp
|
main.cpp
|
||||||
manage.cpp
|
manage.cpp
|
||||||
|
|
88
linux_dmabuf.cpp
Normal file
88
linux_dmabuf.cpp
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
/********************************************************************
|
||||||
|
KWin - the KDE window manager
|
||||||
|
This file is part of the KDE project.
|
||||||
|
|
||||||
|
Copyright © 2019 Roman Gilg <subdiff@gmail.com>
|
||||||
|
|
||||||
|
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 "linux_dmabuf.h"
|
||||||
|
|
||||||
|
#include "wayland_server.h"
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
namespace KWin
|
||||||
|
{
|
||||||
|
|
||||||
|
DmabufBuffer::DmabufBuffer(const QVector<Plane> &planes,
|
||||||
|
uint32_t format,
|
||||||
|
const QSize &size,
|
||||||
|
Flags flags)
|
||||||
|
: KWayland::Server::LinuxDmabufUnstableV1Buffer(format, size)
|
||||||
|
, m_planes(planes)
|
||||||
|
, m_format(format)
|
||||||
|
, m_size(size)
|
||||||
|
, m_flags(flags)
|
||||||
|
{
|
||||||
|
waylandServer()->addLinuxDmabufBuffer(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
DmabufBuffer::~DmabufBuffer()
|
||||||
|
{
|
||||||
|
// Close all open file descriptors
|
||||||
|
for (int i = 0; i < m_planes.count(); i++) {
|
||||||
|
if (m_planes[i].fd != -1)
|
||||||
|
::close(m_planes[i].fd);
|
||||||
|
m_planes[i].fd = -1;
|
||||||
|
}
|
||||||
|
if (waylandServer()) {
|
||||||
|
waylandServer()->removeLinuxDmabufBuffer(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LinuxDmabuf::LinuxDmabuf()
|
||||||
|
: KWayland::Server::LinuxDmabufUnstableV1Interface::Impl()
|
||||||
|
{
|
||||||
|
Q_ASSERT(waylandServer());
|
||||||
|
waylandServer()->linuxDmabuf()->setImpl(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
LinuxDmabuf::~LinuxDmabuf()
|
||||||
|
{
|
||||||
|
waylandServer()->linuxDmabuf()->setImpl(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
using Plane = KWayland::Server::LinuxDmabufUnstableV1Interface::Plane;
|
||||||
|
using Flags = KWayland::Server::LinuxDmabufUnstableV1Interface::Flags;
|
||||||
|
|
||||||
|
KWayland::Server::LinuxDmabufUnstableV1Buffer* LinuxDmabuf::importBuffer(const QVector<Plane> &planes,
|
||||||
|
uint32_t format,
|
||||||
|
const QSize &size,
|
||||||
|
Flags flags)
|
||||||
|
{
|
||||||
|
Q_UNUSED(planes)
|
||||||
|
Q_UNUSED(format)
|
||||||
|
Q_UNUSED(size)
|
||||||
|
Q_UNUSED(flags)
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LinuxDmabuf::setSupportedFormatsAndModifiers(QHash<uint32_t, QSet<uint64_t> > &set)
|
||||||
|
{
|
||||||
|
waylandServer()->linuxDmabuf()->setSupportedFormatsWithModifiers(set);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
74
linux_dmabuf.h
Normal file
74
linux_dmabuf.h
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
/********************************************************************
|
||||||
|
KWin - the KDE window manager
|
||||||
|
This file is part of the KDE project.
|
||||||
|
|
||||||
|
Copyright © 2019 Roman Gilg <subdiff@gmail.com>
|
||||||
|
|
||||||
|
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/>.
|
||||||
|
*********************************************************************/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <kwin_export.h>
|
||||||
|
|
||||||
|
#include <KWayland/Server/linuxdmabuf_v1_interface.h>
|
||||||
|
|
||||||
|
#include <QVector>
|
||||||
|
|
||||||
|
namespace KWin
|
||||||
|
{
|
||||||
|
|
||||||
|
class KWIN_EXPORT DmabufBuffer : public KWayland::Server::LinuxDmabufUnstableV1Buffer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using Plane = KWayland::Server::LinuxDmabufUnstableV1Interface::Plane;
|
||||||
|
using Flags = KWayland::Server::LinuxDmabufUnstableV1Interface::Flags;
|
||||||
|
|
||||||
|
DmabufBuffer(const QVector<Plane> &planes,
|
||||||
|
uint32_t format,
|
||||||
|
const QSize &size,
|
||||||
|
Flags flags);
|
||||||
|
|
||||||
|
~DmabufBuffer() override;
|
||||||
|
|
||||||
|
const QVector<Plane> &planes() const { return m_planes; }
|
||||||
|
uint32_t format() const { return m_format; }
|
||||||
|
QSize size() const { return m_size; }
|
||||||
|
Flags flags() const { return m_flags; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
QVector<Plane> m_planes;
|
||||||
|
uint32_t m_format;
|
||||||
|
QSize m_size;
|
||||||
|
Flags m_flags;
|
||||||
|
};
|
||||||
|
|
||||||
|
class KWIN_EXPORT LinuxDmabuf : public KWayland::Server::LinuxDmabufUnstableV1Interface::Impl
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using Plane = KWayland::Server::LinuxDmabufUnstableV1Interface::Plane;
|
||||||
|
using Flags = KWayland::Server::LinuxDmabufUnstableV1Interface::Flags;
|
||||||
|
|
||||||
|
explicit LinuxDmabuf();
|
||||||
|
~LinuxDmabuf();
|
||||||
|
|
||||||
|
KWayland::Server::LinuxDmabufUnstableV1Buffer *importBuffer(const QVector<Plane> &planes,
|
||||||
|
uint32_t format,
|
||||||
|
const QSize &size,
|
||||||
|
Flags flags) override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void setSupportedFormatsAndModifiers(QHash<uint32_t, QSet<uint64_t> > &set);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
set(SCENE_OPENGL_BACKEND_SRCS
|
set(SCENE_OPENGL_BACKEND_SRCS
|
||||||
abstract_egl_backend.cpp
|
abstract_egl_backend.cpp
|
||||||
backend.cpp
|
backend.cpp
|
||||||
linux_dmabuf.cpp
|
egl_dmabuf.cpp
|
||||||
swap_profiler.cpp
|
swap_profiler.cpp
|
||||||
texture.cpp
|
texture.cpp
|
||||||
)
|
)
|
||||||
|
|
|
@ -18,7 +18,7 @@ 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 "abstract_egl_backend.h"
|
#include "abstract_egl_backend.h"
|
||||||
#include "linux_dmabuf.h"
|
#include "egl_dmabuf.h"
|
||||||
#include "texture.h"
|
#include "texture.h"
|
||||||
#include "composite.h"
|
#include "composite.h"
|
||||||
#include "egl_context_attribute_builder.h"
|
#include "egl_context_attribute_builder.h"
|
||||||
|
@ -171,7 +171,7 @@ void AbstractEglBackend::initWayland()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LinuxDmabuf::factory(this);
|
EglDmabuf::factory(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AbstractEglBackend::initClientExtensions()
|
void AbstractEglBackend::initClientExtensions()
|
||||||
|
@ -377,7 +377,7 @@ void AbstractEglTexture::updateTexture(WindowPixmap *pixmap)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto s = pixmap->surface();
|
auto s = pixmap->surface();
|
||||||
if (DmabufBuffer *dmabuf = static_cast<DmabufBuffer *>(buffer->linuxDmabufBuffer())) {
|
if (EglDmabufBuffer *dmabuf = static_cast<EglDmabufBuffer *>(buffer->linuxDmabufBuffer())) {
|
||||||
q->bind();
|
q->bind();
|
||||||
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES) dmabuf->images()[0]); //TODO
|
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES) dmabuf->images()[0]); //TODO
|
||||||
q->unbind();
|
q->unbind();
|
||||||
|
@ -532,7 +532,7 @@ bool AbstractEglTexture::loadEglTexture(const QPointer< KWayland::Server::Buffer
|
||||||
|
|
||||||
bool AbstractEglTexture::loadDmabufTexture(const QPointer< KWayland::Server::BufferInterface > &buffer)
|
bool AbstractEglTexture::loadDmabufTexture(const QPointer< KWayland::Server::BufferInterface > &buffer)
|
||||||
{
|
{
|
||||||
DmabufBuffer *dmabuf = static_cast<DmabufBuffer *>(buffer->linuxDmabufBuffer());
|
auto *dmabuf = static_cast<EglDmabufBuffer *>(buffer->linuxDmabufBuffer());
|
||||||
if (!dmabuf || dmabuf->images()[0] == EGL_NO_IMAGE_KHR) {
|
if (!dmabuf || dmabuf->images()[0] == EGL_NO_IMAGE_KHR) {
|
||||||
qCritical(KWIN_OPENGL) << "Invalid dmabuf-based wl_buffer";
|
qCritical(KWIN_OPENGL) << "Invalid dmabuf-based wl_buffer";
|
||||||
q->discard();
|
q->discard();
|
||||||
|
|
|
@ -18,13 +18,11 @@ GNU General Public License for more details.
|
||||||
You should have received a copy of the GNU General Public License
|
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 "linux_dmabuf.h"
|
#include "egl_dmabuf.h"
|
||||||
|
|
||||||
#include "drm_fourcc.h"
|
#include "drm_fourcc.h"
|
||||||
#include "../../../wayland_server.h"
|
#include "../../../wayland_server.h"
|
||||||
|
|
||||||
#include <KWayland/Server/display.h>
|
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <EGL/eglmesaext.h>
|
#include <EGL/eglmesaext.h>
|
||||||
|
|
||||||
|
@ -173,67 +171,59 @@ YuvFormat yuvFormats[] = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
DmabufBuffer::DmabufBuffer(EGLImage image,
|
EglDmabufBuffer::EglDmabufBuffer(EGLImage image,
|
||||||
const QVector<Plane> &planes,
|
const QVector<Plane> &planes,
|
||||||
uint32_t format,
|
uint32_t format,
|
||||||
const QSize &size,
|
const QSize &size,
|
||||||
Flags flags,
|
Flags flags,
|
||||||
LinuxDmabuf *interfaceImpl)
|
EglDmabuf *interfaceImpl)
|
||||||
: DmabufBuffer(planes, format, size, flags, interfaceImpl)
|
: EglDmabufBuffer(planes, format, size, flags, interfaceImpl)
|
||||||
{
|
{
|
||||||
m_importType = ImportType::Direct;
|
m_importType = ImportType::Direct;
|
||||||
addImage(image);
|
addImage(image);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
DmabufBuffer::DmabufBuffer(const QVector<Plane> &planes,
|
EglDmabufBuffer::EglDmabufBuffer(const QVector<Plane> &planes,
|
||||||
uint32_t format,
|
uint32_t format,
|
||||||
const QSize &size,
|
const QSize &size,
|
||||||
Flags flags,
|
Flags flags,
|
||||||
LinuxDmabuf *interfaceImpl)
|
EglDmabuf *interfaceImpl)
|
||||||
: KWayland::Server::LinuxDmabufUnstableV1Buffer(format, size)
|
: DmabufBuffer(planes, format, size, flags)
|
||||||
, m_planes(planes)
|
|
||||||
, m_flags(flags)
|
|
||||||
, m_interfaceImpl(interfaceImpl)
|
, m_interfaceImpl(interfaceImpl)
|
||||||
{
|
{
|
||||||
m_importType = ImportType::Conversion;
|
m_importType = ImportType::Conversion;
|
||||||
}
|
}
|
||||||
|
|
||||||
DmabufBuffer::~DmabufBuffer()
|
EglDmabufBuffer::~EglDmabufBuffer()
|
||||||
{
|
{
|
||||||
if (m_interfaceImpl) {
|
removeImages();
|
||||||
m_interfaceImpl->removeBuffer(this);
|
|
||||||
removeImages();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Close all open file descriptors
|
|
||||||
for (int i = 0; i < m_planes.count(); i++) {
|
|
||||||
if (m_planes[i].fd != -1)
|
|
||||||
::close(m_planes[i].fd);
|
|
||||||
m_planes[i].fd = -1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DmabufBuffer::addImage(EGLImage image)
|
void EglDmabufBuffer::setInterfaceImplementation(EglDmabuf *interfaceImpl)
|
||||||
|
{
|
||||||
|
m_interfaceImpl = interfaceImpl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EglDmabufBuffer::addImage(EGLImage image)
|
||||||
{
|
{
|
||||||
m_images << image;
|
m_images << image;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DmabufBuffer::removeImages()
|
void EglDmabufBuffer::removeImages()
|
||||||
{
|
{
|
||||||
for (auto image : m_images) {
|
for (auto image : m_images) {
|
||||||
eglDestroyImageKHR(m_interfaceImpl->m_backend->eglDisplay(), image);
|
eglDestroyImageKHR(m_interfaceImpl->m_backend->eglDisplay(), image);
|
||||||
}
|
}
|
||||||
m_images.clear();
|
m_images.clear();
|
||||||
m_interfaceImpl = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
using Plane = KWayland::Server::LinuxDmabufUnstableV1Interface::Plane;
|
using Plane = KWayland::Server::LinuxDmabufUnstableV1Interface::Plane;
|
||||||
using Flags = KWayland::Server::LinuxDmabufUnstableV1Interface::Flags;
|
using Flags = KWayland::Server::LinuxDmabufUnstableV1Interface::Flags;
|
||||||
|
|
||||||
EGLImage LinuxDmabuf::createImage(const QVector<Plane> &planes,
|
EGLImage EglDmabuf::createImage(const QVector<Plane> &planes,
|
||||||
uint32_t format,
|
uint32_t format,
|
||||||
const QSize &size)
|
const QSize &size)
|
||||||
{
|
{
|
||||||
const bool hasModifiers = eglQueryDmaBufModifiersEXT != nullptr &&
|
const bool hasModifiers = eglQueryDmaBufModifiersEXT != nullptr &&
|
||||||
planes[0].modifier != DRM_FORMAT_MOD_INVALID;
|
planes[0].modifier != DRM_FORMAT_MOD_INVALID;
|
||||||
|
@ -306,16 +296,16 @@ EGLImage LinuxDmabuf::createImage(const QVector<Plane> &planes,
|
||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
|
|
||||||
KWayland::Server::LinuxDmabufUnstableV1Buffer* LinuxDmabuf::importBuffer(const QVector<Plane> &planes,
|
KWayland::Server::LinuxDmabufUnstableV1Buffer* EglDmabuf::importBuffer(const QVector<Plane> &planes,
|
||||||
uint32_t format,
|
uint32_t format,
|
||||||
const QSize &size,
|
const QSize &size,
|
||||||
Flags flags)
|
Flags flags)
|
||||||
{
|
{
|
||||||
Q_ASSERT(planes.count() > 0);
|
Q_ASSERT(planes.count() > 0);
|
||||||
|
|
||||||
// Try first to import as a single image
|
// Try first to import as a single image
|
||||||
if (auto *img = createImage(planes, format, size)) {
|
if (auto *img = createImage(planes, format, size)) {
|
||||||
return new DmabufBuffer(img, planes, format, size, flags, this);
|
return new EglDmabufBuffer(img, planes, format, size, flags, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: to enable this we must be able to store multiple textures per window pixmap
|
// TODO: to enable this we must be able to store multiple textures per window pixmap
|
||||||
|
@ -326,10 +316,10 @@ KWayland::Server::LinuxDmabufUnstableV1Buffer* LinuxDmabuf::importBuffer(const Q
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
KWayland::Server::LinuxDmabufUnstableV1Buffer* LinuxDmabuf::yuvImport(const QVector<Plane> &planes,
|
KWayland::Server::LinuxDmabufUnstableV1Buffer* EglDmabuf::yuvImport(const QVector<Plane> &planes,
|
||||||
uint32_t format,
|
uint32_t format,
|
||||||
const QSize &size,
|
const QSize &size,
|
||||||
Flags flags)
|
Flags flags)
|
||||||
{
|
{
|
||||||
YuvFormat yuvFormat;
|
YuvFormat yuvFormat;
|
||||||
for (YuvFormat f : yuvFormats) {
|
for (YuvFormat f : yuvFormats) {
|
||||||
|
@ -345,7 +335,7 @@ KWayland::Server::LinuxDmabufUnstableV1Buffer* LinuxDmabuf::yuvImport(const QVec
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto *buf = new DmabufBuffer(planes, format, size, flags, this);
|
auto *buf = new EglDmabufBuffer(planes, format, size, flags, this);
|
||||||
|
|
||||||
for (int i = 0; i < yuvFormat.outputPlanes; i++) {
|
for (int i = 0; i < yuvFormat.outputPlanes; i++) {
|
||||||
int planeIndex = yuvFormat.planes[i].planeIndex;
|
int planeIndex = yuvFormat.planes[i].planeIndex;
|
||||||
|
@ -371,7 +361,7 @@ KWayland::Server::LinuxDmabufUnstableV1Buffer* LinuxDmabuf::yuvImport(const QVec
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
LinuxDmabuf* LinuxDmabuf::factory(AbstractEglBackend *backend)
|
EglDmabuf* EglDmabuf::factory(AbstractEglBackend *backend)
|
||||||
{
|
{
|
||||||
if (!backend->hasExtension(QByteArrayLiteral("EGL_EXT_image_dma_buf_import"))) {
|
if (!backend->hasExtension(QByteArrayLiteral("EGL_EXT_image_dma_buf_import"))) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -386,30 +376,29 @@ LinuxDmabuf* LinuxDmabuf::factory(AbstractEglBackend *backend)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new LinuxDmabuf(backend);
|
return new EglDmabuf(backend);
|
||||||
}
|
}
|
||||||
|
|
||||||
LinuxDmabuf::LinuxDmabuf(AbstractEglBackend *backend)
|
EglDmabuf::EglDmabuf(AbstractEglBackend *backend)
|
||||||
: KWayland::Server::LinuxDmabufUnstableV1Interface::Impl()
|
: LinuxDmabuf()
|
||||||
, m_backend(backend)
|
, m_backend(backend)
|
||||||
{
|
{
|
||||||
Q_ASSERT(waylandServer());
|
auto prevBuffersSet = waylandServer()->linuxDmabufBuffers();
|
||||||
m_interface = waylandServer()->display()->createLinuxDmabufInterface(backend);
|
for (auto *buffer : prevBuffersSet) {
|
||||||
setSupportedFormatsAndModifiers();
|
auto *buf = static_cast<EglDmabufBuffer*>(buffer);
|
||||||
m_interface->setImpl(this);
|
buf->setInterfaceImplementation(this);
|
||||||
m_interface->create();
|
buf->addImage(createImage(buf->planes(), buf->format(), buf->size()));
|
||||||
}
|
|
||||||
|
|
||||||
LinuxDmabuf::~LinuxDmabuf()
|
|
||||||
{
|
|
||||||
for (auto *dmabuf : qAsConst(m_buffers)) {
|
|
||||||
dmabuf->removeImages();
|
|
||||||
}
|
}
|
||||||
|
setSupportedFormatsAndModifiers();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LinuxDmabuf::removeBuffer(DmabufBuffer *buffer)
|
EglDmabuf::~EglDmabuf()
|
||||||
{
|
{
|
||||||
m_buffers.remove(buffer);
|
auto curBuffers = waylandServer()->linuxDmabufBuffers();
|
||||||
|
for (auto *buffer : curBuffers) {
|
||||||
|
auto *buf = static_cast<EglDmabufBuffer*>(buffer);
|
||||||
|
buf->removeImages();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint32_t s_multiPlaneFormats[] = {
|
const uint32_t s_multiPlaneFormats[] = {
|
||||||
|
@ -457,7 +446,7 @@ void filterFormatsWithMultiplePlanes(QVector<uint32_t> &formats)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LinuxDmabuf::setSupportedFormatsAndModifiers()
|
void EglDmabuf::setSupportedFormatsAndModifiers()
|
||||||
{
|
{
|
||||||
const EGLDisplay eglDisplay = m_backend->eglDisplay();
|
const EGLDisplay eglDisplay = m_backend->eglDisplay();
|
||||||
EGLint count = 0;
|
EGLint count = 0;
|
||||||
|
@ -498,7 +487,7 @@ void LinuxDmabuf::setSupportedFormatsAndModifiers()
|
||||||
set.insert(format, QSet<uint64_t>());
|
set.insert(format, QSet<uint64_t>());
|
||||||
}
|
}
|
||||||
|
|
||||||
m_interface->setSupportedFormatsWithModifiers(set);
|
LinuxDmabuf::setSupportedFormatsAndModifiers(set);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -20,17 +20,17 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*********************************************************************/
|
*********************************************************************/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "abstract_egl_backend.h"
|
#include "../../../linux_dmabuf.h"
|
||||||
|
|
||||||
#include <KWayland/Server/linuxdmabuf_v1_interface.h>
|
#include "abstract_egl_backend.h"
|
||||||
|
|
||||||
#include <QVector>
|
#include <QVector>
|
||||||
|
|
||||||
namespace KWin
|
namespace KWin
|
||||||
{
|
{
|
||||||
class LinuxDmabuf;
|
class EglDmabuf;
|
||||||
|
|
||||||
class DmabufBuffer : public KWayland::Server::LinuxDmabufUnstableV1Buffer
|
class EglDmabufBuffer : public DmabufBuffer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using Plane = KWayland::Server::LinuxDmabufUnstableV1Interface::Plane;
|
using Plane = KWayland::Server::LinuxDmabufUnstableV1Interface::Plane;
|
||||||
|
@ -41,46 +41,43 @@ public:
|
||||||
Conversion
|
Conversion
|
||||||
};
|
};
|
||||||
|
|
||||||
DmabufBuffer(EGLImage image,
|
EglDmabufBuffer(EGLImage image,
|
||||||
const QVector<Plane> &planes,
|
const QVector<Plane> &planes,
|
||||||
uint32_t format,
|
uint32_t format,
|
||||||
const QSize &size,
|
const QSize &size,
|
||||||
Flags flags,
|
Flags flags,
|
||||||
LinuxDmabuf *interfaceImpl);
|
EglDmabuf *interfaceImpl);
|
||||||
|
|
||||||
DmabufBuffer(const QVector<Plane> &planes,
|
EglDmabufBuffer(const QVector<Plane> &planes,
|
||||||
uint32_t format,
|
uint32_t format,
|
||||||
const QSize &size,
|
const QSize &size,
|
||||||
Flags flags,
|
Flags flags,
|
||||||
LinuxDmabuf *interfaceImpl);
|
EglDmabuf *interfaceImpl);
|
||||||
|
|
||||||
~DmabufBuffer() override;
|
~EglDmabufBuffer() override;
|
||||||
|
|
||||||
|
void setInterfaceImplementation(EglDmabuf *interfaceImpl);
|
||||||
void addImage(EGLImage image);
|
void addImage(EGLImage image);
|
||||||
void removeImages();
|
void removeImages();
|
||||||
|
|
||||||
QVector<EGLImage> images() const { return m_images; }
|
QVector<EGLImage> images() const { return m_images; }
|
||||||
Flags flags() const { return m_flags; }
|
|
||||||
const QVector<Plane> &planes() const { return m_planes; }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QVector<EGLImage> m_images;
|
QVector<EGLImage> m_images;
|
||||||
QVector<Plane> m_planes;
|
EglDmabuf *m_interfaceImpl;
|
||||||
Flags m_flags;
|
|
||||||
LinuxDmabuf *m_interfaceImpl;
|
|
||||||
ImportType m_importType;
|
ImportType m_importType;
|
||||||
};
|
};
|
||||||
|
|
||||||
class LinuxDmabuf : public KWayland::Server::LinuxDmabufUnstableV1Interface::Impl
|
class EglDmabuf : public LinuxDmabuf
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using Plane = KWayland::Server::LinuxDmabufUnstableV1Interface::Plane;
|
using Plane = KWayland::Server::LinuxDmabufUnstableV1Interface::Plane;
|
||||||
using Flags = KWayland::Server::LinuxDmabufUnstableV1Interface::Flags;
|
using Flags = KWayland::Server::LinuxDmabufUnstableV1Interface::Flags;
|
||||||
|
|
||||||
static LinuxDmabuf* factory(AbstractEglBackend *backend);
|
static EglDmabuf* factory(AbstractEglBackend *backend);
|
||||||
|
|
||||||
explicit LinuxDmabuf(AbstractEglBackend *backend);
|
explicit EglDmabuf(AbstractEglBackend *backend);
|
||||||
~LinuxDmabuf();
|
~EglDmabuf();
|
||||||
|
|
||||||
KWayland::Server::LinuxDmabufUnstableV1Buffer *importBuffer(const QVector<Plane> &planes,
|
KWayland::Server::LinuxDmabufUnstableV1Buffer *importBuffer(const QVector<Plane> &planes,
|
||||||
uint32_t format,
|
uint32_t format,
|
||||||
|
@ -92,20 +89,16 @@ private:
|
||||||
uint32_t format,
|
uint32_t format,
|
||||||
const QSize &size);
|
const QSize &size);
|
||||||
|
|
||||||
|
|
||||||
KWayland::Server::LinuxDmabufUnstableV1Buffer *yuvImport(const QVector<Plane> &planes,
|
KWayland::Server::LinuxDmabufUnstableV1Buffer *yuvImport(const QVector<Plane> &planes,
|
||||||
uint32_t format,
|
uint32_t format,
|
||||||
const QSize &size,
|
const QSize &size,
|
||||||
Flags flags);
|
Flags flags);
|
||||||
|
|
||||||
void removeBuffer(DmabufBuffer *buffer);
|
|
||||||
void setSupportedFormatsAndModifiers();
|
void setSupportedFormatsAndModifiers();
|
||||||
|
|
||||||
KWayland::Server::LinuxDmabufUnstableV1Interface *m_interface;
|
|
||||||
QSet<DmabufBuffer*> m_buffers;
|
|
||||||
AbstractEglBackend *m_backend;
|
AbstractEglBackend *m_backend;
|
||||||
|
|
||||||
friend class DmabufBuffer;
|
friend class EglDmabufBuffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
|
@ -45,6 +45,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#include <KWayland/Server/dpms_interface.h>
|
#include <KWayland/Server/dpms_interface.h>
|
||||||
#include <KWayland/Server/idle_interface.h>
|
#include <KWayland/Server/idle_interface.h>
|
||||||
#include <KWayland/Server/idleinhibit_interface.h>
|
#include <KWayland/Server/idleinhibit_interface.h>
|
||||||
|
#include <KWayland/Server/linuxdmabuf_v1_interface.h>
|
||||||
#include <KWayland/Server/output_interface.h>
|
#include <KWayland/Server/output_interface.h>
|
||||||
#include <KWayland/Server/plasmashell_interface.h>
|
#include <KWayland/Server/plasmashell_interface.h>
|
||||||
#include <KWayland/Server/plasmavirtualdesktop_interface.h>
|
#include <KWayland/Server/plasmavirtualdesktop_interface.h>
|
||||||
|
@ -471,6 +472,15 @@ bool WaylandServer::init(const QByteArray &socketName, InitalizationFlags flags)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KWayland::Server::LinuxDmabufUnstableV1Interface *WaylandServer::linuxDmabuf()
|
||||||
|
{
|
||||||
|
if (!m_linuxDmabuf) {
|
||||||
|
m_linuxDmabuf = m_display->createLinuxDmabufInterface(m_display);
|
||||||
|
m_linuxDmabuf->create();
|
||||||
|
}
|
||||||
|
return m_linuxDmabuf;
|
||||||
|
}
|
||||||
|
|
||||||
SurfaceInterface *WaylandServer::findForeignTransientForSurface(SurfaceInterface *surface)
|
SurfaceInterface *WaylandServer::findForeignTransientForSurface(SurfaceInterface *surface)
|
||||||
{
|
{
|
||||||
return m_XdgForeign->transientFor(surface);
|
return m_XdgForeign->transientFor(surface);
|
||||||
|
|
|
@ -68,6 +68,8 @@ class XdgShellInterface;
|
||||||
class XdgForeignInterface;
|
class XdgForeignInterface;
|
||||||
class XdgOutputManagerInterface;
|
class XdgOutputManagerInterface;
|
||||||
class KeyStateInterface;
|
class KeyStateInterface;
|
||||||
|
class LinuxDmabufUnstableV1Interface;
|
||||||
|
class LinuxDmabufUnstableV1Buffer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,6 +124,7 @@ public:
|
||||||
KWayland::Server::XdgOutputManagerInterface *xdgOutputManager() const {
|
KWayland::Server::XdgOutputManagerInterface *xdgOutputManager() const {
|
||||||
return m_xdgOutputManager;
|
return m_xdgOutputManager;
|
||||||
}
|
}
|
||||||
|
KWayland::Server::LinuxDmabufUnstableV1Interface *linuxDmabuf();
|
||||||
|
|
||||||
QList<ShellClient*> clients() const {
|
QList<ShellClient*> clients() const {
|
||||||
return m_clients;
|
return m_clients;
|
||||||
|
@ -224,6 +227,16 @@ public:
|
||||||
void simulateUserActivity();
|
void simulateUserActivity();
|
||||||
void updateKeyState(KWin::Xkb::LEDs leds);
|
void updateKeyState(KWin::Xkb::LEDs leds);
|
||||||
|
|
||||||
|
QSet<KWayland::Server::LinuxDmabufUnstableV1Buffer*> linuxDmabufBuffers() const {
|
||||||
|
return m_linuxDmabufBuffers;
|
||||||
|
}
|
||||||
|
void addLinuxDmabufBuffer(KWayland::Server::LinuxDmabufUnstableV1Buffer *buffer) {
|
||||||
|
m_linuxDmabufBuffers << buffer;
|
||||||
|
}
|
||||||
|
void removeLinuxDmabufBuffer(KWayland::Server::LinuxDmabufUnstableV1Buffer *buffer) {
|
||||||
|
m_linuxDmabufBuffers.remove(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void shellClientAdded(KWin::ShellClient*);
|
void shellClientAdded(KWin::ShellClient*);
|
||||||
void shellClientRemoved(KWin::ShellClient*);
|
void shellClientRemoved(KWin::ShellClient*);
|
||||||
|
@ -256,6 +269,8 @@ private:
|
||||||
KWayland::Server::IdleInterface *m_idle = nullptr;
|
KWayland::Server::IdleInterface *m_idle = nullptr;
|
||||||
KWayland::Server::XdgOutputManagerInterface *m_xdgOutputManager = nullptr;
|
KWayland::Server::XdgOutputManagerInterface *m_xdgOutputManager = nullptr;
|
||||||
KWayland::Server::XdgDecorationManagerInterface *m_xdgDecorationManager = nullptr;
|
KWayland::Server::XdgDecorationManagerInterface *m_xdgDecorationManager = nullptr;
|
||||||
|
KWayland::Server::LinuxDmabufUnstableV1Interface *m_linuxDmabuf = nullptr;
|
||||||
|
QSet<KWayland::Server::LinuxDmabufUnstableV1Buffer*> m_linuxDmabufBuffers;
|
||||||
struct {
|
struct {
|
||||||
KWayland::Server::ClientConnection *client = nullptr;
|
KWayland::Server::ClientConnection *client = nullptr;
|
||||||
QMetaObject::Connection destroyConnection;
|
QMetaObject::Connection destroyConnection;
|
||||||
|
|
Loading…
Reference in a new issue