Add user_data for find tbm_surface and sample app 08/85408/2
authorSangjin Lee <lsj119@samsung.com>
Wed, 24 Aug 2016 10:19:00 +0000 (19:19 +0900)
committerSooChan Lim <sc1.lim@samsung.com>
Thu, 25 Aug 2016 06:29:01 +0000 (23:29 -0700)
Change-Id: I572c388fc84a6a8b7e78338544936df06e73ba3f

src/wayland-tbm-server.c
src/wayland-tbm-server.h
test/Makefile.am
test/tbm-client-remote-consumer-test.c [new file with mode: 0644]
test/tbm-client-remote-provider-test.c [new file with mode: 0644]
test/tbm-server-queue-test.c
test/tbm-server-remote-test.c [new file with mode: 0644]
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 88f628e..8efe6eb 100644 (file)
@@ -70,6 +70,7 @@ struct wayland_tbm_server {
 
 struct wayland_tbm_buffer {
        struct wl_resource *wl_buffer;
+       struct wl_resource *wl_tbm;
        tbm_surface_h surface;
        int flags;
        struct wl_client *client;
@@ -78,6 +79,7 @@ struct wayland_tbm_buffer {
        void *user_data;
 
        struct wl_list link;
+       struct wl_list link_ref;        /*link to same tbm_surface_h*/
 };
 
 struct wayland_tbm_client_resource {
@@ -97,6 +99,53 @@ struct wayland_tbm_client_queue {
        struct wl_list link;
 };
 
+struct wayland_tbm_user_data {
+       struct wl_list wayland_tbm_buffer_list;
+};
+
+static void
+_wayland_tbm_server_free_user_data(void *user_data)
+{
+       struct wayland_tbm_user_data *ud = user_data;
+
+       //check validation and report
+       if (!wl_list_empty(&ud->wayland_tbm_buffer_list)) {
+               struct wayland_tbm_buffer *pos, *tmp;
+               wl_list_for_each_safe(pos, tmp, &ud->wayland_tbm_buffer_list, link_ref) {
+                       WL_TBM_S_LOG("Error: wl_buffer(%p) still alive tbm_surface:%p\n",
+                                               pos->wl_buffer, pos->surface);
+
+                       pos->surface = NULL;
+                       wl_list_remove(&pos->link_ref);
+               }
+       }
+
+       free(user_data);
+}
+
+static struct wayland_tbm_user_data *
+_wayland_tbm_server_get_user_data(tbm_surface_h tbm_surface)
+{
+       static const int key_ud;
+       struct wayland_tbm_user_data *ud = NULL;
+
+       tbm_surface_internal_get_user_data(tbm_surface,
+                                       (unsigned long)&key_ud,
+                                       (void**)&ud);
+       if (!ud) {
+               ud = calloc(1, sizeof(struct wayland_tbm_user_data));
+               tbm_surface_internal_add_user_data(tbm_surface,
+                                                       (unsigned long)&key_ud,
+                                                       _wayland_tbm_server_free_user_data);
+               tbm_surface_internal_set_user_data(tbm_surface,
+                                                       (unsigned long)&key_ud,
+                                                       (void*)ud);
+               wl_list_init(&ud->wayland_tbm_buffer_list);
+       }
+
+       return ud;
+}
+
 static void
 _wayland_tbm_server_buffer_destory(struct wl_resource *wl_buffer)
 {
@@ -114,7 +163,7 @@ _wayland_tbm_server_buffer_destory(struct wl_resource *wl_buffer)
                tbm_buffer->destroy_cb(tbm_buffer->surface, tbm_buffer->user_data);
 
        tbm_surface_internal_set_debug_data(tbm_buffer->surface, "id", NULL);
-
+       wl_list_remove(&tbm_buffer->link_ref);
        tbm_surface_internal_unref(tbm_buffer->surface);
        free(tbm_buffer);
 }
@@ -142,13 +191,17 @@ _wayland_tbm_server_tbm_buffer_create(struct wl_resource *wl_tbm,
        struct wayland_tbm_server *tbm_srv = wl_resource_get_user_data(wl_tbm);
        struct wayland_tbm_client_resource *c_res = NULL, *tmp_res = NULL;
        struct wayland_tbm_buffer *tbm_buffer;
+       struct wayland_tbm_user_data *ud;
        struct wl_client *wl_client;
 
+       ud = _wayland_tbm_server_get_user_data(surface);
+
        tbm_buffer = calloc(1, sizeof * tbm_buffer);
        if (tbm_buffer == NULL) {
                WL_TBM_S_LOG("Error. fail to allocate a tbm_buffer.\n");
                return NULL;
        }
+       wl_list_init(&tbm_buffer->link_ref);
 
        wl_client = wl_resource_get_client(wl_tbm);
 
@@ -160,6 +213,7 @@ _wayland_tbm_server_tbm_buffer_create(struct wl_resource *wl_tbm,
                return NULL;
        }
 
+       wl_list_insert(&ud->wayland_tbm_buffer_list, &tbm_buffer->link_ref);
        wl_resource_set_implementation(tbm_buffer->wl_buffer,
                                       (void (**)(void)) &_wayland_tbm_buffer_impementation,
                                       tbm_buffer, _wayland_tbm_server_buffer_destory);
@@ -167,6 +221,7 @@ _wayland_tbm_server_tbm_buffer_create(struct wl_resource *wl_tbm,
        tbm_buffer->flags = flags;
        tbm_buffer->surface = surface;
        tbm_buffer->client = wl_client;
+       tbm_buffer->wl_tbm = wl_tbm;
 
        /* set the debug_pid to the surface for debugging */
        if (!wl_list_empty(&tbm_srv->cresource_list)) {
@@ -902,6 +957,25 @@ wayland_tbm_server_export_buffer(struct wl_resource *wl_tbm, tbm_surface_h surfa
        return tbm_buffer->wl_buffer;
 }
 
+struct wl_resource *
+wayland_tbm_server_get_remote_buffer(struct wl_resource *wl_buffer, struct wl_resource *wl_tbm)
+{
+       struct wayland_tbm_user_data *ud;
+       struct wayland_tbm_buffer *pos;
+       tbm_surface_h tbm_surface;
+
+       tbm_surface = wayland_tbm_server_get_surface(NULL, wl_buffer);
+       WL_TBM_RETURN_VAL_IF_FAIL(tbm_surface != NULL, NULL);
+
+       ud = _wayland_tbm_server_get_user_data(tbm_surface);
+       wl_list_for_each(pos, &ud->wayland_tbm_buffer_list, link_ref) {
+               if (pos->wl_tbm == wl_tbm)
+                       return pos->wl_buffer;
+       }
+
+       return (struct wl_resource*)NULL;
+}
+
 struct wayland_tbm_client_queue *
 wayland_tbm_server_client_queue_get(struct wayland_tbm_server *tbm_srv, struct wl_resource *wl_surface)
 {
index ad67717..8089728 100644 (file)
@@ -63,6 +63,12 @@ uint32_t
 wayland_tbm_server_get_buffer_flags(struct wayland_tbm_server *tbm_srv,
                                        struct wl_resource *wl_buffer);
 
+struct wl_resource *
+wayland_tbm_server_export_buffer(struct wl_resource *wl_tbm, tbm_surface_h surface);
+
+struct wl_resource *
+wayland_tbm_server_get_remote_buffer(struct wl_resource *wl_buffer, struct wl_resource *wl_tbm);
+
 struct wayland_tbm_client_queue *
 wayland_tbm_server_client_queue_get(struct wayland_tbm_server *tbm_srv,
                                        struct wl_resource *wl_surface);
index 6d4e6a0..0bcbd41 100644 (file)
@@ -4,16 +4,19 @@ TESTS =                       \
        tbm-subcomp-test \
        tbm-server-queue-test   \
        tbm-client-queue-test   \
-       tbm-leak-test
+       tbm-leak-test  \
+       tbm-server-remote-test \
+       tbm-client-remote-provider-test \
+       tbm-client-remote-consumer-test
 
 
 #bin_PROGRAMS = $(TESTS)
 #check_PROGRAMS = $(TESTS)
 noinst_PROGRAMS = $(TESTS)
 
-SERVER_TEST_CFLAGS = -I$(top_srcdir)/src/ $(AM_CFLAGS) $(WL_TBM_SERVER_CFLAGS)
+SERVER_TEST_CFLAGS = -I$(top_srcdir)/src/ $(AM_CFLAGS) $(WL_TBM_COMMON_CFLAGS) $(WL_TBM_SERVER_CFLAGS)
 SERVER_TEST_LDADD = ../src/libwayland-tbm-server.la $(WL_TBM_COMMON_LIBS) $(WL_TBM_SERVER_LIBS)
-CLIENT_TEST_CFLAGS = -I$(top_srcdir)/src/ $(AM_CFLAGS) $(WL_TBM_CLIENT_CFLAGS)
+CLIENT_TEST_CFLAGS = -I$(top_srcdir)/src/ $(AM_CFLAGS) $(WL_TBM_COMMON_CFLAGS) $(WL_TBM_CLIENT_CFLAGS)
 CLIENT_TEST_LDADD = ../src/libwayland-tbm-client.la $(WL_TBM_COMMON_LIBS) $(WL_TBM_CLIENT_LIBS)
 
 PROTOCOL_SOURCES =     \
@@ -44,3 +47,15 @@ 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
+
+tbm_server_remote_test_LDADD = $(SERVER_TEST_LDADD)
+tbm_server_remote_test_CFLAGS = $(SERVER_TEST_CFLAGS)
+tbm_server_remote_test_SOURCES = $(PROTOCOL_SOURCES) tbm-server-remote-test.c
+
+tbm_client_remote_provider_test_LDADD = $(CLIENT_TEST_LDADD)
+tbm_client_remote_provider_test_CFLAGS = $(CLIENT_TEST_CFLAGS)
+tbm_client_remote_provider_test_SOURCES = $(PROTOCOL_SOURCES) tbm-client-remote-provider-test.c
+
+tbm_client_remote_consumer_test_LDADD = $(CLIENT_TEST_LDADD)
+tbm_client_remote_consumer_test_CFLAGS = $(CLIENT_TEST_CFLAGS)
+tbm_client_remote_consumer_test_SOURCES = $(PROTOCOL_SOURCES) tbm-client-remote-consumer-test.c
\ No newline at end of file
diff --git a/test/tbm-client-remote-consumer-test.c b/test/tbm-client-remote-consumer-test.c
new file mode 100644 (file)
index 0000000..76c26c7
--- /dev/null
@@ -0,0 +1,123 @@
+#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 "wayland-tbm-test-client-protocol.h"
+
+#define WL_APP_C_LOG(fmt, ...)   fprintf (stderr, "[CLIENT(%d):%s] " fmt, getpid(), __func__, ##__VA_ARGS__)
+
+typedef struct {
+       struct wayland_tbm_client *tbm_client;
+       struct wl_tbm *wl_tbm;
+       struct wl_tbm_test *wl_tbm_test;
+       struct wl_test_remote *remote;
+
+       struct wl_buffer *bufs[3];
+       int cur_buf;
+       
+       int exit;
+} AppInfoClient;
+
+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_C_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 void 
+_wl_test_remote_update_cb(void *data,
+                      struct wl_test_remote *wl_test_remote,
+                      struct wl_buffer *buffer)
+{
+       WL_APP_C_LOG("wl_buffer:%p, tbm_surface:%p\n",buffer, wl_buffer_get_user_data(buffer));
+}
+
+static const struct wl_test_remote_listener wl_test_remote_impl = {
+       _wl_test_remote_update_cb
+};
+
+void create_consumer(AppInfoClient *app)
+{
+       app->remote = wl_tbm_test_create_remote_surface(app->wl_tbm_test, "test");
+       wl_test_remote_add_listener(app->remote, &wl_test_remote_impl, NULL);
+       wl_test_remote_redirect(app->remote, app->wl_tbm);
+}
+
+int
+main(int argc, char *argv[])
+{
+       struct wl_display *dpy = NULL;
+       struct wl_registry *registry;
+       const char *dpy_name = NULL;
+       const static char *default_dpy_name = "tbm_remote";
+       int ret = 0;
+
+       if (argc > 1) {
+               dpy_name = argv[1];
+       } else {
+               dpy_name = default_dpy_name;
+       }
+
+       dpy = wl_display_connect(dpy_name);
+       if (!dpy) {
+               printf("[APP] failed to connect server\n");
+               return -1;
+       }
+
+       registry = wl_display_get_registry(dpy);
+       wl_registry_add_listener(registry, &wl_registry_impl, &gApp);
+       wl_display_roundtrip(dpy);
+       if (gApp.wl_tbm_test == NULL) {
+               WL_APP_C_LOG("fail to bind::wl_tbm_test");
+               return 0;
+       }
+
+       gApp.tbm_client = wayland_tbm_client_init(dpy);
+       if (!gApp.tbm_client) {
+               WL_APP_C_LOG("fail to wayland_tbm_client_init()\n");
+               goto finish;
+       }
+       gApp.wl_tbm = wayland_tbm_client_get_wl_tbm(gApp.tbm_client);
+
+       create_consumer(&gApp);
+       
+       while (ret >= 0 && gApp.exit == 0) {
+               ret = wl_display_dispatch(dpy);
+       }
+
+finish:
+       return 1;
+}
+
diff --git a/test/tbm-client-remote-provider-test.c b/test/tbm-client-remote-provider-test.c
new file mode 100644 (file)
index 0000000..6bfa802
--- /dev/null
@@ -0,0 +1,138 @@
+#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 "wayland-tbm-test-client-protocol.h"
+
+#define WL_APP_C_LOG(fmt, ...)   fprintf (stderr, "[CLIENT(%d):%s] " fmt, getpid(), __func__, ##__VA_ARGS__)
+
+typedef struct {
+       struct wayland_tbm_client *tbm_client;
+       struct wl_tbm *wl_tbm;
+       struct wl_tbm_test *wl_tbm_test;
+       struct wl_test_surface *surface;
+
+       struct wl_buffer *bufs[3];
+       int cur_buf;
+       
+       int exit;
+} AppInfoClient;
+
+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_C_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,
+};
+
+void create_provider(AppInfoClient *app)
+{
+       tbm_surface_h tbm_surf;
+       int i;
+       
+       app->surface = wl_tbm_test_create_surface(app->wl_tbm_test);
+       wl_tbm_test_set_provider(app->wl_tbm_test, app->surface, "test");
+
+       //Make wl_buffer
+       for (i=0; i<3; i++) {
+               tbm_surf = tbm_surface_create(16,16, TBM_FORMAT_ABGR8888);
+               app->bufs[i] = wayland_tbm_client_create_buffer(app->tbm_client, tbm_surf);
+       }
+}
+
+void _wl_callback_done_cb(void *data,
+                    struct wl_callback *wl_callback,
+                    uint32_t callback_data)
+{
+       AppInfoClient *app = (AppInfoClient *)data;
+
+       wl_test_surface_attach(app->surface, app->bufs[app->cur_buf]);
+       app->cur_buf = (app->cur_buf+1)%3;
+       
+       wl_callback_destroy(wl_callback);
+}
+
+static struct wl_callback_listener do_done_impl = {
+       _wl_callback_done_cb
+};
+
+int
+main(int argc, char *argv[])
+{
+       struct wl_display *dpy = NULL;
+       struct wl_registry *registry;
+       const char *dpy_name = NULL;
+       const static char *default_dpy_name = "tbm_remote";
+       int ret = 0;
+
+       struct wl_callback *wl_cb;
+
+       if (argc > 1) {
+               dpy_name = argv[1];
+       } else {
+               dpy_name = default_dpy_name;
+       }
+
+       dpy = wl_display_connect(dpy_name);
+       if (!dpy) {
+               printf("[APP] failed to connect server\n");
+               return -1;
+       }
+
+       registry = wl_display_get_registry(dpy);
+       wl_registry_add_listener(registry, &wl_registry_impl, &gApp);
+       wl_display_roundtrip(dpy);
+       if (gApp.wl_tbm_test == NULL) {
+               WL_APP_C_LOG("fail to bind::wl_tbm_test");
+               return 0;
+       }
+
+       gApp.tbm_client = wayland_tbm_client_init(dpy);
+       if (!gApp.tbm_client) {
+               WL_APP_C_LOG("fail to wayland_tbm_client_init()\n");
+               goto finish;
+       }
+       gApp.wl_tbm = wayland_tbm_client_get_wl_tbm(gApp.tbm_client);
+
+       create_provider(&gApp);
+       
+       while (ret >= 0 && gApp.exit == 0) {
+               wl_cb = wl_display_sync(dpy);
+               wl_callback_add_listener(wl_cb, &do_done_impl, &gApp);
+               ret = wl_display_dispatch(dpy);
+       }
+
+finish:
+       return 1;
+}
index 3ac18b4..f3f54b5 100644 (file)
@@ -162,8 +162,7 @@ _wl_tbm_test_set_active_surface(struct wl_client *client,
        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);
+       //wayland_tbm_server_client_queue_activate(app->server_queue, 0x1111);
        app->active_surface = app_surface;
 
        SERVER_LOG("Active surface:%p\n", app_surface);
@@ -232,6 +231,7 @@ wl_tbm_test_update_timer_cb(void *data)
 static void
 wl_tbm_test_idle_cb(void *data)
 {
+#if 0  
        AppInfo *app = data;
        AppSurface *app_surface, *tmp;
        tbm_surface_h back = NULL;
@@ -246,7 +246,7 @@ wl_tbm_test_idle_cb(void *data)
                        uint32_t flags;
                        buffer = wayland_tbm_server_get_surface(NULL,
                                                                app->active_surface->update_buffer);
-                       flags = wayland_tbm_server_get_flags(NULL, app->active_surface->update_buffer);
+                       flags = wayland_tbm_server_get_buffer_flags(NULL, app->active_surface->update_buffer);
                        if (flags == SCANOUT_BUFFER) {
                                tbm_surface_queue_enqueue(app->scanout_queue, buffer);
                                app->active_surface->update_buffer = NULL;
@@ -266,7 +266,7 @@ wl_tbm_test_idle_cb(void *data)
                        continue;
 
                buffer = wayland_tbm_server_get_surface(NULL, app_surface->update_buffer);
-               flags = wayland_tbm_server_get_flags(NULL, app_surface->update_buffer);
+               flags = wayland_tbm_server_get_buffer_flags(NULL, app_surface->update_buffer);
 
                SERVER_LOG("Composite %p buffer:%p\n", app_surface, app_surface->update_buffer);
                if (flags == SCANOUT_BUFFER)
@@ -291,14 +291,13 @@ present:
                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,
+                               wayland_tbm_server_client_queue_activate(app->server_queue,
                                                                     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,
+                                       if (wayland_tbm_server_client_queue_activate(app->server_queue,
                                                        app_surface->resource, 1)) {
                                                SERVER_LOG("!! ERROR wayland_tbm_server_queue_set_surface\n");
                                        } else {
@@ -321,6 +320,7 @@ present:
                SERVER_LOG("need_update\n");
                app->need_update = 1;
        }
+#endif
 }
 
 int
@@ -361,8 +361,6 @@ main(int argc, char *argv[])
 
        gApp.scanout_queue = tbm_surface_queue_create(NUM_SCANOUT_BUFFER, 100, 100,
                             TBM_FORMAT_ABGR8888, 0);
-       gApp.server_queue = wayland_tbm_server_create_queue(gApp.tbm_server,
-                           gApp.scanout_queue, SCANOUT_BUFFER);
 
        tbm_surface_queue_dequeue(gApp.scanout_queue, &init_front);
        /*TODO : Clear Screen*/
diff --git a/test/tbm-server-remote-test.c b/test/tbm-server-remote-test.c
new file mode 100644 (file)
index 0000000..97a7e10
--- /dev/null
@@ -0,0 +1,297 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <wayland-server.h>
+#include <wayland-tbm-server.h>
+#include <tbm_surface.h>
+
+#include "wayland-tbm-test-server-protocol.h"
+
+#define SERVER_LOG(fmt, ...)   fprintf (stderr, "[SERVER(%d):%s] " fmt, getpid(), __func__, ##__VA_ARGS__)
+
+typedef struct {
+       struct wl_display *dpy;
+       struct wayland_tbm_server *tbm_server;
+       struct wl_global *wl_tbm_test;
+
+       struct wl_resource *provider;
+}Server;
+
+typedef struct {
+       struct wl_resource *wl_surface;
+       struct wl_resource *wl_surface_bind;
+       struct wl_resource *front;
+
+       struct wl_list remotes;
+}Surface;
+
+typedef struct {
+       struct wl_resource *wl_remote_surface;
+       struct wl_resource *wl_tbm;
+       struct wl_resource *front;
+       Surface *provider;
+       
+       struct wl_list link;
+}RemoteSurface;
+
+Server gServer;
+
+static void
+_wl_test_remote_destroy(struct wl_resource *resource)
+{
+       RemoteSurface *remote = (RemoteSurface*)wl_resource_get_user_data(resource);
+
+       if (remote->provider) {
+               wl_list_remove(&remote->link);
+               SERVER_LOG("%p(%p)\n", resource, remote);
+       }
+       
+       free(remote);
+}
+
+static void
+_wl_test_remote_destroy_cb(struct wl_client *client,
+                       struct wl_resource *resource)
+{
+       wl_resource_destroy(resource);
+}
+
+static void
+_wl_test_remote_release_cb(struct wl_client *client,
+                       struct wl_resource *resource,
+                       struct wl_resource *buffer)
+{
+}
+
+static void
+_wl_test_remote_redirect_cb(struct wl_client *client,
+                        struct wl_resource *resource,
+                        struct wl_resource *wl_tbm)
+{
+       RemoteSurface *remote = wl_resource_get_user_data(resource);
+       remote->wl_tbm = wl_tbm;
+       SERVER_LOG("%p, wl_tbm: %p\n", resource, wl_tbm);
+}
+
+static void
+_wl_test_remote_unredirect_cb(struct wl_client *client,
+                          struct wl_resource *resource)
+{
+       RemoteSurface *remote = wl_resource_get_user_data(resource);
+       remote->wl_tbm = NULL;
+       SERVER_LOG("%p\n", resource);
+}
+
+static void
+_wl_test_remote_bind_cb(struct wl_client *client,
+                    struct wl_resource *resource,
+                    struct wl_resource *surface)
+{
+       RemoteSurface *remote = wl_resource_get_user_data(resource);
+       SERVER_LOG("%p(%p) to surface:%p\n", resource, remote, surface);
+}
+
+static const struct wl_test_remote_interface wl_test_remote_impl = {
+       _wl_test_remote_destroy_cb,
+       _wl_test_remote_release_cb,
+       _wl_test_remote_redirect_cb,
+       _wl_test_remote_unredirect_cb,
+       _wl_test_remote_bind_cb
+};
+
+static void
+_wl_test_surface_destroy(struct wl_resource *resource)
+{
+       Surface *surface = (Surface *)wl_resource_get_user_data(resource);
+
+       SERVER_LOG("%p provider:%p\n", resource, gServer.provider);
+       
+       if (!wl_list_empty(&surface->remotes)) {
+               RemoteSurface *pos, *tmp;
+               
+               wl_list_for_each_safe(pos, tmp,&surface->remotes, link) {
+                       pos->provider = NULL;
+                       wl_list_remove(&pos->link);
+               }
+       }
+
+       if (gServer.provider == resource)
+               gServer.provider = NULL;
+
+       free(surface);
+}
+
+
+static void
+_wl_test_surface_destroy_cb(struct wl_client *client,
+                           struct wl_resource *resource)
+{
+       wl_resource_destroy(resource);
+}
+
+static void
+_wl_test_surface_attach_cb(struct wl_client *client,
+                          struct wl_resource *resource,
+                          struct wl_resource *wl_buffer)
+{
+       Surface *surface = (Surface*)wl_resource_get_user_data(resource);
+
+       if (surface->front && (surface->front != wl_buffer))
+               wl_buffer_send_release(surface->front);
+       
+       surface->front = wl_buffer;
+       if (!wl_list_empty(&surface->remotes)) {
+               RemoteSurface *pos;
+               struct wl_resource *wl_remote_buffer = NULL;
+               
+               wl_list_for_each(pos, &surface->remotes, link) {
+                       if (pos->wl_tbm) {
+                               wl_remote_buffer = wayland_tbm_server_get_remote_buffer(wl_buffer, pos->wl_tbm);
+                               if (!wl_remote_buffer) {
+                                       tbm_surface_h tbm_surface;
+                                       
+                                       tbm_surface = wayland_tbm_server_get_surface(NULL, wl_buffer);
+                                       wl_remote_buffer = wayland_tbm_server_export_buffer(pos->wl_tbm, tbm_surface);
+                                       SERVER_LOG("export: wl_tbm:%p, tbm_surf:%p, wl_buf:%p\n", pos->wl_tbm, tbm_surface, wl_remote_buffer);
+                               }
+
+                               if (wl_remote_buffer) {
+                                       wl_test_remote_send_update(pos->wl_remote_surface, wl_remote_buffer);
+                                       pos->front = wl_remote_buffer;
+                               }
+                       }
+               }
+       }
+}
+
+static void
+_wl_test_surface_frame_cb(struct wl_client *client,
+                         struct wl_resource *resource,
+                         uint32_t callback)
+{
+}
+
+static const struct wl_test_surface_interface wl_test_surface_impl = {
+       _wl_test_surface_destroy_cb,
+       _wl_test_surface_attach_cb,
+       _wl_test_surface_frame_cb
+};
+
+static void 
+_wl_tbm_test_create_surface(struct wl_client *client,
+                              struct wl_resource *resource,
+                              uint32_t id)
+{
+       Surface *surface;
+
+       surface = calloc(1, sizeof(Surface));
+       wl_list_init(&surface->remotes);
+       surface->wl_surface = wl_resource_create(client,
+                                               &wl_test_surface_interface, 1, id);
+       wl_resource_set_implementation(surface->wl_surface, 
+                                               &wl_test_surface_impl, surface,
+                                               _wl_test_surface_destroy);
+}
+
+static void
+_wl_tbm_test_set_active_queue(struct wl_client *client,
+                                struct wl_resource *resource,
+                                struct wl_resource *surface)
+{
+}
+
+static void
+_wl_tbm_test_set_provider(struct wl_client *client,
+                            struct wl_resource *resource,
+                            struct wl_resource *surface,
+                            const char *name)
+{
+       Server *srv = (Server *)wl_resource_get_user_data(resource);
+       srv->provider = surface;
+
+       SERVER_LOG("Provider:%p\n", resource);
+}
+
+static void
+_wl_tbm_create_remote_surface(struct wl_client *client,
+                                     struct wl_resource *resource,
+                                     uint32_t id,
+                                     const char *name)
+{
+       Server *srv = (Server *)wl_resource_get_user_data(resource);
+       Surface *provider;
+       RemoteSurface *remote;
+
+       if (!srv->provider) return;
+       provider = wl_resource_get_user_data(srv->provider);
+
+       remote = calloc(1, sizeof(RemoteSurface));
+       remote->provider = provider;
+       remote->wl_remote_surface = wl_resource_create(client,
+                                                                       &wl_test_remote_interface,
+                                                                       1,
+                                                                       id);
+       wl_resource_set_implementation(remote->wl_remote_surface,
+                               &wl_test_remote_impl,
+                               remote, 
+                               _wl_test_remote_destroy);
+       wl_list_init(&remote->link);
+       wl_list_insert(&provider->remotes, &remote->link);
+       SERVER_LOG("Add remote:%p(%p) to provider:%p(%p)\n",
+               resource, remote,
+               srv->provider, provider);
+}
+
+static const struct wl_tbm_test_interface wl_tbm_test_impl = {
+       _wl_tbm_test_create_surface,
+       _wl_tbm_test_set_active_queue,
+       _wl_tbm_test_set_provider,
+       _wl_tbm_create_remote_surface
+};
+
+static void
+wl_tbm_test_bind_cb(struct wl_client *client, void *data,
+                   uint32_t version, uint32_t id)
+{
+       struct wl_resource *resource;
+
+       resource = wl_resource_create(client, &wl_tbm_test_interface, version, id);
+       wl_resource_set_implementation(resource, &wl_tbm_test_impl, data, NULL);
+
+       SERVER_LOG("client:%p, wl_tbm_test:%p\n", client, resource);
+}
+
+int
+main(int argc, char *argv[])
+{
+       struct wl_display *dpy;
+       struct wayland_tbm_server *tbm_server;
+
+       const char *dpy_name = "tbm_remote";
+
+       dpy = wl_display_create();
+       if (!dpy) {
+               printf("[SRV] failed to create display\n");
+               return -1;
+       }
+
+       wl_display_add_socket(dpy, dpy_name);
+       printf("[SRV] wl_display : %s\n", dpy_name);
+
+       tbm_server = wayland_tbm_server_init(dpy, NULL, -1, 0);
+       if (!tbm_server) {
+               printf("[SRV] failed to tbm_server init\n");
+               wl_display_destroy(dpy);
+               return -1;
+       }
+
+       gServer.dpy = dpy;
+       gServer.tbm_server = tbm_server;
+       gServer.wl_tbm_test = wl_global_create(dpy, &wl_tbm_test_interface, 1, &gServer,
+                                           wl_tbm_test_bind_cb);
+       
+       wl_display_run(dpy);
+
+       return 0;
+}
index 82e27d6..1310602 100644 (file)
@@ -39,17 +39,24 @@ struct wl_resource;
 
 struct wl_buffer;
 struct wl_callback;
+struct wl_tbm;
 struct wl_tbm_test;
+struct wl_test_remote;
 struct wl_test_surface;
 
 extern const struct wl_interface wl_tbm_test_interface;
 extern const struct wl_interface wl_test_surface_interface;
+extern const struct wl_interface wl_test_remote_interface;
 
 #define WL_TBM_TEST_CREATE_SURFACE     0
 #define WL_TBM_TEST_SET_ACTIVE_QUEUE   1
+#define WL_TBM_TEST_SET_PROVIDER       2
+#define WL_TBM_TEST_CREATE_REMOTE_SURFACE      3
 
 #define WL_TBM_TEST_CREATE_SURFACE_SINCE_VERSION       1
 #define WL_TBM_TEST_SET_ACTIVE_QUEUE_SINCE_VERSION     1
+#define WL_TBM_TEST_SET_PROVIDER_SINCE_VERSION 1
+#define WL_TBM_TEST_CREATE_REMOTE_SURFACE_SINCE_VERSION        1
 
 static inline void
 wl_tbm_test_set_user_data(struct wl_tbm_test *wl_tbm_test, void *user_data)
@@ -63,6 +70,12 @@ wl_tbm_test_get_user_data(struct wl_tbm_test *wl_tbm_test)
        return wl_proxy_get_user_data((struct wl_proxy *) wl_tbm_test);
 }
 
+static inline uint32_t
+wl_tbm_test_get_version(struct wl_tbm_test *wl_tbm_test)
+{
+       return wl_proxy_get_version((struct wl_proxy *) wl_tbm_test);
+}
+
 static inline void
 wl_tbm_test_destroy(struct wl_tbm_test *wl_tbm_test)
 {
@@ -87,6 +100,24 @@ wl_tbm_test_set_active_queue(struct wl_tbm_test *wl_tbm_test, struct wl_test_sur
                         WL_TBM_TEST_SET_ACTIVE_QUEUE, surface);
 }
 
+static inline void
+wl_tbm_test_set_provider(struct wl_tbm_test *wl_tbm_test, struct wl_test_surface *surface, const char *name)
+{
+       wl_proxy_marshal((struct wl_proxy *) wl_tbm_test,
+                        WL_TBM_TEST_SET_PROVIDER, surface, name);
+}
+
+static inline struct wl_test_remote *
+wl_tbm_test_create_remote_surface(struct wl_tbm_test *wl_tbm_test, const char *name)
+{
+       struct wl_proxy *surface;
+
+       surface = wl_proxy_marshal_constructor((struct wl_proxy *) wl_tbm_test,
+                        WL_TBM_TEST_CREATE_REMOTE_SURFACE, &wl_test_remote_interface, NULL, name);
+
+       return (struct wl_test_remote *) surface;
+}
+
 #define WL_TEST_SURFACE_DESTROY        0
 #define WL_TEST_SURFACE_ATTACH 1
 #define WL_TEST_SURFACE_FRAME  2
@@ -107,6 +138,12 @@ wl_test_surface_get_user_data(struct wl_test_surface *wl_test_surface)
        return wl_proxy_get_user_data((struct wl_proxy *) wl_test_surface);
 }
 
+static inline uint32_t
+wl_test_surface_get_version(struct wl_test_surface *wl_test_surface)
+{
+       return wl_proxy_get_version((struct wl_proxy *) wl_test_surface);
+}
+
 static inline void
 wl_test_surface_destroy(struct wl_test_surface *wl_test_surface)
 {
@@ -134,6 +171,91 @@ wl_test_surface_frame(struct wl_test_surface *wl_test_surface)
        return (struct wl_callback *) callback;
 }
 
+struct wl_test_remote_listener {
+       /**
+        * update - (none)
+        * @buffer: (none)
+        */
+       void (*update)(void *data,
+                      struct wl_test_remote *wl_test_remote,
+                      struct wl_buffer *buffer);
+};
+
+static inline int
+wl_test_remote_add_listener(struct wl_test_remote *wl_test_remote,
+                           const struct wl_test_remote_listener *listener, void *data)
+{
+       return wl_proxy_add_listener((struct wl_proxy *) wl_test_remote,
+                                    (void (**)(void)) listener, data);
+}
+
+#define WL_TEST_REMOTE_DESTROY 0
+#define WL_TEST_REMOTE_RELEASE 1
+#define WL_TEST_REMOTE_REDIRECT        2
+#define WL_TEST_REMOTE_UNREDIRECT      3
+#define WL_TEST_REMOTE_BIND    4
+
+#define WL_TEST_REMOTE_DESTROY_SINCE_VERSION   1
+#define WL_TEST_REMOTE_RELEASE_SINCE_VERSION   1
+#define WL_TEST_REMOTE_REDIRECT_SINCE_VERSION  1
+#define WL_TEST_REMOTE_UNREDIRECT_SINCE_VERSION        1
+#define WL_TEST_REMOTE_BIND_SINCE_VERSION      1
+
+static inline void
+wl_test_remote_set_user_data(struct wl_test_remote *wl_test_remote, void *user_data)
+{
+       wl_proxy_set_user_data((struct wl_proxy *) wl_test_remote, user_data);
+}
+
+static inline void *
+wl_test_remote_get_user_data(struct wl_test_remote *wl_test_remote)
+{
+       return wl_proxy_get_user_data((struct wl_proxy *) wl_test_remote);
+}
+
+static inline uint32_t
+wl_test_remote_get_version(struct wl_test_remote *wl_test_remote)
+{
+       return wl_proxy_get_version((struct wl_proxy *) wl_test_remote);
+}
+
+static inline void
+wl_test_remote_destroy(struct wl_test_remote *wl_test_remote)
+{
+       wl_proxy_marshal((struct wl_proxy *) wl_test_remote,
+                        WL_TEST_REMOTE_DESTROY);
+
+       wl_proxy_destroy((struct wl_proxy *) wl_test_remote);
+}
+
+static inline void
+wl_test_remote_release(struct wl_test_remote *wl_test_remote, struct wl_buffer *buffer)
+{
+       wl_proxy_marshal((struct wl_proxy *) wl_test_remote,
+                        WL_TEST_REMOTE_RELEASE, buffer);
+}
+
+static inline void
+wl_test_remote_redirect(struct wl_test_remote *wl_test_remote, struct wl_tbm *wl_tbm)
+{
+       wl_proxy_marshal((struct wl_proxy *) wl_test_remote,
+                        WL_TEST_REMOTE_REDIRECT, wl_tbm);
+}
+
+static inline void
+wl_test_remote_unredirect(struct wl_test_remote *wl_test_remote)
+{
+       wl_proxy_marshal((struct wl_proxy *) wl_test_remote,
+                        WL_TEST_REMOTE_UNREDIRECT);
+}
+
+static inline void
+wl_test_remote_bind(struct wl_test_remote *wl_test_remote, struct wl_test_surface *surface)
+{
+       wl_proxy_marshal((struct wl_proxy *) wl_test_remote,
+                        WL_TEST_REMOTE_BIND, surface);
+}
+
 #ifdef  __cplusplus
 }
 #endif
index a834071..419e529 100644 (file)
 
 extern const struct wl_interface wl_buffer_interface;
 extern const struct wl_interface wl_callback_interface;
+extern const struct wl_interface wl_tbm_interface;
+extern const struct wl_interface wl_test_remote_interface;
 extern const struct wl_interface wl_test_surface_interface;
 
 static const struct wl_interface *types[] = {
        &wl_test_surface_interface,
        &wl_test_surface_interface,
+       &wl_test_surface_interface,
+       NULL,
+       &wl_test_remote_interface,
+       NULL,
        &wl_buffer_interface,
        &wl_callback_interface,
+       &wl_buffer_interface,
+       &wl_tbm_interface,
+       &wl_test_surface_interface,
+       &wl_buffer_interface,
 };
 
 static const struct wl_message wl_tbm_test_requests[] = {
        { "create_surface", "n", types + 0 },
        { "set_active_queue", "o", types + 1 },
+       { "set_provider", "os", types + 2 },
+       { "create_remote_surface", "ns", types + 4 },
 };
 
 WL_EXPORT const struct wl_interface wl_tbm_test_interface = {
        "wl_tbm_test", 1,
-       2, wl_tbm_test_requests,
+       4, wl_tbm_test_requests,
        0, NULL,
 };
 
 static const struct wl_message wl_test_surface_requests[] = {
        { "destroy", "", types + 0 },
-       { "attach", "o", types + 2 },
-       { "frame", "n", types + 3 },
+       { "attach", "o", types + 6 },
+       { "frame", "n", types + 7 },
 };
 
 WL_EXPORT const struct wl_interface wl_test_surface_interface = {
-       "wl_surface", 1,
+       "wl_test_surface", 1,
        3, wl_test_surface_requests,
        0, NULL,
 };
 
+static const struct wl_message wl_test_remote_requests[] = {
+       { "destroy", "", types + 0 },
+       { "release", "o", types + 8 },
+       { "redirect", "o", types + 9 },
+       { "unredirect", "", types + 0 },
+       { "bind", "o", types + 10 },
+};
+
+static const struct wl_message wl_test_remote_events[] = {
+       { "update", "o", types + 11 },
+};
+
+WL_EXPORT const struct wl_interface wl_test_remote_interface = {
+       "wl_test_remote", 1,
+       5, wl_test_remote_requests,
+       1, wl_test_remote_events,
+};
+
index 13d8d84..c1b197e 100644 (file)
@@ -39,11 +39,14 @@ struct wl_resource;
 
 struct wl_buffer;
 struct wl_callback;
+struct wl_tbm;
 struct wl_tbm_test;
+struct wl_test_remote;
 struct wl_test_surface;
 
 extern const struct wl_interface wl_tbm_test_interface;
 extern const struct wl_interface wl_test_surface_interface;
+extern const struct wl_interface wl_test_remote_interface;
 
 struct wl_tbm_test_interface {
        /**
@@ -60,6 +63,24 @@ struct wl_tbm_test_interface {
        void (*set_active_queue)(struct wl_client *client,
                                 struct wl_resource *resource,
                                 struct wl_resource *surface);
+       /**
+        * set_provider - (none)
+        * @surface: (none)
+        * @name: (none)
+        */
+       void (*set_provider)(struct wl_client *client,
+                            struct wl_resource *resource,
+                            struct wl_resource *surface,
+                            const char *name);
+       /**
+        * create_remote_surface - (none)
+        * @surface: (none)
+        * @name: (none)
+        */
+       void (*create_remote_surface)(struct wl_client *client,
+                                     struct wl_resource *resource,
+                                     uint32_t surface,
+                                     const char *name);
 };
 
 
@@ -86,6 +107,50 @@ struct wl_test_surface_interface {
 };
 
 
+struct wl_test_remote_interface {
+       /**
+        * destroy - (none)
+        */
+       void (*destroy)(struct wl_client *client,
+                       struct wl_resource *resource);
+       /**
+        * release - (none)
+        * @buffer: (none)
+        */
+       void (*release)(struct wl_client *client,
+                       struct wl_resource *resource,
+                       struct wl_resource *buffer);
+       /**
+        * redirect - (none)
+        * @wl_tbm: (none)
+        */
+       void (*redirect)(struct wl_client *client,
+                        struct wl_resource *resource,
+                        struct wl_resource *wl_tbm);
+       /**
+        * unredirect - (none)
+        */
+       void (*unredirect)(struct wl_client *client,
+                          struct wl_resource *resource);
+       /**
+        * bind - (none)
+        * @surface: (none)
+        */
+       void (*bind)(struct wl_client *client,
+                    struct wl_resource *resource,
+                    struct wl_resource *surface);
+};
+
+#define WL_TEST_REMOTE_UPDATE  0
+
+#define WL_TEST_REMOTE_UPDATE_SINCE_VERSION    1
+
+static inline void
+wl_test_remote_send_update(struct wl_resource *resource_, struct wl_resource *buffer)
+{
+       wl_resource_post_event(resource_, WL_TEST_REMOTE_UPDATE, buffer);
+}
+
 #ifdef  __cplusplus
 }
 #endif
index 3ab2b7d..f77b574 100644 (file)
     <request name="set_active_queue">
       <arg name="surface" type="object" interface="wl_test_surface"/>
     </request>
+
+    <!--For remote test -->
+    <request name="set_provider">
+      <arg name="surface" type="object" interface="wl_test_surface"/>
+      <arg name="name" type="string"/>
+    </request>
+    <request name="create_remote_surface">
+      <arg name="surface" type="new_id" interface="wl_test_remote"/>
+      <arg name="name" type="string"/>
+    </request>
   </interface>
 
   <interface name="wl_test_surface" version="1">
       <arg name="callback" type="new_id" interface="wl_callback"/>
     </request>
   </interface>
+
+  <interface name="wl_test_remote" version="1">
+    <request name="destroy" type="destructor">
+    </request>
+    <request name="release">
+      <arg name="buffer" type="object" interface="wl_buffer"/>
+    </request>
+    <request name="redirect">
+      <arg name="wl_tbm" type="object" interface="wl_tbm"/>
+    </request>
+    <request name="unredirect">
+    </request>
+    <request name="bind">
+      <arg name="surface" type="object" interface="wl_test_surface"/>
+    </request>
+
+    <event name="update">
+      <arg name="buffer" type="object" interface="wl_buffer"/>
+    </event>
+  </interface>
 </protocol>