From 613d76f2df35ff559036a1fd9d922268bd616105 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Tue, 26 Jan 2016 15:38:42 +0100 Subject: [PATCH] [effects] Combine all shaders in resources One resource is used for shader version 1.10 and one for version 1.40. The ideas behind this change is to remove the locating of the shader sources and also to fix that user provided shaders could be loaded instead of the original ones (possible attack vector on Wayland). To simplify the ShaderManager provides a new method call to load the shader from the resource. This means the effects don't need to duplicate the check for the shader version any more and also don't need to duplicate the file reading functionality. REVIEW: 126905 --- effects/CMakeLists.txt | 2 ++ effects/coverswitch/CMakeLists.txt | 7 ---- effects/coverswitch/coverswitch.cpp | 10 +----- effects/cube/CMakeLists.txt | 16 --------- effects/cube/cube.cpp | 38 +++------------------ effects/cube/cube.h | 2 -- effects/invert/CMakeLists.txt | 8 ----- effects/invert/invert.cpp | 14 +------- effects/logout/CMakeLists.txt | 13 ------- effects/logout/logout.cpp | 24 +++---------- effects/logout/logout.h | 1 - effects/lookingglass/CMakeLists.txt | 8 ----- effects/lookingglass/lookingglass.cpp | 12 +------ effects/shaders.qrc | 26 ++++++++++++++ effects/startupfeedback/CMakeLists.txt | 5 --- effects/startupfeedback/startupfeedback.cpp | 16 +++------ libkwineffects/kwinglutils.cpp | 34 ++++++++++++++++++ libkwineffects/kwinglutils.h | 24 +++++++++++++ 18 files changed, 101 insertions(+), 159 deletions(-) create mode 100644 effects/shaders.qrc diff --git a/effects/CMakeLists.txt b/effects/CMakeLists.txt index dec50a9291..e3beebf2ca 100644 --- a/effects/CMakeLists.txt +++ b/effects/CMakeLists.txt @@ -96,6 +96,8 @@ set( kwin4_effect_builtins_sources zoom/zoom.cpp ) +qt5_add_resources( kwin4_effect_builtins_sources shaders.qrc ) + kconfig_add_kcfg_files(kwin4_effect_builtins_sources blur/blurconfig.kcfgc cube/cubeslideconfig.kcfgc diff --git a/effects/coverswitch/CMakeLists.txt b/effects/coverswitch/CMakeLists.txt index bb67b45283..c1a6aed917 100644 --- a/effects/coverswitch/CMakeLists.txt +++ b/effects/coverswitch/CMakeLists.txt @@ -1,12 +1,5 @@ ####################################### # Effect -install( FILES - shaders/1.10/coverswitch-reflection.glsl - DESTINATION ${DATA_INSTALL_DIR}/kwin/shaders/1.10 ) -install( FILES - shaders/1.40/coverswitch-reflection.glsl - DESTINATION ${DATA_INSTALL_DIR}/kwin/shaders/1.40 ) - ####################################### # Config diff --git a/effects/coverswitch/coverswitch.cpp b/effects/coverswitch/coverswitch.cpp index 807d1d6da3..8b91676646 100644 --- a/effects/coverswitch/coverswitch.cpp +++ b/effects/coverswitch/coverswitch.cpp @@ -61,15 +61,7 @@ CoverSwitchEffect::CoverSwitchEffect() captionFont.setPointSize(captionFont.pointSize() * 2); if (effects->compositingType() == OpenGL2Compositing) { - QString shadersDir = QStringLiteral("kwin/shaders/1.10/"); - const qint64 coreVersionNumber = GLPlatform::instance()->isGLES() ? kVersionNumber(3, 0) : kVersionNumber(1, 40); - if (GLPlatform::instance()->glslVersion() >= coreVersionNumber) - shadersDir = QStringLiteral("kwin/shaders/1.40/"); - const QString fragmentshader = QStandardPaths::locate(QStandardPaths::GenericDataLocation, shadersDir + QStringLiteral("coverswitch-reflection.glsl")); - QFile ff(fragmentshader); - if (ff.open(QIODevice::ReadOnly)) { - m_reflectionShader = ShaderManager::instance()->generateCustomShader(ShaderTrait::MapTexture, QByteArray(), ff.readAll()); - } + m_reflectionShader = ShaderManager::instance()->generateShaderFromResources(ShaderTrait::MapTexture, QString(), QStringLiteral("coverswitch-reflection.glsl")); } else { m_reflectionShader = NULL; } diff --git a/effects/cube/CMakeLists.txt b/effects/cube/CMakeLists.txt index 30a6f6e26f..91be75fe38 100644 --- a/effects/cube/CMakeLists.txt +++ b/effects/cube/CMakeLists.txt @@ -6,22 +6,6 @@ install( FILES data/cubecap.png DESTINATION ${DATA_INSTALL_DIR}/kwin ) -install( FILES - data/1.10/cube-cap.glsl - data/1.10/cube-reflection.glsl - data/1.10/cylinder.vert - data/1.10/sphere.vert - DESTINATION ${DATA_INSTALL_DIR}/kwin/shaders/1.10 -) - -install( FILES - data/1.40/cube-cap.glsl - data/1.40/cube-reflection.glsl - data/1.40/cylinder.vert - data/1.40/sphere.vert - DESTINATION ${DATA_INSTALL_DIR}/kwin/shaders/1.40 -) - ####################################### # Config diff --git a/effects/cube/cube.cpp b/effects/cube/cube.cpp index 300beaad15..9a32f96f39 100644 --- a/effects/cube/cube.cpp +++ b/effects/cube/cube.cpp @@ -89,28 +89,15 @@ CubeEffect::CubeEffect() , zOrderingFactor(0.0f) , mAddedHeightCoeff1(0.0f) , mAddedHeightCoeff2(0.0f) - , m_shadersDir(QStringLiteral("kwin/shaders/1.10/")) , m_cubeCapBuffer(NULL) , m_proxy(this) { desktopNameFont.setBold(true); desktopNameFont.setPointSize(14); - const qint64 coreVersionNumber = GLPlatform::instance()->isGLES() ? kVersionNumber(3, 0) : kVersionNumber(1, 40); - if (GLPlatform::instance()->glslVersion() >= coreVersionNumber) - m_shadersDir = QStringLiteral("kwin/shaders/1.40/"); - if (effects->compositingType() == OpenGL2Compositing) { - const QString fragmentshader = QStandardPaths::locate(QStandardPaths::GenericDataLocation, m_shadersDir + QStringLiteral("cube-reflection.glsl")); - QFile ffr(fragmentshader); - if (ffr.open(QIODevice::ReadOnly)) { - m_reflectionShader = ShaderManager::instance()->generateCustomShader(ShaderTrait::MapTexture, QByteArray(), ffr.readAll()); - } - const QString capshader = QStandardPaths::locate(QStandardPaths::GenericDataLocation, m_shadersDir + QStringLiteral("cube-cap.glsl")); - QFile ff(capshader); - if (ff.open(QIODevice::ReadOnly)) { - m_capShader = ShaderManager::instance()->generateCustomShader(ShaderTrait::MapTexture, QByteArray(), ff.readAll()); - } + m_reflectionShader = ShaderManager::instance()->generateShaderFromResources(ShaderTrait::MapTexture, QString(), QStringLiteral("cube-reflection.glsl")); + m_capShader = ShaderManager::instance()->generateShaderFromResources(ShaderTrait::MapTexture, QString(), QStringLiteral("cube-cap.glsl")); } else { m_reflectionShader = NULL; m_capShader = NULL; @@ -301,20 +288,8 @@ bool CubeEffect::loadShader() if (!(GLPlatform::instance()->supports(GLSL) && (effects->compositingType() == OpenGL2Compositing))) return false; - QString cylinderVertexshader = QStandardPaths::locate(QStandardPaths::GenericDataLocation, m_shadersDir + QStringLiteral("cylinder.vert")); - QString sphereVertexshader = QStandardPaths::locate(QStandardPaths::GenericDataLocation, m_shadersDir + QStringLiteral("sphere.vert")); - if (cylinderVertexshader.isEmpty() || sphereVertexshader.isEmpty()) { - qCCritical(KWINEFFECTS) << "Couldn't locate shader files"; - return false; - } - QFile cvf(cylinderVertexshader); - if (!cvf.open(QIODevice::ReadOnly)) { - qCCritical(KWINEFFECTS) << "The cylinder shader couldn't be opened!"; - return false; - } - - cylinderShader = ShaderManager::instance()->generateCustomShader(ShaderTrait::MapTexture | ShaderTrait::AdjustSaturation | ShaderTrait::Modulate, cvf.readAll(), QByteArray()); + cylinderShader = ShaderManager::instance()->generateShaderFromResources(ShaderTrait::MapTexture | ShaderTrait::AdjustSaturation | ShaderTrait::Modulate, QStringLiteral("cylinder.vert"), QString()); if (!cylinderShader->isValid()) { qCCritical(KWINEFFECTS) << "The cylinder shader failed to load!"; return false; @@ -325,12 +300,7 @@ bool CubeEffect::loadShader() cylinderShader->setUniform("width", (float)rect.width() * 0.5f); } - QFile svf(sphereVertexshader); - if (!svf.open(QIODevice::ReadOnly)) { - qCCritical(KWINEFFECTS) << "The sphere shader couldn't be opened!"; - return false; - } - sphereShader = ShaderManager::instance()->generateCustomShader(ShaderTrait::MapTexture | ShaderTrait::AdjustSaturation | ShaderTrait::Modulate, svf.readAll(), QByteArray()); + sphereShader = ShaderManager::instance()->generateShaderFromResources(ShaderTrait::MapTexture | ShaderTrait::AdjustSaturation | ShaderTrait::Modulate, QStringLiteral("sphere.vert"), QString()); if (!sphereShader->isValid()) { qCCritical(KWINEFFECTS) << "The sphere shader failed to load!"; return false; diff --git a/effects/cube/cube.h b/effects/cube/cube.h index 3a01cbfc86..fc2e9dc767 100644 --- a/effects/cube/cube.h +++ b/effects/cube/cube.h @@ -231,8 +231,6 @@ private: float mAddedHeightCoeff1; float mAddedHeightCoeff2; - QString m_shadersDir; - QMatrix4x4 m_rotationMatrix; QMatrix4x4 m_reflectionMatrix; QMatrix4x4 m_textureMirrorMatrix; diff --git a/effects/invert/CMakeLists.txt b/effects/invert/CMakeLists.txt index 3a6689e9db..c81978d0e1 100644 --- a/effects/invert/CMakeLists.txt +++ b/effects/invert/CMakeLists.txt @@ -1,14 +1,6 @@ ####################################### # Effect -# Data files -install( FILES - data/1.10/invert.frag - DESTINATION ${DATA_INSTALL_DIR}/kwin/shaders/1.10 ) -install( FILES - data/1.40/invert.frag - DESTINATION ${DATA_INSTALL_DIR}/kwin/shaders/1.40 ) - ####################################### # Config set(kwin_invert_config_SRCS invert_config.cpp) diff --git a/effects/invert/invert.cpp b/effects/invert/invert.cpp index 4243f6bf21..78d65c26b1 100644 --- a/effects/invert/invert.cpp +++ b/effects/invert/invert.cpp @@ -73,19 +73,7 @@ bool InvertEffect::loadData() { m_inited = true; - QString shadersDir = QStringLiteral("kwin/shaders/1.10/"); - const qint64 coreVersionNumber = GLPlatform::instance()->isGLES() ? kVersionNumber(3, 0) : kVersionNumber(1, 40); - if (GLPlatform::instance()->glslVersion() >= coreVersionNumber) - shadersDir = QStringLiteral("kwin/shaders/1.40/"); - const QString fragmentshader = QStandardPaths::locate(QStandardPaths::GenericDataLocation, shadersDir + QStringLiteral("invert.frag")); - - QFile ff(fragmentshader); - if (!ff.open(QIODevice::ReadOnly)) { - qCCritical(KWINEFFECTS) << "Couldn't open" << fragmentshader << "for reading!"; - return false; - } - - m_shader = ShaderManager::instance()->generateCustomShader(ShaderTrait::MapTexture, QByteArray(), ff.readAll()); + m_shader = ShaderManager::instance()->generateShaderFromResources(ShaderTrait::MapTexture, QString(), QStringLiteral("invert.frag")); if (!m_shader->isValid()) { qCCritical(KWINEFFECTS) << "The shader failed to load!"; return false; diff --git a/effects/logout/CMakeLists.txt b/effects/logout/CMakeLists.txt index 865b493727..0a49a30567 100644 --- a/effects/logout/CMakeLists.txt +++ b/effects/logout/CMakeLists.txt @@ -7,16 +7,3 @@ set( kwin4_effect_builtins_sources ${kwin4_effect_builtins_sources} ) kconfig_add_kcfg_files(kwin4_effect_builtins_sources logout/logoutconfig.kcfgc) - -# Data files -install( FILES - logout/data/1.10/vignetting.frag - logout/data/1.10/logout-blur.frag - DESTINATION ${DATA_INSTALL_DIR}/kwin/shaders/1.10 -) - -install( FILES - logout/data/1.40/vignetting.frag - logout/data/1.40/logout-blur.frag - DESTINATION ${DATA_INSTALL_DIR}/kwin/shaders/1.40 -) diff --git a/effects/logout/logout.cpp b/effects/logout/logout.cpp index a25fe8b54f..f521e2d99d 100644 --- a/effects/logout/logout.cpp +++ b/effects/logout/logout.cpp @@ -67,7 +67,6 @@ LogoutEffect::LogoutEffect() , ignoredWindows() , m_vignettingShader(NULL) , m_blurShader(NULL) - , m_shadersDir(QStringLiteral("kwin/shaders/1.10/")) { if (logoutAtom.isValid()) { // Persistent effect @@ -81,12 +80,6 @@ LogoutEffect::LogoutEffect() connect(effects, SIGNAL(windowClosed(KWin::EffectWindow*)), this, SLOT(slotWindowClosed(KWin::EffectWindow*))); connect(effects, SIGNAL(windowDeleted(KWin::EffectWindow*)), this, SLOT(slotWindowDeleted(KWin::EffectWindow*))); connect(effects, SIGNAL(propertyNotify(KWin::EffectWindow*,long)), this, SLOT(slotPropertyNotify(KWin::EffectWindow*,long))); - - if (effects->isOpenGLCompositing()) { - const qint64 coreVersionNumber = GLPlatform::instance()->isGLES() ? kVersionNumber(3, 0) : kVersionNumber(1, 40); - if (GLPlatform::instance()->glslVersion() >= coreVersionNumber) - m_shadersDir = QStringLiteral("kwin/shaders/1.40/"); - } } LogoutEffect::~LogoutEffect() @@ -304,12 +297,7 @@ bool LogoutEffect::isLogoutDialog(EffectWindow* w) void LogoutEffect::renderVignetting(const QMatrix4x4 &projection) { if (!m_vignettingShader) { - QFile ff(QStandardPaths::locate(QStandardPaths::GenericDataLocation, m_shadersDir + QStringLiteral("vignetting.frag"))); - if (!ff.open(QIODevice::ReadOnly)) { - qCDebug(KWINEFFECTS) << "Could not open Vignetting Shader"; - return; - } - m_vignettingShader = ShaderManager::instance()->generateCustomShader(ShaderTrait(), QByteArray(), ff.readAll()); + m_vignettingShader = ShaderManager::instance()->generateShaderFromResources(ShaderTrait(), QString(), QStringLiteral("vignetting.frag")); if (!m_vignettingShader->isValid()) { qCDebug(KWINEFFECTS) << "Vignetting Shader failed to load"; return; @@ -351,16 +339,12 @@ void LogoutEffect::renderVignetting(const QMatrix4x4 &projection) void LogoutEffect::renderBlurTexture(const QMatrix4x4 &projection) { if (!m_blurShader) { - QFile ff(QStandardPaths::locate(QStandardPaths::GenericDataLocation, m_shadersDir + QStringLiteral("logout-blur.frag"))); - if (!ff.open(QIODevice::ReadOnly)) { - qCDebug(KWINEFFECTS) << "Could not open Logout Blur Shader"; - return; - } - m_blurShader = ShaderManager::instance()->generateCustomShader(ShaderTrait::MapTexture, QByteArray(), ff.readAll()); + m_blurShader = ShaderManager::instance()->generateShaderFromResources(ShaderTrait::MapTexture, QString(), QStringLiteral("logout-blur.frag")); if (!m_blurShader->isValid()) { qCDebug(KWINEFFECTS) << "Logout blur shader failed to load"; } - } else if (!m_blurShader->isValid()) { + } + if (!m_blurShader->isValid()) { // shader is broken - no need to continue here return; } diff --git a/effects/logout/logout.h b/effects/logout/logout.h index 0d88e42c87..db04e9d92e 100644 --- a/effects/logout/logout.h +++ b/effects/logout/logout.h @@ -96,7 +96,6 @@ private: QList m_windows; GLShader *m_vignettingShader; GLShader *m_blurShader; - QString m_shadersDir; }; } // namespace diff --git a/effects/lookingglass/CMakeLists.txt b/effects/lookingglass/CMakeLists.txt index bce627ac6c..4e5c3efdb7 100644 --- a/effects/lookingglass/CMakeLists.txt +++ b/effects/lookingglass/CMakeLists.txt @@ -1,14 +1,6 @@ ####################################### # Effect -# Data files -install( FILES - data/1.10/lookingglass.frag - DESTINATION ${DATA_INSTALL_DIR}/kwin/shaders/1.10 ) -install( FILES - data/1.40/lookingglass.frag - DESTINATION ${DATA_INSTALL_DIR}/kwin/shaders/1.40 ) - ####################################### # Config set(kwin_lookingglass_config_SRCS lookingglass_config.cpp) diff --git a/effects/lookingglass/lookingglass.cpp b/effects/lookingglass/lookingglass.cpp index 4173e8eb8f..4c9c1d223e 100644 --- a/effects/lookingglass/lookingglass.cpp +++ b/effects/lookingglass/lookingglass.cpp @@ -112,17 +112,7 @@ bool LookingGlassEffect::loadData() return false; } - QString shadersDir = QStringLiteral("kwin/shaders/1.10/"); - const qint64 coreVersionNumber = GLPlatform::instance()->isGLES() ? kVersionNumber(3, 0) : kVersionNumber(1, 40); - if (GLPlatform::instance()->glslVersion() >= coreVersionNumber) - shadersDir = QStringLiteral("kwin/shaders/1.40/"); - const QString fragmentshader = QStandardPaths::locate(QStandardPaths::GenericDataLocation, shadersDir + QStringLiteral("lookingglass.frag")); - QFile ff(fragmentshader); - if (!ff.open(QIODevice::ReadOnly)) { - qCCritical(KWINEFFECTS) << "Failed to read shader!"; - return false; - } - m_shader = ShaderManager::instance()->generateCustomShader(ShaderTrait::MapTexture, QByteArray(), ff.readAll()); + m_shader = ShaderManager::instance()->generateShaderFromResources(ShaderTrait::MapTexture, QString(), QStringLiteral("lookingglass.frag")); if (m_shader->isValid()) { ShaderBinder binder(m_shader); m_shader->setUniform("u_textureSize", QVector2D(screenSize.width(), screenSize.height())); diff --git a/effects/shaders.qrc b/effects/shaders.qrc new file mode 100644 index 0000000000..e08cd77331 --- /dev/null +++ b/effects/shaders.qrc @@ -0,0 +1,26 @@ + + + coverswitch/shaders/1.10/coverswitch-reflection.glsl + cube/data/1.10/cube-cap.glsl + cube/data/1.10/cube-reflection.glsl + cube/data/1.10/cylinder.vert + cube/data/1.10/sphere.vert + invert/data/1.10/invert.frag + logout/data/1.10/logout-blur.frag + logout/data/1.10/vignetting.frag + lookingglass/data/1.10/lookingglass.frag + startupfeedback/data/blinking-startup-fragment.glsl + + + coverswitch/shaders/1.40/coverswitch-reflection.glsl + cube/data/1.40/cube-cap.glsl + cube/data/1.40/cube-reflection.glsl + cube/data/1.40/cylinder.vert + cube/data/1.40/sphere.vert + invert/data/1.40/invert.frag + logout/data/1.40/logout-blur.frag + logout/data/1.40/vignetting.frag + lookingglass/data/1.40/lookingglass.frag + + + diff --git a/effects/startupfeedback/CMakeLists.txt b/effects/startupfeedback/CMakeLists.txt index c105d23c59..19a37836fa 100644 --- a/effects/startupfeedback/CMakeLists.txt +++ b/effects/startupfeedback/CMakeLists.txt @@ -6,10 +6,5 @@ set( kwin4_effect_builtins_sources ${kwin4_effect_builtins_sources} startupfeedback/startupfeedback.cpp ) -# Data files -install( FILES - startupfeedback/data/blinking-startup-fragment.glsl - DESTINATION ${DATA_INSTALL_DIR}/kwin ) - ####################################### # Config diff --git a/effects/startupfeedback/startupfeedback.cpp b/effects/startupfeedback/startupfeedback.cpp index 3019a2fd7b..a948a5f33f 100644 --- a/effects/startupfeedback/startupfeedback.cpp +++ b/effects/startupfeedback/startupfeedback.cpp @@ -130,19 +130,11 @@ void StartupFeedbackEffect::reconfigure(Effect::ReconfigureFlags flags) m_type = BlinkingFeedback; if (effects->compositingType() == OpenGL2Compositing) { delete m_blinkingShader; - m_blinkingShader = 0; - const QString shader = QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("kwin/blinking-startup-fragment.glsl")); - - QFile ff(shader); - if (ff.open(QIODevice::ReadOnly)) { - m_blinkingShader = ShaderManager::instance()->generateCustomShader(ShaderTrait::MapTexture, QByteArray(), ff.readAll()); - if (m_blinkingShader->isValid()) { - qCDebug(KWINEFFECTS) << "Blinking Shader is valid"; - } else { - qCDebug(KWINEFFECTS) << "Blinking Shader is not valid"; - } + m_blinkingShader = ShaderManager::instance()->generateShaderFromResources(ShaderTrait::MapTexture, QString(), QStringLiteral("blinking-startup-fragment.glsl")); + if (m_blinkingShader->isValid()) { + qCDebug(KWINEFFECTS) << "Blinking Shader is valid"; } else { - qCCritical(KWINEFFECTS) << "Couldn't open" << shader << "for reading!"; + qCDebug(KWINEFFECTS) << "Blinking Shader is not valid"; } } } else diff --git a/libkwineffects/kwinglutils.cpp b/libkwineffects/kwinglutils.cpp index ccfa3a5f24..9db648598f 100644 --- a/libkwineffects/kwinglutils.cpp +++ b/libkwineffects/kwinglutils.cpp @@ -644,6 +644,13 @@ void ShaderManager::cleanup() ShaderManager::ShaderManager() { m_debug = qstrcmp(qgetenv("KWIN_GL_DEBUG"), "1") == 0; + + const qint64 coreVersionNumber = GLPlatform::instance()->isGLES() ? kVersionNumber(3, 0) : kVersionNumber(1, 40); + if (GLPlatform::instance()->glslVersion() >= coreVersionNumber) { + m_resourcePath = QStringLiteral(":/effect-shaders-1.40/"); + } else { + m_resourcePath = QStringLiteral(":/effect-shaders-1.10/"); + } } ShaderManager::~ShaderManager() @@ -1003,6 +1010,33 @@ GLShader *ShaderManager::generateCustomShader(ShaderTraits traits, const QByteAr return shader; } +GLShader *ShaderManager::generateShaderFromResources(ShaderTraits traits, const QString &vertexFile, const QString &fragmentFile) +{ + auto loadShaderFile = [this] (const QString &fileName) { + QFile file(m_resourcePath + fileName); + if (file.open(QIODevice::ReadOnly)) { + return file.readAll(); + } + qCCritical(LIBKWINGLUTILS) << "Failed to read shader " << fileName; + return QByteArray(); + }; + QByteArray vertexSource; + QByteArray fragmentSource; + if (!vertexFile.isEmpty()) { + vertexSource = loadShaderFile(vertexFile); + if (vertexSource.isEmpty()) { + return new GLShader(); + } + } + if (!fragmentFile.isEmpty()) { + fragmentSource = loadShaderFile(fragmentFile); + if (fragmentSource.isEmpty()) { + return new GLShader(); + } + } + return generateCustomShader(traits, vertexSource, fragmentSource); +} + GLShader *ShaderManager::shader(ShaderTraits traits) { GLShader *shader = m_shaderHash.value(traits); diff --git a/libkwineffects/kwinglutils.h b/libkwineffects/kwinglutils.h index 8bc6f29b94..3c1ac28deb 100644 --- a/libkwineffects/kwinglutils.h +++ b/libkwineffects/kwinglutils.h @@ -301,6 +301,29 @@ public: **/ GLShader *generateCustomShader(ShaderTraits traits, const QByteArray &vertexSource = QByteArray(), const QByteArray &fragmentSource = QByteArray()); + /** + * Creates a custom shader with the given @p traits and custom @p vertexFile and or @p fragmentFile. + * The file names specified in @p vertexFile and @p fragmentFile are relative paths to the shaders + * resource file shipped together with KWin. This means this method can only be used for built-in + * effects, for 3rd party effects @link {generateCustomShader} should be used. + * + * If the @p vertexFile is empty a vertex shader with the given @p traits is generated. + * If it is not empty the @p vertexFile is used as the source for the vertex shader. + * + * The same applies for argument @p fragmentFile just for the fragment shader. + * + * So if both @p vertexFile and @p fragmentFile are provided the @p traits are ignored. + * If neither are provided a new shader following the @p traits is generated. + * + * @param traits The shader traits for generating the shader + * @param vertexFile optional vertex shader source code to be used instead of shader traits + * @param fragmentFile optional fragment shader source code to be used instead of shader traits + * @return new generated shader + * @see generateCustomShader + * @since 5.6 + **/ + GLShader *generateShaderFromResources(ShaderTraits traits, const QString &vertexFile = QString(), const QString &fragmentFile = QString()); + /** * Compiles and tests the dynamically generated shaders. * Returns true if successful and false otherwise. @@ -331,6 +354,7 @@ private: QStack m_boundShaders; QHash m_shaderHash; bool m_debug; + QString m_resourcePath; static ShaderManager *s_shaderManager; };