summaryrefslogtreecommitdiff
path: root/src/render/Renderer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/render/Renderer.cpp')
-rw-r--r--src/render/Renderer.cpp126
1 files changed, 74 insertions, 52 deletions
diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp
index eacd8730..c960b89b 100644
--- a/src/render/Renderer.cpp
+++ b/src/render/Renderer.cpp
@@ -17,17 +17,15 @@ void renderSurface(struct wlr_surface* surface, int x, int y, void* data) {
else // here we clamp to 2, these might be some tiny specks
windowBox = {(int)outputX + RDATA->x + x, (int)outputY + RDATA->y + y, std::clamp(surface->current.width, 2, 1337420), std::clamp(surface->current.height, 2, 1337420)};
- // squish all oversized but dont in some cases, jesus christ this is a mess
- // TODO: this shouldn't be done this way. Custom UV here as well.
- // this is fucking horrible
- // Issue: will cause oversized apps with reserved area to overflow from the window box. (see chromium on ozone wayland)
- const auto PRESQUISHSIZE = Vector2D(windowBox.width, windowBox.height);
if (RDATA->squishOversized) {
if (x + windowBox.width > RDATA->w)
windowBox.width = RDATA->w - x;
if (y + windowBox.height > RDATA->h)
windowBox.height = RDATA->h - y;
}
+
+ if (RDATA->pWindow)
+ g_pHyprRenderer->calculateUVForWindowSurface(RDATA->pWindow, surface, RDATA->squishOversized);
scaleBox(&windowBox, RDATA->output->scale);
@@ -49,21 +47,7 @@ void renderSurface(struct wlr_surface* surface, int x, int y, void* data) {
}
}
else {
- if (RDATA->surface && wlr_surface_is_xdg_surface(RDATA->surface)) {
- wlr_box geo;
- wlr_xdg_surface_get_geometry(wlr_xdg_surface_from_wlr_surface(RDATA->surface), &geo);
-
- // TODO: continuation of the above madness.
- if (geo.x != 0 || geo.y != 0) {
- windowBox.width = PRESQUISHSIZE.x;
- windowBox.height = PRESQUISHSIZE.y;
- }
-
- windowBox.x -= geo.x;
- windowBox.y -= geo.y;
- }
-
- g_pHyprOpenGL->renderTexture(TEXTURE, &windowBox, RDATA->fadeAlpha * RDATA->alpha, rounding, false);
+ g_pHyprOpenGL->renderTexture(TEXTURE, &windowBox, RDATA->fadeAlpha * RDATA->alpha, rounding, true);
}
wlr_surface_send_frame_done(surface, RDATA->when);
@@ -213,6 +197,7 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, CMonitor* pMonitor, timespec*
renderdata.decorate = decorate && !pWindow->m_bX11DoesntWantBorders && (pWindow->m_bIsFloating ? *PNOFLOATINGBORDERS == 0 : true) && (!pWindow->m_bIsFullscreen || PWORKSPACE->m_efFullscreenMode != FULLSCREEN_FULL);
renderdata.rounding = pWindow->m_sAdditionalConfigData.rounding;
renderdata.blur = true; // if it shouldn't, it will be ignored later
+ renderdata.pWindow = pWindow;
// apply window special data
if (pWindow->m_sSpecialRenderData.alphaInactive == -1)
@@ -232,38 +217,6 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, CMonitor* pMonitor, timespec*
if (!pWindow->m_bIsFullscreen || PWORKSPACE->m_efFullscreenMode != FULLSCREEN_FULL) for (auto& wd : pWindow->m_dWindowDecorations)
wd->draw(pMonitor, renderdata.alpha * renderdata.fadeAlpha / 255.f);
- if (!pWindow->m_bIsX11) {
- wlr_box geom;
- wlr_xdg_surface_get_geometry(pWindow->m_uSurface.xdg, &geom);
-
- // first, check for poorly sized windows.
-
- g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = Vector2D((double)geom.x / (double)pWindow->m_uSurface.xdg->surface->current.width, (double)geom.y / (double)pWindow->m_uSurface.xdg->surface->current.height);
- g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight = 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);
-
- 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);
- }
-
- // then, if the surface is too big, modify the pos UV
- if (geom.width > renderdata.w + 1 || geom.height > renderdata.h + 1) {
- const auto OFF = Vector2D(renderdata.w / (double)geom.width, renderdata.h / (double)geom.height);
-
- if (g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft == Vector2D(-1, -1))
- g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = Vector2D(0, 0);
-
- g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight = Vector2D(
- g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight.x * ((double)renderdata.w / ((double)geom.width / g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight.x)),
- g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight.y * ((double)renderdata.h / ((double)geom.height / g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight.y))
- );
- }
- } else {
- g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = Vector2D(-1, -1);
- g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight = Vector2D(-1, -1);
- }
-
wlr_surface_for_each_surface(g_pXWaylandManager->getWindowSurface(pWindow), renderSurface, &renderdata);
if (renderdata.decorate && pWindow->m_sSpecialRenderData.border) {
@@ -288,6 +241,12 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, CMonitor* pMonitor, timespec*
if (mode == RENDER_PASS_ALL || mode == RENDER_PASS_POPUP) {
if (!pWindow->m_bIsX11) {
+ wlr_box geom;
+ wlr_xdg_surface_get_geometry(pWindow->m_uSurface.xdg, &geom);
+
+ renderdata.x -= geom.x;
+ renderdata.y -= geom.y;
+
renderdata.dontRound = true; // don't round popups
renderdata.pMonitor = pMonitor;
renderdata.squishOversized = false; // don't squish popups
@@ -295,6 +254,10 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, CMonitor* pMonitor, timespec*
}
}
+ // reset uv
+ g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = Vector2D(-1, -1);
+ g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight = Vector2D(-1, -1);
+
g_pHyprOpenGL->m_pCurrentWindow = nullptr;
}
@@ -442,6 +405,65 @@ void CHyprRenderer::renderAllClientsForMonitor(const int& ID, timespec* time) {
renderDragIcon(PMONITOR, time);
}
+void CHyprRenderer::calculateUVForWindowSurface(CWindow* pWindow, wlr_surface* pSurface, bool main) {
+ if (!pWindow->m_bIsX11) {
+ Vector2D uvTL;
+ Vector2D uvBR = Vector2D(1, 1);
+
+ wlr_box geom;
+ wlr_xdg_surface_get_geometry(pWindow->m_uSurface.xdg, &geom);
+
+ // wp_viewporter_v1 implementation
+ if (pSurface->current.viewport.has_src) {
+ wlr_fbox bufferSource;
+ wlr_surface_get_buffer_source_box(pSurface, &bufferSource);
+
+ Vector2D surfaceSize = 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);
+
+ // TODO: (example: chromium) this still has a tiny "bump" at the end.
+ if (main) {
+ uvTL = uvTL + (Vector2D((double)geom.x / ((double)pSurface->current.width), (double)geom.y / ((double)pSurface->current.height)) * (((uvBR.x - uvTL.x) * surfaceSize.x) / surfaceSize.x));
+ uvBR = uvBR * Vector2D((double)(geom.width + geom.x) / ((double)pSurface->current.width), (double)(geom.y + geom.height) / ((double)pSurface->current.height));
+ }
+ } else if (main) {
+ // oversized windows' UV adjusting
+ uvTL = Vector2D((double)geom.x / ((double)pSurface->current.width), (double)geom.y / ((double)pSurface->current.height));
+ uvBR = Vector2D((double)(geom.width + geom.x) / ((double)pSurface->current.width), (double)(geom.y + geom.height) / ((double)pSurface->current.height));
+ }
+
+ // set UV
+ 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);
+ }
+
+ if (!main)
+ return; // ignore the rest
+
+ // 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) {
+ const auto OFF = Vector2D(pWindow->m_vRealSize.vec().x / (double)geom.width, pWindow->m_vRealSize.vec().y / (double)geom.height);
+
+ if (g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft == Vector2D(-1, -1))
+ g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = Vector2D(0, 0);
+
+ g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight = Vector2D(
+ g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight.x * ((double)pWindow->m_vRealSize.vec().x / ((double)geom.width / g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight.x)),
+ g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight.y * ((double)pWindow->m_vRealSize.vec().y / ((double)geom.height / g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight.y)));
+ }
+ } else {
+ g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = Vector2D(-1, -1);
+ g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight = Vector2D(-1, -1);
+ }
+}
+
void CHyprRenderer::outputMgrApplyTest(wlr_output_configuration_v1* config, bool test) {
wlr_output_configuration_head_v1* head;
bool noError = true;