mirror of
https://github.com/hyprwm/Hyprland.git
synced 2025-08-02 05:01:56 -07:00
wp-fractional-scaling-v1 impl (#1373)
* Initial fractional scaling impl * apply UV after geom calcs * fix scaling -> scale * meson: add fractional scale proto Co-authored-by: Mihai Fufezan <fufexan@protonmail.com>
This commit is contained in:
@@ -10,7 +10,7 @@ void renderSurface(struct wlr_surface* surface, int x, int y, void* data) {
|
||||
return;
|
||||
|
||||
double outputX = 0, outputY = 0;
|
||||
wlr_output_layout_output_coords(g_pCompositor->m_sWLROutputLayout, RDATA->output, &outputX, &outputY);
|
||||
wlr_output_layout_output_coords(g_pCompositor->m_sWLROutputLayout, RDATA->pMonitor->output, &outputX, &outputY);
|
||||
|
||||
wlr_box windowBox;
|
||||
if (RDATA->surface && surface == RDATA->surface)
|
||||
@@ -28,12 +28,12 @@ void renderSurface(struct wlr_surface* surface, int x, int y, void* data) {
|
||||
if (RDATA->pWindow)
|
||||
g_pHyprRenderer->calculateUVForWindowSurface(RDATA->pWindow, surface, RDATA->squishOversized);
|
||||
|
||||
scaleBox(&windowBox, RDATA->output->scale);
|
||||
scaleBox(&windowBox, RDATA->pMonitor->scale);
|
||||
|
||||
static auto* const PROUNDING = &g_pConfigManager->getConfigValuePtr("decoration:rounding")->intValue;
|
||||
|
||||
float rounding = RDATA->dontRound ? 0 : RDATA->rounding == -1 ? *PROUNDING : RDATA->rounding;
|
||||
rounding *= RDATA->output->scale;
|
||||
rounding *= RDATA->pMonitor->scale;
|
||||
|
||||
rounding -= 1; // to fix a border issue
|
||||
|
||||
@@ -52,7 +52,7 @@ void renderSurface(struct wlr_surface* surface, int x, int y, void* data) {
|
||||
|
||||
if (!g_pHyprRenderer->m_bBlockSurfaceFeedback) {
|
||||
wlr_surface_send_frame_done(surface, RDATA->when);
|
||||
wlr_presentation_surface_sampled_on_output(g_pCompositor->m_sWLRPresentation, surface, RDATA->output);
|
||||
wlr_presentation_surface_sampled_on_output(g_pCompositor->m_sWLRPresentation, surface, RDATA->pMonitor->output);
|
||||
}
|
||||
|
||||
// reset the UV, we might've set it above
|
||||
@@ -230,7 +230,7 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, CMonitor* pMonitor, timespec*
|
||||
static auto* const PNOFLOATINGBORDERS = &g_pConfigManager->getConfigValuePtr("general:no_border_on_floating")->intValue;
|
||||
static auto* const PDIMAROUND = &g_pConfigManager->getConfigValuePtr("decoration:dim_around")->floatValue;
|
||||
|
||||
SRenderData renderdata = {pMonitor->output, time, REALPOS.x, REALPOS.y};
|
||||
SRenderData renderdata = {pMonitor, time, REALPOS.x, REALPOS.y};
|
||||
if (ignorePosition) {
|
||||
renderdata.x = pMonitor->vecPosition.x;
|
||||
renderdata.y = pMonitor->vecPosition.y;
|
||||
@@ -352,7 +352,7 @@ void CHyprRenderer::renderLayer(SLayerSurface* pLayer, CMonitor* pMonitor, times
|
||||
return;
|
||||
}
|
||||
|
||||
SRenderData renderdata = {pMonitor->output, time, pLayer->geometry.x, pLayer->geometry.y};
|
||||
SRenderData renderdata = {pMonitor, time, pLayer->geometry.x, pLayer->geometry.y};
|
||||
renderdata.fadeAlpha = pLayer->alpha.fl();
|
||||
renderdata.blur = pLayer->forceBlur;
|
||||
renderdata.surface = pLayer->layerSurface->surface;
|
||||
@@ -368,7 +368,7 @@ void CHyprRenderer::renderLayer(SLayerSurface* pLayer, CMonitor* pMonitor, times
|
||||
}
|
||||
|
||||
void CHyprRenderer::renderIMEPopup(SIMEPopup* pPopup, CMonitor* pMonitor, timespec* time) {
|
||||
SRenderData renderdata = {pMonitor->output, time, pPopup->realX, pPopup->realY};
|
||||
SRenderData renderdata = {pMonitor, time, pPopup->realX, pPopup->realY};
|
||||
|
||||
renderdata.blur = false;
|
||||
renderdata.surface = pPopup->pSurface->surface;
|
||||
@@ -544,45 +544,23 @@ void CHyprRenderer::calculateUVForWindowSurface(CWindow* pWindow, wlr_surface* p
|
||||
Vector2D uvTL;
|
||||
Vector2D uvBR = Vector2D(1, 1);
|
||||
|
||||
wlr_box geom;
|
||||
wlr_xdg_surface_get_geometry(pWindow->m_uSurface.xdg, &geom);
|
||||
|
||||
const auto SUBSURFACE = g_pXWaylandManager->getWindowSurface(pWindow) != pSurface && main;
|
||||
|
||||
// wp_viewporter_v1 implementation
|
||||
if (pSurface->current.viewport.has_src) {
|
||||
// we stretch it to dest. if no dest, to 1,1
|
||||
wlr_fbox bufferSource;
|
||||
wlr_surface_get_buffer_source_box(pSurface, &bufferSource);
|
||||
|
||||
Vector2D surfaceSize = Vector2D(pSurface->buffer->texture->width, pSurface->buffer->texture->height);
|
||||
Vector2D bufferSize = Vector2D(pSurface->buffer->texture->width, pSurface->buffer->texture->height);
|
||||
|
||||
uvTL = Vector2D(bufferSource.x / surfaceSize.x, bufferSource.y / surfaceSize.y);
|
||||
uvBR = Vector2D((bufferSource.x + bufferSource.width) / surfaceSize.x, (bufferSource.y + bufferSource.height) / surfaceSize.y);
|
||||
// calculate UV for the basic src_box. Assume dest == size. TODO: don't.
|
||||
uvTL = Vector2D(bufferSource.x / bufferSize.x, bufferSource.y / bufferSize.y);
|
||||
uvBR = Vector2D((bufferSource.x + bufferSource.width) / bufferSize.x, (bufferSource.y + bufferSource.height) / bufferSize.y);
|
||||
|
||||
if (uvBR.x < 0.01f || uvBR.y < 0.01f) {
|
||||
uvTL = Vector2D();
|
||||
uvBR = Vector2D(1, 1);
|
||||
}
|
||||
|
||||
// TODO: (example: chromium) this still has a tiny "bump" at the end.
|
||||
if (main) {
|
||||
uvTL = uvTL +
|
||||
(Vector2D((double)geom.x / ((double)pWindow->m_uSurface.xdg->surface->current.width),
|
||||
(double)geom.y / ((double)pWindow->m_uSurface.xdg->surface->current.height)) *
|
||||
(((uvBR.x - uvTL.x) * surfaceSize.x) / surfaceSize.x));
|
||||
uvBR = uvBR *
|
||||
Vector2D((double)(geom.width + geom.x) / ((double)pWindow->m_uSurface.xdg->surface->current.width),
|
||||
(double)(geom.y + geom.height) / ((double)pWindow->m_uSurface.xdg->surface->current.height));
|
||||
}
|
||||
} else if (main) {
|
||||
// oversized windows' UV adjusting
|
||||
uvTL =
|
||||
Vector2D((double)geom.x / ((double)pWindow->m_uSurface.xdg->surface->current.width), (double)geom.y / ((double)pWindow->m_uSurface.xdg->surface->current.height));
|
||||
uvBR = Vector2D((double)(geom.width + geom.x) / ((double)pWindow->m_uSurface.xdg->surface->current.width),
|
||||
(double)(geom.y + geom.height) / ((double)pWindow->m_uSurface.xdg->surface->current.height));
|
||||
}
|
||||
|
||||
// set UV
|
||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = uvTL;
|
||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight = uvBR;
|
||||
|
||||
@@ -593,20 +571,35 @@ void CHyprRenderer::calculateUVForWindowSurface(CWindow* pWindow, wlr_surface* p
|
||||
}
|
||||
|
||||
if (!main)
|
||||
return; // ignore the rest
|
||||
return;
|
||||
|
||||
// then, if the surface is too big, modify the pos UV
|
||||
if ((geom.width > pWindow->m_vRealSize.vec().x + 1 || geom.height > pWindow->m_vRealSize.vec().y + 1) && !SUBSURFACE) {
|
||||
const auto OFF = Vector2D(pWindow->m_vRealSize.vec().x / (double)geom.width, pWindow->m_vRealSize.vec().y / (double)geom.height);
|
||||
wlr_box geom;
|
||||
wlr_xdg_surface_get_geometry(pWindow->m_uSurface.xdg, &geom);
|
||||
|
||||
if (g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft == Vector2D(-1, -1))
|
||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = Vector2D(0, 0);
|
||||
// ignore X and Y, adjust uv
|
||||
if (geom.x != 0 || geom.y != 0) {
|
||||
const auto XPERC = (double)geom.x / (double)pSurface->current.width;
|
||||
const auto YPERC = (double)geom.y / (double)pSurface->current.height;
|
||||
const auto WPERC = (double)(geom.x + geom.width) / (double)pSurface->current.width;
|
||||
const auto HPERC = (double)(geom.y + geom.height) / (double)pSurface->current.height;
|
||||
|
||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight =
|
||||
Vector2D(g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight.x *
|
||||
(pWindow->m_vRealSize.vec().x / ((double)geom.width / g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight.x)),
|
||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight.y *
|
||||
(pWindow->m_vRealSize.vec().y / ((double)geom.height / g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight.y)));
|
||||
const auto TOADDTL = Vector2D(XPERC * (uvBR.x - uvTL.x), YPERC * (uvBR.y - uvTL.y));
|
||||
uvBR = uvBR - Vector2D(1.0 - WPERC * (uvBR.x - uvTL.x), 1.0 - HPERC * (uvBR.y - uvTL.y));
|
||||
uvTL = uvTL + TOADDTL;
|
||||
|
||||
if (geom.width > pWindow->m_vRealSize.vec().x || geom.height > pWindow->m_vRealSize.vec().y) {
|
||||
uvBR.x = uvBR.x * (pWindow->m_vRealSize.vec().x / geom.width);
|
||||
uvBR.y = uvBR.y * (pWindow->m_vRealSize.vec().y / geom.height);
|
||||
}
|
||||
}
|
||||
|
||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = uvTL;
|
||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight = uvBR;
|
||||
|
||||
if (g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft == Vector2D() && g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight == Vector2D(1, 1)) {
|
||||
// No special UV mods needed
|
||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = Vector2D(-1, -1);
|
||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight = Vector2D(-1, -1);
|
||||
}
|
||||
} else {
|
||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = Vector2D(-1, -1);
|
||||
@@ -1119,7 +1112,7 @@ void CHyprRenderer::renderDragIcon(CMonitor* pMonitor, timespec* time) {
|
||||
if (!(g_pInputManager->m_sDrag.dragIcon && g_pInputManager->m_sDrag.iconMapped && g_pInputManager->m_sDrag.dragIcon->surface))
|
||||
return;
|
||||
|
||||
SRenderData renderdata = {pMonitor->output, time, g_pInputManager->m_sDrag.pos.x, g_pInputManager->m_sDrag.pos.y};
|
||||
SRenderData renderdata = {pMonitor, time, g_pInputManager->m_sDrag.pos.x, g_pInputManager->m_sDrag.pos.y};
|
||||
renderdata.surface = g_pInputManager->m_sDrag.dragIcon->surface;
|
||||
renderdata.w = g_pInputManager->m_sDrag.dragIcon->surface->current.width;
|
||||
renderdata.h = g_pInputManager->m_sDrag.dragIcon->surface->current.height;
|
||||
|
Reference in New Issue
Block a user