mirror of
https://github.com/hyprwm/Hyprland.git
synced 2025-08-18 05:23:47 -07:00
opengl: improve render fn arg clarity (#11286)
This commit is contained in:
@@ -579,7 +579,7 @@ SP<Aquamarine::IBuffer> CPointerManager::renderHWCursorBuffer(SP<CPointerManager
|
||||
Debug::log(TRACE, "[pointer] monitor: {}, size: {}, hw buf: {}, scale: {:.2f}, monscale: {:.2f}, xbox: {}", state->monitor->m_name, m_currentCursorImage.size, cursorSize,
|
||||
m_currentCursorImage.scale, state->monitor->m_scale, xbox.size());
|
||||
|
||||
g_pHyprOpenGL->renderTexture(texture, xbox, 1.F);
|
||||
g_pHyprOpenGL->renderTexture(texture, xbox, {});
|
||||
|
||||
g_pHyprOpenGL->end();
|
||||
g_pHyprOpenGL->m_renderData.pMonitor.reset();
|
||||
|
@@ -200,7 +200,7 @@ void CScreencopyFrame::renderMon() {
|
||||
.transform(wlTransformToHyprutils(invertTransform(m_monitor->m_transform)), m_monitor->m_pixelSize.x, m_monitor->m_pixelSize.y);
|
||||
g_pHyprOpenGL->pushMonitorTransformEnabled(true);
|
||||
g_pHyprOpenGL->setRenderModifEnabled(false);
|
||||
g_pHyprOpenGL->renderTexture(TEXTURE, monbox, 1);
|
||||
g_pHyprOpenGL->renderTexture(TEXTURE, monbox, {});
|
||||
g_pHyprOpenGL->setRenderModifEnabled(true);
|
||||
g_pHyprOpenGL->popMonitorTransformEnabled();
|
||||
|
||||
@@ -229,7 +229,7 @@ void CScreencopyFrame::renderMon() {
|
||||
const auto rounding = dontRound ? 0 : w->rounding() * m_monitor->m_scale;
|
||||
const auto roundingPower = dontRound ? 2.0f : w->roundingPower();
|
||||
|
||||
g_pHyprOpenGL->renderRect(noScreenShareBox, Colors::BLACK, rounding, roundingPower);
|
||||
g_pHyprOpenGL->renderRect(noScreenShareBox, Colors::BLACK, {.round = rounding, .roundingPower = roundingPower});
|
||||
|
||||
if (w->m_isX11 || !w->m_popupHead)
|
||||
continue;
|
||||
@@ -249,7 +249,7 @@ void CScreencopyFrame::renderMon() {
|
||||
const auto surfBox = CBox{popupBaseOffset + popRel + localOff, size}.translate(-m_monitor->m_position).scale(m_monitor->m_scale).translate(-m_box.pos());
|
||||
|
||||
if LIKELY (surfBox.w > 0 && surfBox.h > 0)
|
||||
g_pHyprOpenGL->renderRect(surfBox, Colors::BLACK);
|
||||
g_pHyprOpenGL->renderRect(surfBox, Colors::BLACK, {});
|
||||
},
|
||||
nullptr);
|
||||
},
|
||||
@@ -292,7 +292,7 @@ void CScreencopyFrame::copyDmabuf(std::function<void(bool)> callback) {
|
||||
if (PERM == PERMISSION_RULE_ALLOW_MODE_ALLOW) {
|
||||
if (m_tempFb.isAllocated()) {
|
||||
CBox texbox = {{}, m_box.size()};
|
||||
g_pHyprOpenGL->renderTexture(m_tempFb.getTexture(), texbox, 1);
|
||||
g_pHyprOpenGL->renderTexture(m_tempFb.getTexture(), texbox, {});
|
||||
m_tempFb.release();
|
||||
} else
|
||||
renderMon();
|
||||
@@ -301,7 +301,7 @@ void CScreencopyFrame::copyDmabuf(std::function<void(bool)> callback) {
|
||||
else {
|
||||
g_pHyprOpenGL->clear(Colors::BLACK);
|
||||
CBox texbox = CBox{m_monitor->m_transformedSize / 2.F, g_pHyprOpenGL->m_screencopyDeniedTexture->m_size}.translate(-g_pHyprOpenGL->m_screencopyDeniedTexture->m_size / 2.F);
|
||||
g_pHyprOpenGL->renderTexture(g_pHyprOpenGL->m_screencopyDeniedTexture, texbox, 1);
|
||||
g_pHyprOpenGL->renderTexture(g_pHyprOpenGL->m_screencopyDeniedTexture, texbox, {});
|
||||
}
|
||||
|
||||
g_pHyprOpenGL->m_renderData.blockScreenShader = true;
|
||||
@@ -333,7 +333,7 @@ bool CScreencopyFrame::copyShm() {
|
||||
if (PERM == PERMISSION_RULE_ALLOW_MODE_ALLOW) {
|
||||
if (m_tempFb.isAllocated()) {
|
||||
CBox texbox = {{}, m_box.size()};
|
||||
g_pHyprOpenGL->renderTexture(m_tempFb.getTexture(), texbox, 1);
|
||||
g_pHyprOpenGL->renderTexture(m_tempFb.getTexture(), texbox, {});
|
||||
m_tempFb.release();
|
||||
} else
|
||||
renderMon();
|
||||
@@ -342,7 +342,7 @@ bool CScreencopyFrame::copyShm() {
|
||||
else {
|
||||
g_pHyprOpenGL->clear(Colors::BLACK);
|
||||
CBox texbox = CBox{m_monitor->m_transformedSize / 2.F, g_pHyprOpenGL->m_screencopyDeniedTexture->m_size}.translate(-g_pHyprOpenGL->m_screencopyDeniedTexture->m_size / 2.F);
|
||||
g_pHyprOpenGL->renderTexture(g_pHyprOpenGL->m_screencopyDeniedTexture, texbox, 1);
|
||||
g_pHyprOpenGL->renderTexture(g_pHyprOpenGL->m_screencopyDeniedTexture, texbox, {});
|
||||
}
|
||||
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, fb.getFBID());
|
||||
|
@@ -266,7 +266,7 @@ bool CToplevelExportFrame::copyShm(const Time::steady_tp& now) {
|
||||
g_pPointerManager->renderSoftwareCursorsFor(PMONITOR->m_self.lock(), now, fakeDamage, g_pInputManager->getMouseCoordsInternal() - m_window->m_realPosition->value());
|
||||
} else if (PERM == PERMISSION_RULE_ALLOW_MODE_DENY) {
|
||||
CBox texbox = CBox{PMONITOR->m_transformedSize / 2.F, g_pHyprOpenGL->m_screencopyDeniedTexture->m_size}.translate(-g_pHyprOpenGL->m_screencopyDeniedTexture->m_size / 2.F);
|
||||
g_pHyprOpenGL->renderTexture(g_pHyprOpenGL->m_screencopyDeniedTexture, texbox, 1);
|
||||
g_pHyprOpenGL->renderTexture(g_pHyprOpenGL->m_screencopyDeniedTexture, texbox, {});
|
||||
}
|
||||
|
||||
const auto PFORMAT = NFormatUtils::getPixelFormatFromDRM(shm.format);
|
||||
@@ -349,7 +349,7 @@ bool CToplevelExportFrame::copyDmabuf(const Time::steady_tp& now) {
|
||||
g_pPointerManager->renderSoftwareCursorsFor(PMONITOR->m_self.lock(), now, fakeDamage, g_pInputManager->getMouseCoordsInternal() - m_window->m_realPosition->value());
|
||||
} else if (PERM == PERMISSION_RULE_ALLOW_MODE_DENY) {
|
||||
CBox texbox = CBox{PMONITOR->m_transformedSize / 2.F, g_pHyprOpenGL->m_screencopyDeniedTexture->m_size}.translate(-g_pHyprOpenGL->m_screencopyDeniedTexture->m_size / 2.F);
|
||||
g_pHyprOpenGL->renderTexture(g_pHyprOpenGL->m_screencopyDeniedTexture, texbox, 1);
|
||||
g_pHyprOpenGL->renderTexture(g_pHyprOpenGL->m_screencopyDeniedTexture, texbox, {});
|
||||
}
|
||||
|
||||
g_pHyprOpenGL->m_renderData.blockScreenShader = true;
|
||||
|
@@ -814,10 +814,8 @@ void CHyprOpenGLImpl::end() {
|
||||
|
||||
monbox.translate(-ZOOMCENTER).scale(m_renderData.mouseZoomFactor).translate(*PZOOMRIGID ? m_renderData.pMonitor->m_transformedSize / 2.0 : ZOOMCENTER);
|
||||
|
||||
if (monbox.x > 0)
|
||||
monbox.x = 0;
|
||||
if (monbox.y > 0)
|
||||
monbox.y = 0;
|
||||
monbox.x = std::min(monbox.x, 0.0);
|
||||
monbox.y = std::min(monbox.y, 0.0);
|
||||
if (monbox.x + monbox.width < m_renderData.pMonitor->m_transformedSize.x)
|
||||
monbox.x = m_renderData.pMonitor->m_transformedSize.x - monbox.width;
|
||||
if (monbox.y + monbox.height < m_renderData.pMonitor->m_transformedSize.y)
|
||||
@@ -839,7 +837,7 @@ void CHyprOpenGLImpl::end() {
|
||||
if (m_finalScreenShader.program < 1 && !g_pHyprRenderer->m_crashingInProgress)
|
||||
renderTexturePrimitive(m_renderData.pCurrentMonData->offloadFB.getTexture(), monbox);
|
||||
else
|
||||
renderTexture(m_renderData.pCurrentMonData->offloadFB.getTexture(), monbox, 1.f);
|
||||
renderTexture(m_renderData.pCurrentMonData->offloadFB.getTexture(), monbox, {});
|
||||
|
||||
blend(true);
|
||||
|
||||
@@ -1338,19 +1336,24 @@ void CHyprOpenGLImpl::scissor(const int x, const int y, const int w, const int h
|
||||
scissor(box, transform);
|
||||
}
|
||||
|
||||
void CHyprOpenGLImpl::renderRect(const CBox& box, const CHyprColor& col, int round, float roundingPower) {
|
||||
if (!m_renderData.damage.empty())
|
||||
renderRectWithDamage(box, col, m_renderData.damage, round, roundingPower);
|
||||
void CHyprOpenGLImpl::renderRect(const CBox& box, const CHyprColor& col, SRectRenderData data) {
|
||||
if (!data.damage)
|
||||
data.damage = &m_renderData.damage;
|
||||
|
||||
if (data.blur)
|
||||
renderRectWithBlurInternal(box, col, data);
|
||||
else
|
||||
renderRectWithDamageInternal(box, col, data);
|
||||
}
|
||||
|
||||
void CHyprOpenGLImpl::renderRectWithBlur(const CBox& box, const CHyprColor& col, int round, float roundingPower, float blurA, bool xray) {
|
||||
if (m_renderData.damage.empty())
|
||||
void CHyprOpenGLImpl::renderRectWithBlurInternal(const CBox& box, const CHyprColor& col, const SRectRenderData& data) {
|
||||
if (data.damage->empty())
|
||||
return;
|
||||
|
||||
CRegion damage{m_renderData.damage};
|
||||
damage.intersect(box);
|
||||
|
||||
CFramebuffer* POUTFB = xray ? &m_renderData.pCurrentMonData->blurFB : blurMainFramebufferWithDamage(blurA, &damage);
|
||||
CFramebuffer* POUTFB = data.xray ? &m_renderData.pCurrentMonData->blurFB : blurMainFramebufferWithDamage(data.blurA, &damage);
|
||||
|
||||
m_renderData.currentFB->bind();
|
||||
|
||||
@@ -1365,7 +1368,7 @@ void CHyprOpenGLImpl::renderRectWithBlur(const CBox& box, const CHyprColor& col,
|
||||
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
|
||||
|
||||
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
|
||||
renderRect(box, CHyprColor(0, 0, 0, 0), round, roundingPower);
|
||||
renderRect(box, CHyprColor(0, 0, 0, 0), SRectRenderData{.round = data.round, .roundingPower = data.roundingPower});
|
||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
|
||||
glStencilFunc(GL_EQUAL, 1, 0xFF);
|
||||
@@ -1376,7 +1379,8 @@ void CHyprOpenGLImpl::renderRectWithBlur(const CBox& box, const CHyprColor& col,
|
||||
pushMonitorTransformEnabled(true);
|
||||
const auto SAVEDRENDERMODIF = m_renderData.renderModif;
|
||||
m_renderData.renderModif = {}; // fix shit
|
||||
renderTextureInternalWithDamage(POUTFB->getTexture(), MONITORBOX, blurA, damage, 0, 2.0f, false, false, false);
|
||||
renderTexture(POUTFB->getTexture(), MONITORBOX,
|
||||
STextureRenderData{.damage = &damage, .a = data.blurA, .round = 0, .roundingPower = 2.0f, .allowCustomUV = false, .allowDim = false, .noAA = false});
|
||||
popMonitorTransformEnabled();
|
||||
m_renderData.renderModif = SAVEDRENDERMODIF;
|
||||
|
||||
@@ -1387,10 +1391,10 @@ void CHyprOpenGLImpl::renderRectWithBlur(const CBox& box, const CHyprColor& col,
|
||||
glStencilFunc(GL_ALWAYS, 1, 0xFF);
|
||||
scissor(nullptr);
|
||||
|
||||
renderRectWithDamage(box, col, m_renderData.damage, round, roundingPower);
|
||||
renderRectWithDamageInternal(box, col, data);
|
||||
}
|
||||
|
||||
void CHyprOpenGLImpl::renderRectWithDamage(const CBox& box, const CHyprColor& col, const CRegion& damage, int round, float roundingPower) {
|
||||
void CHyprOpenGLImpl::renderRectWithDamageInternal(const CBox& box, const CHyprColor& col, const SRectRenderData& data) {
|
||||
RASSERT((box.width > 0 && box.height > 0), "Tried to render rect with width/height < 0!");
|
||||
RASSERT(m_renderData.pMonitor, "Tried to render rect without begin()!");
|
||||
|
||||
@@ -1419,14 +1423,14 @@ void CHyprOpenGLImpl::renderRectWithDamage(const CBox& box, const CHyprColor& co
|
||||
// Rounded corners
|
||||
m_shaders->m_shQUAD.setUniformFloat2(SHADER_TOP_LEFT, (float)TOPLEFT.x, (float)TOPLEFT.y);
|
||||
m_shaders->m_shQUAD.setUniformFloat2(SHADER_FULL_SIZE, (float)FULLSIZE.x, (float)FULLSIZE.y);
|
||||
m_shaders->m_shQUAD.setUniformFloat(SHADER_RADIUS, round);
|
||||
m_shaders->m_shQUAD.setUniformFloat(SHADER_ROUNDING_POWER, roundingPower);
|
||||
m_shaders->m_shQUAD.setUniformFloat(SHADER_RADIUS, data.round);
|
||||
m_shaders->m_shQUAD.setUniformFloat(SHADER_ROUNDING_POWER, data.roundingPower);
|
||||
|
||||
glBindVertexArray(m_shaders->m_shQUAD.uniformLocations[SHADER_SHADER_VAO]);
|
||||
|
||||
if (m_renderData.clipBox.width != 0 && m_renderData.clipBox.height != 0) {
|
||||
CRegion damageClip{m_renderData.clipBox.x, m_renderData.clipBox.y, m_renderData.clipBox.width, m_renderData.clipBox.height};
|
||||
damageClip.intersect(damage);
|
||||
damageClip.intersect(*data.damage);
|
||||
|
||||
if (!damageClip.empty()) {
|
||||
damageClip.forEachRect([this](const auto& RECT) {
|
||||
@@ -1435,7 +1439,7 @@ void CHyprOpenGLImpl::renderRectWithDamage(const CBox& box, const CHyprColor& co
|
||||
});
|
||||
}
|
||||
} else {
|
||||
damage.forEachRect([this](const auto& RECT) {
|
||||
data.damage->forEachRect([this](const auto& RECT) {
|
||||
scissor(&RECT);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
});
|
||||
@@ -1445,34 +1449,35 @@ void CHyprOpenGLImpl::renderRectWithDamage(const CBox& box, const CHyprColor& co
|
||||
scissor(nullptr);
|
||||
}
|
||||
|
||||
void CHyprOpenGLImpl::renderTexture(SP<CTexture> tex, const CBox& box, float alpha, int round, float roundingPower, bool discardActive, bool allowCustomUV, GLenum wrapX,
|
||||
GLenum wrapY) {
|
||||
void CHyprOpenGLImpl::renderTexture(SP<CTexture> tex, const CBox& box, STextureRenderData data) {
|
||||
RASSERT(m_renderData.pMonitor, "Tried to render texture without begin()!");
|
||||
|
||||
renderTextureInternalWithDamage(tex, box, alpha, m_renderData.damage, round, roundingPower, discardActive, false, allowCustomUV, true, wrapX, wrapY);
|
||||
if (!data.damage) {
|
||||
if (m_renderData.damage.empty())
|
||||
return;
|
||||
|
||||
scissor(nullptr);
|
||||
}
|
||||
data.damage = &m_renderData.damage;
|
||||
}
|
||||
|
||||
void CHyprOpenGLImpl::renderTextureWithDamage(SP<CTexture> tex, const CBox& box, const CRegion& damage, float alpha, int round, float roundingPower, bool discardActive,
|
||||
bool allowCustomUV) {
|
||||
RASSERT(m_renderData.pMonitor, "Tried to render texture without begin()!");
|
||||
|
||||
renderTextureInternalWithDamage(tex, box, alpha, damage, round, roundingPower, discardActive, false, allowCustomUV, true);
|
||||
if (data.blur)
|
||||
renderTextureWithBlurInternal(tex, box, data);
|
||||
else
|
||||
renderTextureInternal(tex, box, data);
|
||||
|
||||
scissor(nullptr);
|
||||
}
|
||||
|
||||
static std::map<std::pair<uint32_t, uint32_t>, std::array<GLfloat, 9>> primariesConversionCache;
|
||||
|
||||
void CHyprOpenGLImpl::passCMUniforms(SShader& shader, const NColorManagement::SImageDescription& imageDescription,
|
||||
const NColorManagement::SImageDescription& targetImageDescription, bool modifySDR, float sdrMinLuminance, int sdrMaxLuminance) {
|
||||
//
|
||||
void CHyprOpenGLImpl::passCMUniforms(SShader& shader, const NColorManagement::SImageDescription& imageDescription,
|
||||
const NColorManagement::SImageDescription& targetImageDescription, bool modifySDR, float sdrMinLuminance, int sdrMaxLuminance) {
|
||||
shader.setUniformInt(SHADER_SOURCE_TF, imageDescription.transferFunction);
|
||||
shader.setUniformInt(SHADER_TARGET_TF, targetImageDescription.transferFunction);
|
||||
|
||||
const auto targetPrimaries = targetImageDescription.primariesNameSet || targetImageDescription.primaries == SPCPRimaries{} ?
|
||||
getPrimaries(targetImageDescription.primariesNamed) :
|
||||
targetImageDescription.primaries;
|
||||
getPrimaries(targetImageDescription.primariesNamed) :
|
||||
targetImageDescription.primaries;
|
||||
|
||||
const std::array<GLfloat, 8> glTargetPrimaries = {
|
||||
targetPrimaries.red.x, targetPrimaries.red.y, targetPrimaries.green.x, targetPrimaries.green.y,
|
||||
@@ -1489,16 +1494,16 @@ void CHyprOpen
|
||||
shader.setUniformFloat(SHADER_DST_REF_LUMINANCE, targetImageDescription.luminances.reference);
|
||||
shader.setUniformFloat(SHADER_SDR_SATURATION,
|
||||
modifySDR && m_renderData.pMonitor->m_sdrSaturation > 0 && targetImageDescription.transferFunction == NColorManagement::CM_TRANSFER_FUNCTION_ST2084_PQ ?
|
||||
m_renderData.pMonitor->m_sdrSaturation :
|
||||
1.0f);
|
||||
m_renderData.pMonitor->m_sdrSaturation :
|
||||
1.0f);
|
||||
shader.setUniformFloat(SHADER_SDR_BRIGHTNESS,
|
||||
modifySDR && m_renderData.pMonitor->m_sdrBrightness > 0 && targetImageDescription.transferFunction == NColorManagement::CM_TRANSFER_FUNCTION_ST2084_PQ ?
|
||||
m_renderData.pMonitor->m_sdrBrightness :
|
||||
m_renderData.pMonitor->m_sdrBrightness :
|
||||
|
||||
1.0f);
|
||||
1.0f);
|
||||
const auto cacheKey = std::make_pair(imageDescription.getId(), targetImageDescription.getId());
|
||||
if (!primariesConversionCache.contains(cacheKey)) {
|
||||
const auto mat = imageDescription.getPrimaries().convertMatrix(targetImageDescription.getPrimaries()).mat();
|
||||
const auto mat = imageDescription.getPrimaries().convertMatrix(targetImageDescription.getPrimaries()).mat();
|
||||
const std::array<GLfloat, 9> glConvertMatrix = {
|
||||
mat[0][0], mat[1][0], mat[2][0], //
|
||||
mat[0][1], mat[1][1], mat[2][1], //
|
||||
@@ -1513,16 +1518,15 @@ void CHyprOpenGLImpl::passCMUniforms(SShader& shader, const SImageDescription& i
|
||||
passCMUniforms(shader, imageDescription, m_renderData.pMonitor->m_imageDescription, true, m_renderData.pMonitor->m_sdrMinLuminance, m_renderData.pMonitor->m_sdrMaxLuminance);
|
||||
}
|
||||
|
||||
void CHyprOpenGLImpl::renderTextureInternalWithDamage(SP<CTexture> tex, const CBox& box, float alpha, const CRegion& damage, int round, float roundingPower, bool discardActive,
|
||||
bool noAA, bool allowCustomUV, bool allowDim, GLenum wrapX, GLenum wrapY) {
|
||||
void CHyprOpenGLImpl::renderTextureInternal(SP<CTexture> tex, const CBox& box, const STextureRenderData& data) {
|
||||
RASSERT(m_renderData.pMonitor, "Tried to render texture without begin()!");
|
||||
RASSERT((tex->m_texID > 0), "Attempted to draw nullptr texture!");
|
||||
|
||||
TRACY_GPU_ZONE("RenderTextureInternalWithDamage");
|
||||
|
||||
alpha = std::clamp(alpha, 0.f, 1.f);
|
||||
float alpha = std::clamp(data.a, 0.f, 1.f);
|
||||
|
||||
if (damage.empty())
|
||||
if (data.damage->empty())
|
||||
return;
|
||||
|
||||
CBox newBox = box;
|
||||
@@ -1578,8 +1582,8 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(SP<CTexture> tex, const CB
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
tex->bind();
|
||||
|
||||
tex->setTexParameter(GL_TEXTURE_WRAP_S, wrapX);
|
||||
tex->setTexParameter(GL_TEXTURE_WRAP_T, wrapY);
|
||||
tex->setTexParameter(GL_TEXTURE_WRAP_S, data.wrapX);
|
||||
tex->setTexParameter(GL_TEXTURE_WRAP_T, data.wrapY);
|
||||
|
||||
if (m_renderData.useNearestNeighbor) {
|
||||
tex->setTexParameter(GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
@@ -1637,7 +1641,7 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(SP<CTexture> tex, const CB
|
||||
if (!usingFinalShader) {
|
||||
shader->setUniformFloat(SHADER_ALPHA, alpha);
|
||||
|
||||
if (discardActive) {
|
||||
if (data.discardActive) {
|
||||
shader->setUniformInt(SHADER_DISCARD_OPAQUE, !!(m_renderData.discardMode & DISCARD_OPAQUE));
|
||||
shader->setUniformInt(SHADER_DISCARD_ALPHA, !!(m_renderData.discardMode & DISCARD_ALPHA));
|
||||
shader->setUniformFloat(SHADER_DISCARD_ALPHA_VALUE, m_renderData.discardOpacity);
|
||||
@@ -1658,10 +1662,10 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(SP<CTexture> tex, const CB
|
||||
// Rounded corners
|
||||
shader->setUniformFloat2(SHADER_TOP_LEFT, TOPLEFT.x, TOPLEFT.y);
|
||||
shader->setUniformFloat2(SHADER_FULL_SIZE, FULLSIZE.x, FULLSIZE.y);
|
||||
shader->setUniformFloat(SHADER_RADIUS, round);
|
||||
shader->setUniformFloat(SHADER_ROUNDING_POWER, roundingPower);
|
||||
shader->setUniformFloat(SHADER_RADIUS, data.round);
|
||||
shader->setUniformFloat(SHADER_ROUNDING_POWER, data.roundingPower);
|
||||
|
||||
if (allowDim && m_renderData.currentWindow) {
|
||||
if (data.allowDim && m_renderData.currentWindow) {
|
||||
if (m_renderData.currentWindow->m_notRespondingTint->value() > 0) {
|
||||
const auto DIM = m_renderData.currentWindow->m_notRespondingTint->value();
|
||||
shader->setUniformInt(SHADER_APPLY_TINT, 1);
|
||||
@@ -1677,7 +1681,7 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(SP<CTexture> tex, const CB
|
||||
}
|
||||
|
||||
glBindVertexArray(shader->uniformLocations[SHADER_SHADER_VAO]);
|
||||
if (allowCustomUV && m_renderData.primarySurfaceUVTopLeft != Vector2D(-1, -1)) {
|
||||
if (data.allowCustomUV && m_renderData.primarySurfaceUVTopLeft != Vector2D(-1, -1)) {
|
||||
const float customUVs[] = {
|
||||
m_renderData.primarySurfaceUVBottomRight.x, m_renderData.primarySurfaceUVTopLeft.y, m_renderData.primarySurfaceUVTopLeft.x,
|
||||
m_renderData.primarySurfaceUVTopLeft.y, m_renderData.primarySurfaceUVBottomRight.x, m_renderData.primarySurfaceUVBottomRight.y,
|
||||
@@ -1708,7 +1712,7 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(SP<CTexture> tex, const CB
|
||||
});
|
||||
}
|
||||
} else {
|
||||
damage.forEachRect([this](const auto& RECT) {
|
||||
data.damage->forEachRect([this](const auto& RECT) {
|
||||
scissor(&RECT);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
});
|
||||
@@ -2116,8 +2120,8 @@ void CHyprOpenGLImpl::preBlurForCurrentMonitor() {
|
||||
clear(CHyprColor(0, 0, 0, 0));
|
||||
|
||||
pushMonitorTransformEnabled(true);
|
||||
renderTextureInternalWithDamage(POUTFB->getTexture(), CBox{0, 0, m_renderData.pMonitor->m_transformedSize.x, m_renderData.pMonitor->m_transformedSize.y}, 1, fakeDamage, 0,
|
||||
2.0f, false, true, false);
|
||||
renderTextureInternal(POUTFB->getTexture(), CBox{0, 0, m_renderData.pMonitor->m_transformedSize.x, m_renderData.pMonitor->m_transformedSize.y},
|
||||
STextureRenderData{.damage = &fakeDamage, .a = 1, .round = 0, .roundingPower = 2.F, .discardActive = false, .allowCustomUV = false, .noAA = true});
|
||||
popMonitorTransformEnabled();
|
||||
|
||||
m_renderData.currentFB->bind();
|
||||
@@ -2165,8 +2169,7 @@ bool CHyprOpenGLImpl::shouldUseNewBlurOptimizations(PHLLS pLayer, PHLWINDOW pWin
|
||||
return false;
|
||||
}
|
||||
|
||||
void CHyprOpenGLImpl::renderTextureWithBlur(SP<CTexture> tex, const CBox& box, float a, SP<CWLSurfaceResource> pSurface, int round, float roundingPower, bool blockBlurOptimization,
|
||||
float blurA, float overallA, GLenum wrapX, GLenum wrapY) {
|
||||
void CHyprOpenGLImpl::renderTextureWithBlurInternal(SP<CTexture> tex, const CBox& box, const STextureRenderData& data) {
|
||||
RASSERT(m_renderData.pMonitor, "Tried to render texture with blur without begin()!");
|
||||
|
||||
TRACY_GPU_ZONE("RenderTextureWithBlur");
|
||||
@@ -2187,14 +2190,15 @@ void CHyprOpenGLImpl::renderTextureWithBlur(SP<CTexture> tex, const CBox& box, f
|
||||
|
||||
// amazing hack: the surface has an opaque region!
|
||||
CRegion inverseOpaque;
|
||||
if (a >= 1.f && pSurface && std::round(pSurface->m_current.size.x * m_renderData.pMonitor->m_scale) == box.w &&
|
||||
std::round(pSurface->m_current.size.y * m_renderData.pMonitor->m_scale) == box.h) {
|
||||
pixman_box32_t surfbox = {0, 0, pSurface->m_current.size.x * pSurface->m_current.scale, pSurface->m_current.size.y * pSurface->m_current.scale};
|
||||
inverseOpaque = pSurface->m_current.opaque;
|
||||
inverseOpaque.invert(&surfbox).intersect(0, 0, pSurface->m_current.size.x * pSurface->m_current.scale, pSurface->m_current.size.y * pSurface->m_current.scale);
|
||||
if (data.a >= 1.f && data.surface && std::round(data.surface->m_current.size.x * m_renderData.pMonitor->m_scale) == box.w &&
|
||||
std::round(data.surface->m_current.size.y * m_renderData.pMonitor->m_scale) == box.h) {
|
||||
pixman_box32_t surfbox = {0, 0, data.surface->m_current.size.x * data.surface->m_current.scale, data.surface->m_current.size.y * data.surface->m_current.scale};
|
||||
inverseOpaque = data.surface->m_current.opaque;
|
||||
inverseOpaque.invert(&surfbox).intersect(0, 0, data.surface->m_current.size.x * data.surface->m_current.scale,
|
||||
data.surface->m_current.size.y * data.surface->m_current.scale);
|
||||
|
||||
if (inverseOpaque.empty()) {
|
||||
renderTexture(tex, box, a, round, roundingPower, false, true, wrapX, wrapY);
|
||||
renderTextureInternal(tex, box, data);
|
||||
return;
|
||||
}
|
||||
} else
|
||||
@@ -2203,14 +2207,14 @@ void CHyprOpenGLImpl::renderTextureWithBlur(SP<CTexture> tex, const CBox& box, f
|
||||
inverseOpaque.scale(m_renderData.pMonitor->m_scale);
|
||||
|
||||
// vvv TODO: layered blur fbs?
|
||||
const bool USENEWOPTIMIZE = shouldUseNewBlurOptimizations(m_renderData.currentLS.lock(), m_renderData.currentWindow.lock()) && !blockBlurOptimization;
|
||||
const bool USENEWOPTIMIZE = shouldUseNewBlurOptimizations(m_renderData.currentLS.lock(), m_renderData.currentWindow.lock()) && !data.blockBlurOptimization;
|
||||
|
||||
CFramebuffer* POUTFB = nullptr;
|
||||
if (!USENEWOPTIMIZE) {
|
||||
inverseOpaque.translate(box.pos());
|
||||
m_renderData.renderModif.applyToRegion(inverseOpaque);
|
||||
inverseOpaque.intersect(texDamage);
|
||||
POUTFB = blurMainFramebufferWithDamage(a, &inverseOpaque);
|
||||
POUTFB = blurMainFramebufferWithDamage(data.a, &inverseOpaque);
|
||||
} else
|
||||
POUTFB = &m_renderData.pCurrentMonData->blurFB;
|
||||
|
||||
@@ -2228,9 +2232,16 @@ void CHyprOpenGLImpl::renderTextureWithBlur(SP<CTexture> tex, const CBox& box, f
|
||||
|
||||
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
|
||||
if (USENEWOPTIMIZE && !(m_renderData.discardMode & DISCARD_ALPHA))
|
||||
renderRect(box, CHyprColor(0, 0, 0, 0), round, roundingPower);
|
||||
renderRect(box, CHyprColor(0, 0, 0, 0), SRectRenderData{.round = data.round, .roundingPower = data.roundingPower});
|
||||
else
|
||||
renderTexture(tex, box, a, round, roundingPower, true, true, wrapX, wrapY); // discard opaque
|
||||
renderTexture(tex, box,
|
||||
STextureRenderData{.a = data.a,
|
||||
.round = data.round,
|
||||
.roundingPower = data.roundingPower,
|
||||
.discardActive = true,
|
||||
.allowCustomUV = true,
|
||||
.wrapX = data.wrapX,
|
||||
.wrapY = data.wrapY}); // discard opaque
|
||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
|
||||
glStencilFunc(GL_EQUAL, 1, 0xFF);
|
||||
@@ -2256,8 +2267,18 @@ void CHyprOpenGLImpl::renderTextureWithBlur(SP<CTexture> tex, const CBox& box, f
|
||||
pushMonitorTransformEnabled(true);
|
||||
if (!USENEWOPTIMIZE)
|
||||
setRenderModifEnabled(false);
|
||||
renderTextureInternalWithDamage(POUTFB->getTexture(), box, (*PBLURIGNOREOPACITY ? blurA : a * blurA) * overallA, texDamage, round, roundingPower, false, false, true, wrapX,
|
||||
wrapY);
|
||||
renderTextureInternal(POUTFB->getTexture(), box,
|
||||
STextureRenderData{
|
||||
.damage = &texDamage,
|
||||
.a = (*PBLURIGNOREOPACITY ? data.blurA : data.a * data.blurA) * data.overallA,
|
||||
.round = data.round,
|
||||
.roundingPower = data.roundingPower,
|
||||
.discardActive = false,
|
||||
.allowCustomUV = true,
|
||||
.noAA = false,
|
||||
.wrapX = data.wrapX,
|
||||
.wrapY = data.wrapY,
|
||||
});
|
||||
if (!USENEWOPTIMIZE)
|
||||
setRenderModifEnabled(true);
|
||||
popMonitorTransformEnabled();
|
||||
@@ -2271,14 +2292,26 @@ void CHyprOpenGLImpl::renderTextureWithBlur(SP<CTexture> tex, const CBox& box, f
|
||||
|
||||
// draw window
|
||||
setCapStatus(GL_STENCIL_TEST, false);
|
||||
renderTextureInternalWithDamage(tex, box, a * overallA, texDamage, round, roundingPower, false, false, true, true, wrapX, wrapY);
|
||||
renderTextureInternal(tex, box,
|
||||
STextureRenderData{
|
||||
.damage = &texDamage,
|
||||
.a = data.a * data.overallA,
|
||||
.round = data.round,
|
||||
.roundingPower = data.roundingPower,
|
||||
.discardActive = false,
|
||||
.allowCustomUV = true,
|
||||
.allowDim = true,
|
||||
.noAA = false,
|
||||
.wrapX = data.wrapX,
|
||||
.wrapY = data.wrapY,
|
||||
});
|
||||
|
||||
glStencilMask(0xFF);
|
||||
glStencilFunc(GL_ALWAYS, 1, 0xFF);
|
||||
scissor(nullptr);
|
||||
}
|
||||
|
||||
void CHyprOpenGLImpl::renderBorder(const CBox& box, const CGradientValueData& grad, int round, float roundingPower, int borderSize, float a, int outerRound) {
|
||||
void CHyprOpenGLImpl::renderBorder(const CBox& box, const CGradientValueData& grad, SBorderRenderData data) {
|
||||
RASSERT((box.width > 0 && box.height > 0), "Tried to render rect with width/height < 0!");
|
||||
RASSERT(m_renderData.pMonitor, "Tried to render rect without begin()!");
|
||||
|
||||
@@ -2290,10 +2323,10 @@ void CHyprOpenGLImpl::renderBorder(const CBox& box, const CGradientValueData& gr
|
||||
CBox newBox = box;
|
||||
m_renderData.renderModif.applyToBox(newBox);
|
||||
|
||||
if (borderSize < 1)
|
||||
if (data.borderSize < 1)
|
||||
return;
|
||||
|
||||
int scaledBorderSize = std::round(borderSize * m_renderData.pMonitor->m_scale);
|
||||
int scaledBorderSize = std::round(data.borderSize * m_renderData.pMonitor->m_scale);
|
||||
scaledBorderSize = std::round(scaledBorderSize * m_renderData.renderModif.combinedScale());
|
||||
|
||||
// adjust box
|
||||
@@ -2302,7 +2335,7 @@ void CHyprOpenGLImpl::renderBorder(const CBox& box, const CGradientValueData& gr
|
||||
newBox.width += 2 * scaledBorderSize;
|
||||
newBox.height += 2 * scaledBorderSize;
|
||||
|
||||
round += round == 0 ? 0 : scaledBorderSize;
|
||||
float round = data.round + (data.round == 0 ? 0 : scaledBorderSize);
|
||||
|
||||
Mat3x3 matrix = m_renderData.monitorProjection.projectBox(
|
||||
newBox, wlTransformToHyprutils(invertTransform(!m_monitorTransformEnabled ? WL_OUTPUT_TRANSFORM_NORMAL : m_renderData.pMonitor->m_transform)), newBox.rot);
|
||||
@@ -2321,8 +2354,8 @@ void CHyprOpenGLImpl::renderBorder(const CBox& box, const CGradientValueData& gr
|
||||
m_shaders->m_shBORDER1.setUniformMatrix3fv(SHADER_PROJ, 1, GL_TRUE, glMatrix.getMatrix());
|
||||
m_shaders->m_shBORDER1.setUniform4fv(SHADER_GRADIENT, grad.m_colorsOkLabA.size() / 4, grad.m_colorsOkLabA);
|
||||
m_shaders->m_shBORDER1.setUniformInt(SHADER_GRADIENT_LENGTH, grad.m_colorsOkLabA.size() / 4);
|
||||
m_shaders->m_shBORDER1.setUniformFloat(SHADER_ANGLE, (int)(grad.m_angle / (PI / 180.0)) % 360 * (PI / 180.0));
|
||||
m_shaders->m_shBORDER1.setUniformFloat(SHADER_ALPHA, a);
|
||||
m_shaders->m_shBORDER1.setUniformFloat(SHADER_ANGLE, (int)(grad.m_angle / (std::numbers::pi / 180.0)) % 360 * (std::numbers::pi / 180.0));
|
||||
m_shaders->m_shBORDER1.setUniformFloat(SHADER_ALPHA, data.a);
|
||||
m_shaders->m_shBORDER1.setUniformInt(SHADER_GRADIENT2_LENGTH, 0);
|
||||
|
||||
CBox transformedBox = newBox;
|
||||
@@ -2336,8 +2369,8 @@ void CHyprOpenGLImpl::renderBorder(const CBox& box, const CGradientValueData& gr
|
||||
m_shaders->m_shBORDER1.setUniformFloat2(SHADER_FULL_SIZE, (float)FULLSIZE.x, (float)FULLSIZE.y);
|
||||
m_shaders->m_shBORDER1.setUniformFloat2(SHADER_FULL_SIZE_UNTRANSFORMED, (float)newBox.width, (float)newBox.height);
|
||||
m_shaders->m_shBORDER1.setUniformFloat(SHADER_RADIUS, round);
|
||||
m_shaders->m_shBORDER1.setUniformFloat(SHADER_RADIUS_OUTER, outerRound == -1 ? round : outerRound);
|
||||
m_shaders->m_shBORDER1.setUniformFloat(SHADER_ROUNDING_POWER, roundingPower);
|
||||
m_shaders->m_shBORDER1.setUniformFloat(SHADER_RADIUS_OUTER, data.outerRound == -1 ? round : data.outerRound);
|
||||
m_shaders->m_shBORDER1.setUniformFloat(SHADER_ROUNDING_POWER, data.roundingPower);
|
||||
m_shaders->m_shBORDER1.setUniformFloat(SHADER_THICK, scaledBorderSize);
|
||||
|
||||
glBindVertexArray(m_shaders->m_shBORDER1.uniformLocations[SHADER_SHADER_VAO]);
|
||||
@@ -2364,8 +2397,7 @@ void CHyprOpenGLImpl::renderBorder(const CBox& box, const CGradientValueData& gr
|
||||
blend(BLEND);
|
||||
}
|
||||
|
||||
void CHyprOpenGLImpl::renderBorder(const CBox& box, const CGradientValueData& grad1, const CGradientValueData& grad2, float lerp, int round, float roundingPower, int borderSize,
|
||||
float a, int outerRound) {
|
||||
void CHyprOpenGLImpl::renderBorder(const CBox& box, const CGradientValueData& grad1, const CGradientValueData& grad2, float lerp, SBorderRenderData data) {
|
||||
RASSERT((box.width > 0 && box.height > 0), "Tried to render rect with width/height < 0!");
|
||||
RASSERT(m_renderData.pMonitor, "Tried to render rect without begin()!");
|
||||
|
||||
@@ -2377,10 +2409,10 @@ void CHyprOpenGLImpl::renderBorder(const CBox& box, const CGradientValueData& gr
|
||||
CBox newBox = box;
|
||||
m_renderData.renderModif.applyToBox(newBox);
|
||||
|
||||
if (borderSize < 1)
|
||||
if (data.borderSize < 1)
|
||||
return;
|
||||
|
||||
int scaledBorderSize = std::round(borderSize * m_renderData.pMonitor->m_scale);
|
||||
int scaledBorderSize = std::round(data.borderSize * m_renderData.pMonitor->m_scale);
|
||||
scaledBorderSize = std::round(scaledBorderSize * m_renderData.renderModif.combinedScale());
|
||||
|
||||
// adjust box
|
||||
@@ -2389,7 +2421,7 @@ void CHyprOpenGLImpl::renderBorder(const CBox& box, const CGradientValueData& gr
|
||||
newBox.width += 2 * scaledBorderSize;
|
||||
newBox.height += 2 * scaledBorderSize;
|
||||
|
||||
round += round == 0 ? 0 : scaledBorderSize;
|
||||
float round = data.round + (data.round == 0 ? 0 : scaledBorderSize);
|
||||
|
||||
Mat3x3 matrix = m_renderData.monitorProjection.projectBox(
|
||||
newBox, wlTransformToHyprutils(invertTransform(!m_monitorTransformEnabled ? WL_OUTPUT_TRANSFORM_NORMAL : m_renderData.pMonitor->m_transform)), newBox.rot);
|
||||
@@ -2408,12 +2440,12 @@ void CHyprOpenGLImpl::renderBorder(const CBox& box, const CGradientValueData& gr
|
||||
m_shaders->m_shBORDER1.setUniformMatrix3fv(SHADER_PROJ, 1, GL_TRUE, glMatrix.getMatrix());
|
||||
m_shaders->m_shBORDER1.setUniform4fv(SHADER_GRADIENT, grad1.m_colorsOkLabA.size() / 4, grad1.m_colorsOkLabA);
|
||||
m_shaders->m_shBORDER1.setUniformInt(SHADER_GRADIENT_LENGTH, grad1.m_colorsOkLabA.size() / 4);
|
||||
m_shaders->m_shBORDER1.setUniformFloat(SHADER_ANGLE, (int)(grad1.m_angle / (PI / 180.0)) % 360 * (PI / 180.0));
|
||||
m_shaders->m_shBORDER1.setUniformFloat(SHADER_ANGLE, (int)(grad1.m_angle / (std::numbers::pi / 180.0)) % 360 * (std::numbers::pi / 180.0));
|
||||
if (!grad2.m_colorsOkLabA.empty())
|
||||
m_shaders->m_shBORDER1.setUniform4fv(SHADER_GRADIENT2, grad2.m_colorsOkLabA.size() / 4, grad2.m_colorsOkLabA);
|
||||
m_shaders->m_shBORDER1.setUniformInt(SHADER_GRADIENT2_LENGTH, grad2.m_colorsOkLabA.size() / 4);
|
||||
m_shaders->m_shBORDER1.setUniformFloat(SHADER_ANGLE2, (int)(grad2.m_angle / (PI / 180.0)) % 360 * (PI / 180.0));
|
||||
m_shaders->m_shBORDER1.setUniformFloat(SHADER_ALPHA, a);
|
||||
m_shaders->m_shBORDER1.setUniformFloat(SHADER_ANGLE2, (int)(grad2.m_angle / (std::numbers::pi / 180.0)) % 360 * (std::numbers::pi / 180.0));
|
||||
m_shaders->m_shBORDER1.setUniformFloat(SHADER_ALPHA, data.a);
|
||||
m_shaders->m_shBORDER1.setUniformFloat(SHADER_GRADIENT_LERP, lerp);
|
||||
|
||||
CBox transformedBox = newBox;
|
||||
@@ -2427,8 +2459,8 @@ void CHyprOpenGLImpl::renderBorder(const CBox& box, const CGradientValueData& gr
|
||||
m_shaders->m_shBORDER1.setUniformFloat2(SHADER_FULL_SIZE, (float)FULLSIZE.x, (float)FULLSIZE.y);
|
||||
m_shaders->m_shBORDER1.setUniformFloat2(SHADER_FULL_SIZE_UNTRANSFORMED, (float)newBox.width, (float)newBox.height);
|
||||
m_shaders->m_shBORDER1.setUniformFloat(SHADER_RADIUS, round);
|
||||
m_shaders->m_shBORDER1.setUniformFloat(SHADER_RADIUS_OUTER, outerRound == -1 ? round : outerRound);
|
||||
m_shaders->m_shBORDER1.setUniformFloat(SHADER_ROUNDING_POWER, roundingPower);
|
||||
m_shaders->m_shBORDER1.setUniformFloat(SHADER_RADIUS_OUTER, data.outerRound == -1 ? round : data.outerRound);
|
||||
m_shaders->m_shBORDER1.setUniformFloat(SHADER_ROUNDING_POWER, data.roundingPower);
|
||||
m_shaders->m_shBORDER1.setUniformFloat(SHADER_THICK, scaledBorderSize);
|
||||
|
||||
glBindVertexArray(m_shaders->m_shBORDER1.uniformLocations[SHADER_SHADER_VAO]);
|
||||
@@ -2533,7 +2565,13 @@ void CHyprOpenGLImpl::saveBufferForMirror(const CBox& box) {
|
||||
|
||||
blend(false);
|
||||
|
||||
renderTexture(m_renderData.currentFB->getTexture(), box, 1.f, 0, 2.0f, false, false);
|
||||
renderTexture(m_renderData.currentFB->getTexture(), box,
|
||||
STextureRenderData{
|
||||
.a = 1.f,
|
||||
.round = 0,
|
||||
.discardActive = false,
|
||||
.allowCustomUV = false,
|
||||
});
|
||||
|
||||
blend(true);
|
||||
|
||||
@@ -2931,11 +2969,11 @@ void CHyprOpenGLImpl::createBGTextureForMonitor(PHLMONITOR pMonitor) {
|
||||
}
|
||||
|
||||
CBox texbox = CBox{origin, m_backgroundTexture->m_size * scale};
|
||||
renderTextureInternalWithDamage(m_backgroundTexture, texbox, 1.0, fakeDamage);
|
||||
renderTextureInternal(m_backgroundTexture, texbox, {.damage = &fakeDamage, .a = 1.0});
|
||||
}
|
||||
|
||||
CBox monbox = {{}, pMonitor->m_pixelSize};
|
||||
renderTextureInternalWithDamage(tex, monbox, 1.0, fakeDamage);
|
||||
renderTextureInternal(tex, monbox, {.damage = &fakeDamage, .a = 1.0});
|
||||
|
||||
// bind back
|
||||
if (m_renderData.currentFB)
|
||||
|
@@ -177,62 +177,87 @@ class CHyprOpenGLImpl {
|
||||
CHyprOpenGLImpl();
|
||||
~CHyprOpenGLImpl();
|
||||
|
||||
void begin(PHLMONITOR, const CRegion& damage, CFramebuffer* fb = nullptr, std::optional<CRegion> finalDamage = {});
|
||||
void beginSimple(PHLMONITOR, const CRegion& damage, SP<CRenderbuffer> rb = nullptr, CFramebuffer* fb = nullptr);
|
||||
void end();
|
||||
struct SRectRenderData {
|
||||
const CRegion* damage = nullptr;
|
||||
int round = 0;
|
||||
float roundingPower = 2.F;
|
||||
bool blur = false;
|
||||
float blurA = 1.F;
|
||||
bool xray = false;
|
||||
};
|
||||
|
||||
void renderRect(const CBox&, const CHyprColor&, int round = 0, float roundingPower = 2.0f);
|
||||
void renderRectWithBlur(const CBox&, const CHyprColor&, int round = 0, float roundingPower = 2.0f, float blurA = 1.f, bool xray = false);
|
||||
void renderRectWithDamage(const CBox&, const CHyprColor&, const CRegion& damage, int round = 0, float roundingPower = 2.0f);
|
||||
void renderTexture(SP<CTexture>, const CBox&, float a, int round = 0, float roundingPower = 2.0f, bool discardActive = false, bool allowCustomUV = false,
|
||||
GLenum wrapX = GL_CLAMP_TO_EDGE, GLenum wrapY = GL_CLAMP_TO_EDGE);
|
||||
void renderTextureWithDamage(SP<CTexture>, const CBox&, const CRegion& damage, float a, int round = 0, float roundingPower = 2.0f, bool discardActive = false,
|
||||
bool allowCustomUV = false);
|
||||
void renderTextureWithBlur(SP<CTexture>, const CBox&, float a, SP<CWLSurfaceResource> pSurface, int round = 0, float roundingPower = 2.0f, bool blockBlurOptimization = false,
|
||||
float blurA = 1.f, float overallA = 1.f, GLenum wrapX = GL_CLAMP_TO_EDGE, GLenum wrapY = GL_CLAMP_TO_EDGE);
|
||||
void renderRoundedShadow(const CBox&, int round, float roundingPower, int range, const CHyprColor& color, float a = 1.0);
|
||||
void renderBorder(const CBox&, const CGradientValueData&, int round, float roundingPower, int borderSize, float a = 1.0, int outerRound = -1 /* use round */);
|
||||
void renderBorder(const CBox&, const CGradientValueData&, const CGradientValueData&, float lerp, int round, float roundingPower, int borderSize, float a = 1.0,
|
||||
int outerRound = -1 /* use round */);
|
||||
void renderTextureMatte(SP<CTexture> tex, const CBox& pBox, CFramebuffer& matte);
|
||||
struct STextureRenderData {
|
||||
const CRegion* damage = nullptr;
|
||||
SP<CWLSurfaceResource> surface = nullptr;
|
||||
float a = 1.F;
|
||||
bool blur = false;
|
||||
float blurA = 1.F, overallA = 1.F;
|
||||
int round = 0;
|
||||
float roundingPower = 2.F;
|
||||
bool discardActive = false;
|
||||
bool allowCustomUV = false;
|
||||
bool allowDim = true;
|
||||
bool noAA = false;
|
||||
bool blockBlurOptimization = false;
|
||||
GLenum wrapX = GL_CLAMP_TO_EDGE, wrapY = GL_CLAMP_TO_EDGE;
|
||||
};
|
||||
|
||||
void pushMonitorTransformEnabled(bool enabled);
|
||||
void popMonitorTransformEnabled();
|
||||
struct SBorderRenderData {
|
||||
int round = 0;
|
||||
float roundingPower = 2.F;
|
||||
int borderSize = 1;
|
||||
float a = 1.0;
|
||||
int outerRound = -1; /* use round */
|
||||
};
|
||||
|
||||
void setRenderModifEnabled(bool enabled);
|
||||
void setViewport(GLint x, GLint y, GLsizei width, GLsizei height);
|
||||
void setCapStatus(int cap, bool status);
|
||||
void begin(PHLMONITOR, const CRegion& damage, CFramebuffer* fb = nullptr, std::optional<CRegion> finalDamage = {});
|
||||
void beginSimple(PHLMONITOR, const CRegion& damage, SP<CRenderbuffer> rb = nullptr, CFramebuffer* fb = nullptr);
|
||||
void end();
|
||||
|
||||
void saveMatrix();
|
||||
void setMatrixScaleTranslate(const Vector2D& translate, const float& scale);
|
||||
void restoreMatrix();
|
||||
void renderRect(const CBox&, const CHyprColor&, SRectRenderData data);
|
||||
void renderTexture(SP<CTexture>, const CBox&, STextureRenderData data);
|
||||
void renderRoundedShadow(const CBox&, int round, float roundingPower, int range, const CHyprColor& color, float a = 1.0);
|
||||
void renderBorder(const CBox&, const CGradientValueData&, SBorderRenderData data);
|
||||
void renderBorder(const CBox&, const CGradientValueData&, const CGradientValueData&, float lerp, SBorderRenderData data);
|
||||
void renderTextureMatte(SP<CTexture> tex, const CBox& pBox, CFramebuffer& matte);
|
||||
|
||||
void blend(bool enabled);
|
||||
void pushMonitorTransformEnabled(bool enabled);
|
||||
void popMonitorTransformEnabled();
|
||||
|
||||
bool shouldUseNewBlurOptimizations(PHLLS pLayer, PHLWINDOW pWindow);
|
||||
void setRenderModifEnabled(bool enabled);
|
||||
void setViewport(GLint x, GLint y, GLsizei width, GLsizei height);
|
||||
void setCapStatus(int cap, bool status);
|
||||
|
||||
void clear(const CHyprColor&);
|
||||
void clearWithTex();
|
||||
void scissor(const CBox&, bool transform = true);
|
||||
void scissor(const pixman_box32*, bool transform = true);
|
||||
void scissor(const int x, const int y, const int w, const int h, bool transform = true);
|
||||
void saveMatrix();
|
||||
void setMatrixScaleTranslate(const Vector2D& translate, const float& scale);
|
||||
void restoreMatrix();
|
||||
|
||||
void destroyMonitorResources(PHLMONITORREF);
|
||||
void blend(bool enabled);
|
||||
|
||||
void markBlurDirtyForMonitor(PHLMONITOR);
|
||||
bool shouldUseNewBlurOptimizations(PHLLS pLayer, PHLWINDOW pWindow);
|
||||
|
||||
void preWindowPass();
|
||||
bool preBlurQueued();
|
||||
void preRender(PHLMONITOR);
|
||||
void clear(const CHyprColor&);
|
||||
void clearWithTex();
|
||||
void scissor(const CBox&, bool transform = true);
|
||||
void scissor(const pixman_box32*, bool transform = true);
|
||||
void scissor(const int x, const int y, const int w, const int h, bool transform = true);
|
||||
|
||||
void saveBufferForMirror(const CBox&);
|
||||
void renderMirrored();
|
||||
void destroyMonitorResources(PHLMONITORREF);
|
||||
|
||||
void applyScreenShader(const std::string& path);
|
||||
void markBlurDirtyForMonitor(PHLMONITOR);
|
||||
|
||||
void bindOffMain();
|
||||
void renderOffToMain(CFramebuffer* off);
|
||||
void bindBackOnMain();
|
||||
void preWindowPass();
|
||||
bool preBlurQueued();
|
||||
void preRender(PHLMONITOR);
|
||||
|
||||
void saveBufferForMirror(const CBox&);
|
||||
void renderMirrored();
|
||||
|
||||
void applyScreenShader(const std::string& path);
|
||||
|
||||
void bindOffMain();
|
||||
void renderOffToMain(CFramebuffer* off);
|
||||
void bindBackOnMain();
|
||||
|
||||
SP<CTexture> loadAsset(const std::string& file);
|
||||
SP<CTexture> renderText(const std::string& text, CHyprColor col, int pt, bool italic = false, const std::string& fontFamily = "", int maxWidth = 0, int weight = 400);
|
||||
@@ -363,12 +388,15 @@ class CHyprOpenGLImpl {
|
||||
void passCMUniforms(SShader&, const NColorManagement::SImageDescription& imageDescription, const NColorManagement::SImageDescription& targetImageDescription,
|
||||
bool modifySDR = false, float sdrMinLuminance = -1.0f, int sdrMaxLuminance = -1);
|
||||
void passCMUniforms(SShader&, const NColorManagement::SImageDescription& imageDescription);
|
||||
void renderTextureInternalWithDamage(SP<CTexture>, const CBox& box, float a, const CRegion& damage, int round = 0, float roundingPower = 2.0f, bool discardOpaque = false,
|
||||
bool noAA = false, bool allowCustomUV = false, bool allowDim = false, GLenum wrapX = GL_CLAMP_TO_EDGE, GLenum wrapY = GL_CLAMP_TO_EDGE);
|
||||
void renderTexturePrimitive(SP<CTexture> tex, const CBox& box);
|
||||
void renderSplash(cairo_t* const, cairo_surface_t* const, double offset, const Vector2D& size);
|
||||
void renderTexturePrimitive(SP<CTexture> tex, const CBox& box);
|
||||
void renderSplash(cairo_t* const, cairo_surface_t* const, double offset, const Vector2D& size);
|
||||
void renderRectInternal(const CBox&, const CHyprColor&, const SRectRenderData& data);
|
||||
void renderRectWithBlurInternal(const CBox&, const CHyprColor&, const SRectRenderData& data);
|
||||
void renderRectWithDamageInternal(const CBox&, const CHyprColor&, const SRectRenderData& data);
|
||||
void renderTextureInternal(SP<CTexture>, const CBox&, const STextureRenderData& data);
|
||||
void renderTextureWithBlurInternal(SP<CTexture>, const CBox&, const STextureRenderData& data);
|
||||
|
||||
void preBlurForCurrentMonitor();
|
||||
void preBlurForCurrentMonitor();
|
||||
|
||||
friend class CHyprRenderer;
|
||||
friend class CTexPassElement;
|
||||
|
@@ -189,18 +189,19 @@ void CHyprDropShadowDecoration::render(PHLMONITOR pMonitor, float const& a) {
|
||||
// build the matte
|
||||
// 10-bit formats have dogshit alpha channels, so we have to use the matte to its fullest.
|
||||
// first, clear region of interest with black (fully transparent)
|
||||
g_pHyprOpenGL->renderRect(fullBox, CHyprColor(0, 0, 0, 1), 0);
|
||||
g_pHyprOpenGL->renderRect(fullBox, CHyprColor(0, 0, 0, 1), {.round = 0});
|
||||
|
||||
// render white shadow with the alpha of the shadow color (otherwise we clear with alpha later and shit it to 2 bit)
|
||||
drawShadowInternal(fullBox, ROUNDING * pMonitor->m_scale, ROUNDINGPOWER, *PSHADOWSIZE * pMonitor->m_scale, CHyprColor(1, 1, 1, PWINDOW->m_realShadowColor->value().a), a);
|
||||
|
||||
// render black window box ("clip")
|
||||
g_pHyprOpenGL->renderRect(windowBox, CHyprColor(0, 0, 0, 1.0), (ROUNDING + 1 /* This fixes small pixel gaps. */) * pMonitor->m_scale, ROUNDINGPOWER);
|
||||
g_pHyprOpenGL->renderRect(windowBox, CHyprColor(0, 0, 0, 1.0),
|
||||
{.round = (ROUNDING + 1 /* This fixes small pixel gaps. */) * pMonitor->m_scale, .roundingPower = ROUNDINGPOWER});
|
||||
|
||||
alphaSwapFB.bind();
|
||||
|
||||
// alpha swap just has the shadow color. It will be the "texture" to render.
|
||||
g_pHyprOpenGL->renderRect(fullBox, PWINDOW->m_realShadowColor->value().stripA(), 0);
|
||||
g_pHyprOpenGL->renderRect(fullBox, PWINDOW->m_realShadowColor->value().stripA(), {.round = 0});
|
||||
|
||||
LASTFB->bind();
|
||||
|
||||
@@ -237,7 +238,7 @@ void CHyprDropShadowDecoration::drawShadowInternal(const CBox& box, int round, f
|
||||
color.a *= a;
|
||||
|
||||
if (*PSHADOWSHARP)
|
||||
g_pHyprOpenGL->renderRect(box, color, round, roundingPower);
|
||||
g_pHyprOpenGL->renderRect(box, color, {.round = round, .roundingPower = roundingPower});
|
||||
else
|
||||
g_pHyprOpenGL->renderRoundedShadow(box, round, roundingPower, range, color, 1.F);
|
||||
}
|
||||
|
@@ -7,9 +7,13 @@ CBorderPassElement::CBorderPassElement(const CBorderPassElement::SBorderData& da
|
||||
|
||||
void CBorderPassElement::draw(const CRegion& damage) {
|
||||
if (m_data.hasGrad2)
|
||||
g_pHyprOpenGL->renderBorder(m_data.box, m_data.grad1, m_data.grad2, m_data.lerp, m_data.round, m_data.roundingPower, m_data.borderSize, m_data.a, m_data.outerRound);
|
||||
g_pHyprOpenGL->renderBorder(
|
||||
m_data.box, m_data.grad1, m_data.grad2, m_data.lerp,
|
||||
{.round = m_data.round, .roundingPower = m_data.roundingPower, .borderSize = m_data.borderSize, .a = m_data.a, .outerRound = m_data.outerRound});
|
||||
else
|
||||
g_pHyprOpenGL->renderBorder(m_data.box, m_data.grad1, m_data.round, m_data.roundingPower, m_data.borderSize, m_data.a, m_data.outerRound);
|
||||
g_pHyprOpenGL->renderBorder(
|
||||
m_data.box, m_data.grad1,
|
||||
{.round = m_data.round, .roundingPower = m_data.roundingPower, .borderSize = m_data.borderSize, .a = m_data.a, .outerRound = m_data.outerRound});
|
||||
}
|
||||
|
||||
bool CBorderPassElement::needsLiveBlur() {
|
||||
|
@@ -199,9 +199,9 @@ CRegion CRenderPass::render(const CRegion& damage_) {
|
||||
void CRenderPass::renderDebugData() {
|
||||
CBox box = {{}, g_pHyprOpenGL->m_renderData.pMonitor->m_transformedSize};
|
||||
for (const auto& rg : m_occludedRegions) {
|
||||
g_pHyprOpenGL->renderRectWithDamage(box, Colors::RED.modifyA(0.1F), rg);
|
||||
g_pHyprOpenGL->renderRect(box, Colors::RED.modifyA(0.1F), {.damage = &rg});
|
||||
}
|
||||
g_pHyprOpenGL->renderRectWithDamage(box, Colors::GREEN.modifyA(0.1F), m_totalLiveBlurRegion);
|
||||
g_pHyprOpenGL->renderRect(box, Colors::GREEN.modifyA(0.1F), {.damage = &m_totalLiveBlurRegion});
|
||||
|
||||
std::unordered_map<CWLSurfaceResource*, float> offsets;
|
||||
|
||||
@@ -224,7 +224,9 @@ void CRenderPass::renderDebugData() {
|
||||
if (box.intersection(CBox{{}, g_pHyprOpenGL->m_renderData.pMonitor->m_size}).empty())
|
||||
return;
|
||||
|
||||
g_pHyprOpenGL->renderRectWithDamage(box, color, CRegion{0, 0, INT32_MAX, INT32_MAX});
|
||||
static const auto FULL_REGION = CRegion{0, 0, INT32_MAX, INT32_MAX};
|
||||
|
||||
g_pHyprOpenGL->renderRect(box, color, {.damage = &FULL_REGION});
|
||||
|
||||
if (offsets.contains(surface.get()))
|
||||
box.translate(Vector2D{0.F, offsets[surface.get()]});
|
||||
@@ -232,8 +234,8 @@ void CRenderPass::renderDebugData() {
|
||||
offsets[surface.get()] = 0;
|
||||
|
||||
box = {box.pos(), texture->m_size};
|
||||
g_pHyprOpenGL->renderRectWithDamage(box, CHyprColor{0.F, 0.F, 0.F, 0.2F}, CRegion{0, 0, INT32_MAX, INT32_MAX}, std::min(5.0, box.size().y));
|
||||
g_pHyprOpenGL->renderTexture(texture, box, 1.F);
|
||||
g_pHyprOpenGL->renderRect(box, CHyprColor{0.F, 0.F, 0.F, 0.2F}, {.damage = &FULL_REGION, .round = std::min(5.0, box.size().y)});
|
||||
g_pHyprOpenGL->renderTexture(texture, box, {});
|
||||
|
||||
offsets[surface.get()] += texture->m_size.y;
|
||||
};
|
||||
@@ -253,7 +255,7 @@ void CRenderPass::renderDebugData() {
|
||||
auto region = g_pSeatManager->m_state.pointerFocus->m_current.input.copy()
|
||||
.scale(g_pHyprOpenGL->m_renderData.pMonitor->m_scale)
|
||||
.translate(BOX->pos() - g_pHyprOpenGL->m_renderData.pMonitor->m_position);
|
||||
g_pHyprOpenGL->renderRectWithDamage(box, CHyprColor{0.8F, 0.8F, 0.2F, 0.4F}, region);
|
||||
g_pHyprOpenGL->renderRect(box, CHyprColor{0.8F, 0.8F, 0.2F, 0.4F}, {.damage = ®ion});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -266,7 +268,7 @@ void CRenderPass::renderDebugData() {
|
||||
|
||||
if (tex) {
|
||||
box = CBox{{0.F, g_pHyprOpenGL->m_renderData.pMonitor->m_size.y - tex->m_size.y}, tex->m_size}.scale(g_pHyprOpenGL->m_renderData.pMonitor->m_scale);
|
||||
g_pHyprOpenGL->renderTexture(tex, box, 1.F);
|
||||
g_pHyprOpenGL->renderTexture(tex, box, {});
|
||||
}
|
||||
|
||||
std::string passStructure;
|
||||
@@ -284,7 +286,7 @@ void CRenderPass::renderDebugData() {
|
||||
if (tex) {
|
||||
box = CBox{{g_pHyprOpenGL->m_renderData.pMonitor->m_size.x - tex->m_size.x, g_pHyprOpenGL->m_renderData.pMonitor->m_size.y - tex->m_size.y}, tex->m_size}.scale(
|
||||
g_pHyprOpenGL->m_renderData.pMonitor->m_scale);
|
||||
g_pHyprOpenGL->renderTexture(tex, box, 1.F);
|
||||
g_pHyprOpenGL->renderTexture(tex, box, {});
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -13,9 +13,10 @@ void CRectPassElement::draw(const CRegion& damage) {
|
||||
g_pHyprOpenGL->m_renderData.clipBox = m_data.clipBox;
|
||||
|
||||
if (m_data.color.a == 1.F || !m_data.blur)
|
||||
g_pHyprOpenGL->renderRectWithDamage(m_data.box, m_data.color, damage, m_data.round, m_data.roundingPower);
|
||||
g_pHyprOpenGL->renderRect(m_data.box, m_data.color, {.damage = &damage, .round = m_data.round, .roundingPower = m_data.roundingPower});
|
||||
else
|
||||
g_pHyprOpenGL->renderRectWithBlur(m_data.box, m_data.color, m_data.round, m_data.roundingPower, m_data.blurA, m_data.xray);
|
||||
g_pHyprOpenGL->renderRect(m_data.box, m_data.color,
|
||||
{.round = m_data.round, .roundingPower = m_data.roundingPower, .blur = true, .blurA = m_data.blurA, .xray = m_data.xray});
|
||||
|
||||
g_pHyprOpenGL->m_renderData.clipBox = {};
|
||||
}
|
||||
|
@@ -116,14 +116,38 @@ void CSurfacePassElement::draw(const CRegion& damage) {
|
||||
// to what we do for misaligned surfaces (blur the entire thing and then render shit without blur)
|
||||
if (m_data.surfaceCounter == 0 && !m_data.popup) {
|
||||
if (BLUR)
|
||||
g_pHyprOpenGL->renderTextureWithBlur(TEXTURE, windowBox, ALPHA, m_data.surface, rounding, roundingPower, m_data.blockBlurOptimization, m_data.fadeAlpha, OVERALL_ALPHA);
|
||||
g_pHyprOpenGL->renderTexture(TEXTURE, windowBox,
|
||||
{
|
||||
.surface = m_data.surface,
|
||||
.a = ALPHA,
|
||||
.blur = true,
|
||||
.blurA = m_data.fadeAlpha,
|
||||
.overallA = OVERALL_ALPHA,
|
||||
.round = rounding,
|
||||
.roundingPower = roundingPower,
|
||||
.allowCustomUV = true,
|
||||
.blockBlurOptimization = m_data.blockBlurOptimization,
|
||||
});
|
||||
else
|
||||
g_pHyprOpenGL->renderTexture(TEXTURE, windowBox, ALPHA * OVERALL_ALPHA, rounding, roundingPower, false, true);
|
||||
g_pHyprOpenGL->renderTexture(TEXTURE, windowBox,
|
||||
{.a = ALPHA * OVERALL_ALPHA, .round = rounding, .roundingPower = roundingPower, .discardActive = false, .allowCustomUV = true});
|
||||
} else {
|
||||
if (BLUR && m_data.popup)
|
||||
g_pHyprOpenGL->renderTextureWithBlur(TEXTURE, windowBox, ALPHA, m_data.surface, rounding, roundingPower, true, m_data.fadeAlpha, OVERALL_ALPHA);
|
||||
g_pHyprOpenGL->renderTexture(TEXTURE, windowBox,
|
||||
{
|
||||
.surface = m_data.surface,
|
||||
.a = ALPHA,
|
||||
.blur = true,
|
||||
.blurA = m_data.fadeAlpha,
|
||||
.overallA = OVERALL_ALPHA,
|
||||
.round = rounding,
|
||||
.roundingPower = roundingPower,
|
||||
.allowCustomUV = true,
|
||||
.blockBlurOptimization = true,
|
||||
});
|
||||
else
|
||||
g_pHyprOpenGL->renderTexture(TEXTURE, windowBox, ALPHA * OVERALL_ALPHA, rounding, roundingPower, false, true);
|
||||
g_pHyprOpenGL->renderTexture(TEXTURE, windowBox,
|
||||
{.a = ALPHA * OVERALL_ALPHA, .round = rounding, .roundingPower = roundingPower, .discardActive = false, .allowCustomUV = true});
|
||||
}
|
||||
|
||||
if (!g_pHyprRenderer->m_bBlockSurfaceFeedback)
|
||||
|
@@ -37,9 +37,12 @@ void CTexPassElement::draw(const CRegion& damage) {
|
||||
}
|
||||
|
||||
if (m_data.blur)
|
||||
g_pHyprOpenGL->renderTextureWithBlur(m_data.tex, m_data.box, m_data.a, nullptr, m_data.round, m_data.roundingPower, false, m_data.blurA, 1.F);
|
||||
g_pHyprOpenGL->renderTexture(
|
||||
m_data.tex, m_data.box,
|
||||
{.a = m_data.a, .blur = true, .blurA = m_data.blurA, .overallA = 1.F, .round = m_data.round, .roundingPower = m_data.roundingPower, .blockBlurOptimization = false});
|
||||
else
|
||||
g_pHyprOpenGL->renderTextureInternalWithDamage(m_data.tex, m_data.box, m_data.a, m_data.damage.empty() ? damage : m_data.damage, m_data.round, m_data.roundingPower);
|
||||
g_pHyprOpenGL->renderTexture(m_data.tex, m_data.box,
|
||||
{.damage = m_data.damage.empty() ? &damage : &m_data.damage, .a = m_data.a, .round = m_data.round, .roundingPower = m_data.roundingPower});
|
||||
}
|
||||
|
||||
bool CTexPassElement::needsLiveBlur() {
|
||||
|
Reference in New Issue
Block a user