OpenGL многопоточность ES и EAGLSharegroup
Q: В моей многопоточности OpenGL приложение ES я загружаю текстуры (или вершины) на вторичном потоке тогда рисуют их на экран на основном потоке. Иногда я вижу пустые изображения или замораживания приложения. Что могло вызывать это?
A: В моей многопоточности OpenGL приложение ES я загружаю текстуры (или вершины) на вторичном потоке тогда рисуют их на экран на основном потоке. Иногда я вижу пустые изображения или замораживания приложения. Что могло вызывать это?
Вероятно, что основные и фоновые потоки получают доступ к тому же OpenGL контекст ES одновременно.
Команды OpenGL ES для определенного контекста не повторно используемы. У Вас никогда не должно быть больше чем одного потока, получающего доступ к единственному контексту одновременно. Это настоятельно рекомендовано это, Вы используете только один поток на контекст.
Перечисление 1 демонстрирует, как создать и сделать текущим контекст contextB использование sharegroup свойство ( EAGLSharegroup объект) полученный из другого уже выделенного контекста contextA. Такие контексты, принадлежащие тому же sharegroup, могут совместно использовать ресурсы, например, текстуры, FBOs, и т.д. Таким образом, можно использовать contextB на вторичном потоке для создания текстур, и contextA на основном потоке для рисования текстур на экран.
Перечисление 1 , Создающее контекст, принадлежащий тому же sharegroup
contextB = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1
sharegroup:contextA.sharegroup];
if (!contextB || ![EAGLContext setCurrentContext:contextB]) {
// Handle errors here
} |
Когда Вы хотите изменить ресурс на одном контексте, необходимо сначала удостовериться, что это не используется в настоящее время на другом даже при доступе к ним от различных потоков. Как только Вы изменяете его, его состояние не определено до сбрасывания, и привязка объекта были завершены. Вы никогда не должны использовать неопределенный объект, получаете ли Вы доступ к нему от различного контекста или нет.
Возьмите текстуру в качестве примера. Перечисление 2 показывает корректный способ иметь дело с многократными контекстами. Любое другое упорядочивание не гарантирует непротиворечивое и корректное поведение. Это может привести к повреждению данных, утечкам или катастрофическим отказам иначе.
Перечисление 2 , Изменяющее текстуру на контексте B до использования его на контексте A
// 1. Ensure context A is not bound to the texture [EAGLContext setCurrentContext:contextA]; glBindTexture(GL_TEXTURE_2D, 0); // 2. Call flush on context A glFlush(); // 3. Modify the texture on context B [EAGLContext setCurrentContext:contextB]; glBindTexture(GL_TEXTURE_2D, texId); // // Modify the texture data here // // 4. Call flush on context B glFlush(); // 5. Rebind the texture on context A [EAGLContext setCurrentContext:contextA]; glBindTexture(GL_TEXTURE_2D, texId); // 6. Use the texture as normal on context A |
Для получения дополнительной информации о EAGLContext/-initWithAPI:sharegroup: API и sharegroup свойство, посмотрите Ссылку класса EAGLContext.
История версии документа
| Дата | Примечания |
|---|---|
| 09.03.2010 | Новый документ, обсуждающий методы наиболее успешной практики для разработки многопоточности OpenGL приложения ES с классом EAGLSharegroup. |