Wayland原始碼分析-damage相關流程
wayland程式碼分析系列,剛剛開始,慢慢來~
本文關注damage相關的流程
Damage?
什麼是damage?做圖形開發的同學應該還比較熟悉,準確定義就不去深究了。
可以理解為,當圖形應用需要重繪指定區域時,傳送的一種事件,X11協議中有針對Damage的專門的擴充套件協議,Wayland中,其實就是client向server傳送的一種事件(request),server端(compositor)收到事件後進行相應的處理,通常也就是重繪指定的區域。
初始情況下,wayland客戶端會將整個surface作為初始區域,傳送damage,目的時繪製surface。
流程
還是以weston程式碼中的最簡單的client示例程式碼simple-shm為例看看相關流程。
client在建立display、window之後,呼叫:wl_surface_damage傳送request,流程開始:
wl_surface_damage實現如下(由scanner工具生成,原始碼中沒有):
static inline void wl_surface_damage(struct wl_surface *wl_surface, int32_t x, int32_t y, int32_t width, int32_t height) { wl_proxy_marshal((struct wl_proxy *) wl_surface, WL_SURFACE_DAMAGE, x, y, width, height); }
本質上就是封裝相關資料,然後呼叫與服務端通訊的介面,將相應的request:WL_SURFACE_DAMAGE傳送給server,然後由server呼叫本地相應的介面完成處理。
服務端接收到相應request之後,呼叫本地介面(有關wayland客戶端和服務端通訊相關的機制,後續再抽空寫單獨的文章來說明),本地介面定義為:
static const struct wl_surface_interface surface_interface = { surface_destroy, surface_attach, surface_damage, surface_frame, surface_set_opaque_region, surface_set_input_region, surface_commit, surface_set_buffer_transform, surface_set_buffer_scale };
可見damage對應介面為:surface_damage,實現為:
static void
surface_damage(struct wl_client *client,
struct wl_resource *resource,
int32_t x, int32_t y, int32_t width, int32_t height)
{
struct weston_surface *surface = wl_resource_get_user_data(resource);
pixman_region32_union_rect(&surface->pending.damage,
&surface->pending.damage,
x, y, width, height);
}
其實,就啥也沒幹,獲取surface後,將新的damage區域與原有的damage區域進行組合,得到新的damage區域。
另,wayland 0.99版本之後,都使用了double buffer state,對於damage區域也是如此,之前更新damage區域時,更新的都是pending的damage,在commit之後,才將pending.damage賦值給current damage,然後clear掉pending.damage供下次使用。然後,在服務端repaint surface時,會清理掉current.damage供下次使用。
從整個流程上看,其實就是更新了一下damage對應的區域而已,沒有其它操作,真正的繪圖操作是在客戶端commit後,由服務端compositor根據之前更新的damage區域來進行的,damage區域以外的區域不會被重繪。