이 글은 아래 원문을 번역한 글로 의역이 있을 수 있습니다. 정확한 의미를 파악하고 싶으신 분은 원문을 참고해주시기 바랍니다.
원문: https://developer.chrome.com/blog/renderingng-data-structures/
저작권 정보: https://developers.google.com/terms/site-policies
Display lists and paint chunks
디스플레이 항목에는 Skia로 래스터화할 수 있는 로우 레벨의 드로잉 명령(여기 참조)이 포함되어 있다. 디스플레이 항목은 테두리 또는 배경 그리기와 같은 몇 개의 도면 명령만으로 되어있어 일반적으로 간단하다. 페인트 트리 워크는 CSS 도장 순서에 따라 배치 트리 및 관련 조각 위로 반복되어 표시 항목 목록을 만든다.
예를 들면 다음과 같다.
이 HTML과 CSS는 각 셀이 표시 항목인 다음과 같은 표시 목록을 생성할 것이다.
뷰의 배경 | #blue배경 | #green배경 | #green인라인 텍스트 |
drawRect 800x600 사이즈에 화이트 컬러 | drawRect 위치 0.0에 100x100 사이즈와 파란색. | drawRect위치 8,8에 80x18 사이즈와 녹색 색상. | drawTextBlob 8,8위치. "Hello world"텍스트 |
디스플레이 아이템 리스트는 back-to-front로 주문(order)되어있다. 위의 예에서 녹색 div는 파란색 div보다 앞에 DOM 순서로 표시되지만, CSS 페인트 순서에서는 음의 z-index 파란색 div가 녹색 div(3단계) 이전(4.1단계)을 그릴 것을 요구한다. 표시 항목은 CSS 도장 순서 규격의 원자 단계에 대략 해당된다.단일 DOM 요소는 #green에 백그라운드 표시 항목과 인라인 텍스트 표시 항목이 있는 방법과 같은 여러 표시 항목을 발생시킬 수 있다.이 세분성은 마이너스 여백에 의해 생성된 인터리빙과 같은 CSS 도장 주문 명세서의 전체 복잡성을 나타내기 위해 중요하다.
이렇게 하면 각 셀이 표시 항목인 다음과 같은 표시 목록이 생성된다.
뷰의 배경 | #green배경 | #gray배경 | #green인라인 텍스트 |
drawRect 800x600 사이즈에 화이트 컬러 | drawRect 위치 8,8에 80x18 사이즈와 녹색 색상. | drawRect 위치 8,16에 35x20 사이즈와 회색. | drawTextBlob 8,8위치. "Hello world"텍스트 |
디스플레이 아이템 리스트는 저장되고 이후 업데이트에 의해 재사용된다. 도장 트리 이동 중에 레이아웃 개체가 변경되지 않은 경우, 해당 표시 항목은 이전 목록에서 복사된다. 추가 최적화는 CSS 도장 주문 명세서의 특성에 의존한다: 원자적(atomically)으로 도장을 쌓는다. 스택 컨텍스트 내에서 레이아웃 객체가 변경되지 않은 경우, 페인트 트리 워크는 스택 컨텍스트를 건너뛰고 이전 목록에서 표시 항목의 전체 시퀀스를 복사한다.
현재 속성 트리 상태는 페인트 트리 이동 동안 유지되며 표시 항목 목록은 동일한 속성 트리 상태를 공유하는 표시 항목의 "청크"로 그룹화된다. 이는 다음 예에서 입증된다.
이렇게 하면 각 셀이 표시 항목인 다음과 같은 표시 목록이 생성된다.
뷰의 배경 | #scroll배경 | #scroll인라인 텍스트 | #orange배경 | #orange인라인 텍스트 |
drawRect800x600 사이즈에 화이트 컬러 | drawRect100x100 사이즈로 포지션0.0과 컬러 핑크 | drawTextBlob위치 0,0, "Hello world". | drawRect위치 0,0에 75x200 사이즈와 오렌지 컬러. | drawTextBlob위치 0,0, "I'm falling" |
그러면 변환 속성 트리와 페인트 청크가 다음과 같이 됩니다(간단하게).
디스플레이 항목 그룹과 속성 트리 상태인 페인트 청크의 순서가 지정된 목록은 렌더링 파이프라인의 레이어드 단계에 대한 입력 사항이다. 페인트 청크의 전체 목록은 단일 복합 레이어로 통합되어 래스터화 될 수 있지만, 사용자가 스크롤할 때마다 비싼 래스터화가 필요할 것이다. 각 페인트 청크에 대해 복합 레이어를 생성하고 모든 재래스터화를 피하기 위해 개별적으로 래스터화할 수 있지만, 그렇게 하면 GPU 메모리가 빠르게 소진될 것이다. 계층화 단계는 GPU 메모리 간에 트레이드오프를 해야 하고 상황이 바뀔 때 비용을 줄여야 한다. 일반적인 접근방식은 기본적으로 청크를 병합하는 것이며, 합성기 스레드 스크롤 또는 합성기 스레드 변환 애니메이션과 같이 합성기 스레드에서 변경될 것으로 예상되는 속성 트리 상태가 있는 페인트 청크를 병합하지 않는 것이다.
앞의 예는 이상적으로 두 개의 복합 레이어를 생성해야 한다.
- 도면 명령을 포함하는 800x600 복합 도면층:
- drawRect 800x600 사이즈에 화이트 컬러.
- drawRect 100x100 사이즈로 포지션0.0과 핑크 컬러.
- 도면 명령을 포함하는 144x224 복합 도면층:
- drawTextBlob 위치 0,0, 문자 "Hello world"로
- 0,18 번역(translate)
- rotateZ (25deg)
- drawRect위치 0.0에 75x200 사이즈와 주황색 컬러
- drawTextBlob위치 0,0, 문자 "I'm falling"
사용자가 스크롤할 경우#scroll, 두 번째 복합 레이어는 이동하지만 래스터화는 필요하지 않다.
예를 들어, 여기의 예로는, 속성 트리에 관한 이전 섹션에서, 6개의 페인트 덩어리가 있다.속성 트리 상태(변환, 클립, 효과, 스크롤)와 함께 다음이 해당된다.
- 문서 배경: 문서 스크롤, 문서 클립, 루트, 문서 스크롤.
- div의 수평, 수직 및 스크롤 코너(세 개의 개별 페인트 청크): 문서 스크롤, 문서 클립,#one흐릿, 문서 스크롤.
- iframe #one:#one회전, 오버플로 스크롤 클립,#one흐릿하고 짧은 두루마리.
- iframe #two:#two척도, 문서 클립, 루트, 문서 스크롤.
합성기 프레임(Compositor frames): 표면, 렌더 표면 및 GPU 텍스처 타일
이전 게시물(작업된 예는 여기에 있음)에서 논의한 바와 같이, 브라우저와 렌더링 프로세스는 컨텐츠의 래스터라이징을 관리한 후, 화면에 표시할 컴포지터 프레임을 Viz 프로세스에 제출한다. 합성기 프레임은 RenderingNG가 래스터화된 콘텐츠를 결합하고 GPU를 사용하여 효율적으로 그리는 방법을 나타낸다.
타일 (Tiles)
이론적으로 렌더 프로세스 또는 브라우저 프로세스 컴포지터는 픽셀을 단일 텍스처로 래스터화하여 렌더러 뷰포트의 전체 크기를 Viz에 제출할 수 있다. 그것을 표시하기 위해 디스플레이 합성기는 단지 그 단일 텍스쳐의 픽셀을 프레임 버퍼의 적절한 위치(예: 화면)로 복사하기만 하면 된다. 그러나, 만약 컴포지터가 하나의 픽셀이라도 업데이트하고 싶다면, 전체 뷰포트를 다시 레이스터화하여 Viz에 새로운 텍스처를 제출해야 한다.
대신 뷰포트는 타일로 구분된다. 별도의 GPU 텍스처 타일은 뷰포트의 일부에 대해 래스터화된 픽셀이 있는 각 타일을 뒤로 한다. 그런 다음 렌더러는 개별 타일을 업데이트하거나 기존 타일의 위치를 변경할 수 있다. 예를 들어 웹 사이트를 스크롤할 때 기존 타일의 위치가 위로 이동하며 페이지 아래쪽에 있는 콘텐츠를 위해 새 타일을 래스터링하면 되는 경우가 있다.
위의 이미지는 4개의 타일을 가진 화창한 날의 모습을 묘사하고 있다. 스크롤이 생기면 다섯 번째 타일이 나타나기 시작한다. 그 타일들 중 하나는 오직 한 가지 색(하늘색)만 가지고 있고, 위에는 비디오와 iframe 이 있다.
쿼드 및 표면 (Quads and surfaces)
GPU 텍스처 타일은 특별한 종류의 쿼드인데, 이것은 단지 한 종류의 텍스처 혹은 다른 종류의 카테고리의 화려한 이름일 뿐이다. 쿼드는 입력 질감을 식별하고, 어떻게 변환하고 그것에 시각 효과를 적용하는지를 나타낸다. 예를 들어, 일반 컨텐츠 타일은 타일 그리드에서 x, y 위치를 나타내는 변환이 있다
이 래스터화된 타일들은 쿼드 목록인 렌더 패스로 포장되어 있다. 렌더 패스는 픽셀 정보를 포함하지 않는다. 대신 원하는 픽셀 출력을 생성하기 위해 각 쿼드를 어디에 그리고 어떻게 그리는지에 대한 지침이 있다. 각 GPU 텍스처 타일에는 draw 쿼드가 있다.디스플레이 합성기는 렌더 패스에 필요한 픽셀 출력을 생성하기 위해 지정된 시각 효과로 각 쿼드 목록을 반복해서 그려야 한다. 렌더 패스에 대한 합성 그리기 쿼드는 GPU에서 효율적으로 수행될 수 있는데, 허용된 시각 효과는 GPU 기능에 직접 매핑되는 효과로 신중하게 선택되기 때문이다.
래스터화된 타일을 넘어 draw 쿼드에도 추가 종류가 있다.예를 들어 질감을 전혀 지지하지 않는 솔리드 컬러 드로잉 쿼드나 비디오나 캔버스 같은 비타일 텍스쳐용 텍스쳐 드로잉 쿼드가 있다.
합성기 프레임이 다른 합성기 프레임을 내장하는 것도 가능하다. 예를 들어, 브라우저 컴포지터는 브라우저 UI로 컴포지터 프레임과 렌더 컴포지터 내용이 포함될 빈 사각형을 만든다. 또 다른 예는 사이트 격리된 iframes이다.이 임베딩은 표면(seurfaces)을 통해 이루어진다.
합성자가 합성기 프레임을 제출할 때 표면 ID라고 하는 식별자를 수반해 다른 합성기 프레임이 참조로 내장할 수 있도록 한다. 특정 표면 ID와 함께 제출된 최신 컴포지터 프레임은 Viz가 저장한다. 그러면 다른 합성기 프레임이 나중에 표면 그리기 쿼드를 통해 이를 참조할 수 있으므로 Viz는 무엇을 그릴지 안다. (표면 그리기 쿼드는 질감이 아닌 표면 ID만 포함한다.)
중간 렌더 패스 (Intermediate render passes)
많은 필터 또는 고급 혼합 모드와 같은 일부 시각적 효과에는 2개 이상의 쿼드가 중간 질감으로 그려져야 한다. 그런 다음 중간 질감을 GPU(또는 다른 중간 질감)의 대상 버퍼로 끌어와 시각 효과를 동시에 적용한다. 이를 위해 합성기 프레임에는 실제로 렌더 패스 목록이 포함되어 있다. 항상 루트 렌더 패스가 있는데, 이 패스는 마지막에 그려지고, 목적지가 프레임 버퍼에 해당하는 패스가 있으며, 더 많을 수 있다.
렌더 패스를 여러 번 사용할 경우 렌더 패스라는 이름이 설명된다. 각 패스는 GPU에서 다중 "패스"로 순차적으로 실행되어야 하는 반면, 단일 패스는 단일 대규모 병렬 GPU 계산으로 완료될 수 있다.
집계 (Aggregation)
다중 컴포지터 프레임이 Viz에 제출되며, 화면에 함께 그려야 한다. 이는 이들을 하나의 집계된 합성자 프레임으로 변환하는 집계 단계에 의해 달성된다. 집계는 지표면 그리기 쿼드를 지정된 합성기 프레임으로 대체한다. 불필요한 중간 텍스처나 화면을 벗어난 콘텐츠를 최적화할 수 있는 기회도 된다. 예를 들어, 많은 경우, 격리된 현장의 합성기 프레임이 자체 중간 질감을 필요로 하지 않으며, 적절한 그리기 쿼드를 통해 프레임 버퍼로 직접 그릴 수 있다. 통합 단계는 그러한 최적화를 파악하여 개별 렌더 컴포지터가 접근할 수 없는 글로벌 지식(global knowledge)을 바탕으로 이를 적용한다.
예
이 게시물의 시작부터 예를 나타내는 실제 합성자 틀은 다음과 같다.
- foo.com/index.html표면: id=0
- Render pass 0: 출력(output) 그리기.
- 렌더 패스 드로 쿼드: 3px 블러로 그린 후 렌더 패스 0에 클리핑하십시오.
- Render pass 1:
- 타일 내용에 대한 쿼드 그리기#one iframe, 각각 x와 y 위치.
- Render pass 1:
- 표면 그리기 쿼드: ID 2로, 스케일로 그리고 변환을 변환한다.
- 렌더 패스 드로 쿼드: 3px 블러로 그린 후 렌더 패스 0에 클리핑하십시오.
- Render pass 0: 출력(output) 그리기.
- 브라우저 UI 표면: ID=1
- Render pass 0: 출력에 그리기.
- 브라우저 UI에 대한 쿼드 그리기(타일링됨)
- Render pass 0: 출력에 그리기.
- bar.com/index.html표면: ID=2
- Render pass 0: 출력에 그리기.
- 다음 내용에 대한 쿼드 그리기#twoiframe, 각각 x와 y 위치
- Render pass 0: 출력에 그리기.
결론
읽어줘서 고마워! 앞의 두 게시물과 함께, 렌더링NG의 개요를 마무리한다.다음은 처음부터 끝까지 렌더링 파이프라인의 많은 하위 구성 요소 내에서 도전과 기술에 대해 심도 있게 다룰 것이다. 그것들은 곧 올 것이다!
우나 크라베츠의 삽화.
'Chrome' 카테고리의 다른 글
Inside look at modern web browser (part 1) (0) | 2022.11.02 |
---|---|
Key data structures and their roles in RenderingNG(한글)(1) (0) | 2022.03.09 |
Overview of the RenderingNG architecture (한글) (1) | 2021.12.15 |