Я пишу программу, в которой мне нужно максимально эффективно получить доступ к пиксельным данным окна X11, в идеале через общую память, без необходимости выполнять вызовы XCB каждый раз, когда я хочу обновить пиксельные данные. Это аналогичная опция Xvfb
-shmem
, но я хочу получить доступ к данным пикселей каждого окна через общую память, а не ко всему экрану.
Я могу настроить X-сервер любым способом, который поможет в этом. X-сервер работает без управления и не подключен к реальному видеооборудованию.
Мне известны расширения XShm и XComposite. Насколько я вижу, каждый из них делает только половину того, что мне нужно:
Могу ли я каким-то образом объединить эти два расширения, чтобы иметь прямой доступ к данным пикселей окна из моего собственного приложения без необходимости постоянно просить X-сервер копировать данные пикселей?
Возможно, вам нужен XRender? Это настолько быстро, насколько это возможно.
@n.m.couldbeanAI Я понимаю, почему так обстоит дело с «обычными» X-серверами, подключенными к реальному оборудованию, но в моем случае он работает без видеооборудования (отредактированный вопрос, чтобы прояснить это). Спасибо за ссылку на XRender, хотя он выглядит как наиболее близкий ответ на то, что я ищу в случае с реальным оборудованием.
X11 не имеет специального лечения для этого случая. Было бы кошмаром реализовать это. Память оконного буфера изначально не является непрерывной внутри кадрового буфера. Кроме того, окно может быть частично затемнено и/или закрыто полупрозрачным окном, поэтому вы не сможете самостоятельно обновить буфер. В чем твоя проблема с Х?
Моя цель — создать способ прозрачного запуска ненадежных приложений с графическим интерфейсом на хосте Linux без виртуальной машины. С этой целью я пишу приложение для песочницы, которое запускает X-сервер внутри ядра пользовательского пространства (gVisor), и я хочу отображать содержимое окон, работающих на изолированном X-сервере, как обычные окна на X-сервере хоста. . Итак, я создаю окна на хост-X-сервере, и их пиксельные данные должны точно отражать пиксельные данные, содержащиеся в памяти изолированного X-сервера. Я изучаю, как это сделать с минимальным копированием памяти.
Я придумал кое-что, используя аргумент Xvfb
-fbdir
, который заставляет Xvfb
хранить данные пикселей для каждого экрана в виде файлов, отображаемых в памяти. Если я помещу каждое окно на отдельный экран и настрою экраны в соответствии с размерами окон, теоретически я смогу получить через это доступ к данным пикселей окна, хотя я еще не проверял, работает ли это за пределами одного экрана. Другой путь может быть чем-то вроде того, что делает Qubes с использованием поддельного видеодрайвера и запуска X-сервера с LD_PRELOAD
библиотекой, которая перехватывает вызовы X glibc для совместного использования страниц данных пикселей.
Согласно комментариям, это на самом деле невозможно, поскольку модель памяти X-сервера предполагает, что данные пикселей окна X11 находятся в памяти видеоаппаратуры, поэтому концепция «разделяемой памяти» с обычными процессами не обязательно имеет смысл в этом контексте. Однако в моем контексте X-сервер не работает на реальном видеооборудовании.
Лучшее решение, которое я нашел для своего варианта использования, — это использовать многоголовый экземпляр Xvfb
с флагом -fbdir
, установленным для каталога внутри /dev/shm
, а затем гарантировать, что каждое окно находится на своем собственном экране, размер которого соответствует размеру окна. размер. Затем каждый экран сопоставляется с окном один к одному, и каждый из них имеет отображаемый в памяти файл в каталоге, на который указывает -fbdir
.
Нет, вы не можете заставить данные пикселей размещаться в вашей собственной памяти. Чтобы показать изображение, вам нужна видеокарта, а карта дисплея имеет собственную память. Только данные в этой памяти могут быть отображены непосредственно. (Некоторые карты могут использовать основную оперативную память в качестве памяти дисплея, но не все).