diff options
| author | Vaxry <43317083+vaxerski@users.noreply.github.com> | 2023-01-20 19:44:30 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-01-20 19:44:30 +0100 |
| commit | 60b880d9312574c3115d973fd532f2e15d1eafff (patch) | |
| tree | b88cad7335c97c876f069f9d378589210332a95f /src/render/Renderer.cpp | |
| parent | cee7bc6e742aa02675701f772f5e7ebfb56f11ab (diff) | |
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>
Diffstat (limited to 'src/render/Renderer.cpp')
| -rw-r--r-- | src/render/Renderer.cpp | 85 |
1 files changed, 39 insertions, 46 deletions
diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index 43351eda..87896e64 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -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); + + // 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; - if (g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft == Vector2D(-1, -1)) - g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = Vector2D(0, 0); + 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; - 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))); + 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; |
