Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Plasma
KWin
Commits
b530a5b6
Commit
b530a5b6
authored
Feb 15, 2022
by
Xaver Hugl
Browse files
backends/drm: fix layer destruction
Layers need to release their resources whenever the render backend gets replaced.
parent
a04bdf23
Pipeline
#141089
passed with stage
in 21 minutes and 6 seconds
Changes
20
Pipelines
3
Hide whitespace changes
Inline
Side-by-side
src/backends/drm/CMakeLists.txt
View file @
b530a5b6
...
...
@@ -14,6 +14,7 @@ set(DRM_SOURCES
dumb_swapchain.cpp
shadowbuffer.cpp
drm_display_device.cpp
drm_layer.cpp
drm_pipeline.cpp
drm_pipeline_legacy.cpp
drm_abstract_output.cpp
...
...
src/backends/drm/drm_backend.cpp
View file @
b530a5b6
...
...
@@ -28,6 +28,7 @@
#include
"waylandoutputconfig.h"
#include
"egl_gbm_backend.h"
#include
"gbm_dmabuf.h"
#include
"drm_render_backend.h"
// KF5
#include
<KCoreAddons>
#include
<KLocalizedString>
...
...
@@ -550,7 +551,13 @@ OpenGLBackend *DrmBackend::createOpenGLBackend()
void
DrmBackend
::
sceneInitialized
()
{
updateOutputs
();
if
(
m_outputs
.
isEmpty
())
{
updateOutputs
();
}
else
{
for
(
const
auto
&
gpu
:
qAsConst
(
m_gpus
))
{
gpu
->
recreateSurfaces
();
}
}
}
QVector
<
CompositingType
>
DrmBackend
::
supportedCompositors
()
const
...
...
@@ -593,8 +600,8 @@ void DrmBackend::removeVirtualOutput(AbstractOutput *output)
DmaBufTexture
*
DrmBackend
::
createDmaBufTexture
(
const
QSize
&
size
)
{
if
(
primaryGpu
()
->
eglBackend
()
&&
primaryGpu
()
->
gbmDevice
())
{
primaryGpu
()
->
eglBackend
()
->
makeCurrent
();
if
(
const
auto
eglBackend
=
dynamic_cast
<
EglGbmBackend
*>
(
m_renderBackend
);
eglBackend
&&
primaryGpu
()
->
gbmDevice
())
{
eglBackend
->
makeCurrent
();
return
GbmDmaBuf
::
createBuffer
(
size
,
primaryGpu
()
->
gbmDevice
());
}
else
{
return
nullptr
;
...
...
@@ -664,4 +671,14 @@ bool DrmBackend::applyOutputChanges(const WaylandOutputConfig &config)
return
true
;
}
void
DrmBackend
::
setRenderBackend
(
DrmRenderBackend
*
backend
)
{
m_renderBackend
=
backend
;
}
DrmRenderBackend
*
DrmBackend
::
renderBackend
()
const
{
return
m_renderBackend
;
}
}
src/backends/drm/drm_backend.h
View file @
b530a5b6
...
...
@@ -30,6 +30,7 @@ class DrmAbstractOutput;
class
Cursor
;
class
DrmGpu
;
class
DrmVirtualOutput
;
class
DrmRenderBackend
;
class
KWIN_EXPORT
DrmBackend
:
public
Platform
{
...
...
@@ -67,6 +68,9 @@ public:
bool
isActive
()
const
;
void
setRenderBackend
(
DrmRenderBackend
*
backend
);
DrmRenderBackend
*
renderBackend
()
const
;
public
Q_SLOTS
:
void
turnOutputsOn
();
void
sceneInitialized
()
override
;
...
...
@@ -105,6 +109,7 @@ private:
QVector
<
DrmGpu
*>
m_gpus
;
QScopedPointer
<
DpmsInputEventFilter
>
m_dpmsFilter
;
QScopedPointer
<
PlaceholderInputEventFilter
>
m_placeholderFilter
;
DrmRenderBackend
*
m_renderBackend
=
nullptr
;
};
...
...
src/backends/drm/drm_gpu.cpp
View file @
b530a5b6
...
...
@@ -422,7 +422,7 @@ bool DrmGpu::testPipelines()
QVector
<
DrmPipeline
*>
inactivePipelines
;
for
(
const
auto
&
pipeline
:
qAsConst
(
m_pipelines
))
{
if
(
!
pipeline
->
pending
.
layer
)
{
pipeline
->
pending
.
layer
=
m_renderBackend
->
createLayer
(
pipeline
->
displayDevice
());
pipeline
->
pending
.
layer
=
m_
platform
->
renderBackend
()
->
createLayer
(
pipeline
->
displayDevice
());
}
if
(
!
pipeline
->
pending
.
active
)
{
pipeline
->
pending
.
active
=
true
;
...
...
@@ -562,21 +562,6 @@ void DrmGpu::removeOutput(DrmOutput *output)
delete
output
;
}
EglGbmBackend
*
DrmGpu
::
eglBackend
()
const
{
return
dynamic_cast
<
EglGbmBackend
*>
(
m_renderBackend
);
}
DrmRenderBackend
*
DrmGpu
::
renderBackend
()
const
{
return
m_renderBackend
;
}
void
DrmGpu
::
setRenderBackend
(
DrmRenderBackend
*
backend
)
{
m_renderBackend
=
backend
;
}
DrmBackend
*
DrmGpu
::
platform
()
const
{
return
m_platform
;
}
...
...
@@ -782,4 +767,16 @@ QSize DrmGpu::cursorSize() const
return
m_cursorSize
;
}
void
DrmGpu
::
recreateSurfaces
()
{
for
(
const
auto
&
pipeline
:
qAsConst
(
m_pipelines
))
{
pipeline
->
pending
.
layer
=
m_platform
->
renderBackend
()
->
createLayer
(
pipeline
->
displayDevice
());
}
for
(
const
auto
&
output
:
qAsConst
(
m_outputs
))
{
if
(
const
auto
virtualOutput
=
qobject_cast
<
DrmVirtualOutput
*>
(
output
))
{
virtualOutput
->
recreateSurface
();
}
}
}
}
src/backends/drm/drm_gpu.h
View file @
b530a5b6
...
...
@@ -59,8 +59,6 @@ public:
bool
isNVidia
()
const
;
gbm_device
*
gbmDevice
()
const
;
EGLDisplay
eglDisplay
()
const
;
EglGbmBackend
*
eglBackend
()
const
;
DrmRenderBackend
*
renderBackend
()
const
;
DrmBackend
*
platform
()
const
;
/**
* Returns the clock from which presentation timestamps are sourced. The returned value
...
...
@@ -73,7 +71,6 @@ public:
const
QVector
<
DrmPipeline
*>
pipelines
()
const
;
void
setEglDisplay
(
EGLDisplay
display
);
void
setRenderBackend
(
DrmRenderBackend
*
backend
);
bool
updateOutputs
();
...
...
@@ -89,6 +86,8 @@ public:
bool
needsModeset
()
const
;
bool
maybeModeset
();
void
recreateSurfaces
();
Q_SIGNALS:
void
outputAdded
(
DrmAbstractOutput
*
output
);
void
outputRemoved
(
DrmAbstractOutput
*
output
);
...
...
@@ -122,7 +121,6 @@ private:
clockid_t
m_presentationClock
;
gbm_device
*
m_gbmDevice
;
EGLDisplay
m_eglDisplay
=
EGL_NO_DISPLAY
;
DrmRenderBackend
*
m_renderBackend
;
DrmBackend
*
const
m_platform
;
QVector
<
DrmPlane
*>
m_planes
;
...
...
src/backends/drm/drm_layer.cpp
0 → 100644
View file @
b530a5b6
/*
KWin - the KDE window manager
This file is part of the KDE project.
SPDX-FileCopyrightText: 2022 Xaver Hugl <xaver.hugl@gmail.com>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include
"drm_layer.h"
namespace
KWin
{
DrmLayer
::
DrmLayer
(
KWin
::
DrmDisplayDevice
*
device
)
:
m_displayDevice
(
device
)
{
}
DrmLayer
::~
DrmLayer
()
=
default
;
DrmDisplayDevice
*
DrmLayer
::
displayDevice
()
const
{
return
m_displayDevice
;
}
}
#include
"drm_layer.moc"
src/backends/drm/drm_layer.h
View file @
b530a5b6
...
...
@@ -11,6 +11,7 @@
#include
<optional>
#include
<QRegion>
#include
<QSharedPointer>
#include
<QObject>
namespace
KWin
{
...
...
@@ -19,10 +20,12 @@ class SurfaceItem;
class
DrmBuffer
;
class
DrmDisplayDevice
;
class
DrmLayer
class
DrmLayer
:
public
QObject
{
Q_OBJECT
public:
virtual
~
DrmLayer
()
=
default
;
DrmLayer
(
DrmDisplayDevice
*
device
);
virtual
~
DrmLayer
();
virtual
std
::
optional
<
QRegion
>
startRendering
()
=
0
;
virtual
bool
endRendering
(
const
QRegion
&
damagedRegion
)
=
0
;
...
...
@@ -44,7 +47,10 @@ public:
virtual
QRegion
currentDamage
()
const
=
0
;
virtual
bool
hasDirectScanoutBuffer
()
const
=
0
;
virtual
DrmDisplayDevice
*
displayDevice
()
const
=
0
;
DrmDisplayDevice
*
displayDevice
()
const
;
protected:
DrmDisplayDevice
*
const
m_displayDevice
;
};
}
src/backends/drm/drm_qpainter_layer.cpp
View file @
b530a5b6
...
...
@@ -10,6 +10,9 @@
#include
"dumb_swapchain.h"
#include
"drm_abstract_output.h"
#include
"drm_buffer.h"
#include
"scene_qpainter_drm_backend.h"
#include
"drm_gpu.h"
#include
"drm_backend.h"
#include
<drm_fourcc.h>
...
...
@@ -17,8 +20,11 @@ namespace KWin
{
DrmQPainterLayer
::
DrmQPainterLayer
(
DrmDisplayDevice
*
displayDevice
)
:
m_displayDevice
(
displayDevice
)
:
DrmLayer
(
displayDevice
)
{
connect
(
static_cast
<
DrmQPainterBackend
*>
(
displayDevice
->
gpu
()
->
platform
()
->
renderBackend
()),
&
DrmQPainterBackend
::
aboutToBeDestroyed
,
this
,
[
this
]()
{
m_swapchain
.
reset
();
});
}
std
::
optional
<
QRegion
>
DrmQPainterLayer
::
startRendering
()
...
...
@@ -69,11 +75,6 @@ QRegion DrmQPainterLayer::currentDamage() const
return
m_currentDamage
;
}
DrmDisplayDevice
*
DrmQPainterLayer
::
displayDevice
()
const
{
return
m_displayDevice
;
}
bool
DrmQPainterLayer
::
hasDirectScanoutBuffer
()
const
{
return
false
;
...
...
src/backends/drm/drm_qpainter_layer.h
View file @
b530a5b6
...
...
@@ -14,7 +14,8 @@ namespace KWin
class
DumbSwapchain
;
class
DrmQPainterLayer
:
public
DrmLayer
{
class
DrmQPainterLayer
:
public
DrmLayer
{
public:
DrmQPainterLayer
(
DrmDisplayDevice
*
displayDevice
);
...
...
@@ -25,14 +26,12 @@ public:
QSharedPointer
<
DrmBuffer
>
currentBuffer
()
const
override
;
QRegion
currentDamage
()
const
override
;
bool
hasDirectScanoutBuffer
()
const
override
;
DrmDisplayDevice
*
displayDevice
()
const
override
;
private:
bool
doesSwapchainFit
()
const
;
QSharedPointer
<
DumbSwapchain
>
m_swapchain
;
QRegion
m_currentDamage
;
DrmDisplayDevice
*
const
m_displayDevice
;
};
}
src/backends/drm/drm_render_backend.h
View file @
b530a5b6
...
...
@@ -21,7 +21,7 @@ class DrmRenderBackend
public:
virtual
~
DrmRenderBackend
()
=
default
;
virtual
QSharedPointer
<
DrmLayer
>
createLayer
(
DrmDisplayDevice
*
displayDevice
)
const
=
0
;
virtual
QSharedPointer
<
DrmLayer
>
createLayer
(
DrmDisplayDevice
*
displayDevice
)
=
0
;
};
...
...
src/backends/drm/drm_virtual_output.cpp
View file @
b530a5b6
...
...
@@ -44,7 +44,7 @@ DrmVirtualOutput::DrmVirtualOutput(const QString &name, DrmGpu *gpu, const QSize
QByteArray
(
"EDID_"
)
+
name
.
toUtf8
());
m_renderLoop
->
setRefreshRate
(
modes
[
m_modeIndex
].
refreshRate
);
m_layer
=
gpu
->
renderBackend
()
->
createLayer
(
this
);
recreateSurface
(
);
}
DrmVirtualOutput
::~
DrmVirtualOutput
()
...
...
@@ -131,4 +131,9 @@ bool DrmVirtualOutput::testScanout()
return
true
;
}
void
DrmVirtualOutput
::
recreateSurface
()
{
m_layer
=
m_gpu
->
platform
()
->
renderBackend
()
->
createLayer
(
this
);
}
}
src/backends/drm/drm_virtual_output.h
View file @
b530a5b6
...
...
@@ -43,6 +43,8 @@ public:
DrmLayer
*
outputLayer
()
const
override
;
bool
testScanout
()
override
;
void
recreateSurface
();
private:
void
vblank
(
std
::
chrono
::
nanoseconds
timestamp
);
void
setDpmsMode
(
DpmsMode
mode
)
override
;
...
...
src/backends/drm/egl_gbm_backend.cpp
View file @
b530a5b6
...
...
@@ -49,14 +49,15 @@ EglGbmBackend::EglGbmBackend(DrmBackend *drmBackend)
:
AbstractEglBackend
(
drmBackend
->
primaryGpu
()
->
deviceId
())
,
m_backend
(
drmBackend
)
{
drmBackend
->
primaryGpu
()
->
setRenderBackend
(
this
);
drmBackend
->
setRenderBackend
(
this
);
setIsDirectRendering
(
true
);
}
EglGbmBackend
::~
EglGbmBackend
()
{
Q_EMIT
aboutToBeDestroyed
();
cleanup
();
m_backend
->
primaryGpu
()
->
setRenderBackend
(
nullptr
);
m_backend
->
setRenderBackend
(
nullptr
);
}
bool
EglGbmBackend
::
initializeEgl
()
...
...
@@ -331,9 +332,14 @@ EGLConfig EglGbmBackend::config(uint32_t format) const
return
m_configs
[
format
];
}
QSharedPointer
<
DrmLayer
>
EglGbmBackend
::
createLayer
(
DrmDisplayDevice
*
displayDevice
)
const
QSharedPointer
<
DrmLayer
>
EglGbmBackend
::
createLayer
(
DrmDisplayDevice
*
displayDevice
)
{
return
QSharedPointer
<
EglGbmLayer
>::
create
(
m_backend
->
primaryGpu
(),
displayDevice
);
return
QSharedPointer
<
EglGbmLayer
>::
create
(
this
,
displayDevice
);
}
DrmGpu
*
EglGbmBackend
::
gpu
()
const
{
return
m_backend
->
primaryGpu
();
}
bool
operator
==
(
const
GbmFormat
&
lhs
,
const
GbmFormat
&
rhs
)
...
...
src/backends/drm/egl_gbm_backend.h
View file @
b530a5b6
...
...
@@ -67,7 +67,7 @@ public:
void
init
()
override
;
bool
scanout
(
AbstractOutput
*
output
,
SurfaceItem
*
surfaceItem
)
override
;
bool
prefer10bpc
()
const
override
;
QSharedPointer
<
DrmLayer
>
createLayer
(
DrmDisplayDevice
*
displayDevice
)
const
override
;
QSharedPointer
<
DrmLayer
>
createLayer
(
DrmDisplayDevice
*
displayDevice
)
override
;
QSharedPointer
<
GLTexture
>
textureForOutput
(
AbstractOutput
*
requestedOutput
)
const
override
;
...
...
@@ -75,6 +75,10 @@ public:
EGLConfig
config
(
uint32_t
format
)
const
;
GbmFormat
gbmFormatForDrmFormat
(
uint32_t
format
)
const
;
std
::
optional
<
uint32_t
>
chooseFormat
(
DrmDisplayDevice
*
displyDevice
)
const
;
DrmGpu
*
gpu
()
const
;
Q_SIGNALS:
void
aboutToBeDestroyed
();
protected:
void
aboutToStartPainting
(
AbstractOutput
*
output
,
const
QRegion
&
damage
)
override
;
...
...
src/backends/drm/egl_gbm_layer.cpp
View file @
b530a5b6
...
...
@@ -19,6 +19,7 @@
#include
"egl_dmabuf.h"
#include
"surfaceitem_wayland.h"
#include
"kwineglimagetexture.h"
#include
"drm_backend.h"
#include
"KWaylandServer/surface_interface.h"
#include
"KWaylandServer/linuxdmabufv1clientbuffer.h"
...
...
@@ -32,20 +33,31 @@
namespace
KWin
{
EglGbmLayer
::
EglGbmLayer
(
DrmGpu
*
renderGpu
,
DrmDisplayDevice
*
displayDevice
)
:
m_displayDevice
(
displayDevice
)
,
m_
renderGpu
(
renderGpu
)
EglGbmLayer
::
EglGbmLayer
(
EglGbmBackend
*
eglBackend
,
DrmDisplayDevice
*
displayDevice
)
:
DrmLayer
(
displayDevice
)
,
m_
eglBackend
(
eglBackend
)
{
connect
(
eglBackend
,
&
EglGbmBackend
::
aboutToBeDestroyed
,
this
,
&
EglGbmLayer
::
destroyResources
);
}
EglGbmLayer
::~
EglGbmLayer
()
{
if
(
m_gbmSurface
&&
m_shadowBuffer
&&
m_gbmSurface
->
makeContextCurrent
())
{
m_shadowBuffer
.
reset
();
}
if
(
m_oldGbmSurface
&&
m_oldShadowBuffer
&&
m_oldGbmSurface
->
makeContextCurrent
())
{
m_oldShadowBuffer
.
reset
();
destroyResources
();
}
void
EglGbmLayer
::
destroyResources
()
{
if
(
m_shadowBuffer
||
m_oldShadowBuffer
)
{
if
(
m_gbmSurface
)
{
m_gbmSurface
->
makeContextCurrent
();
}
else
if
(
m_oldGbmSurface
)
{
m_oldGbmSurface
->
makeContextCurrent
();
}
}
m_shadowBuffer
.
reset
();
m_oldShadowBuffer
.
reset
();
m_gbmSurface
.
reset
();
m_oldGbmSurface
.
reset
();
}
std
::
optional
<
QRegion
>
EglGbmLayer
::
startRendering
()
...
...
@@ -87,7 +99,7 @@ std::optional<QRegion> EglGbmLayer::startRendering()
m_shadowBuffer
=
m_oldShadowBuffer
;
}
else
{
if
(
m_displayDevice
->
softwareTransforms
()
!=
DrmPlane
::
Transformations
(
DrmPlane
::
Transformation
::
Rotate0
))
{
const
auto
format
=
m_
renderGpu
->
eglBackend
()
->
gbmFormatForDrmFormat
(
m_gbmSurface
->
format
());
const
auto
format
=
m_eglBackend
->
gbmFormatForDrmFormat
(
m_gbmSurface
->
format
());
m_shadowBuffer
=
QSharedPointer
<
ShadowBuffer
>::
create
(
m_displayDevice
->
sourceSize
(),
format
);
if
(
!
m_shadowBuffer
->
isComplete
())
{
return
std
::
optional
<
QRegion
>
();
...
...
@@ -164,37 +176,37 @@ bool EglGbmLayer::createGbmSurface()
static
bool
modifiersEnvSet
=
false
;
static
const
bool
modifiersEnv
=
qEnvironmentVariableIntValue
(
"KWIN_DRM_USE_MODIFIERS"
,
&
modifiersEnvSet
)
!=
0
;
auto
format
=
m_
renderGpu
->
eglBackend
()
->
chooseFormat
(
m_displayDevice
);
auto
format
=
m_eglBackend
->
chooseFormat
(
m_displayDevice
);
if
(
!
format
||
m_importMode
==
MultiGpuImportMode
::
DumbBufferXrgb8888
)
{
format
=
DRM_FORMAT_XRGB8888
;
}
const
auto
modifiers
=
m_displayDevice
->
supportedModifiers
(
format
.
value
());
const
auto
size
=
m_displayDevice
->
bufferSize
();
const
auto
config
=
m_
renderGpu
->
eglBackend
()
->
config
(
format
.
value
());
const
bool
allowModifiers
=
m_
renderGpu
->
addFB2ModifiersSupported
()
&&
m_displayDevice
->
gpu
()
->
addFB2ModifiersSupported
()
&&
((
m_
renderGpu
->
isNVidia
()
&&
!
modifiersEnvSet
)
||
(
modifiersEnvSet
&&
modifiersEnv
));
const
auto
config
=
m_eglBackend
->
config
(
format
.
value
());
const
bool
allowModifiers
=
m_
eglBackend
->
gpu
()
->
addFB2ModifiersSupported
()
&&
m_displayDevice
->
gpu
()
->
addFB2ModifiersSupported
()
&&
((
m_
eglBackend
->
gpu
()
->
isNVidia
()
&&
!
modifiersEnvSet
)
||
(
modifiersEnvSet
&&
modifiersEnv
));
QSharedPointer
<
GbmSurface
>
gbmSurface
;
#if HAVE_GBM_BO_GET_FD_FOR_PLANE
if
(
!
allowModifiers
)
{
#else
// modifiers have to be disabled with multi-gpu if gbm_bo_get_fd_for_plane is not available
if
(
!
allowModifiers
||
m_displayDevice
->
gpu
()
!=
m_
renderGpu
)
{
if
(
!
allowModifiers
||
m_displayDevice
->
gpu
()
!=
m_
eglBackend
->
gpu
()
)
{
#endif
int
flags
=
GBM_BO_USE_RENDERING
;
if
(
m_displayDevice
->
gpu
()
==
m_
renderGpu
)
{
if
(
m_displayDevice
->
gpu
()
==
m_
eglBackend
->
gpu
()
)
{
flags
|=
GBM_BO_USE_SCANOUT
;
}
else
{
flags
|=
GBM_BO_USE_LINEAR
;
}
gbmSurface
=
QSharedPointer
<
GbmSurface
>::
create
(
m_
renderGpu
,
size
,
format
.
value
(),
flags
,
config
);
gbmSurface
=
QSharedPointer
<
GbmSurface
>::
create
(
m_
eglBackend
->
gpu
()
,
size
,
format
.
value
(),
flags
,
config
);
}
else
{
gbmSurface
=
QSharedPointer
<
GbmSurface
>::
create
(
m_
renderGpu
,
size
,
format
.
value
(),
modifiers
,
config
);
gbmSurface
=
QSharedPointer
<
GbmSurface
>::
create
(
m_
eglBackend
->
gpu
()
,
size
,
format
.
value
(),
modifiers
,
config
);
if
(
!
gbmSurface
->
isValid
())
{
// the egl / gbm implementation may reject the modifier list from another gpu
// as a fallback use linear, to at least make CPU copy more efficient
const
QVector
<
uint64_t
>
linear
=
{
DRM_FORMAT_MOD_LINEAR
};
gbmSurface
=
QSharedPointer
<
GbmSurface
>::
create
(
m_
renderGpu
,
size
,
format
.
value
(),
linear
,
config
);
gbmSurface
=
QSharedPointer
<
GbmSurface
>::
create
(
m_
eglBackend
->
gpu
()
,
size
,
format
.
value
(),
linear
,
config
);
}
}
if
(
!
gbmSurface
->
isValid
())
{
...
...
@@ -237,12 +249,12 @@ QSharedPointer<GLTexture> EglGbmLayer::texture() const
qCWarning
(
KWIN_DRM
)
<<
"Failed to record frame: No gbm buffer!"
;
return
nullptr
;
}
EGLImageKHR
image
=
eglCreateImageKHR
(
m_
renderGpu
->
eglDisplay
(),
nullptr
,
EGL_NATIVE_PIXMAP_KHR
,
gbmBuffer
->
getBo
(),
nullptr
);
EGLImageKHR
image
=
eglCreateImageKHR
(
m_
eglBackend
->
eglDisplay
(),
nullptr
,
EGL_NATIVE_PIXMAP_KHR
,
gbmBuffer
->
getBo
(),
nullptr
);
if
(
image
==
EGL_NO_IMAGE_KHR
)
{
qCWarning
(
KWIN_DRM
)
<<
"Failed to record frame: Error creating EGLImageKHR - "
<<
glGetError
();
return
nullptr
;
}
return
QSharedPointer
<
EGLImageTexture
>::
create
(
m_
renderGpu
->
eglDisplay
(),
image
,
GL_RGBA8
,
m_displayDevice
->
sourceSize
());
return
QSharedPointer
<
EGLImageTexture
>::
create
(
m_
eglBackend
->
eglDisplay
(),
image
,
GL_RGBA8
,
m_displayDevice
->
sourceSize
());
}
QSharedPointer
<
DrmBuffer
>
EglGbmLayer
::
importBuffer
()
...
...
@@ -455,7 +467,7 @@ void EglGbmLayer::sendDmabufFeedback(KWaylandServer::LinuxDmaBufV1ClientBuffer *
if
(
const
auto
&
drmOutput
=
dynamic_cast
<
DrmOutput
*>
(
m_displayDevice
);
drmOutput
&&
m_scanoutCandidate
.
surface
->
dmabufFeedbackV1
())
{
QVector
<
KWaylandServer
::
LinuxDmaBufV1Feedback
::
Tranche
>
scanoutTranches
;
const
auto
&
drmFormats
=
drmOutput
->
pipeline
()
->
supportedFormats
();
const
auto
tranches
=
m_
renderGpu
->
eglBackend
()
->
dmabuf
()
->
tranches
();
const
auto
tranches
=
m_eglBackend
->
dmabuf
()
->
tranches
();
for
(
const
auto
&
tranche
:
tranches
)
{
KWaylandServer
::
LinuxDmaBufV1Feedback
::
Tranche
scanoutTranche
;
for
(
auto
it
=
tranche
.
formatTable
.
constBegin
();
it
!=
tranche
.
formatTable
.
constEnd
();
it
++
)
{
...
...
@@ -483,11 +495,6 @@ QSharedPointer<DrmBuffer> EglGbmLayer::currentBuffer() const
return
m_scanoutBuffer
?
m_scanoutBuffer
:
m_currentBuffer
;
}
DrmDisplayDevice
*
EglGbmLayer
::
displayDevice
()
const
{
return
m_displayDevice
;
}
int
EglGbmLayer
::
bufferAge
()
const
{
return
m_gbmSurface
?
m_gbmSurface
->
bufferAge
()
:
0
;
...
...
src/backends/drm/egl_gbm_layer.h
View file @
b530a5b6
...
...
@@ -32,11 +32,12 @@ class DrmBuffer;
class
DrmGpu
;
class
SurfaceItem
;
class
GLTexture
;
class
EglGbmBackend
;
class
EglGbmLayer
:
public
DrmLayer
{
public:
EglGbmLayer
(
DrmGpu
*
renderGpu
,
DrmDisplayDevice
*
displayDevice
);
EglGbmLayer
(
EglGbmBackend
*
eglBackend
,
DrmDisplayDevice
*
displayDevice
);
~
EglGbmLayer
();
std
::
optional
<
QRegion
>
startRendering
()
override
;
...
...
@@ -48,7 +49,6 @@ public:
QRegion
currentDamage
()
const
override
;
QSharedPointer
<
GLTexture
>
texture
()
const
;
DrmDisplayDevice
*
displayDevice
()
const
override
;
int
bufferAge
()
const
;
EGLSurface
eglSurface
()
const
;
...
...
@@ -59,6 +59,7 @@ private:
bool
doesSwapchainFit
(
DumbSwapchain
*
swapchain
)
const
;
void
sendDmabufFeedback
(
KWaylandServer
::
LinuxDmaBufV1ClientBuffer
*
failedBuffer
);
bool
renderTestBuffer
();
void
destroyResources
();
QSharedPointer
<
DrmBuffer
>
importBuffer
();
QSharedPointer
<
DrmBuffer
>
importDmabuf
();
...
...
@@ -88,8 +89,7 @@ private:
QSharedPointer
<
DumbSwapchain
>
m_importSwapchain
;
QSharedPointer
<
DumbSwapchain
>
m_oldImportSwapchain
;
DrmDisplayDevice
*
const
m_displayDevice
;
DrmGpu
*
const
m_renderGpu
;
EglGbmBackend
*
const
m_eglBackend
;
};
}
src/backends/drm/gbm_surface.cpp
View file @
b530a5b6
...
...
@@ -16,13 +16,14 @@
#include
"logging.h"
#include
"kwineglutils_p.h"
#include
"kwinglplatform.h"
#include
"drm_backend.h"
namespace
KWin
{
GbmSurface
::
GbmSurface
(
DrmGpu
*
gpu
,
const
QSize
&
size
,
uint32_t
format
,
uint32_t
flags
,
EGLConfig
config
)
:
m_surface
(
gbm_surface_create
(
gpu
->
gbmDevice
(),
size
.
width
(),
size
.
height
(),
format
,
flags
))
,
m_
gpu
(
gpu
)
,
m_
eglBackend
(
static_cast
<
EglGbmBackend
*>
(
gpu
->
platform
()
->
renderBackend
())
)
,
m_size
(
size
)
,
m_format
(
format
)
,
m_renderTarget
(
new
GLRenderTarget
(
0
,
size
))
...
...
@@ -31,7 +32,7 @@ GbmSurface::GbmSurface(DrmGpu *gpu, const QSize &size, uint32_t format, uint32_t
qCCritical
(
KWIN_DRM
)
<<
"Could not create gbm surface!"
<<
strerror
(
errno
);
return
;
}
m_eglSurface
=
eglCreatePlatformWindowSurfaceEXT
(
m_
gpu
->
eglDisplay
(),
config
,
m_surface
,
nullptr
);
m_eglSurface
=
eglCreatePlatformWindowSurfaceEXT
(
m_
eglBackend
->
eglDisplay
(),
config
,
m_surface
,
nullptr
);
if
(
m_eglSurface
==
EGL_NO_SURFACE
)
{
qCCritical
(
KWIN_DRM
)
<<
"Creating EGL surface failed!"
<<
getEglErrorString
();
}
...
...
@@ -39,7 +40,7 @@ GbmSurface::GbmSurface(DrmGpu *gpu, const QSize &size, uint32_t format, uint32_t
GbmSurface
::
GbmSurface
(
DrmGpu
*
gpu
,
const
QSize
&
size
,
uint32_t
format
,
QVector
<
uint64_t
>
modifiers
,
EGLConfig
config
)
:
m_surface
(
gbm_surface_create_with_modifiers
(
gpu
->
gbmDevice
(),
size
.
width
(),
size
.
height
(),
format
,
modifiers
.
isEmpty
()
?
nullptr
:
modifiers
.
constData
(),
modifiers
.
count
()))
,
m_
gpu
(
gpu
)
,
m_
eglBackend
(
static_cast
<
EglGbmBackend
*>
(
gpu
->
platform
()
->
renderBackend
())
)
,
m_size
(
size
)
,
m_format
(
format
)
,
m_modifiers
(
modifiers
)
...
...
@@ -49,7 +50,7 @@ GbmSurface::GbmSurface(DrmGpu *gpu, const QSize &size, uint32_t format, QVector<
qCCritical
(
KWIN_DRM
)
<<
"Could not create gbm surface!"
<<
strerror
(
errno
);
return
;
}
m_eglSurface
=
eglCreatePlatformWindowSurfaceEXT
(
m_
gpu
->
eglDisplay
(),
config
,
m_surface
,
nullptr
);
m_eglSurface
=
eglCreatePlatformWindowSurfaceEXT
(
m_
eglBackend
->
eglDisplay
(),
config
,
m_surface
,
nullptr
);
if
(
m_eglSurface
==
EGL_NO_SURFACE
)
{
qCCritical
(
KWIN_DRM
)
<<
"Creating EGL surface failed!"
<<
getEglErrorString
();
}
...
...
@@ -62,7 +63,7 @@ GbmSurface::~GbmSurface()
buffer
->
releaseBuffer
();
}
if
(
m_eglSurface
!=
EGL_NO_SURFACE
)
{
eglDestroySurface
(
m_
gpu
->
eglDisplay
(),
m_eglSurface
);
eglDestroySurface
(
m_
eglBackend
->
eglDisplay
(),
m_eglSurface
);
}