Профілювання GPU-рендерингу мобільної програми
60 FPS на екрані — це 16.67 мс на кадр. З них CPU готує команди рендерингу, передає їх GPU, GPU малює. Якщо GPU не встигне закінчити до наступного vsync — кадр пропущено. Користувач бачить jank. Але де саме GPU гальмує — без профайлеру неможливо сказати: overdraw, надто складні шейдери, величезні текстури, некоректна робота тайлінгу — причини різні та потребують різних рішень.
Інструменти GPU-профілювання
Android GPU Inspector (AGI)
Google's Android GPU Inspector — найпотужніший інструмент для мобільного GPU. Працює з Adreno (Qualcomm) та Mali (ARM). Потребує пристрій з підтримкою GPU counter profiling — більшість флагманів 2020+ підтримують.
AGI показує:
- GPU Counter — навантаженість шейдерних юнітів, bandwidth, cache hit rate
- Frame Profiler — розбивку кожного кадру за draw calls, час на вершинний та фрагментний шейдер
- Memory — споживання VRAM, текстурний кеш
Критична метрика — Fragment ALU utilization вища за 90% при одночасно низькому Primitive Assembly говорить: проблема у фрагментному шейдері, а не у геометрії. Спрощення шейдера або LOD-система — правильний напрямок.
Xcode Metal Debugger + GPU Frame Capture
Для Metal-програм на iOS — GPU Frame Capture у Xcode. Захоплює один кадр та розбирає його за draw calls. Показує:
- Кожен
MTLRenderCommandEncoderта його внесок у час кадру - Heatmap — які пікселі малюються скільки разів (overdraw visualization)
- Shader profiler — час виконання конкретних інструкцій шейдера з вказанням строки вихідного коду
Для UIKit/SwiftUI — Core Animation Instrument у Instruments. Показує CATransaction, offscreen-rendering passes (жовті шари в Debug → Color Offscreen-Rendered), layer composition.
Включаємо Debug → Color Blended Layers у симуляторі: червоні зони — шари з alpha blending. Кожен червоний піксель малюється двічі (або більше). На екрані з 60% червоного — реальна проблема для бюджетних пристроїв.
Профілювання на Adreno: Snapdragon Profiler
Snapdragon Profiler (Qualcomm) дає найдеталізованішу картину для Adreno GPU: L1/L2 cache miss rate, texture cache utilization, ALU стеки. Використовуємо, коли AGI не дає достатньої деталізації або потрібна робота з Vulkan-програмою.
Що шукаємо та як виправляємо
Overdraw. Developer Options → GPU Overdraw на Android, Debug → Color Blended Layers у симуляторі iOS. Мета — мінімізувати red/pink зони. Видаляємо зайві фони в ViewGroup, встановлюємо opaque = true там, де прозорість не потрібна.
Offscreen rendering passes. CALayer з cornerRadius + masksToBounds на iOS запускає offscreen render pass — малює шар до окремого буфера, потім composit на екран. На списку з 50 ячейок кожна з cornerRadius — 50 зайвих offscreen passes за кадр. Рішення: малюємо скруглені кути через UIBezierPath у drawRect або через фонове зображення з прозорими кутами.
Texture oversized. Текстура 2048×2048 для іконки 44×44 pt — GPU завантажує зайві дані, витрачає cache bandwidth. MTKTextureLoader з MTKTextureLoaderOptionGenerateMipmaps: true та правильним MTKTextureLoaderOptionTextureUsage для mipmapping — стандарт для 3D та складного UI.
Випадок: 30 FPS на Adreno 650
Карткова гра на Unity: на Samsung S21 (Adreno 650) тримала 30 FPS замість очікуваних 60. AGI показав: Fragment ALU utilization 98%, тоді як Vertex Processing — 12%. Фрагментний шейдер води містив 4 семплювання текстури + normal mapping + fresnel-розрахунок. На мобільному GPU фрагментні шейдери дорожчі за вертикальні.
Рішення: спрощений шейдер води для мобільної платформи (2 текстурні семпли замість 4), fresnel апроксимація через dot(viewDir, normal) без pow(). FPS виріс до 58–60 стабільно.
Часові рамки
GPU-профілювання та аналіз — 2–3 дні. Оптимізація рендерингу за результатами — 3–10 днів залежно від складності знайдених проблем.







