mirror of
https://github.com/hyprwm/Hyprland.git
synced 2025-08-08 08:01:57 -07:00
protocols: add hyprland_surface_v1.set_visible_region implementation (#9120)
This commit is contained in:
@@ -7,6 +7,8 @@
|
||||
#include "../../managers/input/InputManager.hpp"
|
||||
#include "../Renderer.hpp"
|
||||
|
||||
#include <hyprutils/math/Box.hpp>
|
||||
#include <hyprutils/math/Vector2D.hpp>
|
||||
#include <hyprutils/utils/ScopeGuard.hpp>
|
||||
using namespace Hyprutils::Utils;
|
||||
|
||||
@@ -28,6 +30,7 @@ void CSurfacePassElement::draw(const CRegion& damage) {
|
||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight = Vector2D(-1, -1);
|
||||
g_pHyprOpenGL->m_RenderData.useNearestNeighbor = false;
|
||||
g_pHyprOpenGL->m_RenderData.clipBox = {};
|
||||
g_pHyprOpenGL->m_RenderData.clipRegion = {};
|
||||
g_pHyprOpenGL->m_RenderData.discardMode = 0;
|
||||
g_pHyprOpenGL->m_RenderData.discardOpacity = 0;
|
||||
g_pHyprOpenGL->m_RenderData.useNearestNeighbor = false;
|
||||
@@ -84,6 +87,11 @@ void CSurfacePassElement::draw(const CRegion& damage) {
|
||||
Debug::log(TRACE, "FIXME: rendering surface with color management enabled, should apply necessary transformations");
|
||||
g_pHyprRenderer->calculateUVForSurface(data.pWindow, data.surface, data.pMonitor->self.lock(), data.mainSurface, windowBox.size(), PROJSIZEUNSCALED, MISALIGNEDFSV1);
|
||||
|
||||
auto cancelRender = false;
|
||||
g_pHyprOpenGL->m_RenderData.clipRegion = visibleRegion(cancelRender);
|
||||
if (cancelRender)
|
||||
return;
|
||||
|
||||
// check for fractional scale surfaces misaligning the buffer size
|
||||
// in those cases it's better to just force nearest neighbor
|
||||
// as long as the window is not animated. During those it'd look weird.
|
||||
@@ -229,6 +237,48 @@ CRegion CSurfacePassElement::opaqueRegion() {
|
||||
return data.texture && data.texture->m_bOpaque ? boundingBox()->expand(-data.rounding) : CRegion{};
|
||||
}
|
||||
|
||||
CRegion CSurfacePassElement::visibleRegion(bool& cancel) {
|
||||
auto PSURFACE = CWLSurface::fromResource(data.surface);
|
||||
if (!PSURFACE)
|
||||
return {};
|
||||
|
||||
const auto& bufferSize = data.surface->current.bufferSize;
|
||||
|
||||
auto visibleRegion = PSURFACE->m_visibleRegion.copy();
|
||||
if (visibleRegion.empty())
|
||||
return {};
|
||||
|
||||
visibleRegion.intersect(CBox(Vector2D(), bufferSize));
|
||||
|
||||
if (visibleRegion.empty()) {
|
||||
cancel = true;
|
||||
return visibleRegion;
|
||||
}
|
||||
|
||||
// deal with any rounding errors that might come from scaling
|
||||
visibleRegion.expand(1);
|
||||
|
||||
auto uvTL = g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft;
|
||||
auto uvBR = g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight;
|
||||
|
||||
if (uvTL == Vector2D(-1, -1))
|
||||
uvTL = Vector2D(0, 0);
|
||||
|
||||
if (uvBR == Vector2D(-1, -1))
|
||||
uvBR = Vector2D(1, 1);
|
||||
|
||||
visibleRegion.translate(-uvTL * bufferSize);
|
||||
|
||||
auto texBox = getTexBox();
|
||||
texBox.scale(data.pMonitor->scale);
|
||||
texBox.round();
|
||||
|
||||
visibleRegion.scale((Vector2D(1, 1) / (uvBR - uvTL)) * (texBox.size() / bufferSize));
|
||||
visibleRegion.translate((data.pos + data.localPos) * data.pMonitor->scale - data.pMonitor->vecPosition);
|
||||
|
||||
return visibleRegion;
|
||||
}
|
||||
|
||||
void CSurfacePassElement::discard() {
|
||||
if (!g_pHyprRenderer->m_bBlockSurfaceFeedback) {
|
||||
Debug::log(TRACE, "discard for invisible surface");
|
||||
|
Reference in New Issue
Block a user