From 711b6e36d2610fb4f693c87f50ad5fe71165ad9c Mon Sep 17 00:00:00 2001 From: Vlad Zahorodnii Date: Thu, 23 Feb 2023 23:04:00 +0200 Subject: [PATCH] effects/zoom: Fix rendering with mixed scale factors When allocating offscreen texture, we should use screen's scale rather than current render target's scale. In addition to that, the cached vbo cannot be used for rendering on other screens with different scale factors, which can happen. --- src/effects/zoom/zoom.cpp | 50 ++++++++++++--------------------------- src/effects/zoom/zoom.h | 1 - 2 files changed, 15 insertions(+), 36 deletions(-) diff --git a/src/effects/zoom/zoom.cpp b/src/effects/zoom/zoom.cpp index 676e80099f..8cd276de7a 100644 --- a/src/effects/zoom/zoom.cpp +++ b/src/effects/zoom/zoom.cpp @@ -255,8 +255,8 @@ void ZoomEffect::prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseco ZoomEffect::OffscreenData *ZoomEffect::ensureOffscreenData(EffectScreen *screen) { - const QRect rect = effects->renderTargetRect(); - const qreal devicePixelRatio = effects->renderTargetScale(); + const QRect rect = screen->geometry(); + const qreal devicePixelRatio = screen->devicePixelRatio(); const QSize nativeSize = rect.size() * devicePixelRatio; OffscreenData &data = m_offscreenData[effects->waylandDisplay() ? screen : nullptr]; @@ -266,30 +266,6 @@ ZoomEffect::OffscreenData *ZoomEffect::ensureOffscreenData(EffectScreen *screen) data.texture->setWrapMode(GL_CLAMP_TO_EDGE); data.framebuffer = std::make_unique(data.texture.get()); } - if (!data.vbo || data.viewport != rect) { - data.vbo.reset(new GLVertexBuffer(GLVertexBuffer::Static)); - data.viewport = scaledRect(rect, devicePixelRatio).toRect(); - - QVector verts; - QVector texcoords; - - // The v-coordinate is flipped because projection matrix is "flipped." - texcoords << 1.0 << 1.0; - verts << (rect.x() + rect.width()) * devicePixelRatio << rect.y() * devicePixelRatio; - texcoords << 0.0 << 1.0; - verts << rect.x() * devicePixelRatio << rect.y() * devicePixelRatio; - texcoords << 0.0 << 0.0; - verts << rect.x() * devicePixelRatio << (rect.y() + rect.height()) * devicePixelRatio; - - texcoords << 1.0 << 0.0; - verts << (rect.x() + rect.width()) * devicePixelRatio << (rect.y() + rect.height()) * devicePixelRatio; - texcoords << 1.0 << 1.0; - verts << (rect.x() + rect.width()) * devicePixelRatio << rect.y() * devicePixelRatio; - texcoords << 0.0 << 0.0; - verts << rect.x() * devicePixelRatio << (rect.y() + rect.height()) * devicePixelRatio; - - data.vbo->setData(6, 2, verts.constData(), texcoords.constData()); - } return &data; } @@ -370,16 +346,20 @@ void ZoomEffect::paintScreen(int mask, const QRegion ®ion, ScreenPaintData &d glClearColor(0.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT); - QMatrix4x4 matrix; - matrix.translate(xTranslation * scale, yTranslation * scale); - matrix.scale(zoom, zoom); - auto shader = ShaderManager::instance()->pushShader(ShaderTrait::MapTexture); - shader->setUniform(GLShader::ModelViewProjectionMatrix, data.projectionMatrix() * matrix); - for (auto &[screen, data] : m_offscreenData) { - data.texture->bind(); - data.vbo->render(GL_TRIANGLES); - data.texture->unbind(); + for (auto &[screen, offscreen] : m_offscreenData) { + const QRect geometry = screen->geometry(); + + QMatrix4x4 matrix; + matrix.translate(xTranslation * scale, yTranslation * scale); + matrix.scale(zoom, zoom); + matrix.translate(geometry.x() * scale, geometry.y() * scale); + + shader->setUniform(GLShader::ModelViewProjectionMatrix, data.projectionMatrix() * matrix); + + offscreen.texture->bind(); + offscreen.texture->render(geometry.size(), scale); + offscreen.texture->unbind(); } ShaderManager::instance()->popShader(); diff --git a/src/effects/zoom/zoom.h b/src/effects/zoom/zoom.h index 0ded11df61..a1bd1107ec 100644 --- a/src/effects/zoom/zoom.h +++ b/src/effects/zoom/zoom.h @@ -89,7 +89,6 @@ private: { std::unique_ptr texture; std::unique_ptr framebuffer; - std::unique_ptr vbo; QRect viewport; };