global_resource: Rework ds_tizen_global_resource 86/315986/1
authorSeunghun Lee <shiin@samsung.com>
Thu, 5 Dec 2024 07:19:37 +0000 (16:19 +0900)
committerTizen Window System <tizen.windowsystem@gmail.com>
Mon, 9 Dec 2024 03:40:34 +0000 (12:40 +0900)
The ds_tizen_global_resource assigns unique ID for a ds_surface which
may be shared between different wl_clients.
The ID of ds_surface may be assigned by clients using tizen_surface
protocol and calling ds_tizen_global_resource_get_or_create_ds_surface()
by compositor.

Change-Id: I5dc9b38f2cce516f863f34fbbcee742a40c10464

include/libds-tizen/global_resource.h
src/global_resource/global_resource.c
tests/tc_global_resource.cpp

index 82612cd7d67947fef5323179fe85fc5aa189c589..0f6ca2749023e052120d5c46e0eb49669e958173 100644 (file)
@@ -10,33 +10,22 @@ extern "C" {
 #endif
 
 struct ds_tizen_global_resource;
-struct ds_tizen_global_resource_info;
 
-struct ds_tizen_global_resource *
-ds_tizen_global_resource_create(struct wl_display *display);
+struct ds_tizen_global_resource_surface;
 
-void
-ds_tizen_global_resource_add_destroy_listener(
-        struct ds_tizen_global_resource *global_resource,
-        struct wl_listener *listener);
+struct ds_tizen_global_resource *ds_tizen_global_resource_create(struct wl_display *display);
 
-void
-ds_tizen_global_resource_add_get_resource_info_listener(
-        struct ds_tizen_global_resource *global_resource,
-        struct wl_listener *listener);
+void ds_tizen_global_resource_add_destroy_listener(struct ds_tizen_global_resource *global_resource, struct wl_listener *listener);
 
-void
-ds_tizen_global_resource_info_add_destroy_listener(
-        struct ds_tizen_global_resource_info *info,
-        struct wl_listener *listener);
+void ds_tizen_global_resource_add_new_surface_listener(struct ds_tizen_global_resource *global_resource, struct wl_listener *listener);
 
-struct ds_surface *
-ds_tizen_global_resource_info_get_surface(
-        struct ds_tizen_global_resource_info *info);
+struct ds_tizen_global_resource_surface *ds_tizen_global_resource_get_or_create_surface(struct ds_tizen_global_resource *global_resource, struct ds_surface *ds_surface);
 
-uint32_t
-ds_tizen_global_resource_get_universal_id(
-        struct ds_tizen_global_resource_info *info);
+void ds_tizen_global_resource_surface_add_destroy_listener(struct ds_tizen_global_resource_surface *surface, struct wl_listener *listener);
+
+struct ds_surface *ds_tizen_global_resource_surface_get_ds_surface(struct ds_tizen_global_resource_surface *surface);
+
+uint32_t ds_tizen_global_resource_surface_get_id(struct ds_tizen_global_resource_surface *surface);
 
 #ifdef __cplusplus
 }
index 4a05c609c195607c102c0284ed081f73acb19b4e..5960d046f43ab9fda059a26a5e0ee416da841507 100644 (file)
@@ -4,70 +4,45 @@
 #include <wayland-server.h>
 #include <tizen-extension-server-protocol.h>
 #include <libds/log.h>
+#include <libds/surface.h>
 
 #include "util.h"
-#include "libds-tizen/global_resource.h"
 
 #define TIZEN_SURFACE_VERSION 1
 
-static uint32_t unique_id = 0;
-
-struct ds_tizen_global_resource
-{
+struct ds_tizen_global_resource {
     struct wl_global *global;
 
-    struct wl_list clients;
+    struct wl_list surfaces;
+    struct wl_listener display_destroy;
 
-    struct wl_listener destroy;
+    uint32_t id_pool;
 
     struct {
         struct wl_signal destroy;
-        struct wl_signal get_resource_info;
+        struct wl_signal new_surface;
     } events;
 };
 
-struct ds_tizen_global_resource_client
-{
+struct ds_tizen_global_resource_surface {
     struct ds_tizen_global_resource *global_resource;
-
-    struct wl_resource *resource;
-    struct wl_client *wl_client;
-
-    struct wl_list infos;
-
-    struct wl_list link; // ds_tizen_global_resource::clients
-};
-
-struct ds_tizen_global_resource_info
-{
-    struct ds_tizen_global_resource_client *client;
-
-    struct wl_resource *resource;
-
     struct ds_surface *surface;
 
-    uint32_t universal_id;
+    struct wl_list link;
+    struct wl_listener surface_destroy;
+
+    uint32_t id;
 
     struct {
         struct wl_signal destroy;
     } events;
-
-    struct wl_list link; // ds_tizen_global_resource_client::infos
 };
 
-static void resource_handle_display_destroy(struct wl_listener *listener,
-        void *data);
-
-static void resource_bind(struct wl_client *wl_client, void *data,
-        uint32_t version, uint32_t id);
-
-static struct ds_tizen_global_resource_info *tizen_global_resource_client_find_info(
-    struct ds_tizen_global_resource_client *client,
-    struct ds_surface *surface);
-
-static struct ds_tizen_global_resource_info *tizen_global_resource_client_get_info(
-        struct ds_tizen_global_resource_client *client,
-        struct ds_surface *surface);
+static void global_resource_handle_display_destroy(struct wl_listener *listener, void *data);
+static void global_resource_bind(struct wl_client *wl_client, void *data, uint32_t version, uint32_t id);
+static struct ds_tizen_global_resource_surface *surface_try_from_ds_surface(struct ds_surface *ds_surface);
+static struct ds_tizen_global_resource_surface *surface_get_or_create(struct ds_tizen_global_resource *global_resource, struct ds_surface *ds_surface);
+static void surface_destroy(struct ds_tizen_global_resource_surface *surface);
 
 WL_EXPORT struct ds_tizen_global_resource *
 ds_tizen_global_resource_create(struct wl_display *display)
@@ -75,271 +50,211 @@ ds_tizen_global_resource_create(struct wl_display *display)
     struct ds_tizen_global_resource *global_resource;
 
     global_resource = calloc(1, sizeof *global_resource);
-    if (!global_resource) {
-        ds_err("calloc() failed.");
+    if (!global_resource)
         return NULL;
-    }
 
-    global_resource->global = wl_global_create(display, &tizen_surface_interface,
-            TIZEN_SURFACE_VERSION, global_resource, resource_bind);
+    global_resource->global = wl_global_create(display, &tizen_surface_interface, TIZEN_SURFACE_VERSION, global_resource, global_resource_bind);
     if (!global_resource->global) {
-        ds_err("wl_global_create() failed. tizen_resource_interface");
         free(global_resource);
         return NULL;
     }
 
-    wl_list_init(&global_resource->clients);
-
-    global_resource->destroy.notify = resource_handle_display_destroy;
-    wl_display_add_destroy_listener(display, &global_resource->destroy);
+    global_resource->id_pool = 1; // start from 1. 0 is reserved for invalid id.
 
     wl_signal_init(&global_resource->events.destroy);
-    wl_signal_init(&global_resource->events.get_resource_info);
+    wl_signal_init(&global_resource->events.new_surface);
+
+    wl_list_init(&global_resource->surfaces);
+
+    global_resource->display_destroy.notify = global_resource_handle_display_destroy;
+    wl_display_add_destroy_listener(display, &global_resource->display_destroy);
 
-    ds_inf("Global created: tizen_global_resource(%p)", global_resource);
+    ds_inf("Create ds_tizen_global_resource(%p)", global_resource);
 
     return global_resource;
 }
 
 WL_EXPORT void
-ds_tizen_global_resource_add_destroy_listener(
-        struct ds_tizen_global_resource *global_resource,
-        struct wl_listener *listener)
+ds_tizen_global_resource_add_destroy_listener(struct ds_tizen_global_resource *global_resource, struct wl_listener *listener)
 {
     wl_signal_add(&global_resource->events.destroy, listener);
 }
 
 WL_EXPORT void
-ds_tizen_global_resource_add_get_resource_info_listener(
-        struct ds_tizen_global_resource *global_resource,
-        struct wl_listener *listener)
+ds_tizen_global_resource_add_new_surface_listener(struct ds_tizen_global_resource *global_resource, struct wl_listener *listener)
 {
-    wl_signal_add(&global_resource->events.get_resource_info, listener);
+    wl_signal_add(&global_resource->events.new_surface, listener);
 }
 
-WL_EXPORT void
-ds_tizen_global_resource_info_add_destroy_listener(
-        struct ds_tizen_global_resource_info *info,
-        struct wl_listener *listener)
-{
-    wl_signal_add(&info->events.destroy, listener);
-}
-
-WL_EXPORT struct ds_surface *
-ds_tizen_global_resource_info_get_surface(
-    struct ds_tizen_global_resource_info *info)
+WL_EXPORT struct ds_tizen_global_resource_surface *
+ds_tizen_global_resource_get_or_create_surface(struct ds_tizen_global_resource *global_resource, struct ds_surface *ds_surface)
 {
-    return info->surface;
+    return surface_get_or_create(global_resource, ds_surface);
 }
 
-WL_EXPORT uint32_t
-ds_tizen_global_resource_get_universal_id(
-    struct ds_tizen_global_resource_info *info)
+WL_EXPORT void
+ds_tizen_global_resource_surface_add_destroy_listener(struct ds_tizen_global_resource_surface *surface, struct wl_listener *listener)
 {
-    return info->universal_id;
+    wl_signal_add(&surface->events.destroy, listener);
 }
 
-static struct ds_tizen_global_resource_info *
-tizen_global_resource_client_find_info(
-    struct ds_tizen_global_resource_client *client,
-    struct ds_surface *surface)
+WL_EXPORT struct ds_surface *
+ds_tizen_global_resource_surface_get_ds_surface(struct ds_tizen_global_resource_surface *surface)
 {
-    struct ds_tizen_global_resource_info *info;
-
-    wl_list_for_each(info, &client->infos, link) {
-        if (surface == info->surface)
-            return info;
-    }
-
-    return NULL;
+    return surface->surface;
 }
 
-static struct ds_tizen_global_resource_info *
-tizen_global_resource_client_get_info(
-    struct ds_tizen_global_resource_client *client,
-    struct ds_surface *surface)
+WL_EXPORT uint32_t
+ds_tizen_global_resource_surface_get_id(struct ds_tizen_global_resource_surface *surface)
 {
-    struct ds_tizen_global_resource_info *info;
-
-    info = tizen_global_resource_client_find_info(client, surface);
-    if (info)
-        return info;
-
-    info = calloc(1, sizeof *info);
-    if (info == NULL) {
-        ds_err("calloc() failed. tizen_global_resource");
-        return NULL;
-    }
-
-    info->client = client;
-    info->surface = surface;
-
-    wl_signal_init(&info->events.destroy);
-
-    wl_list_insert(&client->infos, &info->link);
-
-    return info;
+    return surface->id;
 }
 
 static void
-resource_handle_display_destroy(struct wl_listener *listener, void *data)
+global_resource_handle_display_destroy(struct wl_listener *listener, void *data)
 {
-    struct ds_tizen_global_resource *global_resource;
-
-    global_resource = wl_container_of(listener, global_resource, destroy);
+    struct ds_tizen_global_resource *global_resource = wl_container_of(listener, global_resource, display_destroy);
+    struct ds_tizen_global_resource_surface *surface, *tmp;
 
-    ds_inf("Global destroy: resource(%p)", global_resource);
+    ds_inf("Destroy ds_tizen_global_resource(%p)", global_resource);
 
     wl_signal_emit(&global_resource->events.destroy, global_resource);
-    wl_list_remove(&global_resource->destroy.link);
+
+    wl_list_for_each_safe(surface, tmp, &global_resource->surfaces, link)
+        surface_destroy(surface);
+
     wl_global_destroy(global_resource->global);
+    wl_list_remove(&global_resource->display_destroy.link);
     free(global_resource);
 }
 
 static void
-resource_handle_destroy(struct wl_client *wl_client,
-    struct wl_resource *resource)
+tizen_resource_handle_destroy(struct wl_client *wl_client, struct wl_resource *resource)
 {
     wl_resource_destroy(resource);
 }
 
-static const struct tizen_resource_interface resource_impl =
-{
-   resource_handle_destroy,
+static const struct tizen_resource_interface tizen_resource_impl = {
+    tizen_resource_handle_destroy,
 };
 
 static void
-_tizen_surface_handle_destroy(struct wl_resource *resource)
+surface_destroy(struct ds_tizen_global_resource_surface *surface)
 {
-    struct ds_tizen_global_resource_info *info;
+    ds_inf("Destroy ds_tizen_global_resource_surface(%p) id(%d)", surface, surface->id);
 
-    info = wl_resource_get_user_data(resource);
+    wl_signal_emit(&surface->events.destroy, surface);
 
-    ds_inf("_tizen_surface_handle_destroy (info:%p)", info);
-
-    wl_signal_emit(&info->events.destroy, info);
-    wl_list_remove(&info->link);
-    free(info);
+    wl_list_remove(&surface->link);
+    wl_list_remove(&surface->surface_destroy.link);
+    free(surface);
 }
 
 static void
-surface_handle_get_tizen_global_resource(struct wl_client *wl_client,
-    struct wl_resource *resource,uint32_t id,
-    struct wl_resource *surface_resource)
+surface_handle_ds_surface_destroy(struct wl_listener *listener, void *data)
 {
-    struct ds_tizen_global_resource_client *client;
-    struct ds_tizen_global_resource_info *info;
-    struct ds_surface *surface;
+    struct ds_tizen_global_resource_surface *surface = wl_container_of(listener, surface, surface_destroy);
 
-    ds_inf("tizen_global_resource: surface_handle_get_tizen_global_resource");
+    surface_destroy(surface);
+}
 
-    client = wl_resource_get_user_data(resource);
-    surface = ds_surface_from_resource(surface_resource);
+static struct ds_tizen_global_resource_surface *
+surface_try_from_ds_surface(struct ds_surface *ds_surface)
+{
+    struct ds_tizen_global_resource_surface *surface;
+    struct wl_listener *listener;
 
-    info = tizen_global_resource_client_get_info(client, surface);
-    if (info == NULL) {
-        ds_err("tizen_global_resource_client_get_info() failed.");
-        wl_client_post_no_memory(wl_client);
-        return;
-    }
+    listener = ds_surface_get_destroy_listener(ds_surface, surface_handle_ds_surface_destroy);
+    if (!listener)
+        return NULL;
 
-    info->resource = wl_resource_create(wl_client,
-        &tizen_resource_interface, wl_resource_get_version(resource),
-        id);
-    if (info->resource == NULL) {
-        ds_err("tizen_global_resource : wl_resource_create() failed.");
-        wl_list_remove(&info->link);
-        free(info);
-        wl_client_post_no_memory(wl_client);
-        return;
-    }
+    return wl_container_of(listener, surface, surface_destroy);
+}
 
-    // generate the univeral_id;
-    info->universal_id = unique_id++;
+static struct ds_tizen_global_resource_surface *
+surface_create(struct ds_tizen_global_resource *global_resource, struct ds_surface *ds_surface)
+{
+    struct ds_tizen_global_resource_surface *surface;
 
-    wl_resource_set_implementation(info->resource, &resource_impl, info,
-        _tizen_surface_handle_destroy);
+    surface = calloc(1, sizeof(*surface));
+    if (!surface)
+        return NULL;
 
-    wl_signal_emit(&client->global_resource->events.get_resource_info, info);
+    wl_signal_init(&surface->events.destroy);
 
-    tizen_resource_send_resource_id(info->resource, info->universal_id);
-}
+    surface->id = global_resource->id_pool++;
 
-static void
-surface_handle_destroy(struct wl_client *wl_client,
-    struct wl_resource *resource)
-{
-    struct ds_tizen_global_resource_client *client;
+    surface->global_resource = global_resource;
+    surface->surface = ds_surface;
 
-    client = wl_resource_get_user_data(resource);
+    surface->surface_destroy.notify = surface_handle_ds_surface_destroy;
+    ds_surface_add_destroy_listener(ds_surface, &surface->surface_destroy);
 
-    if (!wl_list_empty(&client->infos)) {
-        ds_err("tizen_global_resource was destroyed before children");
-        return;
-    }
+    ds_inf("Create ds_tizen_global_resource_surface(%p) id(%p)", surface, surface->id);
 
-    wl_resource_destroy(resource);
-}
+    wl_list_insert(&global_resource->surfaces, &surface->link);
+    wl_signal_emit(&global_resource->events.new_surface, surface);
 
-static const struct tizen_surface_interface surface_impl =
-{
-   surface_handle_get_tizen_global_resource,
-   surface_handle_destroy,
-};
+    return surface;
+}
 
-static void
-_tizen_global_resource_client_handle_destroy(struct wl_resource *resource)
+static struct ds_tizen_global_resource_surface *
+surface_get_or_create(struct ds_tizen_global_resource *global_resource, struct ds_surface *ds_surface)
 {
-    struct ds_tizen_global_resource_client *client;
-    struct ds_tizen_global_resource_info *info, *tmp;
-
-    client = wl_resource_get_user_data(resource);
+    struct ds_tizen_global_resource_surface *surface = surface_try_from_ds_surface(ds_surface);
 
-    ds_inf("_tizen_global_resource_client_handle_destroy (client:%p)", client);
+    if (!surface)
+        surface = surface_create(global_resource, ds_surface);
 
-    wl_list_for_each_safe(info, tmp, &client->infos, link) {
-        wl_signal_emit(&info->events.destroy, info);
-        wl_list_remove(&info->link);
-        free(info);
-    }
-
-    wl_list_remove(&client->link);
-    free(client);
+    return surface;
 }
 
 static void
-resource_bind(struct wl_client *wl_client, void *data, uint32_t version,
-        uint32_t id)
+tizen_surface_handle_get_tizen_global_resource(struct wl_client *client, struct wl_resource *resource, uint32_t id, struct wl_resource *surface_resource)
 {
-    struct ds_tizen_global_resource *global_resource = data;
-    struct ds_tizen_global_resource_client *client;
+    struct ds_tizen_global_resource *global_resource = wl_resource_get_user_data(resource);
+    struct ds_surface *ds_surface = ds_surface_from_resource(surface_resource);
+    struct ds_tizen_global_resource_surface *surface;
+    struct wl_resource *new_resource;
+
+    surface = surface_get_or_create(global_resource, ds_surface);
+    if (!surface) {
+        wl_resource_post_no_memory(resource);
+        return;
+    }
 
-    client = calloc(1, sizeof *client);
-    if (client == NULL) {
-        ds_err("calloc() failed. tizen_global_resource");
-        wl_client_post_no_memory(wl_client);
+    new_resource = wl_resource_create(client, &tizen_resource_interface, wl_resource_get_version(resource), id);
+    if (!new_resource) {
+        wl_resource_post_no_memory(resource);
         return;
     }
+    wl_resource_set_implementation(new_resource, &tizen_resource_impl, NULL, NULL);
 
-    ds_inf("tizen_global_resource_client binds. (client:%p)", client);
+    tizen_resource_send_resource_id(new_resource, surface->id);
+}
 
-    client->global_resource = global_resource;
-    client->wl_client = wl_client;
+static void
+tizen_surface_handle_destroy(struct wl_client *wl_client, struct wl_resource *resource)
+{
+    wl_resource_destroy(resource);
+}
 
-    wl_list_init(&client->infos);
+static const struct tizen_surface_interface tizen_surface_impl = {
+    tizen_surface_handle_get_tizen_global_resource,
+    tizen_surface_handle_destroy,
+};
 
-    client->resource = wl_resource_create(wl_client, &tizen_surface_interface,
-            MIN(version, TIZEN_SURFACE_VERSION), id);
+static void
+global_resource_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id)
+{
+    struct ds_tizen_global_resource *global_resource = data;
+    struct wl_resource *resource;
 
-    if (client->resource == NULL) {
-        ds_err("tizen_global_resource : wl_resource_create() failed.");
-        free(client);
-        wl_client_post_no_memory(wl_client);
+    resource = wl_resource_create(client, &tizen_surface_interface, MIN(version, TIZEN_SURFACE_VERSION), id);
+    if (!resource) {
+        wl_client_post_no_memory(client);
         return;
     }
 
-    wl_resource_set_implementation(client->resource, &surface_impl, client,
-            _tizen_global_resource_client_handle_destroy);
-
-    wl_list_insert(&global_resource->clients, &client->link);
+    wl_resource_set_implementation(resource, &tizen_surface_impl, global_resource, NULL);
 }
index fbf5a4e772c40efae97b607de28865514ba9372c..ddf1c844b7a1ee1e3f5c92258c128c6997f41974 100644 (file)
@@ -12,30 +12,25 @@ public:
     MockGlobalResourceCompositor()
         : MockCompositor(&MockGlobalResourceCompositor::TestSetup, this)
     {
-        ds_inf("%s : this(%p)", __func__, this);
-
         // initialize the flags to check
         bSurfaceDestroyed = false;
 
         bDestroyed = false;
-        bGetResourceInfo = false;
-        bDestroyResourceInfo = false;
-        mResourceId = 0;
     }
 
     ~MockGlobalResourceCompositor()
     {
-        ds_inf("%s : this(%p)", __func__, this);
     }
 
+    struct ds_surface *GetSurface() const { return mSurface; }
+    struct ds_tizen_global_resource *GetGlobalResource() const { return mGlobalResource; }
+
     static void TestSetup(void *data)
     {
         MockGlobalResourceCompositor *mockComp =
             static_cast<MockGlobalResourceCompositor *>(data);
         Compositor *comp = mockComp->compositor;
 
-        ds_inf("%s: mockComp(%p)", __func__, mockComp);
-
         // new surface listener
         mockComp->mNewSurfaceListener.notify =
             MockGlobalResourceCompositor::NewSurfaceCallback;
@@ -52,14 +47,6 @@ public:
         mockComp->mDestroyListener.parent = mockComp;
         ds_tizen_global_resource_add_destroy_listener(mockComp->mGlobalResource,
             &mockComp->mDestroyListener);
-
-        // get_resource_info listener
-        mockComp->mGetResourceInfoListener.notify =
-            MockGlobalResourceCompositor::GetResourceInfoCallback;
-        mockComp->mGetResourceInfoListener.parent = mockComp;
-        ds_tizen_global_resource_add_get_resource_info_listener(
-            mockComp->mGlobalResource,
-            &mockComp->mGetResourceInfoListener);
     }
 
     static void NewSurfaceCallback(struct wl_listener *listener, void *data)
@@ -68,98 +55,22 @@ public:
             reinterpret_cast<NewSurfaceListener *>(listener)->parent;
         struct ds_surface *surface = static_cast<struct ds_surface *>(data);
 
-        ds_inf("%s: mockComp(%p), surface(%p)", __func__, mockComp, surface);
-
         mockComp->mSurface = surface;
-
-        // del surface listener
-        mockComp->mDelSurfaceListener.notify =
-            MockGlobalResourceCompositor::DelSurfaceCallback;
-        mockComp->mDelSurfaceListener.parent = mockComp;
-        ds_surface_add_destroy_listener(surface,
-            &mockComp->mDelSurfaceListener);
-    }
-
-    static void DelSurfaceCallback(struct wl_listener *listener, void *data)
-    {
-        MockGlobalResourceCompositor *mockComp =
-            reinterpret_cast<DelSurfaceListener *>(listener)->parent;
-        struct ds_surface *surface = static_cast<struct ds_surface *>(data);
-
-        ds_inf("%s: mockComp(%p), surface(%p)", __func__, mockComp, surface);
-
-        if (ds_surface_get_wl_resource(mockComp->mSurface) ==
-            ds_surface_get_wl_resource(surface)) {
-            ds_inf("%s: surface is deleted.", __func__);
-            mockComp->bSurfaceDestroyed = true;
-        }
     }
 
     static void DestroyCallback(struct wl_listener *listener, void *data)
     {
-        ds_inf("%s", __func__);
-
         MockGlobalResourceCompositor *mockComp =
             reinterpret_cast<DestroyListener *>(listener)->parent;
 
         mockComp->bDestroyed = true;
     }
 
-    static void GetResourceInfoCallback(struct wl_listener *listener,
-        void *data)
-    {
-        ds_inf("%s", __func__);
-
-        MockGlobalResourceCompositor *mockComp =
-            reinterpret_cast<GetResourceInfoListener *>(listener)->parent;
-        struct ds_tizen_global_resource_info *info =
-            static_cast<struct ds_tizen_global_resource_info *>(data);
-
-        ds_inf("%s: mockComp(%p), info(%p)", __func__, mockComp, info);
-
-        mockComp->bGetResourceInfo = true;
-
-        mockComp->mInfo = info;
-        mockComp->mSurface =
-            ds_tizen_global_resource_info_get_surface(mockComp->mInfo);
-
-        mockComp->mResourceId = ds_tizen_global_resource_get_universal_id(mockComp->mInfo);
-
-        // info destroy listener
-        mockComp->mGobalResourceInfoDestroyListener.notify =
-            MockGlobalResourceCompositor::GobalResourceInfoDestroyCallback;
-        mockComp->mGobalResourceInfoDestroyListener.parent = mockComp;
-        ds_tizen_global_resource_info_add_destroy_listener(mockComp->mInfo,
-            &mockComp->mGobalResourceInfoDestroyListener);
-    }
-
-    static void GobalResourceInfoDestroyCallback(struct wl_listener *listener,
-        void *data)
-    {
-        ds_inf("%s", __func__);
-
-        MockGlobalResourceCompositor *mockComp =
-            reinterpret_cast<GobalResourceInfoDestroyListener *>(listener)->parent;
-        struct ds_tizen_global_resource_info *info =
-            static_cast<struct ds_tizen_global_resource_info *>(data);
-
-        ds_inf("%s: mockComp(%p), info(%p)", __func__, mockComp, info);
-
-        if (mockComp->mInfo == info) {
-            ds_inf("%s: info is deleted.", __func__);
-            mockComp->bDestroyResourceInfo = true;
-        }
-    }
-
 public:
     bool bSurfaceDestroyed;
     bool bDestroyed;
-    bool bGetResourceInfo;
-    bool bDestroyResourceInfo;
-    uint32_t mResourceId;
 
 private:
-    struct ds_tizen_global_resource_info *mInfo;
     struct ds_surface *mSurface;
 
     struct NewSurfaceListener : ::wl_listener {
@@ -178,69 +89,43 @@ private:
         MockGlobalResourceCompositor *parent;
     };
     DestroyListener mDestroyListener;
-
-    struct GetResourceInfoListener : ::wl_listener {
-        MockGlobalResourceCompositor *parent;
-    };
-    GetResourceInfoListener mGetResourceInfoListener;
-
-    struct GobalResourceInfoDestroyListener : ::wl_listener {
-        MockGlobalResourceCompositor *parent;
-    };
-    GobalResourceInfoDestroyListener mGobalResourceInfoDestroyListener;
 };
 
 class MockGlobalResourceClient : public MockClient
 {
 public:
     MockGlobalResourceClient()
-        : mResourceId(0),
-          compositor_res(nullptr),
+        : compositor_res(nullptr),
           tizen_surface_res(nullptr)
     {}
     MockGlobalResourceClient(const struct wl_registry_listener *listener)
         : MockClient(listener, this)
     {
-        ds_inf("%s", __func__);
-
-        mResourceId = 0;
     }
     ~MockGlobalResourceClient()
     {
-        ds_inf("%s", __func__);
     }
 
     void SetWlCompositor(struct wl_compositor *global_res)
     {
-        ds_inf("%s", __func__);
-
         compositor_res = global_res;
     }
 
     struct wl_compositor *GetWlCompositor()
     {
-        ds_inf("%s", __func__);
-
         return compositor_res;
     }
 
-    void SetTizenSurfaceShm(struct tizen_surface *global_res)
+    void SetTizenSurface(struct tizen_surface *global_res)
     {
-        ds_inf("%s", __func__);
-
         tizen_surface_res = global_res;
     }
 
-    struct tizen_surface *GetTizenSurfaceShm()
+    struct tizen_surface *GetTizenSurface()
     {
-        ds_inf("%s", __func__);
-
         return tizen_surface_res;
     }
 
-public:
-    uint32_t mResourceId;
-
 private:
     struct wl_compositor *compositor_res;
     struct tizen_surface *tizen_surface_res;
@@ -250,8 +135,6 @@ static void
 client_registry_cb_global(void *data, struct wl_registry *registry,
     uint32_t name, const char *interface, uint32_t version)
 {
-    ds_inf("%s", __func__);
-
     MockGlobalResourceClient *client = static_cast<MockGlobalResourceClient *>(data);
     struct wl_compositor *compositor_res;
     struct tizen_surface *tizen_surface_res;
@@ -271,7 +154,7 @@ client_registry_cb_global(void *data, struct wl_registry *registry,
             ds_err("wl_registry_bind() failed. tizen_surface resource.");
             return;
         }
-        client->SetTizenSurfaceShm(tizen_surface_res);
+        client->SetTizenSurface(tizen_surface_res);
     }
 }
 
@@ -279,14 +162,7 @@ static void
 client_registry_cb_global_remove(void *data, struct wl_registry *registry,
     uint32_t name)
 {
-    ds_inf("%s", __func__);
-
-    MockGlobalResourceClient *client = static_cast<MockGlobalResourceClient *>(data);
-    struct wl_compositor *compositor_res = client->GetWlCompositor();
-    struct tizen_surface *tizen_surface_res = client->GetTizenSurfaceShm();
-
-    tizen_surface_destroy(tizen_surface_res);
-    wl_compositor_destroy(compositor_res);
+    // This blank line is left intentionally.
 }
 
 static const struct wl_registry_listener registry_listener = {
@@ -295,20 +171,16 @@ static const struct wl_registry_listener registry_listener = {
 };
 
 static void
-client_tizen_resource_cb_resoruce_id(void *data,
-    struct tizen_resource *resource_res, uint32_t id)
+tizen_resource_cb_resoruce_id(void *data, struct tizen_resource *resource_res, uint32_t id)
 {
-    ds_inf("%s", __func__);
+    uint32_t *ret = static_cast<uint32_t *>(data);
 
-    MockGlobalResourceClient *client =
-        static_cast<MockGlobalResourceClient *>(data);
-
-    client->mResourceId = id;
+    *ret = id;
 }
 
 static const struct
-tizen_resource_listener resource_cb_listener = {
-    .resource_id = client_tizen_resource_cb_resoruce_id,
+tizen_resource_listener tizen_resource_cb_listener = {
+    .resource_id = tizen_resource_cb_resoruce_id,
 };
 
 class GlobalResourceTest : public ::testing::Test
@@ -319,53 +191,146 @@ public:
 
     MockGlobalResourceCompositor *comp;
     MockGlobalResourceClient *client;
-    struct wl_compositor *compositor_res;
-    struct tizen_surface *tizen_surface_res;
-    struct wl_surface *surface_res;
-    struct tizen_resource *resource_res;
 };
 
 void
 GlobalResourceTest::SetUp(void)
 {
-    //ds_log_init(DS_DBG, NULL);
-
-    ds_inf("%s", __func__);
-
     comp = new MockGlobalResourceCompositor();
+
     client = new MockGlobalResourceClient(&registry_listener);
-    compositor_res = client->GetWlCompositor();
-    tizen_surface_res = client->GetTizenSurfaceShm();
-    surface_res = wl_compositor_create_surface(compositor_res);
+    client->RoundTrip();
 
-    resource_res =
-        tizen_surface_get_tizen_resource(tizen_surface_res, surface_res);
+    ASSERT_NE(client->GetWlCompositor(), nullptr);
+    ASSERT_NE(client->GetTizenSurface(), nullptr);
+}
 
-    tizen_resource_add_listener(resource_res, &resource_cb_listener, client);
+void
+GlobalResourceTest::TearDown(void)
+{
+    tizen_surface_destroy(client->GetTizenSurface());
+    wl_compositor_destroy(client->GetWlCompositor());
 
+    delete client;
+    delete comp;
+}
+
+TEST_F(GlobalResourceTest, CheckGlobalResourceIDCreatedByClient)
+{
+    struct wl_compositor *compositor = client->GetWlCompositor();
+    struct tizen_surface *tizen_surface = client->GetTizenSurface();
+    struct wl_surface *s1, *s2, *s3;
+    struct tizen_resource *tizen_resource;
+    uint32_t sid1 = 0, sid2 = 0, sid3 = 0;
+
+    s1 = wl_compositor_create_surface(compositor);
+    tizen_resource = tizen_surface_get_tizen_resource(tizen_surface, s1);
+    tizen_resource_add_listener(tizen_resource, &tizen_resource_cb_listener, &sid1);
+    client->RoundTrip();
+    tizen_resource_destroy(tizen_resource);
+
+    s2 = wl_compositor_create_surface(compositor);
+    tizen_resource = tizen_surface_get_tizen_resource(tizen_surface, s2);
+    tizen_resource_add_listener(tizen_resource, &tizen_resource_cb_listener, &sid2);
+    client->RoundTrip();
+    tizen_resource_destroy(tizen_resource);
+
+    ASSERT_EQ(sid1, 1); // first surface id should be 1.
+    ASSERT_EQ(sid2, 2); // second surface id should be 2.
+
+    wl_surface_destroy(s1); // destroy s1 and get next surface id.
+
+    s3 = wl_compositor_create_surface(compositor);
+    tizen_resource = tizen_surface_get_tizen_resource(tizen_surface, s3);
+    tizen_resource_add_listener(tizen_resource, &tizen_resource_cb_listener, &sid3);
     client->RoundTrip();
+    tizen_resource_destroy(tizen_resource);
+
+    ASSERT_EQ(sid3, 3); // third surface id should be 3.
+
+    wl_surface_destroy(s2);
+    wl_surface_destroy(s3);
 }
 
-void
-GlobalResourceTest::TearDown(void)
+TEST_F(GlobalResourceTest, CheckGlobalResourceIDCreatedByClientWithSameSurface)
 {
-    ds_inf("%s", __func__);
+    struct wl_compositor *compositor = client->GetWlCompositor();
+    struct tizen_surface *tizen_surface = client->GetTizenSurface();
+    struct wl_surface *surface;
+    struct tizen_resource *tizen_resource;
+    uint32_t sid1 = 0, sid2 = 0;
+
+    surface = wl_compositor_create_surface(compositor);
 
-    tizen_resource_destroy(resource_res);
+    tizen_resource = tizen_surface_get_tizen_resource(tizen_surface, surface);
+    tizen_resource_add_listener(tizen_resource, &tizen_resource_cb_listener, &sid1);
     client->RoundTrip();
-    EXPECT_TRUE(comp->bDestroyResourceInfo);
+    tizen_resource_destroy(tizen_resource);
 
-    wl_surface_destroy(surface_res);
+    tizen_resource = tizen_surface_get_tizen_resource(tizen_surface, surface);
+    tizen_resource_add_listener(tizen_resource, &tizen_resource_cb_listener, &sid2);
     client->RoundTrip();
-    EXPECT_TRUE(comp->bSurfaceDestroyed);
+    tizen_resource_destroy(tizen_resource);
 
-    delete client;
-    delete comp;
+    ASSERT_EQ(sid1, sid2);
+
+    wl_surface_destroy(surface);
+}
+
+TEST_F(GlobalResourceTest, CheckGlobalResourceIDCreatedByCompositor)
+{
+    struct wl_compositor *compositor = client->GetWlCompositor();
+    struct wl_surface *surface;
+    struct ds_tizen_global_resource_surface *global_resource_surface;
+
+    surface = wl_compositor_create_surface(compositor);
+    client->RoundTrip();
+
+    ASSERT_NE(comp->GetSurface(), nullptr);
+
+    global_resource_surface = ds_tizen_global_resource_get_or_create_surface(comp->GetGlobalResource(), comp->GetSurface());
+    ASSERT_NE(global_resource_surface, nullptr);
+    ASSERT_EQ(ds_tizen_global_resource_surface_get_id(global_resource_surface), 1);
+    ASSERT_EQ(ds_tizen_global_resource_get_or_create_surface(comp->GetGlobalResource(), comp->GetSurface()), global_resource_surface);
+
+    wl_surface_destroy(surface);
 }
 
-TEST_F(GlobalResourceTest, Create_P)
+TEST_F(GlobalResourceTest, CheckGlobalResourceIDCreatedByCompositorAndClient)
 {
-    EXPECT_TRUE(true);
-    EXPECT_TRUE(comp->bGetResourceInfo);
-    EXPECT_TRUE(client->mResourceId == 0);
+    struct wl_compositor *compositor = client->GetWlCompositor();
+    struct tizen_surface *tizen_surface = client->GetTizenSurface();
+    struct wl_surface *s1, *s2, *s3;
+    struct tizen_resource *tizen_resource;
+    uint32_t sid1 = 0, sid3 = 0;
+
+    s1 = wl_compositor_create_surface(compositor);
+    tizen_resource = tizen_surface_get_tizen_resource(tizen_surface, s1);
+    tizen_resource_add_listener(tizen_resource, &tizen_resource_cb_listener, &sid1);
+    client->RoundTrip();
+    tizen_resource_destroy(tizen_resource);
+
+    ASSERT_EQ(sid1, 1); // first surface id should be 1.
+
+    s2 = wl_compositor_create_surface(compositor);
+    client->RoundTrip();
+
+    ASSERT_NE(comp->GetSurface(), nullptr);
+
+    struct ds_tizen_global_resource_surface *global_resource_surface = ds_tizen_global_resource_get_or_create_surface(comp->GetGlobalResource(), comp->GetSurface());
+    ASSERT_NE(global_resource_surface, nullptr);
+    ASSERT_EQ(ds_tizen_global_resource_surface_get_id(global_resource_surface), 2); // second surface id should be 2.
+
+    wl_surface_destroy(s2);
+
+    s3 = wl_compositor_create_surface(compositor);
+    tizen_resource = tizen_surface_get_tizen_resource(tizen_surface, s3);
+    tizen_resource_add_listener(tizen_resource, &tizen_resource_cb_listener, &sid3);
+    client->RoundTrip();
+    tizen_resource_destroy(tizen_resource);
+
+    ASSERT_EQ(sid3, 3); // third surface id should be 3.
+
+    wl_surface_destroy(s1);
+    wl_surface_destroy(s3);
 }