Podczas tworzenia lub optymalizowania gier na Androida często przydaje się wiedza o tym, którego potoku graficznego używa silnik. Silniki mogą wybierać Vulkan lub GLES bez wyraźnych sygnałów dostępnych dla dewelopera. Niestety w niektórych sytuacjach poleganie na logcat w celu sprawdzenia, czy gra działa na Vulkanie, czy też po cichu wróciła do OpenGL ES, może być zawodne.
Z tego przewodnika dowiesz się, jak za pomocą Android Performance Analyzer (APA) i niestandardowych zapytań SQL Perfetto jednoznacznie zidentyfikować aktywny interfejs API renderowania gry.
Ograniczenia weryfikacji na podstawie logów
- Logi bez informacji o inicjalizacji: kompilacje produkcyjne często ukrywają ślady inicjalizacji i ładowania sterowników.
- Wyniki fałszywie pozytywne: niektóre silniki gier podczas uruchamiania wczytują zarówno biblioteki Vulkan, jak i OpenGL ES, i wyświetlają dzienniki inicjowania dla obu, nawet jeśli jedna z nich ostatecznie ulegnie awarii i wywoła działanie zastępcze.
- Ciche przełączanie na tryb awaryjny: jeśli inicjowanie Vulkan nie powiedzie się z powodu problemów ze sterownikami na danym urządzeniu, silniki często przełączają się na OpenGL ES bez zgłaszania błędów krytycznych.
Pomiary za pomocą APA
Za pomocą narzędzia Android Performance Analyzer możesz zarejestrować śledzenie systemu i dokładnie przeanalizować dane klatek za pomocą zapytań SQL. Aby zmierzyć wykorzystanie Vulkan i GLES:
Przechwyć śledzenie systemu za pomocą APA: uruchom grę i użyj APA, aby przechwycić śledzenie systemu podczas segmentu, który chcesz przeanalizować, np. w momencie rozgrywki, w którym podejrzewasz, że dochodzi do gubienia klatek. Po połączeniu urządzenia i zakończeniu nagrywania śladu dane śledzenia zostaną załadowane w interfejsie APA.
Kliknij kartę SQL w APA: gdy ekran analizy logów czasu jest otwarty, w menu nawigacyjnym interfejsu kliknij kartę SQL, aby otworzyć środowisko procesora logów czasu, w którym możesz bezpośrednio wysyłać zapytania do danych.
Wklej to zapytanie SQL na karcie APA SQL: skopiuj to zapytanie SQL i wklej je w polu do wprowadzania danych. To zapytanie skanuje log czasu pod kątem zdarzeń interfejsu API rysowania, takich jak
eglSwapBuffers,QueuePresentKHRivkQueuePresentKHR. Grupują je według nazwy procesu i obliczają liczbę wywołań interfejsu API renderowania oraz procentowy rozkład wywołań renderowania Vulkan i 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;Uruchom zapytanie: kliknij przycisk Uruchom zapytanie obok pola do wprowadzania danych. Po uruchomieniu zapytania w panelu wyników pojawi się tabela zawierająca nazwę procesu (
process_name), liczbę prezentacji OpenGL ES (egl_count), liczbę prezentacji Vulkan (vulkan_count), łączną liczbę prezentacji (total_count) oraz odsetek użycia poszczególnych interfejsów API (egl_percentage(%)ivulkan_percentage(%)).
Ekran z wykonanym zapytaniem SQL i wynikowymi danymi interfejsu API renderowania wyświetlanymi w tabeli
Typowe problemy
Unikaj pomyłek związanych z
SurfaceFlinger: zawsze ograniczaj wyszukiwanie do wątku aplikacji gry (RenderThread). Procesy kompozytora w całym systemie, takie jakSurfaceFlinger, mogą wyświetlać ścieżki Vulkan lub EGL, które reprezentują renderowanie interfejsu systemu, a nie wewnętrzny potok renderowania gry. Aby wyodrębnić swoją grę, usuń znacznik komentarza z opcjonalnych filtrów w klauzuliWHEREgłównego zapytania SQL i zastąp'com.example.mygame'nazwą pakietu gry:-- AND p.name = 'com.example.mygame' -- AND t.name = 'RenderThread'Okres rozgrzewki: zawsze rejestruj ślad po pełnym załadowaniu głównej sceny 3D w grze. Przechwytywanie podczas wyświetlania ekranów powitalnych lub przejść wczytywania może prowadzić do błędnych inicjalizacji.
Wymagania dotyczące śledzenia zwolnień w programie LevelUp
Jeśli używasz narzędzia Android Performance Analyzer (APA) do przechwytywania śladu, aby kwalifikować się do zwolnienia z wymagań LevelUp w Grach Google Play, musisz spełnić określone wymagania sprzętowe, aby ślad był prawidłowy.
Zdecydowanie zalecamy przechwytywanie logu czasu za pomocą jednego z urządzeń referencyjnych Level Up.
Aby zapewnić dokładną weryfikację, ślad nie może być pobierany na urządzeniu korzystającym z GPU ANGLE. W szczególności nie możesz używać tych urządzeń do przechwytywania logu czasu wyjątku LevelUp:
- Dowolne urządzenie, którego dostawcą GPU jest SLSI (Samsung), korzystające z GPU AMD Xclipse
- Pixel 11