[과제] 3주차) ThorVG 활용사례 조사 정선용 #96
jeongsunyong
started this conversation in
Blog
Replies: 2 comments 2 replies
|
깃헙주소 링크가 깨져서 확인이 필요할 것 같습니다! |
1 reply
|
안녕하세요~ 상세한 분석이군요 :) |
1 reply
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
DALi에 통합된 ThorVG: 역할과 렌더링 구조
코드로 확인한 DALi의 벡터 그래픽 backend 통합 사례
ThorVG가 실제 제품과 오픈소스 프로젝트에 어떻게 통합되는지 확인하기 위해
Tizen의 UI 프레임워크인 NUI와 그 기반 그래픽 프로젝트 DALi를 조사했다.
Tizen UI 개발자는
View,ImageView,CanvasView같은 NUI API를 사용하고,그 아래에서는 오픈소스 프로젝트인 DALi가 UI 장면과 렌더링을 처리하는데,
과제에서는 TizenFX, DALi Toolkit, DALi Adaptor와 ThorVG의 공개 코드를 기준으로,
ThorVG가 DALi의 어느 지점에 연결되고 어떤 역할을 담당하는지 정리한다.
1. DALi와 ThorVG의 역할
DALi는 Tizen에서 UI 장면을 구성하고 화면에 합성하는 그래픽 프레임워크다.
View의 배치와 상태, 렌더링 리소스, 애니메이션과 최종 GPU 렌더링을 관리한다.
ThorVG와 DALi는 모두 화면을 그리는 그래픽 엔진이다.
최근에 thorVG를 접하게되면서 이 그래픽 엔진이라는 측면에서 겹치는 부분들이 있다고 생각이 들었고, 굳이 백엔드를 두 개 쓰는 이유가 있을까 의문이 들었다.
그러나 둘은 다루는 범위가 다르다.
ThorVG는 DALi의 그래픽 전체를 대신하지 않는다.
DALi는 Tizen에서 UI 장면 전체를 관리하는 그래픽 프레임워크이고 View의 배치와 상태, 애니메이션, 렌더링 리소스를 관리하고 최종적으로 화면을 GPU에서 합성하지만,
ThorVG는 SVG와 Lottie를 해석하거나 도형과 경로를 그리는 벡터 그래픽 엔진이다. DALi처럼 UI 장면 전체를 관리하지는 않지만, 벡터 콘텐츠를 표현하는 데 필요한 path, fill, stroke와 같은 기능과 이를 픽셀로 변환하는 래스터라이저를 제공한다.
일반적인 DALi View는 DALi가 구성한 Geometry와 Shader를 통해 GPU에서 직접 렌더링된다. 반면 CanvasView의 Shape와 Picture, SVG Visual 같은 벡터 콘텐츠는 ThorVG가 픽셀 버퍼로 래스터라이즈한다. DALi는 이 결과를 Texture로 받아 다른 UI 요소와 함께 최종 화면에 합성한다.
따라서 두 라이브러리의 관계는 다음처럼 구분할 수 있다.
2. DALi와 ThorVG의 역할 - example
DALi에서 Rounded Corner의 Rect를 배치한다던지, Stroke를 그린다던지 할 때 사용하는
CornerRadius,Borderline, gradient, masking은 벡터 그래픽과 비슷해 보이지만 모두 ThorVG가 처리하는 것은 아니다.DALi의 일반 View는 대부분 ThorVG를 거치지 않는다.
예를 들어 NUI View에 배경색, 둥근 모서리와 테두리를 지정하면

Toolkit은 ColorVisual과
DecoratedVisualRenderer를 구성한다.DALi는 사각형 Geometry와 속성값을 GPU shader에 전달하고, fragment shader가 둥근 영역과 테두리를 계산한다.
일반
GradientVisual과 ImageVisual의 alpha mask도 DALi 전용 shader 경로를 사용할 수 있다.** 일반 Visual은 DALi shader 경로를 사용한다.
color-visual-shader-factory.cpp—COLOR_SHADER_BORDERLINE,COLOR_SHADER_ROUNDED_BORDERLINEimage-visual-shader-feature-builder.cpp—ALPHA_MASKING,BORDERLINEgradient-visual.cpp— linear/radial/conic 및 rounded-corner 조합일반 View의 배경·모서리·테두리는 위 처럼 ThorVG를 거치지 않고 DALi가 Geometry와 Shader로 구성해 GPU에서 직접 그린다
반면 아래 콘텐츠는 정해진 사각형 shader만으로 처리하기 어렵다.

MoveTo,LineTo,CubicTo로 만드는 임의 pathDALi는 이 범용 벡터 콘텐츠를 직접 해석하고 rasterization하는 대신 ThorVG를 사용한다.
현재 DALi 코드는 ThorVG를 일반 SVG Visual뿐 아니라 CanvasRenderer Shape와 Picture, vector animation에도 공통으로 사용한다.
3. ThorVG는 DALi Adaptor에 통합되어 있다
DALi 공개 코드는 역할에 따라 Core, Adaptor, Toolkit으로 나뉜다. 이 구분을 모두
상세히 알 필요는 없지만, ThorVG의 위치를 이해하려면 Adaptor가 중요하다.
CanvasView와 SVG Visual 같은 상위 UI 기능 및 작업 일정을 관리한다.실제 ThorVG 의존성과 구현 코드는 주로 DALi Adaptor에서 확인된다.
즉 Toolkit이 벡터 렌더링 작업을 요청하면 Adaptor가 ThorVG를 호출하고,
결과 버퍼가 다시 DALi의 Texture로 전달되는 구조다.
(최종 composite은 DALi에서.)
4.
Shape.AddRect()로 본 실제 호출 흐름 : Dali 객체는 ThorVG객체를 어떻게 사용하는지.DALi의
CanvasRenderer는 ThorVG 객체를 DALi API로 감싸 제공하는데,DALi Adaptor는 ThorVG를 필요한 순간에 함수만 호출하는 유틸리티처럼 사용하지 않는다.
DALi의
CanvasRenderer객체가 대응하는 ThorVG 객체를 내부에 보관하고, NUI에서들어온 요청을 ThorVG API로 전달하는 어댑터 역할을 한다.
Shapetvg::ShapePicturetvg::PictureDrawableGrouptvg::SceneCanvasRenderertvg::SwCanvasadaptor가 연결하는 것을 확인해보면,
Shape::Initialize()에서 DALi Adaptor는tvg::Shape를 생성해,DALi
Drawable의 내부 객체로 등록한다.두 객체는 호출할 때마다 임시 변환되는 관계가 아니고,
DALi Shape가
mTvgShape를 보관하고 이후 도형과 스타일 변경 요청을 이 객체로 전달한다.이 대응 관계에서 DALi는 객체의 수명과 갱신 시점을 관리하고, 실제 벡터 데이터는 ThorVG 객체가 가진다.
Shape.AddRect()의 호출 경로를 따라가면 이 구조를 구체적으로 확인할 수 있다.NUI에서 둥근 사각형을 추가하는 작업은
Shape.AddRect()호출로 시작한다.(TizenFX)TizenFX의
Shape.AddRect()는 직접 도형을 그리지 않고 네이티브 DALi 호출로 요청을 전달한다.DALi Adaptor의 실제
Shape::AddRect()는mTvgShape를tvg::Shape로 사용해 ThorVG의appendRect()를 호출하고, 성공하면SetChanged(true)로 갱신이 필요하다는 상태도 기록한다.DALi가 사각형의 벡터 Path를 별도로 계산하는 것이 아니라, API 요청과 변경 상태를 관리하면서 실제 Path 구성은 보관 중인 ThorVG 객체에 위임하는 구조.
네이티브 요청을 받은 DALi Adaptor의 Shape 구현은 내부에서 관리하는 ThorVG Shape에 같은 좌표와 반지름을 전달한다.
전체 호출 관계를 정리하면 다음과 같다.
이 호출만으로 화면에 즉시 픽셀이 그려지는 것은 아니고.
appendRect()는 ThorVG의 벡터 장면에 사각형 Path를 추가하는 단계다.이후 DALi가 CanvasView의 갱신과 래스터라이즈 작업을 예약하면 ThorVG가 장면을 픽셀 버퍼로 변환하고, DALi는 그 결과를 Texture로 받아 다른 UI 요소와 함께 최종 화면에 합성한다.
Shape.AddRect()Shape::AddRect()CanvasViewShape::appendRect()5. SVG에서 ThorVG가 사용되는 두 경로
DALi의 SVG는 크게 두 경로에서 ThorVG를 사용한다.
CanvasRenderer Picture 경로
NUI의
CanvasView에서는Picture를 Shape와 같은 Drawable로 추가할 수 있다.Picture.Load()는 P/Invoke를 통해 DALi의 네이티브 Picture 구현을 호출한다.DALi Adaptor는
tvg::Picture를 생성해 DALi의 Drawable 내부 객체로 등록하고, 파일 경로를 ThorVG의load()에 직접 전달한다.로드한 Picture는
CanvasView.AddDrawable()을 통해 CanvasRenderer에 전달된다. DALi Toolkit의CanvasView는 이 요청을 내부CanvasRenderer로 넘긴다.따라서 이 경로에서 SVG는 독립적인 이미지 한 장이 아니라 Canvas를 구성하는 Drawable 중 하나다. 같은 Canvas에 Shape나 다른 Picture를 추가해 함께 래스터라이즈할 수 있다.
SVG Visual 경로
SVG 한 장을 일반 이미지처럼 표시할 때는
ImageView에 파일 경로를 지정할 수 있다.ImageView는 URL을 DALi에 전달하고, Toolkit의 VisualFactory는 URL 형식을 확인해 SVG인 경우SvgVisual을 생성한다.이후 Toolkit의 SVG Visual 파이프라인이 비동기 로딩, 캐시, 크기 계산과 Texture 생성 과정을 관리한다. Toolkit이 생성한
VectorImageRenderer는 Adaptor에서 다시tvg::Picture를 만들고, 파일 경로가 아니라 메모리에 읽어 둔 SVG 데이터와 형식 문자열을 전달한다.두 경로 모두 최종적으로 ThorVG
Picture::load()에 도달하며, SVG 해석과 벡터 래스터라이즈는 ThorVG가 담당한다. 다만CanvasRenderer::Picture경로는 SVG를 Shape나 다른 Picture와 조합할 수 있는 Canvas의 구성 요소로 사용하고, SVG Visual 경로는 SVG 한 장을ImageView의 이미지 리소스로 표시하는 데 사용한다.이러한 사용 목적의 차이에 따라 ThorVG 앞에 놓인 DALi의 관리 방식도 달라진다.
CanvasRenderer::Picture는 파일 경로를 직접 전달하고 Canvas의 다른 Drawable과 함께 관리한다. 반면 SVG Visual은 Toolkit의 비동기 작업과 캐시를 거친 메모리 데이터를 전달하고, 래스터라이즈 결과를 Texture로 관리한다.6. ThorVG 빌드 통합
Tizen용 DALi Adaptor spec은
pkgconfig(thorvg)를BuildRequires로 선언한다.빌드 과정에서 ThorVG를 찾으면
THORVG_SUPPORT가 정의되고,설치된 ThorVG API에 따라
THORVG_VERSION_0또는THORVG_VERSION_1분기가 선택된다.이 매크로는 단순히 header include 여부만 결정하지 않는다.
CanvasRenderer의 ThorVG 구현 전체와 VectorImageRenderer의 SVG backend 선택에 사용된다.
ThorVG 지원이 없는 빌드에서 SVG VectorImageRenderer는 NanoSVG 구현으로 분기하지만, Tizen 패키지는 ThorVG를 빌드 의존성으로 요구한다.
빌드 연결 지점
packaging/dali-adaptor.spec-BuildRequires: pkgconfig(thorvg)build/tizen/deps-check.cmake-THORVG_SUPPORT,THORVG_VERSION_0/1vector-image-renderer-impl.cpp7. 정리
DALi는 개발자 API와 비동기 작업, 캐시, 네이티브 버퍼를 관리하고 최종 GPU 합성을 담당한다.
SVG, Lottie, 임의 Path처럼 범용적인 벡터 처리가 필요한 콘텐츠는 ThorVG의 Shape와 Picture로 구성하고, SwCanvas를 통해 픽셀 버퍼로 래스터라이즈한다. DALi는 이 결과를 Texture로 연결해 기존 렌더링 파이프라인에서 다른 UI 요소와 함께 합성하는 방식으로 ThorVG를 통합했다.
이러한 역할 분리 덕분에 DALi는 기존 UI 렌더링 구조를 유지하면서도 SVG, Lottie, 임의 Path, fill과 stroke 같은 벡터 그래픽 기능을 활용할 수 있다.
All reactions