如何将 shm/fd 的步长告诉 xcb_shm_get_image()?

问题描述 投票:0回答:1

我正在使用 xcb-shm 来捕获屏幕。我创建与屏幕分辨率相同的 drm/gbm 缓冲区,然后将其 fd 提供给

xcb_shm_attach_fd()
。有时,我创建的 drm/gbm 缓冲区的步幅大小与 xcb 的
geometry->width * 4
不相等,这使得一切都被破坏。

当我尝试捕获 1920x1080 分辨率时,一切都很好,因为我创建的 drm/gbm 缓冲区与

1920 * 4
具有相同的步幅。但是当我为我的第一个 1366x768 显示器创建 drm/gbm 缓冲区时,drm/gbm 的步幅不是
1366 * 4
。是
1408 * 4
。当我将 drm/gbm 缓冲区提供给 xcb 来捕获屏幕时,我得到了损坏的结果。我使用
gbm_bo_create()
并使用
gbm_bo_get_stride()
迈出一大步。

我如何知道 shm/fd 的步幅为

xcb_shm_get_image()
?或者是否有更快/类似的方法来捕获屏幕来处理 shm/fd 步幅?

x11 xorg xcb
1个回答
0
投票

嗯,好吧。这里尝试解释一下。 我认为以下内容不会为您提供任何新信息

第一:SHM 使用与普通 X11 相同的像素格式。因此

xcb_shm_get_image()
为您提供与
xcb_get_image()
相同的格式。像素数据的格式取决于深度和视觉效果。有关这些的信息位于
xcb_get_setup()
的结果中,并由
/usr/bin/xdpyinfo
打印。

让我们看一下我的 X11 服务器的示例。

xdpyinfo
介绍了像素图格式:

supported pixmap formats:
    depth 1, bits_per_pixel 1, scanline_pad 32
    depth 4, bits_per_pixel 8, scanline_pad 32
    depth 8, bits_per_pixel 8, scanline_pad 32
    depth 15, bits_per_pixel 16, scanline_pad 32
    depth 16, bits_per_pixel 16, scanline_pad 32
    depth 24, bits_per_pixel 32, scanline_pad 32
    depth 32, bits_per_pixel 32, scanline_pad 32

这包含有关如何存储数据的信息。 “现在”,我们只关心深度 24 和深度 32。它们都使用每像素 32 位,即 4 字节。在扫描线的末尾,内容被填充为 32 位的倍数。由于每个像素的大小已经是 32 位,这基本上意味着没有填充。

接下来,我的 X11 服务器的默认视觉效果是什么?为什么是这个?只是因为有太多,我必须以某种方式选择一个。

screen #0:
[...]
  default visual id:  0x21
  visual:
    visual id:    0x21
    class:    TrueColor
    depth:    24 planes
    available colormap entries:    256 per subfield
    red, green, blue masks:    0xff0000, 0xff00, 0xff
    significant bits in color specification:    8 bits

该视觉效果使用 24 的深度。正如我们在上面看到的,这意味着每个像素有 4 个字节,并且在扫描线末尾没有额外的填充。

换句话说:尺寸为

w
x
h
的图像需要
w*h*4
字节,每行需要
w*4
字节。

请注意https://www.x.org/releases/X11R7.7/doc/xextproto/shm.html#USE_OF_SHARED_MEMORY_PIXMAPS

与任何图像格式都可用的 X 图像不同,共享内存扩展仅支持共享内存像素图中存储的数据的单一格式(即 XYPixmap 或 ZPixmap)。

但是,我怀疑是否有任何 X11 服务器实际上使用了这一点。

XYPixmap
很奇怪...

© www.soinside.com 2019 - 2024. All rights reserved.