//#define DEBUG_TRACE
#ifdef DEBUG_TRACE
-#define WL_TBM_TRACE(fmt, ...) if (trace_status == WL_TBM_MONITOR_TRACE_STATUS_ON) fprintf (stderr, "[WL_TBM_C(%d):%s] " fmt, getpid(), __func__, ##__VA_ARGS__)
+#define WL_TBM_TRACE(fmt, ...) if (trace_status == WL_TBM_MONITOR_TRACE_STATUS_ON) fprintf(stderr, "[WL_TBM_C(%d):%s] " fmt, getpid(), __func__, ##__VA_ARGS__)
#else
#define WL_TBM_TRACE(fmt, ...)
#endif
static void
+_wayland_tbm_client_dump(struct wayland_tbm_client * tbm_client, WL_TBM_MONITOR_DUMP_COMMAND cmd, WL_TBM_MONITOR_DUMP_TYPE type)
+{
+ if (cmd == WL_TBM_MONITOR_DUMP_COMMAND_SNAPSHOT) {
+ char * path = _wayland_tbm_dump_directory_make();
+ if (path) {
+ tbm_surface_internal_dump_all(path);
+ free(path);
+ }
+ }
+ else if (cmd == WL_TBM_MONITOR_DUMP_COMMAND_ON)
+ WL_TBM_DEBUG("WL_TBM_MONITOR_DUMP_COMMAND_ON isn't implemented yet\n");
+ else if (cmd == WL_TBM_MONITOR_DUMP_COMMAND_OFF)
+ WL_TBM_DEBUG("WL_TBM_MONITOR_DUMP_COMMAND_OFF isn't implemented yet\n");
+}
+
+static void
handle_tbm_monitor_client_tbm_bo(void *data,
struct wl_tbm *wl_tbm,
int32_t command,
- int32_t trace_command,
+ int32_t subcommand,
int32_t target,
int32_t pid)
{
#ifdef DEBUG_TRACE
WL_TBM_TRACE("command=%d, trace_command=%d, target=%d, pid=%d.\n",
- command, trace_command, target, pid);
+ command, subcommand, target, pid);
#endif
if (command == WL_TBM_MONITOR_COMMAND_SHOW) {
} else if (command == WL_TBM_MONITOR_COMMAND_TRACE) {
if (target == WL_TBM_MONITOR_TARGET_CLIENT) {
if (getpid() == pid) {
- if (trace_command == WL_TBM_MONITOR_TRACE_COMMAND_STATUS)
+ if (subcommand == WL_TBM_MONITOR_TRACE_COMMAND_STATUS)
WL_TBM_DEBUG("clinet(%d): trace status: %s\n", getpid(), _tarce_status_to_str(trace_status));
else
- _change_trace_status(&trace_status, trace_command, tbm_client->bufmgr);
+ _change_trace_status(&trace_status, subcommand, tbm_client->bufmgr);
}
} else if (target == WL_TBM_MONITOR_TARGET_ALL) {
- if (trace_command == WL_TBM_MONITOR_TRACE_COMMAND_STATUS)
+ if (subcommand == WL_TBM_MONITOR_TRACE_COMMAND_STATUS)
WL_TBM_DEBUG("clinet(%d): trace status: %s\n", getpid(), _tarce_status_to_str(trace_status));
else
- _change_trace_status(&trace_status, trace_command, tbm_client->bufmgr);
+ _change_trace_status(&trace_status, subcommand, tbm_client->bufmgr);
+ } else {
+ WL_TBM_LOG("[%s]: Error target is not available. target = %d\n", __func__,
+ target);
+ }
+ } else if (command == WL_TBM_MONITOR_COMMAND_DUMP) {
+ if (target == WL_TBM_MONITOR_TARGET_CLIENT) {
+ if (getpid() == pid)
+ _wayland_tbm_client_dump(tbm_client, subcommand & 0xFF, subcommand >> 16 & 0xFF);
+ } else if (target == WL_TBM_MONITOR_TARGET_ALL) {
+ _wayland_tbm_client_dump(tbm_client, subcommand & 0xFF, subcommand >> 16 & 0xFF);
} else {
WL_TBM_LOG("[%s]: Error target is not available. target = %d\n", __func__,
target);
WL_TBM_LOG("[%s]: Error command is not available. command = %d\n", __func__,
command);
}
-
}
static const struct wl_tbm_listener wl_tbm_client_listener = {
WL_TBM_MONITOR_COMMAND_LIST,
WL_TBM_MONITOR_COMMAND_SHOW,
WL_TBM_MONITOR_COMMAND_TRACE,
+ WL_TBM_MONITOR_COMMAND_DUMP,
} WL_TBM_MONITOR_COMMAND;
typedef enum {
} WL_TBM_MONITOR_TRACE_COMMAND;
typedef enum {
+ WL_TBM_MONITOR_DUMP_COMMAND_ON,
+ WL_TBM_MONITOR_DUMP_COMMAND_OFF,
+ WL_TBM_MONITOR_DUMP_COMMAND_REGISTER,
+ WL_TBM_MONITOR_DUMP_COMMAND_UNREGISTER,
+ WL_TBM_MONITOR_DUMP_COMMAND_SNAPSHOT,
+ WL_TBM_MONITOR_DUMP_COMMAND_STATUS,
+} WL_TBM_MONITOR_DUMP_COMMAND;
+
+typedef enum {
+ WL_TBM_MONITOR_DUMP_TYPE_IMPORT,
+ WL_TBM_MONITOR_DUMP_TYPE_REF,
+ WL_TBM_MONITOR_DUMP_TYPE_MAP,
+} WL_TBM_MONITOR_DUMP_TYPE;
+
+typedef enum {
WL_TBM_MONITOR_TRACE_STATUS_UNREGISTERED,
WL_TBM_MONITOR_TRACE_STATUS_OFF,
WL_TBM_MONITOR_TRACE_STATUS_ON,
char *
_tarce_status_to_str(WL_TBM_MONITOR_TRACE_STATUS status);
+char *
+_wayland_tbm_dump_directory_make(void);
+
#ifdef __cplusplus
}
#endif
//#define WL_TBM_SERVER_DEBUG
//#define DEBUG_TRACE
#ifdef DEBUG_TRACE
-#define WL_TBM_TRACE(fmt, ...) if (trace_status == WL_TBM_MONITOR_TRACE_STATUS_ON) fprintf (stderr, "[WL_TBM_S(%d):%s] " fmt, getpid(), __func__, ##__VA_ARGS__)
+#define WL_TBM_TRACE(fmt, ...) if (trace_status == WL_TBM_MONITOR_TRACE_STATUS_ON) fprintf(stderr, "[WL_TBM_S(%d):%s] " fmt, getpid(), __func__, ##__VA_ARGS__)
#else
#define WL_TBM_TRACE(fmt, ...)
#endif
};
static void
+_wayland_tbm_server_dump(struct wayland_tbm_server *tbm_srv, WL_TBM_MONITOR_DUMP_COMMAND cmd, WL_TBM_MONITOR_DUMP_TYPE type)
+{
+ if (cmd == WL_TBM_MONITOR_DUMP_COMMAND_SNAPSHOT) {
+ char * path = _wayland_tbm_dump_directory_make();
+ if (path) {
+ tbm_surface_internal_dump_all(path);
+ free (path);
+ }
+ }
+ else if (cmd == WL_TBM_MONITOR_DUMP_COMMAND_ON)
+ WL_TBM_DEBUG("WL_TBM_MONITOR_DUMP_COMMAND_ON isn't implemented yet\n");
+ else if (cmd == WL_TBM_MONITOR_DUMP_COMMAND_OFF)
+ WL_TBM_DEBUG("WL_TBM_MONITOR_DUMP_COMMAND_OFF isn't implemented yet\n");
+}
+
+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 subcommand,
int32_t target,
int32_t pid)
{
int i = 0;
#ifdef DEBUG_TRACE
- WL_TBM_TRACE("command=%d, trace_command=%d, target=%d, pid=%d.\n",
- command, trace_command, target, pid);
+ WL_TBM_TRACE("command=%d, subcommand=%x, target=%d, pid=%d.\n",
+ command, subcommand, target, pid);
#endif
if (command == WL_TBM_MONITOR_COMMAND_LIST) {
if (c_res->resource == resource)
continue;
- wl_tbm_send_monitor_client_tbm_bo(c_res->resource, command, trace_command,
+ wl_tbm_send_monitor_client_tbm_bo(c_res->resource, command, subcommand,
target, pid);
}
}
if (command == WL_TBM_MONITOR_COMMAND_SHOW) {
tbm_bufmgr_debug_show(tbm_srv->bufmgr);
} else if (command == WL_TBM_MONITOR_COMMAND_TRACE) {
- if (trace_command == WL_TBM_MONITOR_TRACE_COMMAND_STATUS)
+ if (subcommand == WL_TBM_MONITOR_TRACE_COMMAND_STATUS)
WL_TBM_DEBUG("server: trace status: %s\n",
_tarce_status_to_str(trace_status));
else
- _change_trace_status(&trace_status, trace_command, tbm_srv->bufmgr);
+ _change_trace_status(&trace_status, subcommand, tbm_srv->bufmgr);
+ } else if (command == WL_TBM_MONITOR_COMMAND_DUMP) {
+ _wayland_tbm_server_dump(tbm_srv, subcommand & 0xFF, subcommand >> 16 & 0xFF);
} else
wl_resource_post_error(resource, WL_TBM_ERROR_INVALID_FORMAT,
"invalid format");
if (c_res->resource == resource)
continue;
- wl_tbm_send_monitor_client_tbm_bo(c_res->resource, command, trace_command,
+ wl_tbm_send_monitor_client_tbm_bo(c_res->resource, command, subcommand,
target, pid);
}
}
if (c_res->resource == resource)
continue;
- wl_tbm_send_monitor_client_tbm_bo(c_res->resource, command, trace_command,
+ wl_tbm_send_monitor_client_tbm_bo(c_res->resource, command, subcommand,
target, pid);
}
}
- if (trace_command == WL_TBM_MONITOR_TRACE_COMMAND_STATUS)
+ if (subcommand == WL_TBM_MONITOR_TRACE_COMMAND_STATUS)
WL_TBM_DEBUG("server: trace status: %s\n",
_tarce_status_to_str(trace_status));
else
- _change_trace_status(&trace_status, trace_command, tbm_srv->bufmgr);
+ _change_trace_status(&trace_status, subcommand, tbm_srv->bufmgr);
+ } else if (command == WL_TBM_MONITOR_COMMAND_DUMP) {
+ /* send the events to all client containing wl_tbm resource except for the wayland-tbm-monitor(requestor). */
+ if (!wl_list_empty(&tbm_srv->cresource_list)) {
+ wl_list_for_each_safe(c_res, tmp_res, &tbm_srv->cresource_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, subcommand,
+ target, pid);
+ }
+ }
+ _wayland_tbm_server_dump(tbm_srv, subcommand & 0xFF, subcommand >> 16 & 0xFF);
+
} else
wl_resource_post_error(resource, WL_TBM_ERROR_INVALID_FORMAT,
"invalid format");
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <time.h>
+#include <limits.h>
+#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
+#include <tbm_surface.h>
+#include <tbm_surface_internal.h>
#include "wayland-tbm-int.h"
#ifdef HAVE_DLOG
return;
}
+char *
+_wayland_tbm_dump_directory_make(void)
+{
+ char *fullpath;
+ time_t timer;
+ struct tm *t, *buf;
+ char appname[255] = {'\0'};
+
+ timer = time(NULL);
+
+ buf = calloc(1, sizeof(struct tm));
+ if (buf == 0)
+ return NULL;
+
+ t = localtime_r(&timer, buf);
+ if (!t) {
+ free(buf);
+ return NULL;
+ }
+
+ fullpath = (char *) calloc(1, PATH_MAX * sizeof(char));
+ if (!fullpath) {
+ free(buf);
+ return NULL;
+ }
+
+ _wayland_tbm_util_get_appname_from_pid(getpid(), appname);
+
+ _wayland_tbm_util_get_appname_brief(appname);
+
+
+ snprintf(fullpath, PATH_MAX, "/tmp/tbm_dump_%s_%04d%02d%02d.%02d%02d%02d", appname, t->tm_year + 1900,
+ t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
+
+ free(buf);
+
+ if ((mkdir(fullpath, 0755)) < 0) {
+ free(fullpath);
+ return NULL;
+ }
+
+ return fullpath;
+}
struct {
WL_TBM_MONITOR_COMMAND command;
- WL_TBM_MONITOR_TRACE_COMMAND trace_command;
+ union {
+ int subcommand;
+ WL_TBM_MONITOR_TRACE_COMMAND trace_command;
+ struct {
+ WL_TBM_MONITOR_DUMP_COMMAND dump_command : 16;
+ WL_TBM_MONITOR_DUMP_TYPE dump_type : 16;
+ };
+ };
WL_TBM_MONITOR_TARGET target;
int pid;
} options;
/* request the tbm monitor */
wl_tbm_request_tbm_monitor(tbm_monitor->wl_tbm,
tbm_monitor->options.command,
- tbm_monitor->options.trace_command,
+ tbm_monitor->options.subcommand,
tbm_monitor->options.target,
tbm_monitor->options.pid);
wl_display_roundtrip(tbm_monitor->dpy);
}
static void
+_wl_tbm_dump_usage()
+{
+ WL_TBM_LOG(" dump : dump the tbm_bos\n");
+ WL_TBM_LOG(" usage : wayland-tbm-monitor dump [command]\n");
+ WL_TBM_LOG(" <command>\n");
+ WL_TBM_LOG(" snapshot client [pid] : make dumps of all tbm_bos for the client with pid.\n");
+ WL_TBM_LOG(" snapshot server : make dumps of all tbm_bos for the server.\n");
+ WL_TBM_LOG(" snapshot all : make dumps of all tbm_bos for all clients and server.\n");
+ WL_TBM_LOG(" on : turn on process of dumping.\n");
+ WL_TBM_LOG(" off : turn off process of dumping.\n");
+ WL_TBM_LOG(" register [type] client [pid] : register the pid of client.\n");
+ WL_TBM_LOG(" register [type] server : register the server.\n");
+ WL_TBM_LOG(" register [type] all : register all clients and server.\n");
+ WL_TBM_LOG(" unregister client [pid] : unregister the pid of client.\n");
+ WL_TBM_LOG(" unregister server : unregister the server.\n");
+ WL_TBM_LOG(" unregister all : unregister all clients and server.\n");
+ WL_TBM_LOG(" status : show the status of the dump setting values.\n");
+ WL_TBM_LOG(" <type>\n");
+ WL_TBM_LOG(" import : make dump when a tbm_bo is imported/exported.\n");
+ WL_TBM_LOG(" ref : make dump when a tbm_bo is ref/unref.\n");
+ WL_TBM_LOG(" map : make dump when a tbm_bo is mapped/unmapped.\n");
+ WL_TBM_LOG(" <examples>\n");
+ WL_TBM_LOG(" # wayland-tbm-monitor dump register map client 1234\n");
+ WL_TBM_LOG(" # wayland-tbm-monitor dump register import all\n");
+ WL_TBM_LOG(" # wayland-tbm-monitor dump unregister all\n");
+ WL_TBM_LOG(" # wayland-tbm-monitor dump snapshot all\n");
+ WL_TBM_LOG(" # wayland-tbm-monitor dump on\n");
+ WL_TBM_LOG(" # wayland-tbm-monitor dump off\n");
+ WL_TBM_LOG("\n");
+}
+
+
+static void
_wl_tbm_show_usage()
{
WL_TBM_LOG(" show : show the infomation of the tbm_bo\n");
_wl_tbm_list_usage();
_wl_tbm_show_usage();
_wl_tbm_trace_usage();
+ _wl_tbm_dump_usage();
WL_TBM_LOG("\n");
}
static int
+_wl_tbm_select_dump_type_option(struct wayland_tbm_monitor *tbm_monitor, int argc,
+ char *argv[], int arg_pos)
+{
+ if (!strncmp(argv[arg_pos], "import", strlen(argv[arg_pos]) + 1))
+ tbm_monitor->options.dump_type = WL_TBM_MONITOR_DUMP_TYPE_IMPORT;
+ else if (!strncmp(argv[arg_pos], "ref", strlen(argv[arg_pos]) + 1))
+ tbm_monitor->options.dump_type = WL_TBM_MONITOR_DUMP_TYPE_REF;
+ else if (!strncmp(argv[arg_pos], "map", strlen(argv[arg_pos]) + 1))
+ tbm_monitor->options.dump_type = WL_TBM_MONITOR_DUMP_TYPE_MAP;
+ else
+ return 0;
+
+ return 1;
+}
+
+static int
_wl_tbm_select_target_option(struct wayland_tbm_monitor *tbm_monitor, int argc,
char *argv[], int arg_pos)
{
_wl_tbm_trace_usage();
return 0;
}
+ } else if (!strncmp(argv[1], "dump", strlen(argv[1]) + 1)) {
+
+ tbm_monitor->options.command = WL_TBM_MONITOR_COMMAND_DUMP;
+
+ if (!strncmp(argv[2], "on", strlen(argv[2]) + 1)) {
+ tbm_monitor->options.dump_command = WL_TBM_MONITOR_DUMP_COMMAND_ON;
+ tbm_monitor->options.target = WL_TBM_MONITOR_TARGET_ALL;
+ } else if (!strncmp(argv[2], "off", strlen(argv[2]) + 1)) {
+ tbm_monitor->options.dump_command = WL_TBM_MONITOR_DUMP_COMMAND_OFF;
+ tbm_monitor->options.target = WL_TBM_MONITOR_TARGET_ALL;
+ } else if (!strncmp(argv[2], "snapshot", strlen(argv[2]) + 1)) {
+ tbm_monitor->options.dump_command = WL_TBM_MONITOR_DUMP_COMMAND_SNAPSHOT;
+ if (argc < 4)
+ tbm_monitor->options.target = WL_TBM_MONITOR_TARGET_ALL;
+ else {
+ if (!_wl_tbm_select_target_option(tbm_monitor, argc, argv, 3)) {
+ WL_TBM_LOG("error: no pid. please type the target(client [pid]/server/all).\n");
+ _wl_tbm_dump_usage();
+ return 0;
+ }
+ }
+ } else if (!strncmp(argv[2], "register", strlen(argv[2]) + 1)) {
+ if (argc < 5) {
+ WL_TBM_LOG("error: no pid. please type the target(client [pid]/server/all).\n");
+ _wl_tbm_dump_usage();
+ return 0;
+ }
+
+ tbm_monitor->options.trace_command = WL_TBM_MONITOR_DUMP_COMMAND_REGISTER;
+
+ if (!_wl_tbm_select_dump_type_option(tbm_monitor, argc, argv, 3)) {
+ _wl_tbm_dump_usage();
+ return 0;
+ }
+
+ if (!_wl_tbm_select_target_option(tbm_monitor, argc, argv, 4)) {
+ WL_TBM_LOG("error: no pid. please type the target(client [pid]/server/all).\n");
+ _wl_tbm_dump_usage();
+ return 0;
+ }
+ } else if (!strncmp(argv[2], "unregister", strlen(argv[2]) + 1)) {
+ if (argc < 4) {
+ WL_TBM_LOG("error: no pid. please type the target(client [pid]/server/all).\n");
+ _wl_tbm_dump_usage();
+ return 0;
+ }
+
+ tbm_monitor->options.trace_command = WL_TBM_MONITOR_DUMP_COMMAND_UNREGISTER;
+ if (!_wl_tbm_select_target_option(tbm_monitor, argc, argv, 3)) {
+ WL_TBM_LOG("error: no pid. please type the target(client [pid]/server/all).\n");
+ _wl_tbm_dump_usage();
+ return 0;
+ }
+ } else {
+ _wl_tbm_dump_usage();
+ return 0;
+ }
} else {
_wl_tbm_usage();
return 0;