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
parent
dc465ec6ab
commit
554ad9ecda
|
@ -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(QRect(QPoint(0, 0), 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 New Issue