Предотвратить onPause от уничтожения контекста OpenGL - PullRequest
21 голосов
/ 21 января 2010

Я пишу приложение для Android, которое использует OpenGL ES (GLSurfaceView и GLSurfaceView.Renderer). Проблема в том, что когда пользователь переключает приложения, а затем переключается обратно на мое приложение, GLSurfaceView уничтожает и воссоздает контекст GL. Это то, что он должен делать в соответствии с документацией, но есть ли способ предотвратить это?

Загрузка текстур в контекст занимает много времени, и я бы не хотел их перезагружать.

Ответы [ 4 ]

15 голосов
/ 09 февраля 2010

Я думаю, что то, что вы ищете, обсуждается в документации GLSurfaceView:

GLSurfaceView должен быть уведомлен, когда действие приостановлено и возобновлено. Клиенты GLSurfaceView обязаны вызовите onPause (), когда активность pauses и onResume (), когда деятельность возобновляется. Эти звонки позволяют GLSurfaceView, чтобы приостановить и возобновить рендеринг потока, а также разрешить GLSurfaceView для выпуска и воссоздания дисплей OpenGL.

При использовании стандартного Android SDK вы должны освобождать / воссоздавать свой контекст всякий раз, когда действие приостанавливается / возобновляется (включая изменения ориентации экрана). В противном случае контекст GL будет освобожден и не восстановлен при загрузке действия обратно в память. Помните, что мы имеем дело с очень ограниченными ресурсами (особенно на устройствах с низким уровнем спецификации). Итак, короткий ответ: вы не можете предотвратить это, не сломав свое приложение.

Если вы используете стандартную платформу Android / OpenGL, вам нужно сделать следующее ...

В своей деятельности убедитесь, что у вас есть следующие переопределенные методы:

public void onPause() {
    myGlSurfaceView.onPause();
}

public void onResume() {
    myGlSurfaceView.onResume();
}

Все, что вы храните вне среды GL, все равно необходимо будет сохранить и восстановить вручную (растровые изображения, состояние игры и т. Д.), Для этого вам потребуется использовать статические поля или механизм, такой как SharedPreferences.

Обновление

Android 3.x предоставляет функцию для сохранения контекста GL при паузе без необходимости повторного создания. Однако есть несколько предостережений:

  1. Функции Android 3.x недоступны для прибл. 90% устройств на рынке в настоящее время
  2. Устройства также должны поддерживать несколько контекстов EGL, неясно, сколько устройств на рынке в настоящее время поддерживают это.

Используя некоторое отражение API для проверки возможностей, возможно, будет возможно использовать эту функцию на поддерживающих устройствах. Однако вам все равно придется вернуться к воссозданию контекста для остальных. По моему мнению, до тех пор, пока на Android 3 не будет работать больше устройств, было бы лучше не использовать setPreserveEGLContextOnPause и сосредоточиться на том, чтобы подход к контекстному воссозданию был достаточно протестирован.

8 голосов
/ 23 июня 2012

Как упомянуто в комментарии выше, также возможно избежать разрушения контекста GL более ранних выпусков Android (1.x, 2.x), решение состоит в том, чтобы скопировать GLSurfaceView из исходного кода Android-15 SDK, изменить его пакет имя, а затем используйте свою собственную копию GlSurfaceView.

Он должен работать для устройств, которые поддерживают несколько контекстов GL (за исключением чипов Adreno, на данный момент), независимо от версии Android. Предостережение заключается в том, что GLSurfaceView из Android-15 содержит только необходимый материал для работы с Android-15, наша версия должна обрабатывать все версии ОС.

Мы используем нашу собственную реализацию GlSurfaceView, основанную на копии из ReplicaIsland, где Крисс Пруит также использовал свою собственную реализацию.

В нашей версии мы добавили setPreserveEGLContextOnPause из SDK-15, который позволяет сохранить контекст GL, например, на нексусе под управлением Android 2.3.

Мы также изменили другие элементы в соответствии с нашими потребностями, что не относится к этому вопросу (например, 32-разрядный рендеринг на телефонах, которые его поддерживают, в противном случае 16-разрядный).

Наш GlSurfaceView: http://pastebin.com/U4x5JjAr

Вот оригинальная SDK-15 версия GlSurfaceView, отформатированная в том же стиле (Android), что и выше http://pastebin.com/hziRmB3E (чтобы было легко сравнивать и видеть изменения)

Не забудьте включить сохранение контекста, позвонив по номеру:

    glSurfaceView.setPreserveEGLContextOnPause(true);
3 голосов
/ 04 января 2012

Начиная с уровня API 11, вы можете указать, должен ли ваш контекст сохраняться.

Из документа:

public void setPreserveEGLContextOnPause (логическое preserveOnPause) С тех пор: Уровень API 11

Управляет сохранением контекста EGL, когда GLSurfaceView приостановлено и возобновлено.

Если установлено значение true, контекст EGL может быть сохранен, когда GLSurfaceView приостановлен. Сохранен ли контекст EGL на самом деле или нет, зависит от того, является ли Android-устройство программой запуск может поддерживать произвольное количество контекстов EGL или нет. Устройства, которые могут поддерживать только ограниченное количество контекстов EGL, должны освободить контекст EGL, чтобы несколько приложений могли поделиться графическим процессором.

Если установлено значение false, контекст EGL будет освобожден, когда GLSurfaceView приостанавливается и воссоздается, когда GLSurfaceView возобновлен.

По умолчанию установлено значение false.

Параметры preserveOnPause preserve EGL контекст, когда пауза

0 голосов
/ 04 февраля 2010

Прошло много времени с тех пор, как я работал с OpenGL, и это была стандартная сортировка на настольных ПК, но я помню, что стандартный OpenGL не требует перезагрузки текстур при переключении контекста. Конечно, это не очень помогает в этом случае.

Предполагая, что текстуры должны быть перезагружены, возникает вопрос: как вы ускорите это? И тогда возникает вопрос, сколько текстур вам нужно одновременно и можете ли вы загружать их по требованию? Каковы их размеры? Я помню, что полномочия двух обычно быстрее загружались, хотя это также может зависеть от реализации OpenGL и драйверов.

Я также слышал о хранении контекста где-нибудь, где он не будет разрушен, как-то вроде этого потока: проблема переключения представления opengles

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...