From 0032609f217a3a32186ce546fd32807c18cbecb8 Mon Sep 17 00:00:00 2001 From: l10n daemon script Date: Thu, 5 Oct 2017 06:47:00 +0200 Subject: [PATCH 1/4] SVN_SILENT made messages (.desktop file) - always resolve ours In case of conflict in i18n, keep the version of the branch "ours" To resolve a particular conflict, "git checkout --ours path/to/file.desktop" --- effects/frozenapp/package/metadata.desktop | 2 ++ effects/logout/package/metadata.desktop | 1 + kcmkwin/kwinscreenedges/kwintouchscreen.desktop | 3 +++ 3 files changed, 6 insertions(+) diff --git a/effects/frozenapp/package/metadata.desktop b/effects/frozenapp/package/metadata.desktop index d8eabe12fe..9cdae4554e 100644 --- a/effects/frozenapp/package/metadata.desktop +++ b/effects/frozenapp/package/metadata.desktop @@ -16,6 +16,7 @@ Name[nn]=Fjern fargemetting på ikkje-responsive program Name[pl]=Odbarw nieodpowiadające aplikacje Name[pt]=Reduzir a Saturação das Aplicações Bloqueadas Name[pt_BR]=Reduzir saturação de aplicativos que não respondem +Name[ru]=Обесцвечивание зависших приложений Name[sk]=Desaturovať neodpovedajúce aplikácie Name[sl]=Zmanjšaj nasičenost neodzivnih programov Name[sr]=Посивљавање програма без одзива @@ -46,6 +47,7 @@ Comment[nn]=Fjern fargemetting på vindauge på program som ikkje lenger reagere Comment[pl]=Odbarw okna nieodpowiadających (zawieszonych) aplikacji Comment[pt]=Reduzir a saturação das janelas das aplicações sem resposta (bloqueadas) Comment[pt_BR]=Reduzir saturação de janelas de aplicativos que não respondem (travados) +Comment[ru]=Обесцвечивание окон приложений, не отвечающих на запросы Comment[sk]=Desaturovať okná neodpovedajúcich aplikácií Comment[sl]=Zmanjšaj nasičenost oken neodzivnih (zamrznjenih) programov Comment[sr]=Прозори програма који се не одазивају (смрзнутих) бивају посивљени diff --git a/effects/logout/package/metadata.desktop b/effects/logout/package/metadata.desktop index c3ef6ea1af..c2e5a6a2d9 100644 --- a/effects/logout/package/metadata.desktop +++ b/effects/logout/package/metadata.desktop @@ -20,6 +20,7 @@ Name[nn]=Utlogging Name[pl]=wylogowanie Name[pt]=encerramento Name[pt_BR]=sair +Name[ru]=Завершение сеанса Name[sk]=odhlásiť Name[sl]=odjavi Name[sr]=Одјава diff --git a/kcmkwin/kwinscreenedges/kwintouchscreen.desktop b/kcmkwin/kwinscreenedges/kwintouchscreen.desktop index a7525b90cd..3f821a7287 100644 --- a/kcmkwin/kwinscreenedges/kwintouchscreen.desktop +++ b/kcmkwin/kwinscreenedges/kwintouchscreen.desktop @@ -31,6 +31,7 @@ Name[pa]=ਟੱਚ ਸਕਰੀਨ Name[pl]=Ekran dotykowy Name[pt]=Ecrã Táctil Name[pt_BR]=Touch Screen +Name[ru]=Сенсорный экран Name[sk]=Dotyková obrazovka Name[sl]=Zaslon na dotik Name[sr]=Додирник @@ -60,6 +61,7 @@ Comment[pa]=ਟੱਚ ਸਕਰੀਨ ਸਕਰਾਉਣ ਜੈਸਚਰ Comment[pl]=Gesty na ekranie dotykowym Comment[pt]=Gestos para deslizar o ecrã táctil Comment[pt_BR]=Gestos no touch screen +Comment[ru]=Действия при проведении по сенсорному экрану Comment[sk]=Ťahacie gestá dotykovej obrazovky Comment[sl]=Kretnje vlečenja za zaslon na dotik Comment[sr]=Гестови замаха на додирнику @@ -88,6 +90,7 @@ X-KDE-Keywords[nn]=kwin,vindauge,handsamar,effekt,kant,ramme,handling,byte,skriv X-KDE-Keywords[pl]=kwin,okno,menadżer,efekt,krawędź,obramowanie,działanie,przełącz,pulpit,krawędzie pulpitu,krawędzie ekranu,strona ekranu,zachowanie ekranu,ekran dotykowy X-KDE-Keywords[pt]=kwin,janela,gestor,efeito,extremo,contorno,acção,mudar,ecrã,extremos do ecrã no kwin,extremos do ecrã,maximizar as janelas,janelas lado-a-lado,lado do ecrã,comportamento do ecrã,ecrã táctil X-KDE-Keywords[pt_BR]=kwin,janela,gerenciador,efeito,canto,contorno,borda,ação,mudar,área de trabalho,cantos da área de trabalho, desktop,lado da tela,comportamento da tela,touch screen +X-KDE-Keywords[ru]=kwin,window,manager,effect,corner,edge,border,action,switch,desktop,kwin screen edges,desktop edges,screen edges,maximize windows,tile windows,side of screen,screen behavior,switch desktop,virtual desktop,screen corners,окно,окон,диспетчер,эффект,край,граница,действие,переключить,рабочий стол,края экрана kwin,края экрана,края рабочего стола,распахнуть окна,мозаика окон,край экрана,поведение экрана,переключить рабочий стол,виртуальный рабочий стол,углы рабочего стола,углы экрана,тачскрин,сенсорный экран,touch screen X-KDE-Keywords[sk]=Kwin, okná, manažér, efekt, okraj, hranice, akcie, prepínač, desktop, okraje plochy,Okraje obrazovky, bočná strana obrazovky, správanie obrazovky, dotyková obrazovka X-KDE-Keywords[sl]=kwin,okno,upravljalnik oken,upravljanje oken,učinki,rob,obroba,dejanje,preklopi,preklapljanje,robovi namizja,robovi zaslona,rob zaslona,obnašanje zaslona,zaslon na dotik X-KDE-Keywords[sr]=kwin,window,manager,effect,edge,border,action,switch,desktop,desktop edges,screen edges,side of screen,screen behavior,touch screen,К‑вин,прозор,менаџер,ефекат,ивица,радња,пребаци,површ,ивице екрана,ивице површи,странице прозора,понашање прозора,додирник From c27f6dcde199f4c5c376dcfb48dff2e8fbadb0cd Mon Sep 17 00:00:00 2001 From: Jonathan Riddell Date: Thu, 5 Oct 2017 13:07:17 +0100 Subject: [PATCH 2/4] Update version number for 5.11.0 GIT_SILENT --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 456074eed6..b739a2f489 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.1 FATAL_ERROR) project(KWIN) -set(PROJECT_VERSION "5.10.95") +set(PROJECT_VERSION "5.11.0") set(PROJECT_VERSION_MAJOR 5) set(QT_MIN_VERSION "5.7.0") From 31b5b7f9f981ccaca001423c1a2183157bb53356 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Fl=C3=B6ser?= Date: Sat, 30 Sep 2017 16:33:45 +0200 Subject: [PATCH 3/4] Ensure internal Wayland connection is properly setup before creating LockScreen integration With the new Wayland only mode we start too fast and it can happen that the initWithWorkspace is called before the client connection is fully setup. This would result in a crash in the idletime plugin once it tries to create a seat. To prevent this problem the code is split out into a dedicated method and only invoked if all interfaces have been announced on the internal connection. BUG: 385397 FIXED-IN: 5.11.1 --- wayland_server.cpp | 54 ++++++++++++++++++++++++++++++---------------- wayland_server.h | 2 ++ 2 files changed, 37 insertions(+), 19 deletions(-) diff --git a/wayland_server.cpp b/wayland_server.cpp index e305253750..dd4727727f 100644 --- a/wayland_server.cpp +++ b/wayland_server.cpp @@ -330,26 +330,37 @@ void WaylandServer::initWorkspace() } if (hasScreenLockerIntegration()) { - ScreenLocker::KSldApp::self(); - ScreenLocker::KSldApp::self()->setWaylandDisplay(m_display); - ScreenLocker::KSldApp::self()->setGreeterEnvironment(kwinApp()->processStartupEnvironment()); - ScreenLocker::KSldApp::self()->initialize(); - - connect(ScreenLocker::KSldApp::self(), &ScreenLocker::KSldApp::greeterClientConnectionChanged, this, - [this] () { - m_screenLockerClientConnection = ScreenLocker::KSldApp::self()->greeterClientConnection(); - } - ); - - connect(ScreenLocker::KSldApp::self(), &ScreenLocker::KSldApp::unlocked, this, - [this] () { - m_screenLockerClientConnection = nullptr; - } - ); - - if (m_initFlags.testFlag(InitalizationFlag::LockScreen)) { - ScreenLocker::KSldApp::self()->lock(ScreenLocker::EstablishLock::Immediate); + if (m_internalConnection.interfacesAnnounced) { + initScreenLocker(); + } else { + connect(m_internalConnection.registry, &KWayland::Client::Registry::interfacesAnnounced, this, &WaylandServer::initScreenLocker); } + } else { + emit initialized(); + } +} + +void WaylandServer::initScreenLocker() +{ + ScreenLocker::KSldApp::self(); + ScreenLocker::KSldApp::self()->setWaylandDisplay(m_display); + ScreenLocker::KSldApp::self()->setGreeterEnvironment(kwinApp()->processStartupEnvironment()); + ScreenLocker::KSldApp::self()->initialize(); + + connect(ScreenLocker::KSldApp::self(), &ScreenLocker::KSldApp::greeterClientConnectionChanged, this, + [this] () { + m_screenLockerClientConnection = ScreenLocker::KSldApp::self()->greeterClientConnection(); + } + ); + + connect(ScreenLocker::KSldApp::self(), &ScreenLocker::KSldApp::unlocked, this, + [this] () { + m_screenLockerClientConnection = nullptr; + } + ); + + if (m_initFlags.testFlag(InitalizationFlag::LockScreen)) { + ScreenLocker::KSldApp::self()->lock(ScreenLocker::EstablishLock::Immediate); } emit initialized(); } @@ -521,6 +532,11 @@ void WaylandServer::createInternalConnection() m_internalConnection.shm = m_internalConnection.registry->createShmPool(name, version, this); } ); + connect(registry, &Registry::interfacesAnnounced, this, + [this] { + m_internalConnection.interfacesAnnounced = true; + } + ); registry->setup(); } ); diff --git a/wayland_server.h b/wayland_server.h index 1c6cab3732..9cd70cc248 100644 --- a/wayland_server.h +++ b/wayland_server.h @@ -200,6 +200,7 @@ private: void configurationChangeRequested(KWayland::Server::OutputConfigurationInterface *config); template void createSurface(T *surface); + void initScreenLocker(); KWayland::Server::Display *m_display = nullptr; KWayland::Server::CompositorInterface *m_compositor = nullptr; KWayland::Server::SeatInterface *m_seat = nullptr; @@ -222,6 +223,7 @@ private: QThread *clientThread = nullptr; KWayland::Client::Registry *registry = nullptr; KWayland::Client::ShmPool *shm = nullptr; + bool interfacesAnnounced = false; } m_internalConnection; struct { From 47343fb8f75909f6491c0534004df56ee1e53737 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Fl=C3=B6ser?= Date: Thu, 5 Oct 2017 18:58:57 +0200 Subject: [PATCH 4/4] [platforms/drm] Use a shared pointer for gbm_surface Summary: The gbm_surface is owned by the EglGbmBackend, but it's not the only one using it. The DrmSurfaceBuffer is also using it and needs it to destroy the gbm_bo. Now this can become a problem in the following situation: * a page flip is still pending * the EglGbmBackend destroys the gbm_surface -> when the page flip happens the DrmSurfaceBuffer will try to destroy the gbm_bo and crash as the gbm_surface is no longer valid. This situation can happen when switching screens or when switching compositing backend (OpenGL 2 -> OpenGL 3). To address this problem a class GbmSurface is added which wrapps the gbm_surface pointer. The EglGbmBackend creates and holds a shared pointer to the GbmSurface and passes that one to the DrmSurfaceBuffer. So when cleaning up the gbm_surface only the shared pointer is reset and in case the DrmSurfaceBuffer still needs it, it can access it without problems. BUG: 385372 FIXED-IN: 5.11.0 Test Plan: Not yet Reviewers: #kwin, #plasma, subdiff Subscribers: plasma-devel, kwin Tags: #kwin Differential Revision: https://phabricator.kde.org/D8152 --- autotests/CMakeLists.txt | 7 ++ autotests/test_gbm_surface.cpp | 119 ++++++++++++++++++++++ plugins/platforms/drm/CMakeLists.txt | 2 +- plugins/platforms/drm/drm_backend.cpp | 2 +- plugins/platforms/drm/drm_backend.h | 5 +- plugins/platforms/drm/drm_buffer_gbm.cpp | 11 +- plugins/platforms/drm/drm_buffer_gbm.h | 8 +- plugins/platforms/drm/egl_gbm_backend.cpp | 11 +- plugins/platforms/drm/egl_gbm_backend.h | 5 +- plugins/platforms/drm/gbm_surface.cpp | 55 ++++++++++ plugins/platforms/drm/gbm_surface.h | 55 ++++++++++ 11 files changed, 261 insertions(+), 19 deletions(-) create mode 100644 autotests/test_gbm_surface.cpp create mode 100644 plugins/platforms/drm/gbm_surface.cpp create mode 100644 plugins/platforms/drm/gbm_surface.h diff --git a/autotests/CMakeLists.txt b/autotests/CMakeLists.txt index 402d3b48f1..a8bcc9eb21 100644 --- a/autotests/CMakeLists.txt +++ b/autotests/CMakeLists.txt @@ -404,3 +404,10 @@ target_link_libraries(testXkb ) add_test(kwin-testXkb testXkb) ecm_mark_as_test(testXkb) + +if(HAVE_GBM) + add_executable(testGbmSurface test_gbm_surface.cpp ../plugins/platforms/drm/gbm_surface.cpp) + target_link_libraries(testGbmSurface Qt5::Test) + add_test(kwin-testGbmSurface testGbmSurface) + ecm_mark_as_test(kwin-testGbmSurface) +endif() diff --git a/autotests/test_gbm_surface.cpp b/autotests/test_gbm_surface.cpp new file mode 100644 index 0000000000..95ee363865 --- /dev/null +++ b/autotests/test_gbm_surface.cpp @@ -0,0 +1,119 @@ +/******************************************************************** + KWin - the KDE window manager + This file is part of the KDE project. + +Copyright (C) 2017 Martin Flöser + +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 . +*********************************************************************/ +#include "../plugins/platforms/drm/gbm_surface.h" +#include + +#include + +// mocking + +struct gbm_device { + bool surfaceShouldFail = false; +}; + +struct gbm_surface { + uint32_t width; + uint32_t height; + uint32_t format; + uint32_t flags; +}; + +struct gbm_bo { +}; + +struct gbm_surface *gbm_surface_create(struct gbm_device *gbm, uint32_t width, uint32_t height, uint32_t format, uint32_t flags) +{ + if (gbm && gbm->surfaceShouldFail) { + return nullptr; + } + auto ret = new gbm_surface{width, height, format, flags}; + return ret; +} + +void gbm_surface_destroy(struct gbm_surface *surface) +{ + delete surface; +} + +struct gbm_bo *gbm_surface_lock_front_buffer(struct gbm_surface *surface) +{ + Q_UNUSED(surface) + return new gbm_bo; +} + +void gbm_surface_release_buffer(struct gbm_surface *surface, struct gbm_bo *bo) +{ + Q_UNUSED(surface) + delete bo; +} + +using KWin::GbmSurface; + +class GbmSurfaceTest : public QObject +{ + Q_OBJECT +private Q_SLOTS: + void testCreate(); + void testCreateFailure(); + void testBo(); +}; + +void GbmSurfaceTest::testCreate() +{ + GbmSurface surface(nullptr, 2, 3, 4, 5); + gbm_surface *native = surface; + QVERIFY(surface); + QCOMPARE(native->width, 2u); + QCOMPARE(native->height, 3u); + QCOMPARE(native->format, 4u); + QCOMPARE(native->flags, 5u); +} + +void GbmSurfaceTest::testCreateFailure() +{ + gbm_device dev{true}; + GbmSurface surface(&dev, 2, 3, 4, 5); + QVERIFY(!surface); + gbm_surface *native = surface; + QVERIFY(!native); +} + +void GbmSurfaceTest::testBo() +{ + GbmSurface surface(nullptr, 2, 3, 4, 5); + // release buffer on nullptr should not be a problem + surface.releaseBuffer(nullptr); + // now an actual buffer + auto bo = surface.lockFrontBuffer(); + surface.releaseBuffer(bo); + + // and a surface which fails + gbm_device dev{true}; + GbmSurface surface2(&dev, 2, 3, 4, 5); + QVERIFY(!surface2.lockFrontBuffer()); + auto bo2 = surface.lockFrontBuffer(); + // this won't do anything + surface2.releaseBuffer(bo2); + // so we need to clean up properly + surface.releaseBuffer(bo2); +} + +QTEST_GUILESS_MAIN(GbmSurfaceTest) +#include "test_gbm_surface.moc" diff --git a/plugins/platforms/drm/CMakeLists.txt b/plugins/platforms/drm/CMakeLists.txt index 8db5207a7d..cc9141c90c 100644 --- a/plugins/platforms/drm/CMakeLists.txt +++ b/plugins/platforms/drm/CMakeLists.txt @@ -13,7 +13,7 @@ set(DRM_SOURCES ) if(HAVE_GBM) - set(DRM_SOURCES ${DRM_SOURCES} egl_gbm_backend.cpp drm_buffer_gbm.cpp) + set(DRM_SOURCES ${DRM_SOURCES} egl_gbm_backend.cpp drm_buffer_gbm.cpp gbm_surface.cpp) endif() add_library(KWinWaylandDrmBackend MODULE ${DRM_SOURCES}) diff --git a/plugins/platforms/drm/drm_backend.cpp b/plugins/platforms/drm/drm_backend.cpp index 33f894d414..9a51aca2b5 100644 --- a/plugins/platforms/drm/drm_backend.cpp +++ b/plugins/platforms/drm/drm_backend.cpp @@ -714,7 +714,7 @@ DrmDumbBuffer *DrmBackend::createBuffer(const QSize &size) } #if HAVE_GBM -DrmSurfaceBuffer *DrmBackend::createBuffer(gbm_surface *surface) +DrmSurfaceBuffer *DrmBackend::createBuffer(const std::shared_ptr &surface) { DrmSurfaceBuffer *b = new DrmSurfaceBuffer(this, surface); return b; diff --git a/plugins/platforms/drm/drm_backend.h b/plugins/platforms/drm/drm_backend.h index 96a8d0ce65..c44d3f0188 100644 --- a/plugins/platforms/drm/drm_backend.h +++ b/plugins/platforms/drm/drm_backend.h @@ -35,6 +35,8 @@ along with this program. If not, see . #include #include +#include + struct gbm_bo; struct gbm_device; struct gbm_surface; @@ -60,6 +62,7 @@ class DrmOutput; class DrmPlane; class DrmCrtc; class DrmConnector; +class GbmSurface; class KWIN_EXPORT DrmBackend : public Platform @@ -79,7 +82,7 @@ public: void init() override; DrmDumbBuffer *createBuffer(const QSize &size); #if HAVE_GBM - DrmSurfaceBuffer *createBuffer(gbm_surface *surface); + DrmSurfaceBuffer *createBuffer(const std::shared_ptr &surface); #endif void present(DrmBuffer *buffer, DrmOutput *output); diff --git a/plugins/platforms/drm/drm_buffer_gbm.cpp b/plugins/platforms/drm/drm_buffer_gbm.cpp index 8cebfc0516..6959d1bd98 100644 --- a/plugins/platforms/drm/drm_buffer_gbm.cpp +++ b/plugins/platforms/drm/drm_buffer_gbm.cpp @@ -20,6 +20,7 @@ along with this program. If not, see . *********************************************************************/ #include "drm_backend.h" #include "drm_buffer_gbm.h" +#include "gbm_surface.h" #include "logging.h" @@ -34,11 +35,11 @@ namespace KWin { // DrmSurfaceBuffer -DrmSurfaceBuffer::DrmSurfaceBuffer(DrmBackend *backend, gbm_surface *surface) +DrmSurfaceBuffer::DrmSurfaceBuffer(DrmBackend *backend, const std::shared_ptr &surface) : DrmBuffer(backend) , m_surface(surface) { - m_bo = gbm_surface_lock_front_buffer(surface); + m_bo = m_surface->lockFrontBuffer(); if (!m_bo) { qCWarning(KWIN_DRM) << "Locking front buffer failed"; return; @@ -60,10 +61,8 @@ DrmSurfaceBuffer::~DrmSurfaceBuffer() void DrmSurfaceBuffer::releaseGbm() { - if (m_bo) { - gbm_surface_release_buffer(m_surface, m_bo); - m_bo = nullptr; - } + m_surface->releaseBuffer(m_bo); + m_bo = nullptr; } } diff --git a/plugins/platforms/drm/drm_buffer_gbm.h b/plugins/platforms/drm/drm_buffer_gbm.h index 82224b116d..d26f665564 100644 --- a/plugins/platforms/drm/drm_buffer_gbm.h +++ b/plugins/platforms/drm/drm_buffer_gbm.h @@ -23,18 +23,20 @@ along with this program. If not, see . #include "drm_buffer.h" +#include + struct gbm_bo; -struct gbm_surface; namespace KWin { class DrmBackend; +class GbmSurface; class DrmSurfaceBuffer : public DrmBuffer { public: - DrmSurfaceBuffer(DrmBackend *backend, gbm_surface *surface); + DrmSurfaceBuffer(DrmBackend *backend, const std::shared_ptr &surface); ~DrmSurfaceBuffer(); bool needsModeChange(DrmBuffer *b) const override { @@ -51,7 +53,7 @@ public: void releaseGbm() override; private: - gbm_surface *m_surface = nullptr; + std::shared_ptr m_surface; gbm_bo *m_bo = nullptr; }; diff --git a/plugins/platforms/drm/egl_gbm_backend.cpp b/plugins/platforms/drm/egl_gbm_backend.cpp index 646e775666..51792b5416 100644 --- a/plugins/platforms/drm/egl_gbm_backend.cpp +++ b/plugins/platforms/drm/egl_gbm_backend.cpp @@ -22,6 +22,7 @@ along with this program. If not, see . #include "composite.h" #include "drm_backend.h" #include "drm_output.h" +#include "gbm_surface.h" #include "logging.h" #include "options.h" #include "screens.h" @@ -69,6 +70,7 @@ void EglGbmBackend::cleanupSurfaces() for (auto it = m_outputs.constBegin(); it != m_outputs.constEnd(); ++it) { cleanupOutput(*it); } + m_outputs.clear(); } void EglGbmBackend::cleanupOutput(const Output &o) @@ -78,9 +80,6 @@ void EglGbmBackend::cleanupOutput(const Output &o) if (o.eglSurface != EGL_NO_SURFACE) { eglDestroySurface(eglDisplay(), o.eglSurface); } - if (o.gbmSurface) { - gbm_surface_destroy(o.gbmSurface); - } } bool EglGbmBackend::initializeEgl() @@ -157,16 +156,16 @@ void EglGbmBackend::createOutput(DrmOutput *drmOutput) o.output = drmOutput; auto size = drmOutput->pixelSize(); - o.gbmSurface = gbm_surface_create(m_backend->gbmDevice(), size.width(), size.height(), + o.gbmSurface = std::make_shared(m_backend->gbmDevice(), size.width(), size.height(), GBM_FORMAT_XRGB8888, GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING); if (!o.gbmSurface) { qCCritical(KWIN_DRM) << "Create gbm surface failed"; return; } - o.eglSurface = eglCreatePlatformWindowSurfaceEXT(eglDisplay(), config(), (void *)o.gbmSurface, nullptr); + o.eglSurface = eglCreatePlatformWindowSurfaceEXT(eglDisplay(), config(), (void *)((gbm_surface*)o.gbmSurface.get()), nullptr); if (o.eglSurface == EGL_NO_SURFACE) { qCCritical(KWIN_DRM) << "Create Window Surface failed"; - gbm_surface_destroy(o.gbmSurface); + o.gbmSurface.reset(); return; } m_outputs << o; diff --git a/plugins/platforms/drm/egl_gbm_backend.h b/plugins/platforms/drm/egl_gbm_backend.h index 30e17e6824..5ace7c6a92 100644 --- a/plugins/platforms/drm/egl_gbm_backend.h +++ b/plugins/platforms/drm/egl_gbm_backend.h @@ -22,6 +22,8 @@ along with this program. If not, see . #include "abstract_egl_backend.h" #include "scene_opengl.h" +#include + struct gbm_surface; namespace KWin @@ -29,6 +31,7 @@ namespace KWin class DrmBackend; class DrmBuffer; class DrmOutput; +class GbmSurface; /** * @brief OpenGL Backend using Egl on a GBM surface. @@ -60,7 +63,7 @@ private: struct Output { DrmOutput *output = nullptr; DrmBuffer *buffer = nullptr; - gbm_surface *gbmSurface = nullptr; + std::shared_ptr gbmSurface; EGLSurface eglSurface = EGL_NO_SURFACE; int bufferAge = 0; /** diff --git a/plugins/platforms/drm/gbm_surface.cpp b/plugins/platforms/drm/gbm_surface.cpp new file mode 100644 index 0000000000..30eb988fc1 --- /dev/null +++ b/plugins/platforms/drm/gbm_surface.cpp @@ -0,0 +1,55 @@ +/******************************************************************** + KWin - the KDE window manager + This file is part of the KDE project. + +Copyright (C) 2017 Martin Flöser + +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 . +*********************************************************************/ +#include "gbm_surface.h" + +#include + +namespace KWin +{ + +GbmSurface::GbmSurface(gbm_device *gbm, uint32_t width, uint32_t height, uint32_t format, uint32_t flags) + : m_surface(gbm_surface_create(gbm, width, height, format, flags)) +{ +} + +GbmSurface::~GbmSurface() +{ + if (m_surface) { + gbm_surface_destroy(m_surface); + } +} + +gbm_bo *GbmSurface::lockFrontBuffer() +{ + if (!m_surface) { + return nullptr; + } + return gbm_surface_lock_front_buffer(m_surface); +} + +void GbmSurface::releaseBuffer(gbm_bo *bo) +{ + if (!bo || !m_surface) { + return; + } + gbm_surface_release_buffer(m_surface, bo); +} + +} diff --git a/plugins/platforms/drm/gbm_surface.h b/plugins/platforms/drm/gbm_surface.h new file mode 100644 index 0000000000..6877a926c0 --- /dev/null +++ b/plugins/platforms/drm/gbm_surface.h @@ -0,0 +1,55 @@ +/******************************************************************** + KWin - the KDE window manager + This file is part of the KDE project. + +Copyright (C) 2017 Martin Flöser + +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 . +*********************************************************************/ +#ifndef KWIN_DRM_GBM_SURFACE_H +#define KWIN_DRM_GBM_SURFACE_H + +#include + +struct gbm_bo; +struct gbm_device; +struct gbm_surface; + +namespace KWin +{ + +class GbmSurface +{ +public: + explicit GbmSurface(gbm_device *gbm, uint32_t width, uint32_t height, uint32_t format, uint32_t flags); + ~GbmSurface(); + + gbm_bo *lockFrontBuffer(); + void releaseBuffer(gbm_bo *bo); + + operator bool() const { + return m_surface != nullptr; + } + + operator gbm_surface*() const { + return m_surface; + } + +private: + gbm_surface *m_surface; +}; + +} + +#endif