Android 게임을 개발하거나 최적화할 때 엔진에서 사용하는 그래픽 파이프라인을 이해하는 것이 도움이 될 수 있습니다. 엔진은 개발자가 명확하게 액세스할 수 있는 신호 없이 Vulkan 또는 GLES를 선택할 수 있습니다. 안타깝게도 logcat를 사용하여 게임이 Vulkan에서 실행 중인지 또는 OpenGL ES로 자동으로 대체되었는지 확인하는 것이 신뢰할 수 없는 경우가 있습니다.
이 가이드에서는 Android Performance Analyzer (APA) 및 맞춤 Perfetto SQL 쿼리를 사용하여 게임의 활성 렌더링 API를 명확하게 식별하는 방법을 보여줍니다.
로그 기반 인증의 제한사항
- 제거된 로그: 프로덕션 빌드는 초기화 및 드라이버 로드 공간을 숨기는 경우가 많습니다.
- 거짓양성: 일부 게임 엔진은 시작 중에 Vulkan 및 OpenGL ES 라이브러리를 모두 로드하여 둘 다에 대한 초기화 로그를 출력합니다. 결국 하나가 실패하고 대체가 트리거되더라도 마찬가지입니다.
- 자동 대체: 기기별 드라이버 문제로 인해 Vulkan 초기화가 실패하면 엔진은 심각한 오류를 발생시키지 않고 OpenGL ES로 대체하는 경우가 많습니다.
APA를 사용하여 측정
Android Performance Analyzer를 사용하면 시스템 트레이스를 기록하고 SQL 쿼리를 통해 프레임 데이터를 정확하게 분석할 수 있습니다. Vulkan 및 GLES 사용을 측정하려면 다음 단계를 따르세요.
APA로 트레이스 캡처: 게임을 실행하고 APA를 사용하여 분석하려는 세그먼트(예: 게임플레이 중 프레임 드롭이 의심되는 지점)에서 시스템 트레이스를 캡처합니다. 기기가 연결되고 트레이스 기록이 완료되면 트레이스 데이터가 APA 인터페이스에 로드됩니다.
APA에서 SQL 탭 클릭: trace 분석 화면이 열리면 UI의 탐색 메뉴에서 SQL 탭을 클릭하여 trace 프로세서 환경을 엽니다. 여기에서 데이터를 직접 쿼리할 수 있습니다.
APA SQL 탭에 다음 SQL 쿼리 붙여넣기: 다음 SQL 쿼리를 복사하여 쿼리 입력 필드에 붙여넣습니다. 이 쿼리는
eglSwapBuffers,QueuePresentKHR,vkQueuePresentKHR와 같은 그리기 API 이벤트의 트레이스를 스캔합니다. 프로세스 이름별로 그룹화하고 렌더링 API 수와 Vulkan 및 OpenGL ES 렌더링 호출의 백분율 분포를 계산합니다.WITH raw_slices AS ( -- 1. Map each slice (API call) to its corresponding process or package via UTID and UPID SELECT p.name AS process_name, s.name AS slice_name FROM slice s JOIN thread_track tt ON s.track_id = tt.id JOIN thread t USING (utid) JOIN process p USING (upid) WHERE (s.name LIKE 'eglSwapBuffers%' OR s.name IN ('QueuePresentKHR', 'vkQueuePresentKHR')) -- Optional: To isolate your game, uncomment the following and filter by package name and thread name: -- AND p.name = 'com.example.mygame' -- AND t.name = 'RenderThread' ), process_stats AS ( -- 2. Aggregate counts per individual process SELECT process_name, SUM(CASE WHEN slice_name LIKE 'eglSwapBuffers%' THEN 1 ELSE 0 END) AS egl_count, SUM(CASE WHEN slice_name IN ('QueuePresentKHR', 'vkQueuePresentKHR') THEN 1 ELSE 0 END) AS vulkan_count FROM raw_slices GROUP BY process_name ), process_totals AS ( -- 3. Calculate total counts for denominator calculation SELECT process_name, egl_count, vulkan_count, (egl_count + vulkan_count) AS total_count FROM process_stats ) -- 4. Calculate final percentage shares per row, preventing division by zero errors SELECT process_name, egl_count, vulkan_count, total_count, ROUND(CAST(egl_count AS REAL) * 100 / NULLIF(total_count, 0), 2) AS "egl_percentage(%)", ROUND(CAST(vulkan_count AS REAL) * 100 / NULLIF(total_count, 0), 2) AS "vulkan_percentage(%)" FROM process_totals ORDER BY total_count DESC;쿼리 실행: 입력란 근처에 있는 쿼리 실행 버튼을 클릭합니다. 쿼리가 실행되면 결과 창에 프로세스 이름 (
process_name), OpenGL ES 프레젠테이션 수 (egl_count), Vulkan 프레젠테이션 수 (vulkan_count), 총 프레젠테이션 수(total_count), 사용된 각 API의 비율 (egl_percentage(%)및vulkan_percentage(%))을 보여주는 표가 표시됩니다.
실행된 SQL 쿼리와 결과로 생성된 렌더링 API 측정항목이 표에 표시된 화면
일반적인 문제
SurfaceFlinger혼동 방지: 항상 검색 범위를 게임의 애플리케이션 스레드 (RenderThread)로 지정하세요.SurfaceFlinger과 같은 시스템 전체 컴포지터 프로세스는 게임의 내부 렌더링 파이프라인이 아닌 시스템 UI 렌더링을 나타내는 Vulkan 또는 EGL 트랙을 표시할 수 있습니다. 게임을 분리하려면 기본 SQL 쿼리의WHERE절에서 선택적 필터의 주석 처리를 삭제하고'com.example.mygame'을 게임의 패키지 이름으로 바꿉니다.-- AND p.name = 'com.example.mygame' -- AND t.name = 'RenderThread'준비 기간: 항상 게임의 기본 3D 장면이 완전히 로드된 후에 트레이스를 기록합니다. 스플래시 화면 또는 로드 전환 중에 캡처하면 초기화가 잘못될 수 있습니다.
LevelUp 예외 추적 요구사항
Android Performance Analyzer (APA)를 사용하여 트레이스를 캡처하고 Google Play Games LevelUp 예외를 적용받으려면 트레이스가 유효하기 위한 특정 하드웨어 요구사항이 있습니다.
타겟팅된 Level Up 참조 기기 중 하나를 사용하여 트레이스를 캡처하는 것이 좋습니다.
또한 정확한 검증을 위해 ANGLE GPU를 사용하는 기기에서 트레이스를 가져오면 안 됩니다. 특히 다음 기기를 사용하여 LevelUp 예외 트레이스를 캡처할 수 없습니다.
- GPU 공급업체가 SLSI(Samsung)인 모든 기기(AMD Xclipse GPU 사용)
- Pixel 11