backends/drm: move damage tracking into GbmSurface

This commit is contained in:
Xaver Hugl 2021-12-21 13:22:45 +01:00 committed by Vlad Zahorodnii
parent cfdb303012
commit 5d317641a4
4 changed files with 40 additions and 40 deletions

View file

@ -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;
@ -237,9 +237,8 @@ bool EglGbmBackend::swapBuffers(DrmAbstractOutput *drmOutput, const QRegion &dir
if (output.current.shadowBuffer) {
output.current.shadowBuffer->render(output.output);
}
if (output.current.gbmSurface->swapBuffers()) {
if (output.current.gbmSurface->swapBuffers(dirty)) {
cleanupRenderData(output.old);
updateBufferAge(output, dirty);
return true;
} else {
return false;
@ -467,7 +466,7 @@ void EglGbmBackend::aboutToStartPainting(AbstractOutput *drmOutput, const QRegio
Q_ASSERT_X(drmOutput, "aboutToStartPainting", "not using per screen rendering");
Q_ASSERT(m_outputs.contains(drmOutput));
const Output &output = m_outputs[drmOutput];
if (output.current.bufferAge > 0 && !damagedRegion.isEmpty() && supportsPartialUpdate()) {
if (output.current.gbmSurface->bufferAge() > 0 && !damagedRegion.isEmpty() && supportsPartialUpdate()) {
const QRegion region = damagedRegion & output.output->geometry();
QVector<EGLint> rects = regionToRects(region, output.output);
@ -553,19 +552,13 @@ QRegion EglGbmBackend::prepareRenderingForOutput(Output &output)
resetOutput(output);
}
}
output.current.gbmSurface->makeContextCurrent();
if (output.current.shadowBuffer) {
output.current.shadowBuffer->bind();
auto &current = output.current;
const auto needsRepaint = current.gbmSurface->makeContextCurrent(output.output->geometry());
if (current.shadowBuffer) {
current.shadowBuffer->bind();
}
setViewport(output);
const QRect geometry = output.output->geometry();
if (supportsBufferAge()) {
auto current = &output.current;
return current->damageJournal.accumulate(current->bufferAge, geometry);
}
return geometry;
return needsRepaint;
}
QSharedPointer<DrmBuffer> EglGbmBackend::endFrameWithBuffer(AbstractOutput *drmOutput, const QRegion &dirty)
@ -576,11 +569,7 @@ QSharedPointer<DrmBuffer> EglGbmBackend::endFrameWithBuffer(AbstractOutput *drmO
if (output.current.shadowBuffer) {
output.current.shadowBuffer->render(output.output);
}
auto buffer = output.current.gbmSurface->swapBuffersForDrm();
if (buffer) {
updateBufferAge(output, dirty);
}
return buffer;
return output.current.gbmSurface->swapBuffersForDrm(dirty);
} else {
return importFramebuffer(output, dirty);
}
@ -600,14 +589,6 @@ void EglGbmBackend::endFrame(AbstractOutput *drmOutput, const QRegion &renderedR
output.output->present(buffer, dirty);
}
void EglGbmBackend::updateBufferAge(Output &output, const QRegion &dirty)
{
if (supportsBufferAge()) {
eglQuerySurface(eglDisplay(), output.current.gbmSurface->eglSurface(), EGL_BUFFER_AGE_EXT, &output.current.bufferAge);
output.current.damageJournal.add(dirty);
}
}
bool EglGbmBackend::scanout(AbstractOutput *drmOutput, SurfaceItem *surfaceItem)
{
static bool valid;

View file

@ -99,8 +99,6 @@ private:
struct RenderData {
QSharedPointer<ShadowBuffer> shadowBuffer;
QSharedPointer<GbmSurface> gbmSurface;
int bufferAge = 0;
DamageJournal damageJournal;
GbmFormat format;
// for secondary GPU import
@ -126,7 +124,6 @@ private:
QRegion prepareRenderingForOutput(Output &output);
QSharedPointer<DrmBuffer> importFramebuffer(Output &output, const QRegion &dirty) const;
QSharedPointer<DrmBuffer> endFrameWithBuffer(AbstractOutput *output, const QRegion &dirty);
void updateBufferAge(Output &output, const QRegion &dirty);
std::optional<GbmFormat> chooseFormat(Output &output) const;
void cleanupRenderData(Output::RenderData &output);

View file

@ -66,19 +66,24 @@ GbmSurface::~GbmSurface()
gbm_surface_destroy(m_surface);
}
}
bool GbmSurface::makeContextCurrent() const
QRegion GbmSurface::makeContextCurrent(const QRect &geometry) const
{
if (eglMakeCurrent(m_gpu->eglDisplay(), m_eglSurface, m_eglSurface, m_gpu->eglBackend()->context()) == EGL_FALSE) {
qCCritical(KWIN_DRM) << "eglMakeCurrent failed:" << getEglErrorString();
return false;
return {};
}
if (!GLPlatform::instance()->isGLES()) {
glDrawBuffer(GL_BACK);
}
return true;
if (m_gpu->eglBackend()->supportsBufferAge()) {
return m_damageJournal.accumulate(m_bufferAge, geometry);
} else {
return geometry;
}
}
QSharedPointer<DrmGbmBuffer> GbmSurface::swapBuffersForDrm()
QSharedPointer<DrmGbmBuffer> GbmSurface::swapBuffersForDrm(const QRegion &dirty)
{
auto error = eglSwapBuffers(m_gpu->eglDisplay(), m_eglSurface);
if (error != EGL_TRUE) {
@ -96,10 +101,14 @@ QSharedPointer<DrmGbmBuffer> GbmSurface::swapBuffersForDrm()
return nullptr;
}
m_currentDrmBuffer = buffer;
if (m_gpu->eglBackend()->supportsBufferAge()) {
eglQuerySurface(m_gpu->eglDisplay(), m_eglSurface, EGL_BUFFER_AGE_EXT, &m_bufferAge);
m_damageJournal.add(dirty);
}
return buffer;
}
QSharedPointer<GbmBuffer> GbmSurface::swapBuffers()
QSharedPointer<GbmBuffer> GbmSurface::swapBuffers(const QRegion &dirty)
{
auto error = eglSwapBuffers(m_gpu->eglDisplay(), m_eglSurface);
if (error != EGL_TRUE) {
@ -112,6 +121,10 @@ QSharedPointer<GbmBuffer> GbmSurface::swapBuffers()
}
m_currentBuffer = QSharedPointer<GbmBuffer>::create(this, bo);
m_lockedBuffers << m_currentBuffer.get();
if (m_gpu->eglBackend()->supportsBufferAge()) {
eglQuerySurface(m_gpu->eglDisplay(), m_eglSurface, EGL_BUFFER_AGE_EXT, &m_bufferAge);
m_damageJournal.add(dirty);
}
return m_currentBuffer;
}
@ -156,4 +169,9 @@ QVector<uint64_t> GbmSurface::modifiers() const
return m_modifiers;
}
int GbmSurface::bufferAge() const
{
return m_bufferAge;
}
}

View file

@ -14,6 +14,7 @@
#include <QVector>
#include "drm_buffer_gbm.h"
#include "utils/common.h"
struct gbm_device;
struct gbm_surface;
@ -28,10 +29,10 @@ public:
explicit GbmSurface(DrmGpu *gpu, const QSize &size, uint32_t format, QVector<uint64_t> modifiers, EGLConfig config);
~GbmSurface();
bool makeContextCurrent() const;
QRegion makeContextCurrent(const QRect &geometry) const;
QSharedPointer<DrmGbmBuffer> swapBuffersForDrm();
QSharedPointer<GbmBuffer> swapBuffers();
QSharedPointer<DrmGbmBuffer> swapBuffersForDrm(const QRegion &dirty);
QSharedPointer<GbmBuffer> swapBuffers(const QRegion &dirty);
void releaseBuffer(GbmBuffer *buffer);
QSharedPointer<GbmBuffer> currentBuffer() const;
@ -42,6 +43,7 @@ public:
bool isValid() const;
uint32_t format() const;
QVector<uint64_t> modifiers() const;
int bufferAge() const;
private:
gbm_surface *m_surface;
@ -50,6 +52,8 @@ private:
QSize m_size;
const uint32_t m_format;
const QVector<uint64_t> m_modifiers;
int m_bufferAge = 0;
DamageJournal m_damageJournal;
QSharedPointer<GbmBuffer> m_currentBuffer;
QSharedPointer<DrmGbmBuffer> m_currentDrmBuffer;