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
9dc4c730
Commit
9dc4c730
authored
Dec 21, 2021
by
Xaver Hugl
Committed by
Vlad Zahorodnii
Feb 15, 2022
Browse files
backends/drm: move damage tracking into DumbSwapchain
parent
5d317641
Changes
7
Hide whitespace changes
Inline
Side-by-side
src/backends/drm/dumb_swapchain.cpp
View file @
9dc4c730
...
...
@@ -30,20 +30,21 @@ DumbSwapchain::DumbSwapchain(DrmGpu *gpu, const QSize &size, uint32_t drmFormat,
buffer
->
image
()
->
fill
(
Qt
::
black
);
m_slots
.
append
(
Slot
{.
buffer
=
buffer
,
.
age
=
0
,});
}
m_damageJournal
.
setCapacity
(
2
);
if
(
m_slots
.
count
()
<
2
)
{
qCWarning
(
KWIN_DRM
)
<<
"Failed to create dumb buffers for swapchain!"
;
m_slots
.
clear
();
}
}
QSharedPointer
<
DrmDumbBuffer
>
DumbSwapchain
::
acquireBuffer
(
int
*
age
)
QSharedPointer
<
DrmDumbBuffer
>
DumbSwapchain
::
acquireBuffer
(
const
QRect
&
geometry
,
QRegion
*
needsRepaint
)
{
if
(
m_slots
.
isEmpty
())
{
return
nullptr
;
return
{}
;
}
index
=
(
index
+
1
)
%
m_slots
.
count
();
if
(
age
)
{
*
age
=
m_slots
[
index
].
age
;
if
(
needsRepaint
)
{
*
needsRepaint
=
m_damageJournal
.
accumulate
(
m_slots
[
index
].
age
,
geometry
)
;
}
return
m_slots
[
index
].
buffer
;
}
...
...
@@ -53,7 +54,7 @@ QSharedPointer<DrmDumbBuffer> DumbSwapchain::currentBuffer() const
return
m_slots
[
index
].
buffer
;
}
void
DumbSwapchain
::
releaseBuffer
(
QSharedPointer
<
DrmDumbBuffer
>
buffer
)
void
DumbSwapchain
::
releaseBuffer
(
QSharedPointer
<
DrmDumbBuffer
>
buffer
,
const
QRegion
&
damage
)
{
Q_ASSERT
(
m_slots
[
index
].
buffer
==
buffer
);
...
...
@@ -64,6 +65,7 @@ void DumbSwapchain::releaseBuffer(QSharedPointer<DrmDumbBuffer> buffer)
m_slots
[
i
].
age
++
;
}
}
m_damageJournal
.
add
(
damage
);
}
uint32_t
DumbSwapchain
::
drmFormat
()
const
...
...
src/backends/drm/dumb_swapchain.h
View file @
9dc4c730
...
...
@@ -9,6 +9,8 @@
#pragma once
#include
"utils/common.h"
#include
<QVector>
#include
<QSize>
#include
<QSharedPointer>
...
...
@@ -25,9 +27,9 @@ class DumbSwapchain
public:
DumbSwapchain
(
DrmGpu
*
gpu
,
const
QSize
&
size
,
uint32_t
drmFormat
,
QImage
::
Format
imageFormat
=
QImage
::
Format_RGB32
);
QSharedPointer
<
DrmDumbBuffer
>
acquireBuffer
(
int
*
age
=
nullptr
);
QSharedPointer
<
DrmDumbBuffer
>
acquireBuffer
(
const
QRect
&
geometry
=
{},
QRegion
*
needsRepaint
=
nullptr
);
QSharedPointer
<
DrmDumbBuffer
>
currentBuffer
()
const
;
void
releaseBuffer
(
QSharedPointer
<
DrmDumbBuffer
>
buffer
);
void
releaseBuffer
(
QSharedPointer
<
DrmDumbBuffer
>
buffer
,
const
QRegion
&
damage
=
{}
);
qsizetype
slotCount
()
const
;
QSize
size
()
const
;
...
...
@@ -45,6 +47,7 @@ private:
int
index
=
0
;
uint32_t
m_format
;
QVector
<
Slot
>
m_slots
;
DamageJournal
m_damageJournal
;
};
}
src/backends/drm/egl_gbm_backend.cpp
View file @
9dc4c730
...
...
@@ -70,7 +70,7 @@ void EglGbmBackend::cleanupSurfaces()
void
EglGbmBackend
::
cleanupRenderData
(
Output
::
RenderData
&
render
)
{
if
(
render
.
shadowBuffer
)
{
render
.
gbmSurface
->
makeContextCurrent
(
{}
);
render
.
gbmSurface
->
makeContextCurrent
();
render
.
shadowBuffer
=
nullptr
;
}
render
.
importSwapchain
=
nullptr
;
...
...
@@ -198,7 +198,7 @@ bool EglGbmBackend::resetOutput(Output &output)
if
(
!
output
.
output
->
needsSoftwareTransformation
())
{
output
.
current
.
shadowBuffer
=
nullptr
;
}
else
{
output
.
current
.
gbmSurface
->
makeContextCurrent
(
{}
);
output
.
current
.
gbmSurface
->
makeContextCurrent
();
output
.
current
.
shadowBuffer
=
QSharedPointer
<
ShadowBuffer
>::
create
(
output
.
output
->
sourceSize
(),
output
.
current
.
format
);
if
(
!
output
.
current
.
shadowBuffer
->
isComplete
())
{
return
false
;
...
...
@@ -553,12 +553,12 @@ QRegion EglGbmBackend::prepareRenderingForOutput(Output &output)
}
}
auto
&
current
=
output
.
current
;
const
auto
needsRepaint
=
current
.
gbmSurface
->
makeContextCurrent
(
output
.
output
->
geometry
()
);
current
.
gbmSurface
->
makeContextCurrent
();
if
(
current
.
shadowBuffer
)
{
current
.
shadowBuffer
->
bind
();
}
setViewport
(
output
);
return
needsRepaint
;
return
current
.
gbmSurface
->
repaintRegion
(
output
.
output
->
geometry
())
;
}
QSharedPointer
<
DrmBuffer
>
EglGbmBackend
::
endFrameWithBuffer
(
AbstractOutput
*
drmOutput
,
const
QRegion
&
dirty
)
...
...
src/backends/drm/gbm_surface.cpp
View file @
9dc4c730
...
...
@@ -67,20 +67,16 @@ GbmSurface::~GbmSurface()
}
}
QRegion
GbmSurface
::
makeContextCurrent
(
const
QRect
&
geometry
)
const
bool
GbmSurface
::
makeContextCurrent
()
const
{
if
(
eglMakeCurrent
(
m_gpu
->
eglDisplay
(),
m_eglSurface
,
m_eglSurface
,
m_gpu
->
eglBackend
()
->
context
())
==
EGL_FALSE
)
{
qCCritical
(
KWIN_DRM
)
<<
"eglMakeCurrent failed:"
<<
getEglErrorString
();
return
{}
;
return
false
;
}
if
(
!
GLPlatform
::
instance
()
->
isGLES
())
{
glDrawBuffer
(
GL_BACK
);
}
if
(
m_gpu
->
eglBackend
()
->
supportsBufferAge
())
{
return
m_damageJournal
.
accumulate
(
m_bufferAge
,
geometry
);
}
else
{
return
geometry
;
}
return
true
;
}
QSharedPointer
<
DrmGbmBuffer
>
GbmSurface
::
swapBuffersForDrm
(
const
QRegion
&
dirty
)
...
...
@@ -174,4 +170,13 @@ int GbmSurface::bufferAge() const
return
m_bufferAge
;
}
QRegion
GbmSurface
::
repaintRegion
(
const
QRect
&
geometry
)
const
{
if
(
m_gpu
->
eglBackend
()
->
supportsBufferAge
())
{
return
m_damageJournal
.
accumulate
(
m_bufferAge
,
geometry
);
}
else
{
return
geometry
;
}
}
}
src/backends/drm/gbm_surface.h
View file @
9dc4c730
...
...
@@ -29,8 +29,7 @@ public:
explicit
GbmSurface
(
DrmGpu
*
gpu
,
const
QSize
&
size
,
uint32_t
format
,
QVector
<
uint64_t
>
modifiers
,
EGLConfig
config
);
~
GbmSurface
();
QRegion
makeContextCurrent
(
const
QRect
&
geometry
)
const
;
bool
makeContextCurrent
()
const
;
QSharedPointer
<
DrmGbmBuffer
>
swapBuffersForDrm
(
const
QRegion
&
dirty
);
QSharedPointer
<
GbmBuffer
>
swapBuffers
(
const
QRegion
&
dirty
);
void
releaseBuffer
(
GbmBuffer
*
buffer
);
...
...
@@ -44,6 +43,7 @@ public:
uint32_t
format
()
const
;
QVector
<
uint64_t
>
modifiers
()
const
;
int
bufferAge
()
const
;
QRegion
repaintRegion
(
const
QRect
&
geometry
)
const
;
private:
gbm_surface
*
m_surface
;
...
...
src/backends/drm/scene_qpainter_drm_backend.cpp
View file @
9dc4c730
...
...
@@ -30,61 +30,39 @@ DrmQPainterBackend::DrmQPainterBackend(DrmBackend *backend, DrmGpu *gpu)
connect
(
m_gpu
,
&
DrmGpu
::
outputEnabled
,
this
,
&
DrmQPainterBackend
::
initOutput
);
connect
(
m_gpu
,
&
DrmGpu
::
outputDisabled
,
this
,
[
this
]
(
DrmAbstractOutput
*
o
)
{
auto
it
=
std
::
find_if
(
m_outputs
.
begin
(),
m_outputs
.
end
(),
[
o
]
(
const
Output
&
output
)
{
return
output
.
output
==
o
;
}
);
if
(
it
==
m_outputs
.
end
())
{
return
;
}
m_outputs
.
erase
(
it
);
m_swapchains
.
remove
(
o
);
}
);
}
void
DrmQPainterBackend
::
initOutput
(
DrmAbstractOutput
*
output
)
{
Output
o
;
o
.
swapchain
=
QSharedPointer
<
DumbSwapchain
>::
create
(
m_gpu
,
output
->
sourceSize
(),
DRM_FORMAT_XRGB8888
);
o
.
output
=
output
;
m_outputs
.
insert
(
output
,
o
);
m_swapchains
.
insert
(
output
,
QSharedPointer
<
DumbSwapchain
>::
create
(
m_gpu
,
output
->
sourceSize
(),
DRM_FORMAT_XRGB8888
));
connect
(
output
,
&
DrmOutput
::
currentModeChanged
,
this
,
[
output
,
this
]
{
auto
&
o
=
m_outputs
[
output
];
o
.
swapchain
=
QSharedPointer
<
DumbSwapchain
>::
create
(
m_gpu
,
output
->
sourceSize
(),
DRM_FORMAT_XRGB8888
);
o
.
damageJournal
.
setCapacity
(
o
.
swapchain
->
slotCount
());
m_swapchains
[
output
]
=
QSharedPointer
<
DumbSwapchain
>::
create
(
m_gpu
,
output
->
sourceSize
(),
DRM_FORMAT_XRGB8888
);
}
);
}
QImage
*
DrmQPainterBackend
::
bufferForScreen
(
AbstractOutput
*
output
)
{
return
m_
outputs
[
output
].
swapchain
->
currentBuffer
()
->
image
();
return
m_swapchain
s
[
output
]
->
currentBuffer
()
->
image
();
}
QRegion
DrmQPainterBackend
::
beginFrame
(
AbstractOutput
*
output
)
{
Output
*
rendererOutput
=
&
m_outputs
[
output
];
int
bufferAge
;
rendererOutput
->
swapchain
->
acquireBuffer
(
&
bufferAge
);
return
rendererOutput
->
damageJournal
.
accumulate
(
bufferAge
,
rendererOutput
->
output
->
geometry
());
QRegion
needsRepainting
;
m_swapchains
[
output
]
->
acquireBuffer
(
output
->
geometry
(),
&
needsRepainting
);
return
needsRepainting
;
}
void
DrmQPainterBackend
::
endFrame
(
AbstractOutput
*
output
,
const
QRegion
&
renderedRegion
,
const
QRegion
&
damage
)
{
Q_UNUSED
(
renderedRegion
)
Output
&
rendererOutput
=
m_outputs
[
output
];
DrmAbstractOutput
*
drmOutput
=
rendererOutput
.
output
;
QSharedPointer
<
DrmDumbBuffer
>
back
=
rendererOutput
.
swapchain
->
currentBuffer
();
rendererOutput
.
swapchain
->
releaseBuffer
(
back
);
drmOutput
->
present
(
back
,
drmOutput
->
geometry
());
rendererOutput
.
damageJournal
.
add
(
damage
);
QSharedPointer
<
DrmDumbBuffer
>
back
=
m_swapchains
[
output
]
->
currentBuffer
();
m_swapchains
[
output
]
->
releaseBuffer
(
back
,
damage
);
static_cast
<
DrmAbstractOutput
*>
(
output
)
->
present
(
back
,
output
->
geometry
());
}
}
src/backends/drm/scene_qpainter_drm_backend.h
View file @
9dc4c730
...
...
@@ -9,7 +9,6 @@
#ifndef KWIN_SCENE_QPAINTER_DRM_BACKEND_H
#define KWIN_SCENE_QPAINTER_DRM_BACKEND_H
#include
"qpainterbackend.h"
#include
"utils/common.h"
#include
<QObject>
#include
<QVector>
...
...
@@ -37,12 +36,7 @@ public:
private:
void
initOutput
(
DrmAbstractOutput
*
output
);
struct
Output
{
DrmAbstractOutput
*
output
;
QSharedPointer
<
DumbSwapchain
>
swapchain
;
DamageJournal
damageJournal
;
};
QMap
<
AbstractOutput
*
,
Output
>
m_outputs
;
QMap
<
AbstractOutput
*
,
QSharedPointer
<
DumbSwapchain
>>
m_swapchains
;
DrmBackend
*
m_backend
;
DrmGpu
*
m_gpu
;
};
...
...
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