effects: Fix resource file reading for builtin effects
Currently, the invert effect doesn't work because it can't load its fragment shader because builtin effects are static libs. We need Q_INIT_RESOURCE() before reading shader code. This modularizes builtin effects more, which makes easier to add and remove builtin effects, as well as allows to have per effect resources. Technically, changing the inner workings of the ShaderManager is an API incompatible change, but ShaderManager::generateShaderFromResources() can be used only by builtin effects so it's okay. ShaderManager::generateShaderFromResources() had to be changed because two resource files can't share the same prefix. Appending "_core" was inspired by QtQuick.
This commit is contained in:
parent
11763bb32c
commit
754e0d8f6e
19 changed files with 76 additions and 30 deletions
|
@ -169,8 +169,6 @@ set(kwin4_effect_builtins_sources
|
|||
../service_utils.cpp
|
||||
)
|
||||
|
||||
qt5_add_resources(kwin4_effect_builtins_sources shaders.qrc)
|
||||
|
||||
add_library(kwin4_effect_builtins STATIC ${kwin4_effect_builtins_sources})
|
||||
kcoreaddons_target_static_plugins(kwin4_effect_builtins "kwin/effects/plugins" LINK_OPTION "PRIVATE")
|
||||
target_link_libraries(kwin4_effect_builtins PRIVATE
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
set(invert_SOURCES
|
||||
invert.cpp
|
||||
invert.qrc
|
||||
main.cpp
|
||||
)
|
||||
|
||||
|
|
|
@ -22,6 +22,12 @@
|
|||
|
||||
Q_LOGGING_CATEGORY(KWIN_INVERT, "kwin_effect_invert", QtWarningMsg)
|
||||
|
||||
static void ensureResources()
|
||||
{
|
||||
// Must initialize resources manually because the effect is a static lib.
|
||||
Q_INIT_RESOURCE(invert);
|
||||
}
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
|
@ -62,9 +68,10 @@ bool InvertEffect::supported()
|
|||
|
||||
bool InvertEffect::loadData()
|
||||
{
|
||||
ensureResources();
|
||||
m_inited = true;
|
||||
|
||||
m_shader = ShaderManager::instance()->generateShaderFromResources(ShaderTrait::MapTexture, QString(), QStringLiteral("invert.frag"));
|
||||
m_shader = ShaderManager::instance()->generateShaderFromResources(ShaderTrait::MapTexture, QString(), QStringLiteral(":/effects/invert/shaders/invert.frag"));
|
||||
if (!m_shader->isValid()) {
|
||||
qCCritical(KWIN_INVERT) << "The shader failed to load!";
|
||||
return false;
|
||||
|
|
6
src/effects/invert/invert.qrc
Normal file
6
src/effects/invert/invert.qrc
Normal file
|
@ -0,0 +1,6 @@
|
|||
<!DOCTYPE RCC><RCC version="1.0">
|
||||
<qresource prefix="/effects/invert/">
|
||||
<file>shaders/invert.frag</file>
|
||||
<file>shaders/invert_core.frag</file>
|
||||
</qresource>
|
||||
</RCC>
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
set(lookingglass_SOURCES
|
||||
lookingglass.cpp
|
||||
lookingglass.qrc
|
||||
main.cpp
|
||||
)
|
||||
|
||||
|
|
|
@ -29,6 +29,12 @@
|
|||
|
||||
Q_LOGGING_CATEGORY(KWIN_LOOKINGGLASS, "kwin_effect_lookingglass", QtWarningMsg)
|
||||
|
||||
static void ensureResources()
|
||||
{
|
||||
// Must initialize resources manually because the effect is a static lib.
|
||||
Q_INIT_RESOURCE(lookingglass);
|
||||
}
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
|
@ -91,6 +97,8 @@ void LookingGlassEffect::reconfigure(ReconfigureFlags)
|
|||
|
||||
bool LookingGlassEffect::loadData()
|
||||
{
|
||||
ensureResources();
|
||||
|
||||
const QSize screenSize = effects->virtualScreenSize();
|
||||
int texw = screenSize.width();
|
||||
int texh = screenSize.height();
|
||||
|
@ -106,7 +114,7 @@ bool LookingGlassEffect::loadData()
|
|||
return false;
|
||||
}
|
||||
|
||||
m_shader = ShaderManager::instance()->generateShaderFromResources(ShaderTrait::MapTexture, QString(), QStringLiteral("lookingglass.frag"));
|
||||
m_shader = ShaderManager::instance()->generateShaderFromResources(ShaderTrait::MapTexture, QString(), QStringLiteral(":/effects/lookingglass/shaders/lookingglass.frag"));
|
||||
if (m_shader->isValid()) {
|
||||
ShaderBinder binder(m_shader);
|
||||
m_shader->setUniform("u_textureSize", QVector2D(screenSize.width(), screenSize.height()));
|
||||
|
|
7
src/effects/lookingglass/lookingglass.qrc
Normal file
7
src/effects/lookingglass/lookingglass.qrc
Normal file
|
@ -0,0 +1,7 @@
|
|||
<!DOCTYPE RCC><RCC version="1.0">
|
||||
<qresource prefix="/effects/lookingglass/">
|
||||
<file>shaders/lookingglass.frag</file>
|
||||
<file>shaders/lookingglass_core.frag</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
<!DOCTYPE RCC><RCC version="1.0">
|
||||
<qresource prefix="/effect-shaders-1.10">
|
||||
<file alias="invert.frag">invert/data/1.10/invert.frag</file>
|
||||
<file alias="lookingglass.frag">lookingglass/data/1.10/lookingglass.frag</file>
|
||||
<file alias="blinking-startup-fragment.glsl">startupfeedback/data/1.10/blinking-startup-fragment.glsl</file>
|
||||
</qresource>
|
||||
<qresource prefix="/effect-shaders-1.40">
|
||||
<file alias="invert.frag">invert/data/1.40/invert.frag</file>
|
||||
<file alias="lookingglass.frag">lookingglass/data/1.40/lookingglass.frag</file>
|
||||
<file alias="blinking-startup-fragment.glsl">startupfeedback/data/1.40/blinking-startup-fragment.glsl</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|
@ -5,6 +5,7 @@
|
|||
set(startupfeedback_SOURCES
|
||||
main.cpp
|
||||
startupfeedback.cpp
|
||||
startupfeedback.qrc
|
||||
)
|
||||
|
||||
kwin4_add_effect_module(kwin4_effect_startupfeedback ${startupfeedback_SOURCES})
|
||||
|
|
|
@ -30,6 +30,12 @@
|
|||
|
||||
Q_LOGGING_CATEGORY(KWIN_STARTUPFEEDBACK, "kwin_effect_startupfeedback", QtWarningMsg)
|
||||
|
||||
static void ensureResources()
|
||||
{
|
||||
// Must initialize resources manually because the effect is a static lib.
|
||||
Q_INIT_RESOURCE(startupfeedback);
|
||||
}
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
|
@ -145,7 +151,8 @@ void StartupFeedbackEffect::reconfigure(Effect::ReconfigureFlags flags)
|
|||
else if (busyBlinking) {
|
||||
m_type = BlinkingFeedback;
|
||||
if (effects->compositingType() == OpenGLCompositing) {
|
||||
m_blinkingShader.reset(ShaderManager::instance()->generateShaderFromResources(ShaderTrait::MapTexture, QString(), QStringLiteral("blinking-startup-fragment.glsl")));
|
||||
ensureResources();
|
||||
m_blinkingShader.reset(ShaderManager::instance()->generateShaderFromResources(ShaderTrait::MapTexture, QString(), QStringLiteral(":/effects/startupfeedback/shaders/blinking-startup.frag")));
|
||||
if (m_blinkingShader->isValid()) {
|
||||
qCDebug(KWIN_STARTUPFEEDBACK) << "Blinking Shader is valid";
|
||||
} else {
|
||||
|
|
7
src/effects/startupfeedback/startupfeedback.qrc
Normal file
7
src/effects/startupfeedback/startupfeedback.qrc
Normal file
|
@ -0,0 +1,7 @@
|
|||
<!DOCTYPE RCC><RCC version="1.0">
|
||||
<qresource prefix="/effects/startupfeedback/">
|
||||
<file>shaders/blinking-startup.frag</file>
|
||||
<file>shaders/blinking-startup_core.frag</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|
@ -618,12 +618,6 @@ void ShaderManager::cleanup()
|
|||
|
||||
ShaderManager::ShaderManager()
|
||||
{
|
||||
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()
|
||||
|
@ -783,26 +777,49 @@ GLShader *ShaderManager::generateCustomShader(ShaderTraits traits, const QByteAr
|
|||
return shader;
|
||||
}
|
||||
|
||||
static QString resolveShaderFilePath(const QString &filePath)
|
||||
{
|
||||
QString suffix;
|
||||
QString extension;
|
||||
|
||||
const qint64 coreVersionNumber = GLPlatform::instance()->isGLES() ? kVersionNumber(3, 0) : kVersionNumber(1, 40);
|
||||
if (GLPlatform::instance()->glslVersion() >= coreVersionNumber) {
|
||||
suffix = QStringLiteral("_core");
|
||||
}
|
||||
|
||||
if (filePath.endsWith(QStringLiteral(".frag"))) {
|
||||
extension = QStringLiteral(".frag");
|
||||
} else if (filePath.endsWith(QStringLiteral(".vert"))) {
|
||||
extension = QStringLiteral(".vert");
|
||||
} else {
|
||||
qCWarning(LIBKWINGLUTILS) << filePath << "must end either with .vert or .frag";
|
||||
return QString();
|
||||
}
|
||||
|
||||
const QString prefix = filePath.chopped(extension.size());
|
||||
return prefix + suffix + extension;
|
||||
}
|
||||
|
||||
GLShader *ShaderManager::generateShaderFromResources(ShaderTraits traits, const QString &vertexFile, const QString &fragmentFile)
|
||||
{
|
||||
auto loadShaderFile = [this] (const QString &fileName) {
|
||||
QFile file(m_resourcePath + fileName);
|
||||
auto loadShaderFile = [](const QString &filePath) {
|
||||
QFile file(filePath);
|
||||
if (file.open(QIODevice::ReadOnly)) {
|
||||
return file.readAll();
|
||||
}
|
||||
qCCritical(LIBKWINGLUTILS) << "Failed to read shader " << fileName;
|
||||
qCCritical(LIBKWINGLUTILS) << "Failed to read shader " << filePath;
|
||||
return QByteArray();
|
||||
};
|
||||
QByteArray vertexSource;
|
||||
QByteArray fragmentSource;
|
||||
if (!vertexFile.isEmpty()) {
|
||||
vertexSource = loadShaderFile(vertexFile);
|
||||
vertexSource = loadShaderFile(resolveShaderFilePath(vertexFile));
|
||||
if (vertexSource.isEmpty()) {
|
||||
return new GLShader();
|
||||
}
|
||||
}
|
||||
if (!fragmentFile.isEmpty()) {
|
||||
fragmentSource = loadShaderFile(fragmentFile);
|
||||
fragmentSource = loadShaderFile(resolveShaderFilePath(fragmentFile));
|
||||
if (fragmentSource.isEmpty()) {
|
||||
return new GLShader();
|
||||
}
|
||||
|
|
|
@ -306,7 +306,6 @@ private:
|
|||
|
||||
QStack<GLShader*> m_boundShaders;
|
||||
QHash<ShaderTraits, GLShader *> m_shaderHash;
|
||||
QString m_resourcePath;
|
||||
static ShaderManager *s_shaderManager;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue