e_comp_wl_rsm: Fix sending invalid the resource id of provider 01/319501/2
authorChangyeon Lee <cyeon.lee@samsung.com>
Tue, 11 Feb 2025 08:38:42 +0000 (17:38 +0900)
committerChangyeon Lee <cyeon.lee@samsung.com>
Wed, 12 Feb 2025 03:51:09 +0000 (12:51 +0900)
surface does not have valid the resource id if client does not get
the resource id by tizen_surface protocol after below commit.

8ebc2cb845 - e_compositor: Use ds_tizen_surface_exporter

this patch makes remote surface creates and manages the resource id of
provider because the resource id is sent by the remote surface protocol.

Change-Id: Ic532738cd96ab1ff3ac6627e0fe3ec3eafef6b19

src/bin/server/e_comp_wl_rsm.c

index 5697f3572667caf1540de2664a0fa7bf37ee68b0..bd00d521c3b7c2758ddb6298af67da90b9c36227 100644 (file)
@@ -69,6 +69,9 @@ struct _E_Comp_Wl_Remote_Manager
    Eina_List *client_hooks;
    Eina_List *process_hooks;
 
+   Eina_Hash *provider_res_id_hash;
+   uint32_t res_id_pool;
+
    E_Comp_Object_Hook *effect_end;
    int                 wait_effect_end;
 
@@ -98,6 +101,7 @@ struct _E_Comp_Wl_Remote_Provider
    int vis_ref;
    uint32_t input_event_filter;
    int buffer_mode;
+   uint32_t res_id;
 };
 
 /* normal UI client */
@@ -502,6 +506,18 @@ _remote_provider_find(E_Client *ec)
    return provider;
 }
 
+static E_Comp_Wl_Remote_Provider *
+_remote_provider_find_by_res_id(uint32_t res_id)
+{
+   E_Comp_Wl_Remote_Provider *provider;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(_rsm, NULL);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(_rsm->provider_res_id_hash, NULL);
+
+   provider = eina_hash_find(_rsm->provider_res_id_hash, &res_id);
+   return provider;
+}
+
 static E_Comp_Wl_Buffer *
 _remote_surface_comp_wl_buffer_get(E_Client *ec)
 {
@@ -1362,7 +1378,10 @@ _remote_provider_cb_resource_destroy(struct wl_resource *resource)
    if (!provider) return;
 
    if (_rsm)
-     eina_hash_del(_rsm->provider_hash, &provider->common.ec, provider);
+     {
+        eina_hash_del(_rsm->provider_hash, &provider->common.ec, provider);
+        eina_hash_del(_rsm->provider_res_id_hash, &provider->res_id, provider);
+     }
 
    EINA_LIST_FREE(provider->common.surfaces, remote_surface)
      {
@@ -2308,6 +2327,28 @@ static const struct tizen_remote_surface_interface _remote_surface_interface =
    _remote_surface_cb_curr_buff_get,
 };
 
+static uint32_t
+_remote_provider_res_id_get(E_Comp_Wl_Remote_Provider *provider)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(_rsm, 0);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(_rsm->provider_res_id_hash, 0);
+
+   if (provider->res_id > 0)
+     return provider->res_id;
+
+   if (_rsm->res_id_pool == UINT32_MAX)
+     {
+        ERR("Overflow res_id_pool. Reset");
+        _rsm->res_id_pool = 0;
+     }
+
+   provider->res_id = ++_rsm->res_id_pool;
+
+   eina_hash_add(_rsm->provider_res_id_hash, &provider->res_id, provider);
+
+   return provider->res_id;
+}
+
 static void
 _remote_manager_cb_provider_create(struct wl_client *client, struct wl_resource *res_remote_manager, uint32_t id, struct wl_resource *surface_resource)
 {
@@ -2352,18 +2393,18 @@ _remote_manager_cb_provider_create(struct wl_client *client, struct wl_resource
 
    eina_hash_add(_rsm->provider_hash, &ec, provider);
 
-   RSMINF("Created resource(%p)",
-          ec, "PROVIDER", provider, resource);
-
    _remote_provider_client_set(ec, EINA_TRUE);
    _remote_provider_offscreen_set(provider, EINA_TRUE);
 
    /* send resource id */
-   res_id = e_pixmap_res_id_get(ec->pixmap);
+   res_id = _remote_provider_res_id_get(provider);
    tizen_remote_surface_provider_send_resource_id(resource, res_id);
 
    /* set buffer mode */
    provider->buffer_mode = e_config->rsm_buffer_release_mode;
+
+   RSMINF("Created resource(%p) res_id:%d",
+          ec, "PROVIDER", provider, resource, provider->res_id);
 }
 
 static void
@@ -2377,7 +2418,7 @@ _remote_manager_cb_surface_create(struct wl_client *client,
    E_Comp_Wl_Remote_Surface *remote_surface;
    E_Comp_Wl_Remote_Provider *provider = NULL;
    E_Comp_Wl_Remote_Source *source = NULL;
-   E_Client *ec;
+   E_Client *res_id_ec = NULL;
    int version;
    pid_t pid = 0;
    uid_t uid = 0;
@@ -2413,22 +2454,22 @@ _remote_manager_cb_surface_create(struct wl_client *client,
                                   remote_surface,
                                   _remote_surface_cb_resource_destroy);
 
-   ec = e_pixmap_find_client_by_res_id(res_id);
-   if (!ec)
-     {
-        ERR("Could not find client by res_id(%u)", res_id);
-        goto fail;
-     }
-
    if (!wl_tbm)
      {
         ERR("wayland_tbm resource is NULL");
         goto fail;
      }
 
-   provider = _remote_provider_find(ec);
+   provider = _remote_provider_find_by_res_id(res_id);
    if (!provider)
      {
+        res_id_ec = e_pixmap_find_client_by_res_id(res_id);
+        if (!res_id_ec)
+          {
+             ERR("Could not find client by res_id(%u)", res_id);
+             goto fail;
+          }
+
         /* check the privilege for the client which wants to be the remote surface of normal UI client */
         wl_client_get_credentials(client, &pid, &uid, NULL);
         res = e_security_privilege_check(pid, uid, E_PRIVILEGE_INTERNAL_DEFAULT_PLATFORM);
@@ -2442,14 +2483,14 @@ _remote_manager_cb_surface_create(struct wl_client *client,
 
         if (version >= TIZEN_REMOTE_SURFACE_CHANGED_BUFFER_SINCE_VERSION)
           {
-             if (e_comp_wl_subsurface_check(ec))
+             if (e_comp_wl_subsurface_check(res_id_ec))
                {
                   ERR("Subsurface could not be source client");
                   goto fail;
                }
 
              /* if passed */
-             source = _remote_source_get(ec);
+             source = _remote_source_get(res_id_ec);
              if (!source) goto fail;
           }
         else
@@ -2474,7 +2515,7 @@ _remote_manager_cb_surface_create(struct wl_client *client,
 
    RSMINF("Created resource(%p) ec(%p) provider(%p) source(%p) version(%d)",
           remote_surface->ec, "SURFACE", remote_surface,
-          resource, ec, provider, source, remote_surface->version);
+          resource, provider ? provider->common.ec : res_id_ec, provider, source, remote_surface->version);
 
    remote_surface->valid = EINA_TRUE;
 
@@ -2529,7 +2570,7 @@ _remote_manager_cb_surface_create_with_wl_surface(struct wl_client *client,
    E_Comp_Wl_Remote_Surface *remote_surface = NULL;
    E_Comp_Wl_Remote_Provider *provider = NULL;
    E_Comp_Wl_Remote_Source *source = NULL;
-   E_Client *ec, *provider_ec;
+   E_Client *ec, *res_id_ec = NULL;
    Eina_List *surfaces;
    int version;
    pid_t pid = 0;
@@ -2577,22 +2618,22 @@ _remote_manager_cb_surface_create_with_wl_surface(struct wl_client *client,
                                   remote_surface,
                                   _remote_surface_cb_resource_destroy);
 
-   provider_ec = e_pixmap_find_client_by_res_id(res_id);
-   if (!provider_ec)
-     {
-        ERR("Could not find client by res_id(%u)", res_id);
-        goto fail;
-     }
-
    if (!wl_tbm)
      {
         ERR("wayland_tbm resource is NULL");
         goto fail;
      }
 
-   provider = _remote_provider_find(provider_ec);
+   provider = _remote_provider_find_by_res_id(res_id);
    if (!provider)
      {
+        res_id_ec = e_pixmap_find_client_by_res_id(res_id);
+        if (!res_id_ec)
+          {
+             ERR("Could not find client by res_id(%u)", res_id);
+             goto fail;
+          }
+
         /* check the privilege for the client which wants to be the remote surface of normal UI client */
         wl_client_get_credentials(client, &pid, &uid, NULL);
         res = e_security_privilege_check(pid, uid, E_PRIVILEGE_INTERNAL_DEFAULT_PLATFORM);
@@ -2606,14 +2647,14 @@ _remote_manager_cb_surface_create_with_wl_surface(struct wl_client *client,
 
         if (version >= TIZEN_REMOTE_SURFACE_CHANGED_BUFFER_SINCE_VERSION)
           {
-             if (e_comp_wl_subsurface_check(provider_ec))
+             if (e_comp_wl_subsurface_check(res_id_ec))
                {
                   ERR("Subsurface could not be source client");
                   goto fail;
                }
 
              /* if passed */
-             source = _remote_source_get(provider_ec);
+             source = _remote_source_get(res_id_ec);
              if (!source) goto fail;
           }
         else
@@ -2650,7 +2691,7 @@ _remote_manager_cb_surface_create_with_wl_surface(struct wl_client *client,
 
    RSMINF("Created resource(%p) provider_ec(%p) provider(%p) source(%p) version(%d)",
           remote_surface->ec, "SURFACE", remote_surface,
-          resource, provider_ec, provider, source, remote_surface->version);
+          resource, provider ? provider->common.ec : res_id_ec, provider, source, remote_surface->version);
 
    remote_surface->valid = EINA_TRUE;
 
@@ -2736,6 +2777,7 @@ _e_comp_wl_remote_cb_client_del(void *data, E_Client *ec)
    if ((provider = eina_hash_find(_rsm->provider_hash, &ec)))
      {
         eina_hash_del(_rsm->provider_hash, &ec, provider);
+        eina_hash_del(_rsm->provider_res_id_hash, &provider->res_id, provider);
         EINA_LIST_FREE(provider->common.surfaces, remote_surface)
           {
              if (remote_surface->provider == provider)
@@ -3634,6 +3676,7 @@ e_comp_wl_remote_surface_init(void)
    rs_manager->source_hash = eina_hash_pointer_new(NULL);
    rs_manager->bind_surface_hash = eina_hash_pointer_new(NULL);
    rs_manager->dummy_fd = _e_comp_wl_remote_surface_dummy_fd_get();
+   rs_manager->provider_res_id_hash = eina_hash_int32_new(NULL);
 
    if (rs_manager->dummy_fd == -1)
      {
@@ -3706,6 +3749,7 @@ e_comp_wl_remote_surface_shutdown(void)
    E_FREE_FUNC(rsm->consumer_hash, eina_hash_free);
    E_FREE_FUNC(rsm->source_hash, eina_hash_free);
    E_FREE_FUNC(rsm->bind_surface_hash, eina_hash_free);
+   E_FREE_FUNC(rsm->provider_res_id_hash, eina_hash_free);
 
    E_FREE_LIST(rsm->client_hooks, e_client_hook_del);
    E_FREE_LIST(rsm->event_hdlrs, ecore_event_handler_del);