사전 프래그먼트
용어함정

프래그먼트

gabury1고친 사람 github-actions[bot]

프래그먼트는 통짜로 다루기 힘든 것을 잘라 놓은 조각 하나를 부르는 말입니다. 무엇을 잘랐느냐에 따라 가리키는 물건이 아주 달라집니다. 화면을 그리는 쪽에서는 한 칸을 무슨 색으로 칠할지 정하려고 만들어 두는 후보를 말합니다. 앱 화면을 짜는 쪽에서는 화면 한 귀퉁이를 떼어 따로 만든 부품을 말합니다.

쉽고 빠른 이해

무슨 일을 하는 물건인가 — 큰 것을 잘라 한 조각씩 다루게 해 주는 이름입니다. 그래픽 카드가 삼각형을 그릴 때 화면 한 칸마다 만드는 색칠 후보가 프래그먼트입니다. 안드로이드 앱에서 화면 절반을 떼어 따로 만든 부품도 프래그먼트입니다. 이 두 뜻은 이름만 같고 서로 이어지지 않습니다.

왜 이렇게 하나 — 그래픽스에서는 도형을 화면의 칸 하나하나로 옮기는 동안, 화면에 올릴지 아직 모르는 값을 잠깐 담아 둘 것이 필요합니다. 앱 화면에서는 화면 전체를 한 덩이로 두면 큰 화면과 작은 화면에 같은 코드를 못 씁니다.

어떻게 도나

  1. 그래픽스 프래그먼트는 도형이 덮은 칸마다 하나씩 생깁니다
  2. 색을 정하고 앞에 가린 것이 있는지 따져, 살아남은 것만 화면 한 칸이 됩니다
  3. 안드로이드 프래그먼트는 화면 하나에 여럿을 붙였다 뗐다 하며 씁니다

대가 — 그래픽스에서는 겹쳐 그린 도형만큼 버려지는 프래그먼트가 늘어 계산이 헛돕니다. 안드로이드에서는 화면을 쪼갠 만큼 챙길 것이 늘어납니다. 그리고 한 대화에서 두 뜻을 섞어 쓰면 서로 다른 이야기를 하게 됩니다.

상세

이 절은 「프래그먼트」가 가리키는 물건들을 나란히 놓고 봅니다. 먼저 뜻들을 표 하나로 가릅니다. 그다음 그래픽스의 프래그먼트와 안드로이드의 프래그먼트를 차례로 따라갑니다.

끝에서는 나머지 뜻들을 짧게 짚고, 대화에서 어느 뜻인지 알아채는 단서를 모읍니다.

프래그먼트가 가리키는 물건들

뜻마다 자르는 대상이 다릅니다. 공통점은 하나입니다. 통째로 두면 다루기 힘든 것을 조각으로 끊어 하나씩 다룬다는 점입니다.

맥락 프래그먼트 한 조각이 가리키는 것 예
그래픽스 화면 한 칸을 칠할지 정하려고 만든 후보 삼각형이 덮은 칸마다 하나씩
안드로이드 앱 화면 화면 일부를 떼어 만든 부품 왼쪽 목록과 오른쪽 상세
웹 주소 문서 안에서 어디를 볼지 가리키는 끝 조각 주소 끝에 붙는 #설치
인터넷 전송 큰 덩이를 길에 맞게 자른 조각 단편화된 패킷
질의 언어 여러 질의에서 다시 쓰는 필드 묶음 GraphQL 프래그먼트

서로 다른 이 다섯이 한 낱말을 나눠 씁니다. 아래 두 소절은 그중 앞의 둘을 따로 펼칩니다. 이 둘이 서로 가장 멀고, 대화에서 제일 자주 부딪히기 때문입니다.

그래픽스의 프래그먼트

화면에 무언가를 그리는 일은 여러 단계를 거칩니다. 프로그램이 넘기는 것은 정점의 목록입니다. 정점은 도형의 꼭짓점이고, 화면 어디에 있는지를 좌표로 갖습니다.

정점 셋을 이으면 삼각형 하나가 됩니다. 이렇게 정점을 이어 만든 기본 도형을 프리미티브라고 부릅니다. 화면에 보이는 입체는 이런 삼각형을 잔뜩 붙여 만든 것입니다.

그런데 화면은 칸이 촘촘히 박힌 격자입니다. 이 칸 하나가 픽셀입니다. 좌표로만 된 삼각형을 그리려면, 이 삼각형이 어느 칸을 덮는지 먼저 찾아야 합니다. 이 찾는 일이 래스터화입니다.

래스터화가 찾아낸 칸 하나마다 프래그먼트가 하나씩 생깁니다. 프래그먼트는 「이 칸을 칠할 후보」입니다. 아직 화면에 올라간 것이 아니라, 올라갈지 말지 따져 볼 재료입니다.

프래그먼트 하나가 들고 있는 것

프래그먼트는 빈 칸 표시가 아닙니다. 칠할지 말지 정하는 데 필요한 값을 함께 들고 다닙니다.

첫째는 화면에서 몇 번째 칸인지를 말하는 좌표입니다. 둘째는 그 칸이 보는 사람에게서 얼마나 멀리 있는지를 말하는 깊이값입니다. 셋째는 색이나 무늬 좌표처럼 꼭짓점에 붙어 있던 값들입니다.

셋째 값은 조금 특이합니다. 꼭짓점에는 값이 있지만 삼각형 한가운데 칸에는 없습니다. 그래서 세 꼭짓점의 값을 거리에 맞춰 섞어 중간값을 만듭니다. 이렇게 섞어 만드는 일이 보간입니다.

덕분에 꼭짓점 셋에만 색을 줘도 삼각형 안쪽이 부드럽게 물듭니다. 가운데 칸의 프래그먼트는 세 색을 거리만큼 섞은 색을 들고 나옵니다.

프래그먼트가 픽셀이 되기까지

프래그먼트를 받아 무슨 색으로 칠할지 정하는 작은 프로그램이 프래그먼트 셰이더입니다. 그래픽 처리 장치인 GPU(Graphics Processing Unit)가 프래그먼트 하나마다 이 프로그램을 한 번씩 돌립니다.

아래는 꼭짓점에서 보간돼 온 색을 그대로 내보내는 가장 단순한 프래그먼트 셰이더입니다. 모양만 보면 됩니다.

glsl
in vec3 vColor;
out vec4 fragColor;

void main() {
    fragColor = vec4(vColor, 1.0);  // 이 후보 한 칸의 색
}

in 으로 받는 값이 보간돼 들어온 색입니다. out 으로 내보내는 값이 이 후보가 주장하는 색입니다. 마지막 자리의 1.0 은 이 색이 투명하지 않다는 뜻입니다.

색을 정했다고 화면에 올라가는 것은 아닙니다. 프래그먼트는 뒤이어 몇 가지 검사를 받습니다. 그중 중요한 것이 깊이 테스트입니다. 같은 칸을 두고 더 가까운 프래그먼트가 이미 있으면, 뒤에 있는 것은 버려집니다.

살아남은 프래그먼트가 프레임버퍼의 한 칸에 기록됩니다. 프레임버퍼는 화면에 내보낼 그림을 담아 두는 메모리입니다. 이때 앞선 색과 섞어 반투명하게 얹는 일이 블렌딩입니다.

flowchart TD
    A["정점 셋 · 삼각형 하나"] --> B["래스터화 · 덮은 칸 찾기"]
    B --> C["프래그먼트 여럿 · 칸마다 하나"]
    C --> D["프래그먼트 셰이더 · 색 정하기"]
    D --> E{"앞에 가린 것이 있나"}
    E -->|있다| F["버린다"]
    E -->|없다| G["프레임버퍼의 픽셀이 된다"]

그림에서 보듯 프래그먼트와 픽셀을 가르는 선은 이 마지막 갈림입니다. 픽셀은 화면에 남은 결과 한 칸이고, 프래그먼트는 그 한 칸을 두고 다투는 후보입니다.

후보는 픽셀보다 많습니다. 삼각형 여럿이 같은 칸을 겹쳐 덮으면 그 칸에만 후보가 여럿 생기고, 결국 하나만 남습니다. 그래서 그래픽스에서 「프래그먼트가 많이 버려진다」는 말은 안 보일 것을 계산하느라 시간을 썼다는 뜻이 됩니다.

안드로이드의 프래그먼트

여기서 뜻이 통째로 바뀝니다. 안드로이드는 스마트폰과 태블릿에서 도는 앱을 만드는 플랫폼이고, 거기서 프래그먼트는 화면을 이루는 부품 하나를 가리킵니다.

앱의 화면 한 장을 맡는 부품은 액티비티입니다. 사용자가 앱을 열면 액티비티 하나가 떠서 화면을 채웁니다. 다른 화면으로 넘어가면 다른 액티비티가 뜹니다.

화면 한 장을 액티비티 하나가 통째로 맡으면 곤란해지는 때가 있습니다. 좁은 폰에서는 목록 화면과 상세 화면을 따로 띄우는 것이 맞지만, 넓은 태블릿에서는 왼쪽에 목록, 오른쪽에 상세를 함께 두는 편이 낫습니다.

같은 목록 화면을 두 번 만들지 않으려면 화면을 더 작은 부품으로 쪼개야 합니다. 그 부품이 프래그먼트입니다.

프래그먼트는 두 가지를 자기 것으로 갖습니다. 하나는 뷰입니다. 뷰는 화면에 실제로 그려지는 요소 하나이고, 버튼이나 목록 같은 것이 뷰입니다. 다른 하나는 생명주기입니다. 생명주기는 만들어지고 화면에 보이고 사라지기까지 거치는 단계들을 말합니다.

액티비티 안에 프래그먼트가 붙는 모양

프래그먼트는 혼자 뜨지 못합니다. 언제나 액티비티 안의 한 구역을 빌려 그 안에 들어갑니다.

붙이고 떼는 일은 프래그먼트 매니저가 맡습니다. 프래그먼트 매니저는 액티비티가 들고 있는 관리자이고, 「이 구역에 이 프래그먼트를 넣어라」 같은 요청을 받아 처리합니다.

flowchart TD
    M["프래그먼트 매니저 · 붙이고 뗀다"] --> A
    subgraph A["액티비티 한 장 · 태블릿 화면"]
        F1["목록 프래그먼트 · 제 뷰와 생명주기"]
        F2["상세 프래그먼트 · 제 뷰와 생명주기"]
    end

좁은 폰에서는 같은 액티비티가 목록 프래그먼트 하나만 붙입니다. 목록에서 항목을 고르면 그 구역의 프래그먼트를 상세 프래그먼트로 갈아 끼웁니다. 프래그먼트 안의 코드는 양쪽에서 그대로 쓰입니다.

갈아 끼운 내역은 백 스택에 쌓입니다. 뒤로 가기를 누르면 방금 얹은 프래그먼트가 빠지고 앞의 것이 돌아옵니다. 화면 전체를 바꾸지 않고도 뒤로 가기가 자연스럽게 돕니다.

안드로이드 프래그먼트에서 아픈 대목

쪼갠 값은 공짜가 아닙니다. 프래그먼트는 두 종류의 수명을 따로 갖습니다. 하나는 프래그먼트 자신의 수명이고, 다른 하나는 그 프래그먼트가 만든 뷰의 수명입니다.

둘이 갈리는 까닭은 화면을 잠깐 접어 두는 때가 있기 때문입니다. 프래그먼트는 살아 있는데 뷰만 없어지는 구간이 생깁니다. 이때 없어진 뷰를 붙들고 있으면 메모리가 새거나 앱이 죽습니다.

프래그먼트끼리 값을 주고받는 것도 성가십니다. 서로를 직접 부르면 둘이 붙어 버려 따로 쓸 수 없게 됩니다. 그래서 액티비티나 공용 저장소를 가운데 두고 값을 건네는 방식을 씁니다.

그 밖의 프래그먼트

웹 주소의 프래그먼트 — URI(Uniform Resource Identifier, 통합 자원 식별자)는 여러 조각으로 읽힙니다. 그중 # 뒤에 오는 끝 조각이 프래그먼트입니다. 문서 안에서 어느 대목을 보여 줄지 가리킵니다. 이 조각은 브라우저가 쥐고 있고 서버로는 넘어가지 않습니다.

전송 중에 잘린 조각 — 길마다 한 번에 보낼 수 있는 덩이의 크기에 상한이 있습니다. 그보다 큰 덩이는 IP(Internet Protocol, 인터넷 프로토콜)가 여러 조각으로 잘라 보내고 받는 쪽이 다시 잇습니다. 잘린 조각 하나가 프래그먼트이고, 이 자르는 일이 단편화입니다.

질의 언어의 프래그먼트 — GraphQL 에서는 여러 질의가 같은 필드 묶음을 되풀이해 적게 됩니다. 그 묶음에 이름을 붙여 두고 가져다 쓰는 것이 프래그먼트입니다.

브라우저 안의 프래그먼트 — 브라우저는 문서를 화면에 올리기 전에 임시로 담을 그릇을 씁니다. 그런 그릇 중 하나가 DocumentFragment 입니다. 노드를 여기 모아 두었다가 한꺼번에 문서에 넣으면 화면을 다시 그리는 횟수가 줄어듭니다.

어느 뜻인지 가르는 단서

대화나 문서에서 「프래그먼트」가 나오면 함께 붙은 낱말을 봅니다. 대개 그것만으로 어느 뜻인지 갈립니다.

함께 나오는 말 뜻
셰이더 · 래스터화 · 깊이 · 픽셀이 버려진다 그래픽스
액티비티 · 뷰 · 생명주기 · 뒤로 가기 · 태블릿 안드로이드 화면
# · 앵커 · 서버로 안 간다 웹 주소
단편화 · 다시 잇는다 · 크기 상한 인터넷 전송
질의 · 필드 묶음 · 다시 쓴다 질의 언어

이름이 비슷해 헷갈리는 것도 둘 있습니다. 프래그먼트 셰이더는 그래픽스 뜻에만 딸린 프로그램입니다. 반대로 세그먼트는 프래그먼트와 뜻이 겹쳐 보이지만 다른 말입니다. 세그먼트는 처음부터 나누어 담기로 하고 자른 조각을 가리키고, 프래그먼트는 대개 통짜였던 것에서 떨어져 나온 조각을 가리킵니다.

관련 항목

그래픽스 프래그먼트가 생겨나고 사라지는 처리 단계

그래픽스 파이프라인 · 정점 셰이더 · 프리미티브 · 래스터화 · 프래그먼트 셰이더 · 프래그먼트별 테스트 · 깊이 테스트 · 스텐실 테스트 · 블렌딩 · 프레임버퍼

그래픽스 프래그먼트 한 조각이 지니는 값

윈도 좌표 · 깊이값 · 무게중심 좌표 · 보간 · 텍스처 좌표 · 샘플 · 픽셀 · 정점

그래픽스 프래그먼트를 정의하는 규격과 구현

OpenGL · Vulkan · WebGL · Direct3D · GLSL · HLSL · GPU · 셰이더

안드로이드 프래그먼트와 한 화면을 이루는 부품

Android · 액티비티 · 뷰 · 뷰 그룹 · 레이아웃 · 앱 컴포넌트 · 생명주기 · 인텐트

안드로이드 프래그먼트를 붙이고 떼는 장치

프래그먼트 매니저 · 프래그먼트 트랜잭션 · 백 스택 · 내비게이션 컴포넌트 · 뷰모델 · 뷰 바인딩

이름이 겹치는 다른 프래그먼트

프래그먼트 식별자 · URI · 단편화 · IP · MTU · GraphQL · DocumentFragment · 프래그먼트 트리

잘라 낸 조각을 가리키는 다른 이름

세그먼트 · 프레임 · 패킷 · 청크 · 블록 · 샤드 · 페이지

다른 이름: fragment