summaryrefslogtreecommitdiff
path: root/src/render
diff options
context:
space:
mode:
authorvaxerski <43317083+vaxerski@users.noreply.github.com>2022-09-13 15:25:42 +0200
committervaxerski <43317083+vaxerski@users.noreply.github.com>2022-09-13 15:25:42 +0200
commite9f226797e43cedf17b094bc498272213ed53687 (patch)
tree9a1a49cf308dac971a5bd73e4a00175930d323de /src/render
parent7d4f0a319943f56b1a277ceae198fc3f77615afe (diff)
Added monitor mirroring
Diffstat (limited to 'src/render')
-rw-r--r--src/render/OpenGL.cpp29
-rw-r--r--src/render/OpenGL.hpp9
-rw-r--r--src/render/Renderer.cpp24
-rw-r--r--src/render/Renderer.hpp1
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*);