summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Larsson <alexl@redhat.com>2010-08-30 11:39:54 +0200
committerAlexander Larsson <alexl@redhat.com>2010-08-30 11:39:54 +0200
commit560234bc887441ed94c15a2314f3de12405c94b8 (patch)
tree7e75dc5544a633db08acb7974986e081f0fcc20d
parent9ac9099842a7379a991a70627ddf6fe47462fc4a (diff)
Add support for draw logging
-rw-r--r--client/display_channel.cpp144
-rw-r--r--client/inputs_channel.cpp10
-rw-r--r--client/x11/Makefile.am1
3 files changed, 155 insertions, 0 deletions
diff --git a/client/display_channel.cpp b/client/display_channel.cpp
index c371f4a..f3fb3ec 100644
--- a/client/display_channel.cpp
+++ b/client/display_channel.cpp
@@ -1510,9 +1510,153 @@ void DisplayChannel::handle_surface_destroy(RedPeer::InMessage* message)
destroy_surface(surface_destroy->surface_id);
}
}
+#ifdef LOG_DRAWING
+static const char *draw_op_name(int type) {
+ switch (type) {
+ case SPICE_MSG_DISPLAY_DRAW_FILL:
+ return "FILL";
+ case SPICE_MSG_DISPLAY_DRAW_OPAQUE:
+ return "OPAQUE";
+ case SPICE_MSG_DISPLAY_DRAW_COPY:
+ return "COPY";
+ case SPICE_MSG_DISPLAY_DRAW_BLEND:
+ return "BLEND";
+ case SPICE_MSG_DISPLAY_DRAW_BLACKNESS:
+ return "BLACKNESS";
+ case SPICE_MSG_DISPLAY_DRAW_WHITENESS:
+ return "WHITENESS";
+ case SPICE_MSG_DISPLAY_DRAW_INVERS:
+ return "INVERS";
+ case SPICE_MSG_DISPLAY_DRAW_ROP3:
+ return "ROP3";
+ case SPICE_MSG_DISPLAY_DRAW_STROKE:
+ return "STROKE";
+ case SPICE_MSG_DISPLAY_DRAW_TEXT:
+ return "TEXT";
+ case SPICE_MSG_DISPLAY_DRAW_TRANSPARENT:
+ return "TRANSPARENT";
+ case SPICE_MSG_DISPLAY_DRAW_ALPHA_BLEND:
+ return "ALPHA_BLEND";
+ default:
+ return "unknown";
+ }
+}
+
+int do_log_draw = 0;
+struct __attribute__ ((__packed__)) DrawLogEntry {
+ uint32_t text_length;
+ uint32_t surface_id;
+ uint32_t width;
+ uint32_t height;
+ uint32_t stride;
+ uint32_t format;
+ uint32_t box_x;
+ uint32_t box_y;
+ uint32_t box_w;
+ uint32_t box_h;
+ /* text */
+ /* canvas data */
+};
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+static void log_draw(int pre, RedPeer::InMessage* message, DisplaySurfacesManger &surfaces_mngr)
+{
+ SpiceMsgDisplayBase *base = (SpiceMsgDisplayBase*)message->data();
+ static int fd = -1;
+ SpiceCanvas *canvas;
+ pixman_image_t *image;
+ struct DrawLogEntry entry;
+ char buf[4096];
+
+ if (!do_log_draw) {
+ if (fd != -1) {
+ printf("Stopping draw logging\n");
+ close(fd);
+ fd = -1;
+ }
+ return;
+ }
+
+ if (fd == -1) {
+ char filename[1024];
+ long t = (long)time(NULL);
+
+ while (fd == -1) {
+ snprintf(filename, 1024, "/tmp/spice-log.%d.%ld", (int)getpid(), t);
+ fd = open(filename, O_WRONLY | O_CREAT | O_EXCL, 0666);
+ }
+ printf("Starting draw logging to %s\n", filename);
+ }
+
+ canvas = surfaces_mngr.get_canvas(base->surface_id)->get_internal_canvas();
+ image = canvas->ops->get_image(canvas);
+
+ if (pre) {
+ entry.text_length =
+ snprintf(buf, sizeof(buf),
+ "%s %d,%d %dx%d, clip: %d\n",
+ draw_op_name(message->type()),
+ base->box.left,
+ base->box.top,
+ base->box.right - base->box.left,
+ base->box.bottom - base->box.top,
+ base->clip.type);
+
+ switch (message->type()) {
+ case SPICE_MSG_DISPLAY_DRAW_COPY:
+ {
+ SpiceMsgDisplayDrawCopy *copy =
+ (SpiceMsgDisplayDrawCopy*)message->data();
+
+ entry.text_length +=
+ snprintf(buf + entry.text_length, sizeof(buf) - entry.text_length,
+ "src_bitmap type: %d, src_area: %d,%d %dx%d, rop: %d, scale mode: %d, mask: %p\n",
+ copy->data.src_bitmap ? copy->data.src_bitmap->descriptor.type : -1,
+ copy->data.src_area.left,
+ copy->data.src_area.top,
+ copy->data.src_area.right - copy->data.src_area.left,
+ copy->data.src_area.bottom - copy->data.src_area.top,
+ copy->data.rop_descriptor,
+ (int)copy->data.scale_mode,
+ copy->data.mask.bitmap);
+ }
+ break;
+ }
+
+ entry.box_x = base->box.left;
+ entry.box_y = base->box.top;
+ entry.box_w = base->box.right - base->box.left;
+ entry.box_h = base->box.bottom - base->box.top;
+ entry.format = spice_pixman_image_get_format(image);
+ entry.surface_id = base->surface_id;
+ entry.width = pixman_image_get_width(image);
+ entry.height = pixman_image_get_height(image);
+ entry.stride = pixman_image_get_stride(image);
+
+ write(fd, &entry, sizeof(entry));
+ write(fd, buf, entry.text_length);
+ }
+
+ write(fd,
+ pixman_image_get_data(image),
+ pixman_image_get_height(image) * pixman_image_get_stride(image));
+
+}
+
+#define PRE_DRAW log_draw(1, message, surfaces_mngr)
+#define POST_DRAW log_draw(0, message, surfaces_mngr)
+#endif
+
+#ifndef PRE_DRAW
#define PRE_DRAW
+#endif
+#ifndef POST_DRAW
#define POST_DRAW
+#endif
#define DRAW(type) { \
PRE_DRAW; \
diff --git a/client/inputs_channel.cpp b/client/inputs_channel.cpp
index 9ff5479..17dbe5f 100644
--- a/client/inputs_channel.cpp
+++ b/client/inputs_channel.cpp
@@ -352,6 +352,10 @@ uint32_t InputsChannel::get_break_scan_code(RedKey key)
return _scan_table[key].break_scan;
}
+#ifdef LOG_DRAWING
+extern int do_log_draw;
+#endif
+
void InputsChannel::on_key_down(RedKey key)
{
uint32_t scan_code = get_make_scan_code(key);
@@ -360,6 +364,12 @@ void InputsChannel::on_key_down(RedKey key)
return;
}
+#ifdef LOG_DRAWING
+ if (key == REDKEY_SCROLL_LOCK) {
+ do_log_draw = !do_log_draw;
+ }
+#endif
+
Message* message = new Message(SPICE_MSGC_INPUTS_KEY_DOWN);
SpiceMsgcKeyDown event;
event.code = scan_code;
diff --git a/client/x11/Makefile.am b/client/x11/Makefile.am
index 101f6dd..73ec3e6 100644
--- a/client/x11/Makefile.am
+++ b/client/x11/Makefile.am
@@ -10,6 +10,7 @@ INCLUDES = \
-DSW_CANVAS_NO_CHUNKS \
-DUSE_GLZ \
-D__STDC_LIMIT_MACROS \
+ -DLOG_DRAWING \
-I. \
-I.. \
-I$(COMMON_DIR) \