Optimize blur massively and some fixes

This commit is contained in:
vaxerski 2022-05-09 21:37:41 +02:00
parent d70de566c4
commit ef21baaf88
3 changed files with 24 additions and 9 deletions

View file

@ -355,7 +355,7 @@ void CHyprOpenGLImpl::renderTextureInternal(const CTexture& tex, wlr_box* pBox,
// but it works... well, I guess? // but it works... well, I guess?
// //
// Dual (or more) kawase blur // Dual (or more) kawase blur
CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, wlr_box* pBox) { CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, wlr_box* pBox, pixman_region32_t* originalDamage) {
glDisable(GL_BLEND); glDisable(GL_BLEND);
glDisable(GL_STENCIL_TEST); glDisable(GL_STENCIL_TEST);
@ -375,6 +375,12 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, wlr_box* p
const auto BLURSIZE = g_pConfigManager->getInt("decoration:blur_size"); const auto BLURSIZE = g_pConfigManager->getInt("decoration:blur_size");
const auto BLURPASSES = g_pConfigManager->getInt("decoration:blur_passes"); const auto BLURPASSES = g_pConfigManager->getInt("decoration:blur_passes");
// prep damage
pixman_region32_t damage;
pixman_region32_init(&damage);
pixman_region32_copy(&damage, originalDamage);
wlr_region_expand(&damage, &damage, BLURPASSES * BLURSIZE * 2);
// helper // helper
const auto PMIRRORFB = &m_mMonitorRenderResources[m_RenderData.pMonitor].mirrorFB; const auto PMIRRORFB = &m_mMonitorRenderResources[m_RenderData.pMonitor].mirrorFB;
const auto PMIRRORSWAPFB = &m_mMonitorRenderResources[m_RenderData.pMonitor].mirrorSwapFB; const auto PMIRRORSWAPFB = &m_mMonitorRenderResources[m_RenderData.pMonitor].mirrorSwapFB;
@ -437,23 +443,24 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, wlr_box* p
// damage region will be scaled, make a temp // damage region will be scaled, make a temp
pixman_region32_t tempDamage; pixman_region32_t tempDamage;
pixman_region32_init(&tempDamage); pixman_region32_init(&tempDamage);
wlr_region_scale(&tempDamage, m_RenderData.pDamage, 1.f / 2.f); // when DOWNscaling, we make the region twice as small because it's the TARGET wlr_region_scale(&tempDamage, &damage, 1.f / 2.f); // when DOWNscaling, we make the region twice as small because it's the TARGET
drawPass(&m_shBLUR1, &tempDamage); drawPass(&m_shBLUR1, &tempDamage);
// and draw // and draw
for (int i = 1; i < BLURPASSES; ++i) { for (int i = 1; i < BLURPASSES; ++i) {
wlr_region_scale(&tempDamage, m_RenderData.pDamage, 1.f / (1 << (i + 1))); wlr_region_scale(&tempDamage, &damage, 1.f / (1 << (i + 1)));
drawPass(&m_shBLUR1, &tempDamage); // down drawPass(&m_shBLUR1, &tempDamage); // down
} }
for (int i = BLURPASSES - 1; i >= 0; --i) { for (int i = BLURPASSES - 1; i >= 0; --i) {
wlr_region_scale(&tempDamage, m_RenderData.pDamage, 1.f / (1 << i)); // when upsampling we make the region twice as big wlr_region_scale(&tempDamage, &damage, 1.f / (1 << i)); // when upsampling we make the region twice as big
drawPass(&m_shBLUR2, &tempDamage); // up drawPass(&m_shBLUR2, &tempDamage); // up
} }
// finish // finish
pixman_region32_fini(&tempDamage); pixman_region32_fini(&tempDamage);
pixman_region32_fini(&damage);
glEnable(GL_BLEND); glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
@ -463,7 +470,7 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, wlr_box* p
return currentRenderToFB; return currentRenderToFB;
} }
void CHyprOpenGLImpl::renderTextureWithBlur(const CTexture& tex, wlr_box* pBox, float a, int round) { void CHyprOpenGLImpl::renderTextureWithBlur(const CTexture& tex, wlr_box* pBox, float a, wlr_surface* pSurface, int round) {
RASSERT(m_RenderData.pMonitor, "Tried to render texture with blur without begin()!"); RASSERT(m_RenderData.pMonitor, "Tried to render texture with blur without begin()!");
if (g_pConfigManager->getInt("decoration:blur") == 0) { if (g_pConfigManager->getInt("decoration:blur") == 0) {
@ -476,11 +483,19 @@ void CHyprOpenGLImpl::renderTextureWithBlur(const CTexture& tex, wlr_box* pBox,
pixman_region32_init(&damage); pixman_region32_init(&damage);
pixman_region32_intersect_rect(&damage, m_RenderData.pDamage, pBox->x, pBox->y, pBox->width, pBox->height); // clip it to the box pixman_region32_intersect_rect(&damage, m_RenderData.pDamage, pBox->x, pBox->y, pBox->width, pBox->height); // clip it to the box
// amazing hack: the surface has an opaque region!
pixman_region32_t inverseOpaque;
pixman_region32_init(&inverseOpaque);
pixman_box32_t monbox = {0, 0, m_RenderData.pMonitor->vecSize.x, m_RenderData.pMonitor->vecSize.y};
pixman_region32_inverse(&inverseOpaque, &pSurface->current.opaque, &monbox);
pixman_region32_intersect(&damage, &damage, &inverseOpaque);
pixman_region32_fini(&inverseOpaque);
if (!pixman_region32_not_empty(&damage)) if (!pixman_region32_not_empty(&damage))
return; // if its empty, reject. return; // if its empty, reject.
// blur the main FB, it will be rendered onto the mirror // blur the main FB, it will be rendered onto the mirror
const auto POUTFB = blurMainFramebufferWithDamage(a, pBox); const auto POUTFB = blurMainFramebufferWithDamage(a, pBox, &damage);
// bind primary // bind primary
m_mMonitorRenderResources[m_RenderData.pMonitor].primaryFB.bind(); m_mMonitorRenderResources[m_RenderData.pMonitor].primaryFB.bind();

View file

@ -56,7 +56,7 @@ public:
void renderRect(wlr_box*, const CColor&); void renderRect(wlr_box*, const CColor&);
void renderTexture(wlr_texture*, wlr_box*, float a, int round = 0); void renderTexture(wlr_texture*, wlr_box*, float a, int round = 0);
void renderTexture(const CTexture&, wlr_box*, float a, int round = 0); void renderTexture(const CTexture&, wlr_box*, float a, int round = 0);
void renderTextureWithBlur(const CTexture&, wlr_box*, float a, int round = 0); void renderTextureWithBlur(const CTexture&, wlr_box*, float a, wlr_surface* pSurface, int round = 0);
void renderBorder(wlr_box*, const CColor&, int thick = 1, int round = 0); void renderBorder(wlr_box*, const CColor&, int thick = 1, int round = 0);
void makeWindowSnapshot(CWindow*); void makeWindowSnapshot(CWindow*);
@ -102,7 +102,7 @@ private:
void createBGTextureForMonitor(SMonitor*); void createBGTextureForMonitor(SMonitor*);
// returns the out FB, can be either Mirror or MirrorSwap // returns the out FB, can be either Mirror or MirrorSwap
CFramebuffer* blurMainFramebufferWithDamage(float a, wlr_box* pBox); CFramebuffer* blurMainFramebufferWithDamage(float a, wlr_box* pBox, pixman_region32_t* damage);
void renderTextureInternal(const CTexture&, wlr_box* pBox, float a, int round = 0, bool discardOpaque = false); void renderTextureInternal(const CTexture&, wlr_box* pBox, float a, int round = 0, bool discardOpaque = false);
void renderTextureWithBlurInternal(const CTexture&, wlr_box*, float a, int round = 0); void renderTextureWithBlurInternal(const CTexture&, wlr_box*, float a, int round = 0);

View file

@ -20,7 +20,7 @@ void renderSurface(struct wlr_surface* surface, int x, int y, void* data) {
scaleBox(&windowBox, RDATA->output->scale); scaleBox(&windowBox, RDATA->output->scale);
if (RDATA->surface && surface == RDATA->surface) if (RDATA->surface && surface == RDATA->surface)
g_pHyprOpenGL->renderTextureWithBlur(TEXTURE, &windowBox, RDATA->fadeAlpha * RDATA->alpha, RDATA->dontRound ? 0 : g_pConfigManager->getInt("decoration:rounding")); g_pHyprOpenGL->renderTextureWithBlur(TEXTURE, &windowBox, RDATA->fadeAlpha * RDATA->alpha, surface, RDATA->dontRound ? 0 : g_pConfigManager->getInt("decoration:rounding"));
else else
g_pHyprOpenGL->renderTexture(TEXTURE, &windowBox, RDATA->fadeAlpha * RDATA->alpha, RDATA->dontRound ? 0 : g_pConfigManager->getInt("decoration:rounding")); g_pHyprOpenGL->renderTexture(TEXTURE, &windowBox, RDATA->fadeAlpha * RDATA->alpha, RDATA->dontRound ? 0 : g_pConfigManager->getInt("decoration:rounding"));