[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.
This commit is contained in:
parent
600b3cd2c1
commit
9133c0f9d5
2 changed files with 64 additions and 11 deletions
|
@ -25,6 +25,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include "deleted.h"
|
||||
#include "effects.h"
|
||||
#include "main.h"
|
||||
#include "screens.h"
|
||||
#include "toplevel.h"
|
||||
#if HAVE_WAYLAND
|
||||
#if HAVE_DRM
|
||||
|
@ -88,6 +89,17 @@ void QPainterBackend::renderCursor(QPainter *painter)
|
|||
Q_UNUSED(painter)
|
||||
}
|
||||
|
||||
bool QPainterBackend::perScreenRendering() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
QImage *QPainterBackend::bufferForScreen(int screenId)
|
||||
{
|
||||
Q_UNUSED(screenId)
|
||||
return buffer();
|
||||
}
|
||||
|
||||
#if HAVE_WAYLAND
|
||||
//****************************************
|
||||
// WaylandQPainterBackend
|
||||
|
@ -452,19 +464,48 @@ qint64 SceneQPainter::paint(QRegion damage, ToplevelList toplevels)
|
|||
|
||||
int mask = 0;
|
||||
m_backend->prepareRenderingFrame();
|
||||
m_painter->begin(m_backend->buffer());
|
||||
if (m_backend->needsFullRepaint()) {
|
||||
mask |= Scene::PAINT_SCREEN_BACKGROUND_FIRST;
|
||||
damage = QRegion(0, 0, displayWidth(), displayHeight());
|
||||
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());
|
||||
if (m_backend->needsFullRepaint()) {
|
||||
mask |= Scene::PAINT_SCREEN_BACKGROUND_FIRST;
|
||||
damage = QRegion(0, 0, displayWidth(), displayHeight());
|
||||
}
|
||||
QRegion updateRegion, validRegion;
|
||||
paintScreen(&mask, damage, QRegion(), &updateRegion, &validRegion);
|
||||
|
||||
m_backend->renderCursor(m_painter.data());
|
||||
m_backend->showOverlay();
|
||||
|
||||
m_painter->end();
|
||||
m_backend->present(mask, updateRegion);
|
||||
}
|
||||
QRegion updateRegion, validRegion;
|
||||
paintScreen(&mask, damage, QRegion(), &updateRegion, &validRegion);
|
||||
m_backend->renderCursor(m_painter.data());
|
||||
|
||||
m_backend->showOverlay();
|
||||
|
||||
m_painter->end();
|
||||
m_backend->present(mask, updateRegion);
|
||||
// do cleanup
|
||||
clearStackingOrder();
|
||||
|
||||
|
|
|
@ -94,8 +94,20 @@ public:
|
|||
}
|
||||
|
||||
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 void renderCursor(QPainter *painter);
|
||||
/**
|
||||
* Whether the rendering needs to be split per screen.
|
||||
* Default implementation returns @c false.
|
||||
**/
|
||||
virtual bool perScreenRendering() const;
|
||||
|
||||
protected:
|
||||
QPainterBackend();
|
||||
|
|
Loading…
Reference in a new issue