Remove QPainterBackend::needsFullRepaint()

A better alternative is to return the damage region in the beginFrame()
function. This way, the render backend can force full screen repaints or
indicate what parts of the buffer needs to be repainted (for buffer age)
This commit is contained in:
Vlad Zahorodnii 2021-07-24 11:36:00 +03:00
parent 4abbb6f0d6
commit 2fe102768a
12 changed files with 21 additions and 84 deletions

View file

@ -34,7 +34,7 @@ public:
PlatformSurfaceTexture *createPlatformSurfaceTextureWayland(SurfacePixmapWayland *pixmap);
virtual void endFrame(int screenId, const QRegion &damage) = 0;
virtual void beginFrame(int screenId) = 0;
virtual QRegion beginFrame(int screenId) = 0;
/**
* @brief React on screen geometry changes.
*
@ -61,7 +61,6 @@ public:
* @todo Get a better identifier for screen then a counter variable
*/
virtual QImage *bufferForScreen(int screenId) = 0;
virtual bool needsFullRepaint(int screenId) const = 0;
protected:
QPainterBackend();

View file

@ -66,15 +66,10 @@ QImage *DrmQPainterBackend::bufferForScreen(int screenId)
return m_outputs[screenId].swapchain->currentBuffer()->image();
}
bool DrmQPainterBackend::needsFullRepaint(int screenId) const
{
Q_UNUSED(screenId)
return true;
}
void DrmQPainterBackend::beginFrame(int screenId)
QRegion DrmQPainterBackend::beginFrame(int screenId)
{
m_outputs[screenId].swapchain->acquireBuffer();
return m_outputs[screenId].output->geometry();
}
void DrmQPainterBackend::endFrame(int screenId, const QRegion &damage)

View file

@ -31,8 +31,7 @@ public:
DrmQPainterBackend(DrmBackend *backend, DrmGpu *gpu);
QImage *bufferForScreen(int screenId) override;
bool needsFullRepaint(int screenId) const override;
void beginFrame(int screenId) override;
QRegion beginFrame(int screenId) override;
void endFrame(int screenId, const QRegion &damage) override;
private:

View file

@ -13,6 +13,7 @@
#include "main.h"
#include "platform.h"
#include "renderloop.h"
#include "screens.h"
#include "session.h"
#include "vsyncmonitor.h"
// Qt
@ -24,7 +25,6 @@ FramebufferQPainterBackend::FramebufferQPainterBackend(FramebufferBackend *backe
: QPainterBackend()
, m_renderBuffer(backend->screenSize(), QImage::Format_RGB32)
, m_backend(backend)
, m_needsFullRepaint(true)
{
m_renderBuffer.fill(Qt::black);
m_backend->map();
@ -69,16 +69,9 @@ QImage* FramebufferQPainterBackend::bufferForScreen(int screenId)
return &m_renderBuffer;
}
bool FramebufferQPainterBackend::needsFullRepaint(int screenId) const
QRegion FramebufferQPainterBackend::beginFrame(int screenId)
{
Q_UNUSED(screenId)
return m_needsFullRepaint;
}
void FramebufferQPainterBackend::beginFrame(int screenId)
{
Q_UNUSED(screenId)
m_needsFullRepaint = true;
return screens()->geometry(screenId);
}
void FramebufferQPainterBackend::endFrame(int screenId, const QRegion &damage)
@ -89,7 +82,6 @@ void FramebufferQPainterBackend::endFrame(int screenId, const QRegion &damage)
if (!kwinApp()->platform()->session()->isActive()) {
return;
}
m_needsFullRepaint = false;
FramebufferOutput *output = static_cast<FramebufferOutput *>(m_backend->findOutput(screenId));
output->vsyncMonitor()->arm();

View file

@ -25,8 +25,7 @@ public:
~FramebufferQPainterBackend() override;
QImage *bufferForScreen(int screenId) override;
bool needsFullRepaint(int screenId) const override;
void beginFrame(int screenId) override;
QRegion beginFrame(int screenId) override;
void endFrame(int screenId, const QRegion &damage) override;
private:
@ -43,7 +42,6 @@ private:
QImage m_backBuffer;
FramebufferBackend *m_backend;
bool m_needsFullRepaint;
};
}

View file

@ -32,15 +32,9 @@ QImage *VirtualQPainterBackend::bufferForScreen(int screen)
return &m_backBuffers[screen];
}
bool VirtualQPainterBackend::needsFullRepaint(int screenId) const
QRegion VirtualQPainterBackend::beginFrame(int screenId)
{
Q_UNUSED(screenId)
return true;
}
void VirtualQPainterBackend::beginFrame(int screenId)
{
Q_UNUSED(screenId)
return screens()->geometry(screenId);
}
void VirtualQPainterBackend::createOutputs()

View file

@ -27,8 +27,7 @@ public:
~VirtualQPainterBackend() override;
QImage *bufferForScreen(int screenId) override;
bool needsFullRepaint(int screenId) const override;
void beginFrame(int screenId) override;
QRegion beginFrame(int screenId) override;
void endFrame(int screenId, const QRegion &damage) override;
private:

View file

@ -38,16 +38,6 @@ 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;
@ -171,7 +161,6 @@ void WaylandQPainterBackend::endFrame(int screenId, const QRegion &damage)
WaylandQPainterOutput *rendererOutput = m_outputs.value(screenId);
Q_ASSERT(rendererOutput);
rendererOutput->setNeedsFullRepaint(false);
rendererOutput->present(rendererOutput->mapToLocal(damage));
}
@ -181,20 +170,13 @@ QImage *WaylandQPainterBackend::bufferForScreen(int screenId)
return &output->m_backBuffer;
}
void WaylandQPainterBackend::beginFrame(int screenId)
QRegion WaylandQPainterBackend::beginFrame(int screenId)
{
WaylandQPainterOutput *rendererOutput = m_outputs.value(screenId);
Q_ASSERT(rendererOutput);
rendererOutput->prepareRenderingFrame();
rendererOutput->setNeedsFullRepaint(true);
}
bool WaylandQPainterBackend::needsFullRepaint(int screenId) const
{
const WaylandQPainterOutput *rendererOutput = m_outputs.value(screenId);
Q_ASSERT(rendererOutput);
return rendererOutput->needsFullRepaint();
return rendererOutput->m_waylandOutput->geometry();
}
}

View file

@ -48,9 +48,6 @@ public:
void prepareRenderingFrame();
void present(const QRegion &damage);
bool needsFullRepaint() const;
void setNeedsFullRepaint(bool set);
QRegion mapToLocal(const QRegion &region) const;
private:
@ -59,7 +56,6 @@ private:
QWeakPointer<KWayland::Client::Buffer> m_buffer;
QImage m_backBuffer;
bool m_needsFullRepaint = true;
friend class WaylandQPainterBackend;
};
@ -74,9 +70,7 @@ public:
QImage *bufferForScreen(int screenId) override;
void endFrame(int screenId, const QRegion& damage) override;
void beginFrame(int screenId) override;
bool needsFullRepaint(int screenId) const override;
QRegion beginFrame(int screenId) override;
private:
void createOutput(AbstractOutput *waylandOutput);

View file

@ -49,16 +49,10 @@ QImage *X11WindowedQPainterBackend::bufferForScreen(int screen)
return &m_outputs.at(screen)->buffer;
}
bool X11WindowedQPainterBackend::needsFullRepaint(int screenId) const
{
const Output *rendererOutput = m_outputs.value(screenId);
Q_ASSERT(rendererOutput);
return rendererOutput->needsFullRepaint;
}
void X11WindowedQPainterBackend::beginFrame(int screenId)
QRegion X11WindowedQPainterBackend::beginFrame(int screenId)
{
Q_UNUSED(screenId)
return screens()->geometry(screenId);
}
void X11WindowedQPainterBackend::endFrame(int screenId, const QRegion &damage)
@ -83,8 +77,6 @@ void X11WindowedQPainterBackend::endFrame(int screenId, const QRegion &damage)
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;
}
}

View file

@ -30,8 +30,7 @@ public:
~X11WindowedQPainterBackend() override;
QImage *bufferForScreen(int screenId) override;
bool needsFullRepaint(int screenId) const override;
void beginFrame(int screenId) override;
QRegion beginFrame(int screenId) override;
void endFrame(int screenId, const QRegion &damage) override;
private:
@ -41,7 +40,6 @@ private:
struct Output {
xcb_window_t window;
QImage buffer;
bool needsFullRepaint = true;
};
QVector<Output*> m_outputs;
};

View file

@ -79,24 +79,19 @@ void SceneQPainter::paintGenericScreen(int mask, const ScreenPaintData &data)
m_painter->restore();
}
void SceneQPainter::paint(int screenId, const QRegion &_damage, const QList<Toplevel *> &toplevels,
void SceneQPainter::paint(int screenId, const QRegion &damage, const QList<Toplevel *> &toplevels,
RenderLoop *renderLoop)
{
Q_ASSERT(kwinApp()->platform()->isPerScreenRenderingEnabled());
painted_screen = screenId;
createStackingOrder(toplevels);
QRegion damage = _damage;
int mask = 0;
m_backend->beginFrame(screenId);
const bool needsFullRepaint = m_backend->needsFullRepaint(screenId);
if (needsFullRepaint) {
mask |= Scene::PAINT_SCREEN_BACKGROUND_FIRST;
damage = screens()->geometry(screenId);
}
const QRegion repaint = m_backend->beginFrame(screenId);
const QRect geometry = screens()->geometry(screenId);
QImage *buffer = m_backend->bufferForScreen(screenId);
if (buffer && !buffer->isNull()) {
renderLoop->beginFrame();
@ -104,7 +99,7 @@ void SceneQPainter::paint(int screenId, const QRegion &_damage, const QList<Topl
m_painter->setWindow(geometry);
QRegion updateRegion, validRegion;
paintScreen(&mask, damage.intersected(geometry), QRegion(), &updateRegion, &validRegion,
paintScreen(&mask, damage.intersected(geometry), repaint, &updateRegion, &validRegion,
renderLoop);
paintCursor(updateRegion);