diff options
author | Alexander Larsson <alexl@redhat.com> | 2010-08-30 11:39:54 +0200 |
---|---|---|
committer | Alexander Larsson <alexl@redhat.com> | 2010-08-30 11:39:54 +0200 |
commit | 560234bc887441ed94c15a2314f3de12405c94b8 (patch) | |
tree | 7e75dc5544a633db08acb7974986e081f0fcc20d | |
parent | 9ac9099842a7379a991a70627ddf6fe47462fc4a (diff) |
Add support for draw logging
-rw-r--r-- | client/display_channel.cpp | 144 | ||||
-rw-r--r-- | client/inputs_channel.cpp | 10 | ||||
-rw-r--r-- | client/x11/Makefile.am | 1 |
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) \ |