Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimize the effect and render once instead of 5 times #49

Merged
merged 4 commits into from
Jul 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions .github/workflows/glslangValidator.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: GLSL Validator

on:
push:
branches: [ master, latest-shapecorners-code, kwin_5.23 ]
pull_request:
branches: [ master ]

env:
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
BUILD_TYPE: Release

jobs:
ubuntu2004:
# The CMake configure and build commands are platform agnostic and should work equally
# well on Windows or Mac. You can convert this to a matrix build if you need
# cross-platform coverage.
# See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix
runs-on: ubuntu-latest

steps:
- name: Check out repository
uses: actions/checkout@v3

- name: Run github-actions-tune
uses: abbbi/github-actions-tune@v1

- name: Install Dependencies
uses: awalsh128/cache-apt-pkgs-action@staging
with:
packages: glslang-tools
version: 123.0
refresh: true

- name: Validate Shaders
run: glslangValidator shaders_110/shapecorners.frag shaders_140/shapecorners.frag
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ if (NOT EFFECTS_H OR NOT KWIN_GLUTILS OR NOT KWIN_EFFECTS OR NOT OPENGL)
message(FATAL_ERROR "cant continue")
endif (NOT EFFECTS_H OR NOT KWIN_GLUTILS OR NOT KWIN_EFFECTS OR NOT OPENGL)

add_library(${SHAPECORNERS} MODULE shapecorners.cpp main.cpp dbus.h shapecorners.h)
add_library(${SHAPECORNERS} MODULE shapecorners.cpp main.cpp dbus.h shapecorners.h ShaderManager.cpp ShaderManager.h ConfigModel.h ConfigModel.cpp)

target_link_libraries(${SHAPECORNERS}
PUBLIC
Expand Down Expand Up @@ -115,7 +115,7 @@ install(FILES shaders_110/shapecorners.frag DESTINATION ${DATAPATH}/kwin/shaders

#config
project(kwin4_shapecorners_config)
set(kwin4_shapecorners_config_SOURCES shapecorners_config.cpp shapecorners_config.h)
set(kwin4_shapecorners_config_SOURCES shapecorners_config.cpp shapecorners_config.h ConfigModel.cpp)
ki18n_wrap_ui(kwin4_shapecorners_config_SOURCES shapecorners_config.ui)
qt5_add_dbus_interface(kwin4_shapecorners_config_SOURCES org.kde.kwin.Effects.xml kwineffects_interface)
add_library(kwin4_shapecorners_config MODULE ${kwin4_shapecorners_config_SOURCES})
Expand Down
42 changes: 42 additions & 0 deletions ConfigModel.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
//
// Created by matin on 20/07/22.
//

#include <KConfigGroup>
#include <KSharedConfig>
#include "ConfigModel.h"

const QString
key_size = "roundness",
key_dsp = "dsp",
key_shadowColor = "shadowColor",
key_outlineColor = "outlineColor",
key_outlineThickness = "outlineThickness";

ConfigModel::ConfigModel():
m_size(10),
m_outlineThickness(1),
m_shadowColor(QColor(Qt::black)),
m_outlineColor(QColor(Qt::black)),
m_dsp(false)
{
}

void ConfigModel::Load() {
KConfigGroup conf = KSharedConfig::openConfig("shapecorners.conf")->group("General");
m_size = conf.readEntry(key_size, m_size);
m_shadowColor = conf.readEntry(key_shadowColor, m_shadowColor);
m_outlineColor = conf.readEntry(key_outlineColor, m_outlineColor);
m_outlineThickness = conf.readEntry(key_outlineThickness, m_outlineThickness);
m_dsp = conf.readEntry(key_dsp, m_dsp);
}

void ConfigModel::Save() const {
KConfigGroup conf = KSharedConfig::openConfig("shapecorners.conf")->group("General");
conf.writeEntry(key_size, m_size);
conf.writeEntry(key_dsp, m_dsp);
conf.writeEntry(key_shadowColor, m_shadowColor);
conf.writeEntry(key_outlineColor, m_outlineColor);
conf.writeEntry(key_outlineThickness, m_outlineThickness);
conf.sync();
}
23 changes: 23 additions & 0 deletions ConfigModel.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//
// Created by matin on 20/07/22.
//

#ifndef KWIN4_SHAPECORNERS_CONFIG_CONFIGMODEL_H
#define KWIN4_SHAPECORNERS_CONFIG_CONFIGMODEL_H

#include <QColor>

class ConfigModel {
public:
ConfigModel();
void Load();
void Save() const;

float m_size,
m_outlineThickness;
QColor m_shadowColor,
m_outlineColor;
bool m_dsp;
};

#endif //KWIN4_SHAPECORNERS_CONFIG_CONFIGMODEL_H
74 changes: 74 additions & 0 deletions ShaderManager.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
//
// Created by matin on 20/07/22.
//

#include <kwinglplatform.h>
#include <QFile>
#include <QStandardPaths>
#include <kwineffects.h>
#include "ShaderManager.h"

ShaderManager::ShaderManager():
m_manager(KWin::ShaderManager::instance())
{
QString shadersDir(QStringLiteral("kwin/shaders/1.10/"));
#ifdef KWIN_HAVE_OPENGLES
const qint64 coreVersionNumber = kVersionNumber(3, 0);
#else
const qint64 version = KWin::kVersionNumber(1, 40);
#endif
if (KWin::GLPlatform::instance()->glslVersion() >= version)
shadersDir = QStringLiteral("kwin/shaders/1.40/");

const QString fragmentshader = QStandardPaths::locate(QStandardPaths::GenericDataLocation, shadersDir + QStringLiteral("shapecorners.frag"));
// m_shader = KWin::ShaderManager::instance()->loadFragmentShader(KWin::ShaderManager::GenericShader, fragmentshader);
QFile file(fragmentshader);
if (file.open(QFile::ReadOnly))
{
QByteArray frag = file.readAll();
auto shader = m_manager->generateCustomShader(KWin::ShaderTrait::MapTexture, QByteArray(), frag);
#if KWIN_EFFECT_API_VERSION >= 235
m_shader = std::move(shader);
#else
m_shader.reset(shader);
#endif
file.close();
// qDebug() << frag;
// qDebug() << "shader valid: " << m_shader->isValid();
if (m_shader->isValid())
{
m_shader_windowSize = m_shader->uniformLocation("windowSize");
m_shader_windowActive = m_shader->uniformLocation("windowActive");
m_shader_shadowColor = m_shader->uniformLocation("shadowColor");
m_shader_radius = m_shader->uniformLocation("radius");
m_shader_outlineColor = m_shader->uniformLocation("outlineColor");
m_shader_outlineThickness = m_shader->uniformLocation("outlineThickness");
}
else
qDebug() << "ShapeCorners: no valid shaders found! ShapeCorners will not work.";
}
else
{
qDebug() << "ShapeCorners: no shaders found! Exiting...";
}
}

bool ShaderManager::IsValid() const {
return m_shader && m_shader->isValid();
}

void ShaderManager::Bind(QMatrix4x4 mvp, const QRect& geo, bool windowActive, const ConfigModel& config) const {
m_manager->pushShader(m_shader.get());
mvp.translate((float)geo.x(), (float)geo.y());
m_shader->setUniform(KWin::GLShader::ModelViewProjectionMatrix, mvp);
m_shader->setUniform(m_shader_windowSize, QVector2D{(float)geo.width(), (float)geo.height()});
m_shader->setUniform(m_shader_windowActive, windowActive);
m_shader->setUniform(m_shader_shadowColor, config.m_shadowColor);
m_shader->setUniform(m_shader_radius, config.m_size);
m_shader->setUniform(m_shader_outlineColor, config.m_outlineColor);
m_shader->setUniform(m_shader_outlineThickness, config.m_outlineThickness);
}

void ShaderManager::Unbind() const {
m_manager->popShader();
}
37 changes: 37 additions & 0 deletions ShaderManager.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
//
// Created by matin on 20/07/22.
//

#ifndef KWIN4_SHAPECORNERS_CONFIG_SHADERMANAGER_H
#define KWIN4_SHAPECORNERS_CONFIG_SHADERMANAGER_H

#include <kwinglutils.h>
#include <memory>
#include "ConfigModel.h"

namespace KWin {
class GLShader;
class ShaderManager;
}

class ShaderManager {
public:
ShaderManager();

bool IsValid() const;
void Bind(QMatrix4x4 mvp, const QRect& geo, bool windowActive, const ConfigModel& config) const;
void Unbind() const;

private:
std::unique_ptr<KWin::GLShader> m_shader;
KWin::ShaderManager* m_manager;
int m_shader_windowSize = 0;
int m_shader_windowActive = 0;
int m_shader_shadowColor = 0;
int m_shader_radius = 0;
int m_shader_outlineColor = 0;
int m_shader_outlineThickness = 0;
};


#endif //KWIN4_SHAPECORNERS_CONFIG_SHADERMANAGER_H
13 changes: 6 additions & 7 deletions dbus.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

#include <QtDBus/QDBusAbstractAdaptor>
#include "shapecorners.h"
#include <KConfigGroup>

namespace KWin
{
Expand All @@ -21,12 +20,12 @@ class EffectAdaptor : public QDBusAbstractAdaptor
public slots:
Q_NOREPLY void setRoundness(int r)
{
KConfigGroup conf = KSharedConfig::openConfig("shapecorners.conf")->group("General");
if (conf.readEntry("dsp", false))
{
conf.writeEntry("roundness", r);
conf.sync();
m_effect->setRoundness(r);
ConfigModel config;
config.Load();
if(config.m_dsp) {
config.m_size = r;
config.Save();
m_effect->setConfig(config);
}
}
Q_NOREPLY void configure() { m_effect->reconfigure(KWin::Effect::ReconfigureAll); }
Expand Down
60 changes: 41 additions & 19 deletions shaders_110/shapecorners.frag
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#version 110

uniform sampler2D sampler;
uniform int radius;
uniform int cornerIndex;
uniform float radius;
uniform vec2 windowSize;
uniform bool windowActive;
uniform vec4 shadowColor;
uniform vec4 outlineColor;
Expand All @@ -16,33 +16,34 @@ vec4 goTowards(vec4 fromColor, vec4 toColor, float percent) {
}

vec4 shadowCorner(float distance_from_center, vec4 backColor, bool isTopCorner) {
float r2 = radius * sqrt(2.0);
if (windowActive) {
if (isTopCorner) {
float percent = (distance_from_center + 0.15) / (sqrt(2.0)+0.2);
float percent = (distance_from_center + 0.15*radius) / (r2+0.2*radius);
return goTowards(shadowColor, backColor, percent);
}
else {
float percent = (distance_from_center - 0.25) / (sqrt(2.0)+0.1);
float percent = (distance_from_center - 0.25*radius) / (r2+0.1*radius);
return goTowards(shadowColor, backColor, percent);
}
}
else {
if (isTopCorner) {
float percent = (distance_from_center + 0.55) / (sqrt(2.0)+0.5);
float percent = (distance_from_center + 0.55*radius) / (r2+0.5*radius);
return goTowards(shadowColor, backColor, percent);
}
else {
float percent = (distance_from_center) / (sqrt(2.0)+0.1);
float percent = (distance_from_center) / (r2+0.1*radius);
return goTowards(shadowColor, backColor, percent);
}
}
}

vec4 shapeCorner(vec2 texcoord0, vec4 backColor, vec2 center, bool isTopCorner) {
float distance_from_center = distance(texcoord0, center);
if(distance_from_center < (1.0 - outlineThickness/float(radius)))
vec4 shapeCorner(vec2 coord0, vec4 backColor, vec2 center, bool isTopCorner) {
float distance_from_center = distance(coord0, center);
if(distance_from_center < radius - outlineThickness)
backColor.a = 0.0;
else if(distance_from_center < 1.0)
else if(distance_from_center < radius)
backColor = outlineColor;
else {
if(shadowColor.a > 0.0)
Expand All @@ -53,16 +54,37 @@ vec4 shapeCorner(vec2 texcoord0, vec4 backColor, vec2 center, bool isTopCorner)
return backColor;
}

void main()
void main(void)
{
vec4 tex = texture2D(sampler, texcoord0);
if(cornerIndex == 0)
tex = shapeCorner(texcoord0, tex, vec2(1, 0), true);
else if(cornerIndex == 1)
tex = shapeCorner(texcoord0, tex, vec2(0, 0), true);
else if(cornerIndex == 2)
tex = shapeCorner(texcoord0, tex, vec2(0, 1), false);
else if(cornerIndex == 3)
tex = shapeCorner(texcoord0, tex, vec2(1, 1), false);
vec2 coord0 = vec2(texcoord0.x*windowSize.x, texcoord0.y*windowSize.y);
if(coord0.x < radius) {
if(coord0.y < radius)
tex = shapeCorner(coord0, tex, vec2(radius, radius), false);
else if (coord0.y > windowSize.y - radius)
tex = shapeCorner(coord0, tex, vec2(radius, windowSize.y - radius), true);
else if (coord0.x < outlineThickness)
tex = outlineColor;
else
tex.a = 0.0;
}
else if(coord0.x > windowSize.x - radius) {
if(coord0.y < radius)
tex = shapeCorner(coord0, tex, vec2(windowSize.x - radius, radius), false);
else if (coord0.y > windowSize.y - radius)
tex = shapeCorner(coord0, tex, vec2(windowSize.x - radius, windowSize.y - radius), true);
else if (coord0.x > windowSize.x - outlineThickness)
tex = outlineColor;
else
tex.a = 0.0;
}
else {
if (coord0.y < outlineThickness)
tex = outlineColor;
else if (coord0.y > windowSize.y - outlineThickness)
tex = outlineColor;
else
tex.a = 0.0;
}
gl_FragColor = tex;
}
Loading