Ниже приводится подборка вопросов для интервью из выпуска 18:
Вообще говоря, мы используем OpenGL когда,Инструкции выполняются не сразу. Сначала они отправляются в буфер инструкций.,Затем он отправляется на оборудование для выполнения.。glFinish
и glFlush
Все они принудительно отправляют содержимое командного буфера на оборудование для выполнения.
1)glFlush:
glFlush
Очистите буфер и отправьте инструкцию в аппаратный кэш для немедленного выполнения, но он возвращается сразу после передачи инструкции и не ждет выполнения инструкции. Эти инструкции будут выполнены в течение ограниченного времени.
2)glFinish:
glFinish
Немедленно отправьте инструкции из буфера оборудованию для выполнения, но перед возвратом подождите, пока оборудование завершит выполнение этих инструкций. Если вы рисуете непосредственно в переднем буфере, вам необходимо вызвать эту функцию, чтобы убедиться, что рисование завершено, прежде чем вы захотите сохранить снимок экрана. Если используется двойная буферизация, эта функция будет бесполезна.
Если звонишь glFinish
,Обычно приводит к потере производительности。потому чтодляэто будет GPU и CPU Параллельность теряется. Обычно задачи, которые мы отправляем драйверу, группируются, а затем отправляются на оборудование (во время обмена буфера). Если звонишь glFinish
,Просто заставьте водителя отправить команду графический процессор. Затем CPU Подождите, пока все переданные команды будут выполнены. Таким образом GPU В течение всего периода работы процессор Не помогло (по крайней мере в этой теме). И в CPU Во время работы (обычно группировки команд) графический процессор Никакой работы. Это приводит к снижению производительности.
3)glFlush и glFinish разница:
общее использование glFlush
Цель состоит в том, чтобы гарантировать, что после вызова процессор Нет OpenGL Необходимо выполнить соответствующие действия, и команда будет отправлена на оборудование для выполнения. вызов glFinish
Цель состоит в том, чтобы к вашему возвращению работа, связанная с Нетом, осталась невыполненной.
1) Зачем OpenGL нужна синхронизация?
Обычно мы звоним OpenGL После метода он не будет эффективен сразу. B Использование потока A Текстура потока имеет вероятность возникновения исключения, поскольку A Текстура также Нетрендеринг Заканчивать。
2) решение для синхронизации glFinish
Если вы хотите убедиться, что где-то раньше OpenGL После выполнения обычно используется glFinish
,Убедитесь, что он работает правильно. но glFinish
Он может только гарантировать, что команды в очереди команд, соответствующей этому потоку, будут выполнены, а это значит, что вы не можете ждать другого потока в одном потоке. OpenGL После выполнения команды действуют большие ограничения.
3) Решение для синхронизации ограждения
Напомним, что мы были CPU Синхронные операции, например, мы находимся в потоке подожди, в другой теме notify, легко дождаться в одном потоке завершения заданной задачи другого потока. Для нас это тоже очень распространенная операция, но для. Графический процессор, недоступен glFinish
реализовать аналогичную логику. Для OpenGL ES 3.0, мы можем использовать fence
Реализация и использование становятся все более простыми, достаточно вставить fence
,Потом в другомодиннить Вы можете войтиждатьэтот fence
。
Например, у нас есть такая логика, в GLThread 0 Рендеринг текстуры в другом потоке GLThread 1 Чтобы использовать эту текстуру, вам необходимо убедиться, что GLThread 1 При использовании этой текстуры GLThread 0 Рендеринг этой текстуры завершен. fence
Наконец, мы можем GLThread 0 Вставьте fence
,затем в GLThread 1 Если вы хотите использовать эту текстуру, подождите этого fence
。
вставлять fence
код, обычно многопоточный A вставлять:
GLsync fenceSyncObject = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
glFlush();
После вызова этого метода он будет добавлен в текущую очередь команд в виде fence
и возвращает long введите переменную для кодирования этого fence
Синхронизируйте объект, чтобы другие места могли его ждать. гл Флеш Эта функция гарантирована fence
Команду необходимо нажать GPU。
ждать fence
код, обычно многопоточный B ждать:
glClientWaitSync(fence, 0, GL_TIMEOUT_IGNORED);
glDeleteSync(fence);
иметь 2 Методы можно использовать для ожидания, glWaitSync
и glClientWaitSync
,Разница между ними заключается glWaitSync
находится в GPU начальствождать,glClientWaitSync
находится в CPU В ожидании. Это преимущество не будет блокироваться CPU , повысить эффективность рендеринга.
1) Базовое описание совместного использования ресурсов
OpenGL Контекст, связанный с «хаодининить» в рендеринге (Context), OpenGL Созданные ресурсы на самом деле представляют собой лишь контекст, видимый программисту. ID Всё, его содержимое зависит от этого контекста. Для удобства после создания контекста в определённом контексте содержимое контекста зависит от контекста. OpenGL Операции передаются в этот поток для вызова. Таким образом, простым способом 2d/3d Рендеринг — это нормально, но если он включает в себя сложные OpenGL При рендеринге этого может быть недостаточно, фактически OpenGL Рассмотрев это, Контекст может быть разделен между несколькими потоками. eglCreateContext час, Вы можете передать успешно созданный контекст, Таким образом, вы получаете общий контекст (Shared Context).
OpenGL Все команды рисования применяются к текущему Context Вверх, это Current Context это переменная одиннит приват хать (thread-local), то есть если мы рисуем нить, то для этого нить нужно сформулировать один Current Context Да, когда в задаче рисования участвует несколько нить, необходимо отвязать исходную нить и повторно привязать новую нить. Несколько нить не могут одновременно указывать один и тот же один. Context для Current Контекст, иначе это приведет к сбою.
2) Какие ресурсы может использовать OpenGL?
Ресурсы, которыми можно поделиться:
Нет Ресурсы, которыми можно поделиться:
FBO объект кадрового буфера (не является частью buffer добрый); VAO объект массива вершин (не является частью buffer добрый). Среди ресурсов, которыми нельзя делиться, FBO и VAO Это объект управления ресурсами, FBO. Отвечает за управление несколькими буферами и не занимает ресурсы VAO. Ответственный за управление VBO или EBO , сам ресурсов не отнимает.
3) Реализация общего контекста OpenGL?
Реализация iOS ShareContext:
- (EAGLContext *)shareContext:(nullable EAGLContext *)context {
EAGLContext *shareContext = [[EAGLContext alloc] initWithAPI:context.API sharegroup:context.sharegroup];
return shareContext;
}
Реализация Android ShareContext:
public EGLContext eglCreateContext(EGLDisplay display, EGLConfig config, EGLContext share_context, int[] attrib_list) {
EGLContext result = mEgl10.eglCreateContext(display, config,
share_context, attrib_list);
return result;
}
4) Каковы меры предосторожности в отношении общего контекста OpenGL?
1) Какова цель кэша текстур OpenGL?
2) Как спроектировать кэш текстур OpenGL?
3) Как реализовать привязку FBO к указанной текстуре?
Пример кода выглядит следующим образом:
void AttachTextureToFBO (GLuint texId) {
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texId, 0);
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
check(status);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}