mirror of
https://github.com/hyprwm/Hyprland
synced 2024-11-29 15:25:58 +01:00
Added basic monitor transforms, has bugs
blur doesnt work on transformed outputs full damage tracking issues
This commit is contained in:
parent
fdb3f610e5
commit
d0ff0c0990
7 changed files with 58 additions and 20 deletions
|
@ -186,10 +186,24 @@ void CConfigManager::handleMonitor(const std::string& command, const std::string
|
||||||
|
|
||||||
nextItem();
|
nextItem();
|
||||||
|
|
||||||
if (curitem == "disable" || curitem == "disabled" || curitem == "addreserved") {
|
if (curitem == "disable" || curitem == "disabled" || curitem == "addreserved" || curitem == "transform") {
|
||||||
if (curitem == "disable" || curitem == "disabled")
|
if (curitem == "disable" || curitem == "disabled")
|
||||||
newrule.disabled = true;
|
newrule.disabled = true;
|
||||||
else if (curitem == "addreserved") {
|
else if (curitem == "transform") {
|
||||||
|
nextItem();
|
||||||
|
|
||||||
|
wl_output_transform transform = (wl_output_transform)std::stoi(curitem);
|
||||||
|
|
||||||
|
// overwrite if exists
|
||||||
|
for (auto& r : m_dMonitorRules) {
|
||||||
|
if (r.name == newrule.name) {
|
||||||
|
r.transform = transform;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
} else if (curitem == "addreserved") {
|
||||||
nextItem();
|
nextItem();
|
||||||
|
|
||||||
int top = std::stoi(curitem);
|
int top = std::stoi(curitem);
|
||||||
|
|
|
@ -30,6 +30,7 @@ struct SMonitorRule {
|
||||||
float refreshRate = 60;
|
float refreshRate = 60;
|
||||||
int defaultWorkspaceID = -1;
|
int defaultWorkspaceID = -1;
|
||||||
bool disabled = false;
|
bool disabled = false;
|
||||||
|
wl_output_transform transform = WL_OUTPUT_TRANSFORM_NORMAL;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SMonitorAdditionalReservedArea {
|
struct SMonitorAdditionalReservedArea {
|
||||||
|
|
|
@ -191,7 +191,7 @@ void Events::listener_monitorFrame(void* owner, void* data) {
|
||||||
|
|
||||||
// if we have no tracking or full tracking, invalidate the entire monitor
|
// if we have no tracking or full tracking, invalidate the entire monitor
|
||||||
if (DTMODE == DAMAGE_TRACKING_NONE || DTMODE == DAMAGE_TRACKING_MONITOR) {
|
if (DTMODE == DAMAGE_TRACKING_NONE || DTMODE == DAMAGE_TRACKING_MONITOR) {
|
||||||
pixman_region32_union_rect(&damage, &damage, 0, 0, (int)PMONITOR->vecPixelSize.x, (int)PMONITOR->vecPixelSize.y);
|
pixman_region32_union_rect(&damage, &damage, 0, 0, (int)PMONITOR->vecTransformedSize.x, (int)PMONITOR->vecTransformedSize.y);
|
||||||
|
|
||||||
pixman_region32_copy(&g_pHyprOpenGL->m_rOriginalDamageRegion, &damage);
|
pixman_region32_copy(&g_pHyprOpenGL->m_rOriginalDamageRegion, &damage);
|
||||||
} else {
|
} else {
|
||||||
|
@ -246,10 +246,10 @@ void Events::listener_monitorFrame(void* owner, void* data) {
|
||||||
pixman_region32_init(&frameDamage);
|
pixman_region32_init(&frameDamage);
|
||||||
|
|
||||||
const auto TRANSFORM = wlr_output_transform_invert(PMONITOR->output->transform);
|
const auto TRANSFORM = wlr_output_transform_invert(PMONITOR->output->transform);
|
||||||
wlr_region_transform(&frameDamage, &PMONITOR->damage->current, TRANSFORM, (int)PMONITOR->vecPixelSize.x, (int)PMONITOR->vecPixelSize.y);
|
wlr_region_transform(&frameDamage, &PMONITOR->damage->current, TRANSFORM, (int)PMONITOR->vecTransformedSize.x, (int)PMONITOR->vecTransformedSize.y);
|
||||||
|
|
||||||
if (DTMODE == DAMAGE_TRACKING_NONE || DTMODE == DAMAGE_TRACKING_MONITOR)
|
if (DTMODE == DAMAGE_TRACKING_NONE || DTMODE == DAMAGE_TRACKING_MONITOR)
|
||||||
pixman_region32_union_rect(&frameDamage, &frameDamage, 0, 0, (int)PMONITOR->vecPixelSize.x, (int)PMONITOR->vecPixelSize.y);
|
pixman_region32_union_rect(&frameDamage, &frameDamage, 0, 0, (int)PMONITOR->vecTransformedSize.x, (int)PMONITOR->vecTransformedSize.y);
|
||||||
|
|
||||||
wlr_output_set_damage(PMONITOR->output, &frameDamage);
|
wlr_output_set_damage(PMONITOR->output, &frameDamage);
|
||||||
pixman_region32_fini(&frameDamage);
|
pixman_region32_fini(&frameDamage);
|
||||||
|
|
|
@ -7,9 +7,10 @@
|
||||||
#include <array>
|
#include <array>
|
||||||
|
|
||||||
struct SMonitor {
|
struct SMonitor {
|
||||||
Vector2D vecPosition = Vector2D(0,0);
|
Vector2D vecPosition = Vector2D(0,0);
|
||||||
Vector2D vecSize = Vector2D(0,0);
|
Vector2D vecSize = Vector2D(0,0);
|
||||||
Vector2D vecPixelSize = Vector2D(0,0);
|
Vector2D vecPixelSize = Vector2D(0,0);
|
||||||
|
Vector2D vecTransformedSize = Vector2D(0,0);
|
||||||
|
|
||||||
bool primary = false;
|
bool primary = false;
|
||||||
|
|
||||||
|
@ -27,6 +28,7 @@ struct SMonitor {
|
||||||
float refreshRate = 60;
|
float refreshRate = 60;
|
||||||
wlr_output_damage* damage = nullptr;
|
wlr_output_damage* damage = nullptr;
|
||||||
bool needsFrameSkip = false;
|
bool needsFrameSkip = false;
|
||||||
|
wl_output_transform transform = WL_OUTPUT_TRANSFORM_NORMAL;
|
||||||
|
|
||||||
// Double-linked list because we need to have constant mem addresses for signals
|
// Double-linked list because we need to have constant mem addresses for signals
|
||||||
// We have to store pointers and use raw new/delete because they might be moved between them
|
// We have to store pointers and use raw new/delete because they might be moved between them
|
||||||
|
|
|
@ -166,13 +166,17 @@ void CHyprOpenGLImpl::end() {
|
||||||
// end the render, copy the data to the WLR framebuffer
|
// end the render, copy the data to the WLR framebuffer
|
||||||
if (!m_bFakeFrame) {
|
if (!m_bFakeFrame) {
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, m_iWLROutputFb);
|
glBindFramebuffer(GL_FRAMEBUFFER, m_iWLROutputFb);
|
||||||
wlr_box monbox = {0, 0, m_RenderData.pMonitor->vecPixelSize.x, m_RenderData.pMonitor->vecPixelSize.y};
|
wlr_box monbox = {0, 0, m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y};
|
||||||
|
|
||||||
pixman_region32_copy(m_RenderData.pDamage, &m_rOriginalDamageRegion);
|
pixman_region32_copy(m_RenderData.pDamage, &m_rOriginalDamageRegion);
|
||||||
|
|
||||||
clear(CColor(11, 11, 11, 255));
|
clear(CColor(11, 11, 11, 255));
|
||||||
|
|
||||||
|
m_bEndFrame = true;
|
||||||
|
|
||||||
renderTexture(m_mMonitorRenderResources[m_RenderData.pMonitor].primaryFB.m_cTex, &monbox, 255.f, 0);
|
renderTexture(m_mMonitorRenderResources[m_RenderData.pMonitor].primaryFB.m_cTex, &monbox, 255.f, 0);
|
||||||
|
|
||||||
|
m_bEndFrame = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// reset our data
|
// reset our data
|
||||||
|
@ -205,7 +209,15 @@ void CHyprOpenGLImpl::scissor(const wlr_box* pBox) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
glScissor(pBox->x, pBox->y, pBox->width, pBox->height);
|
wlr_box newBox = *pBox;
|
||||||
|
|
||||||
|
int w, h;
|
||||||
|
wlr_output_transformed_resolution(m_RenderData.pMonitor->output, &w, &h);
|
||||||
|
|
||||||
|
const auto TR = wlr_output_transform_invert(m_RenderData.pMonitor->transform);
|
||||||
|
wlr_box_transform(&newBox, &newBox, TR, w, h);
|
||||||
|
|
||||||
|
glScissor(newBox.x, newBox.y, newBox.width, newBox.height);
|
||||||
glEnable(GL_SCISSOR_TEST);
|
glEnable(GL_SCISSOR_TEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,8 +229,9 @@ void CHyprOpenGLImpl::scissor(const pixman_box32* pBox) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
glScissor(pBox->x1, pBox->y1, pBox->x2 - pBox->x1, pBox->y2 - pBox->y1);
|
wlr_box newBox = {pBox->x1, pBox->y1, pBox->x2 - pBox->x1, pBox->y2 - pBox->y1};
|
||||||
glEnable(GL_SCISSOR_TEST);
|
|
||||||
|
scissor(&newBox);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHyprOpenGLImpl::scissor(const int x, const int y, const int w, const int h) {
|
void CHyprOpenGLImpl::scissor(const int x, const int y, const int w, const int h) {
|
||||||
|
@ -231,7 +244,7 @@ void CHyprOpenGLImpl::renderRect(wlr_box* box, const CColor& col, int round) {
|
||||||
RASSERT(m_RenderData.pMonitor, "Tried to render rect without begin()!");
|
RASSERT(m_RenderData.pMonitor, "Tried to render rect without begin()!");
|
||||||
|
|
||||||
float matrix[9];
|
float matrix[9];
|
||||||
wlr_matrix_project_box(matrix, box, WL_OUTPUT_TRANSFORM_NORMAL, 0, m_RenderData.pMonitor->output->transform_matrix); // TODO: write own, don't use WLR here
|
wlr_matrix_project_box(matrix, box, wlr_output_transform_invert(!m_bEndFrame ? WL_OUTPUT_TRANSFORM_NORMAL : m_RenderData.pMonitor->transform), 0, m_RenderData.pMonitor->output->transform_matrix); // TODO: write own, don't use WLR here
|
||||||
|
|
||||||
float glMatrix[9];
|
float glMatrix[9];
|
||||||
wlr_matrix_multiply(glMatrix, m_RenderData.projection, matrix);
|
wlr_matrix_multiply(glMatrix, m_RenderData.projection, matrix);
|
||||||
|
@ -296,7 +309,7 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, wlr_b
|
||||||
RASSERT((tex.m_iTexID > 0), "Attempted to draw NULL texture!");
|
RASSERT((tex.m_iTexID > 0), "Attempted to draw NULL texture!");
|
||||||
|
|
||||||
// get transform
|
// get transform
|
||||||
const auto TRANSFORM = wlr_output_transform_invert(WL_OUTPUT_TRANSFORM_NORMAL);
|
const auto TRANSFORM = wlr_output_transform_invert(!m_bEndFrame ? WL_OUTPUT_TRANSFORM_NORMAL : m_RenderData.pMonitor->transform);
|
||||||
float matrix[9];
|
float matrix[9];
|
||||||
wlr_matrix_project_box(matrix, pBox, TRANSFORM, 0, m_RenderData.pMonitor->output->transform_matrix);
|
wlr_matrix_project_box(matrix, pBox, TRANSFORM, 0, m_RenderData.pMonitor->output->transform_matrix);
|
||||||
|
|
||||||
|
@ -408,7 +421,7 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, wlr_box* p
|
||||||
glDisable(GL_STENCIL_TEST);
|
glDisable(GL_STENCIL_TEST);
|
||||||
|
|
||||||
// get transforms for the full monitor
|
// get transforms for the full monitor
|
||||||
const auto TRANSFORM = wlr_output_transform_invert(WL_OUTPUT_TRANSFORM_NORMAL);
|
const auto TRANSFORM = wlr_output_transform_invert(!m_bEndFrame ? WL_OUTPUT_TRANSFORM_NORMAL : m_RenderData.pMonitor->transform);
|
||||||
float matrix[9];
|
float matrix[9];
|
||||||
wlr_box MONITORBOX = {0, 0, m_RenderData.pMonitor->vecPixelSize.x, m_RenderData.pMonitor->vecPixelSize.y};
|
wlr_box MONITORBOX = {0, 0, m_RenderData.pMonitor->vecPixelSize.x, m_RenderData.pMonitor->vecPixelSize.y};
|
||||||
wlr_matrix_project_box(matrix, &MONITORBOX, TRANSFORM, 0, m_RenderData.pMonitor->output->transform_matrix);
|
wlr_matrix_project_box(matrix, &MONITORBOX, TRANSFORM, 0, m_RenderData.pMonitor->output->transform_matrix);
|
||||||
|
@ -817,10 +830,10 @@ void CHyprOpenGLImpl::createBGTextureForMonitor(SMonitor* pMonitor) {
|
||||||
// get the adequate tex
|
// get the adequate tex
|
||||||
std::string texPath = "/usr/share/hyprland/wall_";
|
std::string texPath = "/usr/share/hyprland/wall_";
|
||||||
Vector2D textureSize;
|
Vector2D textureSize;
|
||||||
if (pMonitor->vecSize.x > 7000) {
|
if (pMonitor->vecTransformedSize.x > 7000) {
|
||||||
textureSize = Vector2D(7680, 4320);
|
textureSize = Vector2D(7680, 4320);
|
||||||
texPath += "8K.png";
|
texPath += "8K.png";
|
||||||
} else if (pMonitor->vecSize.x > 3000) {
|
} else if (pMonitor->vecTransformedSize.x > 3000) {
|
||||||
textureSize = Vector2D(3840, 2160);
|
textureSize = Vector2D(3840, 2160);
|
||||||
texPath += "4K.png";
|
texPath += "4K.png";
|
||||||
} else {
|
} else {
|
||||||
|
@ -853,7 +866,7 @@ void CHyprOpenGLImpl::createBGTextureForMonitor(SMonitor* pMonitor) {
|
||||||
void CHyprOpenGLImpl::clearWithTex() {
|
void CHyprOpenGLImpl::clearWithTex() {
|
||||||
RASSERT(m_RenderData.pMonitor, "Tried to render BGtex without begin()!");
|
RASSERT(m_RenderData.pMonitor, "Tried to render BGtex without begin()!");
|
||||||
|
|
||||||
wlr_box box = {0, 0, m_RenderData.pMonitor->vecPixelSize.x, m_RenderData.pMonitor->vecPixelSize.y};
|
wlr_box box = {0, 0, m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y};
|
||||||
|
|
||||||
renderTexture(m_mMonitorBGTextures[m_RenderData.pMonitor], &box, 255, 0);
|
renderTexture(m_mMonitorBGTextures[m_RenderData.pMonitor], &box, 255, 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,6 +92,7 @@ private:
|
||||||
std::string m_szExtensions;
|
std::string m_szExtensions;
|
||||||
|
|
||||||
bool m_bFakeFrame = false;
|
bool m_bFakeFrame = false;
|
||||||
|
bool m_bEndFrame = false;
|
||||||
|
|
||||||
// Shaders
|
// Shaders
|
||||||
SQuad m_shQUAD;
|
SQuad m_shQUAD;
|
||||||
|
|
|
@ -552,7 +552,7 @@ void CHyprRenderer::applyMonitorRule(SMonitor* pMonitor, SMonitorRule* pMonitorR
|
||||||
Debug::log(LOG, "Applying monitor rule for %s", pMonitor->szName.c_str());
|
Debug::log(LOG, "Applying monitor rule for %s", pMonitor->szName.c_str());
|
||||||
|
|
||||||
// Check if the rule isn't already applied
|
// Check if the rule isn't already applied
|
||||||
if (!force && DELTALESSTHAN(pMonitor->vecPixelSize.x, pMonitorRule->resolution.x, 1) && DELTALESSTHAN(pMonitor->vecPixelSize.y, pMonitorRule->resolution.y, 1) && DELTALESSTHAN(pMonitor->refreshRate, pMonitorRule->refreshRate, 1) && pMonitor->scale == pMonitorRule->scale && DELTALESSTHAN(pMonitor->vecPosition.x, pMonitorRule->offset.x, 1) && DELTALESSTHAN(pMonitor->vecPosition.y, pMonitorRule->offset.y, 1)) {
|
if (!force && DELTALESSTHAN(pMonitor->vecPixelSize.x, pMonitorRule->resolution.x, 1) && DELTALESSTHAN(pMonitor->vecPixelSize.y, pMonitorRule->resolution.y, 1) && DELTALESSTHAN(pMonitor->refreshRate, pMonitorRule->refreshRate, 1) && pMonitor->scale == pMonitorRule->scale && DELTALESSTHAN(pMonitor->vecPosition.x, pMonitorRule->offset.x, 1) && DELTALESSTHAN(pMonitor->vecPosition.y, pMonitorRule->offset.y, 1) && pMonitor->transform == pMonitorRule->transform) {
|
||||||
Debug::log(LOG, "Not applying a new rule to %s because it's already applied!", pMonitor->szName.c_str());
|
Debug::log(LOG, "Not applying a new rule to %s because it's already applied!", pMonitor->szName.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -616,8 +616,10 @@ void CHyprRenderer::applyMonitorRule(SMonitor* pMonitor, SMonitorRule* pMonitorR
|
||||||
pMonitor->vecSize = pMonitorRule->resolution;
|
pMonitor->vecSize = pMonitorRule->resolution;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wlr_output_set_transform(pMonitor->output, pMonitorRule->transform);
|
||||||
|
pMonitor->transform = pMonitorRule->transform;
|
||||||
|
|
||||||
pMonitor->vecPixelSize = pMonitor->vecSize;
|
pMonitor->vecPixelSize = pMonitor->vecSize;
|
||||||
pMonitor->vecSize = (pMonitor->vecSize / pMonitor->scale).floor();
|
|
||||||
|
|
||||||
// update renderer
|
// update renderer
|
||||||
g_pHyprOpenGL->destroyMonitorResources(pMonitor);
|
g_pHyprOpenGL->destroyMonitorResources(pMonitor);
|
||||||
|
@ -627,6 +629,11 @@ void CHyprRenderer::applyMonitorRule(SMonitor* pMonitor, SMonitorRule* pMonitorR
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int x, y;
|
||||||
|
wlr_output_transformed_resolution(pMonitor->output, &x, &y);
|
||||||
|
pMonitor->vecSize = (Vector2D(x, y) / pMonitor->scale).floor();
|
||||||
|
pMonitor->vecTransformedSize = Vector2D(x,y);
|
||||||
|
|
||||||
wlr_output_layout_add(g_pCompositor->m_sWLROutputLayout, pMonitor->output, (int)pMonitorRule->offset.x, (int)pMonitorRule->offset.y);
|
wlr_output_layout_add(g_pCompositor->m_sWLROutputLayout, pMonitor->output, (int)pMonitorRule->offset.x, (int)pMonitorRule->offset.y);
|
||||||
|
|
||||||
//wlr_output_damage_add_whole(pMonitor->damage);
|
//wlr_output_damage_add_whole(pMonitor->damage);
|
||||||
|
|
Loading…
Reference in a new issue