如何获取 FrameBuffer 每行写入的字节数?

Gar*_* Z. 10 framebuffer images display fbi

目标:我正在为帧缓冲区编写一个非常简单的图像查看器/dev/fb0(类似于fbi)。

当前状态:

  1. /sys/class/graphics/fb0/virtual_size我的软件从(例如)中获取像素分辨率1920,1080
  2. 然后(对于每一行)它将为每 1920 个行像素(总共 4x1920=7680 字节)写入 4 个字节(BGRA)到/dev/fb0. 这在我的一台分辨率为 1920x1080 的笔记本电脑上运行得非常好。
  3. y更准确地说:在-row x-col =>处设置一个像素,arr[y * 1920 * 4 + x * 4 + channel]其中值为channel0,1,2,3分别为BGRA)。

问题

/sys/.../virtual_size当我在旧笔记本电脑上使用( ->分辨率)尝试相同的软件时1366,768,图像未正确显示(有点倾斜)。所以我研究了像素宽度值,发现该值为1376(而不是 1366)。

问题

  1. 这10个额外的字节从哪里来?
  2. 并且,我怎样才能在不同的机器上获得这个10个额外字节的值(自动,而不是手动调整它)?
  3. 为什么有些机器需要这额外的 10 个字节,而有些机器不需要它们?

Ste*_*itt 13

以编程方式,要检索有关帧缓冲区的信息,您应该使用sFBIOGET_FSCREENINFOFBIOGET_VSCREENINFO ioctl

#include <fcntl.h>
#include <linux/fb.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>

int main(int argc, char **argv) {
  struct fb_fix_screeninfo fix;
  struct fb_var_screeninfo var;

  int fb = open("/dev/fb0", O_RDWR);
  if (fb < 0) {
    perror("Opening fb0");
    exit(1);
  }

  if (ioctl(fb, FBIOGET_FSCREENINFO, &fix) != 0) {
    perror("FSCREENINFO");
    exit(1);
  }

  if (ioctl(fb, FBIOGET_VSCREENINFO, &var) != 0) {
    perror("VSCREENINFO");
    exit(1);
  }

  printf("Line length: %ld\n", fix.line_length);
  printf("Visible resolution: %ldx%ld\n", var.xres, var.yres);
  printf("Virtual resolution: %ldx%ld\n", var.xres_virtual, var.yres_virtual);
}
Run Code Online (Sandbox Code Playgroud)

line_length为您提供行步幅。

  • @MarcusMüller ioctl 特定于设备类型。几乎每个设备都有一堆您从未听说过的非常具体的 ioctl。除读取、写入或 mmap 之外的每个设备功能都是 ioctl。 (4认同)
  • @MarcusMüller sysfs 告诉您系统中的一般情况;ioctl 告诉您当前打开的内容。想象一下需要对帧缓冲区的名称进行逆向工程,然后在可能已安装或未安装的 sysfs 中打开它。(有些 API *就是*这样的,这太糟糕了) (2认同)

Mar*_*ler 9

步幅不必与宽度相同;在你的 1920 宽屏幕上,你的软件只是“偶然”运行(并不是什么意外,通常会根据硬件对齐要求选择步幅,并且 1920 已经可以被 16 整除,这是常见的对齐要求)。

由于不熟悉良好的 ole Linux 帧缓冲区基础设施,我无法直接告诉您如何做到这一点,但您需要弄清楚步幅。

Linux 只是记录行按 16 的倍数对齐,因此您总是需要将宽度四舍五入到下一个倍数,或者 /sys/class/graphics/fb0/ 包含定义步幅的不同虚拟文件,或行对齐。

  • 它归结为各种硬件元素(显卡的内存单元、用于在 RAM 和 GPU 之间传输数据的 DMA 控制器以及用于计算像素的 CPU SIMD 单元)需要“简单”的地址;当某些内容是 16 位对齐时,您可以只使用第五位向上的内容。 (2认同)