04-Weston DRM Backend

调用过程:

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

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值