Почему в GLSurfaceView.Renderer нет метода onSurfaceDestroyed?

Я работаю над приложением для Android, которое выполняет взаимодействия OpenCL/OpenGL для просмотра камеры. Я использую GLSurfaceView.Renderer. Естественно, код для создания и инициализации рабочей среды OpenCL (из OpenGL) вызывается из onSurfaceCreated, а фактическая обработка каждого кадра предварительного просмотра происходит в onDrawFrame.

Все работает хорошо, кроме того, когда я закончу, я хочу очистить OpenCL. В идеале метод onSurfaceDestroyed был бы идеальным местом для очистки, но в GLSurfaceView.Renderer такого метода нет. Таким образом, коду очистки некуда деться, и, вероятно, в моем приложении есть утечка памяти.

Вот мои вопросы:

  1. Почему в GLSurfaceView.Renderer нет метода onSurfaceDestroyed? Существуют onSurfaceCreated и onSurfaceChanged. Можно ожидать, что OnSurfaceDestroyed будет там.

  2. Учитывая тот факт, что onSurfaceDestroyed не существует в GLSurfaceView.Renderer, куда должен идти мой код очистки и почему?

1 ответ

Решение

GLSurfaceView представляет собой набор вспомогательного кода, который упрощает использование OpenGL ES с SurfaceView. Вы не обязаны использовать это для использования GLES, и если у вас есть куча других вещей, происходящих в то же время, я рекомендую вам не делать этого.

Если вы сравните сложность Grafika " show + capture camera", которая использует GLSurfaceView, с " непрерывным захватом", который использует обычный SurfaceView, вы можете увидеть, что последний требует кучу дополнительного кода для управления EGL и потоком рендерера, но у него также меньше прыжков, потому что ему не нужно бороться с EGL и управлением потоками GLSurfaceView. (Просто прочитайте комментарии в верхней части класса CameraCaptureActivity.)

Как заметил один из комментаторов, я подозреваю, что нет обратного вызова "при уничтожении", потому что класс агрессивно разрушает свой контекст EGL, поэтому очистка GLES не требуется. Конечно, было бы полезно, чтобы поток рендерера имел возможность очистить ресурсы, не относящиеся к GLES, но это не так, поэтому вы должны обрабатывать это с помощью обратных вызовов жизненного цикла Activity. (В какой-то момент разработки CameraCaptureActivity обрабатывал камеру в потоке рендерера, но отсутствие надежного обратного вызова отключения делало это трудным.)

Ваш код очистки, вероятно, должен основываться на обратных вызовах жизненного цикла Activity. Обратите внимание, что они несколько отделены от обратных вызовов SurfaceView. Полное объяснение можно найти в приложении к документации по архитектуре.

Другие вопросы по тегам