调用过程:
weston/compositor/main.c
wet_main-->...
const struct weston_option core_options[] = {
{ WESTON_OPTION_STRING, "backend", 'B', &backend }//根据-B参数加载指定的backend
...
cmdline = copy_command_line(argc, argv);
parse_options(core_options, ARRAY_LENGTH(core_options), &argc, argv);
load_backend-->
load_drm_backend-->
weston_compositor_load_backend(c, WESTON_BACKEND_DRM,&config.base)-->
backend_init = weston_load_module(backend_map[backend], "weston_backend_init");
-->weston_module_path_from_env
-->dlope
...
-->weston_backend_init
-->drm_backend_create
1、load_backend()函数
调用不同的函数加载不同的.so。DRM后端是load_drm_backend()函数,和drm-backend.so
static int
load_backend(struct weston_compositor *compositor, const char *backend,
int *argc, char **argv, struct weston_config *config)
{
if (strstr(backend, "headless-backend.so"))
return load_headless_backend(compositor, argc, argv, config);
else if (strstr(backend, "rdp-backend.so"))
return load_rdp_backend(compositor, argc, argv, config);
else if (strstr(backend, "fbdev-backend.so"))
return load_fbdev_backend(compositor, argc, argv, config);
else if (strstr(backend, "drm-backend.so"))
return load_drm_backend(compositor, argc, argv, config);
else if (strstr(backend, "x11-backend.so"))
return load_x11_backend(compositor, argc, argv, config);
else if (strstr(backend, "wayland-backend.so"))
return load_wayland_backend(compositor, argc, argv, config);
weston_log("Error: unknown backend \"%s\"\n", backend);
return -1;
}
2、weston_compositor_load_backend()
weston_compositor_load_backend()函数通过WESTON_BACKEND_DRM参数调用到DRM,
libweston.h中定义了枚举类型,包括几种常见的后端。
?
?
enum weston_compositor_backend {
WESTON_BACKEND_DRM,
WESTON_BACKEND_FBDEV,
WESTON_BACKEND_HEADLESS,
WESTON_BACKEND_RDP,
WESTON_BACKEND_WAYLAND,
WESTON_BACKEND_X11,
};
3、weston_load_module()
weston_load_module加载drm-backend.so,路径./build/libweston/backend-drm/drm-backend.so
backend_init = weston_load_module(backend_map[backend], "weston_backend_init");
static const char * const backend_map[] = {
[WESTON_BACKEND_DRM] = "drm-backend.so",
[WESTON_BACKEND_FBDEV] = "fbdev-backend.so",
[WESTON_BACKEND_HEADLESS] = "headless-backend.so",
[WESTON_BACKEND_RDP] = "rdp-backend.so",
[WESTON_BACKEND_WAYLAND] = "wayland-backend.so",
[WESTON_BACKEND_X11] = "x11-backend.so",
};
4、drm_backend_create()
drm_backend源码:libweston/backend-drm/
weston/libweston/backend-drm$ tree -L 1
.
├── drm.c
├── drm-gbm.c
├── drm-internal.h
├── drm-virtual.c
├── fb.c
├── kms.c
├── libbacklight.c
├── libbacklight.h
├── meson.build
├── modes.c
├── state-helpers.c
├── state-propose.c
├── vaapi-recorder.c
└── vaapi-recorder.h
0 directories, 14 files
./libweston/backend-drm/drm.c:3234:weston_backend_init-->drm_backend_create
drm_backend_create:
-->weston_launcher_connect
...
if (config->specific_device)
drm_device = open_specific_drm_device(b, config->specific_device);
else
drm_device = find_primary_gpu(b, seat_id);
if (drm_device == NULL) {
weston_log("no drm device found\n");
goto err_udev;
}
...
-->init_kms_caps//kms.c
-->drmGetCap(b->drm.fd, DRM_CAP_TIMESTAMP_MONOTONIC, &cap);
-->drmGetCap(b->drm.fd, DRM_CAP_CURSOR_WIDTH, &cap);
-->drmGetCap(b->drm.fd, DRM_CAP_CURSOR_HEIGHT, &cap);
-->drmSetClientCap(b->drm.fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);//If set to 1, the DRM core will expose all planes (overlay, primary, and
cursor) to userspace.
-->drmGetCap(b->drm.fd, DRM_CAP_CRTC_IN_VBLANK_EVENT, &cap);
-->drmSetClientCap(b->drm.fd, DRM_CLIENT_CAP_ATOMIC, 1);//If set to 1, the DRM core will expose atomic properties to userspace
-->drmSetClientCap(b->drm.fd, DRM_CLIENT_CAP_WRITEBACK_CONNECTORS, 1);//以上这些都是libdrm中的定义了
...//render 选择CPU使用pixman,GPU使用egl
if (b->use_pixman) {
if (init_pixman(b) < 0) {
weston_log("failed to initialize pixman renderer\n");
goto err_udev_dev;
}
} else {
if (init_egl(b) < 0) {//drm-gbm.c
weston_log("failed to initialize egl\n");
goto err_udev_dev;
}
流程一
open_specific_drm_device()函数最终调用到libdrm库中的drmModeGetResources
-->udev_device_new_from_subsystem_sysname
-->drm_device_is_kms
-->weston_launcher_open
-->drmModeGetResources//libdrm
流程二
find_primary_gpu()
-->e = udev_enumerate_new(b->udev);
-->udev_enumerate_add_match_subsystem(e, "drm");
-->udev_enumerate_add_match_sysname(e, "card[0-9]*");
-->udev_enumerate_scan_devices(e);
-->path = udev_list_entry_get_name(entry);
-->device = udev_device_new_from_syspath(b->udev, path);
-->drm_device_is_kms(b, device)
-->weston_launcher_open
-->drmModeGetResources//libdrm
流程三
render的选择
1)init_pixman()
-->pixman_renderer_init//pixman-renderer.c
2)init_egl()
init_egl()
-->create_gbm_device
-->weston_load_module("gl-renderer.so", "gl_renderer_interface");
-->dlopen("libglapi.so.0", RTLD_LAZY | RTLD_GLOBAL);
-->gbm_create_device
-->drm_backend_create_gl_renderer
|