본문 바로가기

# 02/Flutter

[Flutter] Impeller - Flutter의 새로운 렌더링 엔진

반응형

Flutter의 렌더링 방식

 

React Native는 자바스크립트 브릿지를 통해 플랫폼과 통신합니다. 플랫폼의 네이티브 컴포넌트(OEM 위젯)를 그대로 사용하기 때문에 플랫폼 별 유아이가 다르게 그려질 수 있고 플랫폼과 React Native 간 통신을 할 때 필요한 리소스 비용이 상당히 높습니다.

Flutter는 바로 캔버스에 그림을 그리듯이 표현하고, 필요한 제스처 및 이벤트를 브릿지를 통하지 않고 바로 실행하기 때문에 속도가 빠른 편입니다.

Flutter는 Skia 엔진을 이용해서 프레임 워크단에서 유아이를 직접 그리기 때문에 디바이스에 제한 없이 동일한 화면으로 렌더링이 가능합니다. 따라서 iOS에서 Material 디자인을, Android에서 Cupertino 디자인을 쉽게 구현할 수 있습니다.

 

Skia 엔진이란?

Skia는 다양한 하드웨어 및 소프트웨어 플랫폼에서 공통 API를 제공하는 오픈 소스 2D 그래픽 라이브러리입니다.

구글 크롬, Chrome OS, Android, Flutter, Firefox, Firefox OS 등 많은 다른 제품들의 그래픽 엔진 역할을 합니다.

 

 

Skia는 C++로 개발된 오픈 소스 2D 그래픽 라이브러리로 OpenGL의 Canvas를 사용해 렌더링을 합니다.

Skia가 Flutter의 그래픽 엔진으로 채택될 수 있었던 이유는 OpenGL을 사용하기 때문입니다. OpenGL은 그래픽 라이브러리 중 하나로써, 윈도우와 Mac 뿐 만 아니라 모든 운영체제에서 사용할 수 있습니다. 이것이 Flutter가 크로스플랫폼이 될 수 있었던 핵심 요소 중 하나 입니다.

Flutter에서 그려지는 모든 것은 Skia를 통해 그려지는 것이고, Skia는 OpenGL를 통해 렌더링을 합니다.

 

 

렌더러는 UI 코드를 실제로 화면에 표시되는 픽셀로 변환하는 소프트웨어 입니다.

 

 

예를 들어서 Flutter Logo 를 화면에 그린다고 하면 작성한 위젯트리 코드가 있을 것이고 Flutter 프레임워크는 위젯트리를 기반으로 렌더링 트리를 만듭니다. 렌더링 개체에는 실제로 위젯의 위치, 레이아웃, 스타일, 그래픽 효과 등이 포함되어 있습니다. 이러한 명령은 엔진에 제공되며 Display List 라는 간단한 명령 목록에 저장됩니다.

 

 

Display List의 모든 항목을 GPU를 활용하여 Render Pipeline 모음으로 설정합니다.

 

 

Render Pipeline을 사용하려면 먼저 Display List가 그린 모든 경로를 가져와 삼각형 세트로 테셀레이션 해야 합니다.

 

 

 

그런 다음 shader 라는 것을 생성해주는데 shader는 최종 사용자의 장치에서 사용 할 수 있는 GPU에서 컴파일하여 실행할 프로그램입니다.

 

 

 

Skia 엔진에서의 문제점

GPU에 명령을 보내는 코드 조각인 shader가 처음 실행될 때 GPU가 실행할 수 있는 명령으로 컴파일 되어야 하는데 이 과정은 비용이 많이 소모됩니다. Skia 엔진 에서는 이 컴파일 프로세스는 런타임에 프레임에서 바로 발생합니다. 파이프라인은 실제로 무언가를 렌더링하는데 사용해야 하는데 shader 로 인해 일반적으로 프레임이 예산을 초과하여 눈에 띄는 끊김 현상이 발생합니다. 이것을 shader 컴파일 jank 라고 합니다.

 

 

 

Impeller 란?

Flutter 3.10에서 Impeller는 Skia를 대체하고 iOS의 기본 렌더링 엔진이 되었습니다.

Impeller는 이 컴파일에서 가장 비용이 많이 드는 부분을 미리 수행하여 이문제를 크게 개선했습니다.

 

 

Impeller는 각 계층이 작업을 수행하기 위해 그 아래 계층을 사용하는 계층화 된 아키텍처가 있습니다. Aiks는 Impeller의 최상층이고 Skia 스펠링을 뒤집은 것 입니다. Aiks는 Display List에서 경로 그리기 및 이미지 그리기와 같은 높은 수준의 명령을 가져와 엔티티라고 하는 더 간단하고 독립적인 그리기 작업으로 바꿔줍니다. 엔티티를 그리는데 필요한 실제 GPU 명령이 포함된 콘텐츠 개체가 할당됩니다. 여러 전문 콘텐츠가 있고 Aiks가 가장 효율적인 렌더링 알고리즘을 선택하여 할당합니다.

 

Impeller는 이러한 셰이더 컴파일 jank 문제를 크게 개선하기 위해 가장 비용이 많이 드는 컴파일 단계를 사전에 수행합니다. Flutter 엔진이 구동될 때, Impeller의 모든 셰이더는 Impeller 씬이라는 오프라인 셰이더 컴파일러를 통해 번들로 미리 컴파일됩니다. 하지만 미리 컴파일된 여러 셰이더를 초기화하면 시작 시간이 느려지거나 플러터 앱 크기가 커질 수 있다는 점을 걱정할 수 있습니다. 이를 방지하기 위해 Impeller는 Skia가 동적으로 생성하는 많은 특수 셰이더에 비해 훨씬 작고 단순한 셰이더 세트를 활용하는 대체 렌더링 기술을 사용합니다.

Impeller는 Flutter용으로 맞춤 제작되었으며 Flutter 엔진의 핵심 부분을 크게 재작성 하여 이전 Skia 코드를 iOS의 Metal 및 Vulkan과 같은 최신 하드웨어 가속 그래픽 API를 최대한 활용하는 맞춤 런타임으로 대체합니다.

 

 

 


https://io.google/2023/program/60b4bd9e-4159-473d-b031-edabb93d0e00/intl/ko/

https://docs.flutter.dev/perf/impeller

https://medium.com/@NGM44/impeller-flutter-8d8aba691fa3

https://davidserrano.io/impeller-is-production-ready-for-ios-dart-3-x3-web-performance-and-more-with-flutter-3-10

https://empering.tistory.com/entry/Flutter-22-%EC%83%88%EB%A1%AD%EA%B2%8C-%EC%B6%94%EA%B0%80%EB%90%9C-%EA%B2%83%EB%93%A4#b32a9ed0-a35f-4d05-a673-feca7809c283

https://www.youtube.com/watch?v=EgUwBA6rUQw&t=69s

반응형