Weston介绍

article/2025/10/11 1:41:58
  1. Weston结构说明

  1. Weston源码结构

clients:wayland显示客户端应用

compositor:合成器进程(服务端),窗体风 格样式处理

libweston:合成器以及客户端渲染处理以及驱动实现方式,以及wayland服务与客户端逻辑处理(焦点处理,鼠标事件,窗口创建绘制处理等)

backend-drm:默认渲染后端,支持Pixman和OpenGL/ES

backend-headless:不带任何ui及面,主要用于测试

backend-rdp:为远程桌面实现的渲染

backend-vnc:支持传统的fbdev,只支持Pixman

backend-wayland:weston作为一个wayland的客户端形式类似与X11在wayland上

backend-x11:weston作为一个X的客户端,使wayland跑在X服务上

color-lcms:显示器彩色管理相关处理

desktop:支持desktopshell的wayland协议调用处理

renderer-gl:gl渲染接口给display_create使用

shell-utils:shell里面共有的逻辑处理(部分焦点屏幕位置输出等函数)

desktopshell(ivishell、kioskshell、fullscreenshell):不同桌面显示形式

pipewire:

remoting:

shared: weston具体绘制窗口(外窗、模糊)处理函数。

tests: weston测试单元

tools:

wcap:

xwayland: 使X应用可以运行在wayland服务商

  1. weston结构流程

  1. Weston注册事件

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中需要异步处理的操作可以放在其中。每轮循环都会检查其中是否有任务,如果有则执行。

  1. Weston启动流程

1、主函数: main

2、创建weston日志流:

设置文件路径

static bool weston_log_file_open(const char *filename);

创建日志文件

struct weston_log_subscriber* weston_log_subscriber_create_log(FILE *dump_to);

3、创建wl_display对象

创建全局唯一显示对象

struct wl_display *wl_display_create(void);

4、获取服务事件循环

获取事件循环,以便添加信号量

struct wl_event_loop *wl_display_get_event_loop(struct wl_display *display)

5、读取配置文件

可以动态的改变运行配置(需要重启Server端进程),比如使用哪种界面、动画的类型、渲染驱动的类型等

static intload_configuration(struct weston_config **config, int32_t noconfig,

const char *config_file)

6、创建compositor

创建合成器,主要把相关server端服务注册到事件循环当中,当客户端有请求时相应客户端请求

struct weston_compositor *weston_compositor_create(struct wl_display *display, struct weston_log_context *log_ctx, void *user_data, const struct weston_testsuite_data *test_data)

7、初始化后端渲染驱动

根据传入的参数/配置初始化后端渲染驱动等

static int load_backend(struct weston_compositor *compositor, const char *name, int *argc, char **argv, struct weston_config *config, const char *renderer_name)

8、创建socket

创建监听socket(默认/run/user/1000/wayland-0),监听客户与服务端连接

static int weston_create_listening_socket(struct wl_display *display, const char *socket_name)

9、加载shell

加载不同的shell,不同的显示的桌面和桌面上的应用。

static int wet_load_shell(struct weston_compositor *compositor, const char *_name, int *argc, char *argv[])

10、加载其他模块

主要加载输入输出设备等

static int load_modules(struct weston_compositor *ec, const char *modules, int *argc, char *argv[])

11、唤醒合成器

如果合成器处于休眠模式,则所有输出都通过 DPMS 重新启动。如果合成器处于非活动状态(idle/locked, offscreen, or sleeping) 合成器的唤醒信号会被触发。

void weston_compositor_wake(struct weston_compositor *compositor)

12、启动事件循环

监听客户端活动,处理客户端渲染,输入事件等。

void wl_display_run(struct wl_display *display)

  1. 窗口创建流程

1、客户端获取display对象

通过这个wayland协议获取全局唯一display对象

struct wl_display *wl_display_connect(const char *name);

2、获取全局注册表对象(服务端wl_global_create注册的服务)

static inline struct wl_registry *wl_display_get_registry(struct wl_display *wl_display)

3、client监听代理对象,当有服务端新的全局服务注册时,客户端可以接收到事件通知。

static inline int wl_registry_add_listener(struct wl_registry *wl_registry, const struct wl_registry_listener *listener, void *data)

4、同步客户与服务之间的调用

int wl_display_roundtrip(struct wl_display *display);

5、向服务请求创建窗口surface

创建抽象窗口

static inline struct wl_surface *wl_compositor_create_surface( struct wl_compositor *wl_compositor)

创建实体窗口

static inline struct xdg_surface *xdg_wm_base_get_xdg_surface(struct xdg_wm_base *xdg_wm_base, struct wl_surface *surface)

6、添加窗口绘图事件

static inline int xdg_surface_add_listener(struct xdg_surface *xdg_surface,

const struct xdg_surface_listener *listener, void *data)

7、从服务端获取渲染缓冲

static inline struct wl_buffer *wl_shm_pool_create_buffer(struct wl_shm_pool *wl_shm_pool, int32_t offset, int32_t width, int32_t height, int32_t stride, uint32_t format)

8、监听缓冲区状态(是否被服务端释放)

static inline int wl_buffer_add_listener(struct wl_buffer *wl_buffer,

const struct wl_buffer_listener *listener, void *data)

9、设置缓冲区为surface渲染内容

static inline void wl_surface_attach(struct wl_surface *wl_surface, struct wl_buffer *buffer, int32_t x, int32_t y)

10、向服务端发送需要重绘区域

static inline void wl_surface_damage(struct wl_surface *wl_surface, int32_t x, int32_t y, int32_t width, int32_t height)

11、使用双缓冲机制绘制渲染数据

static inline int wl_callback_add_listener(struct wl_callback *wl_callback,

const struct wl_callback_listener *listener, void *data)

12、提交窗口状态

因为表面状态使用双缓冲机制,一次性提交替换当前状态,

static inline void wl_surface_commit(struct wl_surface *wl_surface)

13、开启事件将事件添加到队列开启事件循环

int wl_display_dispatch(struct wl_display *display);

  1. 数据结构

wayland协议客户端和服务端接口数据类型(wayland-util.h)

union wl_argument {

/**< int */

int32_t i;

/**< uint */

uint32_t u;

/**< fixed double和int兼容类型*/

wl_fixed_t f;

/**< string */

const char *s;

/**< object interface基类指针,可以接收保存所有interface的指针*/

struct wl_object *o;

/**< new_id 客户端被解释时的返回值,但是在服务端,这个参数被转化成uint32_t类型传递过来一个id */

uint32_t n;

/**< array */

struct wl_array *a;

/**< fd linux进程文件描述符*/

int32_t h;

};

wayland协议接口参数传递数据(wayland-private.h)

struct wl_object {

const struct wl_interface *interface;

const void *implementation;

uint32_t id;

};

服务端注册的服务(wayland-util.h)

struct wl_interface {

/** Interface name 注册服务的名称*/

const char *name;

/** Interface version 注册服务版本 */

int version;

/** Number of methods (requests) */

int method_count;

/** Method (request) signatures */

const struct wl_message *methods;

/** Number of events */

int event_count;

/** Event signatures */

const struct wl_message *events;

};

wayland 通信时确定object或者new_id参数类型(wayland-util.h)

struct wl_message {

/** Message name */

const char *name;

/** Message signature */

const char *signature;

/** Object argument interfaces */

const struct wl_interface **types;

};

客户端资源对象(wayland-client.h)

struct wl_proxy {

struct wl_object object;

struct wl_display *display;

struct wl_event_queue *queue;

uint32_t flags;

int refcount;

void *user_data;

wl_dispatcher_func_t dispatcher;

uint32_t version;

const char * const *tag;

}

客户端socket连接用来接收发送事件(wayland-client.c)

struct wl_display {

struct wl_proxy proxy;

struct wl_connection *connection;

/* errno of the last wl_display error */

int last_error;

/* When display gets an error event from some object, it stores

* information about it here, so that client can get this

* information afterwards */

struct {

/* Code of the error. It can be compared to

* the interface's errors enumeration. */

uint32_t code;

/* interface (protocol) in which the error occurred */

const struct wl_interface *interface;

/* id of the proxy that caused the error. There's no warranty

* that the proxy is still valid. It's up to client how it will

* use it */

uint32_t id;

} protocol_error;

int fd;

struct wl_map objects;

struct wl_event_queue display_queue;

struct wl_event_queue default_queue;

pthread_mutex_t mutex;

int reader_count;

uint32_t read_serial;

pthread_cond_t reader_cond;

};

服务端所有interface全都是wl_resource结构对象,客户端资源存储对象(wayland-server.c)

struct wl_resource {

struct wl_object object;

wl_resource_destroy_func_t destroy;

struct wl_list link;

struct wl_signal destroy_signal;

struct wl_client *client;

void *data;

};

服务端存储客户端信息结构(wayland-server.c)

struct wl_client {

struct wl_connection *connection;

struct wl_event_source *source;

struct wl_display *display;

struct wl_resource *display_resource;

struct wl_list link;

struct wl_map objects;

struct wl_priv_signal destroy_signal;

struct wl_priv_signal destroy_late_signal;

pid_t pid;

uid_t uid;

gid_t gid;

int error;

struct wl_priv_signal resource_created_signal;

};

服务端与客户端socket连接,用来接收发送事件(wayland-server.c)

struct wl_display {

struct wl_event_loop *loop;

int run;

uint32_t id;

uint32_t serial;

struct wl_list registry_resource_list;

struct wl_list global_list;

struct wl_list socket_list;

struct wl_list client_list;

struct wl_list protocol_loggers;

struct wl_priv_signal destroy_signal;

struct wl_priv_signal create_client_signal;

struct wl_array additional_shm_formats;

wl_display_global_filter_func_t global_filter;

void *global_filter_data;

int terminate_efd;

struct wl_event_source *term_source;

};

enum wl_map_entry_flags {

WL_MAP_ENTRY_LEGACY = (1 << 0), /* Server side only */

WL_MAP_ENTRY_ZOMBIE = (1 << 0) /* Client side only */

};

wayland核心,用于保存进程之间通信的实际对象指针,并得到对于指针的ID,用于进程之间传递(wayland-private.h)

struct wl_map {

/* 保存客户端对象数组*/

struct wl_array client_entries;

/* 保存服务端对象数组*/

struct wl_array server_entries;

uint32_t side;

uint32_t free_list;

};

可以翻倍增长的数组,alloc>size,当相等时alloc扩大为原来两倍(wayland-util.h)

struct wl_array {

/** Array size */

size_t size;

/** Allocated space */

size_t alloc;

/** Array data */

void *data;

};

union map_entry {

uintptr_t next;

void *data;

};

链表指针结构(wayland-util.h)

struct wl_list {

/** Previous list element */

struct wl_list *prev;

/** Next list element */

struct wl_list *next;

};


http://chatgpt.dhexx.cn/article/0MX0EDF5.shtml

相关文章

Wayland/Weston 启动方式简介

前言 本文简单介绍 Weston 常用的几种 backend 启动方式。目前最新的 Weston 8.0.0 支持如下几种 backend&#xff1a; drm-backendfbdev-backendheadless-backendrdp-backendwayland-backendx11-backend 其中 headless-backend 不带任何 UI 界面&#xff0c;主要用于 westo…

weston设置

weston设置 屏幕旋转180度方法修改标题栏位置启动配置文件 屏幕旋转180度方法 编辑 /etc/xdg/weston/weston.ini文件&#xff0c;增加如下语句 [output] nameDSI-1 transform180其中name为你的显示屏名称&#xff0c;可以通过如下命令来查看显示屏名称&#xff1a; card0-DS…

Weston 窗口管理(2)

窗口管理(2) 本文基于 weston 分支 10.0.2 进行描述. 五、概述 本文为窗口管理(1)的续章,更多站在开发者角度,以 weston 的代码实现讲解窗口管理(1)中所实现的部分业务场景. 六、数据结构 在窗口管理(1)中曾经描述过 weston 具体的分层逻辑,如下: 再进一步可以把 WESTON_LAY…

01-weston 简介

参考​​​​​​weston wiki Weston - Gentoo Wiki weston (1): Linux man pages – code.tools Weston-1.12.0 非常详尽&#xff0c;多图慎入&#xff1a;Wayland与Weston简介 - 云社区 - 腾讯云 什么是weston&#xff1f; Wayland是一套display server(Wayland compos…

disunity的使用

1. 下载并安装好jdk: 下载地址&#xff1a;http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 安装教程&#xff1a;http://jingyan.baidu.com/article/6dad5075d1dc40a123e36ea3.html 2.下载disunity: https://…

T-digest

目录 算法算法原理空间消耗及错误界限 示例T-digest的建立T-digest的查询 相关链接 上一篇博客中讲述了使用 R a n d o m Random Random算法进行 q u a n t i l e quantile quantile估算&#xff0c;详情可见Random&#xff0c;本博客将讲诉另外一个 q u a n t i l e quantile …

[反编译U3D]Decompile Unity Resources 修正

反编译unity project的资源文件&#xff0c;包括ios&#xff0c;android&#xff0c;pc等&#xff0c;仅供学习使用&#xff01; 1.disunity Examples 1.1disunityGUI 1.1.2DiunityGUI 使用方法 2.unity3d decompiler 3.UnityAssetsExplorer 反编译unity project的资源文件&…

edit distance 理解

一直没有理解到inert i delete j 的意思。看看图就可以明白了。 对于那道面试题&#xff1a;http://www.careercup.com/question?id6287528252407808 k-palindrome. 最精妙的地方在于只考虑 k 长度以内的改变&#xff0c;这样就可以判断出来了。速度是O(k*n) 1. Definition o…

Tiny-DSOD: Lightweight Object Detection for Resource-Restricted Usages

Y uxi Li1 lyxok1sjtu.edu.cn Jiuwei Li2 jiuwei.liintel.com Weiyao Lin1 wylinsjtu.edu.cn Jianguo Li2 jianguo.liintel.com 1Shanghai Jiao Tong University , China 2Intel Lab China Abstract 近年来&#xff0c;随着深度学习的发展&#xff0c;目标检测技术取得了长足…

android density

为什么要引入dip —The reason for dip to exist is simple enough. Take for instance the T-Mobile G1. It has a pixel resolution of 320x480 pixels. Now image another device, with the same physical screen size, but more pixels, for instance 640x480. This devic…

手游游戏资源提取 (破解、AssetStudio、VGMToolbox、disunity、Il2CppDumper、 .NET Reflector)...

参考&#xff1a; 公主连结 游戏资源提取(解包)简明教程 Unity3D研究院之mac上从.ipa中提取unity3D游戏资源 吾爱破解&#xff1a;记一次unity3d data修改 GitHub&#xff1a;Il2CppDumper 想拿点知名IP的手游素材做点demo&#xff0c;然后搜了下如何能拿到app的素材资源 一 下…

DISN:Deep Implicit Surface Network for High-quality Single-view 3D Reconstruction

时间&#xff1a;2019年 作者&#xff1a;Weiyue Wang ,University of Southern California etc. Abstract&#xff1a; 1.DISN 通过预测基本符号距离场来从二维图像中生成高质量的细节丰富的三维网格&#xff1b; 2.DISN 在二维图像上预测每一个三维点的投影位置&#xff…

Dist

这道题只要找到我们距离的规律就行了&#xff0c;我们可以发现&#xff0c;当行数小于列数时,列数(列数-1)/k,否则&#xff0c;行数(行数-1)/k&#xff0c;没记算一次我们的距离就会增加1&#xff0c;应为行数一减你就往下了一个&#xff0c;所以这个要加1. #include<bits/…

unity3D 如何提取游戏资源 (反编译)+代码反编译【P.M.出品】

转自&#xff1a;https://blog.csdn.net/LANGZI7758521/article/details/52291564 首先感谢 雨松MOMO 的一篇帖子 教我们怎么提取 .ipa 中的游戏资源。教我们初步的破解unity3d资源的基本方法 附上原帖的链接&#xff1a;http://www.xuanyusong.com/archives/2584 下面我会从头…

Unity游戏资源逆向工具

Unity游戏资源逆向工具 https://www.cnblogs.com/kekec/p/12175547.html disunity是一款Java编写&#xff08;需安装jdk1.8&#xff0c;即Java8&#xff09;的解析Unity asset和asset bundle文件&#xff08;流式加载&#xff0c;支持热更新&#xff09;的命令行工具&#xf…

Distillation

蒸馏&#xff0c;把有杂质的东西变成纯度高的 知识从教师网络集成到学生网络&#xff0c;这个过程叫迁移&#xff0c;这么做的原因是终端的算力有限&#xff0c;需要高效率 有关嵌入式开发也有教程&#xff01;&#xff01; 问题的引入&#xff1a;标签有问题&#xff0c;马更…

Unity 提取资源 Disunity、Unity Studio

提取Unity3d资源&#xff0c;用过2个工具 Disunity https://github.com/ata4/disunityUnity Studio https://github.com/RaduMC/UnityStudio 解压XXX.apk.&#xff0c;如果能在XXXX\assets\bin\Data\Managed路径下找到UnityEngine.dll&#xff0c;则表明该游戏由Unity3d打包。…

【逆向工程】 disunity的使用

1. 下载并安装好jdk: 下载地址&#xff1a;http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 安装教程&#xff1a;http://jingyan.baidu.com/article/6dad5075d1dc40a123e36ea3.html 2.下载disunity: https:/…

oracle怎么ping监听,请教TNSPING无监听的问题

请教各位高人&#xff0c;我在自己的虚拟机上装的是solaris10&#xff0c;数据库是oracle10.1.0.3.0&#xff0c;主机名如下&#xff1a; $ hostname fanww $ 在TELNET到虚拟机上之后可以正常启动监听&#xff0c;数据库也能启动&#xff0c;如下&#xff1a; $ lsnrctl start …