From c1d4811bf2086c52d05f58fd995f65b9285073e2 Mon Sep 17 00:00:00 2001 From: Sangjin Lee Date: Wed, 24 Aug 2016 19:19:00 +0900 Subject: [PATCH] Add user_data for find tbm_surface and sample app Change-Id: I572c388fc84a6a8b7e78338544936df06e73ba3f --- src/wayland-tbm-server.c | 76 +++++++- src/wayland-tbm-server.h | 6 + test/Makefile.am | 21 ++- test/tbm-client-remote-consumer-test.c | 123 +++++++++++++ test/tbm-client-remote-provider-test.c | 138 +++++++++++++++ test/tbm-server-queue-test.c | 16 +- test/tbm-server-remote-test.c | 297 ++++++++++++++++++++++++++++++++ test/wayland-tbm-test-client-protocol.h | 122 +++++++++++++ test/wayland-tbm-test-protocol.c | 38 +++- test/wayland-tbm-test-server-protocol.h | 65 +++++++ test/wayland-tbm-test.xml | 30 ++++ 11 files changed, 915 insertions(+), 17 deletions(-) create mode 100644 test/tbm-client-remote-consumer-test.c create mode 100644 test/tbm-client-remote-provider-test.c create mode 100644 test/tbm-server-remote-test.c diff --git a/src/wayland-tbm-server.c b/src/wayland-tbm-server.c index 88f628e..8efe6eb 100644 --- a/src/wayland-tbm-server.c +++ b/src/wayland-tbm-server.c @@ -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) { diff --git a/src/wayland-tbm-server.h b/src/wayland-tbm-server.h index ad67717..8089728 100644 --- a/src/wayland-tbm-server.h +++ b/src/wayland-tbm-server.h @@ -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); diff --git a/test/Makefile.am b/test/Makefile.am index 6d4e6a0..0bcbd41 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -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 index 0000000..76c26c7 --- /dev/null +++ b/test/tbm-client-remote-consumer-test.c @@ -0,0 +1,123 @@ +#include +#include +#include +#include + +#define WL_HIDE_DEPRECATED +#include +#include +#include + +#include + +#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 index 0000000..6bfa802 --- /dev/null +++ b/test/tbm-client-remote-provider-test.c @@ -0,0 +1,138 @@ +#include +#include +#include +#include + +#define WL_HIDE_DEPRECATED +#include +#include +#include + +#include + +#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; +} diff --git a/test/tbm-server-queue-test.c b/test/tbm-server-queue-test.c index 3ac18b4..f3f54b5 100644 --- a/test/tbm-server-queue-test.c +++ b/test/tbm-server-queue-test.c @@ -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 index 0000000..97a7e10 --- /dev/null +++ b/test/tbm-server-remote-test.c @@ -0,0 +1,297 @@ +#include +#include +#include + +#include +#include +#include + +#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; +} diff --git a/test/wayland-tbm-test-client-protocol.h b/test/wayland-tbm-test-client-protocol.h index 82e27d6..1310602 100644 --- a/test/wayland-tbm-test-client-protocol.h +++ b/test/wayland-tbm-test-client-protocol.h @@ -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 diff --git a/test/wayland-tbm-test-protocol.c b/test/wayland-tbm-test-protocol.c index a834071..419e529 100644 --- a/test/wayland-tbm-test-protocol.c +++ b/test/wayland-tbm-test-protocol.c @@ -29,35 +29,65 @@ 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, +}; + diff --git a/test/wayland-tbm-test-server-protocol.h b/test/wayland-tbm-test-server-protocol.h index 13d8d84..c1b197e 100644 --- a/test/wayland-tbm-test-server-protocol.h +++ b/test/wayland-tbm-test-server-protocol.h @@ -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 diff --git a/test/wayland-tbm-test.xml b/test/wayland-tbm-test.xml index 3ab2b7d..f77b574 100644 --- a/test/wayland-tbm-test.xml +++ b/test/wayland-tbm-test.xml @@ -33,6 +33,16 @@ + + + + + + + + + + @@ -45,4 +55,24 @@ + + + + + + + + + + + + + + + + + + + + -- 2.7.4