From b7bd8472f2111405f04ef4e44cc95bb597135fc8 Mon Sep 17 00:00:00 2001 From: Vlad Zahorodnii Date: Mon, 12 Oct 2020 09:45:05 +0300 Subject: [PATCH] scene: Reduce the call cost of Platform::supportsQpaContext() Every time Platform::supportsQpaContext() is called, we go through the list of supported extensions and perform a string comparison op. This is not really cheap. --- platform.cpp | 2 +- .../scenes/opengl/abstract_egl_backend.cpp | 1 + platformsupport/scenes/opengl/backend.h | 25 +++++++++---------- plugins/platforms/virtual/egl_gbm_backend.cpp | 6 ++--- plugins/scenes/opengl/scene_opengl.cpp | 5 ++++ plugins/scenes/opengl/scene_opengl.h | 1 + scene.cpp | 5 ++++ scene.h | 1 + 8 files changed, 28 insertions(+), 18 deletions(-) diff --git a/platform.cpp b/platform.cpp index a2112d2092..5cdc1bd942 100644 --- a/platform.cpp +++ b/platform.cpp @@ -416,7 +416,7 @@ void Platform::warpPointer(const QPointF &globalPos) bool Platform::supportsQpaContext() const { if (Compositor *c = Compositor::self()) { - return c->scene()->openGLPlatformInterfaceExtensions().contains(QByteArrayLiteral("EGL_KHR_surfaceless_context")); + return c->scene()->supportsSurfacelessContext(); } return false; } diff --git a/platformsupport/scenes/opengl/abstract_egl_backend.cpp b/platformsupport/scenes/opengl/abstract_egl_backend.cpp index 1892387cf5..54c32f91ae 100644 --- a/platformsupport/scenes/opengl/abstract_egl_backend.cpp +++ b/platformsupport/scenes/opengl/abstract_egl_backend.cpp @@ -103,6 +103,7 @@ bool AbstractEglBackend::initEglAPI() qCDebug(KWIN_OPENGL) << "EGL version: " << major << "." << minor; const QByteArray eglExtensions = eglQueryString(m_display, EGL_EXTENSIONS); setExtensions(eglExtensions.split(' ')); + setSupportsSurfacelessContext(hasExtension(QByteArrayLiteral("EGL_KHR_surfaceless_context"))); return true; } diff --git a/platformsupport/scenes/opengl/backend.h b/platformsupport/scenes/opengl/backend.h index 53f3143275..c7fdb564de 100644 --- a/platformsupport/scenes/opengl/backend.h +++ b/platformsupport/scenes/opengl/backend.h @@ -166,11 +166,9 @@ public: return m_haveSwapBuffersWithDamage; } - /** - * @returns whether the context is surfaceless - */ - bool isSurfaceLessContext() const { - return m_surfaceLessContext; + bool supportsSurfacelessContext() const + { + return m_haveSurfacelessContext; } /** @@ -267,6 +265,11 @@ protected: m_haveSwapBuffersWithDamage = value; } + void setSupportsSurfacelessContext(bool value) + { + m_haveSurfacelessContext = value; + } + /** * @return const QRegion& Damage of previously rendered frame */ @@ -285,13 +288,6 @@ protected: m_renderTimer.start(); } - /** - * @param set whether the context is surface less - */ - void setSurfaceLessContext(bool set) { - m_surfaceLessContext = set; - } - /** * Sets the platform-specific @p extensions. * @@ -323,6 +319,10 @@ private: */ bool m_havePartialUpdate; bool m_haveSwapBuffersWithDamage = false; + /** + * @brief Whether the backend supports EGL_KHR_surfaceless_context. + */ + bool m_haveSurfacelessContext = false; /** * @brief Whether the initialization failed, of course default to @c false. */ @@ -339,7 +339,6 @@ private: * @brief Timer to measure how long a frame renders. */ QElapsedTimer m_renderTimer; - bool m_surfaceLessContext = false; QList m_extensions; }; diff --git a/plugins/platforms/virtual/egl_gbm_backend.cpp b/plugins/platforms/virtual/egl_gbm_backend.cpp index 81689d49ce..e0e12723e8 100644 --- a/plugins/platforms/virtual/egl_gbm_backend.cpp +++ b/plugins/platforms/virtual/egl_gbm_backend.cpp @@ -103,16 +103,14 @@ bool EglGbmBackend::initRenderingContext() { initBufferConfigs(); - const char* eglExtensionsCString = eglQueryString(eglDisplay(), EGL_EXTENSIONS); - const QList extensions = QByteArray::fromRawData(eglExtensionsCString, qstrlen(eglExtensionsCString)).split(' '); - if (!extensions.contains(QByteArrayLiteral("EGL_KHR_surfaceless_context"))) { + if (!supportsSurfacelessContext()) { + qCWarning(KWIN_VIRTUAL) << "EGL_KHR_surfaceless_context extension is unavailable"; return false; } if (!createContext()) { return false; } - setSurfaceLessContext(true); return makeCurrent(); } diff --git a/plugins/scenes/opengl/scene_opengl.cpp b/plugins/scenes/opengl/scene_opengl.cpp index 7a628752f8..79f3445784 100644 --- a/plugins/scenes/opengl/scene_opengl.cpp +++ b/plugins/scenes/opengl/scene_opengl.cpp @@ -860,6 +860,11 @@ void SceneOpenGL::doneOpenGLContextCurrent() m_backend->doneCurrent(); } +bool SceneOpenGL::supportsSurfacelessContext() const +{ + return m_backend->supportsSurfacelessContext(); +} + Scene::EffectFrame *SceneOpenGL::createEffectFrame(EffectFrameImpl *frame) { return new SceneOpenGL::EffectFrame(frame, this); diff --git a/plugins/scenes/opengl/scene_opengl.h b/plugins/scenes/opengl/scene_opengl.h index 98c683226f..d2c281b84a 100644 --- a/plugins/scenes/opengl/scene_opengl.h +++ b/plugins/scenes/opengl/scene_opengl.h @@ -45,6 +45,7 @@ public: bool syncsToVBlank() const override; bool makeOpenGLContextCurrent() override; void doneOpenGLContextCurrent() override; + bool supportsSurfacelessContext() const override; Decoration::Renderer *createDecorationRenderer(Decoration::DecoratedClientImpl *impl) override; void triggerFence() override; virtual QMatrix4x4 projectionMatrix() const = 0; diff --git a/scene.cpp b/scene.cpp index 9197e8026e..7b3373e992 100644 --- a/scene.cpp +++ b/scene.cpp @@ -681,6 +681,11 @@ void Scene::doneOpenGLContextCurrent() { } +bool Scene::supportsSurfacelessContext() const +{ + return false; +} + void Scene::triggerFence() { } diff --git a/scene.h b/scene.h index e5b25df978..6f846a99b7 100644 --- a/scene.h +++ b/scene.h @@ -139,6 +139,7 @@ public: virtual bool makeOpenGLContextCurrent(); virtual void doneOpenGLContextCurrent(); + virtual bool supportsSurfacelessContext() const; virtual QMatrix4x4 screenProjectionMatrix() const;