SurfaceTexture AttachToGLContext и Surface

Я пытаюсь выяснить, нужно ли мне переделывать Surface, если я хочу вызвать метод attachToGLContext из SurfaceTexture. Я пытался посмотреть в документации по андроиду, но там нет упоминания.

Я предполагаю, что не потому, что, насколько мне известно, Surface — это буфер для SurfaceTexture, который может действовать как внешняя текстура для контекста OpenGL. Таким образом, присоединение SurfaceTexture к другому контексту не должно влиять на это.

Кто-нибудь знает наверняка?


person Kongo    schedule 22.08.2015    source источник


Ответы (1)


Внутреннее имя SurfaceTexture — «GLConsumer». Поверхности имеют отношения производитель-потребитель, а SurfaceTexture — это потребитель, который берет все, что получает, и делает это доступным в виде текстуры GLES.

Присоединенная к нему поверхность (обычно с помощью конструктора поверхности, который принимает SurfaceTexture в качестве аргумента) является стороной производителя. Хотя существует очередь буферов, участвующих в обмене данными между производителем и потребителем, не совсем точно описывать Surface как «буфер». Это больше похоже на конечную точку связи, которая отправляет графические данные потребителю.

Изменение контекста EGL, связанного со стороной потребителя, не повлияет на сторону производителя. Вызовы attach/detach не отключают производителя. Они влияют только на то, что SurfaceTexture делает с буферами данных, которые он получает.

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

person fadden    schedule 22.08.2015
comment
Да, у меня есть служба, которая декодирует кадры медиакодека в текстуру поверхности. У меня есть приложение с несколькими действиями, каждое из которых имеет разное количество поверхностей EGL. Таким образом, я могу привязать текстуру поверхности к разным контекстам EGL из разных активностей. Есть ли способ сохранить один и тот же контекст EGL и передать его от действия к действию с намерением? Я не знаю всех последствий многопоточности, если я попытаюсь это сделать. - person Kongo; 23.08.2015
comment
Контекст EGL может быть текущим только в одном потоке за раз. Если вы сохраните ссылку на него в статической переменной, вы можете сделать его неактуальным в текущем потоке и отправить намерение, которое сообщает следующему действию, что оно теперь ваше. В качестве альтернативы свяжите контекст EGL с потоком, который не умирает, и просто взаимодействуйте с ним с каждым действием (через Looper/Handler). Совместное использование контекста с другими обычно является хорошей идеей — тогда вы можете напрямую ссылаться на внешнюю текстуру в других контекстах. - person fadden; 23.08.2015
comment
Я все еще немного неуверен в номенклатуре. Контекст EGL — это EGLcore, да? И ваше второе предложение о потоке, который не умирает... Я должен убедиться, что этот поток выполняет всю работу по рисованию и настройке, да? Поэтому мне нужно, чтобы обработчик получал ссылки на SurfaceTextures из действий, передал их в поток, настраивал WindowSurfaces, вызывал makeCurrent(), а затем рисовал все в потоке. - person Kongo; 24.08.2015
comment
Я представлял себе выделенный поток, который получает кадры MediaCodec с SurfaceTexture. Связанный контекст EGL создается первым. Различные другие потоки, которым необходимо выполнить рендеринг, имеют контексты EGL, которые разделяют состояние с первым контекстом, чтобы они могли получить доступ к текстуре из SurfaceTexture. См. действие камеры Grafika «показать + захватить», которое отрисовывается в GLSurfaceView из одного потока и в кодировщик MediaCodec в другом, используя текстуру в общем контексте. - person fadden; 24.08.2015
comment
Класс EglCore в Grafika имеет EGLContext и отношение 1:1, но EglCore не является EGLContext. EGLContext — это тонкая оболочка вокруг собственного объекта контекста EGL, который определяется OpenGL ES. - person fadden; 24.08.2015
comment
Спасибо. Я посмотрю на это. - person Kongo; 24.08.2015
comment
@fadden При показе + камера захвата вы рисуете на экране в одном потоке и рисуете в кодировщике в другом. И 2 потока разделяют один контекст opengl. Я обеспокоен тем, что 2 действия рисования будут конфликтовать друг с другом из-за общего контекста. Каково ваше мнение? - person dragonfly; 07.03.2017
comment
@dragonfly: ты прав, когда беспокоишься; см. github.com/google/grafika/issues/36. - person fadden; 07.03.2017
comment
@fadden Прямо сейчас. У меня работа именно такая, две внешние текстуры поверхности в 2 потока. Я хочу нарисовать 2 текстуры в один FBO для слияния изображений. Я закончил код с общим контекстом gl. Но демонстрация зависает через несколько секунд (иногда более 10 секунд). Что мне делать для такой многопоточной работы? Поможет ли мне API attachToGLContext/detach? - person dragonfly; 07.03.2017
comment
Корректная многопоточная обработка текстуры с общим контекстом требует определенного поведения производителя и потребителя, отмеченного в проблеме github, ссылка на которую была указана ранее. Вы можете проверить AOSP, чтобы убедиться, что модуль записи текстур делает то, что вам нужно (например, glFinish() после updateTexImage()). Нет никакой гарантии, что реализация не изменится в будущем, хотя я бы сказал, что она вряд ли изменится существенным образом. Затем вам нужно повторно привязать текстуру, что должно выполняться присоединение/отсоединение. (FWIW, я бы искал более простой общий подход.) - person fadden; 07.03.2017