TL;DR

  • labwc가 wlroots-0.20에서 제공되지 않는 ext-background-effect-v1 프로토콜을 구현하고 SceneFX 0.5로 요청 영역의 실제 배경 흐림을 렌더링함.
  • 프로토콜 상태를 wl_surface.commit에 반영하고, 영역별 흐림 노드를 관리하며 보안 컨텍스트 클라이언트에도 전역 객체를 제공함.
  • rc.xml의 <blur> 설정에 렌더링 패스, 반경, 노이즈, 밝기, 대비, 채도를 포함하고 시작 시 적용 및 SIGHUP 재로드를 지원함.
  • 장식 테두리(SSD)가 흐림 효과 위에 유지되도록 노드 트리를 조정하고, 분수 배율에서 장식이 없는 표면에 생기는 흐림 번짐을 보정함.
  • 중첩 인스턴스와 전용 클라이언트, 헤드리스 검증에서 흐림 영역 변경·해제와 배율별 렌더링 결과를 확인함.

프로토콜 지원과 SceneFX 렌더링

  • wayland-protocols 스테이징 프로토콜인 ext-background-effect-v1 지원을 구현함. 기반 구현은 wlroots에 병합된 코드를 따르며, 해당 기능이 없는 wlroots-0.20을 사용하는 labwc로 이식함.
  • ext_background_effect_manager_v1을 흐림 기능과 함께 광고하고, 표면별 대기·현재 흐림 영역을 추적해 wl_surface.commit에서 적용함. 상태는 wlr_surface_synced를 통해 더블 버퍼링됨.
  • background_effect_exists 및 surface_destroyed 오류를 적용하고, 보안 컨텍스트 클라이언트에도 전역 객체를 허용함.
  • 초기 구현은 프로토콜 상태만 추적했으며, 장면 그래프(scene graph) 렌더링 중 표면 뒤 영역을 흐리게 처리할 wlroots 훅이 없어 실제 흐림은 후속 작업으로 남아 있었음.
  • 이후 wlr_scene API의 대체 구현인 SceneFX 0.5를 사용해 클라이언트가 요청한 영역을 실제로 흐리게 렌더링함. 관련 커밋은 [SceneFX로 ext-background-effect-v1 흐림 영역 렌더링]( /labwc/labwc/pull/3751/commits/d888075fdc89140d245117fcb3c57cbbdf16fdea)임.
  • libscenefx-0.5를 libwlroots-0.20보다 먼저 링크하고 SceneFX 헤더를 사용함. 두 라이브러리가 같은 wlr_scene_* 심볼을 내보내므로 링크 순서가 선택을 결정함.
  • fx_renderer_create()로 렌더러를 생성함. SceneFX는 자체 GLES2 렌더러를 요구함.
  • 각 wl_surface.commit에서 커밋된 흐림 영역의 pixman 사각형마다 wlr_scene_blur 노드를 하나씩 유지함. 노드는 창 아래를 흐리게 하면서 창 콘텐츠 아래에 있도록 표면을 담은 장면 트리의 맨 아래로 내림.
  • 흐림 영역, 트리 또는 표면 노드 오프셋이 바뀐 경우에만 노드를 다시 만들고, 영역이 비워지거나 표면이 매핑 해제되면 제거함. 표면의 장면 노드 렌더링 정보를 캐시해 매 커밋마다 장면 그래프를 검색하지 않으며, 표면 소멸 신호에서 캐시를 무효화함.

설정과 개발 환경

  • rc.xml에 패스, 반경, 노이즈, 밝기, 대비, 채도, 강도를 지정하는 <blur> 섹션을 추가함. 설정은 시작 시 적용되고 SIGHUP에서 다시 읽히며 labwc-config(5)에 문서화됨.
  • 장면 그래프 덤프와 창 전환기 썸네일이 SceneFX 노드 유형을 처리하도록 함.
  • SceneFX 렌더링에 빌드 시 libscenefx-0.5가 필요하므로 CI 컨테이너에 의존성을 설치함. 대상 배포판 패키지는 Arch의 scenefx, Debian의 libscenefx-0.5-dev(testing), FreeBSD의 scenefx05, Void Linux의 scenefx-devel임.
  • CI 실행기에 DRM 렌더 노드가 없어 GLES2 렌더러를 만들지 못하는 문제를 처리함. wlroots 소프트웨어 렌더러를 강제하고 dmabuf 할당에 필요한 /dev/udmabuf를 컨테이너에 전달하며, Void-musl에는 Mesa DRI 드라이버를 설치함.
  • dmabuf 텍스처의 피치가 16의 배수가 아닐 때 llvmpipe에서 발생하는 일반 보호 예외(GP) 문제를 피하려고 정렬된 Adwaita 커서 테마를 사용함.

장식 테두리와 흐림 번짐 보정

  • SceneFX의 흐림 노드는 분수 출력 배율에서 렌더링 클립을 올림 처리하므로 자체 상자보다 약 1~2 버퍼 픽셀 바깥까지 칠할 수 있음. clipped_region은 흐림 렌더링에서 읽히지 않아 wlr_scene_blur_set_clipped_region()으로 번짐을 막을 수 없음.
  • 흐림 노드가 SSD 트리 위에 놓였을 때, 표면에 맞닿은 테두리 영역이 덮이는 문제가 발생함. 각 뷰에 SSD보다 아래에 놓이는 전용 blur_tree를 두고 이를 뷰 장면 트리의 최하단 자식으로 배치함. SSD가 재생성되는 경우에도 SSD가 흐림 위에 남도록 다시 순서를 조정함. 뷰가 소유하지 않는 표면은 기존 배치를 유지함.
  • 관련 수정은 [SSD 테두리를 ext-background-effect 흐림 노드 위에 유지]( /labwc/labwc/pull/3751/commits/0dcf8e48e072c82a1ff9507ca38044b598115686)임.
  • SSD가 없는 레이어 셸 표면(바·도크)과 CSD 뷰에서는 약 1픽셀의 흐린 후광이 윤곽을 따라 나타날 수 있음. 직사각형 계단으로 둥근 모양을 근사하는 클라이언트에서는 현상이 더 두드러짐.
  • 분수 배율이 1보다 크고 2보다 작은 출력에서, SSD가 번짐을 가리지 않는 경우에만 흐림 노드를 만들기 전에 요청 영역의 바깥 윤곽을 논리 픽셀 하나만큼 침식시킴. 침식은 사각형들의 합집합을 기준으로 계산해 같은 영역 내 인접 사각형의 공유 경계는 유지함. 배율 2 이상에서는 침식 비용이 두 경계 행으로 늘어나므로 보정을 적용하지 않음.
  • 출력 배율 변경 뒤 클라이언트가 흐림 영역을 다시 커밋하지 않을 수 있어 output_update_for_layout_change()에서 활성 표면 전체를 재평가함. 관련 수정은 [SSD가 없는 표면의 SceneFX 흐림 번짐 보정]( /labwc/labwc/pull/3751/commits/1d2cb20e62f62149f37985534b623f5b0b3c3c6c)임.

검증 결과

  • 중첩 인스턴스와 전용 클라이언트에서 전체 480x320 영역 흐림, 120x80으로 축소, 영역 전체 해제를 확인했으며 렌더링 결과가 각 변경을 반영함. <blur> 설정 변경도 SIGHUP에서 적용됨.
  • 체커보드 배경과 배율 1.25의 헤드리스 검증에서 Noctalia 바·도크 바깥 첫 행의 표준편차가 흐림 번짐 상태의 약 1에서 선명한 상태의 약 90~100으로 바뀌었으며, 표면 내부는 1029/582개 열 중 선명한 열이 0개로 완전히 흐려진 상태임.
  • 배율 1.0에서는 출력 변화가 없었음. SSD 경로에서는 기준 테두리 링 값 98/100/99/100과 흐림 가시성 지표 6.37이 보정 전후 동일했으며, 대화형 검사도 통과함.