[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
This commit is contained in:
parent
fbf14306d7
commit
613d76f2df
18 changed files with 101 additions and 159 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -231,8 +231,6 @@ private:
|
|||
float mAddedHeightCoeff1;
|
||||
float mAddedHeightCoeff2;
|
||||
|
||||
QString m_shadersDir;
|
||||
|
||||
QMatrix4x4 m_rotationMatrix;
|
||||
QMatrix4x4 m_reflectionMatrix;
|
||||
QMatrix4x4 m_textureMirrorMatrix;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -96,7 +96,6 @@ private:
|
|||
QList<WinDataPair> m_windows;
|
||||
GLShader *m_vignettingShader;
|
||||
GLShader *m_blurShader;
|
||||
QString m_shadersDir;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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()));
|
||||
|
|
26
effects/shaders.qrc
Normal file
26
effects/shaders.qrc
Normal file
|
@ -0,0 +1,26 @@
|
|||
<!DOCTYPE RCC><RCC version="1.0">
|
||||
<qresource prefix="/effect-shaders-1.10">
|
||||
<file alias="coverswitch-reflection.glsl">coverswitch/shaders/1.10/coverswitch-reflection.glsl</file>
|
||||
<file alias="cube-cap.glsl">cube/data/1.10/cube-cap.glsl</file>
|
||||
<file alias="cube-reflection.glsl">cube/data/1.10/cube-reflection.glsl</file>
|
||||
<file alias="cylinder.vert">cube/data/1.10/cylinder.vert</file>
|
||||
<file alias="sphere.vert">cube/data/1.10/sphere.vert</file>
|
||||
<file alias="invert.frag">invert/data/1.10/invert.frag</file>
|
||||
<file alias="logout-blur.frag">logout/data/1.10/logout-blur.frag</file>
|
||||
<file alias="vignetting.frag">logout/data/1.10/vignetting.frag</file>
|
||||
<file alias="lookingglass.frag">lookingglass/data/1.10/lookingglass.frag</file>
|
||||
<file alias="blinking-startup-fragment.glsl">startupfeedback/data/blinking-startup-fragment.glsl</file>
|
||||
</qresource>
|
||||
<qresource prefix="/effect-shaders-1.40">
|
||||
<file alias="coverswitch-reflection.glsl">coverswitch/shaders/1.40/coverswitch-reflection.glsl</file>
|
||||
<file alias="cube-cap.glsl">cube/data/1.40/cube-cap.glsl</file>
|
||||
<file alias="cube-reflection.glsl">cube/data/1.40/cube-reflection.glsl</file>
|
||||
<file alias="cylinder.vert">cube/data/1.40/cylinder.vert</file>
|
||||
<file alias="sphere.vert">cube/data/1.40/sphere.vert</file>
|
||||
<file alias="invert.frag">invert/data/1.40/invert.frag</file>
|
||||
<file alias="logout-blur.frag">logout/data/1.40/logout-blur.frag</file>
|
||||
<file alias="vignetting.frag">logout/data/1.40/vignetting.frag</file>
|
||||
<file alias="lookingglass.frag">lookingglass/data/1.40/lookingglass.frag</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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<GLShader*> m_boundShaders;
|
||||
QHash<ShaderTraits, GLShader *> m_shaderHash;
|
||||
bool m_debug;
|
||||
QString m_resourcePath;
|
||||
static ShaderManager *s_shaderManager;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue