[SceneQPainter] Per-Screen rendering
The backend can indicate that the rendering needs to be split per screen. In that case it has to provide a different rendering buffer per screen. The painting in the scene is adjusted to either take a splitted path or the existing path for all screens in one go.icc-effect-5.14.5
parent
600b3cd2c1
commit
9133c0f9d5
|
@ -25,6 +25,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#include "deleted.h"
|
#include "deleted.h"
|
||||||
#include "effects.h"
|
#include "effects.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
#include "screens.h"
|
||||||
#include "toplevel.h"
|
#include "toplevel.h"
|
||||||
#if HAVE_WAYLAND
|
#if HAVE_WAYLAND
|
||||||
#if HAVE_DRM
|
#if HAVE_DRM
|
||||||
|
@ -88,6 +89,17 @@ void QPainterBackend::renderCursor(QPainter *painter)
|
||||||
Q_UNUSED(painter)
|
Q_UNUSED(painter)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool QPainterBackend::perScreenRendering() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QImage *QPainterBackend::bufferForScreen(int screenId)
|
||||||
|
{
|
||||||
|
Q_UNUSED(screenId)
|
||||||
|
return buffer();
|
||||||
|
}
|
||||||
|
|
||||||
#if HAVE_WAYLAND
|
#if HAVE_WAYLAND
|
||||||
//****************************************
|
//****************************************
|
||||||
// WaylandQPainterBackend
|
// WaylandQPainterBackend
|
||||||
|
@ -452,6 +464,33 @@ qint64 SceneQPainter::paint(QRegion damage, ToplevelList toplevels)
|
||||||
|
|
||||||
int mask = 0;
|
int mask = 0;
|
||||||
m_backend->prepareRenderingFrame();
|
m_backend->prepareRenderingFrame();
|
||||||
|
if (m_backend->perScreenRendering()) {
|
||||||
|
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) {
|
||||||
|
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);
|
||||||
|
|
||||||
|
m_painter->restore();
|
||||||
|
m_painter->end();
|
||||||
|
}
|
||||||
|
m_backend->showOverlay();
|
||||||
|
m_backend->present(mask, overallUpdate);
|
||||||
|
} else {
|
||||||
m_painter->begin(m_backend->buffer());
|
m_painter->begin(m_backend->buffer());
|
||||||
if (m_backend->needsFullRepaint()) {
|
if (m_backend->needsFullRepaint()) {
|
||||||
mask |= Scene::PAINT_SCREEN_BACKGROUND_FIRST;
|
mask |= Scene::PAINT_SCREEN_BACKGROUND_FIRST;
|
||||||
|
@ -459,12 +498,14 @@ qint64 SceneQPainter::paint(QRegion damage, ToplevelList toplevels)
|
||||||
}
|
}
|
||||||
QRegion updateRegion, validRegion;
|
QRegion updateRegion, validRegion;
|
||||||
paintScreen(&mask, damage, QRegion(), &updateRegion, &validRegion);
|
paintScreen(&mask, damage, QRegion(), &updateRegion, &validRegion);
|
||||||
m_backend->renderCursor(m_painter.data());
|
|
||||||
|
|
||||||
|
m_backend->renderCursor(m_painter.data());
|
||||||
m_backend->showOverlay();
|
m_backend->showOverlay();
|
||||||
|
|
||||||
m_painter->end();
|
m_painter->end();
|
||||||
m_backend->present(mask, updateRegion);
|
m_backend->present(mask, updateRegion);
|
||||||
|
}
|
||||||
|
|
||||||
// do cleanup
|
// do cleanup
|
||||||
clearStackingOrder();
|
clearStackingOrder();
|
||||||
|
|
||||||
|
|
|
@ -94,8 +94,20 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual QImage *buffer() = 0;
|
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 bool needsFullRepaint() const = 0;
|
||||||
virtual void renderCursor(QPainter *painter);
|
virtual void renderCursor(QPainter *painter);
|
||||||
|
/**
|
||||||
|
* Whether the rendering needs to be split per screen.
|
||||||
|
* Default implementation returns @c false.
|
||||||
|
**/
|
||||||
|
virtual bool perScreenRendering() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QPainterBackend();
|
QPainterBackend();
|
||||||
|
|
Loading…
Reference in New Issue