Нужны некоторые подробности о том, как SurfaceFlinger и BufferQueue работают на платформе Android.
Исследую проблему с зависанием приложения. Проблема воспроизводится только на Samsung S22 с включенной функцией адаптивной настройки частоты кадров. Мое приложение использует opengl для отображения своего содержимого. Также мы используем виджет VideoView из Android SDK для воспроизведения коротких фильмов. Проблема возникает в тот момент, когда воспроизведение видео приостанавливается и перемещается за пределы экрана. Как я вижу, собственный поток рендеринга моего приложения зависает при вызове.
Насколько я понимаю, Android-рендеринг работает примерно так:
- мое приложение создает буфер с данными во время кадра.
- после того, как данные готовы, он выполняет
eglSwapBuffers
. Это включает в себяqueueBuffer()
передавая данные в BufferQueue SurfaceFlinger, затем ждет следующего свободного буфера вdequeueBuffer()
. - на сигнале VSYNC-sf SurfaceFlinger берет буфер и передает его потребителю (я думаю, HWC?).
- Некоторые внешние потребители используют буфер, рисуют данные, а затем снова освобождают буфер.
Из дампа systrace я вижу, что в какой-то момент SurfaceFlinger перестает обрабатывать буферы в очереди, BufferQueue поднимается до максимума, и приложение зависает, пытаясь удалить из очереди следующий свободный буфер при вызове eglSwapBuffers. Больше не надоacquireBuffer()
илиreleaseBufferCallback()
бывает.
Возникают вопросы: кто является стороной потребителя? Как я могу отследить, какая система выходит из строя? Почему SurfaceFlinger может перестать обрабатывать буферы?
Любые предложения высоко ценятся! С наилучшими пожеланиями!