QNX SCREEN框架是用于图形显示和窗口管理的软件框架,由QNX开发,旨在为嵌入式系统提供高性能、可靠的图形显示和用户界面功能。
QNX SCREEN框架提供了以下主要功能:
显示管理:SCREEN框架允许应用程序管理图形显示设备,包括显示器、触摸屏、图形加速器等。它提供了与硬件设备的通信接口,使应用程序能够获取和控制显示设备的属性、分辨率、刷新率等。
窗口管理:SCREEN框架支持窗口管理,允许应用程序创建、管理和控制多个窗口。它提供了窗口的布局、焦点管理、窗口叠放顺序、窗口移动和调整大小等功能,以实现灵活的用户界面。
图形加速:SCREEN框架通过与图形加速器驱动程序的集成,可以提供硬件加速的图形渲染和绘图功能。这可以提高图形操作的性能和效率,并支持复杂的图形效果和动画。
多屏幕支持:SCREEN框架可以处理多个显示屏,并提供多屏幕的配置和管理功能。它允许应用程序在多个显示屏上创建窗口,并提供显示屏之间的数据传输和协同工作的能力。
事件处理:SCREEN框架提供了事件处理机制,用于处理用户输入、触摸事件、窗口事件等。它允许应用程序注册事件处理器,以响应各种事件并更新用户界面。
可扩展性:SCREEN框架支持插件和扩展,允许开发人员根据特定需求添加自定义功能和驱动程序。这使得框架可以适应不同的硬件平台和应用场景。
screen服务源码不开源,forget it!
screen服务在QNX系统中一般由命令:screen -c /lib64/graphics.conf启动,这个动作通常由startupmanager带起,你可以在源码文件:filesets/launcher_scripts/disp.c中找到相关源码:
static const char* screen_arg [] = {
"screen",
"-c",
"/lib64/graphics.conf",
NULL
};
static const struct aaction screen = {
.type = TYPE_CMD,
.c = {
.flags = FLAG_BACKGROUND,
.path = "screen",
.arg = screen_arg,
.secpol_type = "screen_t",
.uid=SCREEN_UID,
.gid=SCREEN_GID,
.rmasks = 0xFE,
},
};
screen服务初始化依赖于openwfd显示框架,所以要求启动顺序要在wfd服务之后:
32795 wfd_server -U 70:70,33,21
32797 wfd_be 5
32798 screen -c /lib64/graphics.conf
需要注意的是screen的初始化并不依赖于GPU,所以它可以先于GPU驱动先初始化,但是,正常screen接口使用一定要在GPU驱动初始结束之后(特别是与GPU相关的操作).
screen服务正常启动之后会在/dev/目录下生成screen文件夹:
# ls /dev/screen/
0 9711657 mtouch
1196133 buffers qvm
487478 gpus requests
495671 input ssplash
766018 life_cycle_man_demo
823370 lpms
#
0: 这个目录包含了screen配置的主要信息,包括display配置信息,framebuffer配置信息
# ls
blt-1 dpy-2 str-2
blt-2 framebuffer1 str-4
ctx-0 framebuffer2 win-0
dpy-1 globals win-1
# pwd
/dev/screen/0
#
buffers:目录可以获取当前屏幕显示的buffer数据内容
$PID: 目录包含该进程使用到screen相关信息,例如:windows信息,buffer信息,screen_ctx
# find ./
./
./ctx-1
./ssn-0
./str-0
./str-0/str-0
./str-0/str-0-1
./win-2
# ls ./str-0/str-0-1/
buf-62 buf-62.bmp buf-62.data
# pwd
/dev/screen/9711657
#
用于设置修改windows的属性,牛逼的地方在于是实时生效的,效果和修改代码一样:
screencmd setiv win-8 SCREEN_PROPERTY_SIZE 400,400
screencmd setiv win-8 SCREEN_PROPERTY_ROTATION 90
screencmd setiv win-4 SCREEN_PROPERTY_ZORDER 1000
使用的时候,需要知道你想修的windows是哪一个,你可以在/dev/screen/$pid/目录下找到这个信息:
# ls /dev/screen/
0 9711657 mtouch
1196133 buffers qvm
487478 gpus requests
495671 input ssplash
766018 life_cycle_man_demo
823370 lpms
# ls /dev/screen/9711657/
ctx-1 ssn-0 str-0 win-2
#
执行:echo surfacedump=0xFF > /dev/displaylog
可以在/tmp目录下得到dump出来的图层文件:
# ls /tmp/displog_surface_dump_*
/tmp/displog_surface_dump_8_[00:00:39.085]_1920x1080_argb8888.rgb
这个方法其实是wfd的debug方法,可以dump各个pipeline上显示的图像数据,dump输出的数据是raw的rgb数据,可以用yuv player一类的工具直接打开。当然displaylog的功能不仅限于此:
# cat /tmp/displog_help
Input Commands:
echo ? > /dev/displaylog --> help
echo s > /dev/displaylog --> status
echo ll=n > /dev/displaylog --> change log level (default=0x8A)
0x00000000 NONE
0x00000001 API_TYPE
0x00000002 ERROR_INFO_TYPE
0x00000004 PROFILE_TYPE
0x00000008 CRITICAL_ERROR_TYPE
0x00000010 INFO_TYPE
0x00000020 KERNEL_TRACK_TYPE
0x00000040 ISR_ERROR_INFO_TYPE
0x00000080 CRITICAL_INFO_TYPE
0x00000100 BACK_TRACE_TYPE
0X00000200 WARNING_INFO_TYPE
0x00000400 API_PERF_INFO_TYPE
echo rd=n [submodule] [submodule ID]> /dev/displaylog --> register dump
1: MDP
[submodule]
1: SWI
2: CTL
3: VIG
4: VIG_SSPP
5: RGB
6: RGB_SSPP
7: DMA
8: DMA_SSPP
9: CURSOR_SSPP
10: LAYER_MIXER
11: DSPP
12: WB
13: INTF
14: PP
15: ENCR_NS
16: ENCR_S
17: AADC
18: CDM
19: DSC
20: QDSS
2: DSI0
3: DSI1
[submodule]
1: CTRL
2: PHYREG
3: PHY
4: PHYPLL
4: EDP
5: DP0
6: DP1
[submodule]
0: AHBCLK
1: AUXCLK
2: LCLK
3: PCLK
echo surfacedump=n [m] > /dev/displaylog --> dump input surfaces to /tmp/*
1: RGB0 5: VG0 t9: DMA0 13: CURSOR0
2: RGB1 6: VG1 t10: DMA1 14: CURSOR1
3: RGB2 7: VG2 t11: DMA2 15: CURSOR2
4: RGB3 8: VG3 t12: DMA3 16: CURSOR3
0xFF: dump valid surfaces attached to all mdp pipes
[m]: Number of frames to dump for multiframe option
echo apibtenable=n > /dev/displaylog --> API backtrace enable
0: disable
1: enable
echo apibtdump > /dev/displaylog --> Dump API backtrace to file
echo smmudump > /dev/displaylog --> dump SMMU info to /tmp/*
echo md > /dev/displaylog --> dump Mutex info to /tmp/*
echo wfd ?>/dev/displaylog --> dump wfd help info to /tmp/
echo forcereset=n > /dev/displaylog --> forcefully reset a display module
1: PRIMARY
2: EXTERNAL
3: WRITEBACK
echo dpauxread [module] [aux_addr] [len] --> To read the DPCD registers
module:
4: EDP
5: DP0
6: DP1
aux_addr: DPCD address
len: number of DPCD registers to be read
echo dpTPG [module] [stream] [enable] [pattern]
module:
4: EDP
5: DP0
6: DP1
stream:
0: stream 0
1: stream 1
enable:
0: disable
1: enable
TPG pattern:
0: CHECKERED_RECTANGLE_PATTERN[default]
1: BASIC_COLOR_CHANGING_PATTERN
2: COLOR_SQUARE
3: BLACK_WHITE_VERTICAL_LINES
4: GRAYSCALE_RAMP
echo dsiTPG [module] [enable] [pattern]
module:
2: DSI0
3: DSI1
Enable:
0: Disable
1: Enable
pattern:
0: CHECKERED_RECTANGLE_PATTERN[default]
1: BASIC_COLOR_CHANGING_PATTERN
2: COLOR_SQUARE
3: BLACK_WHITE_VERTICAL_LINES
4: GRAYSCALE_RAMP
Reading Outputs:
cat /dev/displaylog
#