当前位置: 首页 > 工具软件 > Weston > 使用案例 >

display:weston结构体笔记

寇景明
2023-12-01

以下例子均基于desktop-shell

weston_head::

Represents a head, usually a display connector

https://fossies.org/dox/weston-9.0.0/structweston__head__coll__graph_org.svg

struct weston_head {
	struct weston_compositor *compositor;	/**< owning compositor */
	struct wl_list compositor_link;	/**< in weston_compositor::head_list */
	struct wl_signal destroy_signal;	/**< destroy callbacks */

	struct weston_output *output;	/**< the output driving this head */
	struct wl_list output_link;	/**< in weston_output::head_list */

	struct wl_list resource_list;	/**< wl_output protocol objects */
	struct wl_global *global;	/**< wl_output global */

	struct wl_list xdg_output_resource_list; /**< xdg_output protocol objects */

	int32_t mm_width;		/**< physical image width in mm */
	int32_t mm_height;		/**< physical image height in mm */

	/** WL_OUTPUT_TRANSFORM enum to apply to match native orientation */
	uint32_t transform;

	char *make;			/**< monitor manufacturer (PNP ID) */
	char *model;			/**< monitor model */
	char *serial_number;		/**< monitor serial */
	uint32_t subpixel;		/**< enum wl_output_subpixel */
	bool connection_internal;	/**< embedded monitor (e.g. laptop) */
	bool device_changed;		/**< monitor information has changed */

	char *name;			/**< head name, e.g. connector name */
	bool connected;			/**< is physically connected */
	bool non_desktop;		/**< non-desktop display, e.g. HMD */

	/** Current content protection status */
	enum weston_hdcp_protection current_protection;
};


weston_head的初始化时的创建过程:
weston_backend_init
    drm_backend_create                            //drm-backend初始化的时候
        drm_backend_discover_connectors
            drm_backend_add_connector
                drm_head_create
                    weston_head_init              //初始化weston_head结构体
                    ...
                    weston_head_set_internal(&head->base);  //依据判断设置internal属性 
                    weston_compositor_add_head    //关联weston_compositor和weston_head
                        weston_compositor_schedule_heads_changed    //主要时处理head change的消息机制::wet->heads_changed_listener.notify = drm_heads_changed;主要是drm_heads_changed函数的调用,注意也就是后面output的创建信号
        

 weston_compositor_schedule_heads_changed    //主要时处理head change的消息机制::wet->heads_changed_listener.notify = drm_heads_changed;主要是drm_heads_changed函数的调用,注意也就是后面output的创建信号 

weston_output::

Content producer for heads

https://fossies.org/dox/weston-9.0.0/structweston__output__coll__graph_org.svg

struct weston_output {
	uint32_t id;
	char *name;

	/** Matches the lifetime from the user perspective */
	struct wl_signal user_destroy_signal;

	void *renderer_state;

	struct wl_list link;
	struct weston_compositor *compositor;

	/** From global to output buffer coordinates. */
	struct weston_matrix matrix;
	/** From output buffer to global coordinates. */
	struct weston_matrix inverse_matrix;

	struct wl_list animation_list;
	int32_t x, y, width, height;

	/** Output area in global coordinates, simple rect */
	pixman_region32_t region;

	/** True if damage has occurred since the last repaint for this output;
	 *  if set, a repaint will eventually occur. */
	bool repaint_needed;

	/** Used only between repaint_begin and repaint_cancel. */
	bool repainted;

	/** State of the repaint loop */
	enum {
		REPAINT_NOT_SCHEDULED = 0, /**< idle; no repaint will occur */
		REPAINT_BEGIN_FROM_IDLE, /**< start_repaint_loop scheduled */
		REPAINT_SCHEDULED, /**< repaint is scheduled to occur */
		REPAINT_AWAITING_COMPLETION, /**< last repaint not yet finished */
	} repaint_status;

	/** If repaint_status is REPAINT_SCHEDULED, contains the time the
	 *  next repaint should be run */
	struct timespec next_repaint;

	/** For cancelling the idle_repaint callback on output destruction. */
	struct wl_event_source *idle_repaint_source;

	struct weston_output_zoom zoom;
	int dirty;
	struct wl_signal frame_signal;
	struct wl_signal destroy_signal;	/**< sent when disabled */
	int move_x, move_y;
	struct timespec frame_time; /* presentation timestamp */
	uint64_t msc;        /* media stream counter */
	int disable_planes;
	int destroying;
	struct wl_list feedback_list;

	uint32_t transform;
	int32_t native_scale;
	int32_t current_scale;
	int32_t original_scale;

	struct weston_mode *native_mode;
	struct weston_mode *current_mode;
	struct weston_mode *original_mode;
	struct wl_list mode_list;

	struct wl_list head_list; /**< List of driven weston_heads */

	enum weston_hdcp_protection desired_protection;
	enum weston_hdcp_protection current_protection;
	bool allow_protection;

	int (*start_repaint_loop)(struct weston_output *output);
	int (*repaint)(struct weston_output *output,
			pixman_region32_t *damage,
			void *repaint_data);
	void (*destroy)(struct weston_output *output);
	void (*assign_planes)(struct weston_output *output, void *repaint_data);
	int (*switch_mode)(struct weston_output *output, struct weston_mode *mode);

	/* backlight values are on 0-255 range, where higher is brighter */
	int32_t backlight_current;
	void (*set_backlight)(struct weston_output *output, uint32_t value);
	void (*set_dpms)(struct weston_output *output, enum dpms_enum level);

	uint16_t gamma_size;
	void (*set_gamma)(struct weston_output *output,
			  uint16_t size,
			  uint16_t *r,
			  uint16_t *g,
			  uint16_t *b);

	bool enabled; /**< is in the output_list, not pending list */
	int scale;

	bool use_renderer_shadow_buffer;

	int (*enable)(struct weston_output *output);
	int (*disable)(struct weston_output *output);

	/** Attach a head in the backend
	 *
	 * @param output The output to attach to.
	 * @param head The head to attach.
	 * @return 0 on success, -1 on failure.
	 *
	 * Do anything necessary to account for a new head being attached to
	 * the output, and check any conditions possible. On failure, both
	 * the head and the output must be left as before the call.
	 *
	 * Libweston core will add the head to the head_list after a successful
	 * call.
	 */
	int (*attach_head)(struct weston_output *output,
			   struct weston_head *head);

	/** Detach a head in the backend
	 *
	 * @param output The output to detach from.
	 * @param head The head to detach.
	 *
	 * Do any clean-up necessary to detach this head from the output.
	 * The head has already been removed from the output's head_list.
	 */
	void (*detach_head)(struct weston_output *output,
			    struct weston_head *head);
};

weston_output的创建过程:
    drm_heads_changed
        drm_process_layoutputs
            drm_process_layoutput
                wet_layoutput_create_output
                    weston_compositor_create_output
                        return compositor->backend->create_output(compositor, name);
                            drm_output_create
                                weston_output_init
                                weston_compositor_add_pending_output

weston_compositor::

Main object, container-like structure which aggregates all other objects.主要对象,类似容器的结构,聚合了所有其他对象。

https://fossies.org/dox/weston-9.0.0/structweston__compositor__coll__graph_org.svg

struct weston_compositor {
	struct wl_signal destroy_signal;

	struct wl_display *wl_display;
	struct weston_desktop_xwayland *xwayland;
	const struct weston_desktop_xwayland_interface *xwayland_interface;

	/* surface signals */
	struct wl_signal create_surface_signal;
	struct wl_signal activate_signal;
	struct wl_signal transform_signal;

	struct wl_signal kill_signal;
	struct wl_signal idle_signal;
	struct wl_signal wake_signal;

	struct wl_signal show_input_panel_signal;
	struct wl_signal hide_input_panel_signal;
	struct wl_signal update_input_panel_signal;

	struct wl_signal seat_created_signal;
	struct wl_signal output_created_signal;
	struct wl_signal output_destroyed_signal;
	struct wl_signal output_moved_signal;
	struct wl_signal output_resized_signal; /* callback argument: resized output */

	/* Signal for output changes triggered by configuration from frontend
	 * or head state changes from backend.
	 */
	struct wl_signal output_heads_changed_signal; /* arg: weston_output */

	struct wl_signal session_signal;
	bool session_active;

	struct weston_layer fade_layer;
	struct weston_layer cursor_layer;

	struct wl_list pending_output_list;
	struct wl_list output_list;
	struct wl_list head_list;	/* struct weston_head::compositor_link */
	struct wl_list seat_list;
	struct wl_list layer_list;	/* struct weston_layer::link */
	struct wl_list view_list;	/* struct weston_view::link */
	struct wl_list plane_list;
	struct wl_list key_binding_list;
	struct wl_list modifier_binding_list;
	struct wl_list button_binding_list;
	struct wl_list touch_binding_list;
	struct wl_list axis_binding_list;
	struct wl_list debug_binding_list;

	uint32_t state;
	struct wl_event_source *idle_source;
	uint32_t idle_inhibit;
	int idle_time;			/* timeout, s */
	struct wl_event_source *repaint_timer;

	const struct weston_pointer_grab_interface *default_pointer_grab;

	/* Repaint state. */
	struct weston_plane primary_plane;
	uint32_t capabilities; /* combination of enum weston_capability */

	struct weston_renderer *renderer;

	pixman_format_code_t read_format;

	struct weston_backend *backend;

	struct weston_launcher *launcher;

	struct wl_list plugin_api_list; /* struct weston_plugin_api::link */

	uint32_t output_id_pool;

	struct xkb_rule_names xkb_names;
	struct xkb_context *xkb_context;
	struct weston_xkb_info *xkb_info;

	int32_t kb_repeat_rate;
	int32_t kb_repeat_delay;

	bool vt_switching;

	clockid_t presentation_clock;
	int32_t repaint_msec;
	struct timespec last_repaint_start;

	unsigned int activate_serial;

	struct wl_global *pointer_constraints;

	int exit_code;

	void *user_data;
	void (*exit)(struct weston_compositor *c);

	/* Whether to let the compositor run without any input device. */
	bool require_input;

	/* Test suite data */
	struct weston_testsuite_data test_data;

	/* Signal for a backend to inform a frontend about possible changes
	 * in head status.
	 */
	struct wl_signal heads_changed_signal;
	struct wl_event_source *heads_changed_source;

	/* Touchscreen calibrator support: */
	enum weston_touch_mode touch_mode;
	struct wl_global *touch_calibration;
	weston_touch_calibration_save_func touch_calibration_save;
	struct weston_layer calibrator_layer;
	struct weston_touch_calibrator *touch_calibrator;

	struct weston_log_context *weston_log_ctx;
	struct weston_log_scope *debug_scene;
	struct weston_log_scope *timeline;

	struct content_protection *content_protection;
};


weston_compositor创建过程:
    main
        wet_main
            weston_compositor_create

weston_surface::

https://fossies.org/dox/weston-9.0.0/structweston__surface__coll__graph_org.svg

struct weston_surface {
	struct wl_resource *resource;
	struct wl_signal destroy_signal; /* callback argument: this surface */
	struct weston_compositor *compositor;
	struct wl_signal commit_signal;

	/** Damage in local coordinates from the client, for tex upload. */
	pixman_region32_t damage;

	pixman_region32_t opaque;        /* part of geometry, see below */
	pixman_region32_t input;
	int32_t width, height;
	int32_t ref_count;

	/* Not for long-term storage.  This exists for book-keeping while
	 * iterating over surfaces and views
	 */
	bool touched;

	void *renderer_state;

	struct wl_list views;

	/*
	 * Which output to vsync this surface to.
	 * Used to determine whether to send or queue frame events, and for
	 * other client-visible syncing/throttling tied to the output
	 * repaint cycle.
	 */
	struct weston_output *output;

	/*
	 * A more complete representation of all outputs this surface is
	 * displayed on.
	 */
	uint32_t output_mask;

	struct wl_list frame_callback_list;
	struct wl_list feedback_list;

	struct weston_buffer_reference buffer_ref;
	struct weston_buffer_viewport buffer_viewport;
	int32_t width_from_buffer; /* before applying viewport */
	int32_t height_from_buffer;
	bool keep_buffer; /* for backends to prevent early release */

	/* wp_viewport resource for this surface */
	struct wl_resource *viewport_resource;

	/* All the pending state, that wl_surface.commit will apply. */
	struct weston_surface_state pending;

	/* Matrices representing of the full transformation between
	 * buffer and surface coordinates.  These matrices are updated
	 * using the weston_surface_build_buffer_matrix function. */
	struct weston_matrix buffer_to_surface_matrix;
	struct weston_matrix surface_to_buffer_matrix;

	/*
	 * If non-NULL, this function will be called on
	 * wl_surface::commit after a new buffer has been set up for
	 * this surface. The integer params are the sx and sy
	 * parameters supplied to wl_surface::attach.
	 */
	void (*committed)(struct weston_surface *es, int32_t sx, int32_t sy);
	void *committed_private;
	int (*get_label)(struct weston_surface *surface, char *buf, size_t len);

	/* Parent's list of its sub-surfaces, weston_subsurface:parent_link.
	 * Contains also the parent itself as a dummy weston_subsurface,
	 * if the list is not empty.
	 */
	struct wl_list subsurface_list; /* weston_subsurface::parent_link */
	struct wl_list subsurface_list_pending; /* ...::parent_link_pending */

	/*
	 * For tracking protocol role assignments. Different roles may
	 * have the same configure hook, e.g. in shell.c. Configure hook
	 * may get reset, this will not.
	 * XXX: map configure functions 1:1 to roles, and never reset it,
	 * and replace role_name with configure.
	 */
	const char *role_name;

	bool is_mapped;
	bool is_opaque;

	/* An list of per seat pointer constraints. */
	struct wl_list pointer_constraints;

	/* zwp_surface_synchronization_v1 resource for this surface */
	struct wl_resource *synchronization_resource;
	int acquire_fence_fd;
	struct weston_buffer_release_reference buffer_release_ref;

	enum weston_hdcp_protection desired_protection;
	enum weston_hdcp_protection current_protection;
	enum weston_surface_protection_mode protection_mode;
};

struct weston_subsurface {
	struct wl_resource *resource;

	/* guaranteed to be valid and non-NULL */
	struct weston_surface *surface;
	struct wl_listener surface_destroy_listener;

	/* can be NULL */
	struct weston_surface *parent;
	struct wl_listener parent_destroy_listener;
	struct wl_list parent_link;
	struct wl_list parent_link_pending;

	struct {
		int32_t x;
		int32_t y;
		int set;
	} position;

	int has_cached_data;
	struct weston_surface_state cached;
	struct weston_buffer_reference cached_buffer_ref;

	/* Sub-surface has been reordered; need to apply damage. */
	bool reordered;

	int synchronized;

	/* Used for constructing the view tree */
	struct wl_list unused_views;
};

weston_surface创建过程:

客户端调用 
wl_compositor_create_surface

server端调用 
static void
compositor_create_surface(struct wl_client *client,
			  struct wl_resource *resource, uint32_t id)
{
	struct weston_compositor *ec = wl_resource_get_user_data(resource);
	struct weston_surface *surface;

	surface = weston_surface_create(ec);                  //1.create surface
	if (surface == NULL) {
		wl_resource_post_no_memory(resource);
		return;
	}

	surface->resource =                                   //2.resource   
		wl_resource_create(client, &wl_surface_interface,
				   wl_resource_get_version(resource), id);
	if (surface->resource == NULL) {
		weston_surface_destroy(surface);
		wl_resource_post_no_memory(resource);
		return;
	}
	wl_resource_set_implementation(surface->resource, &surface_interface,
				       surface, destroy_surface);         //3.接口:attach/destory/damaga/damaga_buffer/commit....等

	wl_signal_emit(&ec->create_surface_signal, surface);  //4.对应的信号
}

compositor_create_surface
    weston_surface_create

weston_view::

https://fossies.org/dox/weston-9.0.0/structweston__view__coll__graph_org.svg

static const struct weston_desktop_api shell_desktop_api = {
	.struct_size = sizeof(struct weston_desktop_api),
	.surface_added = desktop_surface_added,
	.surface_removed = desktop_surface_removed,
	.committed = desktop_surface_committed,
	.move = desktop_surface_move,
	.resize = desktop_surface_resize,
	.set_parent = desktop_surface_set_parent,
	.fullscreen_requested = desktop_surface_fullscreen_requested,
	.maximized_requested = desktop_surface_maximized_requested,
	.minimized_requested = desktop_surface_minimized_requested,
	.ping_timeout = desktop_surface_ping_timeout,
	.pong = desktop_surface_pong,
	.set_xwayland_position = desktop_surface_set_xwayland_position,
};


static const struct weston_desktop_surface_implementation weston_desktop_xdg_surface_internal_implementation = {
	/* These are used for toplevel only */
	.set_maximized = weston_desktop_xdg_toplevel_set_maximized,
	.set_fullscreen = weston_desktop_xdg_toplevel_set_fullscreen,
	.set_resizing = weston_desktop_xdg_toplevel_set_resizing,
	.set_activated = weston_desktop_xdg_toplevel_set_activated,
	.set_size = weston_desktop_xdg_toplevel_set_size,

	.get_maximized = weston_desktop_xdg_toplevel_get_maximized,
	.get_fullscreen = weston_desktop_xdg_toplevel_get_fullscreen,
	.get_resizing = weston_desktop_xdg_toplevel_get_resizing,
	.get_activated = weston_desktop_xdg_toplevel_get_activated,

	/* These are used for popup only */
	.update_position = weston_desktop_xdg_popup_update_position,

	/* Common API */
	.committed = weston_desktop_xdg_surface_committed,
	.ping = weston_desktop_xdg_surface_ping,
	.close = weston_desktop_xdg_surface_close,

	.destroy = weston_desktop_xdg_surface_destroy,
};



struct weston_view {
	struct weston_surface *surface;
	struct wl_list surface_link;
	struct wl_signal destroy_signal;

	struct wl_list link;             /* weston_compositor::view_list */
	struct weston_layer_entry layer_link; /* part of geometry */
	struct weston_plane *plane;

	/* For weston_layer inheritance from another view */
	struct weston_view *parent_view;

	unsigned int click_to_activate_serial;

	pixman_region32_t clip;          /* See weston_view_damage_below() */
	float alpha;                     /* part of geometry, see below */

	void *renderer_state;

	/* Surface geometry state, mutable.
	 * If you change anything, call weston_surface_geometry_dirty().
	 * That includes the transformations referenced from the list.
	 */
	struct {
		float x, y; /* surface translation on display */

		/* struct weston_transform */
		struct wl_list transformation_list;

		/* managed by weston_surface_set_transform_parent() */
		struct weston_view *parent;
		struct wl_listener parent_destroy_listener;
		struct wl_list child_list; /* geometry.parent_link */
		struct wl_list parent_link;

		/* managed by weston_view_set_mask() */
		bool scissor_enabled;
		pixman_region32_t scissor; /* always a simple rect */
	} geometry;

	/* State derived from geometry state, read-only.
	 * This is updated by weston_view_update_transform().
	 */
	struct {
		int dirty;

		/* Approximations in global coordinates:
		 * - boundingbox is guaranteed to include the whole view in
		 *   the smallest possible single rectangle.
		 * - opaque is guaranteed to be fully opaque, though not
		 *   necessarily include all opaque areas.
		 */
		pixman_region32_t boundingbox;
		pixman_region32_t opaque;

		/* matrix and inverse are used only if enabled = 1.
		 * If enabled = 0, use x, y, width, height directly.
		 */
		int enabled;
		struct weston_matrix matrix;
		struct weston_matrix inverse;

		struct weston_transform position; /* matrix from x, y */
	} transform;

	/*
	 * The primary output for this view.
	 * Used for picking the output for driving internal animations on the
	 * view, inheriting the primary output for related views in shells, etc.
	 */
	struct weston_output *output;
	struct wl_listener output_destroy_listener;

	/*
	 * A more complete representation of all outputs this surface is
	 * displayed on.
	 */
	uint32_t output_mask;

	/* Per-surface Presentation feedback flags, controlled by backend. */
	uint32_t psf_flags;

	bool is_mapped;
};


weston_view创建过程:

这个committed逻辑其实是和commit里面的第一个函数weston_surface_commit_state强绑定的
这个committed是在attach以后的signal里面,会调用如下,第一次commit的时候,还没有buffer,会直接跳过前半部分直接执行wl_signal_emit(&surface->commit_signal, surface);
weston_desktop_xdg_surface_committed
    weston_desktop_xdg_toplevel_committed
        weston_desktop_xdg_toplevel_ensure_added
            weston_desktop_api_surface_added
                desktop->api.surface_added(surface, desktop->user_data);
                desktop_surface_added
                    weston_desktop_surface_create_view    
                        weston_desktop_surface_create_desktop_view
                            weston_view_create //create view + assign to surface

 要将变换添加到视图,请创建一个结构weston_transform,并将其添加到列表view-> geometry.transformation_list中。

weston_buffer::buffer本身不存在创建的过程,因为他是从client那边拿到的。

struct weston_buffer {
	struct wl_resource *resource;
	struct wl_signal destroy_signal;
	struct wl_listener destroy_listener;

	union {
		struct wl_shm_buffer *shm_buffer;
		void *legacy_buffer;
	};
	int32_t width, height;
	uint32_t busy_count;
	int y_inverted;
};

 

客户端先创建surface,但是w和h都是0,然后在第一次commit的时候,会完成第一次attch/damage/frame/commit,随后会把view创建出来,这个view的创建是基于不同的如ivi-shell/desktop-shell实现。

weston_surface_is_mapped    //Check if a surface has a view assigned to it,The indicator is set manually when mapping a surface and creating a view for it.
检查一个surface是否有一个分配给它的view,当map一个surface并为它创建一个view时,该指示器是手动设置的。

libweston-desktop介绍

libweston-desktop是一个抽象库,用于compositor支持desktop相关的shell[desktop-shell]。
该API是根据xdg_shell特性设计的,因为它最终将成为现代应用程序使用的推荐shell。
在未来,添加新的shell协议支持会更容易,因为仅限于libweston-desktop。
库的版本控制与libweston相同。如果其中一个破坏了ABI兼容性,另一个也会。
compositor只会看到toplevel surface(“窗口”),其他的都是内部实现细节。
因此,弹出窗口和相关的抓取完全在libweston-desktop中处理。

Xwayland的特殊表面(覆盖重定向)是专用的层,因为compositor不应该知道他们。
所有的shell错误检查也被考虑在内,以及一些规范规则(例如最大化和全屏表面的尺寸约束)。
所有的compositor必须做的是在接口结构中定义一些回调,并管理toplevel surface。

 

 

 

 

 

 类似资料: