인밸리데이션(Invalidation) 은 위젯을 다시 페인팅하는 빈도를 제한하여 UI의 CPU 사용을 줄이는 시스템입니다. 인밸리데이션 시스템 내 위젯의 레이아웃이 UI에서 변경되면 무효화됨(invalidated) 으로 표시됩니다. 그런 다음 무효화된 위젯과 그 자손만 다시 페인팅됩니다.
프로젝트에 인밸리데이션을 활용하는 방법은 두 가지입니다.
-
위젯별로 인밸리데이션을 구현하려면 인밸리데이션 박스(Invalidation Box) 와 리테이너 패널(Retainer Panel) 위젯을 사용합니다.
-
UI 전체에 인밸리데이션을 구현하려면 글로벌 인밸리데이션(Global Invalidation) 을 사용합니다.
아래 섹션에서는 인밸리데이션을 어디에 적용할지 결정할 수 있도록 프로젝트에서 인밸리데이션을 구현하는 방법과 그 작동 원리를 설명합니다.
인밸리데이션 구현 방법
인밸리데이션 박스
인밸리데이션 박스(Invalidation Box) 위젯은 자손 위젯의 지오메트리를 캐싱한 다음 그 위젯의 변경 사항을 모니터링합니다. 인밸리데이션 박스 안 위젯이 바뀌지 않는 한 슬레이트는 다시 페인팅하지 않고 캐싱된 지오메트리로 돌아가며, 이는 위젯의 CPU 사용을 크게 줄입니다.
UMG 에디터 팔레트(Palette) 의 최적화(Optimization) 섹션에서 인밸리데이션 박스 위젯을 찾을 수 있습니다.

인밸리데이션 박스(Invalidation Box)는 안에 포함된 모든 위젯과 해당 위젯의 계층구조 내 자손을 모두 처리합니다.
인밸리데이션 박스의 개념 및 세팅에 대한 자세한 내용은 인밸리데이션 박스 위젯 레퍼런스를 참조하세요.
글로벌 인밸리데이션
글로벌 인밸리데이션(Global Invalidation)은 SWindow
에서 인밸리데이션 기능을 활성화하여 사실상 전체 UI를 인밸리데이션 박스(Invalidation Box)로 감쌉니다. 이 창 안에 있는 모든 인밸리데이션 박스는 비활성화되며, SWindow
만 정보를 캐싱합니다.
Slate.EnableGlobalInvalidation
을 true로 설정하여 글로벌 인밸리데이션을 활성화할 수 있습니다.
리테이너 패널
리테이너 패널(Retainer Panel)은 모든 자손 위젯을 사용자의 화면에 렌더링하기 전에 단일 텍스처로 플래튼합니다. 또한 다음 옵션을 통해 리테이너가 렌더링되는 방식을 환경설정할 수 있습니다.
-
단계별 또는 프레임 레이트 제한 렌더링으로 각 리테이너가 서로 다른 프레임에 그려지도록 환경설정하여 슬레이트가 전체 UI를 동시에 그리지 않게 합니다.
-
각 리테이너 패널이 서로 다른 프레임 레이트를 갖도록 환경설정합니다. 예를 들어 UI의 일부분은 30FPS로, 다른 부분은 60FPS로 실행될 수 있습니다.
이 모든 기능은 단일 프레임에서 UI가 생성하는 드로 콜의 수를 절감하거나 관리하기 위한 것입니다.
리테이너 패널은 다시 페인팅될 때 높은 오버헤드를 유발하고, 개별 위젯이 인밸리데이션 박스를 사용할 때보다 더 많은 메모리를 사용합니다. 각 리테이너 패널마다 개별 위젯의 인밸리데이션 데이터를 사용하는 데다 자체 렌더 타깃까지 있기 때문입니다. UI의 CPU 사용을 줄이려면 인밸리데이션 박스부터 사용해 보는 것이 좋습니다. 드로 콜을 그래도 더 줄여야 한다면, 그 후 리테이너를 구현하여 더 압축할 수 있습니다. 이는 퍼포먼스 예산이 특히 적은 저사양 모바일 디바이스 등의 환경에서 유용합니다.
인밸리데이션의 작동 방식
위젯이 화면에 페인팅될 때는 몇 차례의 연산이 다음 순서로 발생합니다.
-
계층구조: 슬레이트가 계층구조 내에 루트 위젯과 모든 자손을 포함하는 위젯 트리를 만듭니다.
-
레이아웃: 슬레이트가 렌더 트랜스폼을 기반으로 위젯 크기와 화면상의 위치를 계산합니다.
-
페인팅: 슬레이트가 개별 위젯의 지오메트리를 계산합니다.
이 프로세스의 각 단계는 뒤따르는 모든 단계를 거쳐야 합니다. 예를 들어 레이아웃을 계산하면 페인팅 단계를 실행해야 하고, 계층구조를 다시 만들면 페인팅과 레이아웃 단계를 모두 실행해야 합니다.
인밸리데이션 시스템은 메모리에서 위의 데이터 타입을 위젯의 부모 인밸리데이션 박스에 캐싱하거나, 글로벌 인밸리데이션을 사용하는 경우 그려지는 SWindow에 캐싱합니다. 캐싱된 정보가 변경되지 않는 한, 슬레이트는 계산을 다시 하지 않고 해당 정보로 예비 전환합니다. 위젯이 변경되면 더티 목록에 추가됩니다. 렌더링되는 다음 프레임에서 모든 더티 위젯이 변경된 데이터 타입에 따라 재계산됩니다.
어떤 재계산 및 페인팅 프로세스 부분을 건너뛰는지에 따라 대응하는 인밸리데이션 타입이 있습니다.
인밸리데이션 타입 | CPU 비용 | 설명 |
---|---|---|
휘발성/비저빌리티 | 아주 낮음 | 휘발성 여부(Is Volatile) 또는 비저빌리티(Visibility) 플래그가 위젯과 그 자손에서 변경됩니다. |
페인팅(Paint) | 낮음 | 위젯의 지오메트리가 재계산됩니다. 색이나 머티리얼 등 레이아웃이 아닌 파라미터를 변경하면 발생합니다. |
레이아웃(Layout) | 보통 | 페인팅 인밸리데이션의 효과에 더해 화면상에서 위젯의 크기와 위치가 변경됩니다. 위젯의 렌더 트랜스폼을 변경하면 발생합니다. |
자손(Child) | 높음 | 레이아웃 인밸리데이션의 효과에 더해 슬레이트가 자손 위젯 목록을 리빌드합니다. 위젯과 자손의 완전한 재계산을 포함하며, 위젯에서 자손을 추가 또는 제거하면 발생합니다. |
프로젝트에 미치는 영향의 예시를 들면, 위젯의 색만 변경하는 경우 위젯에서 페인팅 인밸리데이션(Paint Invalidation) 이 트리거됩니다. 슬레이트는 자손 목록 및 레이아웃의 재구축을 건너뛰고 지오메트리만 재계산합니다. 캐싱된 레이아웃 데이터는 유효하게 유지되므로 업데이트할 필요가 없습니다.
코드 또는 시퀀서 애니메이션에서 위젯을 이동하거나 위젯의 크기를 조정하는 경우, 레이아웃 인밸리데이션(Layout Invalidation) 이 트리거됩니다. 트리거될 때마다 레이아웃 데이터(위치 및 크기)와 페인팅 데이터(위젯 지오메트리)를 포함한 위젯의 캐싱된 정보가 모두 재계산되어야 합니다. 그래도 자손 인밸리데이션보다는 훨씬 빠릅니다.
위젯의 자손을 추가하거나 제거하면 자손 인밸리데이션(Child Invalidation) 이 트리거됩니다. 자손 목록을 다시 빌드한 뒤 위젯과 전체 자손에서 레이아웃 및 페인팅 계산을 업데이트해야 합니다. 대부분의 경우 단일 프레임 비용의 가치는 있지만, UI에서 프레임마다 수행한다면 상당한 퍼포먼스 병목현상을 유발할 수 있습니다.
휘발성/비저빌리티 인밸리데이션(Volatile/Visibility Invalidation) 은 휘발성 또는 비저빌리티 플래그가 변경될 때만 적용됩니다. 이 두 상황의 경우 다음 프레임에 위젯을 다시 페인팅해야 하지만, 그렇다고 기타 데이터가 유효하지 않은 것은 아닙니다. 자세한 내용은 아래의 휘발성 위젯 섹션을 참조하세요.
인밸리데이션은 특히 자주 변경되지 않는 위젯에 적합합니다. 슬레이트가 오랜 시간 동안 캐싱된 데이터로 돌아갈 수 있어서 UI에 요구되는 방대한 CPU 로드를 줄여주기 때문입니다. 이는 MMORPG나 메뉴가 많은 라이브 서비스 게임 등의 크고 복잡한 UI를 만들 때 특히 중요합니다.
휘발성 위젯
때로는 대단히 자주, 어쩌면 프레임마다 업데이트되어야 하는 위젯을 구현해야 할 수도 있습니다. 이 경우 위젯은 변경되는 틱마다 인밸리데이션되며, 위젯이 인밸리데이션을 전혀 사용하지 않을 때와 동일한 CPU 로드를 사용하면서 위젯 지오메트리를 캐싱하는 데 필요한 메모리도 소비할 수 있습니다.
이를 해결하기 위해 자주 업데이트되는 위젯을 휘발성 위젯으로 표시할 수 있습니다. 위젯이 휘발성으로 표시되면, 인밸리데이션 시스템이 그 위젯과 그 자손의 페인팅 데이터를 캐싱하지 않습니다. 지오메트리는 프레임마다 재계산되고 다시 페인팅되지만, 슬레이트는 필요하지 않은 한 레이아웃 계산을 건너뛸 것입니다. UI 전반에 인밸리데이션을 적용하면서, 업데이트 빈도 때문에 캐싱의 이점이 없는 일부 위젯을 맞춤 설정하려는 경우에 유용합니다.
위젯을 휘발성으로 표시하려면, 위젯의 디테일 패널에서 퍼포먼스(Performance) > 휘발성 여부(Is Volatile) 세팅을 토글합니다.

C++에서 Volatile
파라미터를 true
로 설정하여 위젯을 휘발성으로 표시할 수도 있습니다.