LINUX.ORG.RU

Что быстрее (XGetImage+XPutImage) VS XCopyArea VS (XShmGetImage + XShmPutImage) VS GTK+?

 , , , ,


3

2

Доброго времени суток.

Написал программу, которая содержимое одного окна отображает в другом. Допустим у меня есть Xlib'ный тип Window, есть переменные этого типа, SrcWin и TrgWin, для удобства у обоих один и тот же размер (683*752), который никогда не изменится, одна глубина изображения. SrcWin это окно какого то реального приложения.

Программа раз в 40мс копирует изображение из SrcWin в TrgWin, с помощью XGetImage и XPutImage, на i5-3337U программа берёт почти 20% процессорного времени, процесс Xorg загружает проц примерно на столько же.

Программа работает как ожидалось, однако меня сильно напрягает высокая нагрузка на процессор.

Три вопроса: 1) Альтернативы, указанные в названии темы, могут значительно снизить нагрузку на процессор? Просто было бы здорово, не копировать данные, а отображать буфер пикселей одного окна в соответствующий буфер другого (скопировать значение указателя на область памяти с изображением которое надо отобразить).

2) Читал, что в некоторых тулкитах типа QT, есть такая штука как window-damage event, которую я понимаю как событие, которое появляется, если хотя бы один пиксель был в окне изменён, правильно ли я понимаю суть этого события, и есть ли аналог в Xlib? А то подход, когда надо гонять данные туда сюда каждые 40мс, даже если ничего не поменялось, не выглядит как лучшее решение данной задачи.

3) Может кто в курсе, как работает window-switcher(alt+tab) в KDE? Он ведь отображает содержимое окон в реальном времени, ну или во всяком случае оперативно реагирует на изменения окон которые он отрисовывает, и при этом не напрягает процессор.


есть такая штука как window-damage event,

Можно ловить XExposeEvent, но ловить можно только для своих окон, ЕМНИП. Сам прямой дупликации не делал, рисую на буфере а потом его вывожу. call Zubok.

XGetImage медленный
http://stackoverflow.com/questions/27233227/xlib-xgetimage-is-very-slow
https://www.xpra.org/trac/ticket/345

sambist ★★
()

Что быстрее (XGetImage+XPutImage) VS XCopyArea VS (XShmGetImage + XShmPutImage) VS GTK+?

Это функции для копирования картинки между X-сервером и X-клиентом. Сразу вопрос: а зачем тогда они тебе?

По условию задачи имеем:

Допустим у меня есть Xlib'ный тип Window, есть переменные этого типа, SrcWin и TrgWin, для удобства у обоих один и тот же размер (683*752), который никогда не изменится, одна глубина изображения. SrcWin это окно какого то реального приложения.

Если есть SrcWin и TrgWin, то их изображения уже на сервере. Значит, тебе нужно копирование всецело на сервере. XCopyArea. Окно и pixmap - это drawables. Проблема тут может быть в том, что если окно перекрыто кем-то, то копируются только видимые части окна! Если не включен или отсутствует backing store, то при свернутом окне вообще ничего не скопируется. Варианты: копировать при помощи XCopyArea окно-источник в pixmap, когда ты его прорисовываешь, а потом копировать pixmap в окно-приемник либо XCopyArea, либо XSetWindowBackgroundPixmap. Получается такой redirect вручную.

Еще вариант: использовать Composite Extension. Вот тут похожее обсуждали. Проблемы с XRenderComposite

2) Читал, что в некоторых тулкитах типа QT, есть такая штука как window-damage event, которую я понимаю как событие, которое появляется, если хотя бы один пиксель был в окне изменён, правильно ли я понимаю суть этого события, и есть ли аналог в Xlib?

Я полагаю, что речь тут идет о X Damage Extension.

О Composite Extension или Damage Extension можно тут посмотреть: https://www.talisman.org/~erlkonig/misc/x11-composite-tutorial/

Zubok ★★★★★
()

3) Может кто в курсе, как работает window-switcher(alt+tab) в KDE?

KWin, полагаю, тотально использует composite extension. Это расширение глобально и без твоей помощи редиректит окна в теневые pixmaps.

Что быстрее (XGetImage+XPutImage) VS XCopyArea VS (XShmGetImage + XShmPutImage) VS GTK+?

XShm конечно. Насколько я помню код GTK (второй): он проверяет наличие расширения MIT-SHM и если оно есть, то использует его. Проверять обязательно, так как клиент может быть удаленным и никакого SHM не будет. https://developer.gnome.org/gdk2/stable/gdk2-Images.html#gdk-image-new

Zubok ★★★★★
()
Ответ на: комментарий от Zubok

Варианты: копировать при помощи XCopyArea окно-источник в pixmap, когда ты его прорисовываешь, а потом копировать pixmap в окно-приемник либо XCopyArea, либо XSetWindowBackgroundPixmap. Получается такой redirect вручную.

Закат солнца вручную. Можно рисовать сначала в теневой pixmap, а потом копировать из него в нужное destination window.

Zubok ★★★★★
()
Последнее исправление: Zubok (всего исправлений: 1)
Ответ на: комментарий от sambist

Я уже порядком материалов нагуглил, видел и эту ссылку на SO, собственно поэтому вопрос и задал ( ответа, который мне нужен, там нет ). За вторую ссылку спасибо.

Про кеды спросил потому, что если открою сорцы, то это будет первый раз, система там комплексная (уже открыл) и вот так сходу код для работы переключателя окон не нашёл, что то похожее есть, но там сплошные обёртки чего низкоуровневого, поэтому спросил, вдруг кто то имел или имеет дело с кодом кедов.

http://tronche.com/gui/x/xlib/events/exposure/expose.html вот что у меня есть для Expose, оттуда «The circumstances in which the X server generates Expose events are not as definite as those for other events», конкретно у меня, когда я пытался ловить Expose для другого окна, событие ловилось в случае ресайза или сворачивания, при изменениях внутри ничего не происходило.

awpe
() автор топика
Ответ на: комментарий от Zubok

Большое спасибо за большой ответ!

Сейчас моя программа работает так:

дано - два Window SrcWin и TrgWin, первое это ID какого то приложения, второе ID окна, которое программа создаёт.

В целом - программа копирует содержимое окна с помощью связки XGetImage и XPutImage пока оно отрисовано, иначе пытается использовать последний полученный XImage (если он был).

Подробнее - программа пытается получить XImage из SrcWin с помощью XGetImage во временную переменную tmpXImg, если получилось, то проверяется наличие чего либо в основной XImage (myXImg!=NULL), если там что то есть то вызывается XDestroyImage, tmpXImg копируется в нормальную основную myXImg, и содержимое при помощи XPutImage отправляется в TrgWin. Если не получилось получить XImage в tmpXImg из SrcWin, например потому что окно свернули, и основная myXImg не NULL, то она же снова испльзуется для XPutImage в TrgWin. В этом случае интервал отрисовки увеличивается пока XGetImage не начнёт возвращать в tmpXImg не NULL.

Поведение:

В случае если SrcWin больше по размеру чем TrgWin, то XPutImage всё равно вызывается на размеры SrcWin, ни в консоль ни в valgrind ошибок из за этого не попало, картинка успешно «режется».

Если TrgWin больше SrcWin, то в TrgWin попадает весь SrcWin, а остальная область автоматически заливается цветом фона окна (background pixel), плюс принудительно рисуются прямоугольники в неактивной области, чтобы избежать артефактов.

1) В KDE перекрытие окон не вызвает появляния чёрных областей в TrgWin, а с чистым xmonad вызывает, видимо KDE как то хранит эти XImage, но вы говорили, что оно хранит их в теневых pixmapах, однако я вызываю XGetImage а не функцию QT или KDE, почему же всё равно получаю изображение как бы не перекрывал окна?

В KDE только свёрнутые окна вызывают ошибку XGetImage.

2) Если не сложно дайте, пожалуйста, ссылку про backing store?

несколько вопросов к «Варианты: копировать при помощи XCopyArea окно-источник в pixmap, когда ты его прорисовываешь, а потом копировать pixmap в окно-приемник либо XCopyArea, либо XSetWindowBackgroundPixmap.»:

3) что значит «когда ты его прорисовываешь»? - когда я вытаскиваю событие Expose? Но я его только для своих окон могу получить, разве нет? Для чужих окон оно только на ресайз реагирует, вроде...

4) У XCopyArea аргументы src и dest тоже Drawable, разве не будет тоже самое только вместо XImage Pixmap появится? Или разница в том, что XGetImage и XPutImage приводят к тому, что данные «гуляют» между сервером и клиентом, а XCopyArea проводит свои манипуляции строго на сервере? Тогда получается что Pixmapы всегда хранятся на сервере?

Вопросы к «Еще вариант: использовать Composite Extension.»:

5) Вы о X11/Extensions/XRender.h?

6) Этот Composite Extension позволяет создать теневой объект в который можно в любой момент отрисовать любое окно по id (Window)? Если да то можно пример и/или ссылку на доки?

Вопросы к «KWin, полагаю, тотально использует composite extension. Это расширение глобально и без твоей помощи редиректит окна в теневые pixmaps.»:

7) В исодниках почти всё начинается с буквы Q, я буду прав предположив, что QT имеет обёртки для XRender? А GTK?

Вопросы к «XShm конечно. Насколько я помню код GTK (второй): он проверяет наличие расширения MIT-SHM и если оно есть, то использует его. Проверять обязательно, так как клиент может быть удаленным и никакого SHM не будет.»

8) Есть такое явление, я гуглил разные форумы и SO и в ответах видел названия функций, но вот гугление функций меня постоянно на разные патчи наводило, в частности на патчи GTK где проверяли на доступность MIT-SHM, перед использованием XShm, собственно увидев XShm в GTK, вопрос о скорости и появился, однако я не понял MIT-SHM, он по умолчанию есть на локальной машине? Т.е. если у меня иксы на той же машине, то и MIT-SHM в наличии?

Вопросы к «Закат солнца вручную. Можно рисовать сначала в теневой pixmap, а потом копировать из него в нужное destination window.»

9) Допустим есть окно gedit'а, у меня есть его id, как его нарисовать в теневой pixmap?

10) Вообще несколько раз Вы упомянули слово «теневой», это объекты, которые каким то особым образом создаются, чтобы оказаться в памяти иксов а не моего приложения? Что Вы под этим словом подразумевали?

11) Что быстрее/эффективнее для решения данной задачи XSchm или XCopyArea? Просто программа с Xlib уже есть рабочая, что то уже понимаю в этом Xlib, хочу сделать программу быстрее, и чтобы ресурсы не потребляла в таком количестве, а использование QT/GTK приведёт к тому, что придётся учить QT и GTK, там ведь только с виду всё просто, без понимания того, как оно работает внутри, можно вечно писать программу, или ошибаюсь?

12) https://www.talisman.org/~erlkonig/misc/x11-composite-tutorial/ - я оттуда про damage-eventы узнал, надо наверное внимательнее прочитать, т.к. мне показалось, что статья на QT ориентирована, у вас не найдётся ссылки на подобный ресурс для Xlib? Как вообще избавится от таймера и отслеживать изменения непосредственно изменения в окне srcWin (коим может быть любая программа)?

13) Я так понимаю, если backing store нельзя включить программно, то мне остаётся следующее:

если есть MIT-SHM то использовать его, иначе если включен backing store, то постоянно с определённым интервалом (или если смогу разобраться как, то по волшебному событию XDamage) копировать содержимое SrcWin в TrgWin с XCopyArea, иначе использовать XCopyArea, с тем же таймером для копирование из SrcWin в pixmap, а оттуда в TrgWin, здесь нужен промежуточный Pixmap (в отличии от предыдущей условной ветки) т.к. при сворачивании SrcWin ничего не получится скопировать, и придётся использовать Pixmap для хранения последнего изображения.

14) Можно с помощью Xlib заставить иксы нарисовать свёрнутое окно в моё окно или другой объект?

15) Pixmap более универсальный чем XImage? Можно утверждать что если есть два экрана (Screen), с разной глубиной то с XImage копирование не получится, из за разности в глубине а с Pixmap всё будет автоматически преобразовано, или я чего то не понял?

Куча вопросов... Заранее спасибо за ответы!

P.S. Извиняюсь за многабукв, но в сети мало инфы по Xlib, а в самой документации всякие непонятки типа «поведение должно быть определено, но так получилось, что оно не определено так хорошо, как у других объектов» итд...

awpe
() автор топика
Ответ на: комментарий от awpe

Подробнее - программа пытается получить XImage из SrcWin с помощью XGetImage во временную переменную tmpXImg

Да забудьте вы пока про эти XImage. Они обычно нужны, когда надо выполнить некоторую достаточно сложную обработку изображения. Тогда их получают на клиенте и делают с ними все, что захочется, не нагружая X server. Понятно, почему у вас такая адская загрузка процессора - вы туда-сюда гоняете растр через сокет/пайп. XCopyArea решит всю проблему.

что значит «когда ты его прорисовываешь»?

Это значит, что содержимое любого окна не возникает само собой. Так или иначе его должен кто-то отрисовать. Zubok, скорее всего, полагал, что отрисовывает его ваша программа. А вот если копировать надо из чужого окна, то тут, увы, не будет правильного решения. Т.е. скопировать то можно, но, как уже говорилось, нет гарантии, что в этот момент окно не будет заслонено, или вообще свернуто.

Или разница в том, что XGetImage и XPutImage приводят к тому, что данные «гуляют» между сервером и клиентом, а XCopyArea проводит свои манипуляции строго на сервере? Тогда получается что Pixmapы всегда хранятся на сервере?

Да! Об этом тут и пишут все подряд по нескольку раз. И скорее всего, XCopyArea решит вашу проблему.

Допустим есть окно gedit'а, у меня есть его id, как его нарисовать в теневой pixmap?

Создать Pixmap нужного размера и сделать в него XCopyArea. Правда есть, нюанс. Что вы понимаете под окном gedit'а и как GTK его строит.

Вообще несколько раз Вы упомянули слово «теневой», это объекты, которые каким то особым образом создаются, чтобы оказаться в памяти иксов а не моего приложения? Что Вы под этим словом подразумевали?

XCreatePixmap вызываете на нужном дисплее, вот и получаете «теневой» пиксмап. Любой Pixmap - это, условно говоря, поименованный образ растра, лежащий в памяти X server-а.

Я так понимаю, если backing store нельзя включить программно, то мне остаётся следующее:

MIT-SHM конечно можно попробовать. Все-таки 40 мс - это довольно таки часто.

Можно утверждать что если есть два экрана (Screen), с разной глубиной то с XImage копирование не получится, из за разности в глубине а с Pixmap всё будет автоматически преобразовано, или я чего то не понял?

Нет нельзя. Если глубина разная, то надо будет как-то исхитряться копировать отдельные битовые плоскости, а потом как-то приводить это хозяйство к общему знаменателю. Чудес не бывает.

zloy_starper ★★★
()
Ответ на: комментарий от awpe

P.S. Извиняюсь за многабукв

Не, это действительно многабукав. Я на такое не подписывался. :)

На самом деле, не сказано, какая стоит задача? В исходном посте есть только посыл, что есть окно 1 и окно 2 и надо скопировать одно в другое. Но вот это:

9) Допустим есть окно gedit'а, у меня есть его id, как его нарисовать в теневой pixmap?

говорит о том, что речь идет не о копирование своих окон, а всех вообще. X Window System в базовом варианте не хранит изображения окон в offscreen memory. Если надо нарисовать что-то в окне, то иксы прямо в фреймбуфер и рисуют, поэтому нельзя получить изображение всего окна, если оно перекрыто другим. Можно получить только видимую область. Чтобы в этом убедиться, можно вызвать, например,

$ xwd > convert - /tmp/window.png
$ display /tmp/window.png

(она использует XGetImage) на частично закрытое окно ткруть крестиком и убедиться, что пришла только видимая часть. Это все говорит о том, что в базовых иксах нельзя получить окно, не имея теневого изображения окна в памяти.

Потом появилось расширение Composite Extension, которое одной командой позволяет включить автоматический редирект в теневой pixmap либо всех окон вообще, либо отдельных. Вообще, до Composite Extension был backing store у окон. Он нужен был, чтобы X Server не слал много событий expose клиентам, а обновлял окна своими силами. http://tronche.com/gui/x/xlib/window/attributes/backing-store.html Но backing store может пропасть или с самого начала быть недоступным, об этом есть специальное предупреждение, чтобы не рассчитывали на него, та как оно всегда может из соображений экономии памяти пропасть, поэтому expose обрабатывать все равно обязательно надо. Насколько я знаю, сейчас backing store реализовано при помощи все того же Composite Extension.

12) https://www.talisman.org/~erlkonig/misc/x11-composite-tutorial/ - я оттуда про damage-eventы узнал, надо наверное внимательнее прочитать, т.к. мне показалось, что статья на QT ориентирована, у вас не найдётся ссылки на подобный ресурс для Xlib?

Там нет ничего серьезного для Qt. Когда у тебя уже pixmap, то уже не важно, чем ты его обрабатываешь - делай все при помощи xlib просто. Там же Qt все те же пиксмапы читает, но просто приводит их к своем представлению.

Это как раз то, что тебе нужно:

This tutorial is mainly aimed at those that are interested in using Composite for providing thumbnails in a desktop pager, or for those working on Exposé like features. But the concepts introduced here are applicable to Composite managers as well. This tutorial is not meant to be the one and only reference you'll ever need for everything having to do with the Composite extension however, but I've tried to cover all aspects of its usage for the above mentioned purposes. It should also help you avoid all the pitfalls you're likely to run into when using the Composite extension.

Zubok ★★★★★
()
Последнее исправление: Zubok (всего исправлений: 1)
Ответ на: комментарий от Zubok

Спасибо большое! Информация была очень полезна.

Однако, наткнулся на проблему - использую XCopyArea для копирования изображения из одного буфера в другой, сначала из окна источника в pixmap, потом из pixmap в своё окно, с некоторыми приложениями работает, а с некоторыми нет, при этом тот же код с XGetImage тормозит, но работает корректно с любыми приложениями, в чём может быть беда?

Например из firefox pixmap достаётся нормальный а из rxvt терминала нет, куда смотреть?

При попытке взять pixmap из rxvt туда попадает всякий мусор из ошмётков браузера. При этом если сначала запустить программу на копирование браузера, где всё нормально, а потом на копирование терминала, то в pixmap будет почти целая картинка последнего pixmapa для браузера. Если перед запуском включать другие приложения, то при попытке получить pixmap из rxvt получаю мусор из тех приложений.

ID окон правильные, иначе бы не работала ф-ия XGetImage.

код примерно такой (окно целевого приложения такого же размера, как и окно источника):

//...
XSelectInput (d, w_target, ExposureMask);
XMapWindow (d, w_target);

myGC = DefaultGCOfScreen (defaultScreen);
pm   = XCreatePixmap (d, w_src, w_src_width, w_src_height, w_src_depth);

delay.tv_sec  = 0;
delay.tv_nsec = 100000000L; // 100ms

while (1)
{
    while (XPending (d))
    {
        XNextEvent (d, &ev);
        switch (ev.type) 
        {
            case Expose:
                XClearArea(d, w_target, 0, 0, 0, 0, False);
                nanosleep (&delay, NULL);
                break;
            default:
                break;
        }
    }

    XGetWindowAttributes (d, w_src, &w_src_attr);

    w_src_width  = w_src_attr.height;
    w_src_height = w_src_attr.width;

    XCopyArea (d, w_src, pm, myGC, 0, 0, w_src_width, w_src_height, 0, 0);
        
    XCopyArea (d, pm, w_target, myGC, 0, 0, w_src_width, w_src_height, 0, 0);

    nanosleep (&delay, NULL);
}
awpe
() автор топика
Ответ на: комментарий от awpe

По Expose, кстати, можно копировать не весь pixmap, а только регион. В событии Expose идут параметры, которые дают регион x, y, width, height. Поэтому можно из pixmap копировать только вот этот кусочек. Каждый раз всю область копировать не надо.

Я поясню, к чему я это. Если твое destination window ты задвинешь за край экрана, а потом назад или перегородишь другим окном, а потом снова откроешь, то ему надо перерисовать закрытую часть. Он и пошлет тебе Expose с регионом. В pixmap у тебя образ окна, поэтому можно вот этот кусочек скопировать. Можно применить технологии сжатия событий expose. Либо самостоятельно анализировать регионы (более сложный способ), либо ждать, когда count = 0 (параметр в Expose, простой вариант).

Zubok ★★★★★
()
Ответ на: комментарий от Zubok

Мне нужна только часть окна источника поверх фонового изображения, так что сначала переведу изображение фона в pixmap pmBG(пока что там просто фон одноцветный), потом в цикле в pixmap pmRes вставляю pmBG, поверх этого часть окна источника, ну и потом pmRes идёт в окно с результатом. Как ещё добится того чтобы чтобы часть окна источника была нарисована поверх фоновой картинки и чтобы в процессе рисования не было разрывов изображения?

Посмотрел что там с rxvt - оконный менеджер рисует окно со своей рамкой, внутри rxvt рисует своё чёрное окно с именем (WM_NAME,WM_CLASS), и уже внутри этого окна с круговым отступом 2 пикселя рисуется содержимое rxvt, моя программа получает окно с фокусом, потом идёт по цепочке до рутового окна дисплея, то окно что перед рутом проверяется на наличие имени (WM_NAME,WM_CLASS), если имя есть значит это то что нужно (если xmonad например), если имени нет, то на одну позицию вверх если и там имени нет, то ошибка, а если есть то это оно, как проще получить правильное окно я не знаю...

xmonad: display_root_window --correct_window (WM_NAME, MW_CLASS установлены)

lxde: display_root_window --de_wm_window (которое рамку и эл. управления вокруг окон рисует) ----correct_window (WM_NAME, MW_CLASS установлены)

чтобы в обоих случаях получить correct_window вот такую систему применяю, однако с rxvt проблема - внутренее окно с содержимым имени не имеет, но перекрывает окно с именем (тот же эффект, как если на нормально транслируемое окно начать перетаскивать другое - закрытая другим окном область пропадает), которое видимо для отступа используется, поможет ли здесь composite extension - я ведь могу буферизировать только одно окно, или можно сразу всю цепочку с потомками?

awpe
() автор топика
Ответ на: комментарий от Zubok

Если твое destination window ты задвинешь за край экрана, а потом назад или перегородишь другим окном, а потом снова откроешь, то ему надо перерисовать закрытую часть

Я использую NorthWestGravity, я так понял что в этом случае если меняется размер окна, или оно чем-то перекрывается, иксы не стирают содержимое, это не так?

awpe
() автор топика
Ответ на: комментарий от awpe

Так задача и не ясна. Скажу так: если тебе нужно гарантированное изображение открытых окон вне зависимости от того, перекрыты ли они, то гарантию дает только Composite Extension. Появление теневых пиксмапов - гарантированый результат действия функций этого расширения. Поэтому не теряй времени на пустые эксперименты, а сразу работай с Composite.

я ведь могу буферизировать только одно окно, или можно сразу всю цепочку с потомками?

Да, все можно: и дерево, начиная с root, и отдельные окна.

http://www.x.org/archive/X11R7.5/doc/man/man3/Xcomposite.3.html

Zubok ★★★★★
()
Ответ на: комментарий от awpe

1) В KDE перекрытие окон не вызвает появляния чёрных областей в TrgWin, а с чистым xmonad вызывает,

А разве в xmonad окна перекрываются? Он же вроде тайловый оконный менеджер. Или там возможность плавающих окон (или как там зовется?) есть. Вообще, в чем очновная задача? Речь шла о функциональности пейджера. Делается пейджер для xmonad?

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

Zubok ★★★★★
()
Последнее исправление: Zubok (всего исправлений: 1)
Ответ на: комментарий от Zubok

Вообще, в чем очновная задача?

Пейджер универсальный, с плюшками 1шт :)

В xmonad есть возможность перевести окно в плавающий режим, разница в том, что в xmonad, в отличие от других оконных менеджеров(ОМ) (может не всех, но kwin и openbox точно), у окон приложений родительское окно - это самое что ни на есть рутовое окно на данном экране, в других же ОМ они сначала своё с рамкой создают, однако, я заметил, что вроде бы и не установлено ни xcompmgr ни других compton'ов (ну только kwin похоже использует composite extension), но поведение немного разное...

Кроме того в ОМ можно оказаться на другом экране, как я понял из мануала по ICCC, разные ОМ по-разному смотрят на необходимость убивать содержимое, которое на другом рабочем столе (я точно не помню какой hint там надо установить, вроде wm_state менять надо у окна(в смысле ОМу нужно это сделать), чтобы иксы не хранили буфер с окном).

Ну я теперь понял, что без composite extension далеко не уедешь...

Я предполагаю, что composite extension на современных десктопах с линуксом, 99% есть по умолчанию, и только в 1% случаев его нет, и то если пользователь сам отключил его где-то в настройках или при компиляции, это так?

awpe
() автор топика
Ответ на: комментарий от Zubok

Прочитал про MIT-SHM, и не понял в чём отличие от стандартных pixmap'ов?

Вроде так же - клиент получает адрес с объектом, и сервер тоже с этим адресом работает, таким образом не нужно копировать много данных от сервера клиенту и обратно, с обычными pixmap'ами работают, как я понял, так же - по их id, а хранятся они на сервере в обоих случаях. Или обычный pixmap для каждого клиента кникален, а тот что через MIT-SHM можно между клиентами разделять?

awpe
() автор топика
Ответ на: комментарий от awpe

Image ­— это структура X-клиента, а pixmap — это объект на стороне сервера X. В случае MIT-SHM, казалось бы, сервер X имеет доступ к клиентской картинке напрямую. Но есть два основных «но»:

1) В случае удаленного клиента у тебя неизбежно должен применяться обычный GetImage/PutImage, что приведет к перегонке картинки по сети туда-обратно. Это надо иметь в виду и использовать Images там, где они действительно эффективны. Например, если ты делаешь много битовых операций над изображением, то тогда правильнее делать это все в Image, а на сервер присылать обновления, чтобы отобразить. Нельзя рассматривать MIT-SHM как средство для использования Image как Pixmap. Его надо рассматривать только как технологию оптимизации в случае, если клиент и сервер находятся на одной машине.

2) Даже если Pixmap и разделяемая Image доступны серверу напрямую, есть важное отличие: операции с pixmap потенциально аппаратно ускорены, а с Image — нет. Pixmaps могут мигрировать между памятью CPU и GPU. Этой миграцией занимаются механизмы 2D ускорения, такие как EXA. Если у тебя pixmaps оказались в памяти GPU (то есть в offscreen memory), а они туда действительно набиваются, то операции копирования областей, например, будет выполнять GPU, если драйвер нормальный, конечно.

(II) EXA(0): Driver allocated offscreen pixmaps
(II) EXA(0): Driver registered support for the following operations:
(II)         Solid
(II)         Copy
(II)         Composite (RENDER acceleration)
(II)         UploadToScreen
(II)         DownloadFromScreen

Если ты используешь OpenGL, то там уже есть расширение, которое умеет Pixmaps преобразовывать в текстуры и манипулировать ими (GLX_EXT_texture_from_pixmap). XImage из разделяемой памяти не может мигрировать в память GPU по определению.

Вот, например, простая вводная: https://techbase.kde.org/Development/Tutorials/Graphics/Performance. Просто замени QPixmap на pixmap, а QImage на XImage. Разве только момент медленности преобразования чуть подправить, так как свои XImage ты можешь в удобном для pixmap формате держать. Тогда преобразования не нужно. Но в общем все так: преобразование Image в Drawable (pixmap или window) и назад - это дорогая операция с дичайшим roundtrip.

Zubok ★★★★★
()
Последнее исправление: Zubok (всего исправлений: 3)
Ответ на: комментарий от Zubok

Кстати, а о какой двойной буферизации идет речь, за которую обычно люто ругают X? Дескать она катастрофически снижает производительность графической подсистемы. Ведь в конце концов любой композитинг с альфа-каналом и прочими плюшками не может быть реализован без офскринного буфера. Тот же Wayland построен по тому же принципу. Но на него уже чуть ли не молиться начинают.

zloy_starper ★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.