Określanie interfejsu API renderowania gier Vulkan lub OpenGL ES

Podczas tworzenia lub optymalizowania gier na Androida często przydatne jest sprawdzenie, jakiego 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 platformie Vulkan, czy też cicho przełączyła się na OpenGL ES, może być zawodne.

Z tego przewodnika dowiesz się, jak za pomocą analizatora wydajności Androida (APA) i niestandardowych zapytań SQL Perfetto jednoznacznie określić aktywny interfejs API renderowania gry.

Ograniczenia weryfikacji na podstawie logów

  • Oczyszczone logi: kompilacje produkcyjne często ukrywają ślady inicjowania i ładowania sterowników.
  • Fałszywe alarmy: niektóre silniki gier wczytują podczas uruchamiania biblioteki Vulkan i OpenGL ES, wyświetlając dzienniki inicjowania dla obu tych bibliotek, nawet jeśli jedna z nich ostatecznie ulegnie awarii i spowoduje powrót do poprzedniej wersji.
  • Ciche wycofywanie: jeśli inicjowanie platformy Vulkan nie powiedzie się z powodu problemów ze sterownikami na konkretnym urządzeniu, silniki często wracają do OpenGL ES bez zgłaszania krytycznych błędów.

Pomiar za pomocą APA

Za pomocą narzędzia Android Performance Analyzer możesz rejestrować ślad systemowy i dokładnie analizować dane o klatkach za pomocą zapytań SQL. Aby zmierzyć wykorzystanie interfejsów Vulkan i GLES:

  1. Rejestrowanie śladu za pomocą APA: uruchom grę i użyj APA, aby zarejestrować ślad systemu w trakcie segmentu, który chcesz przeanalizować, np. w momencie rozgrywki, w którym podejrzewasz spadek liczby klatek. Po podłączeniu urządzenia i zakończeniu nagrywania śladu dane śladu zostaną wczytane w interfejsie APA.

  2. Kliknij kartę SQL w APA: gdy otworzysz ekran analizy śladu, w menu nawigacyjnym interfejsu kliknij kartę SQL, aby otworzyć środowisko procesora śladów, w którym możesz bezpośrednio wysyłać zapytania dotyczące danych.

  3. Wklej to zapytanie SQL na karcie SQL APA: skopiuj to zapytanie SQL i wklej je w polu do wprowadzania danych zapytania. To zapytanie skanuje ślad pod kątem zdarzeń interfejsu API rysowania, takich jak eglSwapBuffers, QueuePresentKHR i vkQueuePresentKHR. Grupuje je według nazwy procesu i oblicza 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;
    
  4. Uruchom zapytanie: kliknij przycisk Uruchom zapytanie obok pola do wprowadzania danych. Po uruchomieniu zapytania w okienku wyników pojawi się tabela z nazwą procesu (process_name), liczbą prezentacji OpenGL ES (egl_count), liczbą prezentacji Vulkan (vulkan_count), łączną liczbą prezentacji (total_count) oraz odsetkiem użycia każdego interfejsu API (egl_percentage(%)vulkan_percentage(%)).

    Ekran z wykonanym zapytaniem SQL i wyświetlonymi w tabeli wynikowymi danymi interfejsu API renderowania

Typowe pułapki

  • Unikaj SurfaceFlingernieporozumień: zawsze ograniczaj wyszukiwanie do wątku aplikacji gry (RenderThread). Procesy kompozytora w całym systemie, takie jak SurfaceFlinger, mogą wyświetlać ścieżki Vulkan lub EGL, które reprezentują renderowanie interfejsu systemu, a nie wewnętrzny potok renderowania gry. Aby wyodrębnić grę, usuń znacznik komentarza z opcjonalnych filtrów w klauzuli WHERE głó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 wczytaniu głównej sceny 3D gry. Rejestrowanie podczas ekranów powitalnych lub przejść wczytywania może powodować wprowadzające w błąd inicjalizacje.

Wymagania dotyczące śledzenia zwolnień z programu LevelUp

Jeśli używasz narzędzia Android Performance Analyzer (APA) do rejestrowania śladu, aby uzyskać zwolnienie z wymagań programu LevelUp w Gry Google Play, musisz spełnić określone wymagania sprzętowe, aby ślad był ważny.

Zdecydowanie zalecamy rejestrowanie śladu za pomocą jednego z urządzeń referencyjnych Level Up.

Aby zapewnić dokładną weryfikację, ślad nie może być rejestrowany na urządzeniu korzystającym z procesora graficznego ANGLE. W szczególności nie możesz używać tych urządzeń do rejestrowania śladu zwolnienia z LevelUp:

  • Każde urządzenie, którego dostawcą GPU jest SLSI (Samsung) i które korzysta z układów GPU AMD Xclipse.
  • Pixel 11