LINUX.ORG.RU

Не удается изменить размер виртуального экрана для фреймбуфера в linux 5.10

 ,


0

1

У меня есть работающее приложение, которое работало напрямую с /dev/fb0 и использовало двойную буферизацию. Приложение прекрасно работало на linux 4.4, но запустив ПО на linux 5.10 я получил сообщение об ошибке:

fbset: ioctl FBIOPUT_VSCREENINFO: Invalid argument

Конкретное место в коде, которое приводит к ошибке:

	/* Set virtual display size double the width for double buffering */
	device->fb_vinfo.yres_virtual = device->fb_vinfo.yres * 2;
	if (ioctl(device->fb_fd, FBIOPUT_VSCREENINFO, &device->fb_vinfo)) {
		perror("Error setting variable screen info from fb");
		goto handle_ioctl_error;
	}

Я так понимаю, что проблема связана с тем, что в linux 5.10 fb эмулируется через DRM и драйвер DRM не поддерживает изменение размера виртуального экрана больше физического. Возможно дело в конкретной реализации drm - sun4i-drmdrmfb.

Вот лог загрузки ядра (linux 5.10 на Allwinner A20):

[    8.593273] sun4i-drm display-engine: bound 1e00000.display-frontend (ops 0xc0aa5648)
[    8.601279] sun4i-drm display-engine: bound 1e20000.display-frontend (ops 0xc0aa5648)
[    8.609606] sun4i-drm display-engine: bound 1e60000.display-backend (ops 0xc0aa4de8)
[    8.617394] sun4i-drm display-engine: attempt to add DMA range to existing map
[    8.624981] sun4i-drm display-engine: bound 1e40000.display-backend (ops 0xc0aa4de8)
[    8.633498] sun4i-drm display-engine: bound 1c0c000.lcd-controller (ops 0xc0aa363c)
[    8.641837] sun4i-drm display-engine: No panel or bridge found... RGB output disabled
[    8.649733] sun4i-drm display-engine: bound 1c0d000.lcd-controller (ops 0xc0aa363c)
[    8.658485] [drm] Initialized sun4i-drm 1.0.0 20150629 for display-engine on minor 0
[    8.709176] Console: switching to colour frame buffer device 60x50
[    8.731589] sun4i-drm display-engine: [drm] fb0: sun4i-drmdrmfb frame buffer device

Можно прям в консоли проверить:

# fbset -i

mode "800x480"
    geometry 800 480 800 400 32
    timings 0 0 0 0 0 0 0
    accel true
    rgba 8/16,8/8,8/0,0/0
endmode

Frame buffer device information:
    Name        : sun4i-drmdrmfb
    Address     : (nil)
    Size        : 1536000
    Type        : PACKED PIXELS
    Visual      : TRUECOLOR
    XPanStep    : 1
    YPanStep    : 1
    YWrapStep   : 0
    LineLength  : 3200
    Accelerator : No

попробуем установить виртуальную область меньше физической:

# fbset -v -xres 800 -yres 480 -vxres 800 -vyres 400
Linux Frame Buffer Device Configuration Version 2.1 (23/06/1999)
(C) Copyright 1995-1999 by Geert Uytterhoeven

Opening frame buffer device `/dev/fb0'
Using current video mode from `/dev/fb0'
Setting video mode to `/dev/fb0'

# fbset

mode "800x480"
    geometry 800 480 800 400 32
    timings 0 0 0 0 0 0 0
    accel true
    rgba 8/16,8/8,8/0,0/0
endmode

вернем все как было:

# fbset -v -xres 800 -yres 480 -vxres 800 -vyres 480
Linux Frame Buffer Device Configuration Version 2.1 (23/06/1999)
(C) Copyright 1995-1999 by Geert Uytterhoeven

Opening frame buffer device `/dev/fb0'
Using current video mode from `/dev/fb0'
Setting video mode to `/dev/fb0'

# fbset 

mode "800x480"
    geometry 800 480 800 480 32
    timings 0 0 0 0 0 0 0
    accel true
    rgba 8/16,8/8,8/0,0/0
endmode

пробуем установить виртуальный экран как 800x960 для double buffering:

# fbset -v -xres 800 -yres 480 -vxres 800 -vyres 960
Linux Frame Buffer Device Configuration Version 2.1 (23/06/1999)
(C) Copyright 1995-1999 by Geert Uytterhoeven

Opening frame buffer device `/dev/fb0'
Using current video mode from `/dev/fb0'
Setting video mode to `/dev/fb0'
ioctl FBIOPUT_VSCREENINFO: Invalid argument

Кто ни будь сталкивался с такой проблемой? Что можно сделать в данном случае - отказаться от double buffering? переписать бекенд на libdrm?

Хотелось бы еще понять почему драйвер drm не поддерживает изменение размера виртуального дисплея…

Спасибо.

почему драйвер drm не поддерживает изменение размера виртуального дисплея

потому что fbdev депрекнули лет 10 назад а ты пользуешься эмуляцией

https://elixir.bootlin.com/linux/v5.10.74/source/drivers/gpu/drm/drm_fb_helper.c#L1288

Что можно сделать в данном случае

переписывать конечно

https://github.com/dvdhrm/docs/blob/master/drm-howto/modeset-double-buffered.c

anonymous ()

работающее приложение, которое работало напрямую с /dev/fb0

А что за приложение, если не секрет? А то я из работающих напрямую с фрейбуфером только пару видеоплееров и смотрелок картинок знаю)

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

почему ядерная консоль до сих пор работает поверх виртуального фреймбуфера?

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

anonymous ()