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
94b731c1
Commit
94b731c1
authored
Nov 09, 2020
by
Vlad Zahorodnii
Browse files
Prepare QPainter render backend for per screen rendering
parent
edfb0a3f
Changes
13
Hide whitespace changes
Inline
Side-by-side
platformsupport/scenes/qpainter/backend.cpp
View file @
94b731c1
...
...
@@ -39,10 +39,4 @@ bool QPainterBackend::perScreenRendering() const
return
false
;
}
QImage
*
QPainterBackend
::
bufferForScreen
(
int
screenId
)
{
Q_UNUSED
(
screenId
)
return
buffer
();
}
}
platformsupport/scenes/qpainter/backend.h
View file @
94b731c1
...
...
@@ -21,8 +21,8 @@ class QPainterBackend
{
public:
virtual
~
QPainterBackend
();
virtual
void
present
(
int
mask
,
const
QRegion
&
damage
)
=
0
;
virtual
void
prepareRenderingFrame
()
=
0
;
virtual
void
present
(
int
screenId
,
int
mask
,
const
QRegion
&
damage
)
=
0
;
virtual
void
prepareRenderingFrame
(
int
screenId
)
=
0
;
/**
* @brief React on screen geometry changes.
*
...
...
@@ -42,16 +42,14 @@ public:
bool
isFailed
()
const
{
return
m_failed
;
}
virtual
QImage
*
buffer
()
=
0
;
/**
* Overload for the case that there is a different buffer per screen.
* Default implementation just calls buffer.
* @param screenId The id of the screen as used in Screens
* @todo Get a better identifier for screen then a counter variable
*/
virtual
QImage
*
bufferForScreen
(
int
screenId
);
virtual
bool
needsFullRepaint
()
const
=
0
;
virtual
QImage
*
bufferForScreen
(
int
screenId
)
=
0
;
virtual
bool
needsFullRepaint
(
int
screenId
)
const
=
0
;
/**
* Whether the rendering needs to be split per screen.
* Default implementation returns @c false.
...
...
plugins/platforms/drm/scene_qpainter_drm_backend.cpp
View file @
94b731c1
...
...
@@ -88,40 +88,34 @@ void DrmQPainterBackend::initOutput(DrmOutput *output)
m_outputs
<<
o
;
}
QImage
*
DrmQPainterBackend
::
buffer
()
{
return
bufferForScreen
(
0
);
}
QImage
*
DrmQPainterBackend
::
bufferForScreen
(
int
screenId
)
{
const
Output
&
o
=
m_outputs
.
at
(
screenId
);
return
o
.
buffer
[
o
.
index
]
->
image
();
}
bool
DrmQPainterBackend
::
needsFullRepaint
()
const
bool
DrmQPainterBackend
::
needsFullRepaint
(
int
screenId
)
const
{
Q_UNUSED
(
screenId
)
return
true
;
}
void
DrmQPainterBackend
::
prepareRenderingFrame
()
void
DrmQPainterBackend
::
prepareRenderingFrame
(
int
screenId
)
{
for
(
auto
it
=
m_outputs
.
begin
();
it
!=
m_outputs
.
end
();
++
it
)
{
(
*
it
).
index
=
((
*
it
).
index
+
1
)
%
2
;
}
Output
&
rendererOutput
=
m_outputs
[
screenId
];
rendererOutput
.
index
=
(
rendererOutput
.
index
+
1
)
%
2
;
}
void
DrmQPainterBackend
::
present
(
int
mask
,
const
QRegion
&
damage
)
void
DrmQPainterBackend
::
present
(
int
screenId
,
int
mask
,
const
QRegion
&
damage
)
{
Q_UNUSED
(
mask
)
Q_UNUSED
(
damage
)
if
(
!
LogindIntegration
::
self
()
->
isActiveSession
())
{
return
;
}
for
(
auto
it
=
m_outputs
.
begin
();
it
!=
m_outputs
.
end
();
++
it
)
{
const
Output
&
o
=
*
it
;
m_backend
->
present
(
o
.
buffer
[
o
.
index
],
o
.
output
);
}
const
Output
&
rendererOutput
=
m_outputs
[
screenId
];
m_backend
->
present
(
rendererOutput
.
buffer
[
rendererOutput
.
index
],
rendererOutput
.
output
);
}
bool
DrmQPainterBackend
::
perScreenRendering
()
const
...
...
plugins/platforms/drm/scene_qpainter_drm_backend.h
View file @
94b731c1
...
...
@@ -27,11 +27,10 @@ public:
DrmQPainterBackend
(
DrmBackend
*
backend
,
DrmGpu
*
gpu
);
~
DrmQPainterBackend
()
override
;
QImage
*
buffer
()
override
;
QImage
*
bufferForScreen
(
int
screenId
)
override
;
bool
needsFullRepaint
()
const
override
;
void
prepareRenderingFrame
()
override
;
void
present
(
int
mask
,
const
QRegion
&
damage
)
override
;
bool
needsFullRepaint
(
int
screenId
)
const
override
;
void
prepareRenderingFrame
(
int
screenId
)
override
;
void
present
(
int
screenId
,
int
mask
,
const
QRegion
&
damage
)
override
;
bool
perScreenRendering
()
const
override
;
private:
...
...
plugins/platforms/fbdev/scene_qpainter_fb_backend.cpp
View file @
94b731c1
...
...
@@ -47,29 +47,27 @@ FramebufferQPainterBackend::FramebufferQPainterBackend(FramebufferBackend *backe
FramebufferQPainterBackend
::~
FramebufferQPainterBackend
()
=
default
;
QImage
*
FramebufferQPainterBackend
::
buffer
()
{
return
bufferForScreen
(
0
);
}
QImage
*
FramebufferQPainterBackend
::
bufferForScreen
(
int
screenId
)
{
Q_UNUSED
(
screenId
)
return
&
m_renderBuffer
;
}
bool
FramebufferQPainterBackend
::
needsFullRepaint
()
const
bool
FramebufferQPainterBackend
::
needsFullRepaint
(
int
screenId
)
const
{
Q_UNUSED
(
screenId
)
return
m_needsFullRepaint
;
}
void
FramebufferQPainterBackend
::
prepareRenderingFrame
()
void
FramebufferQPainterBackend
::
prepareRenderingFrame
(
int
screenId
)
{
Q_UNUSED
(
screenId
)
m_needsFullRepaint
=
true
;
}
void
FramebufferQPainterBackend
::
present
(
int
mask
,
const
QRegion
&
damage
)
void
FramebufferQPainterBackend
::
present
(
int
screenId
,
int
mask
,
const
QRegion
&
damage
)
{
Q_UNUSED
(
screenId
)
Q_UNUSED
(
mask
)
Q_UNUSED
(
damage
)
...
...
plugins/platforms/fbdev/scene_qpainter_fb_backend.h
View file @
94b731c1
...
...
@@ -24,11 +24,10 @@ public:
FramebufferQPainterBackend
(
FramebufferBackend
*
backend
);
~
FramebufferQPainterBackend
()
override
;
QImage
*
buffer
()
override
;
QImage
*
bufferForScreen
(
int
screenId
)
override
;
bool
needsFullRepaint
()
const
override
;
void
prepareRenderingFrame
()
override
;
void
present
(
int
mask
,
const
QRegion
&
damage
)
override
;
bool
needsFullRepaint
(
int
screenId
)
const
override
;
void
prepareRenderingFrame
(
int
screenId
)
override
;
void
present
(
int
screenId
,
int
mask
,
const
QRegion
&
damage
)
override
;
bool
perScreenRendering
()
const
override
;
private:
...
...
plugins/platforms/virtual/scene_qpainter_virtual_backend.cpp
View file @
94b731c1
...
...
@@ -25,23 +25,20 @@ VirtualQPainterBackend::VirtualQPainterBackend(VirtualBackend *backend)
VirtualQPainterBackend
::~
VirtualQPainterBackend
()
=
default
;
QImage
*
VirtualQPainterBackend
::
buffer
()
{
return
&
m_backBuffers
[
0
];
}
QImage
*
VirtualQPainterBackend
::
bufferForScreen
(
int
screen
)
{
return
&
m_backBuffers
[
screen
];
}
bool
VirtualQPainterBackend
::
needsFullRepaint
()
const
bool
VirtualQPainterBackend
::
needsFullRepaint
(
int
screenId
)
const
{
Q_UNUSED
(
screenId
)
return
true
;
}
void
VirtualQPainterBackend
::
prepareRenderingFrame
()
void
VirtualQPainterBackend
::
prepareRenderingFrame
(
int
screenId
)
{
Q_UNUSED
(
screenId
)
}
void
VirtualQPainterBackend
::
createOutputs
()
...
...
@@ -54,14 +51,12 @@ void VirtualQPainterBackend::createOutputs()
}
}
void
VirtualQPainterBackend
::
present
(
int
mask
,
const
QRegion
&
damage
)
void
VirtualQPainterBackend
::
present
(
int
screenId
,
int
mask
,
const
QRegion
&
damage
)
{
Q_UNUSED
(
mask
)
Q_UNUSED
(
damage
)
if
(
m_backend
->
saveFrames
())
{
for
(
int
i
=
0
;
i
<
m_backBuffers
.
size
()
;
i
++
)
{
m_backBuffers
[
i
].
save
(
QStringLiteral
(
"%1/screen%2-%3.png"
).
arg
(
m_backend
->
screenshotDirPath
(),
QString
::
number
(
i
),
QString
::
number
(
m_frameCounter
++
)));
}
m_backBuffers
[
screenId
].
save
(
QStringLiteral
(
"%1/screen%2-%3.png"
).
arg
(
m_backend
->
screenshotDirPath
(),
QString
::
number
(
screenId
),
QString
::
number
(
m_frameCounter
++
)));
}
}
...
...
plugins/platforms/virtual/scene_qpainter_virtual_backend.h
View file @
94b731c1
...
...
@@ -26,11 +26,10 @@ public:
VirtualQPainterBackend
(
VirtualBackend
*
backend
);
~
VirtualQPainterBackend
()
override
;
QImage
*
buffer
()
override
;
QImage
*
bufferForScreen
(
int
screenId
)
override
;
bool
needsFullRepaint
()
const
override
;
void
prepareRenderingFrame
()
override
;
void
present
(
int
mask
,
const
QRegion
&
damage
)
override
;
bool
needsFullRepaint
(
int
screenId
)
const
override
;
void
prepareRenderingFrame
(
int
screenId
)
override
;
void
present
(
int
screenId
,
int
mask
,
const
QRegion
&
damage
)
override
;
bool
perScreenRendering
()
const
override
;
private:
...
...
plugins/platforms/wayland/scene_qpainter_wayland_backend.cpp
View file @
94b731c1
...
...
@@ -36,6 +36,16 @@ WaylandQPainterOutput::~WaylandQPainterOutput()
}
}
bool
WaylandQPainterOutput
::
needsFullRepaint
()
const
{
return
m_needsFullRepaint
;
}
void
WaylandQPainterOutput
::
setNeedsFullRepaint
(
bool
set
)
{
m_needsFullRepaint
=
set
;
}
bool
WaylandQPainterOutput
::
init
(
KWayland
::
Client
::
ShmPool
*
pool
)
{
m_pool
=
pool
;
...
...
@@ -111,10 +121,14 @@ void WaylandQPainterOutput::prepareRenderingFrame()
// qCDebug(KWIN_WAYLAND_BACKEND) << "Created a new back buffer for output surface" << m_waylandOutput->surface();
}
QRegion
WaylandQPainterOutput
::
mapToLocal
(
const
QRegion
&
region
)
const
{
return
region
.
translated
(
-
m_waylandOutput
->
geometry
().
topLeft
());
}
WaylandQPainterBackend
::
WaylandQPainterBackend
(
Wayland
::
WaylandBackend
*
b
)
:
QPainterBackend
()
,
m_backend
(
b
)
,
m_needsFullRepaint
(
true
)
{
const
auto
waylandOutputs
=
m_backend
->
waylandOutputs
();
...
...
@@ -154,21 +168,19 @@ void WaylandQPainterBackend::createOutput(WaylandOutput *waylandOutput)
m_outputs
<<
output
;
}
void
WaylandQPainterBackend
::
present
(
int
mask
,
const
QRegion
&
damage
)
void
WaylandQPainterBackend
::
present
(
int
screenId
,
int
mask
,
const
QRegion
&
damage
)
{
Q_UNUSED
(
mask
)
Compositor
::
self
()
->
aboutToSwapBuffers
(
);
m_needsFullRepaint
=
false
;
WaylandQPainterOutput
*
rendererOutput
=
m_outputs
.
value
(
screenId
);
Q_ASSERT
(
rendererOutput
)
;
for
(
auto
*
output
:
m_outputs
)
{
output
->
present
(
damage
);
if
(
screenId
==
0
)
{
Compositor
::
self
()
->
aboutToSwapBuffers
(
);
}
}
QImage
*
WaylandQPainterBackend
::
buffer
()
{
return
bufferForScreen
(
0
);
rendererOutput
->
setNeedsFullRepaint
(
false
);
rendererOutput
->
present
(
rendererOutput
->
mapToLocal
(
damage
));
}
QImage
*
WaylandQPainterBackend
::
bufferForScreen
(
int
screenId
)
...
...
@@ -177,17 +189,20 @@ QImage *WaylandQPainterBackend::bufferForScreen(int screenId)
return
&
output
->
m_backBuffer
;
}
void
WaylandQPainterBackend
::
prepareRenderingFrame
()
void
WaylandQPainterBackend
::
prepareRenderingFrame
(
int
screenId
)
{
for
(
auto
*
output
:
m_outputs
)
{
output
->
prepareRenderingFrame
();
}
m_needsFullRepaint
=
true
;
WaylandQPainterOutput
*
rendererOutput
=
m_outputs
.
value
(
screenId
);
Q_ASSERT
(
rendererOutput
);
rendererOutput
->
prepareRenderingFrame
();
rendererOutput
->
setNeedsFullRepaint
(
true
);
}
bool
WaylandQPainterBackend
::
needsFullRepaint
()
const
bool
WaylandQPainterBackend
::
needsFullRepaint
(
int
screenId
)
const
{
return
m_needsFullRepaint
;
const
WaylandQPainterOutput
*
rendererOutput
=
m_outputs
.
value
(
screenId
);
Q_ASSERT
(
rendererOutput
);
return
rendererOutput
->
needsFullRepaint
();
}
}
...
...
plugins/platforms/wayland/scene_qpainter_wayland_backend.h
View file @
94b731c1
...
...
@@ -47,12 +47,18 @@ public:
void
prepareRenderingFrame
();
void
present
(
const
QRegion
&
damage
);
bool
needsFullRepaint
()
const
;
void
setNeedsFullRepaint
(
bool
set
);
QRegion
mapToLocal
(
const
QRegion
&
region
)
const
;
private:
WaylandOutput
*
m_waylandOutput
;
KWayland
::
Client
::
ShmPool
*
m_pool
;
QWeakPointer
<
KWayland
::
Client
::
Buffer
>
m_buffer
;
QImage
m_backBuffer
;
bool
m_needsFullRepaint
=
true
;
friend
class
WaylandQPainterBackend
;
};
...
...
@@ -64,13 +70,12 @@ public:
explicit
WaylandQPainterBackend
(
WaylandBackend
*
b
);
~
WaylandQPainterBackend
()
override
;
QImage
*
buffer
()
override
;
QImage
*
bufferForScreen
(
int
screenId
)
override
;
void
present
(
int
mask
,
const
QRegion
&
damage
)
override
;
void
prepareRenderingFrame
()
override
;
void
present
(
int
screenId
,
int
mask
,
const
QRegion
&
damage
)
override
;
void
prepareRenderingFrame
(
int
screenId
)
override
;
bool
needsFullRepaint
()
const
override
;
bool
needsFullRepaint
(
int
screenId
)
const
override
;
bool
perScreenRendering
()
const
override
;
private:
...
...
@@ -78,8 +83,6 @@ private:
void
frameRendered
();
WaylandBackend
*
m_backend
;
bool
m_needsFullRepaint
;
QVector
<
WaylandQPainterOutput
*>
m_outputs
;
};
...
...
plugins/platforms/x11/windowed/scene_qpainter_x11_backend.cpp
View file @
94b731c1
...
...
@@ -39,12 +39,6 @@ void X11WindowedQPainterBackend::createOutputs()
output
->
buffer
.
fill
(
Qt
::
black
);
m_outputs
<<
output
;
}
m_needsFullRepaint
=
true
;
}
QImage
*
X11WindowedQPainterBackend
::
buffer
()
{
return
bufferForScreen
(
0
);
}
QImage
*
X11WindowedQPainterBackend
::
bufferForScreen
(
int
screen
)
...
...
@@ -52,16 +46,19 @@ QImage *X11WindowedQPainterBackend::bufferForScreen(int screen)
return
&
m_outputs
.
at
(
screen
)
->
buffer
;
}
bool
X11WindowedQPainterBackend
::
needsFullRepaint
()
const
bool
X11WindowedQPainterBackend
::
needsFullRepaint
(
int
screenId
)
const
{
return
m_needsFullRepaint
;
const
Output
*
rendererOutput
=
m_outputs
.
value
(
screenId
);
Q_ASSERT
(
rendererOutput
);
return
rendererOutput
->
needsFullRepaint
;
}
void
X11WindowedQPainterBackend
::
prepareRenderingFrame
()
void
X11WindowedQPainterBackend
::
prepareRenderingFrame
(
int
screenId
)
{
Q_UNUSED
(
screenId
)
}
void
X11WindowedQPainterBackend
::
present
(
int
mask
,
const
QRegion
&
damage
)
void
X11WindowedQPainterBackend
::
present
(
int
screenId
,
int
mask
,
const
QRegion
&
damage
)
{
Q_UNUSED
(
mask
)
Q_UNUSED
(
damage
)
...
...
@@ -71,13 +68,17 @@ void X11WindowedQPainterBackend::present(int mask, const QRegion &damage)
m_gc
=
xcb_generate_id
(
c
);
xcb_create_gc
(
c
,
m_gc
,
window
,
0
,
nullptr
);
}
for
(
auto
it
=
m_outputs
.
constBegin
();
it
!=
m_outputs
.
constEnd
();
++
it
)
{
// TODO: only update changes?
const
QImage
&
buffer
=
(
*
it
)
->
buffer
;
xcb_put_image
(
c
,
XCB_IMAGE_FORMAT_Z_PIXMAP
,
(
*
it
)
->
window
,
m_gc
,
buffer
.
width
(),
buffer
.
height
(),
0
,
0
,
0
,
24
,
buffer
.
sizeInBytes
(),
buffer
.
constBits
());
}
Output
*
rendererOutput
=
m_outputs
.
value
(
screenId
);
Q_ASSERT
(
rendererOutput
);
// TODO: only update changes?
const
QImage
&
buffer
=
rendererOutput
->
buffer
;
xcb_put_image
(
c
,
XCB_IMAGE_FORMAT_Z_PIXMAP
,
rendererOutput
->
window
,
m_gc
,
buffer
.
width
(),
buffer
.
height
(),
0
,
0
,
0
,
24
,
buffer
.
sizeInBytes
(),
buffer
.
constBits
());
rendererOutput
->
needsFullRepaint
=
false
;
}
bool
X11WindowedQPainterBackend
::
perScreenRendering
()
const
...
...
plugins/platforms/x11/windowed/scene_qpainter_x11_backend.h
View file @
94b731c1
...
...
@@ -29,21 +29,20 @@ public:
X11WindowedQPainterBackend
(
X11WindowedBackend
*
backend
);
~
X11WindowedQPainterBackend
()
override
;
QImage
*
buffer
()
override
;
QImage
*
bufferForScreen
(
int
screenId
)
override
;
bool
needsFullRepaint
()
const
override
;
void
prepareRenderingFrame
()
override
;
void
present
(
int
mask
,
const
QRegion
&
damage
)
override
;
bool
needsFullRepaint
(
int
screenId
)
const
override
;
void
prepareRenderingFrame
(
int
screenId
)
override
;
void
present
(
int
screenId
,
int
mask
,
const
QRegion
&
damage
)
override
;
bool
perScreenRendering
()
const
override
;
private:
void
createOutputs
();
bool
m_needsFullRepaint
=
true
;
xcb_gcontext_t
m_gc
=
XCB_NONE
;
X11WindowedBackend
*
m_backend
;
struct
Output
{
xcb_window_t
window
;
QImage
buffer
;
bool
needsFullRepaint
=
true
;
};
QVector
<
Output
*>
m_outputs
;
};
...
...
plugins/scenes/qpainter/scene_qpainter.cpp
View file @
94b731c1
...
...
@@ -90,34 +90,31 @@ qint64 SceneQPainter::paint(const QRegion &_damage, const QList<Toplevel *> &top
createStackingOrder
(
toplevels
);
QRegion
damage
=
_damage
;
int
mask
=
0
;
m_backend
->
prepareRenderingFrame
();
const
bool
needsFullRepaint
=
m_backend
->
needsFullRepaint
();
if
(
needsFullRepaint
)
{
mask
|=
Scene
::
PAINT_SCREEN_BACKGROUND_FIRST
;
damage
=
screens
()
->
geometry
();
}
QRegion
overallUpdate
;
for
(
int
i
=
0
;
i
<
screens
()
->
count
();
++
i
)
{
int
mask
=
0
;
painted_screen
=
i
;
m_backend
->
prepareRenderingFrame
(
i
);
const
bool
needsFullRepaint
=
m_backend
->
needsFullRepaint
(
i
);
if
(
needsFullRepaint
)
{
mask
|=
Scene
::
PAINT_SCREEN_BACKGROUND_FIRST
;
damage
=
screens
()
->
geometry
();
}
const
QRect
geometry
=
screens
()
->
geometry
(
i
);
QImage
*
buffer
=
m_backend
->
bufferForScreen
(
i
);
if
(
!
buffer
||
buffer
->
isNull
())
{
continue
;
}
m_painter
->
begin
(
buffer
);
m_painter
->
save
();
m_painter
->
setWindow
(
geometry
);
QRegion
updateRegion
,
validRegion
;
paintScreen
(
&
mask
,
damage
.
intersected
(
geometry
),
QRegion
(),
&
updateRegion
,
&
validRegion
);
overallUpdate
=
overallUpdate
.
united
(
updateRegion
);
paintCursor
(
updateRegion
);
m_painter
->
restore
();
m_painter
->
end
();
m_backend
->
present
(
i
,
mask
,
updateRegion
);
}
m_backend
->
present
(
mask
,
overallUpdate
);
// do cleanup
clearStackingOrder
();
...
...
@@ -184,7 +181,7 @@ void SceneQPainter::screenGeometryChanged(const QSize &size)
QImage
*
SceneQPainter
::
qpainterRenderBuffer
()
const
{
return
m_backend
->
buffer
(
);
return
m_backend
->
buffer
ForScreen
(
0
);
}
//****************************************
...
...
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