Технические вопросы и ответы QA1612

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.