OpenGL ES 및 EGL 구현

OpenGL은 3D 그래픽 처리 하드웨어의 표준 소프트웨어 인터페이스를 지정하는 크로스 플랫폼 그래픽 API입니다. OpenGL ES는 삽입된 기기용 OpenGL 사양의 하위 집합입니다.

Android 호환 기기는 EGL, OpenGL ES 1.x, OpenGL ES 2.0용 드라이버를 제공해야 합니다. OpenGL ES 3.x 지원은 선택사항입니다. 주요 고려사항은 다음과 같습니다.

  • GL 드라이버가 뛰어난 성능을 발휘하고 OpenGL ES 표준을 준수하도록 합니다.
  • GL 컨텍스트를 무제한으로 허용합니다. Android는 백그라운드에서 앱을 허용하고 GL 컨텍스트를 활성 상태로 유지하기 때문에 드라이버의 컨텍스트 수를 제한해서는 안 됩니다.
  • 한번에 20~30개의 활성 GL 컨텍스트를 갖는 것이 일반적이므로 각 컨텍스트에 할당되는 메모리의 양에 주의해야 합니다.
  • YV12 이미지 형식 및 미디어 코덱 또는 카메라와 같이 시스템의 다른 구성 요소에서 가져온 기타 YUV 이미지 형식을 지원합니다.
  • 필수 확장 프로그램인 EGL_KHR_wait_sync, GL_OES_texture_external, EGL_ANDROID_image_native_buffer, EGL_ANDROID_recordable을 지원합니다. 또한 Hardware Composer v1.1 이상에서는 EGL_ANDROID_framebuffer_target 확장 프로그램이 필요합니다.

EGL_ANDROID_blob_cache, EGL_KHR_fence_sync, EGL_ANDROID_native_fence_sync도 지원하는 것이 좋습니다.

Android 10은 EGL 1.5 인터페이스를 구현합니다. EGL 1.5의 새로운 기능에 관한 자세한 내용은 Khronos 출시 1.5 사양을 참조하세요.

드라이버 로드

Android는 시스템 이미지가 빌드될 때 시스템에서 사용 가능한 GPU를 식별할 수 있어야 합니다. 32비트 및 64비트 OpenGL ES 드라이버의 기본 경로는 각각 /vendor/lib/egl/vendor/lib64/egl입니다. 로더는 두 시스템 속성인 ro.hardware.eglro.board.platform 또는 정확한 이름을 사용하여 시스템 드라이버를 검색하고 로드합니다. OpenGL ES 드라이버는 하나의 바이너리로 제공되거나 3개의 바이너리로 분할되어야 합니다. OpenGL ES 드라이버가 하나의 바이너리로 제공되는 경우 다음 이름 중 하나를 사용합니다.

libGLES_${ro.hardware.egl}.so
libGLES_${ro.board.platform}.so
libGLES.so

OpenGL ES 드라이버가 3개의 바이너리로 제공되는 경우 다음 이름 집합 중 하나를 사용합니다.

libEGL_${ro.hardware.egl}.so
libGLESv1_CM_${ro.hardware.egl}.so
libGLESv2_${ro.hardware.egl}.so

libEGL_${ro.board.platform}.so
libGLESv1_CM_${ro.board.platform}.so
libGLESv2_${ro.board.platform}.so

libEGL.so
libGLESv1_CM.so
libGLESv2.so

OpenGL ES 계층

Android 10에는 GLES 2.0 이상의 레이어 시스템이 도입되었습니다. GLES 레이어는 앱 내에서 제공하거나 도구에서 제공하는 공유 객체입니다. GLES 레이어를 사용하면 디버그 가능한 앱에서 Vulkan과 동일한 설정 메커니즘을 사용하여 레이어를 검색하고 로드할 수 있습니다.

EGL 로더 내의 구성요소인 GLES LayerLoader는 GLES 레이어를 식별합니다. GLES LayerLoader가 찾은 각 레이어의 경우 GLES LayerLoader는 AndroidGLESLayer_Initialize를 호출하고 libEGL의 함수 목록을 탐색하고 알려진 모든 함수에 대해 AndroidGLESLayer_GetProcAddress를 호출합니다. 레이어는 함수를 가로채는 경우 함수의 주소를 추적합니다. 레이어가 함수를 가로채지 않으면 AndroidGLESLayer_GetProcAddress는 전달된 것과 동일한 함수 주소를 반환합니다. 그런 다음 LayerLoader는 함수 후크 목록을 업데이트하여 레이어의 진입점을 가리킵니다.

레이어 사용 설정

전역적으로 또는 앱별로 GLES 레이어를 사용 설정할 수 있습니다. 앱별 설정은 재부팅을 거쳐도 지속되는 반면, 전역 속성은 재부팅 시 지워집니다.

앱별로 레이어 사용 설정하기:

# Enable layers
adb shell settings put global enable_gpu_debug_layers 1

# Specify target app
adb shell settings put global gpu_debug_app package_name

# Specify layer list (from top to bottom)
adb shell settings put global gpu_debug_layers_gles layer1:layer2:...:layerN

# Specify packages to search for layers
adb shell settings put global gpu_debug_layer_app package1:package2:...:packageN

앱별로 레이어 사용 중지하기:

adb shell settings delete global enable_gpu_debug_layers
adb shell settings delete global gpu_debug_app
adb shell settings delete global gpu_debug_layer_app

전역적으로 레이어 사용 설정하기:

# Attempts to load layers for all applications, including native executables
adb shell setprop debug.gles.layers layer1:layer2:...:layerN

레이어 테스트

GLES 레이어는 Android CTS를 기반으로 작동하며 CTS의 호환 기기 테스트를 통과해야 합니다. 레이어가 기기에서 작동하는지 확인하려면 $ atest CtsGpuToolsHostTestCases를 실행합니다.