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.
master
Vlad Zahorodnii 2 years ago
parent a62dc13161
commit 711b6e36d2

@ -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(geometry.size(), scale);
offscreen.texture->unbind();
}
ShaderManager::instance()->popShader();

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

Loading…
Cancel
Save