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
cdab4be1
Commit
cdab4be1
authored
Oct 25, 2020
by
Xaver Hugl
Committed by
Vlad Zahorodnii
Oct 25, 2020
Browse files
Automatically detect the proprietary NVidia driver and use EGLStreams accordingly
parent
6b940c12
Changes
7
Hide whitespace changes
Inline
Side-by-side
plugins/platforms/drm/drm_backend.cpp
View file @
cdab4be1
...
...
@@ -67,11 +67,6 @@ DrmBackend::DrmBackend(QObject *parent)
,
m_udevMonitor
(
m_udev
->
monitor
())
,
m_dpmsFilter
()
{
#if HAVE_EGL_STREAMS
if
(
qEnvironmentVariableIsSet
(
"KWIN_DRM_USE_EGL_STREAMS"
))
{
m_useEglStreams
=
true
;
}
#endif
setSupportsGammaControl
(
true
);
supportsOutputChanges
();
}
...
...
@@ -482,7 +477,7 @@ DrmOutput *DrmBackend::findOutput(quint32 connector)
bool
DrmBackend
::
present
(
DrmBuffer
*
buffer
,
DrmOutput
*
output
)
{
if
(
!
buffer
||
buffer
->
bufferId
()
==
0
)
{
if
(
m_
deleteBufferAfterPageFlip
)
{
if
(
output
->
gpu
()
->
deleteBufferAfterPageFlip
()
)
{
delete
buffer
;
}
return
false
;
...
...
@@ -494,7 +489,7 @@ bool DrmBackend::present(DrmBuffer *buffer, DrmOutput *output)
Compositor
::
self
()
->
aboutToSwapBuffers
();
}
return
true
;
}
else
if
(
m_
deleteBufferAfterPageFlip
)
{
}
else
if
(
output
->
gpu
()
->
deleteBufferAfterPageFlip
()
)
{
delete
buffer
;
}
return
false
;
...
...
@@ -506,9 +501,14 @@ void DrmBackend::initCursor()
#if HAVE_EGL_STREAMS
// Hardware cursors aren't currently supported with EGLStream backend,
// possibly an NVIDIA driver bug
if
(
m_useEglStreams
)
{
setSoftWareCursor
(
true
);
bool
needsSoftwareCursor
=
false
;
for
(
auto
gpu
:
qAsConst
(
m_gpus
))
{
if
(
gpu
->
useEglStreams
())
{
needsSoftwareCursor
=
true
;
break
;
}
}
setSoftWareCursor
(
needsSoftwareCursor
);
#endif
m_cursorEnabled
=
waylandServer
()
->
seat
()
->
hasPointer
();
...
...
@@ -604,21 +604,19 @@ Screens *DrmBackend::createScreens(QObject *parent)
QPainterBackend
*
DrmBackend
::
createQPainterBackend
()
{
m_
d
eleteBufferAfterPageFlip
=
false
;
m_
gpus
.
at
(
0
)
->
setD
eleteBufferAfterPageFlip
(
false
)
;
return
new
DrmQPainterBackend
(
this
,
m_gpus
.
at
(
0
));
}
OpenGLBackend
*
DrmBackend
::
createOpenGLBackend
()
{
#if HAVE_EGL_STREAMS
if
(
m_useEglStreams
)
{
m_deleteBufferAfterPageFlip
=
false
;
if
(
m_gpus
.
at
(
0
)
->
useEglStreams
())
{
return
new
EglStreamBackend
(
this
,
m_gpus
.
at
(
0
));
}
#endif
#if HAVE_GBM
m_deleteBufferAfterPageFlip
=
true
;
return
new
EglGbmBackend
(
this
,
m_gpus
.
at
(
0
));
#else
return
Platform
::
createOpenGLBackend
();
...
...
@@ -642,7 +640,7 @@ QVector<CompositingType> DrmBackend::supportedCompositors() const
#if HAVE_GBM
return
QVector
<
CompositingType
>
{
OpenGLCompositing
,
QPainterCompositing
};
#elif HAVE_EGL_STREAMS
return
m_useEglStreams
?
return
m_
gpus
.
at
(
0
)
->
useEglStreams
()
?
QVector
<
CompositingType
>
{
OpenGLCompositing
,
QPainterCompositing
}
:
QVector
<
CompositingType
>
{
QPainterCompositing
};
#else
...
...
@@ -661,7 +659,7 @@ QString DrmBackend::supportInformation() const
s
<<
"Atomic Mode Setting on GPU "
<<
g
<<
": "
<<
m_gpus
.
at
(
g
)
->
atomicModeSetting
()
<<
Qt
::
endl
;
}
#if HAVE_EGL_STREAMS
s
<<
"Using EGL Streams: "
<<
m_useEglStreams
<<
Qt
::
endl
;
s
<<
"Using EGL Streams: "
<<
m_
gpus
.
at
(
0
)
->
useEglStreams
()
<<
Qt
::
endl
;
#endif
return
supportInfo
;
}
...
...
plugins/platforms/drm/drm_backend.h
View file @
cdab4be1
...
...
@@ -78,17 +78,6 @@ public:
void
createDpmsFilter
();
void
checkOutputsAreOn
();
// QPainter reuses buffers
bool
deleteBufferAfterPageFlip
()
const
{
return
m_deleteBufferAfterPageFlip
;
}
#if HAVE_EGL_STREAMS
bool
useEglStreams
()
const
{
return
m_useEglStreams
;
}
#endif
QVector
<
CompositingType
>
supportedCompositors
()
const
override
;
QString
supportInformation
()
const
override
;
...
...
@@ -130,13 +119,9 @@ private:
// active and enabled pipelines (above + wl_output)
QVector
<
DrmOutput
*>
m_enabledOutputs
;
bool
m_deleteBufferAfterPageFlip
;
bool
m_cursorEnabled
=
false
;
int
m_pageFlipsPending
=
0
;
bool
m_active
=
false
;
#if HAVE_EGL_STREAMS
bool
m_useEglStreams
=
false
;
#endif
QVector
<
DrmGpu
*>
m_gpus
;
QScopedPointer
<
DpmsInputEventFilter
>
m_dpmsFilter
;
};
...
...
plugins/platforms/drm/drm_gpu.cpp
View file @
cdab4be1
...
...
@@ -32,7 +32,7 @@
namespace
KWin
{
DrmGpu
::
DrmGpu
(
DrmBackend
*
backend
,
QByteArray
devNode
,
int
fd
,
int
drmId
)
:
m_backend
(
backend
),
m_devNode
(
devNode
),
m_fd
(
fd
),
m_drmId
(
drmId
),
m_atomicModeSetting
(
false
),
m_useEglStreams
(
false
),
m_gbmDevice
(
nullptr
)
DrmGpu
::
DrmGpu
(
DrmBackend
*
backend
,
QByteArray
devNode
,
int
fd
,
int
drmId
)
:
m_backend
(
backend
),
m_devNode
(
devNode
),
m_fd
(
fd
),
m_drmId
(
drmId
),
m_atomicModeSetting
(
false
),
m_gbmDevice
(
nullptr
)
{
uint64_t
capability
=
0
;
...
...
@@ -47,6 +47,12 @@ DrmGpu::DrmGpu(DrmBackend *backend, QByteArray devNode, int fd, int drmId) : m_b
}
else
{
m_cursorSize
.
setHeight
(
64
);
}
// find out if this GPU is using the NVidia proprietary driver
DrmScopedPointer
<
drmVersion
>
version
(
drmGetVersion
(
fd
));
m_useEglStreams
=
strstr
(
version
->
name
,
"nvidia-drm"
);
m_deleteBufferAfterPageFlip
=
!
m_useEglStreams
;
}
DrmGpu
::~
DrmGpu
()
...
...
plugins/platforms/drm/drm_gpu.h
View file @
cdab4be1
...
...
@@ -54,6 +54,14 @@ public:
return
m_atomicModeSetting
;
}
bool
useEglStreams
()
const
{
return
m_useEglStreams
;
}
bool
deleteBufferAfterPageFlip
()
const
{
return
m_deleteBufferAfterPageFlip
;
}
QByteArray
devNode
()
const
{
return
m_devNode
;
}
...
...
@@ -78,6 +86,10 @@ public:
m_eglDisplay
=
display
;
}
void
setDeleteBufferAfterPageFlip
(
bool
deleteBuffer
)
{
m_deleteBufferAfterPageFlip
=
deleteBuffer
;
}
DrmDumbBuffer
*
createBuffer
(
const
QSize
&
size
)
const
{
return
new
DrmDumbBuffer
(
m_fd
,
size
);
}
...
...
@@ -105,6 +117,7 @@ private:
const
int
m_drmId
;
bool
m_atomicModeSetting
;
bool
m_useEglStreams
;
bool
m_deleteBufferAfterPageFlip
;
gbm_device
*
m_gbmDevice
;
EGLDisplay
m_eglDisplay
=
EGL_NO_DISPLAY
;
...
...
plugins/platforms/drm/drm_object_crtc.cpp
View file @
cdab4be1
...
...
@@ -67,7 +67,7 @@ bool DrmCrtc::initProps()
void
DrmCrtc
::
flipBuffer
()
{
if
(
m_currentBuffer
&&
m_
backend
->
deleteBufferAfterPageFlip
()
&&
m_currentBuffer
!=
m_nextBuffer
)
{
if
(
m_currentBuffer
&&
m_
gpu
->
deleteBufferAfterPageFlip
()
&&
m_currentBuffer
!=
m_nextBuffer
)
{
delete
m_currentBuffer
;
}
m_currentBuffer
=
m_nextBuffer
;
...
...
@@ -98,7 +98,7 @@ bool DrmCrtc::blank()
}
if
(
m_output
->
setModeLegacy
(
m_blackBuffer
))
{
if
(
m_currentBuffer
&&
m_
backend
->
deleteBufferAfterPageFlip
())
{
if
(
m_currentBuffer
&&
m_
gpu
->
deleteBufferAfterPageFlip
())
{
delete
m_currentBuffer
;
delete
m_nextBuffer
;
}
...
...
plugins/platforms/drm/drm_output.cpp
View file @
cdab4be1
...
...
@@ -65,7 +65,7 @@ void DrmOutput::teardown()
// TODO: when having multiple planes, also clean up these
m_primaryPlane
->
setOutput
(
nullptr
);
if
(
m_
backend
->
deleteBufferAfterPageFlip
())
{
if
(
m_
gpu
->
deleteBufferAfterPageFlip
())
{
delete
m_primaryPlane
->
current
();
}
m_primaryPlane
->
setCurrent
(
nullptr
);
...
...
@@ -694,7 +694,7 @@ void DrmOutput::pageFlipped()
}
// Egl based surface buffers get destroyed, QPainter based dumb buffers not
// TODO: split up DrmOutput in two for dumb and egl/gbm surface buffer compatible subclasses completely?
if
(
m_
backend
->
deleteBufferAfterPageFlip
())
{
if
(
m_
gpu
->
deleteBufferAfterPageFlip
())
{
if
(
m_gpu
->
atomicModeSetting
())
{
if
(
!
m_primaryPlane
->
next
())
{
// on manual vt switch
...
...
@@ -784,7 +784,7 @@ bool DrmOutput::presentAtomically(DrmBuffer *buffer)
}
#if HAVE_EGL_STREAMS
if
(
m_
backend
->
useEglStreams
()
&&
!
m_modesetRequested
)
{
if
(
m_
gpu
->
useEglStreams
()
&&
!
m_modesetRequested
)
{
// EglStreamBackend queues normal page flips through EGL,
// modesets are still performed through DRM-KMS
m_pageFlipPending
=
true
;
...
...
@@ -935,7 +935,7 @@ bool DrmOutput::doAtomicCommit(AtomicCommitMode mode)
}
#if HAVE_EGL_STREAMS
if
(
!
m_
backend
->
useEglStreams
())
if
(
!
m_
gpu
->
useEglStreams
())
// EglStreamBackend uses the NV_output_drm_flip_event EGL extension
// to register the flip event through eglStreamConsumerAcquireAttribNV
#endif
...
...
@@ -988,7 +988,7 @@ bool DrmOutput::atomicReqModesetPopulate(drmModeAtomicReq *req, bool enable)
m_primaryPlane
->
setValue
(
int
(
DrmPlane
::
PropertyIndex
::
CrtcH
),
mSize
.
height
());
m_primaryPlane
->
setValue
(
int
(
DrmPlane
::
PropertyIndex
::
CrtcId
),
m_crtc
->
id
());
}
else
{
if
(
m_
backend
->
deleteBufferAfterPageFlip
())
{
if
(
m_
gpu
->
deleteBufferAfterPageFlip
())
{
delete
m_primaryPlane
->
current
();
delete
m_primaryPlane
->
next
();
}
...
...
plugins/platforms/drm/drm_pointer.h
View file @
cdab4be1
...
...
@@ -13,6 +13,7 @@
#include
<QScopedPointer>
#include
<xf86drmMode.h>
#include
<xf86drm.h>
namespace
KWin
{
...
...
@@ -20,6 +21,15 @@ namespace KWin
template
<
typename
T
>
struct
DrmDeleter
;
template
<
>
struct
DrmDeleter
<
drmVersion
>
{
static
void
cleanup
(
drmVersion
*
version
)
{
drmFreeVersion
(
version
);
}
};
template
<
>
struct
DrmDeleter
<
drmModeAtomicReq
>
{
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment