diff options
| author | vaxerski <43317083+vaxerski@users.noreply.github.com> | 2022-09-13 15:25:42 +0200 |
|---|---|---|
| committer | vaxerski <43317083+vaxerski@users.noreply.github.com> | 2022-09-13 15:25:42 +0200 |
| commit | e9f226797e43cedf17b094bc498272213ed53687 (patch) | |
| tree | 9a1a49cf308dac971a5bd73e4a00175930d323de /src/render | |
| parent | 7d4f0a319943f56b1a277ceae198fc3f77615afe (diff) | |
Added monitor mirroring
Diffstat (limited to 'src/render')
| -rw-r--r-- | src/render/OpenGL.cpp | 29 | ||||
| -rw-r--r-- | src/render/OpenGL.hpp | 9 | ||||
| -rw-r--r-- | src/render/Renderer.cpp | 24 | ||||
| -rw-r--r-- | src/render/Renderer.hpp | 1 |
4 files changed, 57 insertions, 6 deletions
diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp index 48581548..ea11bbb7 100644 --- a/src/render/OpenGL.cpp +++ b/src/render/OpenGL.cpp @@ -102,6 +102,7 @@ void CHyprOpenGLImpl::begin(CMonitor* pMonitor, pixman_region32_t* pDamage, bool m_RenderData.pCurrentMonData->primaryFB.alloc(pMonitor->vecPixelSize.x, pMonitor->vecPixelSize.y); m_RenderData.pCurrentMonData->mirrorFB.alloc(pMonitor->vecPixelSize.x, pMonitor->vecPixelSize.y); m_RenderData.pCurrentMonData->mirrorSwapFB.alloc(pMonitor->vecPixelSize.x, pMonitor->vecPixelSize.y); + m_RenderData.pCurrentMonData->monitorMirrorFB.alloc(pMonitor->vecPixelSize.x, pMonitor->vecPixelSize.y); createBGTextureForMonitor(pMonitor); } @@ -120,11 +121,14 @@ void CHyprOpenGLImpl::begin(CMonitor* pMonitor, pixman_region32_t* pDamage, bool void CHyprOpenGLImpl::end() { // end the render, copy the data to the WLR framebuffer if (!m_bFakeFrame) { + pixman_region32_copy(m_RenderData.pDamage, &m_rOriginalDamageRegion); + + if (!m_RenderData.pMonitor->mirrors.empty()) + g_pHyprOpenGL->saveBufferForMirror(); // save with original damage region + glBindFramebuffer(GL_FRAMEBUFFER, m_iWLROutputFb); wlr_box monbox = {0, 0, m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y}; - pixman_region32_copy(m_RenderData.pDamage, &m_rOriginalDamageRegion); - clear(CColor(11, 11, 11, 255)); m_bEndFrame = true; @@ -1088,6 +1092,27 @@ void CHyprOpenGLImpl::renderRoundedShadow(wlr_box* box, int round, int range, fl glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); } +void CHyprOpenGLImpl::saveBufferForMirror() { + m_RenderData.pCurrentMonData->monitorMirrorFB.bind(); + + wlr_box monbox = {0, 0, m_RenderData.pMonitor->vecPixelSize.x, m_RenderData.pMonitor->vecPixelSize.y}; + + renderTexture(m_RenderData.pCurrentMonData->primaryFB.m_cTex, &monbox, 255.f, 0, false, false); + + m_RenderData.pCurrentMonData->primaryFB.bind(); +} + +void CHyprOpenGLImpl::renderMirrored() { + wlr_box monbox = {0, 0, m_RenderData.pMonitor->vecPixelSize.x, m_RenderData.pMonitor->vecPixelSize.y}; + + const auto PFB = &m_mMonitorRenderResources[m_RenderData.pMonitor->pMirrorOf].monitorMirrorFB; + + if (PFB->m_cTex.m_iTexID <= 0) + return; + + renderTexture(PFB->m_cTex, &monbox, 255.f, 0, false, false); +} + void CHyprOpenGLImpl::renderSplash(cairo_t *const CAIRO, cairo_surface_t *const CAIROSURFACE) { cairo_select_font_face(CAIRO, "Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); diff --git a/src/render/OpenGL.hpp b/src/render/OpenGL.hpp index b81fd0f8..e3350c15 100644 --- a/src/render/OpenGL.hpp +++ b/src/render/OpenGL.hpp @@ -33,8 +33,10 @@ inline const float fanVertsFull[] = { struct SMonitorRenderData { CFramebuffer primaryFB; - CFramebuffer mirrorFB; - CFramebuffer mirrorSwapFB; + CFramebuffer mirrorFB; // these are used for some effects, + CFramebuffer mirrorSwapFB; // etc + + CFramebuffer monitorMirrorFB; // used for mirroring outputs CTexture stencilTex; @@ -102,6 +104,9 @@ public: void preWindowPass(); void preRender(CMonitor*); + void saveBufferForMirror(); + void renderMirrored(); + SCurrentRenderData m_RenderData; GLint m_iCurrentOutputFb = 0; diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index fc02af61..a1699f36 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -778,7 +778,7 @@ void CHyprRenderer::damageWindow(CWindow* pWindow) { } void CHyprRenderer::damageMonitor(CMonitor* pMonitor) { - if (g_pCompositor->m_bUnsafeState) + if (g_pCompositor->m_bUnsafeState || pMonitor->isMirror()) return; wlr_box damageBox = {0, 0, pMonitor->vecPixelSize.x, pMonitor->vecPixelSize.y}; @@ -795,6 +795,9 @@ void CHyprRenderer::damageBox(wlr_box* pBox) { return; for (auto& m : g_pCompositor->m_vMonitors) { + if (m->isMirror()) + continue; // don't damage mirrors traditionally + wlr_box damageBox = {pBox->x - m->vecPosition.x, pBox->y - m->vecPosition.y, pBox->width, pBox->height}; scaleBox(&damageBox, m->scale); m->addDamage(&damageBox); @@ -818,6 +821,19 @@ void CHyprRenderer::damageRegion(pixman_region32_t* rg) { } } +void CHyprRenderer::damageMirrorsWith(CMonitor* pMonitor, pixman_region32_t* pRegion) { + for (auto& mirror : pMonitor->mirrors) { + Vector2D scale = {mirror->vecSize.x / pMonitor->vecSize.x, mirror->vecSize.y / pMonitor->vecSize.y}; + + pixman_region32_t rg; + pixman_region32_init(&rg); + pixman_region32_copy(&rg, pRegion); + wlr_region_scale_xy(&rg, &rg, scale.x, scale.y); + pMonitor->addDamage(&rg); + pixman_region32_fini(&rg); + } +} + 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; @@ -1029,7 +1045,8 @@ bool CHyprRenderer::applyMonitorRule(CMonitor* pMonitor, SMonitorRule* pMonitorR pMonitor->vecPosition = finalPos; } - wlr_output_layout_add(g_pCompositor->m_sWLROutputLayout, pMonitor->output, (int)pMonitor->vecPosition.x, (int)pMonitor->vecPosition.y); + if (!pMonitor->isMirror()) + wlr_output_layout_add(g_pCompositor->m_sWLROutputLayout, pMonitor->output, (int)pMonitor->vecPosition.x, (int)pMonitor->vecPosition.y); wlr_output_enable(pMonitor->output, true); @@ -1042,6 +1059,9 @@ bool CHyprRenderer::applyMonitorRule(CMonitor* pMonitor, SMonitorRule* pMonitorR // frame skip pMonitor->framesToSkip = 1; + // reload to fix mirrors + g_pConfigManager->m_bWantsMonitorReload = true; + return true; } diff --git a/src/render/Renderer.hpp b/src/render/Renderer.hpp index 04b2bb45..067e618c 100644 --- a/src/render/Renderer.hpp +++ b/src/render/Renderer.hpp @@ -35,6 +35,7 @@ public: void damageBox(const int& x, const int& y, const int& w, const int& h); void damageRegion(pixman_region32_t*); void damageMonitor(CMonitor*); + void damageMirrorsWith(CMonitor*, pixman_region32_t*); bool applyMonitorRule(CMonitor*, SMonitorRule*, bool force = false); bool shouldRenderWindow(CWindow*, CMonitor*); bool shouldRenderWindow(CWindow*); |
