zccrs
deepin
2025-04-29 09:45 #if KWIN_VERSION_MIN > 17 || (KWIN_VERSION_MIN == 17 && KWIN_VERSION_PAT > 5)
void ScissorWindow::drawWindow(KWin::EffectWindow *w, int mask, const QRegion &_region, KWin::WindowPaintData &data)
{
QRegion region = _region;
#else
void ScissorWindow::drawWindow(KWin::EffectWindow *w, int mask, QRegion region, KWin::WindowPaintData &data)
{
#endif
// 工作区特效会使用PAINT_WINDOW_LANCZOS绘制,此时不支持多次调用Effect::drawWindow,
// 否则只会显示第一次调用绘制的内容, 因此在这种模式下禁用掉窗口裁剪特效
if (!w->isPaintingEnabled() || (mask & PAINT_WINDOW_LANCZOS) || w->isDesktop()) {
return Effect::drawWindow(w, mask, region, data);
}
MaskCache::TextureData mask_texture = MaskCache::instance()->getTextureByWindow(w);
if (!mask_texture) {
return Effect::drawWindow(w, mask, region, data);
}
QRegion corner_region;
if (!mask_texture->customMask) {
const QRect window_rect = w->geometry();
QRect corner_rect(window_rect.topLeft(), mask_texture->size);
// top left
corner_region += corner_rect;
// top right
corner_rect.moveRight(window_rect.right());
corner_region += corner_rect;
// bottom right
corner_rect.moveBottom(window_rect.bottom());
corner_region += corner_rect;
// bottom left
corner_rect.moveLeft(window_rect.left());
corner_region += corner_rect;
// 本次绘制未包含圆角区域时则直接按原有的行为渲染
if ((region & corner_region).isEmpty()) {
return Effect::drawWindow(w, mask, region, data);
}
// 窗口发生几何转换时不能拆分绘制窗口的区域,否则会导致两个区域不契合,例如开启wobbly windows窗口特效,
// 移动窗口时会导致窗口圆角出现毛刺
if (mask & PAINT_WINDOW_TRANSFORMED) {
corner_region = QRegion();
}
}
KWin::WindowQuadList decoration_quad_list;
KWin::WindowQuadList content_quad_list;
for (const KWin::WindowQuad &quad : data.quads) {
switch (quad.type()) {
case KWin::WindowQuadShadow:
case KWin::WindowQuadDecoration:
decoration_quad_list.append(quad);
break;
case KWin::WindowQuadContents:
content_quad_list.append(quad);
break;
default:
break;
}
}
if (!mask_texture->customMask) {
// 此时只允许绘制窗口边框和阴影
// 针对设置了自定义裁剪的窗口,则不绘制标题栏和阴影
data.quads = decoration_quad_list;
if (KWin::effects->waylandDisplay()) {
if (!w->isDock()) {
Effect::drawWindow(w, mask, region, data);
}
} else {
Effect::drawWindow(w, mask, region, data);
}
}
if (!corner_region.isEmpty()) {
QRegion new_region = region - corner_region;
// 先绘制未处于mask区域的窗口材质
if (!new_region.isEmpty()) {
data.quads = content_quad_list;
Effect::drawWindow(w, mask, new_region, data);
}
// 重新设置要绘制的区域
region = region - new_region;
}
// 将mask材质绑定到第二个材质
glActiveTexture(GL_TEXTURE1);
mask_texture->bind();
// 对于窗口圆角的材质,由于其需要被访问材质范围外的像素,在此设置范围外材质的颜色
// 其中alpha通道为1表示此处的窗口像素完全显示
if (!mask_texture->customMask) {
float borderColor[] = { 1.0f, 1.0f, 1.0f, 1.0f };
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
}
// 重新激活第一个材质
glActiveTexture(GL_TEXTURE0);
// 激活着色器
KWin::GLShader *shader = mask_texture->customMask ? m_fullMaskShader : m_shader;
KWin::ShaderManager::instance()->pushShader(shader);
shader->setUniform("mask", 1);
if (!mask_texture->customMask) {
shader->setUniform("scale", QVector2D(w->width() / qreal(mask_texture->size.width()), w->height() / qreal(mask_texture->size.height())));
}
// 此时只允许绘制窗口内容
auto old_shader = data.shader;
data.quads = content_quad_list;
data.shader = shader;
#ifndef DISBLE_DDE_KWIN_XCB
class SetWindowDepth {
public:
SetWindowDepth(KWin::EffectWindow *w, int depth)
: m_window(w)
{
// 此时正在进行窗口绘制,会有大量的调用,应当避免窗口发射hasAlphaChanged信号
QSignalBlocker blocker(w->parent());
Q_UNUSED(blocker)
KWinUtils::setClientDepth(w->parent(), depth);
}
~SetWindowDepth() {
bool ok = false;
int depth = m_window->data(WindowDepthRole).toInt(&ok);
QObject *client = m_window->parent();
if (!ok) {
depth = KWinUtils::getWindowDepth(client);
// 保存以便下次使用
m_window->setData(WindowDepthRole, depth);
}
// 此时正在进行窗口绘制,会有大量的调用,应当避免窗口发射hasAlphaChanged信号
QSignalBlocker blocker(client);
Q_UNUSED(blocker)
KWinUtils::setClientDepth(client, depth);
}
private:
KWin::EffectWindow *m_window;
};
// 要想窗口裁剪生效,必须要保证窗口材质绘制时开启了alpha通道混合
if (!w->hasAlpha()) {
SetWindowDepth set_depth(w, 32);
Q_UNUSED(set_depth)
Effect::drawWindow(w, mask, region, data);
} else
#endif
{
Effect::drawWindow(w, mask, region, data);
}
data.shader = old_shader;
KWin::ShaderManager::instance()->popShader();
// 解除材质绑定
glActiveTexture(GL_TEXTURE1);
mask_texture->unbind();
glActiveTexture(GL_TEXTURE0);
}
你看的哪个版本?
Reply Like 0 View the author
绑定的是纹理块2,解绑的时候确在纹理块0执行,有没有大佬告诉我为什么
