[debug] Adds a dump-pick-buffers CLUTTER_DEBUG option
Now if you export CLUTTER_DEBUG=dump-pick-buffers clutter will write out a png, e.g. pick-buffer-00000.png, each time _clutter_to_pick() is called. It's a rather crude way to debug the picking (realtime visualization in a second stage would probably be nicer) but it we've used this approach successfully numerous times when debugging Clutter picking issues so it makes sense to have a debug option for it.
This commit is contained in:
parent
27ae9722de
commit
dae569b468
@ -7,23 +7,24 @@
|
|||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
CLUTTER_DEBUG_MISC = 1 << 0,
|
CLUTTER_DEBUG_MISC = 1 << 0,
|
||||||
CLUTTER_DEBUG_ACTOR = 1 << 1,
|
CLUTTER_DEBUG_ACTOR = 1 << 1,
|
||||||
CLUTTER_DEBUG_TEXTURE = 1 << 2,
|
CLUTTER_DEBUG_TEXTURE = 1 << 2,
|
||||||
CLUTTER_DEBUG_EVENT = 1 << 3,
|
CLUTTER_DEBUG_EVENT = 1 << 3,
|
||||||
CLUTTER_DEBUG_PAINT = 1 << 4,
|
CLUTTER_DEBUG_PAINT = 1 << 4,
|
||||||
CLUTTER_DEBUG_GL = 1 << 5,
|
CLUTTER_DEBUG_GL = 1 << 5,
|
||||||
CLUTTER_DEBUG_ALPHA = 1 << 6,
|
CLUTTER_DEBUG_ALPHA = 1 << 6,
|
||||||
CLUTTER_DEBUG_BEHAVIOUR = 1 << 7,
|
CLUTTER_DEBUG_BEHAVIOUR = 1 << 7,
|
||||||
CLUTTER_DEBUG_PANGO = 1 << 8,
|
CLUTTER_DEBUG_PANGO = 1 << 8,
|
||||||
CLUTTER_DEBUG_BACKEND = 1 << 9,
|
CLUTTER_DEBUG_BACKEND = 1 << 9,
|
||||||
CLUTTER_DEBUG_SCHEDULER = 1 << 10,
|
CLUTTER_DEBUG_SCHEDULER = 1 << 10,
|
||||||
CLUTTER_DEBUG_SCRIPT = 1 << 11,
|
CLUTTER_DEBUG_SCRIPT = 1 << 11,
|
||||||
CLUTTER_DEBUG_SHADER = 1 << 12,
|
CLUTTER_DEBUG_SHADER = 1 << 12,
|
||||||
CLUTTER_DEBUG_MULTISTAGE = 1 << 13,
|
CLUTTER_DEBUG_MULTISTAGE = 1 << 13,
|
||||||
CLUTTER_DEBUG_ANIMATION = 1 << 14,
|
CLUTTER_DEBUG_ANIMATION = 1 << 14,
|
||||||
CLUTTER_DEBUG_LAYOUT = 1 << 15,
|
CLUTTER_DEBUG_LAYOUT = 1 << 15,
|
||||||
CLUTTER_DEBUG_NOP_PICKING = 1 << 16,
|
CLUTTER_DEBUG_NOP_PICKING = 1 << 16,
|
||||||
|
CLUTTER_DEBUG_DUMP_PICK_BUFFERS = 1 << 17,
|
||||||
} ClutterDebugFlag;
|
} ClutterDebugFlag;
|
||||||
|
|
||||||
#ifdef CLUTTER_ENABLE_DEBUG
|
#ifdef CLUTTER_ENABLE_DEBUG
|
||||||
|
@ -38,6 +38,8 @@
|
|||||||
#include <glib/gi18n-lib.h>
|
#include <glib/gi18n-lib.h>
|
||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
|
|
||||||
|
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||||
|
|
||||||
#include "clutter-event.h"
|
#include "clutter-event.h"
|
||||||
#include "clutter-backend.h"
|
#include "clutter-backend.h"
|
||||||
#include "clutter-main.h"
|
#include "clutter-main.h"
|
||||||
@ -95,7 +97,8 @@ static const GDebugKey clutter_debug_keys[] = {
|
|||||||
{ "multistage", CLUTTER_DEBUG_MULTISTAGE },
|
{ "multistage", CLUTTER_DEBUG_MULTISTAGE },
|
||||||
{ "animation", CLUTTER_DEBUG_ANIMATION },
|
{ "animation", CLUTTER_DEBUG_ANIMATION },
|
||||||
{ "layout", CLUTTER_DEBUG_LAYOUT },
|
{ "layout", CLUTTER_DEBUG_LAYOUT },
|
||||||
{ "nop-picking", CLUTTER_DEBUG_NOP_PICKING }
|
{ "nop-picking", CLUTTER_DEBUG_NOP_PICKING },
|
||||||
|
{ "dump-pick-buffers", CLUTTER_DEBUG_DUMP_PICK_BUFFERS }
|
||||||
};
|
};
|
||||||
#endif /* CLUTTER_ENABLE_DEBUG */
|
#endif /* CLUTTER_ENABLE_DEBUG */
|
||||||
|
|
||||||
@ -336,6 +339,13 @@ _clutter_id_to_color (guint id, ClutterColor *col)
|
|||||||
col->green = green;
|
col->green = green;
|
||||||
col->blue = blue;
|
col->blue = blue;
|
||||||
col->alpha = 0xff;
|
col->alpha = 0xff;
|
||||||
|
|
||||||
|
if (G_UNLIKELY (clutter_debug_flags & CLUTTER_DEBUG_DUMP_PICK_BUFFERS))
|
||||||
|
{
|
||||||
|
col->red = (col->red << 4) | (col->red >> 4);
|
||||||
|
col->green = (col->green << 4) | (col->green >> 4);
|
||||||
|
col->blue = (col->blue << 4) | (col->blue >> 4);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
guint
|
guint
|
||||||
@ -350,9 +360,22 @@ _clutter_pixel_to_id (guchar pixel[4])
|
|||||||
/* reduce the pixel components to the number of bits actually used of the
|
/* reduce the pixel components to the number of bits actually used of the
|
||||||
* 8bits.
|
* 8bits.
|
||||||
*/
|
*/
|
||||||
red = pixel[0] >> (8 - ctx->fb_r_mask);
|
if (G_UNLIKELY (clutter_debug_flags & CLUTTER_DEBUG_DUMP_PICK_BUFFERS))
|
||||||
green = pixel[1] >> (8 - ctx->fb_g_mask);
|
{
|
||||||
blue = pixel[2] >> (8 - ctx->fb_b_mask);
|
guchar tmp;
|
||||||
|
tmp = ((pixel[0] << 4) | (pixel[0] >> 4));
|
||||||
|
red = tmp >> (8 - ctx->fb_r_mask);
|
||||||
|
tmp = ((pixel[1] << 4) | (pixel[1] >> 4));
|
||||||
|
green = tmp >> (8 - ctx->fb_g_mask);
|
||||||
|
tmp = ((pixel[2] << 4) | (pixel[2] >> 4));
|
||||||
|
blue = tmp >> (8 - ctx->fb_b_mask);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
red = pixel[0] >> (8 - ctx->fb_r_mask);
|
||||||
|
green = pixel[1] >> (8 - ctx->fb_g_mask);
|
||||||
|
blue = pixel[2] >> (8 - ctx->fb_b_mask);
|
||||||
|
}
|
||||||
|
|
||||||
/* divide potentially by two if 'fuzzy' */
|
/* divide potentially by two if 'fuzzy' */
|
||||||
red = red >> (ctx->fb_r_mask - ctx->fb_r_mask_used);
|
red = red >> (ctx->fb_r_mask - ctx->fb_r_mask_used);
|
||||||
@ -366,6 +389,58 @@ _clutter_pixel_to_id (guchar pixel[4])
|
|||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
pixbuf_free (guchar *pixels, gpointer data)
|
||||||
|
{
|
||||||
|
g_free (pixels);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
read_pixels_to_file (char *filename_stem,
|
||||||
|
int x,
|
||||||
|
int y,
|
||||||
|
int width,
|
||||||
|
int height)
|
||||||
|
{
|
||||||
|
GLubyte *data;
|
||||||
|
GdkPixbuf *pixbuf;
|
||||||
|
static int read_count = 0;
|
||||||
|
GdkPixbuf *flipped;
|
||||||
|
|
||||||
|
data = g_malloc (4 * width * height);
|
||||||
|
glReadPixels (0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, data);
|
||||||
|
pixbuf = gdk_pixbuf_new_from_data (data,
|
||||||
|
GDK_COLORSPACE_RGB,
|
||||||
|
TRUE, /* has alpha */
|
||||||
|
8, /* bits per sample */
|
||||||
|
width, /* width */
|
||||||
|
height, /* height */
|
||||||
|
width * 4, /* rowstride */
|
||||||
|
pixbuf_free, /* callback to free data */
|
||||||
|
NULL); /* callback data */
|
||||||
|
if (pixbuf)
|
||||||
|
{
|
||||||
|
flipped = gdk_pixbuf_flip (pixbuf, FALSE);
|
||||||
|
g_object_unref (pixbuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flipped)
|
||||||
|
{
|
||||||
|
char *filename =
|
||||||
|
g_strdup_printf ("%s-%05d.png", filename_stem, read_count);
|
||||||
|
GError *error = NULL;
|
||||||
|
if (!gdk_pixbuf_save (flipped, filename, "png", &error, NULL))
|
||||||
|
{
|
||||||
|
g_warning ("Failed to save pick buffer to file %s: %s",
|
||||||
|
filename, error->message);
|
||||||
|
g_error_free (error);
|
||||||
|
}
|
||||||
|
g_free (filename);
|
||||||
|
g_object_unref (flipped);
|
||||||
|
read_count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ClutterActor *
|
ClutterActor *
|
||||||
_clutter_do_pick (ClutterStage *stage,
|
_clutter_do_pick (ClutterStage *stage,
|
||||||
gint x,
|
gint x,
|
||||||
@ -389,7 +464,9 @@ _clutter_do_pick (ClutterStage *stage,
|
|||||||
/* needed for when a context switch happens */
|
/* needed for when a context switch happens */
|
||||||
_clutter_stage_maybe_setup_viewport (stage);
|
_clutter_stage_maybe_setup_viewport (stage);
|
||||||
|
|
||||||
cogl_clip_push_window_rect (x, y, 1, 1);
|
if (G_LIKELY (!(clutter_debug_flags & CLUTTER_DEBUG_DUMP_PICK_BUFFERS)))
|
||||||
|
cogl_clip_push_window_rect (x, y, 1, 1);
|
||||||
|
|
||||||
cogl_color_set_from_4ub (&white, 255, 255, 255, 255);
|
cogl_color_set_from_4ub (&white, 255, 255, 255, 255);
|
||||||
cogl_disable_fog ();
|
cogl_disable_fog ();
|
||||||
cogl_clear (&white,
|
cogl_clear (&white,
|
||||||
@ -407,7 +484,9 @@ _clutter_do_pick (ClutterStage *stage,
|
|||||||
context->pick_mode = mode;
|
context->pick_mode = mode;
|
||||||
clutter_actor_paint (CLUTTER_ACTOR (stage));
|
clutter_actor_paint (CLUTTER_ACTOR (stage));
|
||||||
context->pick_mode = CLUTTER_PICK_NONE;
|
context->pick_mode = CLUTTER_PICK_NONE;
|
||||||
cogl_clip_pop ();
|
|
||||||
|
if (G_LIKELY (!(clutter_debug_flags & CLUTTER_DEBUG_DUMP_PICK_BUFFERS)))
|
||||||
|
cogl_clip_pop ();
|
||||||
|
|
||||||
/* Calls should work under both GL and GLES, note GLES needs RGBA */
|
/* Calls should work under both GL and GLES, note GLES needs RGBA */
|
||||||
glGetIntegerv(GL_VIEWPORT, viewport);
|
glGetIntegerv(GL_VIEWPORT, viewport);
|
||||||
@ -418,6 +497,9 @@ _clutter_do_pick (ClutterStage *stage,
|
|||||||
/* Read the color of the screen co-ords pixel */
|
/* Read the color of the screen co-ords pixel */
|
||||||
glReadPixels (x, viewport[3] - y -1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
|
glReadPixels (x, viewport[3] - y -1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
|
||||||
|
|
||||||
|
if (G_UNLIKELY (clutter_debug_flags & CLUTTER_DEBUG_DUMP_PICK_BUFFERS))
|
||||||
|
read_pixels_to_file ("pick-buffer", 0, 0, viewport[2], viewport[3]);
|
||||||
|
|
||||||
/* Restore whether GL_DITHER was enabled */
|
/* Restore whether GL_DITHER was enabled */
|
||||||
if (dither_was_on)
|
if (dither_was_on)
|
||||||
glEnable (GL_DITHER);
|
glEnable (GL_DITHER);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user