scene: Compute projection matrix based on the render target rect

Neither SceneQPainter nor SceneOpenGL have to compute the projection
matrix by themselves. It can be done by the Scene when setting the
projection matrix. The main benefit behind this change is that it
reduces the amount of custom setup code around paintScreen(), which
makes us one step closer to getting rid of graphics-specific paint()
function and just calling paintScreen().
This commit is contained in:
Vlad Zahorodnii 2022-02-15 15:10:31 +02:00
parent 5caa28c1a3
commit ba000d5a4e
4 changed files with 21 additions and 28 deletions

View file

@ -187,7 +187,7 @@ void Scene::removeRepaints(AbstractOutput *output)
}
QMatrix4x4 Scene::createProjectionMatrix(const QRect &rect)
static QMatrix4x4 createProjectionMatrix(const QRect &rect)
{
// Create a perspective projection with a 60° field-of-view,
// and an aspect ratio of 1.0.
@ -214,6 +214,11 @@ QMatrix4x4 Scene::createProjectionMatrix(const QRect &rect)
return ret;
}
QMatrix4x4 Scene::renderTargetProjectionMatrix() const
{
return m_renderTargetProjectionMatrix;
}
QRect Scene::renderTargetRect() const
{
return m_renderTargetRect;
@ -222,6 +227,7 @@ QRect Scene::renderTargetRect() const
void Scene::setRenderTargetRect(const QRect &rect)
{
m_renderTargetRect = rect;
m_renderTargetProjectionMatrix = createProjectionMatrix(rect);
}
qreal Scene::renderTargetScale() const
@ -255,14 +261,13 @@ void Scene::paintScreen(AbstractOutput *output, const QList<Toplevel *> &topleve
setRenderTargetScale(output->scale());
QRegion update, valid;
paintScreen(renderTargetRect(), QRect(), &update, &valid, output->renderLoop(), createProjectionMatrix(renderTargetRect()));
paintScreen(renderTargetRect(), QRect(), &update, &valid, output->renderLoop());
clearStackingOrder();
}
// returns mask and possibly modified region
void Scene::paintScreen(const QRegion &damage, const QRegion &repaint,
QRegion *updateRegion, QRegion *validRegion, RenderLoop *renderLoop,
const QMatrix4x4 &projection)
QRegion *updateRegion, QRegion *validRegion, RenderLoop *renderLoop)
{
const QRegion displayRegion(geometry());
@ -310,7 +315,7 @@ void Scene::paintScreen(const QRegion &damage, const QRegion &repaint,
painted_region = region;
repaint_region = repaint;
ScreenPaintData data(projection, screen);
ScreenPaintData data(m_renderTargetProjectionMatrix, screen);
effects->paintScreen(mask, region, data);
Q_EMIT frameRendered();

View file

@ -189,8 +189,7 @@ public:
virtual void paintDesktop(int desktop, int mask, const QRegion &region, ScreenPaintData &data);
static QMatrix4x4 createProjectionMatrix(const QRect &rect);
QMatrix4x4 renderTargetProjectionMatrix() const;
QRect renderTargetRect() const;
void setRenderTargetRect(const QRect &rect);
qreal renderTargetScale() const;
@ -210,8 +209,7 @@ protected:
void clearStackingOrder();
// shared implementation, starts painting the screen
void paintScreen(const QRegion &damage, const QRegion &repaint,
QRegion *updateRegion, QRegion *validRegion, RenderLoop *renderLoop,
const QMatrix4x4 &projection = QMatrix4x4());
QRegion *updateRegion, QRegion *validRegion, RenderLoop *renderLoop);
// Render cursor texture in case hardware cursor is disabled/non-applicable
virtual void paintCursor(AbstractOutput *output, const QRegion &region) = 0;
friend class EffectsHandlerImpl;
@ -273,6 +271,7 @@ private:
QHash< Toplevel*, Window* > m_windows;
QMap<AbstractOutput *, QRegion> m_repaints;
QRect m_geometry;
QMatrix4x4 m_renderTargetProjectionMatrix;
QRect m_renderTargetRect;
qreal m_renderTargetScale = 1;
// how many times finalPaintScreen() has been called

View file

@ -153,7 +153,7 @@ void SceneOpenGL::paintCursor(AbstractOutput *output, const QRegion &rendered)
}
// get cursor position in projection coordinates
QMatrix4x4 mvp = m_projectionMatrix;
QMatrix4x4 mvp = renderTargetProjectionMatrix();
mvp.translate(cursorPos.x(), cursorPos.y());
// handle transparence
@ -248,10 +248,7 @@ void SceneOpenGL::paint(AbstractOutput *output, const QRegion &damage, const QLi
repaint = m_backend->beginFrame(output);
GLVertexBuffer::streamingBuffer()->beginFrame();
updateProjectionMatrix(renderTargetRect());
paintScreen(damage.intersected(renderTargetRect()), repaint, &update, &valid,
renderLoop, projectionMatrix()); // call generic implementation
paintScreen(damage.intersected(renderTargetRect()), repaint, &update, &valid, renderLoop); // call generic implementation
paintCursor(output, valid);
renderLoop->endFrame();
@ -356,7 +353,7 @@ void SceneOpenGL::paintOffscreenQuickView(OffscreenQuickView *w)
return;
}
QMatrix4x4 mvp(projectionMatrix());
QMatrix4x4 mvp(renderTargetProjectionMatrix());
mvp.translate(rect.x(), rect.y());
shader->setUniform(GLShader::ModelViewProjectionMatrix, mvp);
@ -452,14 +449,9 @@ bool SceneOpenGL::supported(OpenGLBackend *backend)
return true;
}
void SceneOpenGL::updateProjectionMatrix(const QRect &rect)
{
m_projectionMatrix = Scene::createProjectionMatrix(rect);
}
void SceneOpenGL::paintSimpleScreen(int mask, const QRegion &region)
{
m_screenProjectionMatrix = m_projectionMatrix;
m_screenProjectionMatrix = renderTargetProjectionMatrix();
Scene::paintSimpleScreen(mask, region);
}
@ -468,7 +460,7 @@ void SceneOpenGL::paintGenericScreen(int mask, const ScreenPaintData &data)
{
const QMatrix4x4 screenMatrix = transformation(mask, data);
m_screenProjectionMatrix = m_projectionMatrix * screenMatrix;
m_screenProjectionMatrix = renderTargetProjectionMatrix() * screenMatrix;
Scene::paintGenericScreen(mask, data);
}
@ -481,7 +473,7 @@ void SceneOpenGL::doPaintBackground(const QVector< float >& vertices)
vbo->setData(vertices.count() / 2, 2, vertices.data(), nullptr);
ShaderBinder binder(ShaderTrait::UniformColor);
binder.shader()->setUniform(GLShader::ModelViewProjectionMatrix, m_projectionMatrix);
binder.shader()->setUniform(GLShader::ModelViewProjectionMatrix, renderTargetProjectionMatrix());
vbo->render(GL_TRIANGLES);
}
@ -697,7 +689,7 @@ QMatrix4x4 OpenGLWindow::modelViewProjectionMatrix(int mask, const WindowPaintDa
if (mask & Scene::PAINT_SCREEN_TRANSFORMED)
return m_scene->screenProjectionMatrix() * mvMatrix;
return m_scene->projectionMatrix() * mvMatrix;
return m_scene->renderTargetProjectionMatrix() * mvMatrix;
}
static QMatrix4x4 transformForPaintData(int mask, const WindowPaintData &data)
@ -957,7 +949,7 @@ void SceneOpenGL::EffectFrame::render(const QRegion &_region, double opacity, do
shader->setUniform(GLShader::ModulationConstant, QVector4D(1.0, 1.0, 1.0, 1.0));
shader->setUniform(GLShader::Saturation, 1.0f);
}
const QMatrix4x4 projection = m_scene->projectionMatrix();
const QMatrix4x4 projection = m_scene->renderTargetProjectionMatrix();
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

View file

@ -53,7 +53,6 @@ public:
QVector<QByteArray> openGLPlatformInterfaceExtensions() const override;
QSharedPointer<GLTexture> textureForOutput(AbstractOutput *output) const override;
QMatrix4x4 projectionMatrix() const { return m_projectionMatrix; }
QMatrix4x4 screenProjectionMatrix() const override { return m_screenProjectionMatrix; }
static SceneOpenGL *createScene(OpenGLBackend *backend, QObject *parent);
@ -75,7 +74,6 @@ protected:
private:
void doPaintBackground(const QVector< float >& vertices);
void updateProjectionMatrix(const QRect &geometry);
void performPaintWindow(EffectWindowImpl* w, int mask, const QRegion &region, WindowPaintData& data);
bool init_ok = true;
@ -83,7 +81,6 @@ private:
LanczosFilter *m_lanczosFilter = nullptr;
QScopedPointer<GLTexture> m_cursorTexture;
bool m_cursorTextureDirty = false;
QMatrix4x4 m_projectionMatrix;
QMatrix4x4 m_screenProjectionMatrix;
GLuint vao = 0;
};