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.
This commit is contained in:
parent
a62dc13161
commit
711b6e36d2
2 changed files with 15 additions and 36 deletions
|
@ -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 ®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();
|
||||
|
||||
|
|
|
@ -89,7 +89,6 @@ private:
|
|||
{
|
||||
std::unique_ptr<GLTexture> texture;
|
||||
std::unique_ptr<GLFramebuffer> framebuffer;
|
||||
std::unique_ptr<GLVertexBuffer> vbo;
|
||||
QRect viewport;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue