Это очень интересный вопрос, и я боролся с этой проблемой с нескольких сторон.
Проблема довольно сложная и зависит от платформы, вы, кажется, работаете на EGL, что означает встроенный, и у вас есть несколько вариантов, если только ваша платформа их не предлагает.
У вас есть следующие варианты:
glTexSubImage2D
glTexSubImage2D может копировать несколько видов буферов из текстур OpenGL. в память процессора. К сожалению, он не поддерживается в GLES 2/3, но ваш встроенный провайдер может поддерживать его через расширение. Это хорошо, потому что вы можете либо рендерить в FBO, либо получать пиксели из конкретной текстуры, которая вам нужна. Он также требует минимального вмешательства в код.
glReadPixels
glReadPixels — наиболее распространенный способ загрузки всех или часть пикселей графического процессора, которые уже обработаны. Хоть и медленно, но работает на GLES и Desktop. На настольном компьютере с приличным графическим процессором терпимо вплоть до частоты кадров в интерактивном режиме, но будьте осторожны, во встроенном режиме он может быть действительно медленным, поскольку останавливает поток рендеринга для получения данных (ужасные потери кадров обеспечены). Вы можете сохранить код, так как его можно заставить работать с минимальными изменениями кода.
Объекты пиксельного буфера (PBO)
Как только вы начнете проводить реальные исследования, -object-on-mali-t-880" rel="nofollow noreferrer">PBO появляются тут и там, потому что их можно заставить работать асинхронно. Они также, как правило, не поддерживаются во встраиваемых системах, но могут очень хорошо работать на настольных компьютерах даже на посредственных графических процессорах. Также немного сложно настроить и потребовать определенных модификаций рендеринга.
Кадровый буфер
На встроенном иногда вы уже выполняете рендеринг в фреймбуфер, поэтому идите туда и извлекайте пиксели. Также работает на рабочем столе. Вы можете mmap()
преобразовать буфер в файл и легко получить частичное содержимое. Но будьте осторожны, во многих встроенных системах EGL работает не с фреймбуфером, а с другим «оверлеем», поэтому вы можете сделать снимок фона. Также следует отметить, что некоторые мультимедийные приложения запускаются с пользовательским интерфейсом в EGL и медиаплеерами в буфере кадра. Так что, если вам нужно захватить только видеоплееры, это может вам подойти. В других случаях EGL нацелен на текстуру, которая копируется во фреймбуфер, и он также будет работать нормально.
Насколько я знаю, рендеринг в текстуру и поток в фреймбуфер - это то, как они сделали приятный пользовательский интерфейс Qt, который вы видите на Ableton Push 2
Более экзотический Dispmanx/OpenWF
На некоторых встроенных системах (в частности, на Raspberry Pi и большинстве Broadcom Videocore) у вас есть DispmanX. Что действительно интересно:
Это весело:
Самый низкий уровень доступа к графическому процессору, по-видимому, осуществляется через API под названием Dispmanx[...]
Это продолжается...
Просто чтобы дать вам полное отсутствие вдохновения от использования Dispmanx, почти нет примеров и серьезной документации.
В основном DispmanX очень близок к baremetal. Так что это даже глубже, чем фреймбуфер или EGL. Действительно интересный материал, потому что вы можете использовать vc_dispmanx_snapshot()
и очень быстро получить моментальный снимок всего. И под быстротой я подразумеваю, что я получил снимок экрана RGBA32 со скоростью 30 кадров в секунду без заметного заикания на экране и около 4–6% дополнительных ресурсов процессора на Rasberry Pi. Ночью и днем из-за glReadPixels производил очень заметные падения кадров даже при захвате 1x1 пиксель.
Это почти то, что я нашел.
person
Ariel M.
schedule
12.06.2020
LD_PRELOAD
при запуске приложения. - person Velkan   schedule 22.11.2017