diff --git a/src/lib/ecore_wl2/Ecore_Wl2.h b/src/lib/ecore_wl2/Ecore_Wl2.h index dc050e021a..bbf4f23279 100644 --- a/src/lib/ecore_wl2/Ecore_Wl2.h +++ b/src/lib/ecore_wl2/Ecore_Wl2.h @@ -996,6 +996,18 @@ EAPI void ecore_wl2_subsurface_opaque_region_set(Ecore_Wl2_Subsurface *subsurfac */ EAPI int ecore_wl2_output_dpi_get(Ecore_Wl2_Output *output); +/** + * Return the version of the display's compositor object + * + * @param disp the display to get the compositor object version from + * + * @return the version of the display's compositor object + * + * @ingroup Ecore_Wl2_Display_Group + * @since 1.17 + */ +EAPI int ecore_wl2_display_compositor_version_get(Ecore_Wl2_Display *disp); + EAPI Ecore_Wl2_Seat *ecore_wl2_seat_create(Ecore_Wl2_Display *display, const char *name, const struct wl_seat_interface *implementation, int version, Ecore_Wl2_Bind_Cb bind_cb, Ecore_Wl2_Unbind_Cb unbind_cb); EAPI void ecore_wl2_seat_destroy(Ecore_Wl2_Seat *seat); EAPI void ecore_wl2_seat_capabilities_send(Ecore_Wl2_Seat *seat, enum wl_seat_capability caps); diff --git a/src/lib/ecore_wl2/ecore_wl2_display.c b/src/lib/ecore_wl2/ecore_wl2_display.c index 48eec25679..e72506a125 100644 --- a/src/lib/ecore_wl2/ecore_wl2_display.c +++ b/src/lib/ecore_wl2/ecore_wl2_display.c @@ -4,6 +4,9 @@ #include "ecore_wl2_private.h" +/* for MIN() */ +#include + static Eina_Bool _fatal_error = EINA_FALSE; static Eina_Hash *_server_displays = NULL; static Eina_Hash *_client_displays = NULL; @@ -74,8 +77,14 @@ _cb_global_add(void *data, struct wl_registry *registry, unsigned int id, const if (!strcmp(interface, "wl_compositor")) { + int request_version = 3; +#ifdef WL_SURFACE_DAMAGE_BUFFER_SINCE_VERSION + request_version = 4; +#endif ewd->wl.compositor = - wl_registry_bind(registry, id, &wl_compositor_interface, 3); + wl_registry_bind(registry, id, &wl_compositor_interface, + MIN(version, request_version)); + ewd->wl.compositor_version = MIN(version, request_version); } else if (!strcmp(interface, "wl_subcompositor")) { @@ -746,3 +755,11 @@ ecore_wl2_display_registry_get(Ecore_Wl2_Display *display) return display->wl.registry; } + +EAPI int +ecore_wl2_display_compositor_version_get(Ecore_Wl2_Display *display) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(display, 0); + + return display->wl.compositor_version; +} diff --git a/src/lib/ecore_wl2/ecore_wl2_input.c b/src/lib/ecore_wl2/ecore_wl2_input.c index a5cbf0ce4a..df7847c1b5 100644 --- a/src/lib/ecore_wl2/ecore_wl2_input.c +++ b/src/lib/ecore_wl2/ecore_wl2_input.c @@ -1191,8 +1191,14 @@ _ecore_wl2_input_cursor_update(void *data) image->hotspot_x, image->hotspot_y); wl_surface_attach(input->cursor.surface, buffer, 0, 0); - wl_surface_damage(input->cursor.surface, - 0, 0, image->width, image->height); +#ifdef WL_SURFACE_DAMAGE_BUFFER_SINCE_VERSION + if (input->display->wl.compositor_version >= WL_SURFACE_DAMAGE_BUFFER_SINCE_VERSION) + wl_surface_damage_buffer(input->cursor.surface, + 0, 0, image->width, image->height); + else +#endif + wl_surface_damage(input->cursor.surface, + 0, 0, image->width, image->height); wl_surface_commit(input->cursor.surface); if ((input->cursor.wl_cursor->image_count > 1) && diff --git a/src/lib/ecore_wl2/ecore_wl2_private.h b/src/lib/ecore_wl2/ecore_wl2_private.h index e33eaa2aac..a31e65098f 100644 --- a/src/lib/ecore_wl2/ecore_wl2_private.h +++ b/src/lib/ecore_wl2/ecore_wl2_private.h @@ -62,6 +62,7 @@ struct _Ecore_Wl2_Display struct wl_shm *shm; struct wl_shell *wl_shell; struct xdg_shell *xdg_shell; + int compositor_version; } wl; uint32_t serial; diff --git a/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_shm.c b/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_shm.c index be092fb660..23b9b01e1c 100644 --- a/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_shm.c +++ b/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_shm.c @@ -130,6 +130,7 @@ _ee_cb_sync_done(void *data, int type EINA_UNUSED, void *event EINA_UNUSED) { einfo->info.wl_disp = ecore_wl2_display_get(wdata->display); einfo->info.wl_shm = ecore_wl2_display_shm_get(wdata->display); + einfo->info.compositor_version = ecore_wl2_display_compositor_version_get(wdata->display); einfo->info.destination_alpha = EINA_TRUE; einfo->info.rotation = ee->rotation; einfo->info.wl_surface = ecore_wl2_window_surface_get(wdata->win); @@ -329,6 +330,7 @@ ecore_evas_wayland_shm_new_internal(const char *disp_name, unsigned int parent, einfo->info.destination_alpha = EINA_TRUE; einfo->info.rotation = ee->rotation; einfo->info.wl_surface = ecore_wl2_window_surface_get(wdata->win); + einfo->info.compositor_version = ecore_wl2_display_compositor_version_get(ewd); if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) { diff --git a/src/modules/evas/engines/wayland_shm/Evas_Engine_Wayland_Shm.h b/src/modules/evas/engines/wayland_shm/Evas_Engine_Wayland_Shm.h index a48f09c212..c7c6873568 100644 --- a/src/modules/evas/engines/wayland_shm/Evas_Engine_Wayland_Shm.h +++ b/src/modules/evas/engines/wayland_shm/Evas_Engine_Wayland_Shm.h @@ -21,6 +21,7 @@ struct _Evas_Engine_Info_Wayland_Shm int edges; struct wl_display *wl_disp; + int compositor_version; } info; /* non-blocking or blocking mode */ diff --git a/src/modules/evas/engines/wayland_shm/evas_engine.c b/src/modules/evas/engines/wayland_shm/evas_engine.c index de4ea9e372..82500908b3 100644 --- a/src/modules/evas/engines/wayland_shm/evas_engine.c +++ b/src/modules/evas/engines/wayland_shm/evas_engine.c @@ -23,7 +23,7 @@ struct _Render_Engine /* LOCAL FUNCTIONS */ Render_Engine * -_render_engine_swapbuf_setup(int w, int h, unsigned int rotation, unsigned int depth, Eina_Bool alpha, struct wl_shm *shm, struct wl_surface *surface, struct wl_display *disp) +_render_engine_swapbuf_setup(int w, int h, unsigned int rotation, unsigned int depth, Eina_Bool alpha, struct wl_shm *shm, struct wl_surface *surface, struct wl_display *disp, int compositor_version) { Render_Engine *re; Outbuf *ob; @@ -35,7 +35,8 @@ _render_engine_swapbuf_setup(int w, int h, unsigned int rotation, unsigned int d /* try to allocate space for new render engine */ if (!(re = calloc(1, sizeof(Render_Engine)))) return NULL; - ob = _evas_outbuf_setup(w, h, rotation, depth, alpha, shm, surface, disp); + ob = _evas_outbuf_setup(w, h, rotation, depth, alpha, shm, surface, disp, + compositor_version); if (!ob) goto err; if (!evas_render_engine_software_generic_init(&re->generic, ob, @@ -137,7 +138,8 @@ eng_setup(Evas *eo_evas, void *info) einfo->info.destination_alpha, einfo->info.wl_shm, einfo->info.wl_surface, - einfo->info.wl_disp); + einfo->info.wl_disp, + einfo->info.compositor_version); if (re) re->generic.ob->info = einfo; @@ -152,7 +154,8 @@ eng_setup(Evas *eo_evas, void *info) einfo->info.rotation, einfo->info.depth, einfo->info.destination_alpha, einfo->info.wl_shm, einfo->info.wl_surface, - einfo->info.wl_disp); + einfo->info.wl_disp, + einfo->info.compositor_version); if (ob) { ob->info = einfo; diff --git a/src/modules/evas/engines/wayland_shm/evas_engine.h b/src/modules/evas/engines/wayland_shm/evas_engine.h index 610673935a..6a2fe75d3a 100644 --- a/src/modules/evas/engines/wayland_shm/evas_engine.h +++ b/src/modules/evas/engines/wayland_shm/evas_engine.h @@ -81,6 +81,7 @@ struct _Shm_Surface int w, h; int dx, dy; int num_buff; + int compositor_version; Shm_Leaf leaf[MAX_BUFFERS]; Shm_Leaf *current; @@ -117,14 +118,14 @@ struct _Outbuf } priv; }; -Shm_Surface *_evas_shm_surface_create(struct wl_display *disp, struct wl_shm *shm, struct wl_surface *surface, int w, int h, int num_buff, Eina_Bool alpha); +Shm_Surface *_evas_shm_surface_create(struct wl_display *disp, struct wl_shm *shm, struct wl_surface *surface, int w, int h, int num_buff, Eina_Bool alpha, int compositor_version); void _evas_shm_surface_destroy(Shm_Surface *surface); void _evas_shm_surface_reconfigure(Shm_Surface *surface, int dx, int dy, int w, int h, int num_buff, uint32_t flags); void *_evas_shm_surface_data_get(Shm_Surface *surface, int *w, int *h); Eina_Bool _evas_shm_surface_assign(Shm_Surface *surface); void _evas_shm_surface_post(Shm_Surface *surface, Eina_Rectangle *rects, unsigned int count); -Outbuf *_evas_outbuf_setup(int w, int h, int rot, Outbuf_Depth depth, Eina_Bool alpha, struct wl_shm *shm, struct wl_surface *surface, struct wl_display *disp); +Outbuf *_evas_outbuf_setup(int w, int h, int rot, Outbuf_Depth depth, Eina_Bool alpha, struct wl_shm *shm, struct wl_surface *surface, struct wl_display *disp, int compositor_version); void _evas_outbuf_free(Outbuf *ob); void _evas_outbuf_flush(Outbuf *ob, Tilebuf_Rect *rects, Evas_Render_Mode render_mode); void _evas_outbuf_idle_flush(Outbuf *ob); diff --git a/src/modules/evas/engines/wayland_shm/evas_outbuf.c b/src/modules/evas/engines/wayland_shm/evas_outbuf.c index 99b42e4766..36a0cffa1e 100644 --- a/src/modules/evas/engines/wayland_shm/evas_outbuf.c +++ b/src/modules/evas/engines/wayland_shm/evas_outbuf.c @@ -10,7 +10,7 @@ #define BLUE_MASK 0x0000ff Outbuf * -_evas_outbuf_setup(int w, int h, int rot, Outbuf_Depth depth, Eina_Bool alpha, struct wl_shm *shm, struct wl_surface *surface, struct wl_display *disp) +_evas_outbuf_setup(int w, int h, int rot, Outbuf_Depth depth, Eina_Bool alpha, struct wl_shm *shm, struct wl_surface *surface, struct wl_display *disp, int compositor_version) { Outbuf *ob = NULL; char *num; @@ -44,7 +44,7 @@ _evas_outbuf_setup(int w, int h, int rot, Outbuf_Depth depth, Eina_Bool alpha, s /* try to create the outbuf surface */ if (!(ob->surface = - _evas_shm_surface_create(disp, shm, surface, w, h, ob->num_buff, alpha))) + _evas_shm_surface_create(disp, shm, surface, w, h, ob->num_buff, alpha, compositor_version))) goto surf_err; eina_array_step_set(&ob->priv.onebuf_regions, sizeof(Eina_Array), 8); diff --git a/src/modules/evas/engines/wayland_shm/evas_shm.c b/src/modules/evas/engines/wayland_shm/evas_shm.c index 593a8ae475..04e7f7bedc 100644 --- a/src/modules/evas/engines/wayland_shm/evas_shm.c +++ b/src/modules/evas/engines/wayland_shm/evas_shm.c @@ -309,7 +309,7 @@ _shm_leaf_release(Shm_Leaf *leaf) } Shm_Surface * -_evas_shm_surface_create(struct wl_display *disp, struct wl_shm *shm, struct wl_surface *surface, int w, int h, int num_buff, Eina_Bool alpha) +_evas_shm_surface_create(struct wl_display *disp, struct wl_shm *shm, struct wl_surface *surface, int w, int h, int num_buff, Eina_Bool alpha, int compositor_version) { Shm_Surface *surf; int i = 0; @@ -328,6 +328,7 @@ _evas_shm_surface_create(struct wl_display *disp, struct wl_shm *shm, struct wl_ surf->num_buff = num_buff; surf->alpha = alpha; surf->flags = 0; + surf->compositor_version = compositor_version; /* create surface buffers */ for (; i < surf->num_buff; i++) @@ -505,12 +506,24 @@ _evas_shm_surface_post(Shm_Surface *surface, Eina_Rectangle *rects, unsigned int unsigned int k = 0; for (; k < count; k++) - wl_surface_damage(surface->surface, - rects[k].x, rects[k].y, - rects[k].w, rects[k].h); +#ifdef WL_SURFACE_DAMAGE_BUFFER_SINCE_VERSION + if (surface->compositor_version >= WL_SURFACE_DAMAGE_BUFFER_SINCE_VERSION) + wl_surface_damage_buffer(surface->surface, + rects[k].x, rects[k].y, + rects[k].w, rects[k].h); + else +#endif + wl_surface_damage(surface->surface, + rects[k].x, rects[k].y, + rects[k].w, rects[k].h); } else - wl_surface_damage(surface->surface, 0, 0, leaf->w, leaf->h); +#ifdef WL_SURFACE_DAMAGE_BUFFER_SINCE_VERSION + if (surface->compositor_version >= WL_SURFACE_DAMAGE_BUFFER_SINCE_VERSION) + wl_surface_damage_buffer(surface->surface, 0, 0, leaf->w, leaf->h); + else +#endif + wl_surface_damage(surface->surface, 0, 0, leaf->w, leaf->h); /* frame_cb = wl_surface_frame(surface->surface); */ /* wl_callback_add_listener(frame_cb, &_shm_frame_listener, surface); */