surface_queue: Chanage front-end APIs 95/62395/13
authorSangjin Lee <lsj119@samsung.com>
Wed, 16 Mar 2016 02:02:08 +0000 (11:02 +0900)
committerSooChan Lim <sc1.lim@samsung.com>
Tue, 22 Mar 2016 11:54:06 +0000 (20:54 +0900)
Change-Id: Ia0f2543e971af595aa16d8f8ee3ff90147fe2787

12 files changed:
Makefile.am
src/wayland-tbm-client.c [changed mode: 0644->0755]
src/wayland-tbm-server.c
src/wayland-tbm-server.h [changed mode: 0644->0755]
test/Makefile.am
test/tbm-client-queue-test.c
test/tbm-leak-test.c [new file with mode: 0644]
test/tbm-server-queue-test.c
test/wayland-tbm-test-client-protocol.h
test/wayland-tbm-test-protocol.c
test/wayland-tbm-test-server-protocol.h
test/wayland-tbm-test.xml

index a62ad59..241a644 100644 (file)
@@ -1,6 +1,6 @@
 MAINTAINERCLEANFILES = Makefile.in
 
-SUBDIRS = src test tool
+SUBDIRS = src tool
 
 pkgconfigdir = $(libdir)/pkgconfig
 pkgconfig_DATA = \
old mode 100644 (file)
new mode 100755 (executable)
index 9e9a688..565b6b5
@@ -77,8 +77,14 @@ struct wayland_tbm_surface_queue {
        tbm_surface_queue_h tbm_queue;
 };
 
-static const int key_wl_tbm_buffer;
-#define KEY_WL_TBM_BUFFER ((unsigned long)&key_wl_tbm_buffer)
+static const int key_wl_buffer_imported;
+#define KEY_WL_BUFFER_IMPORTED ((unsigned long)&key_wl_buffer_imported)
+
+#ifdef DEBUG_TRACE
+#define WL_TBM_TRACE(fmt, ...)   fprintf (stderr, "[WL_TBM_C(%d):%s] " fmt, getpid(), __func__, ##__VA_ARGS__)
+#else
+#define WL_TBM_TRACE(fmt, ...)
+#endif
 
 static void
 handle_tbm_monitor_client_tbm_bo(void *data,
@@ -228,13 +234,18 @@ wayland_tbm_client_create_buffer(struct wayland_tbm_client *tbm_client,
        struct wl_buffer *wl_buffer = NULL;
        int i;
 
-       struct wayland_tbm_buffer *tbm_buffer = NULL;
        uint32_t flags = 0;
 
-       tbm_surface_internal_get_user_data(surface, KEY_WL_TBM_BUFFER,
-                                          (void **)&tbm_buffer);
-       if (tbm_buffer) {
-               return tbm_buffer->wl_buffer;
+       if (tbm_surface_internal_get_user_data(surface,
+                                          KEY_WL_BUFFER_IMPORTED,
+                                          (void **)&wl_buffer)) {
+               if (wl_buffer) {
+                       tbm_surface_internal_set_user_data(surface, KEY_WL_BUFFER_IMPORTED, NULL);
+                       return wl_buffer;
+               } else {
+                       WL_TBM_LOG("already created wl_buffer from surface: %p\n", surface);
+                       return NULL;
+               }
        }
 
        ret = tbm_surface_get_info(surface, &info);
@@ -317,13 +328,6 @@ wayland_tbm_client_create_buffer(struct wayland_tbm_client *tbm_client,
                        close(bufs[i]);
        }
 
-       tbm_buffer = calloc(1, sizeof(struct wayland_tbm_buffer));
-       tbm_buffer->wl_buffer = wl_buffer;
-       tbm_buffer->flags = flags;
-       wl_list_init(&tbm_buffer->link);
-       tbm_surface_internal_add_user_data(surface, KEY_WL_TBM_BUFFER, free);
-       tbm_surface_internal_set_user_data(surface, KEY_WL_TBM_BUFFER, tbm_buffer);
-
        return wl_buffer;
 
 err:
@@ -442,6 +446,7 @@ __tbm_surface_from_param(tbm_bufmgr bufmgr,
        }
        tbm_surface = tbm_surface_internal_create_with_bos(&info, bos, numName);
        WL_TBM_RETURN_VAL_IF_FAIL(tbm_surface != NULL, NULL);
+       WL_TBM_TRACE("[IMPORT] :%p\n", tbm_surface);
 
        if (is_fd) {
                close(buf0);
@@ -449,6 +454,10 @@ __tbm_surface_from_param(tbm_bufmgr bufmgr,
                close(buf2);
        }
 
+       for (i = 0; i < numName; i++) {
+               tbm_bo_unref(bos[i]);
+       }
+
        return tbm_surface;
 }
 
@@ -467,7 +476,9 @@ __tbm_surface_alloc_cb(tbm_surface_queue_h surface_queue, void *data)
                buffer = wl_container_of(link, buffer, link);
                surface = buffer->tbm_surface;
                wl_list_remove(link);
+               free(buffer);
 
+               WL_TBM_TRACE("[ALLOC_FB] : %p\n", surface);
        } else {
                int width = tbm_surface_queue_get_width(queue_info->tbm_queue);
                int height = tbm_surface_queue_get_height(queue_info->tbm_queue);
@@ -477,6 +488,7 @@ __tbm_surface_alloc_cb(tbm_surface_queue_h surface_queue, void *data)
                                                        height,
                                                        format,
                                                        queue_info->flag);
+               WL_TBM_TRACE("[ALLOC] : %p\n", surface);
        }
 
        return surface;
@@ -486,18 +498,7 @@ static void
 __tbm_surface_free_cb(tbm_surface_queue_h surface_queue, void *data,
                      tbm_surface_h surface)
 {
-       struct wayland_tbm_buffer *buffer = NULL;
-
-       tbm_surface_internal_get_user_data(surface, KEY_WL_TBM_BUFFER,
-                                          (void **)&buffer);
-
-       if (buffer) {
-               if (buffer->wl_buffer) {
-                       wl_buffer_destroy(buffer->wl_buffer);
-               }
-               tbm_surface_internal_set_user_data(surface, KEY_WL_TBM_BUFFER, NULL);
-               tbm_surface_internal_delete_user_data(surface, KEY_WL_TBM_BUFFER);
-       }
+       WL_TBM_TRACE("[FREE] : %p\n", surface);
 
        tbm_surface_destroy(surface);
 }
@@ -513,6 +514,7 @@ __tbm_surface_queue_flush(struct wayland_tbm_surface_queue *queue_info)
                wl_buffer_destroy(buffer->wl_buffer);
                buffer->wl_buffer = NULL;
                tbm_surface_destroy(buffer->tbm_surface);
+               free(buffer);
        }
 
        tbm_surface_queue_flush(queue_info->tbm_queue);
@@ -608,10 +610,10 @@ handle_tbm_queue_buffer_attached_with_id(void *data,
        wl_list_insert(&queue_info->attach_bufs, &buffer->link);
 
        tbm_surface_internal_add_user_data(buffer->tbm_surface,
-                                          KEY_WL_TBM_BUFFER, free);
+                                          KEY_WL_BUFFER_IMPORTED, NULL);
        tbm_surface_internal_set_user_data(buffer->tbm_surface,
-                                          KEY_WL_TBM_BUFFER,
-                                          buffer);
+                                          KEY_WL_BUFFER_IMPORTED,
+                                          buffer->wl_buffer);
        return;
 
 fail:
@@ -671,10 +673,10 @@ handle_tbm_queue_buffer_attached_with_fd(void *data,
        wl_list_insert(&queue_info->attach_bufs, &buffer->link);
 
        tbm_surface_internal_add_user_data(buffer->tbm_surface,
-                                          KEY_WL_TBM_BUFFER, free);
+                                          KEY_WL_BUFFER_IMPORTED, NULL);
        tbm_surface_internal_set_user_data(buffer->tbm_surface,
-                                          KEY_WL_TBM_BUFFER,
-                                          buffer);
+                                          KEY_WL_BUFFER_IMPORTED,
+                                          buffer->wl_buffer);
        return;
 fail:
        if (buffer->wl_buffer)
@@ -695,6 +697,7 @@ handle_tbm_queue_active(void *data,
        queue_info->is_active = 1;
        queue_info->usage = usage;
 
+       WL_TBM_TRACE("[ACTIVE] : \n");
        __tbm_surface_queue_flush(queue_info);
 }
 
@@ -731,15 +734,26 @@ const struct wl_tbm_queue_listener wl_tbm_queue_listener = {
 };
 
 static void
-handle_tbm_surface_queue_notify(tbm_surface_queue_h surface_queue,
+handle_tbm_surface_queue_destroy_notify(tbm_surface_queue_h surface_queue,
                void *data)
 {
        struct wayland_tbm_surface_queue *queue_info = data;
-       WL_TBM_C_LOG("\n");
+       struct wayland_tbm_buffer *buffer, *tmp;
+       WL_TBM_TRACE("\n");
 
        if (queue_info->wl_tbm_queue)
                wl_tbm_queue_destroy(queue_info->wl_tbm_queue);
 
+       wl_list_for_each_safe(buffer, tmp, &queue_info->attach_bufs, link) {
+               if (buffer->wl_buffer) {
+                       wl_buffer_destroy(buffer->wl_buffer);
+                       buffer->wl_buffer = NULL;
+               }
+
+               tbm_surface_destroy(buffer->tbm_surface);
+               free(buffer);
+       }
+
        free(queue_info);
 }
 
@@ -784,7 +798,7 @@ wayland_tbm_client_create_surface_queue(struct wayland_tbm_client *tbm_client,
                                               queue_info);
 
                tbm_surface_queue_add_destroy_cb(queue_info->tbm_queue,
-                       handle_tbm_surface_queue_notify, queue_info);
+                       handle_tbm_surface_queue_destroy_notify, queue_info);
        } else {
                WL_TBM_C_LOG("INFO cur(%dx%d fmt:0x%x num:%d) new(%dx%d fmt:0x%x num:%d)\n",
                        queue_info->width, queue_info->height,
index 6a5edb0..33a8ec1 100755 (executable)
-/*
-Copyright (C) 2015 Samsung Electronics co., Ltd. All Rights Reserved.
-
-Contact:
-      SooChan Lim <sc1.lim@samsung.com>,
-      Sangjin Lee <lsj119@samsung.com>,
-      Boram Park <boram1288.park@samsung.com>,
-      Changyeon Lee <cyeon.lee@samsung.com>
-
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the "Software"),
-to deal in the Software without restriction, including without limitation
-the rights to use, copy, modify, merge, publish, distribute, sublicense,
-and/or sell copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice (including the next
-paragraph) shall be included in all copies or substantial portions of the
-Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
-THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
-*/
-
-#define WL_HIDE_DEPRECATED
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stddef.h>
-#include <unistd.h>
-#include <fcntl.h>
-
-#include <tbm_surface.h>
-#include <tbm_surface_internal.h>
-#include <wayland-server.h>
-
-#include "wayland-tbm-server.h"
-#include "wayland-tbm-server-protocol.h"
-
-#include "wayland-tbm-int.h"
-
-#define WL_TBM_SERVER_DEBUG
-
-#define MIN(x,y) (((x)<(y))?(x):(y))
-
-struct wayland_tbm_server {
-       struct wl_display *display;
-       struct wl_global *wl_tbm_global;
-
-       struct wl_list client_resource_list;
-
-       tbm_bufmgr bufmgr;
-
-       /*Scanout*/
-       struct wl_list queue_list;
-       struct wl_list server_queue_list;
-};
-
-struct wl_tbm_buffer {
-       struct wl_resource *resource;
-       tbm_surface_h tbm_surface;
-       tbm_surface_queue_h tbm_queue;
-       int flags;
-};
-
-struct wayland_tbm_client_resource {
-       struct wl_resource *resource;
-       pid_t pid;
-       char *app_name;
-       struct wl_list link;
-};
-
-struct wayland_tbm_server_queue {
-       struct wl_list link;
-       struct wayland_tbm_server *tbm_srv;
-       tbm_surface_queue_h tbm_queue;
-       uint32_t flags;
-
-       struct wl_tbm_queue *client_queue;
-};
-
-struct wl_tbm_queue {
-       struct wl_list link;
-
-       struct wl_resource *resource;
-       struct wl_resource *wl_tbm;
-       struct wl_resource *surface;
-       struct wayland_tbm_server_queue *server_queue;
-
-       int num_attached;
-};
-
-static const int key_wl_tbm_queue;
-#define KEY_WL_TBM_QUEUE ((unsigned long)&key_wl_tbm_queue)
-
-const static int key_wl_tbm_buffer;
-#define KEY_WL_TBM_BUFFER      ((unsigned long)&key_wl_tbm_buffer)
-
-static void _create_tbm_queue(struct wl_client *client,
-                             struct wl_resource *resource,
-                             uint32_t surface_queue,
-                             struct wl_resource *surface);
-
-static void _destory_tbm_queue(struct wl_resource *resource);
-
-static void _buffer_destroy(struct wl_client *client,
-                           struct wl_resource *resource);
-
-static const struct wl_buffer_interface _wayland_tbm_buffer_impementation = {
-       _buffer_destroy
-};
-
-static void
-_destroy_buffer(struct wl_resource *resource)
-{
-       struct wl_tbm_buffer *buffer = wl_resource_get_user_data(resource);
-
-       tbm_surface_internal_delete_user_data(buffer->tbm_surface, KEY_WL_TBM_BUFFER);
-
-       if (buffer->tbm_queue) {
-               tbm_surface_queue_release(buffer->tbm_queue, buffer->tbm_surface);
-               WL_TBM_S_LOG("Release to queue(%p), tbm_surface:%p\n", buffer->tbm_queue,
-                            buffer->tbm_surface);
-       }
-
-       tbm_surface_destroy(buffer->tbm_surface);
-
-       free(buffer);
-}
-
-static void
-_buffer_destroy(struct wl_client *client, struct wl_resource *resource)
-{
-       wl_resource_destroy(resource);
-}
-
-static struct wl_tbm_buffer *
-_create_wl_buffer(struct wl_client *client, struct wl_resource *resource,
-                 uint id, tbm_surface_h tbm_buffer, int flags)
-{
-       struct wayland_tbm_server *tbm_srv = wl_resource_get_user_data(resource);
-       struct wayland_tbm_client_resource *c_res = NULL, *tmp_res = NULL;
-       struct wl_tbm_buffer *buffer;
-
-       buffer = calloc(1, sizeof * buffer);
-       if (buffer == NULL) {
-               wl_resource_post_no_memory(resource);
-               return NULL;
-       }
-
-       buffer->flags = flags;
-       buffer->tbm_surface = (void *)tbm_buffer;
-       if (buffer->tbm_surface == NULL) {
-               wl_resource_post_error(resource,
-                                      WL_TBM_ERROR_INVALID_NAME,
-                                      "tbm_surface is NULL");
-               free(buffer);
-               return NULL;
-       }
-
-       /* set the debug_pid to the surface for debugging */
-       if (!wl_list_empty(&tbm_srv->client_resource_list)) {
-               wl_list_for_each_safe(c_res, tmp_res, &tbm_srv->client_resource_list, link) {
-                       if (c_res->resource == resource) {
-                               tbm_surface_internal_set_debug_pid(tbm_buffer, c_res->pid);
-                               break;
-                       }
-               }
-       }
-
-       buffer->resource = wl_resource_create(client, &wl_buffer_interface, 1, id);
-       if (!buffer->resource) {
-               wl_resource_post_no_memory(resource);
-               free(buffer);
-               return NULL;
-       }
-
-       wl_resource_set_implementation(buffer->resource,
-                                      (void (* *)(void)) &_wayland_tbm_buffer_impementation,
-                                      buffer, _destroy_buffer);
-       tbm_surface_internal_add_user_data(tbm_buffer, KEY_WL_TBM_BUFFER, NULL);
-       tbm_surface_internal_set_user_data(tbm_buffer, KEY_WL_TBM_BUFFER,
-                                          (void *)buffer);
-
-       return buffer;
-}
-
-static void
-_create_buffer(struct wl_client *client, struct wl_resource *resource,
-              uint32_t id,
-              tbm_surface_info_s *info,
-              int32_t is_fd, int32_t *names, int32_t num_name, uint32_t flags)
-{
-       struct wayland_tbm_server *tbm_srv = wl_resource_get_user_data(resource);
-       struct wl_tbm_buffer *buffer;
-       tbm_surface_h surface;
-       tbm_bo bos[TBM_SURF_PLANE_MAX];
-       int i;
-
-       for (i = 0; i < num_name; i++) {
-               if (is_fd) {
-                       bos[i] = tbm_bo_import_fd(tbm_srv->bufmgr, names[i]);
-               } else {
-                       bos[i] = tbm_bo_import(tbm_srv->bufmgr, names[i]);
-               }
-       }
-
-       surface = tbm_surface_internal_create_with_bos(info, bos, num_name);
-       for (i = 0; i < num_name; i++)
-               tbm_bo_unref(bos[i]);
-
-       buffer = _create_wl_buffer(client, resource, id, surface, flags);
-       if (!buffer) {
-               WL_TBM_S_LOG("failed to create wl_buffer id:%d\n", id);
-               tbm_surface_destroy(surface);
-               return;
-       }
-
-       return;
-}
-
-static void
-_wayland_tbm_server_impl_request_tbm_monitor(struct wl_client *client,
-               struct wl_resource *resource,
-               int32_t command,
-               int32_t trace_command,
-               int32_t target,
-               int32_t pid)
-{
-       struct wayland_tbm_server *tbm_srv = wl_resource_get_user_data(resource);
-       struct wayland_tbm_client_resource *c_res = NULL, *tmp_res = NULL;
-       int i = 0;
-
-#ifdef WL_TBM_SERVER_DEBUG
-       WL_TBM_LOG("[%s]: command=%d, trace_command=%d, target=%d, pid=%d.\n", __func__,
-                  command, trace_command, target, pid);
-#endif
-
-       if (command == WL_TBM_MONITOR_COMMAND_LIST) {
-               WL_TBM_DEBUG("==================  app list       =======================\n");
-               WL_TBM_DEBUG("no pid  app_name\n");
-
-               if (!wl_list_empty(&tbm_srv->client_resource_list)) {
-                       wl_list_for_each_safe(c_res, tmp_res, &tbm_srv->client_resource_list, link) {
-                               /* skip the requestor (wayland-tbm-monitor */
-                               if (c_res->resource == resource)
-                                       continue;
-
-                               if (!c_res->app_name) {
-                                       c_res->app_name = (char *) calloc(1, 255 * sizeof(char));
-
-                                       _wayland_tbm_util_get_appname_from_pid(c_res->pid, c_res->app_name);
-                                       _wayland_tbm_util_get_appname_brief(c_res->app_name);
-                               }
-
-                               WL_TBM_DEBUG("%-3d%-5d%s\n", ++i, c_res->pid, c_res->app_name);
-                       }
-               }
-
-               WL_TBM_DEBUG("======================================================\n");
-
-               return;
-       }
-
-       if (target == WL_TBM_MONITOR_TARGET_CLIENT) {
-               if (pid < 1) {
-                       wl_resource_post_error(resource, WL_TBM_ERROR_INVALID_FORMAT, "invalid format");
-                       return;
-               }
-               /* send the events to all client containing wl_tbm resource except for the wayland-tbm-monitor(requestor). */
-               if (!wl_list_empty(&tbm_srv->client_resource_list)) {
-                       wl_list_for_each_safe(c_res, tmp_res, &tbm_srv->client_resource_list, link) {
-                               /* skip the requestor (wayland-tbm-monitor */
-                               if (c_res->resource == resource)
-                                       continue;
-
-                               wl_tbm_send_monitor_client_tbm_bo(c_res->resource, command, trace_command,
-                                                                 target, pid);
-                       }
-               }
-       } else if (target == WL_TBM_MONITOR_TARGET_SERVER) {
-               if (command == WL_TBM_MONITOR_COMMAND_SHOW) {
-                       tbm_bufmgr_debug_show(tbm_srv->bufmgr);
-               } else if (command == WL_TBM_MONITOR_COMMAND_TRACE) {
-                       WL_TBM_LOG("[%s]: TRACE NOT IMPLEMENTED.\n", __func__);
-               } else
-                       wl_resource_post_error(resource, WL_TBM_ERROR_INVALID_FORMAT,
-                                              "invalid format");
-       } else if (target == WL_TBM_MONITOR_TARGET_ALL) {
-               if (command == WL_TBM_MONITOR_COMMAND_SHOW) {
-                       /* send the events to all client containing wl_tbm resource except for the wayland-tbm-monitor(requestor). */
-                       if (!wl_list_empty(&tbm_srv->client_resource_list)) {
-                               wl_list_for_each_safe(c_res, tmp_res, &tbm_srv->client_resource_list, link) {
-                                       /* skip the requestor (wayland-tbm-monitor */
-                                       if (c_res->resource == resource)
-                                               continue;
-
-                                       wl_tbm_send_monitor_client_tbm_bo(c_res->resource, command, trace_command,
-                                                                         target, pid);
-                               }
-                       }
-                       tbm_bufmgr_debug_show(tbm_srv->bufmgr);
-               } else if (command == WL_TBM_MONITOR_COMMAND_TRACE) {
-                       wl_tbm_send_monitor_client_tbm_bo(resource, command, trace_command, target,
-                                                         pid);
-                       WL_TBM_LOG("[%s]: TRACE NOT IMPLEMENTED.\n", __func__);
-               } else
-                       wl_resource_post_error(resource, WL_TBM_ERROR_INVALID_FORMAT,
-                                              "invalid format");
-       } else
-               wl_resource_post_error(resource, WL_TBM_ERROR_INVALID_FORMAT,
-                                      "invalid format");
-
-}
-
-
-static void
-_wayland_tbm_server_impl_create_buffer(struct wl_client *client,
-                                      struct wl_resource *resource,
-                                      uint32_t id,
-                                      int32_t width, int32_t height, uint32_t format, int32_t num_plane,
-                                      int32_t buf_idx0, int32_t offset0, int32_t stride0,
-                                      int32_t buf_idx1, int32_t offset1, int32_t stride1,
-                                      int32_t buf_idx2, int32_t offset2, int32_t stride2,
-                                      uint32_t flags,
-                                      int32_t num_buf, uint32_t buf0, uint32_t buf1, uint32_t buf2)
-{
-       int32_t names[TBM_SURF_PLANE_MAX] = { -1, -1, -1, -1};
-       tbm_surface_info_s info;
-       int bpp;
-       int numPlane, numName = 0;
-
-#ifdef WL_TBM_SERVER_DEBUG
-       WL_TBM_LOG("[%s]: trying.\n", __func__);
-#endif
-
-       bpp = tbm_surface_internal_get_bpp(format);
-       numPlane = tbm_surface_internal_get_num_planes(format);
-       if (numPlane != num_plane) {
-               wl_resource_post_error(resource, WL_TBM_ERROR_INVALID_FORMAT,
-                                      "invalid format");
-               return;
-       }
-
-       memset(&info, 0x0, sizeof(tbm_surface_info_s));
-
-       info.width = width;
-       info.height = height;
-       info.format = format;
-       info.bpp = bpp;
-       info.num_planes = numPlane;
-
-       /*Fill plane info*/
-       if (numPlane > 0) {
-               info.planes[0].offset = offset0;
-               info.planes[0].stride = stride0;
-               numPlane--;
-       }
-
-       if (numPlane > 0) {
-               info.planes[1].offset = offset1;
-               info.planes[1].stride = stride1;
-               numPlane--;
-       }
-
-       if (numPlane > 0) {
-               info.planes[2].offset = offset2;
-               info.planes[2].stride = stride2;
-               numPlane--;
-       }
-
-       /*Fill buffer*/
-       numName = num_buf;
-       names[0] = buf0;
-       names[1] = buf1;
-       names[2] = buf2;
-
-       _create_buffer(client, resource, id, &info, 0, names, numName, flags);
-}
-
-static void
-_wayland_tbm_server_impl_create_buffer_with_fd(struct wl_client *client,
-               struct wl_resource *resource,
-               uint32_t id,
-               int32_t width, int32_t height, uint32_t format, int num_plane,
-               int32_t buf_idx0, int32_t offset0, int32_t stride0,
-               int32_t buf_idx1, int32_t offset1, int32_t stride1,
-               int32_t buf_idx2, int32_t offset2, int32_t stride2,
-               uint32_t flags,
-               int32_t num_buf, int32_t buf0, int32_t buf1, int32_t buf2)
-{
-       int32_t names[TBM_SURF_PLANE_MAX] = {0, 0, 0, 0};
-       tbm_surface_info_s info;
-       int bpp;
-       int numPlane, numName = 0;
-
-#ifdef WL_TBM_SERVER_DEBUG
-       WL_TBM_LOG("[%s]: trying.\n", __func__);
-#endif
-
-       bpp = tbm_surface_internal_get_bpp(format);
-       numPlane = tbm_surface_internal_get_num_planes(format);
-       if (numPlane != num_plane) {
-               wl_resource_post_error(resource, WL_TBM_ERROR_INVALID_FORMAT,
-                                      "invalid format");
-               return;
-       }
-
-       memset(&info, 0x0, sizeof(tbm_surface_info_s));
-
-       info.width = width;
-       info.height = height;
-       info.format = format;
-       info.bpp = bpp;
-       info.num_planes = numPlane;
-
-       /*Fill plane info*/
-       if (numPlane > 0) {
-               info.planes[0].offset = offset0;
-               info.planes[0].stride = stride0;
-               numPlane--;
-       }
-
-       if (numPlane > 0) {
-               info.planes[1].offset = offset1;
-               info.planes[1].stride = stride1;
-               numPlane--;
-       }
-
-       if (numPlane > 0) {
-               info.planes[2].offset = offset2;
-               info.planes[2].stride = stride2;
-               numPlane--;
-       }
-
-       /*Fill buffer*/
-       numName = num_buf;
-       names[0] = buf0;
-       names[1] = buf1;
-       names[2] = buf2;
-
-       _create_buffer(client, resource, id, &info, 1, names, numName, flags);
-
-       close(buf0);
-       close(buf1);
-       close(buf2);
-}
-
-static void
-_wayland_tbm_server_impl_create_surface_queue(struct wl_client *client,
-               struct wl_resource *resource,
-               uint32_t surface_queue,
-               struct wl_resource *surface)
-{
-       _create_tbm_queue(client, resource, surface_queue, surface);
-}
-
-static const struct wl_tbm_interface _wayland_tbm_server_implementation = {
-       _wayland_tbm_server_impl_create_buffer,
-       _wayland_tbm_server_impl_create_buffer_with_fd,
-       _wayland_tbm_server_impl_request_tbm_monitor,
-       _wayland_tbm_server_impl_create_surface_queue,
-};
-
-static void
-_wayland_tbm_server_destroy_resource (struct wl_resource *resource)
-{
-       struct wayland_tbm_server *tbm_srv = NULL;
-       struct wayland_tbm_client_resource *c_res = NULL, *tmp_res;
-
-       /* remove the client resources to the list */
-       tbm_srv = wl_resource_get_user_data(resource);
-       if (!wl_list_empty(&tbm_srv->client_resource_list)) {
-               wl_list_for_each_safe(c_res, tmp_res, &tbm_srv->client_resource_list, link) {
-                       if (c_res->resource == resource) {
-#ifdef WL_TBM_SERVER_DEBUG
-                               WL_TBM_LOG("[%s]: resource,%p pid,%d \n", __func__, c_res->resource,
-                                          c_res->pid);
-#endif
-                               wl_list_remove(&c_res->link);
-                               if (c_res->app_name)
-                                       free(c_res->app_name);
-                               free(c_res);
-                               break;
-                       }
-               }
-       }
-}
-
-static void
-_wayland_tbm_server_bind_cb(struct wl_client *client, void *data,
-                           uint32_t version,
-                           uint32_t id)
-{
-       struct wayland_tbm_server *tbm_srv = NULL;
-       struct wayland_tbm_client_resource *c_res = NULL;
-
-       struct wl_resource *resource;
-       pid_t pid = 0;
-       uid_t uid = 0;
-       gid_t gid = 0;
-
-
-       resource = wl_resource_create(client, &wl_tbm_interface, MIN(version, 1), id);
-       if (!resource) {
-               wl_client_post_no_memory(client);
-               return;
-       }
-
-       wl_resource_set_implementation(resource,
-                                      &_wayland_tbm_server_implementation,
-                                      data,
-                                      _wayland_tbm_server_destroy_resource);
-
-       /* add the client resources to the list */
-       tbm_srv = wl_resource_get_user_data(resource);
-       wl_client_get_credentials(client, &pid, &uid, &gid);
-
-#ifdef WL_TBM_SERVER_DEBUG
-       WL_TBM_LOG("[%s]: resource,%p pid,%d \n", __func__, resource, pid);
-#endif
-
-       c_res = calloc (1, sizeof(struct wayland_tbm_client_resource));
-       c_res->pid = pid;
-       c_res->resource = resource;
-       wl_list_insert(&tbm_srv->client_resource_list, &c_res->link);
-}
-
-struct wayland_tbm_server *
-wayland_tbm_server_init(struct wl_display *display, const char *device_name,
-                       int fd,
-                       uint32_t flags)
-{
-       struct wayland_tbm_server *tbm_srv;
-
-       tbm_srv = calloc(1, sizeof(struct wayland_tbm_server));
-       WL_TBM_RETURN_VAL_IF_FAIL(tbm_srv != NULL, NULL);
-
-       tbm_srv->display = display;
-
-       /* init the client resource list */
-       wl_list_init(&tbm_srv->client_resource_list);
-       wl_list_init(&tbm_srv->server_queue_list);
-
-       //init bufmgr
-       tbm_srv->bufmgr = tbm_bufmgr_init(-1);
-       if (!tbm_srv->bufmgr) {
-               free(tbm_srv);
-               return NULL;
-       }
-
-       if (!getenv("WL_TBM_EMBEDDED_SERVER")) {
-               WL_TBM_S_LOG("Bind start\n");
-               tbm_bufmgr_bind_native_display(tbm_srv->bufmgr, (void *)display);
-       }
-       tbm_srv->wl_tbm_global = wl_global_create(display, &wl_tbm_interface, 1,
-                                tbm_srv, _wayland_tbm_server_bind_cb);
-
-       //init wl_tbm_queue
-       wl_list_init(&tbm_srv->queue_list);
-
-       return tbm_srv;
-}
-
-void
-wayland_tbm_server_deinit(struct wayland_tbm_server *tbm_srv)
-{
-       wl_global_destroy(tbm_srv->wl_tbm_global);
-
-       tbm_bufmgr_deinit(tbm_srv->bufmgr);
-
-       free(tbm_srv);
-}
-
-tbm_surface_h
-wayland_tbm_server_get_surface(struct wayland_tbm_server *tbm_srv,
-                              struct wl_resource *resource)
-{
-       struct wl_tbm_buffer *wl_buffer;
-
-       if (resource == NULL)
-               return NULL;
-
-       if (wl_resource_instance_of(resource, &wl_buffer_interface,
-                                   &_wayland_tbm_buffer_impementation)) {
-               wl_buffer = wl_resource_get_user_data(resource);
-               return wl_buffer->tbm_surface;
-       }
-
-       return NULL;
-}
-
-struct wl_resource *
-wayland_tbm_server_get_resource(struct wayland_tbm_server *tbm_srv,
-                               tbm_surface_h surface)
-{
-       struct wl_tbm_buffer *wl_buffer = NULL;
-
-       tbm_surface_internal_get_user_data(surface, KEY_WL_TBM_BUFFER,
-                                          (void **)&wl_buffer);
-       if (wl_buffer)
-               return wl_buffer->resource;
-
-       return NULL;
-}
-
-uint32_t
-wayland_tbm_server_get_flags(struct wayland_tbm_server *tbm_srv,
-                            struct wl_resource *resource)
-{
-       struct wl_tbm_buffer *wl_buffer;
-
-       if (resource == NULL)
-               return 0;
-
-       if (wl_resource_instance_of(resource, &wl_buffer_interface,
-                                   &_wayland_tbm_buffer_impementation)) {
-               wl_buffer = wl_resource_get_user_data(resource);
-               return wl_buffer->flags;
-       }
-
-       return 0;
-}
-
-void *
-wayland_tbm_server_get_bufmgr(struct wayland_tbm_server *tbm_srv)
-{
-       if (tbm_srv == NULL)
-               return NULL;
-
-       return (void *)tbm_srv->bufmgr;
-}
-
-static void
-_wayland_tbm_queue_impl_destroy(struct wl_client *client,
-                               struct wl_resource *resource)
-{
-       _destory_tbm_queue(resource);
-}
-
-static void
-_wayland_tbm_queue_impl_detach_buffer(struct wl_client *client,
-                                     struct wl_resource *resource,
-                                     struct wl_resource *buffer)
-{
-}
-
-static const struct wl_tbm_queue_interface _wayland_tbm_queue_impementation = {
-       _wayland_tbm_queue_impl_destroy,
-       _wayland_tbm_queue_impl_detach_buffer,
-};
-
-struct wl_tbm_queue *
-_find_tbm_queue(struct wayland_tbm_server *tbm_srv, struct wl_resource *surface)
-{
-       struct wl_tbm_queue *queue = NULL;
-
-       wl_list_for_each(queue, &tbm_srv->queue_list, link) {
-               if (queue && queue->surface == surface)
-                       return queue;
-       }
-
-       return NULL;
-}
-
-static void
-_destory_tbm_queue(struct wl_resource *resource)
-{
-       struct wl_tbm_queue *queue = wl_resource_get_user_data(resource);
-
-       wl_list_remove(&queue->link);
-
-       free(queue);
-}
-
-static void
-_create_tbm_queue(struct wl_client *client,
-                 struct wl_resource *resource,
-                 uint32_t surface_queue,
-                 struct wl_resource *surface)
-{
-       struct wayland_tbm_server *tbm_srv = wl_resource_get_user_data(resource);
-       struct wl_tbm_queue *queue;
-
-       queue = calloc(1, sizeof * queue);
-       if (queue == NULL) {
-               wl_resource_post_no_memory(resource);
-               return;
-       }
-
-       wl_list_init(&queue->link);
-       queue->wl_tbm = resource;
-       queue->surface = surface;
-       queue->resource = wl_resource_create(client, &wl_tbm_queue_interface, 1,
-                                            surface_queue);
-       if (!queue->resource) {
-               wl_resource_post_no_memory(resource);
-               free(queue);
-               return;
-       }
-
-       wl_resource_set_implementation(queue->resource,
-                                      (void (* *)(void)) &_wayland_tbm_queue_impementation,
-                                      queue, _destory_tbm_queue);
-       wl_list_insert(&tbm_srv->queue_list, &queue->link);
-}
-
-static void
-_server_queue_buffer_attach(struct wl_tbm_queue *client_queue,
-                           tbm_surface_h buffer)
-{
-       struct wl_tbm_buffer *wl_tbm_buffer = NULL;
-       tbm_surface_info_s info;
-       int num_buf;
-       int bufs[TBM_SURF_PLANE_MAX] = { -1, -1, -1, -1};
-       int is_fd = -1;
-       int ret = -1, i;
-       uint32_t flags;
-
-       flags = client_queue->server_queue->flags;
-       wl_tbm_buffer = _create_wl_buffer(wl_resource_get_client(client_queue->wl_tbm),
-                                         client_queue->wl_tbm,
-                                         0, buffer, flags);
-       WL_TBM_RETURN_IF_FAIL(wl_tbm_buffer != NULL);
-       tbm_surface_internal_ref(buffer);
-
-       ret = tbm_surface_get_info(buffer, &info);
-       if (ret != TBM_SURFACE_ERROR_NONE) {
-               WL_TBM_S_LOG("Failed to create buffer from surface\n");
-               _destroy_buffer(wl_tbm_buffer->resource);
-               return;
-       }
-
-       if (info.num_planes > 3) {
-               WL_TBM_S_LOG("invalid num_planes(%d)\n", info.num_planes);
-               _destroy_buffer(wl_tbm_buffer->resource);
-               return;
-       }
-
-       num_buf = tbm_surface_internal_get_num_bos(buffer);
-       if (num_buf == 0) {
-               WL_TBM_S_LOG("surface doesn't have any bo.\n");
-               _destroy_buffer(wl_tbm_buffer->resource);
-               goto err;
-       }
-
-       for (i = 0; i < num_buf; i++) {
-               tbm_bo bo = tbm_surface_internal_get_bo(buffer, i);
-               if (bo == NULL) {
-                       WL_TBM_S_LOG("Failed to get bo from surface\n");
-                       goto err;
-               }
-
-               /* try to get fd first */
-               if (is_fd == -1 || is_fd == 1) {
-                       bufs[i] = tbm_bo_export_fd(bo);
-                       if (bufs[i] >= 0)
-                               is_fd = 1;
-               }
-
-               /* if fail to get fd, try to get name second */
-               if (is_fd == -1 || is_fd == 0) {
-                       bufs[i] = tbm_bo_export(bo);
-                       if (bufs[i] > 0)
-                               is_fd = 0;
-               }
-
-               if (is_fd == -1 ||
-                   (is_fd == 1 && bufs[i] < 0) ||
-                   (is_fd == 0 && bufs[i] <= 0)) {
-                       WL_TBM_S_LOG("Failed to export(is_fd:%d, bufs:%d)\n", is_fd, bufs[i]);
-                       goto err;
-               }
-       }
-
-       if (is_fd == 1)
-               wl_tbm_queue_send_buffer_attached_with_fd(client_queue->resource,
-                               wl_tbm_buffer->resource,
-                               info.width, info.height, info.format, info.num_planes,
-                               tbm_surface_internal_get_plane_bo_idx(buffer, 0),
-                               info.planes[0].offset, info.planes[0].stride,
-                               tbm_surface_internal_get_plane_bo_idx(buffer, 1),
-                               info.planes[1].offset, info.planes[1].stride,
-                               tbm_surface_internal_get_plane_bo_idx(buffer, 2),
-                               info.planes[2].offset, info.planes[2].stride,
-                               flags, num_buf, bufs[0],
-                               (bufs[1] == -1) ? bufs[0] : bufs[1],
-                               (bufs[2] == -1) ? bufs[0] : bufs[2]);
-       else
-               wl_tbm_queue_send_buffer_attached_with_fd(client_queue->resource,
-                               wl_tbm_buffer->resource,
-                               info.width, info.height, info.format, info.num_planes,
-                               tbm_surface_internal_get_plane_bo_idx(buffer, 0),
-                               info.planes[0].offset, info.planes[0].stride,
-                               tbm_surface_internal_get_plane_bo_idx(buffer, 1),
-                               info.planes[1].offset, info.planes[1].stride,
-                               tbm_surface_internal_get_plane_bo_idx(buffer, 2),
-                               info.planes[2].offset, info.planes[2].stride,
-                               flags, num_buf, bufs[0],
-                               (bufs[1] == -1) ? bufs[0] : bufs[1],
-                               (bufs[2] == -1) ? bufs[0] : bufs[2]);
-
-
-       for (i = 0; i < TBM_SURF_PLANE_MAX; i++) {
-               if (is_fd == 1 && (bufs[i] >= 0))
-                       close(bufs[i]);
-       }
-
-       wl_tbm_buffer->tbm_queue = client_queue->server_queue->tbm_queue;
-       return;
-err:
-       for (i = 0; i < TBM_SURF_PLANE_MAX; i++) {
-               if (is_fd == 1 && (bufs[i] >= 0))
-                       close(bufs[i]);
-       }
-
-       if (wl_tbm_buffer) {
-               _destroy_buffer(wl_tbm_buffer->resource);
-               tbm_surface_internal_unref(buffer);
-       }
-
-       return;
-}
-
-static void
-_server_queue_buffer_attach_free_queue(struct wl_tbm_queue *client_queue)
-{
-       tbm_surface_queue_h queue;
-       tbm_surface_h buffer;
-       struct wl_resource *wl_buffer;
-
-       queue = client_queue->server_queue->tbm_queue;
-       while (tbm_surface_queue_can_dequeue(queue, 0)) {
-               tbm_surface_queue_dequeue(queue, &buffer);
-
-               wl_buffer = wayland_tbm_server_get_resource(NULL, buffer);
-               if (wl_buffer) {
-                       wl_buffer_send_release(wl_buffer);
-                       continue;
-               }
-
-               _server_queue_buffer_attach(client_queue, buffer);
-       }
-}
-
-static void
-_server_queue_dequeuable_cb(tbm_surface_queue_h surface_queue,
-                           void *data)
-{
-       struct wl_tbm_queue *client_queue = data;
-       struct wl_resource *wl_buffer;
-       tbm_surface_h buffer = NULL;
-
-       tbm_surface_queue_dequeue(surface_queue, &buffer);
-       WL_TBM_RETURN_IF_FAIL(buffer != NULL);
-
-       wl_buffer = wayland_tbm_server_get_resource(NULL, buffer);
-       if (wl_buffer) {
-               wl_buffer_send_release(wl_buffer);
-               return;
-       }
-
-       _server_queue_buffer_attach(client_queue, buffer);
-}
-
-struct wayland_tbm_server_queue *
-wayland_tbm_server_create_queue(struct wayland_tbm_server *tbm_srv,
-                               tbm_surface_queue_h queue, uint32_t flags)
-{
-       struct wayland_tbm_server_queue *server_queue = NULL;
-
-       WL_TBM_RETURN_VAL_IF_FAIL(tbm_srv != NULL, NULL);
-       WL_TBM_RETURN_VAL_IF_FAIL(queue != NULL, NULL);
-
-       server_queue = calloc(1, sizeof(struct wayland_tbm_server_queue));
-       WL_TBM_RETURN_VAL_IF_FAIL(server_queue != NULL, NULL);
-
-       server_queue->tbm_srv = tbm_srv;
-       server_queue->tbm_queue = queue;
-       server_queue->flags = flags;
-       wl_list_insert(&tbm_srv->server_queue_list, &server_queue->link);
-
-       return server_queue;
-}
-
-int
-wayland_tbm_server_queue_set_surface(struct wayland_tbm_server_queue *server_queue,
-                                    struct wl_resource *surface, uint32_t usage)
-{
-       struct wl_tbm_queue *client_queue = NULL;
-
-       WL_TBM_RETURN_VAL_IF_FAIL(server_queue != NULL, 0);
-
-       if (surface) {
-               client_queue = _find_tbm_queue(server_queue->tbm_srv, surface);
-               WL_TBM_RETURN_VAL_IF_FAIL(client_queue != NULL, 0);
-       }
-
-       if (client_queue == server_queue->client_queue)
-               return 1;
-
-       if (server_queue->client_queue) {
-               //Send deactivate;
-               server_queue->client_queue->server_queue = NULL;
-
-               tbm_surface_queue_remove_dequeuable_cb(server_queue->tbm_queue,
-                                                      _server_queue_dequeuable_cb,
-                                                      server_queue->client_queue);
-               wl_tbm_queue_send_deactive(server_queue->client_queue->resource);
-       }
-
-       if (client_queue) {
-               //Send activate and attach free buffer;
-               client_queue->server_queue = server_queue;
-
-               wl_tbm_queue_send_active(client_queue->resource, usage);
-               wl_tbm_queue_send_info(client_queue->resource,
-                               tbm_surface_queue_get_width(server_queue->tbm_queue),
-                               tbm_surface_queue_get_height(server_queue->tbm_queue),
-                               tbm_surface_queue_get_format(server_queue->tbm_queue),
-                               TBM_BO_SCANOUT,
-                               tbm_surface_queue_get_size(server_queue->tbm_queue));
-
-               _server_queue_buffer_attach_free_queue(client_queue);
-               tbm_surface_queue_add_dequeuable_cb(server_queue->tbm_queue,
-                                                   _server_queue_dequeuable_cb, client_queue);
-       }
-
-       server_queue->client_queue = client_queue;
-
-       return 1;
-}
-
-
+/*\r
+Copyright (C) 2015 Samsung Electronics co., Ltd. All Rights Reserved.\r
+\r
+Contact:\r
+      SooChan Lim <sc1.lim@samsung.com>,\r
+      Sangjin Lee <lsj119@samsung.com>,\r
+      Boram Park <boram1288.park@samsung.com>,\r
+      Changyeon Lee <cyeon.lee@samsung.com>\r
+\r
+Permission is hereby granted, free of charge, to any person obtaining a\r
+copy of this software and associated documentation files (the "Software"),\r
+to deal in the Software without restriction, including without limitation\r
+the rights to use, copy, modify, merge, publish, distribute, sublicense,\r
+and/or sell copies of the Software, and to permit persons to whom the\r
+Software is furnished to do so, subject to the following conditions:\r
+\r
+The above copyright notice and this permission notice (including the next\r
+paragraph) shall be included in all copies or substantial portions of the\r
+Software.\r
+\r
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL\r
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\r
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\r
+DEALINGS IN THE SOFTWARE.\r
+*/\r
+\r
+#define WL_HIDE_DEPRECATED\r
+\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <string.h>\r
+#include <stddef.h>\r
+#include <unistd.h>\r
+#include <fcntl.h>\r
+\r
+#include <tbm_surface.h>\r
+#include <tbm_surface_internal.h>\r
+#include <wayland-server.h>\r
+\r
+#include "wayland-tbm-server.h"\r
+#include "wayland-tbm-server-protocol.h"\r
+\r
+#include "wayland-tbm-int.h"\r
+\r
+#define WL_TBM_SERVER_DEBUG\r
+\r
+#define MIN(x,y) (((x)<(y))?(x):(y))\r
+\r
+struct wayland_tbm_server {\r
+       struct wl_display *display;\r
+       struct wl_global *wl_tbm_global;\r
+\r
+       tbm_bufmgr bufmgr;\r
+\r
+       struct wl_list cqueue_list; /* for scanout buffer */\r
+       struct wl_list cresource_list; /* for tbm monitor */\r
+};\r
+\r
+struct wayland_tbm_buffer {\r
+       struct wl_resource *wl_buffer;\r
+       tbm_surface_h surface;\r
+       int flags;\r
+       struct wl_client *client;\r
+\r
+       wayland_tbm_server_surface_destroy_cb destroy_cb;\r
+       void *user_data;\r
+};\r
+\r
+struct wayland_tbm_client_resource {\r
+       struct wl_resource *resource;\r
+       pid_t pid;\r
+       char *app_name;\r
+\r
+       struct wl_list link;\r
+};\r
+\r
+struct wayland_tbm_client_queue {\r
+       struct wl_resource *wl_tbm;\r
+       struct wl_resource *wl_tbm_queue;\r
+       struct wl_resource *wl_surface;\r
+\r
+       struct wl_list link;\r
+};\r
+\r
+static const int key_wl_tbm_queue;\r
+#define KEY_WL_TBM_QUEUE ((unsigned long)&key_wl_tbm_queue)\r
+\r
+const static int key_tbm_buffer;\r
+#define KEY_TBM_BUFFER ((unsigned long)&key_tbm_buffer)\r
+\r
+static void _wayland_tbm_server_tbm_buffer_destroy(struct wayland_tbm_buffer *tbm_buffer);\r
+\r
+static void\r
+_tbm_buffer_destroy(struct wl_resource *wl_buffer)\r
+{\r
+       struct wayland_tbm_buffer *tbm_buffer = wl_resource_get_user_data(wl_buffer);\r
+\r
+       _wayland_tbm_server_tbm_buffer_destroy(tbm_buffer);\r
+}\r
+\r
+static void\r
+_wayland_tbm_server_tbm_buffer_impl_destroy(struct wl_client *client, struct wl_resource *wl_buffer)\r
+{\r
+    wl_resource_destroy(wl_buffer);\r
+}\r
+\r
+static const struct wl_buffer_interface _wayland_tbm_buffer_impementation = {\r
+       _wayland_tbm_server_tbm_buffer_impl_destroy\r
+};\r
+\r
+static void\r
+_wayland_tbm_server_tbm_buffer_destroy(struct wayland_tbm_buffer *tbm_buffer)\r
+{\r
+       if (tbm_buffer->destroy_cb)\r
+        tbm_buffer->destroy_cb(tbm_buffer->surface, tbm_buffer->user_data);\r
+\r
+       tbm_surface_internal_delete_user_data(tbm_buffer->surface, KEY_TBM_BUFFER);\r
+       tbm_surface_destroy(tbm_buffer->surface);\r
+\r
+       free(tbm_buffer);\r
+}\r
+\r
+static struct wayland_tbm_buffer *\r
+_wayland_tbm_server_tbm_buffer_create(struct wl_resource *wl_tbm,\r
+                       struct wl_client *client, tbm_surface_h surface, uint id, int flags)\r
+{\r
+       struct wayland_tbm_server *tbm_srv = wl_resource_get_user_data(wl_tbm);\r
+       struct wayland_tbm_client_resource *c_res = NULL, *tmp_res = NULL;\r
+       struct wayland_tbm_buffer *tbm_buffer;\r
+\r
+       tbm_buffer = calloc(1, sizeof * tbm_buffer);\r
+       if (tbm_buffer == NULL) {\r
+               WL_TBM_S_LOG("Error. fail to allocate a tbm_buffer.\n");\r
+               return NULL;\r
+       }\r
+\r
+       /* create a wl_buffer resource */\r
+       tbm_buffer->wl_buffer = wl_resource_create(client, &wl_buffer_interface, 1, id);\r
+       if (!tbm_buffer->wl_buffer) {\r
+               WL_TBM_S_LOG("Error. fail to create wl_buffer resource.\n");\r
+               free(tbm_buffer);\r
+               return NULL;\r
+       }\r
+\r
+       wl_resource_set_implementation(tbm_buffer->wl_buffer,\r
+                                      (void (* *)(void)) &_wayland_tbm_buffer_impementation,\r
+                                      tbm_buffer, _tbm_buffer_destroy);\r
+\r
+       tbm_buffer->flags = flags;\r
+       tbm_buffer->surface = surface;\r
+       tbm_buffer->client = client;\r
+\r
+       tbm_surface_internal_add_user_data(surface, KEY_TBM_BUFFER, NULL);\r
+       tbm_surface_internal_set_user_data(surface, KEY_TBM_BUFFER,\r
+                                          (void *)tbm_buffer);\r
+\r
+       /* set the debug_pid to the surface for debugging */\r
+       if (!wl_list_empty(&tbm_srv->cresource_list)) {\r
+               wl_list_for_each_safe(c_res, tmp_res, &tbm_srv->cresource_list, link) {\r
+                       if (c_res->resource == wl_tbm) {\r
+                               tbm_surface_internal_set_debug_pid(surface, c_res->pid);\r
+                               break;\r
+                       }\r
+               }\r
+       }\r
+\r
+       return tbm_buffer;\r
+}\r
+\r
+static void\r
+_destroy_tbm_queue(struct wl_resource *wl_tbm_queue)\r
+{\r
+       struct wayland_tbm_client_queue *cqueue = wl_resource_get_user_data(wl_tbm_queue);\r
+\r
+       if (cqueue) {\r
+               wl_list_remove(&cqueue->link);\r
+               free(cqueue);\r
+\r
+               wl_resource_set_user_data(wl_tbm_queue, NULL);\r
+       }\r
+}\r
+\r
+static void\r
+_wayland_tbm_server_queue_impl_destroy(struct wl_client *client,\r
+                               struct wl_resource *wl_tbm_queue)\r
+{\r
+       wl_resource_destroy(wl_tbm_queue);\r
+}\r
+\r
+static void\r
+_wayland_tbm_server_queue_impl_detach_buffer(struct wl_client *client,\r
+                                     struct wl_resource *wl_tbm_queue,\r
+                                     struct wl_resource *wl_buffer)\r
+{\r
+}\r
+\r
+static const struct wl_tbm_queue_interface _wayland_tbm_queue_impementation = {\r
+       _wayland_tbm_server_queue_impl_destroy,\r
+       _wayland_tbm_server_queue_impl_detach_buffer,\r
+};\r
+\r
+static void\r
+_wayland_tbm_server_impl_request_tbm_monitor(struct wl_client *client,\r
+               struct wl_resource *resource,\r
+               int32_t command,\r
+               int32_t trace_command,\r
+               int32_t target,\r
+               int32_t pid)\r
+{\r
+       struct wayland_tbm_server *tbm_srv = wl_resource_get_user_data(resource);\r
+       struct wayland_tbm_client_resource *c_res = NULL, *tmp_res = NULL;\r
+       int i = 0;\r
+\r
+#ifdef WL_TBM_SERVER_DEBUG\r
+       WL_TBM_LOG("[%s]: command=%d, trace_command=%d, target=%d, pid=%d.\n", __func__,\r
+                  command, trace_command, target, pid);\r
+#endif\r
+\r
+       if (command == WL_TBM_MONITOR_COMMAND_LIST) {\r
+               WL_TBM_DEBUG("==================  app list       =======================\n");\r
+               WL_TBM_DEBUG("no pid  app_name\n");\r
+\r
+               if (!wl_list_empty(&tbm_srv->cresource_list)) {\r
+                       wl_list_for_each_safe(c_res, tmp_res, &tbm_srv->cresource_list, link) {\r
+                               /* skip the requestor (wayland-tbm-monitor */\r
+                               if (c_res->resource == resource)\r
+                                       continue;\r
+\r
+                               if (!c_res->app_name) {\r
+                                       c_res->app_name = (char *) calloc(1, 255 * sizeof(char));\r
+\r
+                                       _wayland_tbm_util_get_appname_from_pid(c_res->pid, c_res->app_name);\r
+                                       _wayland_tbm_util_get_appname_brief(c_res->app_name);\r
+                               }\r
+\r
+                               WL_TBM_DEBUG("%-3d%-5d%s\n", ++i, c_res->pid, c_res->app_name);\r
+                       }\r
+               }\r
+\r
+               WL_TBM_DEBUG("======================================================\n");\r
+\r
+               return;\r
+       }\r
+\r
+       if (target == WL_TBM_MONITOR_TARGET_CLIENT) {\r
+               if (pid < 1) {\r
+                       wl_resource_post_error(resource, WL_TBM_ERROR_INVALID_FORMAT, "invalid format");\r
+                       return;\r
+               }\r
+               /* send the events to all client containing wl_tbm resource except for the wayland-tbm-monitor(requestor). */\r
+               if (!wl_list_empty(&tbm_srv->cresource_list)) {\r
+                       wl_list_for_each_safe(c_res, tmp_res, &tbm_srv->cresource_list, link) {\r
+                               /* skip the requestor (wayland-tbm-monitor */\r
+                               if (c_res->resource == resource)\r
+                                       continue;\r
+\r
+                               wl_tbm_send_monitor_client_tbm_bo(c_res->resource, command, trace_command,\r
+                                                                 target, pid);\r
+                       }\r
+               }\r
+       } else if (target == WL_TBM_MONITOR_TARGET_SERVER) {\r
+               if (command == WL_TBM_MONITOR_COMMAND_SHOW) {\r
+                       tbm_bufmgr_debug_show(tbm_srv->bufmgr);\r
+               } else if (command == WL_TBM_MONITOR_COMMAND_TRACE) {\r
+                       WL_TBM_LOG("[%s]: TRACE NOT IMPLEMENTED.\n", __func__);\r
+               } else\r
+                       wl_resource_post_error(resource, WL_TBM_ERROR_INVALID_FORMAT,\r
+                                              "invalid format");\r
+       } else if (target == WL_TBM_MONITOR_TARGET_ALL) {\r
+               if (command == WL_TBM_MONITOR_COMMAND_SHOW) {\r
+                       /* send the events to all client containing wl_tbm resource except for the wayland-tbm-monitor(requestor). */\r
+                       if (!wl_list_empty(&tbm_srv->cresource_list)) {\r
+                               wl_list_for_each_safe(c_res, tmp_res, &tbm_srv->cresource_list, link) {\r
+                                       /* skip the requestor (wayland-tbm-monitor */\r
+                                       if (c_res->resource == resource)\r
+                                               continue;\r
+\r
+                                       wl_tbm_send_monitor_client_tbm_bo(c_res->resource, command, trace_command,\r
+                                                                         target, pid);\r
+                               }\r
+                       }\r
+                       tbm_bufmgr_debug_show(tbm_srv->bufmgr);\r
+               } else if (command == WL_TBM_MONITOR_COMMAND_TRACE) {\r
+                       wl_tbm_send_monitor_client_tbm_bo(resource, command, trace_command, target,\r
+                                                         pid);\r
+                       WL_TBM_LOG("[%s]: TRACE NOT IMPLEMENTED.\n", __func__);\r
+               } else\r
+                       wl_resource_post_error(resource, WL_TBM_ERROR_INVALID_FORMAT,\r
+                                              "invalid format");\r
+       } else\r
+               wl_resource_post_error(resource, WL_TBM_ERROR_INVALID_FORMAT,\r
+                                      "invalid format");\r
+\r
+}\r
+\r
+\r
+static void\r
+_wayland_tbm_server_impl_create_buffer(struct wl_client *client,\r
+                                      struct wl_resource *wl_tbm,\r
+                                      uint32_t id,\r
+                                      int32_t width, int32_t height, uint32_t format, int32_t num_plane,\r
+                                      int32_t buf_idx0, int32_t offset0, int32_t stride0,\r
+                                      int32_t buf_idx1, int32_t offset1, int32_t stride1,\r
+                                      int32_t buf_idx2, int32_t offset2, int32_t stride2,\r
+                                      uint32_t flags,\r
+                                      int32_t num_buf, uint32_t buf0, uint32_t buf1, uint32_t buf2)\r
+{\r
+       struct wayland_tbm_server *tbm_srv = wl_resource_get_user_data(wl_tbm);\r
+       struct wayland_tbm_buffer *tbm_buffer = NULL;\r
+       tbm_surface_h surface = NULL;\r
+       tbm_surface_info_s info;\r
+       tbm_bo bos[TBM_SURF_PLANE_MAX];\r
+       int32_t names[TBM_SURF_PLANE_MAX] = { -1, -1, -1, -1};\r
+       int bpp;\r
+       int numPlane;\r
+       int i;\r
+\r
+#ifdef WL_TBM_SERVER_DEBUG\r
+       WL_TBM_LOG("[%s]: trying.\n", __func__);\r
+#endif\r
+\r
+       bpp = tbm_surface_internal_get_bpp(format);\r
+       numPlane = tbm_surface_internal_get_num_planes(format);\r
+       if (numPlane != num_plane) {\r
+               wl_resource_post_error(wl_tbm, WL_TBM_ERROR_INVALID_FORMAT,\r
+                                      "invalid format");\r
+               return;\r
+       }\r
+\r
+       memset(&info, 0x0, sizeof(tbm_surface_info_s));\r
+\r
+       info.width = width;\r
+       info.height = height;\r
+       info.format = format;\r
+       info.bpp = bpp;\r
+       info.num_planes = numPlane;\r
+\r
+       /*Fill plane info*/\r
+       if (numPlane > 0) {\r
+               info.planes[0].offset = offset0;\r
+               info.planes[0].stride = stride0;\r
+               numPlane--;\r
+       }\r
+\r
+       if (numPlane > 0) {\r
+               info.planes[1].offset = offset1;\r
+               info.planes[1].stride = stride1;\r
+               numPlane--;\r
+       }\r
+\r
+       if (numPlane > 0) {\r
+               info.planes[2].offset = offset2;\r
+               info.planes[2].stride = stride2;\r
+               numPlane--;\r
+       }\r
+\r
+       /*Fill buffer*/\r
+       names[0] = buf0;\r
+       names[1] = buf1;\r
+       names[2] = buf2;\r
+\r
+       for (i = 0; i < num_buf; i++) {\r
+               bos[i] = tbm_bo_import(tbm_srv->bufmgr, names[i]);\r
+       }\r
+\r
+       surface = tbm_surface_internal_create_with_bos(&info, bos, num_buf);\r
+       for (i = 0; i < num_buf; i++)\r
+               tbm_bo_unref(bos[i]);\r
+\r
+       tbm_buffer = _wayland_tbm_server_tbm_buffer_create(wl_tbm, client, surface, id, flags);\r
+       if (tbm_buffer == NULL) {\r
+               tbm_surface_destroy(surface);\r
+               wl_resource_post_no_memory(wl_tbm);\r
+               return;\r
+       }\r
+\r
+}\r
+\r
+static void\r
+_wayland_tbm_server_impl_create_buffer_with_fd(struct wl_client *client,\r
+               struct wl_resource *wl_tbm,\r
+               uint32_t id,\r
+               int32_t width, int32_t height, uint32_t format, int num_plane,\r
+               int32_t buf_idx0, int32_t offset0, int32_t stride0,\r
+               int32_t buf_idx1, int32_t offset1, int32_t stride1,\r
+               int32_t buf_idx2, int32_t offset2, int32_t stride2,\r
+               uint32_t flags,\r
+               int32_t num_buf, int32_t buf0, int32_t buf1, int32_t buf2)\r
+{\r
+       struct wayland_tbm_server *tbm_srv = wl_resource_get_user_data(wl_tbm);\r
+       struct wayland_tbm_buffer *tbm_buffer = NULL;\r
+       tbm_surface_h surface = NULL;\r
+       tbm_surface_info_s info;\r
+       tbm_bo bos[TBM_SURF_PLANE_MAX];\r
+       int32_t names[TBM_SURF_PLANE_MAX] = { -1, -1, -1, -1};\r
+       int bpp;\r
+       int numPlane;\r
+       int i;\r
+\r
+#ifdef WL_TBM_SERVER_DEBUG\r
+       WL_TBM_LOG("[%s]: trying.\n", __func__);\r
+#endif\r
+\r
+       bpp = tbm_surface_internal_get_bpp(format);\r
+       numPlane = tbm_surface_internal_get_num_planes(format);\r
+       if (numPlane != num_plane) {\r
+               wl_resource_post_error(wl_tbm, WL_TBM_ERROR_INVALID_FORMAT,\r
+                                      "invalid format");\r
+               return;\r
+       }\r
+\r
+       memset(&info, 0x0, sizeof(tbm_surface_info_s));\r
+\r
+       info.width = width;\r
+       info.height = height;\r
+       info.format = format;\r
+       info.bpp = bpp;\r
+       info.num_planes = numPlane;\r
+\r
+       /*Fill plane info*/\r
+       if (numPlane > 0) {\r
+               info.planes[0].offset = offset0;\r
+               info.planes[0].stride = stride0;\r
+               numPlane--;\r
+       }\r
+\r
+       if (numPlane > 0) {\r
+               info.planes[1].offset = offset1;\r
+               info.planes[1].stride = stride1;\r
+               numPlane--;\r
+       }\r
+\r
+       if (numPlane > 0) {\r
+               info.planes[2].offset = offset2;\r
+               info.planes[2].stride = stride2;\r
+               numPlane--;\r
+       }\r
+\r
+       /*Fill buffer*/\r
+       names[0] = buf0;\r
+       names[1] = buf1;\r
+       names[2] = buf2;\r
+\r
+       for (i = 0; i < num_buf; i++) {\r
+               bos[i] = tbm_bo_import_fd(tbm_srv->bufmgr, names[i]);\r
+       }\r
+\r
+       surface = tbm_surface_internal_create_with_bos(&info, bos, num_buf);\r
+       for (i = 0; i < num_buf; i++)\r
+               tbm_bo_unref(bos[i]);\r
+\r
+       tbm_buffer = _wayland_tbm_server_tbm_buffer_create(wl_tbm, client, surface, id, flags);\r
+       if (tbm_buffer == NULL) {\r
+               tbm_surface_destroy(surface);\r
+               wl_resource_post_no_memory(wl_tbm);\r
+               return;\r
+       }\r
+\r
+       close(buf0);\r
+       close(buf1);\r
+       close(buf2);\r
+}\r
+\r
+static void\r
+_wayland_tbm_server_impl_create_surface_queue(struct wl_client *client,\r
+               struct wl_resource *wl_tbm,\r
+               uint32_t surface_queue,\r
+               struct wl_resource *wl_surface)\r
+{\r
+       struct wayland_tbm_server *tbm_srv = wl_resource_get_user_data(wl_tbm);\r
+       struct wayland_tbm_client_queue *cqueue = NULL;\r
+\r
+       cqueue = calloc(1, sizeof(struct wayland_tbm_client_queue));\r
+       if (!cqueue) {\r
+               wl_resource_post_no_memory(wl_tbm);\r
+               return;\r
+       }\r
+\r
+       cqueue->wl_tbm = wl_tbm;\r
+       cqueue->wl_surface = wl_surface;\r
+       cqueue->wl_tbm_queue = wl_resource_create(client, &wl_tbm_queue_interface, 1,\r
+                                                                               surface_queue);\r
+       if (!cqueue->wl_tbm_queue) {\r
+               wl_resource_post_no_memory(wl_tbm);\r
+               free(cqueue);\r
+               return;\r
+       }\r
+\r
+       wl_resource_set_implementation(cqueue->wl_tbm_queue,\r
+                                      (void (* *)(void)) &_wayland_tbm_queue_impementation,\r
+                                      cqueue, _destroy_tbm_queue);\r
+\r
+       wl_list_init(&cqueue->link);\r
+\r
+       /* add a cqueue to the list */\r
+       wl_list_insert(&tbm_srv->cqueue_list, &cqueue->link);\r
+}\r
+\r
+static const struct wl_tbm_interface _wayland_tbm_server_implementation = {\r
+       _wayland_tbm_server_impl_create_buffer,\r
+       _wayland_tbm_server_impl_create_buffer_with_fd,\r
+       _wayland_tbm_server_impl_request_tbm_monitor,\r
+       _wayland_tbm_server_impl_create_surface_queue,\r
+};\r
+\r
+static void\r
+_wayland_tbm_server_destroy_resource(struct wl_resource *wl_tbm)\r
+{\r
+       struct wayland_tbm_server *tbm_srv = NULL;\r
+       struct wayland_tbm_client_resource *c_res = NULL, *tmp_res;\r
+\r
+       /* remove the client resources to the list */\r
+       tbm_srv = wl_resource_get_user_data(wl_tbm);\r
+       if (!wl_list_empty(&tbm_srv->cresource_list)) {\r
+               wl_list_for_each_safe(c_res, tmp_res, &tbm_srv->cresource_list, link) {\r
+                       if (c_res->resource == wl_tbm) {\r
+#ifdef WL_TBM_SERVER_DEBUG\r
+                               WL_TBM_LOG("[%s]: resource,%p pid,%d \n", __func__, c_res->resource,\r
+                                          c_res->pid);\r
+#endif\r
+                               wl_list_remove(&c_res->link);\r
+                               if (c_res->app_name)\r
+                                       free(c_res->app_name);\r
+                               free(c_res);\r
+                               break;\r
+                       }\r
+               }\r
+       }\r
+}\r
+\r
+static void\r
+_wayland_tbm_server_bind_cb(struct wl_client *client, void *data,\r
+                           uint32_t version,\r
+                           uint32_t id)\r
+{\r
+       struct wayland_tbm_server *tbm_srv = NULL;\r
+       struct wayland_tbm_client_resource *c_res = NULL;\r
+       struct wl_resource *wl_tbm;\r
+\r
+       pid_t pid = 0;\r
+       uid_t uid = 0;\r
+       gid_t gid = 0;\r
+\r
+       wl_tbm = wl_resource_create(client, &wl_tbm_interface, MIN(version, 1), id);\r
+       if (!wl_tbm) {\r
+               wl_client_post_no_memory(client);\r
+               return;\r
+       }\r
+\r
+       wl_resource_set_implementation(wl_tbm,\r
+                                      &_wayland_tbm_server_implementation,\r
+                                      data,\r
+                                      _wayland_tbm_server_destroy_resource);\r
+\r
+       /* add the client resources to the list */\r
+       tbm_srv = wl_resource_get_user_data(wl_tbm);\r
+       wl_client_get_credentials(client, &pid, &uid, &gid);\r
+\r
+#ifdef WL_TBM_SERVER_DEBUG\r
+       WL_TBM_LOG("[%s]: resource,%p pid,%d \n", __func__, wl_tbm, pid);\r
+#endif\r
+\r
+       c_res = calloc (1, sizeof(struct wayland_tbm_client_resource));\r
+       c_res->pid = pid;\r
+       c_res->resource = wl_tbm;\r
+       wl_list_insert(&tbm_srv->cresource_list, &c_res->link);\r
+}\r
+\r
+struct wayland_tbm_server *\r
+wayland_tbm_server_init(struct wl_display *display, const char *device_name,\r
+                       int fd,\r
+                       uint32_t flags)\r
+{\r
+       struct wayland_tbm_server *tbm_srv;\r
+\r
+       tbm_srv = calloc(1, sizeof(struct wayland_tbm_server));\r
+       WL_TBM_RETURN_VAL_IF_FAIL(tbm_srv != NULL, NULL);\r
+\r
+       tbm_srv->display = display;\r
+\r
+       //init bufmgr\r
+       tbm_srv->bufmgr = tbm_bufmgr_init(-1);\r
+       if (!tbm_srv->bufmgr) {\r
+               free(tbm_srv);\r
+               return NULL;\r
+       }\r
+\r
+       if (!getenv("WL_TBM_EMBEDDED_SERVER")) {\r
+               WL_TBM_S_LOG("Bind start\n");\r
+               tbm_bufmgr_bind_native_display(tbm_srv->bufmgr, (void *)display);\r
+       }\r
+       tbm_srv->wl_tbm_global = wl_global_create(display, &wl_tbm_interface, 1,\r
+                                tbm_srv, _wayland_tbm_server_bind_cb);\r
+\r
+\r
+       //init wayland_tbm_client_queue\r
+       wl_list_init(&tbm_srv->cqueue_list);\r
+\r
+       /* init the client resource list */\r
+       wl_list_init(&tbm_srv->cresource_list);\r
+\r
+\r
+       return tbm_srv;\r
+}\r
+\r
+void\r
+wayland_tbm_server_deinit(struct wayland_tbm_server *tbm_srv)\r
+{\r
+       WL_TBM_RETURN_IF_FAIL(tbm_srv != NULL);\r
+\r
+       wl_global_destroy(tbm_srv->wl_tbm_global);\r
+\r
+       tbm_bufmgr_deinit(tbm_srv->bufmgr);\r
+\r
+       free(tbm_srv);\r
+}\r
+\r
+tbm_surface_h\r
+wayland_tbm_server_get_surface(struct wayland_tbm_server *tbm_srv,\r
+                              struct wl_resource *wl_buffer)\r
+{\r
+       struct wayland_tbm_buffer *tbm_buffer  = NULL;\r
+\r
+//     WL_TBM_RETURN_VAL_IF_FAIL(tbm_srv != NULL, NULL);\r
+       WL_TBM_RETURN_VAL_IF_FAIL(wl_buffer != NULL, NULL);\r
+\r
+       if (wl_resource_instance_of(wl_buffer, &wl_buffer_interface,\r
+                                   &_wayland_tbm_buffer_impementation)) {\r
+               tbm_buffer = wl_resource_get_user_data(wl_buffer);\r
+               return tbm_buffer->surface;\r
+       }\r
+\r
+       return NULL;\r
+}\r
+\r
+void *\r
+wayland_tbm_server_get_bufmgr(struct wayland_tbm_server *tbm_srv)\r
+{\r
+       WL_TBM_RETURN_VAL_IF_FAIL(tbm_srv != NULL, NULL);\r
+\r
+       return (void *)tbm_srv->bufmgr;\r
+}\r
+\r
+uint32_t\r
+wayland_tbm_server_get_buffer_flags(struct wayland_tbm_server *tbm_srv,\r
+                                       struct wl_resource *wl_buffer)\r
+{\r
+       struct wayland_tbm_buffer *tbm_buffer  = NULL;\r
+\r
+       WL_TBM_RETURN_VAL_IF_FAIL(wl_buffer != NULL, 0);\r
+\r
+       if (wl_resource_instance_of(wl_buffer, &wl_buffer_interface,\r
+                                   &_wayland_tbm_buffer_impementation)) {\r
+               tbm_buffer = wl_resource_get_user_data(wl_buffer);\r
+               return tbm_buffer->flags;\r
+       }\r
+\r
+       return 0;\r
+}\r
+\r
+struct wayland_tbm_client_queue *\r
+wayland_tbm_server_client_queue_get(struct wayland_tbm_server *tbm_srv, struct wl_resource *wl_surface)\r
+{\r
+       struct wayland_tbm_client_queue *cqueue = NULL;\r
+       WL_TBM_RETURN_VAL_IF_FAIL(tbm_srv != NULL, NULL);\r
+       WL_TBM_RETURN_VAL_IF_FAIL(wl_surface != NULL, NULL);\r
+\r
+       wl_list_for_each(cqueue, &tbm_srv->cqueue_list, link) {\r
+               if (cqueue && cqueue->wl_surface == wl_surface)\r
+                       return cqueue;\r
+       }\r
+\r
+       return NULL;\r
+}\r
+\r
+void\r
+wayland_tbm_server_client_queue_activate(struct wayland_tbm_client_queue *cqueue, uint32_t usage)\r
+{\r
+       WL_TBM_RETURN_IF_FAIL(cqueue != NULL);\r
+       WL_TBM_RETURN_IF_FAIL(cqueue->wl_tbm_queue != NULL);\r
+\r
+       wl_tbm_queue_send_active(cqueue->wl_tbm_queue, usage);\r
+}\r
+\r
+void\r
+wayland_tbm_server_client_queue_deactivate(struct wayland_tbm_client_queue *cqueue)\r
+{\r
+       WL_TBM_RETURN_IF_FAIL(cqueue != NULL);\r
+       WL_TBM_RETURN_IF_FAIL(cqueue->wl_tbm_queue != NULL);\r
+\r
+       wl_tbm_queue_send_deactive(cqueue->wl_tbm_queue);\r
+}\r
+\r
+\r
+int\r
+_wayland_tbm_server_wl_tbm_queue_send_surface(struct wl_resource *wl_tbm_queue,\r
+                                       struct wl_resource *wl_buffer, tbm_surface_h surface,\r
+                                       uint32_t flags)\r
+{\r
+       tbm_surface_info_s info;\r
+       int num_buf;\r
+       int bufs[TBM_SURF_PLANE_MAX] = { -1, -1, -1, -1};\r
+       int is_fd = -1;\r
+       int ret = -1, i;\r
+\r
+       ret = tbm_surface_get_info(surface, &info);\r
+       if (ret != TBM_SURFACE_ERROR_NONE) {\r
+               WL_TBM_S_LOG("Failed to create buffer from surface\n");\r
+               return 0;\r
+       }\r
+\r
+       if (info.num_planes > 3) {\r
+               WL_TBM_S_LOG("invalid num_planes(%d)\n", info.num_planes);\r
+               return 0;\r
+       }\r
+\r
+       num_buf = tbm_surface_internal_get_num_bos(surface);\r
+       if (num_buf == 0) {\r
+               WL_TBM_S_LOG("surface doesn't have any bo.\n");\r
+               goto err;\r
+       }\r
+\r
+       for (i = 0; i < num_buf; i++) {\r
+               tbm_bo bo = tbm_surface_internal_get_bo(surface, i);\r
+               if (bo == NULL) {\r
+                       goto err;\r
+               }\r
+\r
+               /* try to get fd first */\r
+               if (is_fd == -1 || is_fd == 1) {\r
+                       bufs[i] = tbm_bo_export_fd(bo);\r
+                       if (bufs[i] >= 0)\r
+                               is_fd = 1;\r
+               }\r
+\r
+               /* if fail to get fd, try to get name second */\r
+               if (is_fd == -1 || is_fd == 0) {\r
+                       bufs[i] = tbm_bo_export(bo);\r
+                       if (bufs[i] > 0)\r
+                               is_fd = 0;\r
+               }\r
+\r
+               if (is_fd == -1 ||\r
+                   (is_fd == 1 && bufs[i] < 0) ||\r
+                   (is_fd == 0 && bufs[i] <= 0)) {\r
+                       WL_TBM_S_LOG("Failed to export(is_fd:%d, bufs:%d)\n", is_fd, bufs[i]);\r
+                       goto err;\r
+               }\r
+       }\r
+\r
+       if (is_fd == 1)\r
+               wl_tbm_queue_send_buffer_attached_with_fd(wl_tbm_queue,\r
+                               wl_buffer,\r
+                               info.width, info.height, info.format, info.num_planes,\r
+                               tbm_surface_internal_get_plane_bo_idx(surface, 0),\r
+                               info.planes[0].offset, info.planes[0].stride,\r
+                               tbm_surface_internal_get_plane_bo_idx(surface, 1),\r
+                               info.planes[1].offset, info.planes[1].stride,\r
+                               tbm_surface_internal_get_plane_bo_idx(surface, 2),\r
+                               info.planes[2].offset, info.planes[2].stride,\r
+                               flags, num_buf, bufs[0],\r
+                               (bufs[1] == -1) ? bufs[0] : bufs[1],\r
+                               (bufs[2] == -1) ? bufs[0] : bufs[2]);\r
+       else\r
+               wl_tbm_queue_send_buffer_attached_with_fd(wl_tbm_queue,\r
+                               wl_buffer,\r
+                               info.width, info.height, info.format, info.num_planes,\r
+                               tbm_surface_internal_get_plane_bo_idx(surface, 0),\r
+                               info.planes[0].offset, info.planes[0].stride,\r
+                               tbm_surface_internal_get_plane_bo_idx(surface, 1),\r
+                               info.planes[1].offset, info.planes[1].stride,\r
+                               tbm_surface_internal_get_plane_bo_idx(surface, 2),\r
+                               info.planes[2].offset, info.planes[2].stride,\r
+                               flags, num_buf, bufs[0],\r
+                               (bufs[1] == -1) ? bufs[0] : bufs[1],\r
+                               (bufs[2] == -1) ? bufs[0] : bufs[2]);\r
+\r
+\r
+       for (i = 0; i < TBM_SURF_PLANE_MAX; i++) {\r
+               if (is_fd == 1 && (bufs[i] >= 0))\r
+                       close(bufs[i]);\r
+       }\r
+\r
+       WL_TBM_S_LOG("Release wl_tbm_queue tbm_surface(%p).\n", surface);\r
+\r
+       return 1;\r
+err:\r
+       for (i = 0; i < TBM_SURF_PLANE_MAX; i++) {\r
+               if (is_fd == 1 && (bufs[i] >= 0))\r
+                       close(bufs[i]);\r
+       }\r
+\r
+       return 0;\r
+}\r
+\r
+int\r
+wayland_tbm_server_client_queue_export_buffer(struct wayland_tbm_client_queue *cqueue,\r
+                       tbm_surface_h surface, uint32_t flags,\r
+                       wayland_tbm_server_surface_destroy_cb destroy_cb, void *user_data)\r
+{\r
+       struct wl_resource *wl_tbm = NULL;\r
+       struct wayland_tbm_buffer *tbm_buffer = NULL;\r
+       struct wl_client *client = NULL;\r
+       void *data = NULL;\r
+\r
+       WL_TBM_RETURN_VAL_IF_FAIL(cqueue != NULL, 0);\r
+       WL_TBM_RETURN_VAL_IF_FAIL(cqueue->wl_tbm_queue != NULL, 0);\r
+       WL_TBM_RETURN_VAL_IF_FAIL(surface != NULL, 0);\r
+\r
+    /* return if the surface is already exported to the client on the cqueue */\r
+       tbm_surface_internal_get_user_data(surface, KEY_TBM_BUFFER, &data);\r
+       if (data != NULL) {\r
+               WL_TBM_S_LOG("WARNING...surface(%p) is already export\n", surface);\r
+               return 0;\r
+       }\r
+\r
+       wl_tbm = cqueue->wl_tbm;\r
+       client = wl_resource_get_client(cqueue->wl_tbm_queue);\r
+\r
+       tbm_surface_internal_ref(surface);\r
+       tbm_buffer = _wayland_tbm_server_tbm_buffer_create(wl_tbm, client, surface, 0, flags);\r
+       if (tbm_buffer == NULL) {\r
+               tbm_surface_internal_unref(surface);\r
+               return 0;\r
+       }\r
+\r
+       tbm_buffer->destroy_cb = destroy_cb;\r
+       tbm_buffer->user_data = user_data;\r
+\r
+       if(!_wayland_tbm_server_wl_tbm_queue_send_surface(cqueue->wl_tbm_queue,\r
+                               tbm_buffer->wl_buffer, surface, flags)) {\r
+               WL_TBM_S_LOG("Failed to send the surface to the wl_tbm_queue\n");\r
+               _wayland_tbm_server_tbm_buffer_destroy(tbm_buffer);\r
+               tbm_surface_internal_unref(surface);\r
+               return 0;\r
+       }\r
+\r
+       return 1;\r
+}\r
+\r
old mode 100644 (file)
new mode 100755 (executable)
index 530f6d6..461f2b5
@@ -1,83 +1,86 @@
-/*
-Copyright (C) 2015 Samsung Electronics co., Ltd. All Rights Reserved.
-
-Contact:
-      SooChan Lim <sc1.lim@samsung.com>,
-      Sangjin Lee <lsj119@samsung.com>,
-      Boram Park <boram1288.park@samsung.com>,
-      Changyeon Lee <cyeon.lee@samsung.com>
-
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the "Software"),
-to deal in the Software without restriction, including without limitation
-the rights to use, copy, modify, merge, publish, distribute, sublicense,
-and/or sell copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice (including the next
-paragraph) shall be included in all copies or substantial portions of the
-Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
-THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
-*/
-
-#ifndef WAYLAND_TBM_SERVER_H
-#define WAYLAND_TBM_SERVER_H
-
-#ifdef  __cplusplus
-extern "C" {
-#endif
-
-#include <wayland-server.h>
-#include <tbm_surface.h>
-#include <tbm_surface_queue.h>
-
-struct wayland_tbm_server;
-struct wayland_tbm_server_queue;
-
-struct wayland_tbm_server *
-wayland_tbm_server_init(struct wl_display *display,
-                       const char *device_name,
-                       int fd,
-                       uint32_t flags);
-
-void
-wayland_tbm_server_deinit(struct wayland_tbm_server *tbm_srv);
-
-void *
-wayland_tbm_server_get_bufmgr(struct wayland_tbm_server        *tbm_srv);
-
-tbm_surface_h
-wayland_tbm_server_get_surface(struct wayland_tbm_server       *tbm_srv,
-                              struct wl_resource *resource);
-
-struct wl_resource *
-wayland_tbm_server_get_resource(struct wayland_tbm_server *tbm_srv,
-                               tbm_surface_h surface);
-
-uint32_t
-wayland_tbm_server_get_flags(struct wayland_tbm_server *tbm_srv,
-                            struct wl_resource *resource);
-
-struct wayland_tbm_server_queue *
-wayland_tbm_server_create_queue(struct wayland_tbm_server *tbm_srv,
-                               tbm_surface_queue_h queue, uint32_t flags);
-
-
-int
-wayland_tbm_server_queue_set_surface(struct wayland_tbm_server_queue
-                                    *server_queue,
-                                    struct wl_resource *surface, uint32_t usage);
-
-
-#ifdef  __cplusplus
-}
-#endif
-
-#endif
+/*\r
+Copyright (C) 2015 Samsung Electronics co., Ltd. All Rights Reserved.\r
+\r
+Contact:\r
+      SooChan Lim <sc1.lim@samsung.com>,\r
+      Sangjin Lee <lsj119@samsung.com>,\r
+      Boram Park <boram1288.park@samsung.com>,\r
+      Changyeon Lee <cyeon.lee@samsung.com>\r
+\r
+Permission is hereby granted, free of charge, to any person obtaining a\r
+copy of this software and associated documentation files (the "Software"),\r
+to deal in the Software without restriction, including without limitation\r
+the rights to use, copy, modify, merge, publish, distribute, sublicense,\r
+and/or sell copies of the Software, and to permit persons to whom the\r
+Software is furnished to do so, subject to the following conditions:\r
+\r
+The above copyright notice and this permission notice (including the next\r
+paragraph) shall be included in all copies or substantial portions of the\r
+Software.\r
+\r
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL\r
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\r
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\r
+DEALINGS IN THE SOFTWARE.\r
+*/\r
+\r
+#ifndef WAYLAND_TBM_SERVER_H\r
+#define WAYLAND_TBM_SERVER_H\r
+\r
+#ifdef  __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+#include <wayland-server.h>\r
+#include <tbm_surface.h>\r
+#include <tbm_surface_queue.h>\r
+\r
+struct wayland_tbm_server;\r
+struct wayland_tbm_client_queue;\r
+\r
+typedef void (*wayland_tbm_server_surface_destroy_cb) (tbm_surface_h surface, void *data);\r
+\r
+struct wayland_tbm_server *\r
+wayland_tbm_server_init(struct wl_display *display,\r
+                       const char *device_name,\r
+                       int fd,\r
+                       uint32_t flags);\r
+\r
+void\r
+wayland_tbm_server_deinit(struct wayland_tbm_server *tbm_srv);\r
+\r
+void *\r
+wayland_tbm_server_get_bufmgr(struct wayland_tbm_server        *tbm_srv);\r
+\r
+tbm_surface_h\r
+wayland_tbm_server_get_surface(struct wayland_tbm_server *tbm_srv,\r
+                              struct wl_resource *wl_buffer);\r
+\r
+uint32_t\r
+wayland_tbm_server_get_buffer_flags(struct wayland_tbm_server *tbm_srv,\r
+                                       struct wl_resource *wl_buffer);\r
+\r
+struct wayland_tbm_client_queue *\r
+wayland_tbm_server_client_queue_get(struct wayland_tbm_server *tbm_srv,\r
+                                       struct wl_resource *wl_surface);\r
+\r
+void\r
+wayland_tbm_server_client_queue_activate(struct wayland_tbm_client_queue *client_queue,\r
+                                       uint32_t usage);\r
+\r
+void\r
+wayland_tbm_server_client_queue_deactivate(struct wayland_tbm_client_queue *client_queue);\r
+\r
+int\r
+wayland_tbm_server_client_queue_export_buffer(struct wayland_tbm_client_queue *client_queue,\r
+                       tbm_surface_h surface, uint32_t flags, wayland_tbm_server_surface_destroy_cb destroy_cb,\r
+                       void *user_data);\r
+\r
+#ifdef  __cplusplus\r
+}\r
+#endif\r
+\r
+#endif\r
index e5be06a..6d4e6a0 100644 (file)
@@ -3,7 +3,8 @@ TESTS =                         \
        tbm-client-test \
        tbm-subcomp-test \
        tbm-server-queue-test   \
-       tbm-client-queue-test
+       tbm-client-queue-test   \
+       tbm-leak-test
 
 
 #bin_PROGRAMS = $(TESTS)
@@ -39,3 +40,7 @@ tbm_server_queue_test_SOURCES = $(PROTOCOL_SOURCES) tbm-server-queue-test.c
 tbm_client_queue_test_LDADD = $(CLIENT_TEST_LDADD)
 tbm_client_queue_test_CFLAGS = $(CLIENT_TEST_CFLAGS)
 tbm_client_queue_test_SOURCES = $(PROTOCOL_SOURCES) tbm-client-queue-test.c
+
+tbm_leak_test_LDADD = $(CLIENT_TEST_LDADD)
+tbm_leak_test_CFLAGS = $(CLIENT_TEST_CFLAGS)
+tbm_leak_test_SOURCES = $(PROTOCOL_SOURCES) tbm-leak-test.c
index 989560c..7fe9b93 100644 (file)
@@ -23,6 +23,8 @@ typedef struct {
        tbm_surface_queue_h surface_queue;
 
        int try_draw;
+       int exit;
+       int count;
 } AppInfoClient;
 
 typedef struct {
@@ -46,6 +48,18 @@ _create_surface_and_queue(AppInfoClient *app)
        return;
 }
 
+static void
+_destroy_surface_and_queue(AppInfoClient *app)
+{
+       tbm_surface_queue_destroy(app->surface_queue);
+       wl_test_surface_destroy(app->surface);
+
+       WL_APP_C_LOG("surface:%p, surface_queue:%p\n", app->surface,
+                    app->surface_queue);
+
+       return;
+}
+
 static const int key_app_buffer;
 
 static struct wl_buffer *
@@ -113,6 +127,11 @@ _drawing_surface(AppInfoClient *app)
        struct wl_buffer *wl_buffer;
        struct wl_callback *wl_callback;
 
+       app->count++;
+       if (app->count == 10) {
+               app->exit = 1;
+       }
+
        if (!tbm_surface_queue_can_dequeue(surface_queue, 0)) {
                WL_APP_C_LOG("Wait free_buffer\n");
                app->try_draw = 1;
@@ -192,6 +211,7 @@ main(int argc, char *argv[])
        const char *dpy_name = NULL;
        const static char *default_dpy_name = "queue";
        int ret = 0;
+       tbm_bufmgr bufmgr = NULL;
 
        if (argc > 1) {
                dpy_name = argv[1];
@@ -218,14 +238,22 @@ main(int argc, char *argv[])
                WL_APP_C_LOG("fail to wayland_tbm_client_init()\n");
                goto finish;
        }
+       bufmgr = tbm_bufmgr_init(-1);
+       tbm_bufmgr_debug_show(bufmgr);
 
        _create_surface_and_queue(&gApp);
        _drawing_surface(&gApp);
-       while (ret >= 0) {
+       while (ret >= 0 && gApp.exit == 0) {
                ret = wl_display_dispatch(dpy);
                if (gApp.try_draw)
                        _drawing_surface(&gApp);
        }
+
+       tbm_bufmgr_debug_show(bufmgr);
 finish:
+       if (gApp.surface)
+               _destroy_surface_and_queue(&gApp);
+       if (bufmgr)
+               tbm_bufmgr_debug_show(bufmgr);
        return 1;
 }
diff --git a/test/tbm-leak-test.c b/test/tbm-leak-test.c
new file mode 100644 (file)
index 0000000..9899e51
--- /dev/null
@@ -0,0 +1,299 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#define WL_HIDE_DEPRECATED
+#include <wayland-client.h>
+#include <wayland-tbm-client.h>
+#include <wayland-tbm-int.h>
+
+#include <tbm_surface.h>
+#include <tbm_surface_queue.h>
+#include <tbm_surface_internal.h>
+
+#include "wayland-tbm-test-client-protocol.h"
+
+#define WL_APP_LOG(fmt, ...)   fprintf (stderr, "[CLIENT(%d):%s] " fmt, getpid(), __func__, ##__VA_ARGS__)
+#define WL_APP_CHECK(cond) {\
+    if (!(cond)) {\
+        WL_APP_LOG ("[%s:%d] : '%s' failed.\n", __FUNCTION__,__LINE__, #cond);\
+    }\
+}
+
+typedef struct {
+       struct wl_display *dpy;
+       struct wayland_tbm_client *tbm_client;
+       struct wl_tbm_test *wl_tbm_test;
+       tbm_bufmgr bufmgr;
+} AppInfoClient;
+
+static AppInfoClient gApp;
+
+static void
+_wl_registry_global_cb(void *data,
+                      struct wl_registry *wl_registry,
+                      uint32_t name,
+                      const char *interface,
+                      uint32_t version)
+{
+       AppInfoClient *app = (AppInfoClient *)data;
+
+       if (!strcmp(interface, "wl_tbm_test")) {
+               WL_APP_LOG("bind %s", interface);
+               app->wl_tbm_test = wl_registry_bind(wl_registry, name,
+                                                   &wl_tbm_test_interface, 1);
+       }
+}
+
+static void
+_wl_registry_global_remove_cb(void *data,
+                             struct wl_registry *wl_registry,
+                             uint32_t name)
+{
+}
+
+static const struct wl_registry_listener wl_registry_impl = {
+       _wl_registry_global_cb,
+       _wl_registry_global_remove_cb,
+};
+
+static int test_01(AppInfoClient* app);
+static int test_02(AppInfoClient* app);
+static int test_03(AppInfoClient* app);
+static int test_04(AppInfoClient* app);
+static int test_05(AppInfoClient* app);
+static int test_06(AppInfoClient* app);
+
+int
+main(int argc, char *argv[])
+{
+       struct wl_registry *registry;
+       const char *dpy_name = NULL;
+       const static char *default_dpy_name = "queue";
+
+       if (argc > 1) {
+               dpy_name = argv[1];
+       } else {
+               dpy_name = default_dpy_name;
+       }
+
+       gApp.dpy = wl_display_connect(dpy_name);
+       if (!gApp.dpy) {
+               printf("[APP] failed to connect server\n");
+               return -1;
+       }
+
+       registry = wl_display_get_registry(gApp.dpy);
+       wl_registry_add_listener(registry, &wl_registry_impl, &gApp);
+       wl_display_roundtrip(gApp.dpy);
+       if (gApp.wl_tbm_test == NULL) {
+               WL_APP_LOG("fail to bind::wl_tbm_test");
+               return 0;
+       }
+
+       gApp.tbm_client = wayland_tbm_client_init(gApp.dpy);
+       if (!gApp.tbm_client) {
+               WL_APP_LOG("fail to wayland_tbm_client_init()\n");
+               goto finish;
+       }
+       gApp.bufmgr = tbm_bufmgr_init(-1);
+       tbm_bufmgr_debug_show(gApp.bufmgr);
+
+       test_01(&gApp);
+       test_02(&gApp);
+       test_03(&gApp);
+       test_04(&gApp);
+       test_05(&gApp);
+       test_06(&gApp);
+
+
+finish:
+       if (gApp.bufmgr) {
+               tbm_bufmgr_debug_show(gApp.bufmgr);
+               tbm_bufmgr_deinit(gApp.bufmgr);
+       }
+
+       return 1;
+}
+static int
+print_mem_info(AppInfoClient* app, char *str)
+{
+       WL_APP_LOG("## %s ##\n", str);
+       tbm_bufmgr_debug_show(app->bufmgr);
+       WL_APP_LOG("\n");
+
+       return 0;
+}
+
+static int
+test_01(AppInfoClient* app)
+{
+       struct wl_test_surface* surface;
+       tbm_surface_queue_h surface_queue;
+       tbm_surface_h buffer = NULL;
+
+       surface = wl_tbm_test_create_surface(app->wl_tbm_test);
+       surface_queue = wayland_tbm_client_create_surface_queue(app->tbm_client,
+                                       (struct wl_surface*)surface,
+                                       3, 100, 100, TBM_FORMAT_ABGR8888);
+
+       tbm_surface_queue_dequeue(surface_queue, &buffer);
+       WL_APP_CHECK(buffer != NULL);
+       tbm_surface_queue_enqueue(surface_queue, buffer);
+       tbm_surface_queue_dequeue(surface_queue, &buffer);
+       WL_APP_CHECK(buffer != NULL);
+       tbm_surface_queue_enqueue(surface_queue, buffer);
+
+       tbm_surface_queue_destroy(surface_queue);
+       wl_test_surface_destroy(surface);
+       wl_display_roundtrip(app->dpy);
+
+       print_mem_info(app, "TEST_01");
+
+       return 0;
+}
+
+static int
+test_02(AppInfoClient* app)
+{
+       struct wl_test_surface* surface;
+       tbm_surface_queue_h surface_queue;
+       tbm_surface_h buffer = NULL;
+
+       surface = wl_tbm_test_create_surface(app->wl_tbm_test);
+       surface_queue = wayland_tbm_client_create_surface_queue(app->tbm_client,
+                                       (struct wl_surface*)surface,
+                                       3, 100, 100, TBM_FORMAT_ABGR8888);
+
+       tbm_surface_queue_dequeue(surface_queue, &buffer);
+       WL_APP_CHECK(buffer != NULL);
+       tbm_surface_queue_dequeue(surface_queue, &buffer);
+       WL_APP_CHECK(buffer != NULL);
+
+       tbm_surface_queue_destroy(surface_queue);
+       wl_test_surface_destroy(surface);
+       wl_display_roundtrip(app->dpy);
+
+       print_mem_info(app, "TEST_02");
+
+       return 0;
+}
+
+static int
+test_03(AppInfoClient* app)
+{
+       struct wl_test_surface* surface;
+       tbm_surface_queue_h surface_queue;
+       tbm_surface_h buffer = NULL;
+
+       surface = wl_tbm_test_create_surface(app->wl_tbm_test);
+       surface_queue = wayland_tbm_client_create_surface_queue(app->tbm_client,
+                                       (struct wl_surface*)surface,
+                                       3, 100, 100, TBM_FORMAT_ABGR8888);
+
+       tbm_surface_queue_dequeue(surface_queue, &buffer);
+       WL_APP_CHECK(buffer != NULL);
+       tbm_surface_queue_dequeue(surface_queue, &buffer);
+       WL_APP_CHECK(buffer != NULL);
+
+       tbm_surface_queue_reset(surface_queue, 200, 200, TBM_FORMAT_ABGR8888);
+
+       tbm_surface_queue_destroy(surface_queue);
+       wl_test_surface_destroy(surface);
+       wl_display_roundtrip(app->dpy);
+
+       print_mem_info(app, "TEST_03");
+
+       return 0;
+}
+
+static int
+test_04(AppInfoClient* app)
+{
+       struct wl_test_surface* surface;
+       tbm_surface_queue_h surface_queue;
+       tbm_surface_h buffer = NULL;
+
+       surface = wl_tbm_test_create_surface(app->wl_tbm_test);
+       surface_queue = wayland_tbm_client_create_surface_queue(app->tbm_client,
+                                       (struct wl_surface*)surface,
+                                       3, 100, 100, TBM_FORMAT_ABGR8888);
+
+       tbm_surface_queue_dequeue(surface_queue, &buffer);
+       WL_APP_CHECK(buffer != NULL);
+       tbm_surface_queue_dequeue(surface_queue, &buffer);
+       WL_APP_CHECK(buffer != NULL);
+
+       tbm_surface_queue_reset(surface_queue, 200, 200, TBM_FORMAT_ABGR8888);
+       tbm_surface_queue_dequeue(surface_queue, &buffer);
+       WL_APP_CHECK(buffer != NULL);
+       tbm_surface_queue_enqueue(surface_queue, buffer);
+       tbm_surface_queue_dequeue(surface_queue, &buffer);
+       WL_APP_CHECK(buffer != NULL);
+       tbm_surface_internal_ref(buffer);
+
+       tbm_surface_queue_destroy(surface_queue);
+       wl_test_surface_destroy(surface);
+       wl_display_roundtrip(app->dpy);
+
+       print_mem_info(app, "TEST_04");
+       tbm_surface_internal_unref(buffer);
+       print_mem_info(app, "TEST_04_final");
+
+       return 0;
+}
+
+static int
+test_05(AppInfoClient* app)
+{
+       struct wl_test_surface* surface;
+       tbm_surface_queue_h surface_queue;
+       tbm_surface_h buffer = NULL;
+       struct wl_buffer* wl_buffer;
+
+       surface = wl_tbm_test_create_surface(app->wl_tbm_test);
+       surface_queue = wayland_tbm_client_create_surface_queue(app->tbm_client,
+                                       (struct wl_surface*)surface,
+                                       3, 100, 100, TBM_FORMAT_ABGR8888);
+
+       tbm_surface_queue_dequeue(surface_queue, &buffer);
+       WL_APP_CHECK(buffer != NULL);
+
+       wl_buffer = wayland_tbm_client_create_buffer(app->tbm_client, buffer);
+       wl_test_surface_attach(surface, wl_buffer);
+       wl_display_roundtrip(app->dpy);
+
+       tbm_surface_queue_destroy(surface_queue);
+       wl_test_surface_destroy(surface);
+       wl_display_roundtrip(app->dpy);
+
+       print_mem_info(app, "TEST_05");
+
+       return 0;
+}
+
+static int
+test_06(AppInfoClient* app)
+{
+       struct wl_test_surface* surface;
+       tbm_surface_queue_h surface_queue;
+
+       WL_APP_LOG("\n");
+       surface = wl_tbm_test_create_surface(app->wl_tbm_test);
+       surface_queue = wayland_tbm_client_create_surface_queue(app->tbm_client,
+                                       (struct wl_surface*)surface,
+                                       3, 100, 100, TBM_FORMAT_ABGR8888);
+
+       wl_tbm_test_set_active_queue(app->wl_tbm_test, surface);
+       wl_display_roundtrip(app->dpy);
+
+       tbm_surface_queue_destroy(surface_queue);
+       wl_test_surface_destroy(surface);
+       wl_display_roundtrip(app->dpy);
+
+       print_mem_info(app, "TEST_06");
+
+       return 0;
+}
+
index d93e498..fc3156a 100644 (file)
@@ -40,6 +40,8 @@ struct _AppInfo {
        uint32_t update_count;
 
        tbm_surface_h front, back;
+
+       int test_mode;
 };
 
 struct _AppSurface {
@@ -59,7 +61,22 @@ static void wl_tbm_test_idle_cb(void *data);
 static void
 _wl_test_surface_destroy(struct wl_resource *resource)
 {
+       AppSurface *app_surface = wl_resource_get_user_data(resource);
+       if (!app_surface) {
+               SERVER_LOG("resource:%p fail get user_data\n", resource);
+               return;
+       }
+
+       AppInfo *app = app_surface->app;
        SERVER_LOG("resource:%p\n", resource);
+
+       wl_list_remove(&app_surface->link);
+       wl_resource_set_user_data(resource, NULL);
+
+       if (app_surface == app->active_surface)
+               app->active_surface = NULL;
+
+       free(app_surface);
 }
 
 
@@ -67,7 +84,7 @@ static void
 _wl_test_surface_destroy_cb(struct wl_client *client,
                            struct wl_resource *resource)
 {
-       _wl_test_surface_destroy(resource);
+       wl_resource_destroy(resource);
 }
 
 static void
@@ -138,8 +155,24 @@ _wl_tbm_test_create_surface(struct wl_client *client,
        SERVER_LOG("Add surface:%p\n", test_surface);
 }
 
+static void
+_wl_tbm_test_set_active_surface(struct wl_client *client,
+                           struct wl_resource *resource,
+                           struct wl_resource *surface)
+{
+       AppInfo *app = (AppInfo *)wl_resource_get_user_data(resource);
+       AppSurface *app_surface = (AppSurface *)wl_resource_get_user_data(surface);
+
+       wayland_tbm_server_queue_set_surface(app->server_queue,
+                       surface, 0x1111);
+       app->active_surface = app_surface;
+
+       SERVER_LOG("Active surface:%p\n", app_surface);
+}
+
 static const struct wl_tbm_test_interface wl_tbm_test_impl = {
-       _wl_tbm_test_create_surface
+       _wl_tbm_test_create_surface,
+       _wl_tbm_test_set_active_surface
 };
 
 static void
@@ -256,22 +289,24 @@ wl_tbm_test_idle_cb(void *data)
        tbm_surface_queue_enqueue(app->scanout_queue, back);
 
 present:
-       app->update_count++;
-       if (!(app->update_count % 5)) {
-               SERVER_LOG("MODE_CHANGE active:%p\n", app->active_surface);
-               if (app->active_surface) {
-                       wayland_tbm_server_queue_set_surface(app->server_queue,
-                                                            NULL,
-                                                            0);
-                       app->active_surface = NULL;
-               } else {
-                       if (!wl_list_empty(&app->list_surface)) {
-                               app_surface = wl_container_of(app->list_surface.next, app_surface, link);
-                               if (wayland_tbm_server_queue_set_surface(app->server_queue,
-                                               app_surface->resource, 1)) {
-                                       SERVER_LOG("!! ERROR wayland_tbm_server_queue_set_surface\n");
-                               } else {
-                                       app->active_surface = app_surface;
+       if (app->test_mode == 1) {
+               app->update_count++;
+               if (!(app->update_count % 5)) {
+                       SERVER_LOG("MODE_CHANGE active:%p\n", app->active_surface);
+                       if (app->active_surface) {
+                               wayland_tbm_server_queue_set_surface(app->server_queue,
+                                                                    NULL,
+                                                                    0);
+                               app->active_surface = NULL;
+                       } else {
+                               if (!wl_list_empty(&app->list_surface)) {
+                                       app_surface = wl_container_of(app->list_surface.next, app_surface, link);
+                                       if (wayland_tbm_server_queue_set_surface(app->server_queue,
+                                                       app_surface->resource, 1)) {
+                                               SERVER_LOG("!! ERROR wayland_tbm_server_queue_set_surface\n");
+                                       } else {
+                                               app->active_surface = app_surface;
+                                       }
                                }
                        }
                }
@@ -299,6 +334,11 @@ main(int argc, char *argv[])
 
        const char *dpy_name = "queue";
 
+       if (argc > 1) {
+               SERVER_LOG("TEST_MODE: %s\n", argv[1]);
+               gApp.test_mode = atoi(argv[1]);
+       }
+
        dpy = wl_display_create();
        if (!dpy) {
                printf("[SRV] failed to create display\n");
index 333c89d..82e27d6 100644 (file)
@@ -46,8 +46,10 @@ extern const struct wl_interface wl_tbm_test_interface;
 extern const struct wl_interface wl_test_surface_interface;
 
 #define WL_TBM_TEST_CREATE_SURFACE     0
+#define WL_TBM_TEST_SET_ACTIVE_QUEUE   1
 
 #define WL_TBM_TEST_CREATE_SURFACE_SINCE_VERSION       1
+#define WL_TBM_TEST_SET_ACTIVE_QUEUE_SINCE_VERSION     1
 
 static inline void
 wl_tbm_test_set_user_data(struct wl_tbm_test *wl_tbm_test, void *user_data)
@@ -73,11 +75,18 @@ wl_tbm_test_create_surface(struct wl_tbm_test *wl_tbm_test)
        struct wl_proxy *surface;
 
        surface = wl_proxy_marshal_constructor((struct wl_proxy *) wl_tbm_test,
-                                              WL_TBM_TEST_CREATE_SURFACE, &wl_test_surface_interface, NULL);
+                        WL_TBM_TEST_CREATE_SURFACE, &wl_test_surface_interface, NULL);
 
        return (struct wl_test_surface *) surface;
 }
 
+static inline void
+wl_tbm_test_set_active_queue(struct wl_tbm_test *wl_tbm_test, struct wl_test_surface *surface)
+{
+       wl_proxy_marshal((struct wl_proxy *) wl_tbm_test,
+                        WL_TBM_TEST_SET_ACTIVE_QUEUE, surface);
+}
+
 #define WL_TEST_SURFACE_DESTROY        0
 #define WL_TEST_SURFACE_ATTACH 1
 #define WL_TEST_SURFACE_FRAME  2
@@ -87,8 +96,7 @@ wl_tbm_test_create_surface(struct wl_tbm_test *wl_tbm_test)
 #define WL_TEST_SURFACE_FRAME_SINCE_VERSION    1
 
 static inline void
-wl_test_surface_set_user_data(struct wl_test_surface *wl_test_surface,
-                             void *user_data)
+wl_test_surface_set_user_data(struct wl_test_surface *wl_test_surface, void *user_data)
 {
        wl_proxy_set_user_data((struct wl_proxy *) wl_test_surface, user_data);
 }
@@ -109,8 +117,7 @@ wl_test_surface_destroy(struct wl_test_surface *wl_test_surface)
 }
 
 static inline void
-wl_test_surface_attach(struct wl_test_surface *wl_test_surface,
-                      struct wl_buffer *buffer)
+wl_test_surface_attach(struct wl_test_surface *wl_test_surface, struct wl_buffer *buffer)
 {
        wl_proxy_marshal((struct wl_proxy *) wl_test_surface,
                         WL_TEST_SURFACE_ATTACH, buffer);
@@ -122,7 +129,7 @@ wl_test_surface_frame(struct wl_test_surface *wl_test_surface)
        struct wl_proxy *callback;
 
        callback = wl_proxy_marshal_constructor((struct wl_proxy *) wl_test_surface,
-                                               WL_TEST_SURFACE_FRAME, &wl_callback_interface, NULL);
+                        WL_TEST_SURFACE_FRAME, &wl_callback_interface, NULL);
 
        return (struct wl_callback *) callback;
 }
index 10ba05d..a834071 100644 (file)
@@ -33,24 +33,26 @@ extern const struct wl_interface wl_test_surface_interface;
 
 static const struct wl_interface *types[] = {
        &wl_test_surface_interface,
+       &wl_test_surface_interface,
        &wl_buffer_interface,
        &wl_callback_interface,
 };
 
 static const struct wl_message wl_tbm_test_requests[] = {
        { "create_surface", "n", types + 0 },
+       { "set_active_queue", "o", types + 1 },
 };
 
 WL_EXPORT const struct wl_interface wl_tbm_test_interface = {
        "wl_tbm_test", 1,
-       1, wl_tbm_test_requests,
+       2, wl_tbm_test_requests,
        0, NULL,
 };
 
 static const struct wl_message wl_test_surface_requests[] = {
        { "destroy", "", types + 0 },
-       { "attach", "o", types + 1 },
-       { "frame", "n", types + 2 },
+       { "attach", "o", types + 2 },
+       { "frame", "n", types + 3 },
 };
 
 WL_EXPORT const struct wl_interface wl_test_surface_interface = {
index d5eaaad..13d8d84 100644 (file)
@@ -53,6 +53,13 @@ struct wl_tbm_test_interface {
        void (*create_surface)(struct wl_client *client,
                               struct wl_resource *resource,
                               uint32_t surface);
+       /**
+        * set_active_queue - (none)
+        * @surface: (none)
+        */
+       void (*set_active_queue)(struct wl_client *client,
+                                struct wl_resource *resource,
+                                struct wl_resource *surface);
 };
 
 
index 85f47d3..be1cf89 100644 (file)
@@ -1,45 +1,48 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<protocol name="tbm_test">
-
-  <copyright>
-    Copyright 2015 Samsung Electronics co., Ltd. All Rights Reserved.
-
-    Permission to use, copy, modify, distribute, and sell this
-    software and its documentation for any purpose is hereby granted
-    without fee, provided that\n the above copyright notice appear in
-    all copies and that both that copyright notice and this permission
-    notice appear in supporting documentation, and that the name of
-    the copyright holders not be used in advertising or publicity
-    pertaining to distribution of the software without specific,
-    written prior permission.  The copyright holders make no
-    representations about the suitability of this software for any
-    purpose.  It is provided "as is" without express or implied
-    warranty.
-
-    THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
-    SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
-    FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
-    SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
-    AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
-    ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
-    THIS SOFTWARE.
-  </copyright>
-
-  <interface name="wl_tbm_test" version="1">
-       <request name="create_surface">
-               <arg name="surface" type="new_id" interface="wl_test_surface"/>
-       </request>
-  </interface>
-
-  <interface name="wl_test_surface" version="1">
-       <request name="destroy" type="destructor">
-       </request>
-       <request name="attach">
-               <arg name="buffer" type="object" interface="wl_buffer"/>
-       </request>
-    <request name="frame">
-      <arg name="callback" type="new_id" interface="wl_callback"/>
-    </request>
-  </interface>
-</protocol>
+<?xml version="1.0" encoding="UTF-8"?>\r
+<protocol name="tbm_test">\r
+\r
+  <copyright>\r
+    Copyright 2015 Samsung Electronics co., Ltd. All Rights Reserved.\r
+\r
+    Permission to use, copy, modify, distribute, and sell this\r
+    software and its documentation for any purpose is hereby granted\r
+    without fee, provided that\n the above copyright notice appear in\r
+    all copies and that both that copyright notice and this permission\r
+    notice appear in supporting documentation, and that the name of\r
+    the copyright holders not be used in advertising or publicity\r
+    pertaining to distribution of the software without specific,\r
+    written prior permission.  The copyright holders make no\r
+    representations about the suitability of this software for any\r
+    purpose.  It is provided "as is" without express or implied\r
+    warranty.\r
+\r
+    THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS\r
+    SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND\r
+    FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY\r
+    SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\r
+    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN\r
+    AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,\r
+    ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF\r
+    THIS SOFTWARE.\r
+  </copyright>\r
+\r
+  <interface name="wl_tbm_test" version="1">\r
+       <request name="create_surface">\r
+               <arg name="surface" type="new_id" interface="wl_test_surface"/>\r
+       </request>\r
+       <request name="set_active_queue">\r
+               <arg name="surface" type="object" interface="wl_test_surface"/>\r
+       </request>\r
+  </interface>\r
+\r
+  <interface name="wl_test_surface" version="1">\r
+       <request name="destroy" type="destructor">\r
+       </request>\r
+       <request name="attach">\r
+               <arg name="buffer" type="object" interface="wl_buffer"/>\r
+       </request>\r
+    <request name="frame">\r
+      <arg name="callback" type="new_id" interface="wl_callback"/>\r
+    </request>\r
+  </interface>\r
+</protocol>\r