scenes/opengl: Merge SceneOpenGL and SceneOpenGL2

There's no OpenGL 1 renderer anymore so we can have only one scene
class now.
This commit is contained in:
Vlad Zahorodnii 2021-11-03 17:34:51 +02:00
parent 2d93b625e2
commit 0f6f4ee624
2 changed files with 71 additions and 110 deletions

View file

@ -73,7 +73,6 @@ namespace KWin
SceneOpenGL::SceneOpenGL(OpenGLBackend *backend, QObject *parent)
: Scene(parent)
, init_ok(true)
, m_backend(backend)
{
if (m_backend->isFailed()) {
@ -97,6 +96,37 @@ SceneOpenGL::SceneOpenGL(OpenGLBackend *backend, QObject *parent)
return;
}
// We only support the OpenGL 2+ shader API, not GL_ARB_shader_objects
if (!hasGLVersion(2, 0)) {
qCDebug(KWIN_OPENGL) << "OpenGL 2.0 is not supported";
init_ok = false;
return;
}
const QSize &s = screens()->size();
GLRenderTarget::setVirtualScreenSize(s);
GLRenderTarget::setVirtualScreenGeometry(screens()->geometry());
// push one shader on the stack so that one is always bound
ShaderManager::instance()->pushShader(ShaderTrait::MapTexture);
if (checkGLError("Init")) {
qCCritical(KWIN_OPENGL) << "OpenGL 2 compositing setup failed";
init_ok = false;
return; // error
}
// It is not legal to not have a vertex array object bound in a core context
if (!GLPlatform::instance()->isGLES() && hasGLExtension(QByteArrayLiteral("GL_ARB_vertex_array_object"))) {
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
}
if (!ShaderManager::instance()->selfTest()) {
qCCritical(KWIN_OPENGL) << "ShaderManager self test failed";
init_ok = false;
return;
}
m_debug = qstrcmp(qgetenv("KWIN_GL_DEBUG"), "1") == 0;
initDebugOutput();
@ -104,6 +134,8 @@ SceneOpenGL::SceneOpenGL(OpenGLBackend *backend, QObject *parent)
if (options->isGlStrictBindingFollowsDriver()) {
options->setGlStrictBinding(!glPlatform->supports(LooseBinding));
}
qCDebug(KWIN_OPENGL) << "OpenGL 2 compositing successfully initialized";
}
SceneOpenGL::~SceneOpenGL()
@ -111,6 +143,10 @@ SceneOpenGL::~SceneOpenGL()
if (init_ok) {
makeOpenGLContextCurrent();
}
if (m_lanczosFilter) {
delete m_lanczosFilter;
m_lanczosFilter = nullptr;
}
SceneOpenGL::EffectFrame::cleanup();
// backend might be still needed for a different scene
@ -207,8 +243,8 @@ SceneOpenGL *SceneOpenGL::createScene(QObject *parent)
}
SceneOpenGL *scene = nullptr;
// first let's try an OpenGL 2 scene
if (SceneOpenGL2::supported(backend.data())) {
scene = new SceneOpenGL2(backend.take(), parent);
if (SceneOpenGL::supported(backend.data())) {
scene = new SceneOpenGL(backend.take(), parent);
if (scene->initFailed()) {
delete scene;
scene = nullptr;
@ -275,7 +311,7 @@ void SceneOpenGL::handleGraphicsReset(GLenum status)
* Render cursor texture in case hardware cursor is disabled.
* Useful for screen recording apps or backends that can't do planes.
*/
void SceneOpenGL2::paintCursor(const QRegion &rendered)
void SceneOpenGL::paintCursor(const QRegion &rendered)
{
Cursor* cursor = Cursors::self()->currentCursor();
@ -627,6 +663,11 @@ bool SceneOpenGL::animationsSupported() const
return !GLPlatform::instance()->isSoftwareEmulation();
}
CompositingType SceneOpenGL::compositingType() const
{
return OpenGLCompositing;
}
QVector<QByteArray> SceneOpenGL::openGLPlatformInterfaceExtensions() const
{
return m_backend->extensions().toVector();
@ -652,10 +693,7 @@ SurfaceTexture *SceneOpenGL::createSurfaceTextureX11(SurfacePixmapX11 *pixmap)
return m_backend->createSurfaceTextureX11(pixmap);
}
//****************************************
// SceneOpenGL2
//****************************************
bool SceneOpenGL2::supported(OpenGLBackend *backend)
bool SceneOpenGL::supported(OpenGLBackend *backend)
{
const QByteArray forceEnv = qgetenv("KWIN_COMPOSE");
if (!forceEnv.isEmpty()) {
@ -677,72 +715,19 @@ bool SceneOpenGL2::supported(OpenGLBackend *backend)
return true;
}
SceneOpenGL2::SceneOpenGL2(OpenGLBackend *backend, QObject *parent)
: SceneOpenGL(backend, parent)
, m_lanczosFilter(nullptr)
{
if (!init_ok) {
// base ctor already failed
return;
}
// We only support the OpenGL 2+ shader API, not GL_ARB_shader_objects
if (!hasGLVersion(2, 0)) {
qCDebug(KWIN_OPENGL) << "OpenGL 2.0 is not supported";
init_ok = false;
return;
}
const QSize &s = screens()->size();
GLRenderTarget::setVirtualScreenSize(s);
GLRenderTarget::setVirtualScreenGeometry(screens()->geometry());
// push one shader on the stack so that one is always bound
ShaderManager::instance()->pushShader(ShaderTrait::MapTexture);
if (checkGLError("Init")) {
qCCritical(KWIN_OPENGL) << "OpenGL 2 compositing setup failed";
init_ok = false;
return; // error
}
// It is not legal to not have a vertex array object bound in a core context
if (!GLPlatform::instance()->isGLES() && hasGLExtension(QByteArrayLiteral("GL_ARB_vertex_array_object"))) {
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
}
if (!ShaderManager::instance()->selfTest()) {
qCCritical(KWIN_OPENGL) << "ShaderManager self test failed";
init_ok = false;
return;
}
qCDebug(KWIN_OPENGL) << "OpenGL 2 compositing successfully initialized";
init_ok = true;
}
SceneOpenGL2::~SceneOpenGL2()
{
if (m_lanczosFilter) {
makeOpenGLContextCurrent();
delete m_lanczosFilter;
m_lanczosFilter = nullptr;
}
}
void SceneOpenGL2::updateProjectionMatrix(const QRect &rect)
void SceneOpenGL::updateProjectionMatrix(const QRect &rect)
{
m_projectionMatrix = Scene::createProjectionMatrix(rect);
}
void SceneOpenGL2::paintSimpleScreen(int mask, const QRegion &region)
void SceneOpenGL::paintSimpleScreen(int mask, const QRegion &region)
{
m_screenProjectionMatrix = m_projectionMatrix;
Scene::paintSimpleScreen(mask, region);
}
void SceneOpenGL2::paintGenericScreen(int mask, const ScreenPaintData &data)
void SceneOpenGL::paintGenericScreen(int mask, const ScreenPaintData &data)
{
const QMatrix4x4 screenMatrix = transformation(mask, data);
@ -751,7 +736,7 @@ void SceneOpenGL2::paintGenericScreen(int mask, const ScreenPaintData &data)
Scene::paintGenericScreen(mask, data);
}
void SceneOpenGL2::doPaintBackground(const QVector< float >& vertices)
void SceneOpenGL::doPaintBackground(const QVector< float >& vertices)
{
GLVertexBuffer *vbo = GLVertexBuffer::streamingBuffer();
vbo->reset();
@ -764,12 +749,12 @@ void SceneOpenGL2::doPaintBackground(const QVector< float >& vertices)
vbo->render(GL_TRIANGLES);
}
Scene::Window *SceneOpenGL2::createWindow(Toplevel *t)
Scene::Window *SceneOpenGL::createWindow(Toplevel *t)
{
return new OpenGLWindow(t, this);
}
void SceneOpenGL2::finalDrawWindow(EffectWindowImpl* w, int mask, const QRegion &region, WindowPaintData& data)
void SceneOpenGL::finalDrawWindow(EffectWindowImpl* w, int mask, const QRegion &region, WindowPaintData& data)
{
if (waylandServer() && waylandServer()->isScreenLocked() && !w->window()->isLockScreen() && !w->window()->isInputMethod()) {
return;
@ -777,7 +762,7 @@ void SceneOpenGL2::finalDrawWindow(EffectWindowImpl* w, int mask, const QRegion
performPaintWindow(w, mask, region, data);
}
void SceneOpenGL2::performPaintWindow(EffectWindowImpl* w, int mask, const QRegion &region, WindowPaintData& data)
void SceneOpenGL::performPaintWindow(EffectWindowImpl* w, int mask, const QRegion &region, WindowPaintData& data)
{
if (mask & PAINT_WINDOW_LANCZOS) {
if (!m_lanczosFilter) {
@ -965,8 +950,6 @@ void OpenGLWindow::createRenderNode(Item *item, RenderContext *context)
QMatrix4x4 OpenGLWindow::modelViewProjectionMatrix(int mask, const WindowPaintData &data) const
{
SceneOpenGL2 *scene = static_cast<SceneOpenGL2 *>(m_scene);
const QMatrix4x4 pMatrix = data.projectionMatrix();
const QMatrix4x4 mvMatrix = data.modelViewMatrix();
@ -982,9 +965,9 @@ QMatrix4x4 OpenGLWindow::modelViewProjectionMatrix(int mask, const WindowPaintDa
// with the default projection matrix. If the effect hasn't specified a
// model-view matrix, mvMatrix will be the identity matrix.
if (mask & Scene::PAINT_SCREEN_TRANSFORMED)
return scene->screenProjectionMatrix() * mvMatrix;
return m_scene->screenProjectionMatrix() * mvMatrix;
return scene->projectionMatrix() * mvMatrix;
return m_scene->projectionMatrix() * mvMatrix;
}
static QMatrix4x4 transformForPaintData(int mask, const WindowPaintData &data)

View file

@ -30,6 +30,7 @@ class KWIN_EXPORT SceneOpenGL
Q_OBJECT
public:
class EffectFrame;
explicit SceneOpenGL(OpenGLBackend *backend, QObject *parent = nullptr);
~SceneOpenGL() override;
bool initFailed() const override;
void paint(AbstractOutput *output, const QRegion &damage, const QList<Toplevel *> &windows,
@ -41,7 +42,6 @@ public:
void doneOpenGLContextCurrent() override;
bool supportsNativeFence() const override;
DecorationRenderer *createDecorationRenderer(Decoration::DecoratedClientImpl *impl) override;
virtual QMatrix4x4 projectionMatrix() const = 0;
bool animationsSupported() const override;
SurfaceTexture *createSurfaceTextureInternal(SurfacePixmapInternal *pixmap) override;
SurfaceTexture *createSurfaceTextureX11(SurfacePixmapX11 *pixmap) override;
@ -54,13 +54,17 @@ public:
return m_backend;
}
CompositingType compositingType() const override;
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(QObject *parent);
static bool supported(OpenGLBackend *backend);
protected:
SceneOpenGL(OpenGLBackend *backend, QObject *parent = nullptr);
void paintBackground(const QRegion &region) override;
void aboutToStartPainting(AbstractOutput *output, const QRegion &damage) override;
void extendPaintRegion(QRegion &region, bool opaqueFullscreen) override;
@ -68,55 +72,29 @@ protected:
void paintDesktop(int desktop, int mask, const QRegion &region, ScreenPaintData &data) override;
void paintEffectQuickView(EffectQuickView *w) override;
void handleGraphicsReset(GLenum status);
virtual void doPaintBackground(const QVector<float> &vertices) = 0;
virtual void updateProjectionMatrix(const QRect &geometry) = 0;
protected:
bool init_ok;
private:
bool viewportLimitsMatched(const QSize &size) const;
private:
bool m_resetOccurred = false;
bool m_debug;
OpenGLBackend *m_backend;
};
class SceneOpenGL2 : public SceneOpenGL
{
Q_OBJECT
public:
explicit SceneOpenGL2(OpenGLBackend *backend, QObject *parent = nullptr);
~SceneOpenGL2() override;
CompositingType compositingType() const override {
return OpenGLCompositing;
}
static bool supported(OpenGLBackend *backend);
QMatrix4x4 projectionMatrix() const override { return m_projectionMatrix; }
QMatrix4x4 screenProjectionMatrix() const override { return m_screenProjectionMatrix; }
protected:
void paintSimpleScreen(int mask, const QRegion &region) override;
void paintGenericScreen(int mask, const ScreenPaintData &data) override;
void doPaintBackground(const QVector< float >& vertices) override;
Scene::Window *createWindow(Toplevel *t) override;
void finalDrawWindow(EffectWindowImpl* w, int mask, const QRegion &region, WindowPaintData& data) override;
void updateProjectionMatrix(const QRect &geometry) override;
void paintCursor(const QRegion &region) override;
private:
bool viewportLimitsMatched(const QSize &size) const;
void doPaintBackground(const QVector< float >& vertices);
void updateProjectionMatrix(const QRect &geometry);
void performPaintWindow(EffectWindowImpl* w, int mask, const QRegion &region, WindowPaintData& data);
void handleGraphicsReset(GLenum status);
LanczosFilter *m_lanczosFilter;
bool init_ok = true;
bool m_resetOccurred = false;
bool m_debug = false;
OpenGLBackend *m_backend;
LanczosFilter *m_lanczosFilter = nullptr;
QScopedPointer<GLTexture> m_cursorTexture;
bool m_cursorTextureDirty = false;
QMatrix4x4 m_projectionMatrix;
QMatrix4x4 m_screenProjectionMatrix;
GLuint vao;
GLuint vao = 0;
};
class OpenGLWindow final : public Scene::Window