LINUX.ORG.RU

XCB как узнать размер данных pixmap?

 , , , ,


0

1

Имеется особая необходимость выяснять размер данных pixmap.
Как это сделать через XCB?

уже достаточно давно брожу по просторам XCB, но не натыкался на возможность узнать размер данных у pixmap-ы.

★★

напрашивается только методология с предварительным вызовом xcb_get_image() и затем xcb_get_image_data_length() — но есть ли более простой способ сделать это?

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

ну он требует лишних действий — получить имейдж — хотя мне его данные не нужны этими вызовами. Конечно я хз — оказывает ли это какое то воздействие на производительность.

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

Тут скорее всего другой вопрос: «сколько вешать в граммах?» для pixmap не имеет смысла без контекста - gcontext, устройства, железа.

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

мне надо данные pixmap запихнуть в vulkan... что бы это сделать я использую xcb_shm, так вот для этой xcb_shm надо знать сколько весит pixmap...

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

Так, погоди, а что, умножить три цифры друг на друга современные хипстеры уже не могут?

typedef struct xcb_get_geometry_reply_t {
    uint8_t      response_type;
    uint8_t      depth;
    uint16_t     sequence;
    uint32_t     length;
    xcb_window_t root;
    int16_t      x;
    int16_t      y;
    uint16_t     width;
    uint16_t     height;
    uint16_t     border_width;
    uint8_t      pad0[2];
} xcb_get_geometry_reply_t;

depth
The depth of the drawable (bits per pixel for the object).
width
The width of drawable.
height
The height of drawable.

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

не понятно какой размер получится — ибо формат image при получении для впихивания в vulkan может быть различным — я использую XCB_IMAGE_FORMAT_Z_PIXMAP. От этого формата может быть различный реальный занимаемый размер

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

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

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

умножить три цифры друг на друга современные хипстеры уже не могут?

Все равно это искусственная цифра, несвязанная с реальностью. Потому что каждый пиксель может быть выравнен под размер «единицы информации», каждая строка может быть выравнена по размер «блока информации» и так далее.

anonymous
()
Ответ на: комментарий от safocl

Тогда какие проблемы? Умножай высоту, ширину и глубину и запихивай. Для «правильных» размеров и глубины проблем скорее всего не будет. «Правильных» - в смысле кратных правильной степени 2.

А так, скорее всего (потому что я не эксперт), надо смотреть в стороны DRI xcb_dri{2,3}. Там дергать буферы и их размеры.

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

Тогда какие проблемы? Умножай высоту, ширину и глубину и запихивай.

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

А так, скорее всего (потому что я не эксперт), надо смотреть в стороны DRI xcb_dri{2,3}. Там дергать буферы и их размеры.

именно так и хочу — однако, в моих драйверах nvidia gtx1650 пока что нет поддержки dmabuff — но вроде в бетта драйверах уже добавили в 470 версии... — жду стабильной ветки

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

Должно хватить какого-нибудь render’а.

а что там есть такого, что бы помочь? как с помощью этого расширения получить image для vulkan?

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

мне надо данные pixmap запихнуть в vulkan... что бы это сделать я использую xcb_shm, так вот для этой xcb_shm надо знать сколько весит pixmap...

Извини, возможно порю чушь, ага, и ей больно... Ничего не знаю о vulkan'е; просто сходу просится простое решение.

VkXcbSurfaceCreateInfoKHR createInfo = {0};
createInfo.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR;
createInfo.pNext = NULL;
createInfo.connection = connection;
createInfo.window = pixmap; /* <- твой pixmap */
res = vkCreateXcbSurfaceKHR(instance, &createInfo, NULL, pSurface);
То, нет?

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

Я тут перегнул конечно. Должно хватить какого-нибудь render’а.

Можно, конечно, повозиться и вытащить данные, но манипуляции с сырыми данными — не самая лучшая идея. Как правило, если дело дошло до этого, ты что-то делаешь не так.

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

Я не знаток вулкана. Я не знал, что вулкану можно просто передать drawable/window и он сам вытащит данные в нужном формате. А ТС же хочет передать сырые данные через SHM.

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

Я не знаток вулкана. Я не знал, что вулкану можно просто передать drawable/window и он сам вытащит данные в нужном формате. А ТС же хочет передать сырые данные через SHM.

Да я же тебя не попрекаю. Я вот обо что. Скорее всего для dri(2,3) — а для Render точно! — данные будут уже в видеопамяти. Скопировать оттуда сырые данные, (ага, а потом обратно) будет безумно дорогой операцией.

Ну да, и идеологически неверно.

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

ну вопервых так не пройдет, надо именно xcb_window_t...
да и сюрфейс сам нужен для отрисовки — а мне надо данные получить из.

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

если у тебя есть предложение как твою идею реализовать в вулкане — то я открыт для обсуждений...
и я не хочу данные в сыром виде — они как бы в определенном формате передаются... там есть указание формата в котором будут данные.

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

да — dri3 точно юзает dmabuf — но увы у меня с nvidia видяхой енто пока не светит — как минимум до стабильной версии дров с подддержкой dmabuf

а так да — по идее самым лучшим выходом — будет переиспользование данных в видеопамяти вулканом.

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

ну вопервых так не пройдет, надо именно xcb_window_t...

Что Window, что Pixmap — одно и то же — Drawable. И тип там один — xid (typedef uint32_t). Пробуй. Разве что формат pixmap'а должен быть такой же как и window, куда ты собираешься его рисовать.

да и сюрфейс сам нужен для отрисовки — а мне надо данные получить из.

Да кто же тебя запрещает его создавать. Я сам не знаю, но по аналогии (везде так) должна быть функция, копирующая с одной поверхности на другую.

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

Что Window, что Pixmap — одно и то же — Drawable. И тип там один — xid (typedef uint32_t). Пробуй. Разве что формат pixmap'а должен быть такой же как и window, куда ты собираешься его рисовать.

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

Да кто же тебя запрещает его создавать. Я сам не знаю, но по аналогии (везде так) должна быть функция, копирующая с одной поверхности на другую.

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

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

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

Погляди, как в винде выводится изображение, ага. (CreateCompatibleDC, CreateCompatibleBitmap, BitBlt и все такое.)

нет — там именно xcb_window_t — хоть это по сути одно и то же — но идеологически они различны

Ты ведь даже не попробовал. Обычно всегда можно использовать вместо Window Pixmap. Хотя, возможно, это не тот случай. А ты бы нам рассказал об этом.

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

Погляди, как в винде выводится изображение, ага. (CreateCompatibleDC, CreateCompatibleBitmap, BitBlt и все такое.)

и где тут сюрфейс?

Ты ведь даже не попробовал. Обычно всегда можно использовать вместо Window Pixmap.

не всегда — только если указано Drawable — потому что Pixmap это Drawable — в спеке X window так сказано/

да и бессмысленно это — в vulkan нельзя с сюрфейса снять данные — только отрисовать данные в него.

safocl ★★
() автор топика
Последнее исправление: safocl (всего исправлений: 2)

почему-то когда я делаю xcb_get_geometry — то reply возвращает nullptr, если я проверяю геометрию offscreen image, который замаплен на pixmap функцией xcb_composite_name_window_pixmap от root window...

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

Надеюсь, я правильно понял проблему. Тебе нужно узнать, как считать так называемый «stride» или «pitch»? Если так, то вот пример:

// округлить до следующей степени двойки
static inline u32 alignUpPow2u32(u32 a, u32 b) { return (a + b - 1) & -b; }

// макрос для небольшой портяночки, кто захочет, здесь можно использовать xcb_format_iterator_t
#define xcb_setup_for_each_pixmap_format(setup, fmt) \
    for (const xcb_format_t *fmt = xcb_setup_pixmap_formats(setup), *const _end = fmt + setup->pixmap_formats_len; \
        fmt < _end; ++fmt)

// здесь передаем наш желаемый "stride" и глубину и функция возвращает округленное значение
// stride = xcbPixmapFormatStride(setup, width * BYTES_PER_PIXEL, DEPTH);
// imageSize = stride * height;
// если вызывать нужно часто, можно сохранить результаты отдельно
u32 xcbPixmapFormatStride(const xcb_setup_t *setup, u32 stride, u8 depth)
{
    assert(setup && stride && depth);
    xcb_setup_for_each_pixmap_format (setup, fmt)
        if (fmt->depth == depth)
        // scanline_pad дан в битах
            return alignUpPow2u32(stride, fmt->scanline_pad >> 3);
    return 0;
}

Хотя согласно спецификации X11 scanline_pad может принимать только значения 1, 2, 4 (в байтах), т. е., например, любое изображение с 4 байтами на пиксель будет удовлетворять этому требованию.

goto-vlad
()
Ответ на: комментарий от safocl

мне надо размер данных которые будут выведены из pixmap получить.

То есть, stride * height, как в примере выше? Исходя из этих цитат я именно это и понял. Или имелось в виду что-то другое?

я использую XCB_IMAGE_FORMAT_Z_PIXMAP. От этого формата может быть различный реальный занимаемый размер

что бы это сделать я использую xcb_shm, так вот для этой xcb_shm надо знать сколько весит pixmap…

goto-vlad
()
Ответ на: комментарий от goto-vlad

ну в простом случае хранения данных в сыром формате — да — однако они могут не храниться в нем, например я использую формат XCB_IMAGE_FORMAT_Z_PIXMAP, размер данных которого не обязательно будет равен произведению stride * height

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

ну в простом случае хранения данных в сыром формате — да — однако они могут не храниться в нем, например я использую формат XCB_IMAGE_FORMAT_Z_PIXMAP, размер данных которого не обязательно будет равен произведению stride * height

Цитируем спецификацию:

ZFormat - the data for a pixmap is said to be in Z format if it is organized as a set of pixel values in scanline order.

Scanline order - an image represented in scanline order contains scanlines ordered by increasing y coordinate.

Scanline - a scanline is a list of pixel or bit values viewed as a horizontal row (all values having the same y coordinate) of an image, with the values ordered by increasing x coordinate.

Про выравнивание:

Each scanline is padded to a multiple of bits as given by scanline-pad.

Это условие мы соблюли в функции выше.

Я не вижу никаких фактов указывающих на то, что «размер данных не обязательно будет равен произведению stride * height». Если найдешь, сообщи.

goto-vlad
()
Последнее исправление: goto-vlad (всего исправлений: 1)
Ответ на: комментарий от safocl

я использую xcb_shm, так вот для этой xcb_shm надо знать сколько весит pixmap…

просто создаешь и используешь всегда один shm buffer размером с root window,
далее получаешь через visual параметры полученного pixmap, размер xcb_get_image_data_length

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

так у меня не работает возможность получения геометрии pixmap если это offscreen image root window — через xcb_composite_name_window_pixmap.
походу надо будет создавать другой pixmap через CreatePixmap, создавать на них GC и копировать с первого на второй GC контекст...
но это лишнее выполнение действий...

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

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

да с root окном всего этого делать не надо... в принципе а с остальными все работает получение геометрии pixmap.

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

всегда усеченный.

в том то и дело.

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

всегда усеченный

я про другое имел ввиду, про damage notify.
а если окно заказываешь там всегда размер указываешь, вот он также по окну усеченный.

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