Commit 9dc4c730 authored by Xaver Hugl's avatar Xaver Hugl Committed by Vlad Zahorodnii
Browse files

backends/drm: move damage tracking into DumbSwapchain

parent 5d317641
......@@ -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
......
......@@ -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;
};
}
......@@ -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)
......
......@@ -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;
}
}
}
......@@ -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;
......
......@@ -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_swapchains[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());
}
}
......@@ -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;
};
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment