У меня точно такая же проблема.
Мое решение использует прокси текстуры . Это означает, что когда вы создаете текстуры, используя некоторые данные из памяти или файла, вы создаете фиктивную текстуру, которая содержит копию этих данных в памяти или путь к файлу (вы можете предварительно загрузить данные в память для более быстрой загрузки).
После этого в следующий раз, когда мой рендерер вызывает bind () (что-то вроде glBindTexture), я проверяю, есть ли данные для загрузки, и, если они существуют, я просто создаю новую текстуру и загружаю данные.
Этот подход подходит мне лучше всего, потому что в моем случае текстуры могут быть созданы из любого потока и в любое время.
Но если вы хотите предварительно загрузить все текстуры, вы можете просто сделать это в onSurfaceCreated
или onSurfaceChanged
То же самое относится и к буферам.
Другой подход заключается в использовании нативной активности (посмотрите пример NDK). В этом случае вы можете обрабатывать контекст вручную, но для этого требуется уровень API 9.