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

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

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

当前状态:

  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,3BGRA

问题:

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

问题:

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

答案1

以编程方式,要检索有关帧缓冲区的信息,您应该使用和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);
}

line_length为您提供行步幅。

答案2

跨步不必与宽度;在您的 1920 宽屏幕上,您的软件只是“偶然”工作了(这并不是偶然,步幅通常是根据硬件对齐要求选择的,而 1920 已经可以被 16 整除,这是一个常见的对齐要求)。

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

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

相关内容