diff options
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | assets/wall0.png | bin | 0 -> 14194868 bytes | |||
-rw-r--r-- | assets/wall1.png | bin | 0 -> 5690948 bytes | |||
-rw-r--r-- | assets/wall2.png | bin | 0 -> 28264194 bytes | |||
-rw-r--r-- | assets/wall_2K.png | bin | 18186 -> 0 bytes | |||
-rw-r--r-- | assets/wall_4K.png | bin | 49045 -> 0 bytes | |||
-rw-r--r-- | assets/wall_8K.png | bin | 149067 -> 0 bytes | |||
-rw-r--r-- | assets/wall_anime2_2K.png | bin | 523055 -> 0 bytes | |||
-rw-r--r-- | assets/wall_anime2_4K.png | bin | 1387297 -> 0 bytes | |||
-rw-r--r-- | assets/wall_anime2_8K.png | bin | 1378652 -> 0 bytes | |||
-rw-r--r-- | assets/wall_anime_2K.png | bin | 514144 -> 0 bytes | |||
-rw-r--r-- | assets/wall_anime_4K.png | bin | 1427703 -> 0 bytes | |||
-rw-r--r-- | assets/wall_anime_8K.png | bin | 1700093 -> 0 bytes | |||
-rw-r--r-- | example/hyprland.conf | 2 | ||||
-rw-r--r-- | src/config/ConfigManager.cpp | 1 | ||||
-rw-r--r-- | src/config/defaultConfig.hpp | 2 | ||||
-rw-r--r-- | src/render/OpenGL.cpp | 168 | ||||
-rw-r--r-- | src/render/OpenGL.hpp | 6 |
18 files changed, 98 insertions, 83 deletions
@@ -45,7 +45,7 @@ install: cd ${PREFIX}/bin && ln -sf Hyprland hyprland if [ ! -f ${PREFIX}/share/wayland-sessions/hyprland.desktop ]; then cp ./example/hyprland.desktop ${PREFIX}/share/wayland-sessions; fi mkdir -p ${PREFIX}/share/hyprland - cp ./assets/wall_* ${PREFIX}/share/hyprland + cp ./assets/wall* ${PREFIX}/share/hyprland mkdir -p ${PREFIX}/share/xdg-desktop-portal cp ./assets/hyprland-portals.conf ${PREFIX}/share/xdg-desktop-portal diff --git a/assets/wall0.png b/assets/wall0.png Binary files differnew file mode 100644 index 00000000..73bdeef8 --- /dev/null +++ b/assets/wall0.png diff --git a/assets/wall1.png b/assets/wall1.png Binary files differnew file mode 100644 index 00000000..ad2b5678 --- /dev/null +++ b/assets/wall1.png diff --git a/assets/wall2.png b/assets/wall2.png Binary files differnew file mode 100644 index 00000000..9ade4720 --- /dev/null +++ b/assets/wall2.png diff --git a/assets/wall_2K.png b/assets/wall_2K.png Binary files differdeleted file mode 100644 index 5aea012a..00000000 --- a/assets/wall_2K.png +++ /dev/null diff --git a/assets/wall_4K.png b/assets/wall_4K.png Binary files differdeleted file mode 100644 index f835a978..00000000 --- a/assets/wall_4K.png +++ /dev/null diff --git a/assets/wall_8K.png b/assets/wall_8K.png Binary files differdeleted file mode 100644 index 539aa97d..00000000 --- a/assets/wall_8K.png +++ /dev/null diff --git a/assets/wall_anime2_2K.png b/assets/wall_anime2_2K.png Binary files differdeleted file mode 100644 index 5a465efa..00000000 --- a/assets/wall_anime2_2K.png +++ /dev/null diff --git a/assets/wall_anime2_4K.png b/assets/wall_anime2_4K.png Binary files differdeleted file mode 100644 index b04e6d00..00000000 --- a/assets/wall_anime2_4K.png +++ /dev/null diff --git a/assets/wall_anime2_8K.png b/assets/wall_anime2_8K.png Binary files differdeleted file mode 100644 index b8da18ef..00000000 --- a/assets/wall_anime2_8K.png +++ /dev/null diff --git a/assets/wall_anime_2K.png b/assets/wall_anime_2K.png Binary files differdeleted file mode 100644 index 202dc493..00000000 --- a/assets/wall_anime_2K.png +++ /dev/null diff --git a/assets/wall_anime_4K.png b/assets/wall_anime_4K.png Binary files differdeleted file mode 100644 index 687b79c3..00000000 --- a/assets/wall_anime_4K.png +++ /dev/null diff --git a/assets/wall_anime_8K.png b/assets/wall_anime_8K.png Binary files differdeleted file mode 100644 index 25c15cd7..00000000 --- a/assets/wall_anime_8K.png +++ /dev/null diff --git a/example/hyprland.conf b/example/hyprland.conf index 62b6e6e5..5d5441e9 100644 --- a/example/hyprland.conf +++ b/example/hyprland.conf @@ -112,7 +112,7 @@ gestures { misc { # See https://wiki.hyprland.org/Configuring/Variables/ for more - force_default_wallpaper = -1 # Set to 0 to disable the anime mascot wallpapers + force_default_wallpaper = -1 # Set to 0 or 1 to disable the anime mascot wallpapers } # Example per-device config diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 187d44b6..a3ac568e 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -99,7 +99,6 @@ void CConfigManager::setDefaultVars() { configValues["misc:disable_hyprland_logo"].intValue = 0; configValues["misc:disable_splash_rendering"].intValue = 0; - configValues["misc:force_hypr_chan"].intValue = 0; configValues["misc:force_default_wallpaper"].intValue = -1; configValues["misc:vfr"].intValue = 1; configValues["misc:vrr"].intValue = 0; diff --git a/src/config/defaultConfig.hpp b/src/config/defaultConfig.hpp index 1e149a7a..7bd43bfd 100644 --- a/src/config/defaultConfig.hpp +++ b/src/config/defaultConfig.hpp @@ -119,7 +119,7 @@ gestures { misc { # See https://wiki.hyprland.org/Configuring/Variables/ for more - force_default_wallpaper = -1 # Set to 0 to disable the anime mascot wallpapers + force_default_wallpaper = -1 # Set to 0 or 1 to disable the anime mascot wallpapers } # Example per-device config diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp index 27720982..b995f945 100644 --- a/src/render/OpenGL.cpp +++ b/src/render/OpenGL.cpp @@ -214,6 +214,9 @@ void CHyprOpenGLImpl::begin(CMonitor* pMonitor, CRegion* pDamage, CFramebuffer* m_RenderData.pCurrentMonData = &m_mMonitorRenderResources[pMonitor]; + if (!m_RenderData.pCurrentMonData->m_bShadersInitialized) + initShaders(); + // ensure a framebuffer for the monitor exists if (!m_mMonitorRenderResources.contains(pMonitor) || m_RenderData.pCurrentMonData->offloadFB.m_vSize != pMonitor->vecPixelSize) { m_RenderData.pCurrentMonData->stencilTex.allocate(); @@ -234,9 +237,6 @@ void CHyprOpenGLImpl::begin(CMonitor* pMonitor, CRegion* pDamage, CFramebuffer* if (m_RenderData.pCurrentMonData->monitorMirrorFB.isAllocated() && m_RenderData.pMonitor->mirrors.empty()) m_RenderData.pCurrentMonData->monitorMirrorFB.release(); - if (!m_RenderData.pCurrentMonData->m_bShadersInitialized) - initShaders(); - m_RenderData.damage.set(*pDamage); m_bFakeFrame = fb; @@ -744,7 +744,7 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, CBox* alpha = std::clamp(alpha, 0.f, 1.f); - if (m_RenderData.damage.empty()) + if (damage->empty()) return; CBox newBox = *pBox; @@ -1901,10 +1901,10 @@ void CHyprOpenGLImpl::renderMirrored() { renderTexture(PFB->m_cTex, &monbox, 1.f, 0, false, false); } -void CHyprOpenGLImpl::renderSplash(cairo_t* const CAIRO, cairo_surface_t* const CAIROSURFACE, double offsetY) { +void CHyprOpenGLImpl::renderSplash(cairo_t* const CAIRO, cairo_surface_t* const CAIROSURFACE, double offsetY, const Vector2D& size) { cairo_select_font_face(CAIRO, "Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); - const auto FONTSIZE = (int)(m_RenderData.pMonitor->vecPixelSize.y / 76); + const auto FONTSIZE = (int)(size.y / 76); cairo_set_font_size(CAIRO, FONTSIZE); cairo_set_source_rgba(CAIRO, 1.0, 1.0, 1.0, 0.32); @@ -1912,7 +1912,7 @@ void CHyprOpenGLImpl::renderSplash(cairo_t* const CAIRO, cairo_surface_t* const cairo_text_extents_t textExtents; cairo_text_extents(CAIRO, g_pCompositor->m_szCurrentSplash.c_str(), &textExtents); - cairo_move_to(CAIRO, (m_RenderData.pMonitor->vecPixelSize.x - textExtents.width) / 2.0, m_RenderData.pMonitor->vecPixelSize.y - textExtents.height + offsetY); + cairo_move_to(CAIRO, (size.x - textExtents.width) / 2.0, size.y - textExtents.height + offsetY); cairo_show_text(CAIRO, g_pCompositor->m_szCurrentSplash.c_str()); @@ -1924,109 +1924,123 @@ void CHyprOpenGLImpl::createBGTextureForMonitor(CMonitor* pMonitor) { static auto* const PRENDERTEX = &g_pConfigManager->getConfigValuePtr("misc:disable_hyprland_logo")->intValue; static auto* const PNOSPLASH = &g_pConfigManager->getConfigValuePtr("misc:disable_splash_rendering")->intValue; - static auto* const PFORCEHYPRCHAN = &g_pConfigManager->getConfigValuePtr("misc:force_hypr_chan")->intValue; static auto* const PFORCEWALLPAPER = &g_pConfigManager->getConfigValuePtr("misc:force_default_wallpaper")->intValue; const auto FORCEWALLPAPER = std::clamp(*PFORCEWALLPAPER, static_cast<int64_t>(-1L), static_cast<int64_t>(2L)); + static std::string texPath = ""; + if (*PRENDERTEX) return; // release the last tex if exists - const auto PTEX = &m_mMonitorBGTextures[pMonitor]; - PTEX->destroyTexture(); + const auto PFB = &m_mMonitorBGFBs[pMonitor]; + PFB->release(); - PTEX->allocate(); + PFB->alloc(pMonitor->vecPixelSize.x, pMonitor->vecPixelSize.y, pMonitor->drmFormat); Debug::log(LOG, "Allocated texture for BGTex"); // TODO: use relative paths to the installation // or configure the paths at build time - std::string texPath = "/usr/share/hyprland/wall_"; - std::string prefixes[] = {"", "anime_", "anime2_"}; - - // get the adequate tex - if (FORCEWALLPAPER == -1) { - std::random_device dev; - std::mt19937 engine(dev()); - std::uniform_int_distribution<> distribution(0, 2); - std::uniform_int_distribution<> distribution_anime(1, 2); - - if (PFORCEHYPRCHAN) - texPath += prefixes[distribution_anime(engine)]; - else - texPath += prefixes[distribution(engine)]; - } else - texPath += prefixes[FORCEWALLPAPER]; - - Vector2D textureSize; - if (pMonitor->vecTransformedSize.x > 3850) { - textureSize = Vector2D(7680, 4320); - texPath += "8K.png"; - } else if (pMonitor->vecTransformedSize.x > 1930) { - textureSize = Vector2D(3840, 2160); - texPath += "4K.png"; - } else { - textureSize = Vector2D(1920, 1080); - texPath += "2K.png"; - } + if (texPath.empty()) { + texPath = "/usr/share/hyprland/wall"; + + // get the adequate tex + if (FORCEWALLPAPER == -1) { + std::mt19937_64 engine(time(nullptr)); + std::uniform_int_distribution<> distribution(0, 2); + + texPath += std::to_string(distribution(engine)); + } else + texPath += std::to_string(std::clamp(*PFORCEWALLPAPER, (int64_t)0, (int64_t)2)); + + texPath += ".png"; - // check if wallpapers exist - if (!std::filesystem::exists(texPath)) { - // try local - texPath = texPath.substr(0, 5) + "local/" + texPath.substr(5); + // check if wallpapers exist + if (!std::filesystem::exists(texPath)) { + // try local + texPath = texPath.substr(0, 5) + "local/" + texPath.substr(5); - if (!std::filesystem::exists(texPath)) - return; // the texture will be empty, oh well. We'll clear with a solid color anyways. + if (!std::filesystem::exists(texPath)) + return; // the texture will be empty, oh well. We'll clear with a solid color anyways. + } } - PTEX->m_vSize = textureSize; + // create a new one with cairo + CTexture tex; + + const auto CAIROISURFACE = cairo_image_surface_create_from_png(texPath.c_str()); + const auto CAIROFORMAT = cairo_image_surface_get_format(CAIROISURFACE); + + tex.allocate(); + const Vector2D IMAGESIZE = {cairo_image_surface_get_width(CAIROISURFACE), cairo_image_surface_get_height(CAIROISURFACE)}; // calc the target box const double MONRATIO = m_RenderData.pMonitor->vecTransformedSize.x / m_RenderData.pMonitor->vecTransformedSize.y; - const double WPRATIO = 1.77; + const double WPRATIO = IMAGESIZE.x / IMAGESIZE.y; Vector2D origin; double scale; if (MONRATIO > WPRATIO) { - scale = m_RenderData.pMonitor->vecTransformedSize.x / PTEX->m_vSize.x; + scale = m_RenderData.pMonitor->vecTransformedSize.x / IMAGESIZE.x; - origin.y = (m_RenderData.pMonitor->vecTransformedSize.y - PTEX->m_vSize.y * scale) / 2.0; + origin.y = (m_RenderData.pMonitor->vecTransformedSize.y - IMAGESIZE.y * scale) / 2.0; } else { - scale = m_RenderData.pMonitor->vecTransformedSize.y / PTEX->m_vSize.y; + scale = m_RenderData.pMonitor->vecTransformedSize.y / IMAGESIZE.y; - origin.x = (m_RenderData.pMonitor->vecTransformedSize.x - PTEX->m_vSize.x * scale) / 2.0; + origin.x = (m_RenderData.pMonitor->vecTransformedSize.x - IMAGESIZE.x * scale) / 2.0; } - CBox box = {origin.x, origin.y, PTEX->m_vSize.x * scale, PTEX->m_vSize.y * scale}; + const Vector2D scaledSize = IMAGESIZE * scale; - m_mMonitorRenderResources[pMonitor].backgroundTexBox = box; + const auto CAIROSURFACE = cairo_image_surface_create(CAIROFORMAT, scaledSize.x, scaledSize.y); + const auto CAIRO = cairo_create(CAIROSURFACE); - // create a new one with cairo - const auto CAIROSURFACE = cairo_image_surface_create_from_png(texPath.c_str()); - const auto CAIRO = cairo_create(CAIROSURFACE); - - // scale it to fit the current monitor - cairo_scale(CAIRO, textureSize.x / pMonitor->vecTransformedSize.x, textureSize.y / pMonitor->vecTransformedSize.y); + cairo_set_antialias(CAIRO, CAIRO_ANTIALIAS_BEST); + cairo_scale(CAIRO, scale, scale); + cairo_rectangle(CAIRO, 0, 0, 100, 100); + cairo_set_source_surface(CAIRO, CAIROISURFACE, 0, 0); + cairo_paint(CAIRO); - // render splash on wallpaper if (!*PNOSPLASH) - renderSplash(CAIRO, CAIROSURFACE, origin.y * WPRATIO / MONRATIO); + renderSplash(CAIRO, CAIROSURFACE, origin.y * WPRATIO / MONRATIO * scale, IMAGESIZE); + + cairo_surface_flush(CAIROSURFACE); + + CBox box = {origin.x, origin.y, IMAGESIZE.x * scale, IMAGESIZE.y * scale}; + tex.m_vSize = IMAGESIZE * scale; // copy the data to an OpenGL texture we have - const auto DATA = cairo_image_surface_get_data(CAIROSURFACE); - glBindTexture(GL_TEXTURE_2D, PTEX->m_iTexID); + const GLint glIFormat = CAIROFORMAT == CAIRO_FORMAT_RGB96F ? GL_RGB32F : GL_RGBA; + const GLint glFormat = CAIROFORMAT == CAIRO_FORMAT_RGB96F ? GL_RGB : GL_RGBA; + const GLint glType = CAIROFORMAT == CAIRO_FORMAT_RGB96F ? GL_FLOAT : GL_UNSIGNED_BYTE; + + const auto DATA = cairo_image_surface_get_data(CAIROSURFACE); + glBindTexture(GL_TEXTURE_2D, tex.m_iTexID); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); #ifndef GLES2 - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_BLUE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED); + if (CAIROFORMAT != CAIRO_FORMAT_RGB96F) { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_BLUE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED); + } #endif - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, textureSize.x, textureSize.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, DATA); + glTexImage2D(GL_TEXTURE_2D, 0, glIFormat, tex.m_vSize.x, tex.m_vSize.y, 0, glFormat, glType, DATA); cairo_surface_destroy(CAIROSURFACE); + cairo_surface_destroy(CAIROISURFACE); cairo_destroy(CAIRO); + // render the texture to our fb + PFB->bind(); + CRegion fakeDamage{0, 0, INT16_MAX, INT16_MAX}; + renderTextureInternalWithDamage(tex, &box, 1.0, &fakeDamage); + + // bind back + if (m_RenderData.currentFB) + m_RenderData.currentFB->bind(); + Debug::log(LOG, "Background created for monitor {}", pMonitor->szName); } @@ -2035,15 +2049,19 @@ void CHyprOpenGLImpl::clearWithTex() { TRACY_GPU_ZONE("RenderClearWithTex"); - auto TEXIT = m_mMonitorBGTextures.find(m_RenderData.pMonitor); + auto TEXIT = m_mMonitorBGFBs.find(m_RenderData.pMonitor); - if (TEXIT == m_mMonitorBGTextures.end()) { + if (TEXIT == m_mMonitorBGFBs.end()) { createBGTextureForMonitor(m_RenderData.pMonitor); - TEXIT = m_mMonitorBGTextures.find(m_RenderData.pMonitor); + TEXIT = m_mMonitorBGFBs.find(m_RenderData.pMonitor); } - if (TEXIT != m_mMonitorBGTextures.end()) - renderTexture(TEXIT->second, &m_mMonitorRenderResources[m_RenderData.pMonitor].backgroundTexBox, 1); + if (TEXIT != m_mMonitorBGFBs.end()) { + CBox monbox = {0, 0, m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y}; + m_bEndFrame = true; + renderTexture(TEXIT->second.m_cTex, &monbox, 1); + m_bEndFrame = false; + } } void CHyprOpenGLImpl::destroyMonitorResources(CMonitor* pMonitor) { @@ -2061,10 +2079,10 @@ void CHyprOpenGLImpl::destroyMonitorResources(CMonitor* pMonitor) { g_pHyprOpenGL->m_mMonitorRenderResources.erase(RESIT); } - auto TEXIT = g_pHyprOpenGL->m_mMonitorBGTextures.find(pMonitor); - if (TEXIT != g_pHyprOpenGL->m_mMonitorBGTextures.end()) { - TEXIT->second.destroyTexture(); - g_pHyprOpenGL->m_mMonitorBGTextures.erase(TEXIT); + auto TEXIT = g_pHyprOpenGL->m_mMonitorBGFBs.find(pMonitor); + if (TEXIT != g_pHyprOpenGL->m_mMonitorBGFBs.end()) { + TEXIT->second.release(); + g_pHyprOpenGL->m_mMonitorBGFBs.erase(TEXIT); } Debug::log(LOG, "Monitor {} -> destroyed all render data", pMonitor->szName); diff --git a/src/render/OpenGL.hpp b/src/render/OpenGL.hpp index 9fd6d197..fc5eed41 100644 --- a/src/render/OpenGL.hpp +++ b/src/render/OpenGL.hpp @@ -71,8 +71,6 @@ struct SMonitorRenderData { bool blurFBDirty = true; bool blurFBShouldRender = false; - CBox backgroundTexBox; - // Shaders bool m_bShadersInitialized = false; CShader m_shQUAD; @@ -191,7 +189,7 @@ class CHyprOpenGLImpl { std::unordered_map<CWindow*, CFramebuffer> m_mWindowFramebuffers; std::unordered_map<SLayerSurface*, CFramebuffer> m_mLayerFramebuffers; std::unordered_map<CMonitor*, SMonitorRenderData> m_mMonitorRenderResources; - std::unordered_map<CMonitor*, CTexture> m_mMonitorBGTextures; + std::unordered_map<CMonitor*, CFramebuffer> m_mMonitorBGFBs; struct { PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC glEGLImageTargetRenderbufferStorageOES = nullptr; @@ -229,7 +227,7 @@ class CHyprOpenGLImpl { void renderTextureInternalWithDamage(const CTexture&, CBox* pBox, float a, CRegion* damage, int round = 0, bool discardOpaque = false, bool noAA = false, bool allowCustomUV = false, bool allowDim = false); void renderTexturePrimitive(const CTexture& tex, CBox* pBox); - void renderSplash(cairo_t* const, cairo_surface_t* const, double); + void renderSplash(cairo_t* const, cairo_surface_t* const, double offset, const Vector2D& size); void preBlurForCurrentMonitor(); |