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.

(cherry picked from commit 711b6e36d2610fb4f693c87f50ad5fe71165ad9c)
icc-effect-5.27.2
Vlad Zahorodnii 2023-02-23 23:04:00 +02:00
parent dc465ec6ab
commit 554ad9ecda
2 changed files with 15 additions and 36 deletions

View File

@ -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<GLFramebuffer>(data.texture.get());
}
if (!data.vbo || data.viewport != rect) {
data.vbo.reset(new GLVertexBuffer(GLVertexBuffer::Static));
data.viewport = scaledRect(rect, devicePixelRatio).toRect();
QVector<float> verts;
QVector<float> 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 &region, 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(QRect(QPoint(0, 0), geometry.size()), scale);
offscreen.texture->unbind();
}
ShaderManager::instance()->popShader();

View File

@ -89,7 +89,6 @@ private:
{
std::unique_ptr<GLTexture> texture;
std::unique_ptr<GLFramebuffer> framebuffer;
std::unique_ptr<GLVertexBuffer> vbo;
QRect viewport;
};