backends/drm: move damage tracking into GbmSurface
This commit is contained in:
parent
cfdb303012
commit
5d317641a4
4 changed files with 40 additions and 40 deletions
|
@ -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 ¤t = 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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue