mirror of
https://github.com/hyprwm/Hyprland.git
synced 2025-07-25 17:21:54 -07:00
renderer: reduce a lot of glcalls and cache various states (#10757)
* opengl: cache viewport state according to nvidia docs calling glViewPort unnecessarily on the same already set viewport is wasteful and can cause state changes when not needed. cache it in a struct and only call it when the viewport is actually changing. * opengl: cache glenable/gldisable state avoid making multiple glenable/gldisable calls on already set caps, can cause state changes and incur driver overhead. * opengl: cache glscissor box only call glscissor if the box actually has changed, try to avoid state changes. * opengl: cache gluniform calls cache the gluniform calls, the uniform values are cached in driver per program only the drawcalls setting the uniform yet again with the same value on same location is causing more overhead then caching it ourself and just no oping on it if no changes. * shader: rewrite handling of uniforms and state this is way faster as we don't need to mess with maps (hashing, etc) and instead can just use an array * opengl: stuff and 300 shaders * opengl: typo * opengl: get the uniform locations properly now that the legacy shaders are gone get the uniformlocations for SKIP_CM etc, so they can be properly set and used depending on if cm_enabled is set to false or true, before it was falling back to a legacy shader that didnt even have those uniforms. * opengl: check epsilon on float and remove extra glcall seems an extra unset glcall was added, remove it. and check the float epsilon on the glfloat. * opengl: remove instanced shader draw remove the instanced boolean from the vertex shader, might be neglible differences, needs more benchmark/work to see if its even worth it. * texture: cache texture paramaters parameters where occasionally set twice or more on same texture, short version wrap it and cache it. and move gpu churn to cpu churn. add a bind/unbind to texture aswell. * texture: use fast std::array caching cache the texparameter values in fast array lookups and incase we dont want it cached, apply it anyways. * shader: fix typo and hdr typo actually use Matrix4x2fv in the 4x2fv cache function, and send the proper float array for hdr. * texture: make caching not linear lookup make caching of texture params not linear. * minor style changes * opengl: revert drawarrays revert the mostly code style reduce loc change of drawarrays, and focus on the caching. its a if else case going wrong here breaking blur/contrast amongst others drawing. --------- Co-authored-by: Vaxry <vaxry@vaxry.net>
This commit is contained in:
@@ -260,11 +260,11 @@ void CHyprDebugOverlay::draw() {
|
||||
// copy the data to an OpenGL texture we have
|
||||
const auto DATA = cairo_image_surface_get_data(m_cairoSurface);
|
||||
m_texture->allocate();
|
||||
glBindTexture(GL_TEXTURE_2D, m_texture->m_texID);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_BLUE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED);
|
||||
m_texture->bind();
|
||||
m_texture->setTexParameter(GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
m_texture->setTexParameter(GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
m_texture->setTexParameter(GL_TEXTURE_SWIZZLE_R, GL_BLUE);
|
||||
m_texture->setTexParameter(GL_TEXTURE_SWIZZLE_B, GL_RED);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, PMONITOR->m_pixelSize.x, PMONITOR->m_pixelSize.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, DATA);
|
||||
|
||||
|
@@ -235,11 +235,11 @@ void CHyprNotificationOverlay::draw(PHLMONITOR pMonitor) {
|
||||
// copy the data to an OpenGL texture we have
|
||||
const auto DATA = cairo_image_surface_get_data(m_cairoSurface);
|
||||
m_texture->allocate();
|
||||
glBindTexture(GL_TEXTURE_2D, m_texture->m_texID);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_BLUE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED);
|
||||
m_texture->bind();
|
||||
m_texture->setTexParameter(GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
m_texture->setTexParameter(GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
m_texture->setTexParameter(GL_TEXTURE_SWIZZLE_R, GL_BLUE);
|
||||
m_texture->setTexParameter(GL_TEXTURE_SWIZZLE_B, GL_RED);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, MONSIZE.x, MONSIZE.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, DATA);
|
||||
|
||||
|
@@ -143,11 +143,11 @@ void CHyprError::createQueued() {
|
||||
// copy the data to an OpenGL texture we have
|
||||
const auto DATA = cairo_image_surface_get_data(CAIROSURFACE);
|
||||
m_texture->allocate();
|
||||
glBindTexture(GL_TEXTURE_2D, m_texture->m_texID);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_BLUE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED);
|
||||
m_texture->bind();
|
||||
m_texture->setTexParameter(GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
m_texture->setTexParameter(GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
m_texture->setTexParameter(GL_TEXTURE_SWIZZLE_R, GL_BLUE);
|
||||
m_texture->setTexParameter(GL_TEXTURE_SWIZZLE_B, GL_RED);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, PMONITOR->m_pixelSize.x, PMONITOR->m_pixelSize.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, DATA);
|
||||
|
||||
|
@@ -95,6 +95,8 @@
|
||||
#define UNREACHABLE() std::unreachable();
|
||||
#endif
|
||||
|
||||
#if ISDEBUG
|
||||
|
||||
#define GLCALL(__CALL__) \
|
||||
{ \
|
||||
__CALL__; \
|
||||
@@ -105,6 +107,13 @@
|
||||
} \
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define GLCALL(__CALL__) \
|
||||
{ __CALL__; }
|
||||
|
||||
#endif
|
||||
|
||||
#define HYPRUTILS_FORWARD(ns, name) \
|
||||
namespace Hyprutils { \
|
||||
namespace ns { \
|
||||
|
@@ -20,11 +20,11 @@ bool CFramebuffer::alloc(int w, int h, uint32_t drmFormat) {
|
||||
if (!m_tex) {
|
||||
m_tex = makeShared<CTexture>();
|
||||
m_tex->allocate();
|
||||
glBindTexture(GL_TEXTURE_2D, m_tex->m_texID);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
m_tex->bind();
|
||||
m_tex->setTexParameter(GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
m_tex->setTexParameter(GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
m_tex->setTexParameter(GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
m_tex->setTexParameter(GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
firstAlloc = true;
|
||||
}
|
||||
|
||||
@@ -35,13 +35,13 @@ bool CFramebuffer::alloc(int w, int h, uint32_t drmFormat) {
|
||||
}
|
||||
|
||||
if (firstAlloc || m_size != Vector2D(w, h)) {
|
||||
glBindTexture(GL_TEXTURE_2D, m_tex->m_texID);
|
||||
m_tex->bind();
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, glFormat, w, h, 0, GL_RGBA, glType, nullptr);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_fb);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_tex->m_texID, 0);
|
||||
|
||||
if (m_stencilTex) {
|
||||
glBindTexture(GL_TEXTURE_2D, m_stencilTex->m_texID);
|
||||
m_stencilTex->bind();
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, w, h, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, nullptr);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, m_stencilTex->m_texID, 0);
|
||||
}
|
||||
@@ -62,7 +62,7 @@ bool CFramebuffer::alloc(int w, int h, uint32_t drmFormat) {
|
||||
|
||||
void CFramebuffer::addStencil(SP<CTexture> tex) {
|
||||
m_stencilTex = tex;
|
||||
glBindTexture(GL_TEXTURE_2D, m_stencilTex->m_texID);
|
||||
m_stencilTex->bind();
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, m_size.x, m_size.y, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, nullptr);
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_fb);
|
||||
@@ -72,7 +72,7 @@ void CFramebuffer::addStencil(SP<CTexture> tex) {
|
||||
auto status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||
RASSERT((status == GL_FRAMEBUFFER_COMPLETE), "Failed adding a stencil to fbo!", status);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
m_stencilTex->unbind();
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ void CFramebuffer::bind() {
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fb);
|
||||
|
||||
if (g_pHyprOpenGL)
|
||||
glViewport(0, 0, g_pHyprOpenGL->m_renderData.pMonitor->m_pixelSize.x, g_pHyprOpenGL->m_renderData.pMonitor->m_pixelSize.y);
|
||||
g_pHyprOpenGL->setViewport(0, 0, g_pHyprOpenGL->m_renderData.pMonitor->m_pixelSize.x, g_pHyprOpenGL->m_renderData.pMonitor->m_pixelSize.y);
|
||||
else
|
||||
glViewport(0, 0, m_size.x, m_size.y);
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -83,7 +83,6 @@ enum eMonitorExtraRenderFBs : uint8_t {
|
||||
|
||||
struct SPreparedShaders {
|
||||
std::string TEXVERTSRC;
|
||||
std::string TEXVERTSRC300;
|
||||
std::string TEXVERTSRC320;
|
||||
SShader m_shQUAD;
|
||||
SShader m_shRGBA;
|
||||
@@ -201,6 +200,8 @@ class CHyprOpenGLImpl {
|
||||
void popMonitorTransformEnabled();
|
||||
|
||||
void setRenderModifEnabled(bool enabled);
|
||||
void setViewport(GLint x, GLint y, GLsizei width, GLsizei height);
|
||||
void setCapStatus(int cap, bool status);
|
||||
|
||||
void saveMatrix();
|
||||
void setMatrixScaleTranslate(const Vector2D& translate, const float& scale);
|
||||
@@ -307,40 +308,47 @@ class CHyprOpenGLImpl {
|
||||
EGL_CONTEXT_GLES_3_2,
|
||||
};
|
||||
|
||||
eEGLContextVersion m_eglContextVersion = EGL_CONTEXT_GLES_3_2;
|
||||
struct {
|
||||
GLint x = 0;
|
||||
GLint y = 0;
|
||||
GLsizei width = 0;
|
||||
GLsizei height = 0;
|
||||
} m_lastViewport;
|
||||
|
||||
std::vector<SDRMFormat> m_drmFormats;
|
||||
bool m_hasModifiers = false;
|
||||
std::unordered_map<int, bool> m_capStatus;
|
||||
|
||||
int m_drmFD = -1;
|
||||
std::string m_extensions;
|
||||
eEGLContextVersion m_eglContextVersion = EGL_CONTEXT_GLES_3_2;
|
||||
|
||||
bool m_fakeFrame = false;
|
||||
bool m_applyFinalShader = false;
|
||||
bool m_blend = false;
|
||||
bool m_offloadedFramebuffer = false;
|
||||
bool m_cmSupported = true;
|
||||
std::vector<SDRMFormat> m_drmFormats;
|
||||
bool m_hasModifiers = false;
|
||||
|
||||
bool m_monitorTransformEnabled = false; // do not modify directly
|
||||
std::stack<bool> m_monitorTransformStack;
|
||||
int m_drmFD = -1;
|
||||
std::string m_extensions;
|
||||
|
||||
SShader m_finalScreenShader;
|
||||
CTimer m_globalTimer;
|
||||
GLuint m_currentProgram;
|
||||
bool m_fakeFrame = false;
|
||||
bool m_applyFinalShader = false;
|
||||
bool m_blend = false;
|
||||
bool m_offloadedFramebuffer = false;
|
||||
bool m_cmSupported = true;
|
||||
|
||||
SP<CTexture> m_missingAssetTexture;
|
||||
SP<CTexture> m_backgroundTexture;
|
||||
SP<CTexture> m_lockDeadTexture;
|
||||
SP<CTexture> m_lockDead2Texture;
|
||||
SP<CTexture> m_lockTtyTextTexture;
|
||||
bool m_monitorTransformEnabled = false; // do not modify directly
|
||||
std::stack<bool> m_monitorTransformStack;
|
||||
SP<CTexture> m_missingAssetTexture;
|
||||
SP<CTexture> m_backgroundTexture;
|
||||
SP<CTexture> m_lockDeadTexture;
|
||||
SP<CTexture> m_lockDead2Texture;
|
||||
SP<CTexture> m_lockTtyTextTexture;
|
||||
SShader m_finalScreenShader;
|
||||
CTimer m_globalTimer;
|
||||
GLuint m_currentProgram;
|
||||
|
||||
void logShaderError(const GLuint&, bool program = false, bool silent = false);
|
||||
void createBGTextureForMonitor(PHLMONITOR);
|
||||
void initDRMFormats();
|
||||
void initEGL(bool gbm);
|
||||
EGLDeviceEXT eglDeviceFromDRMFD(int drmFD);
|
||||
void initAssets();
|
||||
void initMissingAssetTexture();
|
||||
void logShaderError(const GLuint&, bool program = false, bool silent = false);
|
||||
void createBGTextureForMonitor(PHLMONITOR);
|
||||
void initDRMFormats();
|
||||
void initEGL(bool gbm);
|
||||
EGLDeviceEXT eglDeviceFromDRMFD(int drmFD);
|
||||
void initAssets();
|
||||
void initMissingAssetTexture();
|
||||
|
||||
//
|
||||
std::optional<std::vector<uint64_t>> getModsForFormat(EGLint format);
|
||||
@@ -349,9 +357,9 @@ class CHyprOpenGLImpl {
|
||||
CFramebuffer* blurMainFramebufferWithDamage(float a, CRegion* damage);
|
||||
CFramebuffer* blurFramebufferWithDamage(float a, CRegion* damage, CFramebuffer& source);
|
||||
|
||||
void passCMUniforms(const SShader&, const NColorManagement::SImageDescription& imageDescription, const NColorManagement::SImageDescription& targetImageDescription,
|
||||
void passCMUniforms(SShader&, const NColorManagement::SImageDescription& imageDescription, const NColorManagement::SImageDescription& targetImageDescription,
|
||||
bool modifySDR = false, float sdrMinLuminance = -1.0f, int sdrMaxLuminance = -1);
|
||||
void passCMUniforms(const SShader&, const NColorManagement::SImageDescription& imageDescription);
|
||||
void passCMUniforms(SShader&, const NColorManagement::SImageDescription& imageDescription);
|
||||
void renderTextureInternalWithDamage(SP<CTexture>, const CBox& box, float a, const CRegion& damage, int round = 0, float roundingPower = 2.0f, bool discardOpaque = false,
|
||||
bool noAA = false, bool allowCustomUV = false, bool allowDim = false, GLenum wrapX = GL_CLAMP_TO_EDGE, GLenum wrapY = GL_CLAMP_TO_EDGE);
|
||||
void renderTexturePrimitive(SP<CTexture> tex, const CBox& box);
|
||||
|
@@ -1,44 +1,204 @@
|
||||
#include "Shader.hpp"
|
||||
#include "render/OpenGL.hpp"
|
||||
|
||||
#define EPSILON(x, y) (std::abs((x) - (y)) < 1e-5f)
|
||||
|
||||
static bool compareFloat(auto a, auto b) {
|
||||
if (a.size() != b.size())
|
||||
return false;
|
||||
|
||||
for (size_t i = 0; i < a.size(); ++i)
|
||||
if (std::fabs(a[i] - b[i]) > 1e-5f)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
SShader::SShader() {
|
||||
uniformLocations.fill(-1);
|
||||
}
|
||||
|
||||
SShader::~SShader() {
|
||||
destroy();
|
||||
}
|
||||
|
||||
void SShader::createVao() {
|
||||
GLuint shaderVao = 0, shaderVbo = 0, shaderVboUv = 0;
|
||||
|
||||
glGenVertexArrays(1, &shaderVao);
|
||||
glBindVertexArray(shaderVao);
|
||||
|
||||
if (posAttrib != -1) {
|
||||
glGenBuffers(1, &shaderVboPos);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, shaderVboPos);
|
||||
if (uniformLocations[SHADER_POS_ATTRIB] != -1) {
|
||||
glGenBuffers(1, &shaderVbo);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, shaderVbo);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(fullVerts), fullVerts, GL_STATIC_DRAW);
|
||||
glEnableVertexAttribArray(posAttrib);
|
||||
glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE, 0, (void*)0);
|
||||
glEnableVertexAttribArray(uniformLocations[SHADER_POS_ATTRIB]);
|
||||
glVertexAttribPointer(uniformLocations[SHADER_POS_ATTRIB], 2, GL_FLOAT, GL_FALSE, 0, nullptr);
|
||||
}
|
||||
|
||||
// UV VBO (dynamic, may be updated per frame)
|
||||
if (texAttrib != -1) {
|
||||
if (uniformLocations[SHADER_TEX_ATTRIB] != -1) {
|
||||
glGenBuffers(1, &shaderVboUv);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, shaderVboUv);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(fullVerts), fullVerts, GL_DYNAMIC_DRAW); // Initial dummy UVs
|
||||
glEnableVertexAttribArray(texAttrib);
|
||||
glVertexAttribPointer(texAttrib, 2, GL_FLOAT, GL_FALSE, 0, (void*)0);
|
||||
glEnableVertexAttribArray(uniformLocations[SHADER_TEX_ATTRIB]);
|
||||
glVertexAttribPointer(uniformLocations[SHADER_TEX_ATTRIB], 2, GL_FLOAT, GL_FALSE, 0, nullptr);
|
||||
}
|
||||
|
||||
glBindVertexArray(0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
||||
uniformLocations[SHADER_SHADER_VAO] = shaderVao;
|
||||
uniformLocations[SHADER_SHADER_VBO_POS] = shaderVbo;
|
||||
uniformLocations[SHADER_SHADER_VBO_UV] = shaderVboUv;
|
||||
|
||||
RASSERT(uniformLocations[SHADER_SHADER_VAO] >= 0, "SHADER_SHADER_VAO could not be created");
|
||||
RASSERT(uniformLocations[SHADER_SHADER_VBO_POS] >= 0, "SHADER_SHADER_VBO_POS could not be created");
|
||||
RASSERT(uniformLocations[SHADER_SHADER_VBO_UV] >= 0, "SHADER_SHADER_VBO_UV could not be created");
|
||||
}
|
||||
|
||||
void SShader::setUniformInt(eShaderUniform location, GLint v0) {
|
||||
if (uniformLocations.at(location) == -1)
|
||||
return;
|
||||
|
||||
auto& cached = uniformStatus.at(location);
|
||||
|
||||
if (cached.index() != 0 && std::get<GLint>(cached) == v0)
|
||||
return;
|
||||
|
||||
cached = v0;
|
||||
glUniform1i(uniformLocations[location], v0);
|
||||
}
|
||||
|
||||
void SShader::setUniformFloat(eShaderUniform location, GLfloat v0) {
|
||||
if (uniformLocations.at(location) == -1)
|
||||
return;
|
||||
|
||||
auto& cached = uniformStatus.at(location);
|
||||
|
||||
if (cached.index() != 0) {
|
||||
auto val = std::get<GLfloat>(cached);
|
||||
if (EPSILON(val, v0))
|
||||
return;
|
||||
}
|
||||
|
||||
cached = v0;
|
||||
glUniform1f(uniformLocations[location], v0);
|
||||
}
|
||||
|
||||
void SShader::setUniformFloat2(eShaderUniform location, GLfloat v0, GLfloat v1) {
|
||||
if (uniformLocations.at(location) == -1)
|
||||
return;
|
||||
|
||||
auto& cached = uniformStatus.at(location);
|
||||
|
||||
if (cached.index() != 0) {
|
||||
auto val = std::get<std::array<GLfloat, 2>>(cached);
|
||||
if (EPSILON(val[0], v0) && EPSILON(val[1], v1))
|
||||
return;
|
||||
}
|
||||
|
||||
cached = std::array<GLfloat, 2>{v0, v1};
|
||||
glUniform2f(uniformLocations[location], v0, v1);
|
||||
}
|
||||
|
||||
void SShader::setUniformFloat3(eShaderUniform location, GLfloat v0, GLfloat v1, GLfloat v2) {
|
||||
if (uniformLocations.at(location) == -1)
|
||||
return;
|
||||
|
||||
auto& cached = uniformStatus.at(location);
|
||||
|
||||
if (cached.index() != 0) {
|
||||
auto val = std::get<std::array<GLfloat, 3>>(cached);
|
||||
if (EPSILON(val[0], v0) && EPSILON(val[1], v1) && EPSILON(val[2], v2))
|
||||
return;
|
||||
}
|
||||
|
||||
cached = std::array<GLfloat, 3>{v0, v1, v2};
|
||||
glUniform3f(uniformLocations[location], v0, v1, v2);
|
||||
}
|
||||
|
||||
void SShader::setUniformFloat4(eShaderUniform location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) {
|
||||
if (uniformLocations.at(location) == -1)
|
||||
return;
|
||||
|
||||
auto& cached = uniformStatus.at(location);
|
||||
|
||||
if (cached.index() != 0) {
|
||||
auto val = std::get<std::array<GLfloat, 4>>(cached);
|
||||
if (EPSILON(val[0], v0) && EPSILON(val[1], v1) && EPSILON(val[2], v2) && EPSILON(val[3], v3))
|
||||
return;
|
||||
}
|
||||
|
||||
cached = std::array<GLfloat, 4>{v0, v1, v2, v3};
|
||||
glUniform4f(uniformLocations[location], v0, v1, v2, v3);
|
||||
}
|
||||
|
||||
void SShader::setUniformMatrix3fv(eShaderUniform location, GLsizei count, GLboolean transpose, std::array<GLfloat, 9> value) {
|
||||
if (uniformLocations.at(location) == -1)
|
||||
return;
|
||||
|
||||
auto& cached = uniformStatus.at(location);
|
||||
|
||||
if (cached.index() != 0) {
|
||||
auto val = std::get<SUniformMatrix3Data>(cached);
|
||||
if (val.count == count && val.transpose == transpose && compareFloat(val.value, value))
|
||||
return;
|
||||
}
|
||||
|
||||
cached = SUniformMatrix3Data{.count = count, .transpose = transpose, .value = value};
|
||||
glUniformMatrix3fv(uniformLocations[location], count, transpose, value.data());
|
||||
}
|
||||
|
||||
void SShader::setUniformMatrix4x2fv(eShaderUniform location, GLsizei count, GLboolean transpose, std::array<GLfloat, 8> value) {
|
||||
if (uniformLocations.at(location) == -1)
|
||||
return;
|
||||
|
||||
auto& cached = uniformStatus.at(location);
|
||||
|
||||
if (cached.index() != 0) {
|
||||
auto val = std::get<SUniformMatrix4Data>(cached);
|
||||
if (val.count == count && val.transpose == transpose && compareFloat(val.value, value))
|
||||
return;
|
||||
}
|
||||
|
||||
cached = SUniformMatrix4Data{.count = count, .transpose = transpose, .value = value};
|
||||
glUniformMatrix4x2fv(uniformLocations[location], count, transpose, value.data());
|
||||
}
|
||||
|
||||
void SShader::setUniform4fv(eShaderUniform location, GLsizei count, std::vector<float> value) {
|
||||
if (uniformLocations.at(location) == -1)
|
||||
return;
|
||||
|
||||
auto& cached = uniformStatus.at(location);
|
||||
|
||||
if (cached.index() != 0) {
|
||||
auto val = std::get<SUniform4Data>(cached);
|
||||
if (val.count == count && compareFloat(val.value, value))
|
||||
return;
|
||||
}
|
||||
|
||||
cached = SUniform4Data{.count = count, .value = value};
|
||||
glUniform4fv(uniformLocations[location], count, value.data());
|
||||
}
|
||||
|
||||
void SShader::destroy() {
|
||||
uniformStatus.fill(std::monostate());
|
||||
|
||||
if (program == 0)
|
||||
return;
|
||||
|
||||
GLuint shaderVao, shaderVbo, shaderVboUv;
|
||||
|
||||
shaderVao = uniformLocations[SHADER_SHADER_VAO] == -1 ? 0 : uniformLocations[SHADER_SHADER_VAO];
|
||||
shaderVbo = uniformLocations[SHADER_SHADER_VBO_POS] == -1 ? 0 : uniformLocations[SHADER_SHADER_VBO_POS];
|
||||
shaderVboUv = uniformLocations[SHADER_SHADER_VBO_UV] == -1 ? 0 : uniformLocations[SHADER_SHADER_VBO_UV];
|
||||
|
||||
if (shaderVao)
|
||||
glDeleteVertexArrays(1, &shaderVao);
|
||||
|
||||
if (shaderVboPos)
|
||||
glDeleteBuffers(1, &shaderVboPos);
|
||||
if (shaderVbo)
|
||||
glDeleteBuffers(1, &shaderVbo);
|
||||
|
||||
if (shaderVboUv)
|
||||
glDeleteBuffers(1, &shaderVboUv);
|
||||
|
@@ -1,85 +1,113 @@
|
||||
#pragma once
|
||||
|
||||
#include "../defines.hpp"
|
||||
#include <unordered_map>
|
||||
#include <array>
|
||||
#include <variant>
|
||||
|
||||
enum eShaderUniform : uint8_t {
|
||||
SHADER_PROJ = 0,
|
||||
SHADER_COLOR,
|
||||
SHADER_ALPHA_MATTE,
|
||||
SHADER_TEX_TYPE,
|
||||
SHADER_SKIP_CM,
|
||||
SHADER_SOURCE_TF,
|
||||
SHADER_TARGET_TF,
|
||||
SHADER_SRC_TF_RANGE,
|
||||
SHADER_DST_TF_RANGE,
|
||||
SHADER_TARGET_PRIMARIES,
|
||||
SHADER_MAX_LUMINANCE,
|
||||
SHADER_DST_MAX_LUMINANCE,
|
||||
SHADER_DST_REF_LUMINANCE,
|
||||
SHADER_SDR_SATURATION,
|
||||
SHADER_SDR_BRIGHTNESS,
|
||||
SHADER_CONVERT_MATRIX,
|
||||
SHADER_TEX,
|
||||
SHADER_ALPHA,
|
||||
SHADER_POS_ATTRIB,
|
||||
SHADER_TEX_ATTRIB,
|
||||
SHADER_MATTE_TEX_ATTRIB,
|
||||
SHADER_DISCARD_OPAQUE,
|
||||
SHADER_DISCARD_ALPHA,
|
||||
SHADER_DISCARD_ALPHA_VALUE,
|
||||
SHADER_SHADER_VAO,
|
||||
SHADER_SHADER_VBO_POS,
|
||||
SHADER_SHADER_VBO_UV,
|
||||
SHADER_TOP_LEFT,
|
||||
SHADER_BOTTOM_RIGHT,
|
||||
SHADER_FULL_SIZE,
|
||||
SHADER_FULL_SIZE_UNTRANSFORMED,
|
||||
SHADER_RADIUS,
|
||||
SHADER_RADIUS_OUTER,
|
||||
SHADER_ROUNDING_POWER,
|
||||
SHADER_THICK,
|
||||
SHADER_HALFPIXEL,
|
||||
SHADER_RANGE,
|
||||
SHADER_SHADOW_POWER,
|
||||
SHADER_USE_ALPHA_MATTE,
|
||||
SHADER_APPLY_TINT,
|
||||
SHADER_TINT,
|
||||
SHADER_GRADIENT,
|
||||
SHADER_GRADIENT_LENGTH,
|
||||
SHADER_ANGLE,
|
||||
SHADER_GRADIENT2,
|
||||
SHADER_GRADIENT2_LENGTH,
|
||||
SHADER_ANGLE2,
|
||||
SHADER_GRADIENT_LERP,
|
||||
SHADER_TIME,
|
||||
SHADER_DISTORT,
|
||||
SHADER_WL_OUTPUT,
|
||||
SHADER_CONTRAST,
|
||||
SHADER_PASSES,
|
||||
SHADER_VIBRANCY,
|
||||
SHADER_VIBRANCY_DARKNESS,
|
||||
SHADER_BRIGHTNESS,
|
||||
SHADER_NOISE,
|
||||
|
||||
SHADER_LAST,
|
||||
};
|
||||
|
||||
struct SShader {
|
||||
SShader();
|
||||
~SShader();
|
||||
|
||||
GLuint program = 0;
|
||||
GLint proj = -1;
|
||||
GLint color = -1;
|
||||
GLint alphaMatte = -1;
|
||||
GLint texType = -1;
|
||||
GLint skipCM = -1;
|
||||
GLint sourceTF = -1;
|
||||
GLint targetTF = -1;
|
||||
GLint srcTFRange = -1;
|
||||
GLint dstTFRange = -1;
|
||||
GLint targetPrimaries = -1;
|
||||
GLint maxLuminance = -1;
|
||||
GLint dstMaxLuminance = -1;
|
||||
GLint dstRefLuminance = -1;
|
||||
GLint sdrSaturation = -1; // sdr -> hdr saturation
|
||||
GLint sdrBrightness = -1; // sdr -> hdr brightness multiplier
|
||||
GLint convertMatrix = -1;
|
||||
GLint tex = -1;
|
||||
GLint alpha = -1;
|
||||
GLint posAttrib = -1;
|
||||
GLint texAttrib = -1;
|
||||
GLint matteTexAttrib = -1;
|
||||
GLint discardOpaque = -1;
|
||||
GLint discardAlpha = -1;
|
||||
GLfloat discardAlphaValue = -1;
|
||||
GLuint program = 0;
|
||||
|
||||
GLuint shaderVao = 0;
|
||||
GLuint shaderVboPos = 0;
|
||||
GLuint shaderVboUv = 0;
|
||||
std::array<GLint, SHADER_LAST> uniformLocations;
|
||||
|
||||
GLint topLeft = -1;
|
||||
GLint bottomRight = -1;
|
||||
GLint fullSize = -1;
|
||||
GLint fullSizeUntransformed = -1;
|
||||
GLint radius = -1;
|
||||
GLint radiusOuter = -1;
|
||||
GLfloat roundingPower = -1;
|
||||
float initialTime = 0;
|
||||
|
||||
GLint thick = -1;
|
||||
struct SUniformMatrix3Data {
|
||||
GLsizei count = 0;
|
||||
GLboolean transpose = false;
|
||||
std::array<GLfloat, 9> value = {};
|
||||
};
|
||||
|
||||
GLint halfpixel = -1;
|
||||
struct SUniformMatrix4Data {
|
||||
GLsizei count = 0;
|
||||
GLboolean transpose = false;
|
||||
std::array<GLfloat, 8> value = {};
|
||||
};
|
||||
|
||||
GLint range = -1;
|
||||
GLint shadowPower = -1;
|
||||
GLint useAlphaMatte = -1; // always inverted
|
||||
struct SUniform4Data {
|
||||
GLsizei count = 0;
|
||||
std::vector<float> value;
|
||||
};
|
||||
|
||||
GLint applyTint = -1;
|
||||
GLint tint = -1;
|
||||
//
|
||||
std::array<std::variant<std::monostate, GLint, GLfloat, std::array<GLfloat, 2>, std::array<GLfloat, 3>, std::array<GLfloat, 4>, SUniformMatrix3Data, SUniformMatrix4Data,
|
||||
SUniform4Data>,
|
||||
SHADER_LAST>
|
||||
uniformStatus;
|
||||
//
|
||||
|
||||
GLint gradient = -1;
|
||||
GLint gradientLength = -1;
|
||||
GLint angle = -1;
|
||||
GLint gradient2 = -1;
|
||||
GLint gradient2Length = -1;
|
||||
GLint angle2 = -1;
|
||||
GLint gradientLerp = -1;
|
||||
|
||||
float initialTime = 0;
|
||||
GLint time = -1;
|
||||
GLint distort = -1;
|
||||
GLint wl_output = -1;
|
||||
|
||||
// Blur prepare
|
||||
GLint contrast = -1;
|
||||
|
||||
// Blur
|
||||
GLint passes = -1; // Used by `vibrancy`
|
||||
GLint vibrancy = -1;
|
||||
GLint vibrancy_darkness = -1;
|
||||
|
||||
// Blur finish
|
||||
GLint brightness = -1;
|
||||
GLint noise = -1;
|
||||
|
||||
void createVao();
|
||||
void destroy();
|
||||
void createVao();
|
||||
void setUniformInt(eShaderUniform location, GLint v0);
|
||||
void setUniformFloat(eShaderUniform location, GLfloat v0);
|
||||
void setUniformFloat2(eShaderUniform location, GLfloat v0, GLfloat v1);
|
||||
void setUniformFloat3(eShaderUniform location, GLfloat v0, GLfloat v1, GLfloat v2);
|
||||
void setUniformFloat4(eShaderUniform location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
|
||||
void setUniformMatrix3fv(eShaderUniform location, GLsizei count, GLboolean transpose, std::array<GLfloat, 9> value);
|
||||
void setUniformMatrix4x2fv(eShaderUniform location, GLsizei count, GLboolean transpose, std::array<GLfloat, 8> value);
|
||||
void setUniform4fv(eShaderUniform location, GLsizei count, std::vector<float> value);
|
||||
void destroy();
|
||||
};
|
||||
|
@@ -67,21 +67,21 @@ void CTexture::createFromShm(uint32_t drmFormat, uint8_t* pixels, uint32_t strid
|
||||
m_type = format->withAlpha ? TEXTURE_RGBA : TEXTURE_RGBX;
|
||||
m_size = size_;
|
||||
m_isSynchronous = true;
|
||||
m_target = GL_TEXTURE_2D;
|
||||
allocate();
|
||||
|
||||
GLCALL(glBindTexture(GL_TEXTURE_2D, m_texID));
|
||||
GLCALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
|
||||
GLCALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
|
||||
bind();
|
||||
setTexParameter(GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
setTexParameter(GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
if (format->flipRB) {
|
||||
GLCALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_BLUE));
|
||||
GLCALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED));
|
||||
setTexParameter(GL_TEXTURE_SWIZZLE_R, GL_BLUE);
|
||||
setTexParameter(GL_TEXTURE_SWIZZLE_B, GL_RED);
|
||||
}
|
||||
|
||||
GLCALL(glPixelStorei(GL_UNPACK_ROW_LENGTH_EXT, stride / format->bytesPerBlock));
|
||||
GLCALL(glTexImage2D(GL_TEXTURE_2D, 0, format->glInternalFormat ? format->glInternalFormat : format->glFormat, size_.x, size_.y, 0, format->glFormat, format->glType, pixels));
|
||||
GLCALL(glPixelStorei(GL_UNPACK_ROW_LENGTH_EXT, 0));
|
||||
GLCALL(glBindTexture(GL_TEXTURE_2D, 0));
|
||||
unbind();
|
||||
|
||||
if (m_keepDataCopy) {
|
||||
m_dataCopy.resize(stride * size_.y);
|
||||
@@ -103,11 +103,11 @@ void CTexture::createFromDma(const Aquamarine::SDMABUFAttrs& attrs, void* image)
|
||||
allocate();
|
||||
m_eglImage = image;
|
||||
|
||||
GLCALL(glBindTexture(GL_TEXTURE_2D, m_texID));
|
||||
GLCALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
|
||||
GLCALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
|
||||
bind();
|
||||
setTexParameter(GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
setTexParameter(GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
GLCALL(g_pHyprOpenGL->m_proc.glEGLImageTargetTexture2DOES(m_target, image));
|
||||
GLCALL(glBindTexture(GL_TEXTURE_2D, 0));
|
||||
unbind();
|
||||
}
|
||||
|
||||
void CTexture::update(uint32_t drmFormat, uint8_t* pixels, uint32_t stride, const CRegion& damage) {
|
||||
@@ -116,13 +116,13 @@ void CTexture::update(uint32_t drmFormat, uint8_t* pixels, uint32_t stride, cons
|
||||
const auto format = NFormatUtils::getPixelFormatFromDRM(drmFormat);
|
||||
ASSERT(format);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, m_texID);
|
||||
bind();
|
||||
|
||||
auto rects = damage.copy().intersect(CBox{{}, m_size}).getRects();
|
||||
|
||||
if (format->flipRB) {
|
||||
GLCALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_BLUE));
|
||||
GLCALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED));
|
||||
setTexParameter(GL_TEXTURE_SWIZZLE_R, GL_BLUE);
|
||||
setTexParameter(GL_TEXTURE_SWIZZLE_B, GL_RED);
|
||||
}
|
||||
|
||||
for (auto const& rect : rects) {
|
||||
@@ -139,7 +139,7 @@ void CTexture::update(uint32_t drmFormat, uint8_t* pixels, uint32_t stride, cons
|
||||
GLCALL(glPixelStorei(GL_UNPACK_SKIP_PIXELS_EXT, 0));
|
||||
GLCALL(glPixelStorei(GL_UNPACK_SKIP_ROWS_EXT, 0));
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
unbind();
|
||||
|
||||
if (m_keepDataCopy) {
|
||||
m_dataCopy.resize(stride * m_size.y);
|
||||
@@ -166,3 +166,40 @@ void CTexture::allocate() {
|
||||
const std::vector<uint8_t>& CTexture::dataCopy() {
|
||||
return m_dataCopy;
|
||||
}
|
||||
|
||||
void CTexture::bind() {
|
||||
GLCALL(glBindTexture(m_target, m_texID));
|
||||
}
|
||||
|
||||
void CTexture::unbind() {
|
||||
GLCALL(glBindTexture(m_target, 0));
|
||||
}
|
||||
|
||||
constexpr std::optional<size_t> CTexture::getCacheStateIndex(GLenum pname) {
|
||||
switch (pname) {
|
||||
case GL_TEXTURE_WRAP_S: return TEXTURE_PAR_WRAP_S;
|
||||
case GL_TEXTURE_WRAP_T: return TEXTURE_PAR_WRAP_T;
|
||||
case GL_TEXTURE_MAG_FILTER: return TEXTURE_PAR_MAG_FILTER;
|
||||
case GL_TEXTURE_MIN_FILTER: return TEXTURE_PAR_MIN_FILTER;
|
||||
case GL_TEXTURE_SWIZZLE_R: return TEXTURE_PAR_SWIZZLE_R;
|
||||
case GL_TEXTURE_SWIZZLE_B: return TEXTURE_PAR_SWIZZLE_B;
|
||||
default: return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
void CTexture::setTexParameter(GLenum pname, GLint param) {
|
||||
const auto cacheIndex = getCacheStateIndex(pname);
|
||||
|
||||
if (!cacheIndex) {
|
||||
GLCALL(glTexParameteri(m_target, pname, param));
|
||||
return;
|
||||
}
|
||||
|
||||
const auto idx = cacheIndex.value();
|
||||
|
||||
if (m_cachedStates[idx] == param)
|
||||
return;
|
||||
|
||||
m_cachedStates[idx] = param;
|
||||
GLCALL(glTexParameteri(m_target, pname, param));
|
||||
}
|
||||
|
@@ -34,6 +34,9 @@ class CTexture {
|
||||
void allocate();
|
||||
void update(uint32_t drmFormat, uint8_t* pixels, uint32_t stride, const CRegion& damage);
|
||||
const std::vector<uint8_t>& dataCopy();
|
||||
void bind();
|
||||
void unbind();
|
||||
void setTexParameter(GLenum pname, GLint param);
|
||||
|
||||
eTextureType m_type = TEXTURE_RGBA;
|
||||
GLenum m_target = GL_TEXTURE_2D;
|
||||
@@ -46,10 +49,21 @@ class CTexture {
|
||||
bool m_isSynchronous = false;
|
||||
|
||||
private:
|
||||
void createFromShm(uint32_t drmFormat, uint8_t* pixels, uint32_t stride, const Vector2D& size);
|
||||
void createFromDma(const Aquamarine::SDMABUFAttrs&, void* image);
|
||||
enum eTextureParam : uint8_t {
|
||||
TEXTURE_PAR_WRAP_S = 0,
|
||||
TEXTURE_PAR_WRAP_T,
|
||||
TEXTURE_PAR_MAG_FILTER,
|
||||
TEXTURE_PAR_MIN_FILTER,
|
||||
TEXTURE_PAR_SWIZZLE_R,
|
||||
TEXTURE_PAR_SWIZZLE_B,
|
||||
TEXTURE_PAR_LAST,
|
||||
};
|
||||
|
||||
bool m_keepDataCopy = false;
|
||||
void createFromShm(uint32_t drmFormat, uint8_t* pixels, uint32_t stride, const Vector2D& size);
|
||||
void createFromDma(const Aquamarine::SDMABUFAttrs&, void* image);
|
||||
inline constexpr std::optional<size_t> getCacheStateIndex(GLenum pname);
|
||||
|
||||
std::vector<uint8_t> m_dataCopy;
|
||||
};
|
||||
bool m_keepDataCopy = false;
|
||||
std::vector<uint8_t> m_dataCopy;
|
||||
std::array<std::optional<GLint>, TEXTURE_PAR_LAST> m_cachedStates;
|
||||
};
|
||||
|
@@ -347,11 +347,11 @@ static void renderGradientTo(SP<CTexture> tex, CGradientValueData* grad) {
|
||||
// copy the data to an OpenGL texture we have
|
||||
const auto DATA = cairo_image_surface_get_data(CAIROSURFACE);
|
||||
tex->allocate();
|
||||
glBindTexture(GL_TEXTURE_2D, tex->m_texID);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_BLUE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED);
|
||||
tex->bind();
|
||||
tex->setTexParameter(GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
tex->setTexParameter(GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
tex->setTexParameter(GL_TEXTURE_SWIZZLE_R, GL_BLUE);
|
||||
tex->setTexParameter(GL_TEXTURE_SWIZZLE_B, GL_RED);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bufferSize.x, bufferSize.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, DATA);
|
||||
|
||||
|
@@ -1,6 +1,5 @@
|
||||
#version 100
|
||||
#version 300 es
|
||||
precision highp float;
|
||||
varying highp vec2 v_texcoord; // is in 0-1
|
||||
uniform sampler2D tex;
|
||||
|
||||
uniform float radius;
|
||||
@@ -9,6 +8,8 @@ uniform int passes;
|
||||
uniform float vibrancy;
|
||||
uniform float vibrancy_darkness;
|
||||
|
||||
in vec2 v_texcoord;
|
||||
|
||||
// see http://alienryderflex.com/hsp.html
|
||||
const float Pr = 0.299;
|
||||
const float Pg = 0.587;
|
||||
@@ -107,6 +108,7 @@ vec3 hsl2rgb(vec3 col) {
|
||||
return rgb;
|
||||
}
|
||||
|
||||
layout(location = 0) out vec4 fragColor;
|
||||
void main() {
|
||||
vec2 uv = v_texcoord * 2.0;
|
||||
|
||||
@@ -119,7 +121,7 @@ void main() {
|
||||
vec4 color = sum / 8.0;
|
||||
|
||||
if (vibrancy == 0.0) {
|
||||
gl_FragColor = color;
|
||||
fragColor = color;
|
||||
} else {
|
||||
// Invert it so that it correctly maps to the config setting
|
||||
float vibrancy_darkness1 = 1.0 - vibrancy_darkness;
|
||||
@@ -136,6 +138,6 @@ void main() {
|
||||
|
||||
vec3 newColor = hsl2rgb(vec3(hsl[0], saturation, hsl[2]));
|
||||
|
||||
gl_FragColor = vec4(newColor, color[3]);
|
||||
fragColor = vec4(newColor, color[3]);
|
||||
}
|
||||
}
|
||||
|
@@ -1,11 +1,15 @@
|
||||
#version 100
|
||||
#version 300 es
|
||||
precision highp float;
|
||||
varying highp vec2 v_texcoord; // is in 0-1
|
||||
uniform sampler2D tex;
|
||||
|
||||
uniform float radius;
|
||||
uniform vec2 halfpixel;
|
||||
|
||||
in vec2 v_texcoord;
|
||||
|
||||
out vec4 v_color;
|
||||
|
||||
layout(location = 0) out vec4 fragColor;
|
||||
void main() {
|
||||
vec2 uv = v_texcoord / 2.0;
|
||||
|
||||
@@ -19,5 +23,5 @@ void main() {
|
||||
sum += texture2D(tex, uv + vec2(0.0, -halfpixel.y * 2.0) * radius);
|
||||
sum += texture2D(tex, uv + vec2(-halfpixel.x, -halfpixel.y) * radius) * 2.0;
|
||||
|
||||
gl_FragColor = sum / 12.0;
|
||||
fragColor = sum / 12.0;
|
||||
}
|
||||
|
@@ -1,28 +0,0 @@
|
||||
precision highp float;
|
||||
varying vec2 v_texcoord; // is in 0-1
|
||||
uniform sampler2D tex;
|
||||
|
||||
uniform float noise;
|
||||
uniform float brightness;
|
||||
|
||||
float hash(vec2 p) {
|
||||
vec3 p3 = fract(vec3(p.xyx) * 1689.1984);
|
||||
p3 += dot(p3, p3.yzx + 33.33);
|
||||
return fract((p3.x + p3.y) * p3.z);
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec4 pixColor = texture2D(tex, v_texcoord);
|
||||
|
||||
// noise
|
||||
float noiseHash = hash(v_texcoord);
|
||||
float noiseAmount = (mod(noiseHash, 1.0) - 0.5);
|
||||
pixColor.rgb += noiseAmount * noise;
|
||||
|
||||
// brightness
|
||||
if (brightness < 1.0) {
|
||||
pixColor.rgb *= brightness;
|
||||
}
|
||||
|
||||
gl_FragColor = pixColor;
|
||||
}
|
@@ -1,29 +0,0 @@
|
||||
precision highp float;
|
||||
varying vec2 v_texcoord; // is in 0-1
|
||||
uniform sampler2D tex;
|
||||
|
||||
uniform float contrast;
|
||||
uniform float brightness;
|
||||
|
||||
float gain(float x, float k) {
|
||||
float a = 0.5 * pow(2.0 * ((x < 0.5) ? x : 1.0 - x), k);
|
||||
return (x < 0.5) ? a : 1.0 - a;
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec4 pixColor = texture2D(tex, v_texcoord);
|
||||
|
||||
// contrast
|
||||
if (contrast != 1.0) {
|
||||
pixColor.r = gain(pixColor.r, contrast);
|
||||
pixColor.g = gain(pixColor.g, contrast);
|
||||
pixColor.b = gain(pixColor.b, contrast);
|
||||
}
|
||||
|
||||
// brightness
|
||||
if (brightness > 1.0) {
|
||||
pixColor.rgb *= brightness;
|
||||
}
|
||||
|
||||
gl_FragColor = pixColor;
|
||||
}
|
@@ -1,174 +0,0 @@
|
||||
#extension GL_ARB_shading_language_include : enable
|
||||
|
||||
precision highp float;
|
||||
varying vec4 v_color;
|
||||
varying vec2 v_texcoord;
|
||||
|
||||
uniform vec2 fullSizeUntransformed;
|
||||
uniform float radiusOuter;
|
||||
uniform float thick;
|
||||
|
||||
// Gradients are in OkLabA!!!! {l, a, b, alpha}
|
||||
uniform vec4 gradient[10];
|
||||
uniform vec4 gradient2[10];
|
||||
uniform int gradientLength;
|
||||
uniform int gradient2Length;
|
||||
uniform float angle;
|
||||
uniform float angle2;
|
||||
uniform float gradientLerp;
|
||||
uniform float alpha;
|
||||
|
||||
#include "rounding.glsl"
|
||||
|
||||
float linearToGamma(float x) {
|
||||
return x >= 0.0031308 ? 1.055 * pow(x, 0.416666666) - 0.055 : 12.92 * x;
|
||||
}
|
||||
|
||||
vec4 okLabAToSrgb(vec4 lab) {
|
||||
float l = pow(lab[0] + lab[1] * 0.3963377774 + lab[2] * 0.2158037573, 3.0);
|
||||
float m = pow(lab[0] + lab[1] * (-0.1055613458) + lab[2] * (-0.0638541728), 3.0);
|
||||
float s = pow(lab[0] + lab[1] * (-0.0894841775) + lab[2] * (-1.2914855480), 3.0);
|
||||
|
||||
return vec4(linearToGamma(l * 4.0767416621 + m * -3.3077115913 + s * 0.2309699292),
|
||||
linearToGamma(l * (-1.2684380046) + m * 2.6097574011 + s * (-0.3413193965)),
|
||||
linearToGamma(l * (-0.0041960863) + m * (-0.7034186147) + s * 1.7076147010),
|
||||
lab[3]);
|
||||
}
|
||||
|
||||
vec4 getOkColorForCoordArray1(vec2 normalizedCoord) {
|
||||
if (gradientLength < 2)
|
||||
return gradient[0];
|
||||
|
||||
float finalAng = 0.0;
|
||||
|
||||
if (angle > 4.71 /* 270 deg */) {
|
||||
normalizedCoord[1] = 1.0 - normalizedCoord[1];
|
||||
finalAng = 6.28 - angle;
|
||||
} else if (angle > 3.14 /* 180 deg */) {
|
||||
normalizedCoord[0] = 1.0 - normalizedCoord[0];
|
||||
normalizedCoord[1] = 1.0 - normalizedCoord[1];
|
||||
finalAng = angle - 3.14;
|
||||
} else if (angle > 1.57 /* 90 deg */) {
|
||||
normalizedCoord[0] = 1.0 - normalizedCoord[0];
|
||||
finalAng = 3.14 - angle;
|
||||
} else {
|
||||
finalAng = angle;
|
||||
}
|
||||
|
||||
float sine = sin(finalAng);
|
||||
|
||||
float progress = (normalizedCoord[1] * sine + normalizedCoord[0] * (1.0 - sine)) * float(gradientLength - 1);
|
||||
int bottom = int(floor(progress));
|
||||
int top = bottom + 1;
|
||||
|
||||
return gradient[top] * (progress - float(bottom)) + gradient[bottom] * (float(top) - progress);
|
||||
}
|
||||
|
||||
vec4 getOkColorForCoordArray2(vec2 normalizedCoord) {
|
||||
if (gradient2Length < 2)
|
||||
return gradient2[0];
|
||||
|
||||
float finalAng = 0.0;
|
||||
|
||||
if (angle2 > 4.71 /* 270 deg */) {
|
||||
normalizedCoord[1] = 1.0 - normalizedCoord[1];
|
||||
finalAng = 6.28 - angle;
|
||||
} else if (angle2 > 3.14 /* 180 deg */) {
|
||||
normalizedCoord[0] = 1.0 - normalizedCoord[0];
|
||||
normalizedCoord[1] = 1.0 - normalizedCoord[1];
|
||||
finalAng = angle - 3.14;
|
||||
} else if (angle2 > 1.57 /* 90 deg */) {
|
||||
normalizedCoord[0] = 1.0 - normalizedCoord[0];
|
||||
finalAng = 3.14 - angle2;
|
||||
} else {
|
||||
finalAng = angle2;
|
||||
}
|
||||
|
||||
float sine = sin(finalAng);
|
||||
|
||||
float progress = (normalizedCoord[1] * sine + normalizedCoord[0] * (1.0 - sine)) * float(gradient2Length - 1);
|
||||
int bottom = int(floor(progress));
|
||||
int top = bottom + 1;
|
||||
|
||||
return gradient2[top] * (progress - float(bottom)) + gradient2[bottom] * (float(top) - progress);
|
||||
}
|
||||
|
||||
vec4 getColorForCoord(vec2 normalizedCoord) {
|
||||
vec4 result1 = getOkColorForCoordArray1(normalizedCoord);
|
||||
|
||||
if (gradient2Length <= 0)
|
||||
return okLabAToSrgb(result1);
|
||||
|
||||
vec4 result2 = getOkColorForCoordArray2(normalizedCoord);
|
||||
|
||||
return okLabAToSrgb(mix(result1, result2, gradientLerp));
|
||||
}
|
||||
|
||||
void main() {
|
||||
|
||||
highp vec2 pixCoord = vec2(gl_FragCoord);
|
||||
highp vec2 pixCoordOuter = pixCoord;
|
||||
highp vec2 originalPixCoord = v_texcoord;
|
||||
originalPixCoord *= fullSizeUntransformed;
|
||||
float additionalAlpha = 1.0;
|
||||
|
||||
vec4 pixColor = vec4(1.0, 1.0, 1.0, 1.0);
|
||||
|
||||
bool done = false;
|
||||
|
||||
pixCoord -= topLeft + fullSize * 0.5;
|
||||
pixCoord *= vec2(lessThan(pixCoord, vec2(0.0))) * -2.0 + 1.0;
|
||||
pixCoordOuter = pixCoord;
|
||||
pixCoord -= fullSize * 0.5 - radius;
|
||||
pixCoordOuter -= fullSize * 0.5 - radiusOuter;
|
||||
|
||||
// center the pixes dont make it top-left
|
||||
pixCoord += vec2(1.0, 1.0) / fullSize;
|
||||
pixCoordOuter += vec2(1.0, 1.0) / fullSize;
|
||||
|
||||
if (min(pixCoord.x, pixCoord.y) > 0.0 && radius > 0.0) {
|
||||
float dist = pow(pow(pixCoord.x,roundingPower)+pow(pixCoord.y,roundingPower),1.0/roundingPower);
|
||||
float distOuter = pow(pow(pixCoordOuter.x,roundingPower)+pow(pixCoordOuter.y,roundingPower),1.0/roundingPower);
|
||||
float h = (thick / 2.0);
|
||||
|
||||
if (dist < radius - h) {
|
||||
// lower
|
||||
float normalized = smoothstep(0.0, 1.0, (dist - radius + thick + SMOOTHING_CONSTANT) / (SMOOTHING_CONSTANT * 2.0));
|
||||
additionalAlpha *= normalized;
|
||||
done = true;
|
||||
} else if (min(pixCoordOuter.x, pixCoordOuter.y) > 0.0) {
|
||||
// higher
|
||||
float normalized = 1.0 - smoothstep(0.0, 1.0, (distOuter - radiusOuter + SMOOTHING_CONSTANT) / (SMOOTHING_CONSTANT * 2.0));
|
||||
additionalAlpha *= normalized;
|
||||
done = true;
|
||||
} else if (distOuter < radiusOuter - h) {
|
||||
additionalAlpha = 1.0;
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
|
||||
// now check for other shit
|
||||
if (!done) {
|
||||
// distance to all straight bb borders
|
||||
float distanceT = originalPixCoord[1];
|
||||
float distanceB = fullSizeUntransformed[1] - originalPixCoord[1];
|
||||
float distanceL = originalPixCoord[0];
|
||||
float distanceR = fullSizeUntransformed[0] - originalPixCoord[0];
|
||||
|
||||
// get the smallest
|
||||
float smallest = min(min(distanceT, distanceB), min(distanceL, distanceR));
|
||||
|
||||
if (smallest > thick)
|
||||
discard;
|
||||
}
|
||||
|
||||
if (additionalAlpha == 0.0)
|
||||
discard;
|
||||
|
||||
pixColor = getColorForCoord(v_texcoord);
|
||||
pixColor.rgb *= pixColor[3];
|
||||
|
||||
pixColor *= alpha * additionalAlpha;
|
||||
|
||||
gl_FragColor = pixColor;
|
||||
}
|
@@ -1,8 +1,10 @@
|
||||
#version 300 es
|
||||
|
||||
#extension GL_ARB_shading_language_include : enable
|
||||
#extension GL_OES_EGL_image_external : require
|
||||
|
||||
precision highp float;
|
||||
varying vec2 v_texcoord;
|
||||
in vec2 v_texcoord;
|
||||
uniform samplerExternalOES texture0;
|
||||
uniform float alpha;
|
||||
|
||||
@@ -15,6 +17,7 @@ uniform int discardAlphaValue;
|
||||
uniform int applyTint;
|
||||
uniform vec3 tint;
|
||||
|
||||
layout(location = 0) out vec4 fragColor;
|
||||
void main() {
|
||||
|
||||
vec4 pixColor = texture2D(texture0, v_texcoord);
|
||||
@@ -31,5 +34,5 @@ void main() {
|
||||
if (radius > 0.0)
|
||||
pixColor = rounding(pixColor);
|
||||
|
||||
gl_FragColor = pixColor * alpha;
|
||||
fragColor = pixColor * alpha;
|
||||
}
|
||||
|
@@ -1,5 +1,7 @@
|
||||
#version 300 es
|
||||
|
||||
precision highp float;
|
||||
varying vec2 v_texcoord;
|
||||
in vec2 v_texcoord;
|
||||
uniform sampler2D tex;
|
||||
uniform float time; // quirk: time is set to 0 at the beginning, should be around 10 when crash.
|
||||
uniform float distort;
|
||||
@@ -24,6 +26,7 @@ float noise(vec2 point) {
|
||||
return mixed * mixed;
|
||||
}
|
||||
|
||||
layout(location = 0) out vec4 fragColor;
|
||||
void main() {
|
||||
float ABERR_OFFSET = 4.0 * (distort / 5.5) * time;
|
||||
float TEAR_AMOUNT = 9000.0 * (1.0 - (distort / 5.5));
|
||||
@@ -60,5 +63,5 @@ void main() {
|
||||
|
||||
pixColor[0] += distort / 90.0;
|
||||
|
||||
gl_FragColor = pixColor;
|
||||
fragColor = pixColor;
|
||||
}
|
||||
|
@@ -1,7 +1,10 @@
|
||||
#version 300 es
|
||||
|
||||
precision highp float;
|
||||
varying vec2 v_texcoord; // is in 0-1
|
||||
in vec2 v_texcoord; // is in 0-1
|
||||
uniform sampler2D tex;
|
||||
|
||||
layout(location = 0) out vec4 fragColor;
|
||||
void main() {
|
||||
gl_FragColor = texture2D(tex, v_texcoord);
|
||||
fragColor = texture2D(tex, v_texcoord);
|
||||
}
|
||||
|
@@ -1,14 +1,17 @@
|
||||
#version 300 es
|
||||
|
||||
#extension GL_ARB_shading_language_include : enable
|
||||
precision highp float;
|
||||
varying vec4 v_color;
|
||||
in vec4 v_color;
|
||||
|
||||
#include "rounding.glsl"
|
||||
|
||||
layout(location = 0) out vec4 fragColor;
|
||||
void main() {
|
||||
vec4 pixColor = v_color;
|
||||
|
||||
if (radius > 0.0)
|
||||
pixColor = rounding(pixColor);
|
||||
|
||||
gl_FragColor = pixColor;
|
||||
fragColor = pixColor;
|
||||
}
|
||||
|
@@ -1,6 +1,8 @@
|
||||
#version 300 es
|
||||
|
||||
#extension GL_ARB_shading_language_include : enable
|
||||
precision highp float;
|
||||
varying vec2 v_texcoord; // is in 0-1
|
||||
in vec2 v_texcoord; // is in 0-1
|
||||
uniform sampler2D tex;
|
||||
uniform float alpha;
|
||||
|
||||
@@ -13,6 +15,7 @@ uniform float discardAlphaValue;
|
||||
uniform int applyTint;
|
||||
uniform vec3 tint;
|
||||
|
||||
layout(location = 0) out vec4 fragColor;
|
||||
void main() {
|
||||
|
||||
vec4 pixColor = texture2D(tex, v_texcoord);
|
||||
@@ -32,5 +35,5 @@ void main() {
|
||||
if (radius > 0.0)
|
||||
pixColor = rounding(pixColor);
|
||||
|
||||
gl_FragColor = pixColor * alpha;
|
||||
fragColor = pixColor * alpha;
|
||||
}
|
||||
|
@@ -1,8 +1,11 @@
|
||||
#version 300 es
|
||||
|
||||
precision highp float;
|
||||
varying vec2 v_texcoord; // is in 0-1
|
||||
in vec2 v_texcoord; // is in 0-1
|
||||
uniform sampler2D tex;
|
||||
uniform sampler2D texMatte;
|
||||
|
||||
layout(location = 0) out vec4 fragColor;
|
||||
void main() {
|
||||
gl_FragColor = texture2D(tex, v_texcoord) * texture2D(texMatte, v_texcoord)[0]; // I know it only uses R, but matte should be black/white anyways.
|
||||
fragColor = texture2D(tex, v_texcoord) * texture2D(texMatte, v_texcoord)[0]; // I know it only uses R, but matte should be black/white anyways.
|
||||
}
|
||||
|
@@ -1,6 +1,7 @@
|
||||
#version 300 es
|
||||
#extension GL_ARB_shading_language_include : enable
|
||||
precision highp float;
|
||||
varying vec2 v_texcoord;
|
||||
in vec2 v_texcoord;
|
||||
uniform sampler2D tex;
|
||||
uniform float alpha;
|
||||
|
||||
@@ -13,6 +14,7 @@ uniform int discardAlphaValue;
|
||||
uniform int applyTint;
|
||||
uniform vec3 tint;
|
||||
|
||||
layout(location = 0) out vec4 fragColor;
|
||||
void main() {
|
||||
|
||||
if (discardOpaque == 1 && alpha == 1.0)
|
||||
@@ -21,13 +23,13 @@ void main() {
|
||||
vec4 pixColor = vec4(texture2D(tex, v_texcoord).rgb, 1.0);
|
||||
|
||||
if (applyTint == 1) {
|
||||
pixColor[0] = pixColor[0] * tint[0];
|
||||
pixColor[1] = pixColor[1] * tint[1];
|
||||
pixColor[2] = pixColor[2] * tint[2];
|
||||
pixColor[0] = pixColor[0] * tint[0];
|
||||
pixColor[1] = pixColor[1] * tint[1];
|
||||
pixColor[2] = pixColor[2] * tint[2];
|
||||
}
|
||||
|
||||
if (radius > 0.0)
|
||||
pixColor = rounding(pixColor);
|
||||
|
||||
gl_FragColor = pixColor * alpha;
|
||||
fragColor = pixColor * alpha;
|
||||
}
|
||||
|
@@ -1,86 +0,0 @@
|
||||
#extension GL_ARB_shading_language_include : enable
|
||||
precision highp float;
|
||||
varying vec4 v_color;
|
||||
varying vec2 v_texcoord;
|
||||
|
||||
uniform vec2 topLeft;
|
||||
uniform vec2 bottomRight;
|
||||
uniform vec2 fullSize;
|
||||
uniform float radius;
|
||||
uniform float roundingPower;
|
||||
uniform float range;
|
||||
uniform float shadowPower;
|
||||
|
||||
float pixAlphaRoundedDistance(float distanceToCorner) {
|
||||
if (distanceToCorner > radius) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
if (distanceToCorner > radius - range) {
|
||||
return pow((range - (distanceToCorner - radius + range)) / range, shadowPower); // i think?
|
||||
}
|
||||
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
float modifiedLength(vec2 a) {
|
||||
return pow(pow(abs(a.x),roundingPower)+pow(abs(a.y),roundingPower),1.0/roundingPower);
|
||||
}
|
||||
|
||||
void main() {
|
||||
|
||||
vec4 pixColor = v_color;
|
||||
float originalAlpha = pixColor[3];
|
||||
|
||||
bool done = false;
|
||||
|
||||
vec2 pixCoord = fullSize * v_texcoord;
|
||||
|
||||
// ok, now we check the distance to a border.
|
||||
|
||||
if (pixCoord[0] < topLeft[0]) {
|
||||
if (pixCoord[1] < topLeft[1]) {
|
||||
// top left
|
||||
pixColor[3] = pixColor[3] * pixAlphaRoundedDistance(modifiedLength(pixCoord - topLeft));
|
||||
done = true;
|
||||
} else if (pixCoord[1] > bottomRight[1]) {
|
||||
// bottom left
|
||||
pixColor[3] = pixColor[3] * pixAlphaRoundedDistance(modifiedLength(pixCoord - vec2(topLeft[0], bottomRight[1])));
|
||||
done = true;
|
||||
}
|
||||
} else if (pixCoord[0] > bottomRight[0]) {
|
||||
if (pixCoord[1] < topLeft[1]) {
|
||||
// top right
|
||||
pixColor[3] = pixColor[3] * pixAlphaRoundedDistance(modifiedLength(pixCoord - vec2(bottomRight[0], topLeft[1])));
|
||||
done = true;
|
||||
} else if (pixCoord[1] > bottomRight[1]) {
|
||||
// bottom right
|
||||
pixColor[3] = pixColor[3] * pixAlphaRoundedDistance(modifiedLength(pixCoord - bottomRight));
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!done) {
|
||||
// distance to all straight bb borders
|
||||
float distanceT = pixCoord[1];
|
||||
float distanceB = fullSize[1] - pixCoord[1];
|
||||
float distanceL = pixCoord[0];
|
||||
float distanceR = fullSize[0] - pixCoord[0];
|
||||
|
||||
// get the smallest
|
||||
float smallest = min(min(distanceT, distanceB), min(distanceL, distanceR));
|
||||
|
||||
if (smallest < range) {
|
||||
pixColor[3] = pixColor[3] * pow((smallest / range), shadowPower);
|
||||
}
|
||||
}
|
||||
|
||||
if (pixColor[3] == 0.0) {
|
||||
discard; return;
|
||||
}
|
||||
|
||||
// premultiply
|
||||
pixColor.rgb *= pixColor[3];
|
||||
|
||||
gl_FragColor = pixColor;
|
||||
}
|
@@ -1,15 +0,0 @@
|
||||
uniform mat3 proj;
|
||||
uniform vec4 color;
|
||||
attribute vec2 pos;
|
||||
attribute vec2 texcoord;
|
||||
attribute vec2 texcoordMatte;
|
||||
varying vec4 v_color;
|
||||
varying vec2 v_texcoord;
|
||||
varying vec2 v_texcoordMatte;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(proj * vec3(pos, 1.0), 1.0);
|
||||
v_color = color;
|
||||
v_texcoord = texcoord;
|
||||
v_texcoordMatte = texcoordMatte;
|
||||
}
|
@@ -2,9 +2,11 @@
|
||||
|
||||
uniform mat3 proj;
|
||||
uniform vec4 color;
|
||||
|
||||
in vec2 pos;
|
||||
in vec2 texcoord;
|
||||
in vec2 texcoordMatte;
|
||||
|
||||
out vec4 v_color;
|
||||
out vec2 v_texcoord;
|
||||
out vec2 v_texcoordMatte;
|
||||
|
@@ -2,9 +2,11 @@
|
||||
|
||||
uniform mat3 proj;
|
||||
uniform vec4 color;
|
||||
|
||||
in vec2 pos;
|
||||
in vec2 texcoord;
|
||||
in vec2 texcoordMatte;
|
||||
|
||||
out vec4 v_color;
|
||||
out vec2 v_texcoord;
|
||||
out vec2 v_texcoordMatte;
|
||||
|
Reference in New Issue
Block a user