精华内容
下载资源
问答
  • WaylandWeston关系
    2022-05-16 11:10:59

    Wayland是一套display server(Wayland compositor)与client间的通信协议

    Weston是Wayland compositor的参考实现

    Wayland基于domain socket实现了一套display server与client间通信的库(简单的基于例子的介绍可以参见http://blog.csdn.net/jinzhuojun/article/details/40264449),并且以XML形式定义了一套可扩展通信协议。这个协议分为Wayland核心协议和扩展协议(位于Weston中)。Weston作为Wayland compositor的参考实现,一般和Wayland同步发布。

    Wayland协议主要提供了Client端应用与Server端Compositor的通信机制,Weston是Server端Compositor的一个参考实现。Wayland协议中最基础的是提供了一种面向对象的跨进程过程调用的功能,在作用上类似于Android中的Binder。与Binder不同的是,在Wayland中Client和Server底层通过domain socket进行连接。和Binder一样,domain socket支持在进程间传递fd,这为传递graphic buffer和shared memory等提供了基础。Client和Server端一方面各自在消息循环中等待socket上的数据,拿到数据后经过反序列化处理生成本地的函数调用,然后进行调用;另一方面将本地的远端调用请求封装序列化后通过socket发出。另外,由于是基于消息循环的处理模型,意味着这种调用不是同步,但通过等待Server端处理完成后的事件再返回可以达到同步调用的效果。

    UNIX Domain Socket是在socket架构上发展起来的用于同一台主机的进程间通讯(IPC)

    特点:

    1. 它不需要经过网络协议栈,不需要打包拆包、计算校验和、维护序号和应答等

    2. 只是将应用层数据从一个进程拷贝到另一个进程。

    工作模式:

    SOCK_DGRAM     类似于 UDP

    SOCK_STREAM    类似于TCP

    用途:

    UNIX Domain Socket可用于两个没有亲缘关系的进程,是全双工的,是目前使用最广泛的IPC机制

    比如X Window服务器和GUI程序之间就是通过UNIX Domain Socket通讯的

    二、工作流程

    与网络socket的不同点:

        1.   address family为AF_UNIX

        2.  unix domain socket不需要IP和端口,取而代之的是文件路径来表示“网络地址”

        原理:               

                   UNIXDomain socket用结构体sockaddr_un表示,是一个socket类型的文件在文件系统中的路径

                   这个socket文件由bind()调用创建,如果调用bind()时该文件已存在,则bind()错误返回

                  

                   UNIX Domain Socket客户端一般要显式调用bind函数,而不象网络socket一样依赖系统自动分配的地址。

                   客户端bind的socket文件名可以包含客户端的pid,这样服务器就可以区分不同的客户端

    工作流程:

    服务器端:创建socket—绑定文件(端口)—监听—接受客户端连接—接收/发送数据—…—关闭

    客户端:   创建socket—绑定文件(端口)—连接—发送/接收数据—…—关闭

    三、阻塞和非阻塞(SOCK_STREAM方式)

    读写操作有两种操作方式:阻塞和非阻塞

    1.阻塞模式下

    阻塞模式下,发送数据方和接收数据方的表现情况如同命名管道

    2.非阻塞模式

    在send或recv函数的标志参数中设置MSG_DONTWAIT,则发送和接收都会返回。如果没有成功,则返回值为-1,errno为EAGAIN 或 EWOULDBLOCK

    四.实例

    服务端代码:

    #include <stdio.h>

    #include <sys/stat.h>

    #include <sys/socket.h>

    #include <sys/un.h>

    #include <errno.h>

    #include <stddef.h>

    #include <string.h>

    #include <unistd.h>

    #include <time.h>

    #include <stdlib.h>

    #define UNIX_DOMAIN "/data/local/tmp/ndk_cmd"

    int main(void) {

        int listen_fd = socket(PF_UNIX, SOCK_STREAM, 0);

        if (listen_fd < 0) {

            perror("cannot create communication socket\n");

            return 1;

        }

        //set server addr_param

        struct sockaddr_un srv_addr;

        srv_addr.sun_family = AF_UNIX;

        strncpy(srv_addr.sun_path, UNIX_DOMAIN, sizeof(srv_addr.sun_path) - 1);

        unlink (UNIX_DOMAIN);

        //bind sockfd & addr

        int ret = bind(listen_fd, (struct sockaddr*) &srv_addr, sizeof(srv_addr));

        if (ret == -1) {

            perror("cannot bind server socket");

            close(listen_fd);

            unlink(UNIX_DOMAIN);

            return 1;

        }

        //listen sockfd

        ret = listen(listen_fd, 1);

        if (ret == -1) {

            perror("cannot listen the client connect request");

            close(listen_fd);

            unlink(UNIX_DOMAIN);

            return 1;

        }

        //have connect request use accept

        struct sockaddr_un clt_addr;

        int len = sizeof(clt_addr);

        int com_fd = accept(listen_fd, (struct sockaddr*) &clt_addr, &len);

        if (com_fd < 0) {

            perror("cannot accept client connect request");

            close(listen_fd);

            unlink(UNIX_DOMAIN);

            return 1;

        }

        //read and printf sent client info

        printf("/n=====info=====/n");

        static char recv_buf[1024];

        for (int i = 0; i < 4; i++) {

            memset(recv_buf, 0, 1024);

            int num = read(com_fd, recv_buf, sizeof(recv_buf));

            printf("Message from client (%d)) :%s\n", num, recv_buf);

        }

        close(com_fd);

        close(listen_fd);

        unlink(UNIX_DOMAIN);

        return 0;

    }

    客户端代码:

    #include <stdio.h>

    #include <stddef.h>

    #include <sys/stat.h>

    #include <sys/socket.h>

    #include <sys/un.h>

    #include <errno.h>

    #include <string.h>

    #include <unistd.h>

    #include <time.h>

    #include <stdlib.h>

    int main(void) {

        //creat unix socket

        int connect_fd = socket(PF_UNIX, SOCK_STREAM, 0);

        if (connect_fd < 0) {

            perror("cannot create communication socket");

            return 1;

        }

        static struct sockaddr_un srv_addr;

        srv_addr.sun_family = AF_UNIX;

        strcpy(srv_addr.sun_path, "/data/local/tmp/ndk_cmd");

        //connect server

        int ret = connect(connect_fd, (struct sockaddr*) &srv_addr, sizeof(srv_addr));

        if (ret == -1) {

            perror("cannot connect to the server");

            close(connect_fd);

            return 1;

        }

        char snd_buf[1024];

        memset(snd_buf, 0, 1024);

        strcpy(snd_buf, "message from client");

        //send info server

        for (int i = 0; i < 4; i++)

            write(connect_fd, snd_buf, sizeof(snd_buf));

        close(connect_fd);

        return 0;

    }

    Socket,又称套接字,是Linux跨进程通信(IPC,Inter Process Communication,详情参考:Linux进程间通信方式总结)方式的一种。相比于其他IPC方式,Socket更牛的地方在于,它不仅仅可以做到同一台主机内跨进程通信,它还可以做到不同主机间的跨进程通信。根据通信域的不同可以划分成2种:Unix domain socket 和 Internet domain socket。

    main(int argc, char **argv)      simple-shm.c
    {
        struct sigaction sigint;
        struct display *display;
        struct window *window;
        int ret = 0;

        display = create_display();  {

                 display->display = wl_display_connect(NULL);

                 wl_display_roundtrip(display->display);

        }

               
        window = create_
    window(display, 250, 250);
        if (!window)
            return 1;

         {

               xdg_wm_base_get_xdg_surface(display->wm_base,
                                window->surface);
            assert(window->xdg_surface);
            xdg_surface_add_listener(window->xdg_surface,
                         &xdg_surface_listener, window);

             }

        sigint.sa_handler = signal_int;
        sigemptyset(&sigint.sa_mask);
        sigint.sa_flags = SA_RESETHAND;
        sigaction(SIGINT, &sigint, NULL);

        /* Initialise damage to full surface, so the padding gets painted */
        wl_
    surface_damage(window->surface, 0, 0,
                  window->width, window->height);

        if (!window->wait_for_configure)
          
     redraw(window, NULL, 0);

        while (running && ret != -1)
            ret = wl_display_dispatch(display->display);

        fprintf(stderr, "simple-shm exiting\n");

        destroy_window(window);
        destroy_display(display);

        return 0;
    }

     

    一、基本工作流程

    以Weston自带的例程simple-shm为例,先感受一下Client如何通过Wayland协议和Compositor通信。

    1. 连接Server,绑定服务

    display->display = wl_display_connect() // 通过socket建立与Server端的连接,得到wl_display。它即代表了Server端的display资源,同时也是代理对象wl_proxy。Client可以通过它来向Server端提交调用请求和接收事件。

    display->registry = wl_display_get_registry(display->display) // 申请创建registry,得到代理对象wl_registry。这个对象相当于Client在Server端放的一个用于嗅探资源的Observer。Client通过它得到Server端有哪些Global对象的信息。Server端有一系列的Global对象,如wl_compositor, wl_shm等,串在display->global_list链表里。Global对象在概念上类似于Service服务,因此Server端相当于充当了ServiceManager的角色。

    wl_registry_add_listener(display->registry, ®istry_listener,...) // 让Client监听刚才创建的wl_registry代理对象。这样,当Client调用wl_display_get_registry()函数或者有新的Global对象加入到Server端时,Client就会收到event通知

    wl_display_roundtrip() // 等待前面的请求全被Server端处理完,它同步了Client和Server端。这意味着到这个函数返回时,Server端有几个Global对象,回调处理函数registry_handle_global()应该就已经被调用过几次了。

    registry_handle_global()中会判断是当前这次event代表何种Global对象,然后调用wl_registry_bind()进行绑定,得到远程服务对象的本地代理对象。这些代理对象类型可以是wl_shm, wl_compositor等,但本质上都是wl_proxy类型。这步的作用类似于Android中的bindService(),它会得到一个远端Service的本地代理。

    2. 创建窗口

    window->surface = wl_compositor_create_surface() // 通过刚才绑定的wl_compositor服务创建Server端的weston_surface,返回代理对象 wl_surface。

    xdg_shell_get_xdg_surface(..., window->surface, ...) // 通过刚才绑定的xdg_shell服务创建Server端的shell_surface,返回代理对象 xdg_surface。有些例子中用的是wl_shell_surface,它和xdg_surface的作用是一样的。xdg_surface是作为wl_shell_surface将来的替代品,但还没进Wayland核心协议。

    为什么一个窗口要创建两个surface呢?因为Wayland协议假设Server端对Surface的管理分两个层次。以Weston为例,Compositor只负责合成(代码主要在compositor.c),它相当于Android中的SurfaceFligner,它所看到的主要是weston_surface。而Weston在启动时会加载shell模块(如desktop-shell.so,代码主要在desktop-shell/shell.c),它相当于Android中的WindowManagerService,它所看到的主要是shell_surface。shell_surface在结构上是weston_surface的进一步封装,为了做窗口管理。这样,合成渲染和窗口管理的模块既可以方便地相互访问又保证了较低的耦合度。

    3. 分配buffer与绘制

    wl_surface_damage() // 告诉Compositor该surface哪块区域是脏的,需要重绘。一开始是整个窗口区域。

    redraw() //  接下来调用redraw()开始绘制的循环,这里是双buffer的软件渲染。

        window_next_buffer() // 取一个buffer,用作绘制。

            create_shm_buffer() // 如果该buffer尚未分配则用之前绑定的wl_shm服务分配一块共享内存。

                fd = os_create_anonymous_file() // 为了创建共享内存,先创建一个临时文件作为内存映射的backing file。

                mmap(..., fd,...) // 将该文件先映射到Client端的内存空间。

                pool = wl_shm_create_pool(..., fd,...) // 通过wl_shm服务创建共享内存池。将刚才的fd作为参数传过去,这样Server端就可以和Client通过这个fd映射到同一块物理内存。

                buffer->buffer = wl_shm_pool_create_buffer(pool, ...) // 通过这个共享内存池在Server端分配buffer,返回wl_buffer为其本地代理对象。

              wl_buffer_add_listener(buffer->buffer, &buffer_listener,...) // 监听这个buffer代理对象,当Server端不再用这个buffer时,会发送release事件。这样,Client就可以重用这个buffer作下一帧的绘制。

        paint_pixels() // Client在buffer上绘制自己的内容。

        wl_surface_attach()// 将绘制好的buffer attach到surface上。作用上类似于Android中的updateTexImage(),即把某一个buffer与surface绑定。

        wl_surface_damage()// 告诉Server端的Compositor这个surface哪块区域是脏区域,需要重新绘制。

        window->callback = wl_surface_frame() // 在Server端创建Frame callback,它会被放在该surface下的frame_callback_list列表中。返回它的代理对象wl_callback

        wl_callback_add_listener(window->callback, &frame_listener, ...) // 监听前面得到的callback代理对象。在Server端Compositor在完成一帧的合成渲染后,会往这些callback对象发done的事件(参考weston_output_repaint())。Client收到后会调用参数中wl_callback_listener中的done事件对应的方法,这里是redraw()函数。这样,就形成了一个循环。

        wl_surface_commit() // 在0.99版本后,为了保证原子性及使surface属性的改动顺序无关,Server端对于surface的属性(damage region, input region, opaque region, etc.)都是双buffer的(weston_surface_state)。所以commit前的改动都存在backing buffer中。只有当Client调用wl_surface_commit()时,这些改动才生效。

    与Android作个类比,这里的wl_surface对应SF中的Layer,wl_buffer对应GraphicBuffer。Weston对应SF+WMS。一个surface对应用户视角看到的一个窗口。为了使Client和Server并行作业,一般会用多个buffer。和Android比较不同的是,Android是Server端来维护buffer的生命周期,而 Wayland中是Client端来做的。

    更多相关内容
  • WaylandWeston简介

    千次阅读 2021-04-19 14:23:53
    先来简单说一下X11 和Wayland的区别: x11是一个很古老的系统,有了几十年的历史,一开始设计之初,是受限于个人电脑的弱小,所以将所有渲染相关的计算都放在服务端,所谓的X Server. 所有的客户端可以试运行在...

    先来简单说一下X11 和Wayland的区别:

          x11是一个很古老的系统,有了几十年的历史,一开始设计之初,是受限于个人电脑的弱小,所以将所有渲染相关的计算都放在服务端,所谓的X Server. 所有的客户端可以试运行在本地的,也可以试运行在网络上的,称之为客户端XClient. X Server和XClient通信的手段就是X Protocol. 所有的客户端接收到鼠标,键盘等等事件,都要通知Server,然后Server经过计算,通知Driver进行描画。这在当时是唯一可行的方式,但是在现在看来却过时了。因为客户端也有很强大的渲染能力

          所以Wayland诞生了。Wayland的原理是,所有的渲染都发生在客户端,客户端接收到输入事件之后,自行计算需要渲染的区域,然后再内存中开辟一段(可以是共享内存,也可以是显存,取决于实际硬件),然后将绘制好的图像放入buffer中,然后通知Wayland的Server,称之为 Compositor,Compositor会监听所有client的请求,然后做一件很简单的工作,就是把Client绘制好的图片合成一下,然后发送到渲染器渲染就行了。这样就大大减少了Client和Server的频繁交互和数据传递。效率大大提高

    简单地说,Wayland是一套display server(Wayland compositor)与client间的通信协议,而Weston是Wayland compositor的参考实现。其官网为http://wayland.freedesktop.org/

          它们定位于在Linux上替换X图形系统。X图形系统经历了30年左右的发展,其设计在今天看来已略显陈旧。在X系统中,X Server作为中心服务,连接client和硬件以及compositor。但时至今日,原本在X Server中做的事很多已被移到kernel或者单独的库中因此X Server就显得比较累赘了。Wayland在架构上去掉了这个中间层,将compositor作为display server,使client与compositor直接通信从而在灵活性和性能等方面上能够比前辈更加出色

    Wayland既可以用于传统的桌面又适用于移动设备,已经被用于Tizen,Sailfish OS等商业操作系统,同时越来越多的窗口和图形系统开始兼容Wayland协议。Wayland基于domain socket实现了一套display server与client间通信的库(简单的基于例子的介绍可以参见http://blog.csdn.net/jinzhuojun/article/details/40264449),并且以XML形式定义了一套可扩展通信协议。这个协议分为Wayland核心协议和扩展协议(位于Weston中)。Weston作为Wayland compositor的参考实现,一般和Wayland同步发布。其它Wayland compositor实现还有如mutter, Kwin, Lipstick, Enlightenment, Clayland等。

    下面分别从架构,源码及模块结构,渲染流水线,窗口和输入管理几个方面介绍下Wayland/Weston的实现。

    架构

    Wayland的系统体系架构可以参见官方文档或者https://zgdy-czg.blog.csdn.net/article/details/115760945 这里不再累述。Weston从内部体系结构来看,主要分为窗口管理(shell)合成器(compositor)输入管理几个部分。

    可见,如果拿Android作类比,从功能上看它等同于InputManagerServiceWindowManagerServiceSurfaceFlinger

    从大体的流程上来看,输入管理模块接受用户输入,然后一方面shell作出相应的窗口管理操作(如窗口堆栈的改变focus的变化等),另一方面将该input event传给之前注册了相应输入事件的client。client收到后会在handler中做相应动作,如调整视图然后重绘。如有重绘发生,新buffer渲染完成后client将其handle传给server,接着server端生成z-order序的窗口列表,之后compositor用renderer进行合成最后输出(比如到framebuffer)。

    \

    Weston是主要服务进程,它的事件处理模型采用的是典型的Reactor模式。根据Linux中万物皆文件的原则,主循环通过epoll机制等待在一系列的文件fd上。这种模型与基于线程的binder不同,是一种串行的事件处理模型。在此模型上的过程调用在不加额外同步机制的情况下是异步的。好处是不会有竞争问题,数据同步开销较小。缺点是当有一个事件处理比较耗时或者在等待IO,则有可能使整个系统性能下降或响应不及时。

    \

    主循环上等待的几个核心fd包括:
    • Server/Client通信:listener fd在Weston启动时建立,并一直监听新的client连接。一个client连接后会与Weston建立一对domain socket,Wayland就是基于它来通信的
    • 输入处理:一方面通过udev monitor监听设备的添加删除事件。另一方面如有新设备添加时会将该设备打开并监听该fd来得到输入事件
    • 其它:监听如timer(用于如睡眠锁屏等场景)和signal(如收到SIGINT, SIGTERM, SIGQUIT时退出主循环)等事件。timer和signal可以分别用timerfd和signalfd来用fd来表示。另外还有logind的dbus连接等。
    除这些外,在event loop中还会维护一个idle list。Weston中需要异步处理的操作可以放在其中。每轮循环都会检查其中是否有任务,有的话拿出来执行。

    下面看下Weston的运行时进程模型。Weston设计时是可以用一般用户运行的,但就需要用weston-launch来启动。当需要进行一些需要root权限的工作,比如关于DRM, TTY, input device的相关操作,就交由weston-launch去做。

    Weston会在启动时或按需起一些子进程,它们本质上是Weston的client,它们会通过专用的协议做一些系统应用的工作。如系统应用weston-desktop-shell负责一些系统全局的界面,比如panel, background, cursor, app launcher, lock screen等。它不作为Weston服务本身的一部分,而是作为一个client。其作用有点类似于Android中的SystemUI。这样便可方便地替换成定制的界面。weston-keyboard是软键盘面板。weston-screenshooter和weston-screensaver分别用于截屏屏保,它们都是有需要才由Weston启动的。前者在截屏快捷键按下时启动,后者在需要锁屏时启动。

    \

    另外,Weston启动时会读取weston.ini这个配置文件,其中可以配置桌面,动画和后端等等信息。详细配置见http://manpages.ubuntu.com/manpages/raring/man5/weston.ini.5.html

    源码与模块结构

    wayland/weston/libinput等项目源码位于http://cgit.freedesktop.org/wayland下。

    Wayland的协议定义在protocol目录,通信协议实现在src目录。

    它主要编译出三个库,libwayland-client,libwayland-server和libwayland-cursor

    第一个为协议的client端实现,第二个为协议的server端实现,第三个是协议中鼠标相关处理实现。

    编译时会首先编译出wayland-scanner这个可执行文件,它利用expat这个库来解析xml文件,将wayland.xml生成相应的wayland-protocol.cwayland-client-protocol.hwayland-server-protocol.h它们会被Wayland的client和server在编译时用到。同时wayland-scanner也需要在生成Weston中的Wayland扩展协议中起同样作用。

    \

    Wayland主要依赖于两个库,一个上面提到的expat协议,另一个libffi用于在跨进程过程调用中根据函数描述生成相应calling convention跳板代码

    -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    Weston的主要实现在src目录下。与Wayland类似,protocol目录下放着Wayland协议定义。在clients目录下是一些client的例子,也包括了desktop-shell和keyboard等核心client的例子,也包含了如simple-egl, simple-shm, simple-touch等针对性的简单用例。

    Weston启动过程中会分别加载几个backend(后端):shell backendrender backendcompositor backend。它们分别用于窗口管理合成渲染合成内容输出

    \

    由于这些后端都有不同的实现,为了逻辑上的独立性和结构上的灵活性,他们都编译成动态链接库从而可以在Weston初始化时被加载进来。这种方式在Weston中被广泛采用,一些功能比如屏幕共享等都是以这种形式加载的。

    举例来说,compositor backend主要决定了compositor合成完后的结果怎么处置。从数据结构上,weston_output是output设备的抽象,而下面的backend会实现具体的output设备。
    fbdev:直接输出至linux的framebuffer设备。接口通用。
    • headless:和noop-renderer配合使用,可以在没有窗口系统的机子(比如server上)测试逻辑。
    • RPI:用于Raspberry Pi平台。
    • RDP:合成后通过RDP传输到RDP peer显示,用于远程桌面。
    DRM:Direct redering manager,桌面上一般用这个。
    x11:Wayland compositor作为X server的client。它可以让Wayland client运行在X11上。
    wayland:Wayland composiotr作为server同时,也作为另一个Wayland compositor的client。用于nested compositor。

    Renderer backend主要作为compositor的合成之用,除去noop-renderer外,有gl-renderer和pixman-renderer两种。前者为GPU硬件渲染,后者为软件渲染。shell backend用于实现具体的窗口管理。相应的实现分别在desktop-shell,fullscreen-shell和ivi-shell目录中。

    Wayland/Weston运行时依赖的库主要有下面几个,其相互关系大体如下。

    \

    libEGL, libGLES:本地窗口系统与图形driver的glue layer,mesa提供了开源版本的实现。
    libdrm:封装KMS,GEM等图形相关接口。平台相关。
    libffi:用于在运行时根据调用接口描述生成函数跳板并调用。
    pixman:用于像素操作的库,包括region, box等计算。用了许多平台相关的优化。
    cairo:软件渲染库,类似于skia。也有OpenGL后端。
    libinput:输入处理,依赖于mtdev, libudev, libevdev等库。
    libxkbcommon:主要用于键盘处理。
    libjpeg, libpng, libwebp:用于加载各种图片文件,像壁纸,面板和鼠标等都需要。

    渲染流水线

    一个Wayland client要将内存渲染到屏幕上,首先要申请一个graphic buffer绘制完后传给Wayland compositor并通知其重绘。Wayland compositor收集所有Wayland client的请求,然后以一定周期把所有提交的graphic buffer进行合成,合成完后进行输出。

    本质上,client需要将窗口内容绘制到一个和compositor共享的buffer上。这个buffer可以是普通共享内存,也可以是DRM中的GBM或是gralloc提供的可供硬件(如GPU)操作的graphic buffer。在大多数移动平台上,没有专门的显存,因此它们最终都来自系统内存,区别在于图形加速硬件一般会要求物理连续且符合对齐要求的内存。如果是普通共享内存,一般是物理不连续的,多数情况用于软件渲染。有些图形驱动也支持用物理不连续内存做硬件加速,但效率相对会低一些。根据buffer类型的不同client可以选择自己绘制,或是通过Cairo,OpenGL绘制,或是更高层的如Qt,GTK+这些widget库等绘制。绘制完后client将buffer的handle以及需要重绘的区域传给server。在server端,compositor将该buffer转为纹理(如果是共享内存使用glTexImage2D上传纹理,硬件加速buffer用GL_OES_EGL_image_external扩展生成外部纹理)。最后将其与其它的窗口内容进行合成。下面是抽象的流程图。

    \


    注意Wayland设计中默认buffer是从client端分配的。这和Android中在server端分配buffer的策略是不同的。

    这样,client可以自行设计buffer的管理策略。理论上,client可以始终只用一块buffer,但因为这块buffer在client和server同时访问会产生竞争,所以一般client端都会实现buffer queue

    流水线上比较关键的一环是buffer跨进程的传输,也就是client和server间的有效传递。buffer当然不可能通过拷贝传输,因此这里只会传handle,本质上是传buffer的fd。我们知道fd是per-process的。而可以传递fd的主要IPC机制有binder, domain socket和pipe等

    Wayland底层用的是domain socket,因此可以用于传fd。

    在这条流水线上,可以看到,client和server端都会发生绘制。client绘制本地的窗口内容,server端主要用于合成时渲染。注意两边都可独立选择用软件或者硬件渲染

    现在的商用设备上,多是硬件加速渲染。和Android上的SurfaceFlinger和Ubuntu上的Mir一样,Wayland同样基于EGL接口。EGL用于将本地窗口系统与OpenGL关联起来,与WGL, GLX等作用类似,只是它是用于Embedded platform的。在Wayland/Weston系统中,Wayland定义了用于EGL的窗口抽象,来作为EGL stack(也就是厂商的图形驱动)和Wayland协议的glue layer。它对EGL进行了扩展,增加了比如eglBindWaylandDisplayWL, eglUnbindWaylandDisplayWL, eglQueryWaylandBufferWL等接口,对Wayland友好的EGL库应该提供它们的实现,也就是说要提供Wayland EGL platform,比如mesa(src/egl/main/eglapi.c中)。另一种做法是像libhybris中eglplatform一样通过EGL wrapper的方式加上这些支持(hybris/egl/platforms/common/eglplatformcommon.cpp)。同时,EGL stack需要提供厂商相关的协议扩展使client能与compositor共享buffer。wayland-egl库提供了Wayland中surface和EGL粘合的作用。一个要用硬件加速的EGL window可以基于Wayland的surface创建,即通过wayland-egl提供的接口创建wl_egl_window。wl_egl_window结构中包含了wl_surface,然后wl_egl_window就可以被传入EGL的eglCreateWindowSurface()接口。这样就将Wayland surface与EGL stack联系在一起了。

    窗口管理

    前面提到,buffer需要有surface为载体,这个surface可以理解为一个窗口的绘制表面。如果一个Wayland client的窗口要被窗口管理器(Shell)所管理,则需要为这个surface创建相应的shell surface。理一下这里相关的几个核心概念:surfaceviewshell surface。首先,surface是Weston中的核心数据结构之一。Surface代表Wayland client的一个绘图表面。Client通过将画好的buffer attach到surface上来更新窗口,因此说surface是buffer的载体

    在Weston中,shell是窗口管理器,因此一个surface要想被窗口管理器管理,需要创建相应的shell surface。同时shell surface对应的其实是surface的一个view。view是surface的一个视图。换句话说,同一个surface理论上可以有多个view,因此weston_surface结构中有view的列表。这里和我们逻辑上的窗口的概念最近似的是view,因为它对应用户所看到的一个窗口。而当surface与view是1:1关系时(绝大多数情况下),surface也可近似等同于窗口。在server端它们的数据结构是相互关联的。

    \

    如果从Server/Client角度,它们的相互对应关系如下:

    \

     

    另外subsurface可以作为surface的附属绘图表面,它与父surface保持关联,但拥有独立的绘图surface,类似于Android中的SurfaceView,作用也是类似。主要用于Camera,Video等应用。

    窗口管理不是直接管理view,而是分为两层进行管理。Layer是中间层,系统中的layer大体有下面几个,按从上到下顺序为:
    • Fade layer
    • Lock layer
    • Cursor layer
    • Input panel layer
    • Fullscreen layer
    • Panel layer
    Workspace layers
    • Background layer


    其中的workspace layer是一个数组,默认是一个,也可以有多个,其数量可以在weston.ini中指定。大部分的普通应用窗口就是在这个layer中。这些layer被串成list。每次在要做合成时,会首先将这些layer的view按顺序合并到一个view list中。这样,在composition过程中compositor只需访问这个view list。

    \

    可以看到,这是一个二层有序列表合成一个有序列表的过程。这和Android中的WMS通过为每种类型的窗口定义一段z轴区域的原理类似。WMS中每个类型的窗口对定一个基数(定义在WindowManager.java),它会乘以乘数再加上偏移从而得到z轴上的区域边界。区别在于Weston中不是以数值而是有序列表表示z-order。结合具体的数据结构:

    \


     

    输入管理

    为了提高输入管理部分的重用性模块性。Weston将对输入设备(键盘,鼠标,触摸屏等)的处理分离到一个单独的库,也就是libinput中。这样,其它的图形处理系统也可以共用这部分,比如X.Org Server和Mir。

    具体地,它提供了设备检测设备处理输入事件处理等基本功能,类似于Android中的EventHub。此外它还有pointer acceleration,touchpad support及gesture recognition等功能。libinput更像是一个框架,它将几个更底层的库的功能整合起来。它主要依赖于以下几个库:
    mtdev:Multi-touch设备处理,比如它会将不带tracking ID的protocol A转化为protocol B
    libevdev处理kernel中evdev模块对接。
    libudev:主要用于和udevd的通信,从而获取设备的增加删除事件。也可从kernel获取。

    Weston中的输入管理模块与libinput对接,它实现了两大部分的功能:一是对输入设备的维护二是对输入事件的处理。对于输入事件既会在Weston中做处理,也会传给相应的client。从事件处理模型上来看,libinput的主循环监听udev monitor fd,它主要用于监听设备的添加删除事件。如果有设备添加,会打开该设备并把fd加入到libinput的主循环上。另一方面,Weston中会将libinput的epoll fd加入主循环。这样形成级联的epoll,无论是udev monitor还是input device的fd有事件来,都会通知到Weston和libinput的主循环。这些事件通过libinput中的事件缓冲队列存储,而Weston会作为消费者从中拿事件并根据事件类型进行处理。

    \

     

    Weston中支持三种输入设备,分别是键盘触摸鼠标。一套输入设备属于一个seat(严格来说,seat中包括一套输入输出设备)。因此,weston_seat中包含weston_keyboardweston_pointerweston_touch三个结构。系统中可以有多个seat,它们的结构被串在weston_compositor的seat_list链表中。相应的数据结构如下。

    \

    可以看到,对于焦点处理,每个设备有自己的focus,它指向焦点窗口,用于拖拽和输入等。成员focus_resource_list中包含了焦点窗口所在client中输入设备proxy对应的resource对象。在这个list中意味着可以接收到相应的事件。

    最后,Wayland/Weston作为正在活跃开发的项目,还有其它很多功能已被加入或正被加入进来。本文只是粗线条的介绍了Wayland/Weston主要结构及功能,具体细节之后再展开。

     

    展开全文
  • 非常详尽,多图慎入:WaylandWeston简介

    万次阅读 多人点赞 2019-06-08 21:09:36
    简单地说,Wayland是一套display server(Wayland compositor)与client间的通信协议,而WestonWayland compos...

    简单地说,Wayland是一套display server(Wayland compositor)与client间的通信协议,而Weston是Wayland compositor的参考实现。其官网为http://wayland.freedesktop.org/。它们定位于在Linux上替换X图形系统。X图形系统经历了30年左右的发展,其设计在今天看来已略显陈旧。在X系统中,X Server作为中心服务,连接clien和硬件以及compositor。但时至今日,原本在X Server中做的事很多已被移到kernel或者单独的库中,因此X Server就显得比较累赘了。Wayland在架构上去掉了这个中间层,将compositor作为display server,使client与compositor直接通信,从而在灵活性和性能等方面上能够比前辈更加出色。


    Wayland既可以用于传统的桌面又适用于移动设备,已经被用于Tizen,Sailfish OS等商业操作系统,同时越来越多的窗口和图形系统开始兼容Wayland协议。Wayland基于domain socket实现了一套display server与client间通信的库(简单的基于例子的介绍可以参见http://blog.csdn.net/jinzhuojun/article/details/40264449),并且以XML形式定义了一套可扩展通信协议。这个协议分为Wayland核心协议和扩展协议(位于Weston中)。Weston作为Wayland compositor的参考实现,一般和Wayland同步发布。其它Wayland compositor实现还有如mutter, Kwin, Lipstick, Enlightenment, Clayland等。


    下面分别从架构,源码及模块结构,渲染流水线,窗口和输入管理几个方面介绍下Wayland/Weston的实现。


    架构

    Wayland的系统体系架构可以参见官方文档,不再累述。Weston从内部体系结构来看,主要分为窗口管理(shell),合成器(compositor)和输入管理几个部分。可见,如果拿Android作类比,从功能上看它约等同于InputManagerService,WindowManagerService和SurfaceFlinger。从大体的流程上来看,输入管理模块接受用户输入,然后一方面shell作出相应的窗口管理操作(如窗口堆栈的改变,focus的变化等),另一方面将该input event传给之前注册了相应输入事件的client。client收到后会在handler中做相应动作,如调整视图然后重绘。如有重绘发生,新buffer渲染完成后client将其handle传给server,接着server端生成z-order序的窗口列表,之后compositor用renderer进行合成,最后输出(比如到framebuffer)。


    640?wx_fmt=png


    Weston是主要服务进程,它的事件处理模型采用的是典型的Reactor模式。根据Linux中万物皆文件的原则,主循环通过epoll机制等待在一系列的文件fd上。这种模型与基于线程的binder不同,是一种串行的事件处理模型。在此模型上的过程调用在不加额外同步机制的情况下是异步的。好处是不会有竞争问题,数据同步开销较小。缺点是当有一个事件处理比较耗时或者在等待IO,则有可能使整个系统性能下降或响应不及时。


    640?wx_fmt=png



    主循环上等待的几个核心fd包括:

    • Server/Client通信:listener fd在Weston启动时建立,并一直监听新的client连接。一个client连接后会与Weston建立一对domain socket,Wayland就是基于它来通信的。

    • 输入处理:一方面通过udev monitor监听设备的添加删除事件。另一方面如有新设备添加时会将该设备打开并监听该fd来得到输入事件。

    • 其它:监听如timer(用于如睡眠锁屏等场景)和signal(如收到SIGINT, SIGTERM, SIGQUIT时退出主循环)等事件。timer和signal可以分别用timerfd和signalfd来用fd来表示。另外还有logind的dbus连接等。

    除这些外,在event loop中还会维护一个idle list。Weston中需要异步处理的操作可以放在其中。每轮循环都会检查其中是否有任务,有的话拿出来执行。


    下面看下Weston的运行时进程模型。Weston设计时是可以以一般用户运行的,但就需要用weston-launch来启动。当需要进行一些需要root权限的工作,比如关于DRM, TTY, input device的相关操作,就交由weston-launch去做。


    Weston会在启动时或按需起一些子进程,它们本质上是Weston的client,它们会通过专用的协议做一些系统应用的工作。如系统应用weston-desktop-shell负责一些系统全局的界面,比如panel, background, cursor, app launcher, lock screen等。它不作为Weston服务本身的一部分,而是作为一个client。其作用有点类似于Android中的SystemUI。这样便可方便地替换成定制的界面。weston-keyboard是软键盘面板。weston-screenshooter和weston-screensaver分别用于截屏和屏保,它们都是按需才由Weston启动的。前者在截屏快捷键按下时启动,后者在需要锁屏时启动。


    640?wx_fmt=png

    另外,Weston启动时会读取weston.ini这个配置文件,其中可以配置桌面,动画和后端等等信息。详细配置见http://manpages.ubuntu.com/manpages/raring/man5/weston.ini.5.html。


    源码与模块结构

    wayland/weston/libinput等项目源码位于http://cgit.freedesktop.org/wayland下。


    Wayland的协议定义在protocol目录,通信协议实现在src目录。它主要编译出三个库,libwayland-client,libwayland-server和libwayland-cursor。第一个为协议的client端实现,第二个为协议的server端实现。第三个是协议中鼠标相关处理实现。编译时会首先编译出wayland-scanner这个可执行文件,它利用expat这个库来解析xml文件,将wayland.xml生成相应的wayland-protocol.c,wayland-client-protocol.h和wayland-server-protocol.h。它们会被Wayland的client和server在编译时用到。同时wayland-scanner也需要在生成Weston中的Wayland扩展协议中起同样作用。

    640?wx_fmt=png


    Wayland主要依赖于两个库,一个上面提到的expat协议,另一个libffi用于在跨进程过程调用中根据函数描述生成相应calling convention的跳板代码。


    Weston的主要实现在src目录下。与Wayland类似,protocol目录下放着Wayland协议定义。在clients目录下是一些client的例子,也包括了desktop-shell和keyboard等核心client的例子,也包含了如simple-egl, simple-shm, simple-touch等针对性的简单用例。Weston启动过程中会分别加载几个backend:shell backend, render backend和compositor backend。它们分别用于窗口管理,合成渲染和合成内容输出。

    640?wx_fmt=png



    由于这些后端都可有不同的实现,为了逻辑上的独立性和结构上的灵活性,他们都编译成动态链接库从而可以在Weston初始化时被加载进来。这种方式在Weston中被广泛采用,一些功能比如屏幕共享等都是以这种形式加载的。


    举例来说,compositor backend主要决定了compositor合成完后的结果怎么处置。从数据结构上,weston_output是output设备的抽象,而下面的backend会实现具体的output设备。

    • fbdev:直接输出至linux的framebuffer设备。接口通用。

    • headless:和noop-renderer配合使用,可以在没有窗口系统的机子(比如server上)测试逻辑。

    • RPI:用于Raspberry Pi平台。

    • RDP:合成后通过RDP传输到RDP peer显示,用于远程桌面。

    • DRM:Direct redering manager,桌面上一般用这个。

    • x11:Wayland compositor作为X server的client。它可以让Wayland client运行在X11上。

    • wayland:Wayland composiotr作为server同时,也作为另一个Wayland compositor的client。用于nested compositor。


    Renderer backend主要用于compositor的合成之用,除去noop-renderer外,有gl-renderer和pixman-renderer两种。前者为GPU硬件渲染,后者为软件渲染。shell backend用于实现具体的窗口管理。相应的实现分别在desktop-shell,fullscreen-shell和ivi-shell目录中。


    Wayland/Weston运行时依赖的库主要有下面几个,其相互关系大体如下。


    640?wx_fmt=png


    • libEGL, libGLES:本地窗口系统与图形driver的glue layer,mesa提供了开源版本的实现。

    • libdrm:封装KMS,GEM等图形相关接口。平台相关。

    • libffi:用于在运行时根据调用接口描述生成函数跳板并调用。

    • pixman:用于像素操作的库,包括region, box等计算。用了许多平台相关的优化。

    • cairo:软件渲染库,类似于skia。也有OpenGL后端。

    • libinput:输入处理,依赖于mtdev, libudev, libevdev等库。

    • libxkbcommon:主要用于键盘处理。

    • libjpeg, libpng, libwebp:用于加载各种图片文件,像壁纸,面板和鼠标等都需要。



    渲染流水线

    一个Wayland client要将内存渲染到屏幕上,首先要申请一个graphic buffer,绘制完后传给Wayland compositor并通知其重绘。Wayland compositor收集所有Wayland client的请求,然后以一定周期把所有提交的graphic buffer进行合成。合成完后进行输出。本质上,client需要将窗口内容绘制到一个和compositor共享的buffer上。这个buffer可以是普通共享内存,也可以是DRM中的GBM或是gralloc提供的可供硬件(如GPU)操作的graphic buffer。在大多数移动平台上,没有专门的显存,因此它们最终都来自系统内存,区别在于图形加速硬件一般会要求物理连续且符合对齐要求的内存。如果是普通共享内存,一般是物理不连续的,多数情况用于软件渲染。有些图形驱动也支持用物理不连续内存做硬件加速,但效率相对会低一些。根据buffer类型的不同,client可以选择自己绘制,或是通过Cairo,OpenGL绘制,或是更高层的如Qt,GTK+这些widget库等绘制。绘制完后client将buffer的handle传给server,以及需要重绘的区域。在server端,compositor将该buffer转为纹理(如果是共享内存使用glTexImage2D上传纹理,硬件加速buffer用GL_OES_EGL_image_external扩展生成外部纹理)。最后将其与其它的窗口内容进行合成。下面是抽象的流程图。


    640?wx_fmt=png


    注意Wayland设计中默认buffer是从client端分配的。这和Android中在server端分配buffer的策略是不同的。这样,client可以自行设计buffer的管理策略。理论上,client可以始终只用一块buffer,但因为这块buffer在client和server同时访问会产生竞争,所以一般client端都会实现buffer queue。流水线上比较关键的一环是buffer跨进程的传输,也就是client和server间的有效传递。buffer当然不可能通过拷贝传输,因此这里只会传handle,本质上是传buffer的fd。我们知道fd是per-process的。而可以传递fd的主要IPC机制有binder, domain socket和pipe等。Wayland底层用的是domain socket,因此可以用于传fd。


    在这条流水线上,可以看到,client和server端都会发生绘制。client绘制本地的窗口内容,server端主要用于合成时渲染。注意两边都可独立选择用软件或者硬件渲染。现在的商用设备上,多是硬件加速渲染。和Android上的SurfaceFlinger和Ubuntu上的Mir一样,Wayland同样基于EGL接口。EGL用于将本地窗口系统与OpenGL关联起来,与WGL, GLX等作用类似,只是它是用于Embedded platform的。在Wayland/Weston系统中,Wayland定义了用于EGL的窗口抽象,来作为EGL stack(也就是厂商的图形驱动)和Wayland协议的glue layer。它对EGL进行了扩展,增加了比如eglBindWaylandDisplayWL, eglUnbindWaylandDisplayWL, eglQueryWaylandBufferWL等接口,对Wayland友好的EGL库应该提供它们的实现,也就是说要提供Wayland EGL platform,比如mesa(src/egl/main/eglapi.c中)。另一种做法是像libhybris中eglplatform一样通过EGL wrapper的方式加上这些支持(hybris/egl/platforms/common/eglplatformcommon.cpp)。同时,EGL stack需要提供厂商相关的协议扩展使client能与compositor共享buffer。wayland-egl库提供了Wayland中surface和EGL粘合的作用。一个要用硬件加速的EGL window可以基于Wayland的surface创建,即通过wayland-egl提供的接口创建wl_egl_window。wl_egl_window结构中包含了wl_surface,然后wl_egl_window就可以被传入EGL的eglCreateWindowSurface()接口。这样就将Wayland surface与EGL stack联系在一起了。


    窗口管理

    前面提到,buffer需要有surface为载体,这个surface可以理解为一个窗口的绘制表面。如果一个Wayland client的窗口要被窗口管理器(Shell)所管理,则需要为这个surface创建相应的shell surface。理一下这里相关的几个核心概念:surface,view,shell surface。首先,surface是Weston中的核心数据结构之一。Surface代表Wayland client的一个绘图表面。Client通过将画好的buffer attach到surface上来更新窗口,因此说surface是buffer的载体。在Weston中,shell是窗口管理器,因此一个surface要想被窗口管理器管理,需要创建相应的shell surface。同时shell surface对应的其实是surface的一个view。view是surface的一个视图。换句话说,同一个surface理论上可以有多个view,因此weston_surface结构中有view的列表。这里和我们逻辑上的窗口的概念最近似的是view,因为它对应用户所看到的一个窗口。而当surface与view是1:1关系时(绝大多数情况下),surface也可近似等同于窗口。在server端它们的数据结构是相互关联的。


    640?wx_fmt=png


    如果从Server/Client角度,它们的相互对应关系如下:


    640?wx_fmt=png


    另外subsurface可以作为surface的附属绘图表面,它与父surface保持关联,但拥有独立的绘图surface,类似于Android中的SurfaceView,作用也是类似。主要用于Camera,Video等应用。


    窗口管理不是直接管理view,而是分为两层进行管理。Layer是中间层,系统中的layer大体有下面几个,按从上到下顺序为:

    • Fade layer

    • Lock layer

    • Cursor layer

    • Input panel layer

    • Fullscreen layer

    • Panel layer

    • Workspace layers

    • Background layer


    其中的workspace layer是一个数组,默认是一个,也可以有多个,其数量可以在weston.ini中指定。大部分的普通应用窗口就是在这个layer中。这些layer被串成list。每次在要做合成时,会首先将这些layer的view按顺序合并到一个view list中。这样,在composition过程中compositor只需访问这个view list。


    640?wx_fmt=png


    可以看到,这是一个二层有序列表合成一个有序列表的过程。这和Android中的WMS通过为每种类型的窗口定义一段z轴区域的原理类似。WMS中每个类型的窗口对定一个基数(定义在WindowManager.java),它会乘以乘数再加上偏移从而得到z轴上的区域边界。区别在于Weston中不是以数值而是有序列表表示z-order。结合具体的数据结构:


    640?wx_fmt=png


    输入管理

    为了提高输入管理部分的重用性和模块性。Weston将对输入设备(键盘,鼠标,触摸屏等)的处理分离到一个单独的库,也就是libinput中。这样,其它的图形处理系统也可以共用这部分,比如X.Org Server和Mir。具体地,它提供了设备检测,设备处理,输入事件处理等基本功能,类似于Android中的EventHub。此外它还有pointer acceleration,touchpad support及gesture recognition等功能。libinput更像是一个框架,它将几个更底层的库的功能整合起来。它主要依赖于以下几个库:

    • mtdev:Multi-touch设备处理,比如它会将不带tracking ID的protocol A转化为protocol B。

    • libevdev:处理kernel中evdev模块对接。

    • libudev:主要用于和udevd的通信,从而获取设备的增加删除事件。也可从kernel获取。


    Weston中的输入管理模块与libinput对接,它实现了两大部分的功能:一是对输入设备的维护,二是对输入事件的处理。对于输入事件既会在Weston中做处理,也会传给相应的client。从事件处理模型上来看,libinput的主循环监听udev monitor fd,它主要用于监听设备的添加删除事件。如果有设备添加,会打开该设备并把fd加入到libinput的主循环上。另一方面,Weston中会将libinput的epoll fd加入主循环。这样形成级联的epoll,无论是udev monitor还是input device的fd有事件来,都会通知到Weston和libinput的主循环。这些事件通过libinput中的事件缓冲队列存储,而Weston会作为消费者从中拿事件并根据事件类型进行处理。


    640?wx_fmt=png


    Weston中支持三种输入设备,分别是键盘,触摸和鼠标。一套输入设备属于一个seat(严格来说,seat中包括一套输入输出设备)。因此,weston_seat中包含weston_keyboard,weston_pointer和weston_touch三个结构。系统中可以有多个seat,它们的结构被串在weston_compositor的seat_list链表中。相应的数据结构如下。


    640?wx_fmt=png


    可以看到,对于焦点处理,每个设备有自己的focus,它指向焦点窗口,用于拖拽和输入等。成员focus_resource_list中包含了焦点窗口所在client中输入设备proxy对应的resource对象。在这个list中意味着可以接收到相应的事件。


    最后,Wayland/Weston作为正在活跃开发的项目,还有其它很多功能已被加入或正被加入进来。本文只是粗线条的介绍了Wayland/Weston主要结构及功能,具体细节之后再展开。


    作者:ariesjzj 

    原文:https://blog.csdn.net/jinzhuojun/article/details/47290707 

    展开全文
  • Wayland/Weston 启动方式简介

    万次阅读 2020-03-17 14:26:25
    本文简单介绍 Weston 常用的几种 backend 启动方式。...wayland-backend x11-backend 其中 headless-backend 不带任何 UI 界面,主要用于 weston 自测试,rdp-backend 则用于远程桌面。这两个 backend 本文不做介绍。

    前言

    本文简单介绍 Weston 常用的几种 backend 启动方式。目前最新的 Weston 8.0.0 支持如下几种 backend:

    • drm-backend
    • fbdev-backend
    • headless-backend
    • rdp-backend
    • wayland-backend
    • x11-backend

    其中 headless-backend 不带任何 UI 界面,主要用于 weston 自测试,rdp-backend 则用于远程桌面。这两个 backend 本文不做介绍。

    运行环境:

    • Ubuntu: 16.04
    • Weston: 1.9.0

    操作提示:

    • Ctrl+Alt+F2 返回图形界面(GDM3,Ubuntu18.04)
    • Ctrl+Alt+F7 返回图形界面(lightDM, Ubuntu16.04)
    • Ctrl+Alt+Backspace 退出Weston界面

    drm-backend

    操作步骤:

    1. Ctrl+Alt+F4 切换到虚拟终端;
    2. weston

    在这里插入图片描述
    weston 默认使用 drm 作为后端,因此运行时不需要附带任何参数。该模式下,Wayland 输出界面直接通过 /dev/dri/card0 节点来显示。渲染方式支持 Pixman (CPU 软绘)和 OpenGL/ES (GPU 硬件渲染)。

    fbdev-backend

    操作步骤:

    1. sudo usermod -a -G video hexaolong2008,将当前账号添加到video组(否则将提示权限错误,因为 /dev/fb0 属于 video 组)
    2. reboot
    3. Ctrl+Alt+F4 切换到虚拟终端
    4. weston --backend=fbdev-backend.so

    在这里插入图片描述
    该模式下,Wayland 输出界面通过 /dev/fb0 节点来显示,但不支持 OpenGL 硬件加速,因此只能使用 pixman 做 CPU 纯软绘操作,界面会比较卡顿。

    wayland-backend

    操作步骤:

    1. 先启动一个 weston
    2. 在 Weston 终端里,输入 weston 命令再启动一个 Weston 桌面

    在这里插入图片描述
    该模式下,Weston 的输出将被作为另一个 Weston 的输入,以 Wayland Client 身份运行。

    x11-backend

    操作步骤:直接在 GNOME 终端里执行 weston 命令
    在这里插入图片描述
    该模式下,Weston 的界面输出,将被作为一个 X Window 送到 X Server 中去显示。

    xwayland

    首先,它不是一个 backend,它只是 Wayland 的一个扩展功能,可以让你在 Weston 中运行 X 的程序。
    操作步骤:

    1. sudo apt install xwayland,安装 /usr/bin/Xwayland 可执行程序;
    2. weston --modules=xwayland.so,随便以哪种 backend 方式启动都可以;
    3. 启动后,可以直接在 Weston 终端中运行 X 程序,如 x-terminal-emulator

    在这里插入图片描述
    该模式下,会启动 /usr/bin/Xwayland 程序,它会提供一个 X Server,用来运行 X 程序。而这个 X Server 又是运行在 Wayland Server 上的,所以 X Server 的界面输出,最终是作为一个 Wayland Client 而送去显示的。

    SSH远程启动

    $ weston --tty=1
    

    ssh 启动方式需要明确指定使用哪个终端来显示。

    串口启动

    $ sudo -E weston --tty=1
    

    串口启动同样需要明确指定使用哪个VT来显示。

    weston-launch

    官方的说明是,weston-launch 可以为 weston 提供更高级的访问权限,如 input 设备、drm master 访问权限等,但我实际使用 weston 指令时并没有碰到权限问题。

    展开全文
  • 《Using Linux Media Controller for Wayland/Weston Renderer》 •Wayland/Weston Overview • Porting Weston to R-Car • Why Linux Media Controller Renderer? • Linux Media Controller Framework • V4...
  • Wayland/Weston的fbdev后端

    千次阅读 2017-02-06 19:03:04
    fedora 25发布有一段时间了,其最突出的特色就是用wayland取代了X。Wayland 依赖 libkms(Kernel ModeSetting, 内核模式设定。显示器的分辨率和色深加在一起被i成为模式),而libkms是包含在DRM(Direct Rendering ...
  • 采用centos7,虚拟机编译。...下载weston最新代码 在 weston根目录 $meson build/ --prefix=$WLD -Drenderer-gl=false -Dbackend-rdp=false -Dxwayland=false -Dcolor-management-colord=false -Dremot...
  • imx6 yocto Wayland-Weston AGL image

    千次阅读 2018-02-24 15:00:33
    备忘记录:This builds the Wayland-Weston AGL image with the basic AGL interface. Demos can then be run on top of this.This image has only been run on i.MX 6QP Sabre and Sabre Auto.It is not supported ...
  • WaylandWeston

    2020-01-02 10:28:15
    简单地说,Wayland是一套display server(Wayland compositor)与client间的通信协议,而WestonWayland compositor的参考实现。其官网为http://wayland.freedesktop.org/。它们定位于在Linux上替换X图形系统。X图形...
  • 基于wayland/weston源码编译简介下载工具设置环境变量构建wayland构建wayland-protocols构建weston运行westonweston的一些测试程序 简介 官网:https://wayland.freedesktop.org/ 简单地说,Wayland是一套display ...
  • WestonWayland Compositor的实现。其Server端作为独立的进程运行在系统中。MakeFile中编译成果为,“weston”的可执行程序 MakeFile.am(weston 2.0.0) bin_PROGRAMS += weston weston_LDFLAGS = -export-dynamic...
  • WestonWayland提供的示例程序。 Ubuntu下安装: sudo apt install weston 效果为: 独立运行 将环境切换到tty2,或者其他的tty。 一般Ctrl+Alt+F[1-7]表示切换到tty[1-7]。 然后执行 weston-launch 效果为: ...
  • Weston多屏显示 Weston默认支持多屏显示(比如前屏+后屏) output对象可以理解为逻辑上的一块屏幕,对于DRM,其信息通过drmModeGetResources接口获得。 View结构体有两个成员,一个保存output对象的引用来作为...
  • 简单地说,Wayland是一套display server(Wayland compositor)与client间的通信协议,而WestonWayland compositor的参考实现。其官网为http://wayland.freedesktop.org/。它们定位于在Linux上替换X图形系统。X图形...
  • wayland详解

    千次阅读 2019-09-29 01:02:21
    简单地说,Wayland是一套display server(Wayland compositor)与client间的通信协议,而WestonWayland compositor的参考实现。其官网为http://wayland.freedesktop.org/。它们定位于在Linux上替换X图形系统。X图形...
  • weston参考文档: https://www.mankier.com/5/weston.ini#Screen-Share_Section https://www.mankier.com/7/weston-drm https://blog.csdn.net/u012080932/article/details/114373675 ... 5718 root@ok5718-idk:~#
  • (工作正在进行中!) 韦斯顿 绑定libweston / libweston-desktop ,核心,参考合成。 特色: 使用libweston静态链接的自定义build.rs构建-无autoconf,无共享库插件 ...MIT许可证,与Weston本身相
  • Qt5 on Wayland

    千次阅读 2020-07-09 01:17:11
    文章目录获取源代码和编译参考:移植Qt应用程序已知...构建和使用QtWayland的最低要求是Wayland(和Weston)1.0.0。 如果您还想构建qtwebkit浏览器,则最好遵循从git构建Qt 5的说明,该指南可生成更多内容。init-repo
  • Orbital是Wayland的合成器和外壳,使用Qt5和Weston。 该项目的目标是构建一个简单但灵活且外观漂亮的Wayland桌面。 它不是成熟的DE,而是X11世界中WM的类似物,例如Awesome或Fluxbox。 依存关系 轨道取决于两件事:...
  • 02-编译weston demo

    2022-02-28 19:00:22
    参考链接:Building Weston 1、首先设置环境变量 写个简单的set-env.sh脚本方便运行: #!/bin/bash export WLD=/home/your_user_name/work/weston/install # change this to another location if you prefer ...
  • 【ARM-Linux开发】waylandweston的介绍

    千次阅读 2018-05-25 15:44:40
    https://blog.csdn.net/LG1259156776/article/details/53260920简单地说,Wayland是一套display server(Wayland compositor)与client间的通信协议,而WestonWayland compositor的参考实现。其官网为...
  • wayland的running 错误

    2017-06-02 08:05:55
    Hi: 各位大神,小白我刚开始学习wayland,遇到了如下问题,求赐教啊。 Running Weston时,执行weston ,输出如下错误: [15:52:35.037] libwayland: wl_global_create: implemented version higher than interface...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 487
精华内容 194
关键字:

wayland weston