backends/drm: use a swapchain instead of an OpenGL texture for the shadow buffer(s)
This seems to have better performance on Intel GPUs, and allows us to implement damage tracking for the shadow "buffer" in the future CCBUG: 477223
This commit is contained in:
parent
786dc09704
commit
c26101a9fe
4 changed files with 50 additions and 15 deletions
|
@ -121,23 +121,46 @@ std::optional<OutputLayerBeginFrameInfo> EglGbmLayerSurface::startRendering(cons
|
|||
|
||||
const QRegion repaint = bufferAgeEnabled ? m_surface->damageJournal.accumulate(slot->age(), infiniteRegion()) : infiniteRegion();
|
||||
if (enableColormanagement) {
|
||||
if (!m_surface->shadowBuffer || m_surface->shadowTexture->size() != m_surface->gbmSwapchain->size()) {
|
||||
m_surface->shadowTexture = GLTexture::allocate(GL_RGBA16F, m_surface->gbmSwapchain->size());
|
||||
if (!m_surface->shadowTexture) {
|
||||
return std::nullopt;
|
||||
if (!m_surface->shadowSwapchain || m_surface->shadowSwapchain->size() != m_surface->gbmSwapchain->size()) {
|
||||
const auto formats = m_eglBackend->eglDisplayObject()->nonExternalOnlySupportedDrmFormats();
|
||||
const auto createSwapchain = [&formats, this](bool requireAlpha) {
|
||||
for (auto it = formats.begin(); it != formats.end(); it++) {
|
||||
const auto info = FormatInfo::get(it.key());
|
||||
if (!info || info->bitsPerColor != 16 || !info->floatingPoint) {
|
||||
continue;
|
||||
}
|
||||
if (requireAlpha && info->alphaBits == 0) {
|
||||
continue;
|
||||
}
|
||||
m_surface->shadowSwapchain = EglSwapchain::create(m_eglBackend->drmDevice()->allocator(), m_eglBackend->openglContext(), m_surface->gbmSwapchain->size(), it.key(), it.value());
|
||||
if (m_surface->shadowSwapchain) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
createSwapchain(true);
|
||||
if (!m_surface->shadowSwapchain && m_formatOption != FormatOption::RequireAlpha) {
|
||||
createSwapchain(false);
|
||||
}
|
||||
m_surface->shadowBuffer = std::make_unique<GLFramebuffer>(m_surface->shadowTexture.get());
|
||||
}
|
||||
m_surface->shadowTexture->setContentTransform(m_surface->currentSlot->framebuffer()->colorAttachment()->contentTransform());
|
||||
if (!m_surface->shadowSwapchain) {
|
||||
qCCritical(KWIN_DRM) << "Failed to create shadow swapchain!";
|
||||
return std::nullopt;
|
||||
}
|
||||
m_surface->currentShadowSlot = m_surface->shadowSwapchain->acquire();
|
||||
if (!m_surface->currentShadowSlot) {
|
||||
return std::nullopt;
|
||||
}
|
||||
m_surface->currentShadowSlot->texture()->setContentTransform(m_surface->currentSlot->framebuffer()->colorAttachment()->contentTransform());
|
||||
m_surface->renderStart = std::chrono::steady_clock::now();
|
||||
m_surface->timeQuery->begin();
|
||||
return OutputLayerBeginFrameInfo{
|
||||
.renderTarget = RenderTarget(m_surface->shadowBuffer.get(), m_surface->intermediaryColorDescription),
|
||||
.repaint = repaint,
|
||||
.renderTarget = RenderTarget(m_surface->currentShadowSlot->framebuffer(), m_surface->intermediaryColorDescription),
|
||||
.repaint = infiniteRegion(),
|
||||
};
|
||||
} else {
|
||||
m_surface->shadowTexture.reset();
|
||||
m_surface->shadowBuffer.reset();
|
||||
m_surface->shadowSwapchain.reset();
|
||||
m_surface->currentShadowSlot.reset();
|
||||
m_surface->renderStart = std::chrono::steady_clock::now();
|
||||
m_surface->timeQuery->begin();
|
||||
return OutputLayerBeginFrameInfo{
|
||||
|
@ -173,7 +196,9 @@ bool EglGbmLayerSurface::endRendering(const QRegion &damagedRegion)
|
|||
mat.ortho(QRectF(QPointF(), fbo->size()));
|
||||
binder.shader()->setUniform(GLShader::Mat4Uniform::ModelViewProjectionMatrix, mat);
|
||||
glDisable(GL_BLEND);
|
||||
m_surface->shadowTexture->render(m_surface->gbmSwapchain->size());
|
||||
m_surface->currentShadowSlot->texture()->render(m_surface->gbmSwapchain->size());
|
||||
EGLNativeFence fence(m_surface->context->displayObject());
|
||||
m_surface->shadowSwapchain->release(m_surface->currentShadowSlot, fence.fileDescriptor().duplicate());
|
||||
GLFramebuffer::popFramebuffer();
|
||||
}
|
||||
m_surface->damageJournal.add(damagedRegion);
|
||||
|
@ -227,7 +252,7 @@ std::shared_ptr<DrmFramebuffer> EglGbmLayerSurface::currentBuffer() const
|
|||
const ColorDescription &EglGbmLayerSurface::colorDescription() const
|
||||
{
|
||||
if (m_surface) {
|
||||
return m_surface->shadowTexture ? m_surface->intermediaryColorDescription : m_surface->targetColorDescription;
|
||||
return m_surface->currentShadowSlot ? m_surface->intermediaryColorDescription : m_surface->targetColorDescription;
|
||||
} else {
|
||||
return ColorDescription::sRGB;
|
||||
}
|
||||
|
@ -241,7 +266,7 @@ bool EglGbmLayerSurface::doesSurfaceFit(const QSize &size, const QMap<uint32_t,
|
|||
std::shared_ptr<GLTexture> EglGbmLayerSurface::texture() const
|
||||
{
|
||||
if (m_surface) {
|
||||
return m_surface->shadowTexture ? m_surface->shadowTexture : m_surface->currentSlot->texture();
|
||||
return m_surface->currentShadowSlot ? m_surface->currentShadowSlot->texture() : m_surface->currentSlot->texture();
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -99,8 +99,8 @@ private:
|
|||
|
||||
// for color management
|
||||
bool colormanagementEnabled = false;
|
||||
std::shared_ptr<GLTexture> shadowTexture;
|
||||
std::unique_ptr<GLFramebuffer> shadowBuffer;
|
||||
std::shared_ptr<EglSwapchain> shadowSwapchain;
|
||||
std::shared_ptr<EglSwapchainSlot> currentShadowSlot;
|
||||
ColorDescription targetColorDescription = ColorDescription::sRGB;
|
||||
ColorDescription intermediaryColorDescription = ColorDescription::sRGB;
|
||||
QVector3D channelFactors = {1, 1, 1};
|
||||
|
|
|
@ -24,6 +24,7 @@ std::optional<FormatInfo> FormatInfo::get(uint32_t drmFormat)
|
|||
.alphaBits = 0,
|
||||
.bitsPerPixel = 32,
|
||||
.openglFormat = GL_RGBA8,
|
||||
.floatingPoint = false,
|
||||
};
|
||||
case DRM_FORMAT_ARGB8888:
|
||||
case DRM_FORMAT_ABGR8888:
|
||||
|
@ -35,6 +36,7 @@ std::optional<FormatInfo> FormatInfo::get(uint32_t drmFormat)
|
|||
.alphaBits = 8,
|
||||
.bitsPerPixel = 32,
|
||||
.openglFormat = GL_RGBA8,
|
||||
.floatingPoint = false,
|
||||
};
|
||||
case DRM_FORMAT_XRGB2101010:
|
||||
case DRM_FORMAT_XBGR2101010:
|
||||
|
@ -46,6 +48,7 @@ std::optional<FormatInfo> FormatInfo::get(uint32_t drmFormat)
|
|||
.alphaBits = 0,
|
||||
.bitsPerPixel = 32,
|
||||
.openglFormat = GL_RGB10_A2,
|
||||
.floatingPoint = false,
|
||||
};
|
||||
case DRM_FORMAT_ARGB2101010:
|
||||
case DRM_FORMAT_ABGR2101010:
|
||||
|
@ -57,6 +60,7 @@ std::optional<FormatInfo> FormatInfo::get(uint32_t drmFormat)
|
|||
.alphaBits = 2,
|
||||
.bitsPerPixel = 32,
|
||||
.openglFormat = GL_RGB10_A2,
|
||||
.floatingPoint = false,
|
||||
};
|
||||
case DRM_FORMAT_XRGB16161616F:
|
||||
case DRM_FORMAT_XBGR16161616F:
|
||||
|
@ -66,6 +70,7 @@ std::optional<FormatInfo> FormatInfo::get(uint32_t drmFormat)
|
|||
.alphaBits = 0,
|
||||
.bitsPerPixel = 64,
|
||||
.openglFormat = GL_RGBA16F,
|
||||
.floatingPoint = true,
|
||||
};
|
||||
case DRM_FORMAT_ARGB16161616F:
|
||||
case DRM_FORMAT_ABGR16161616F:
|
||||
|
@ -75,6 +80,7 @@ std::optional<FormatInfo> FormatInfo::get(uint32_t drmFormat)
|
|||
.alphaBits = 16,
|
||||
.bitsPerPixel = 64,
|
||||
.openglFormat = GL_RGBA16F,
|
||||
.floatingPoint = true,
|
||||
};
|
||||
case DRM_FORMAT_ARGB4444:
|
||||
case DRM_FORMAT_ABGR4444:
|
||||
|
@ -86,6 +92,7 @@ std::optional<FormatInfo> FormatInfo::get(uint32_t drmFormat)
|
|||
.alphaBits = 4,
|
||||
.bitsPerPixel = 16,
|
||||
.openglFormat = GL_RGBA4,
|
||||
.floatingPoint = false,
|
||||
};
|
||||
case DRM_FORMAT_ARGB1555:
|
||||
case DRM_FORMAT_ABGR1555:
|
||||
|
@ -97,6 +104,7 @@ std::optional<FormatInfo> FormatInfo::get(uint32_t drmFormat)
|
|||
.alphaBits = 1,
|
||||
.bitsPerPixel = 16,
|
||||
.openglFormat = GL_RGB5_A1,
|
||||
.floatingPoint = false,
|
||||
};
|
||||
case DRM_FORMAT_NV12:
|
||||
return FormatInfo{
|
||||
|
@ -105,6 +113,7 @@ std::optional<FormatInfo> FormatInfo::get(uint32_t drmFormat)
|
|||
.alphaBits = 0,
|
||||
.bitsPerPixel = 24,
|
||||
.openglFormat = GL_R8,
|
||||
.floatingPoint = false,
|
||||
};
|
||||
default:
|
||||
return std::nullopt;
|
||||
|
|
|
@ -45,6 +45,7 @@ struct KWIN_EXPORT FormatInfo
|
|||
uint32_t alphaBits;
|
||||
uint32_t bitsPerPixel;
|
||||
GLint openglFormat;
|
||||
bool floatingPoint;
|
||||
|
||||
std::optional<YuvConversion> yuvConversion() const
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue