以下例子均基于desktop-shell
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的创建信号
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
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
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
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是一个抽象库,用于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。