benchmark theme on startup

2002-02-06  Havoc Pennington  <hp@pobox.com>

	* src/theme-viewer.c: benchmark theme on startup

	* src/theme-parser.c (parse_draw_op_element): fix "colorize !=
	NULL" to "colorize_spec != NULL" and free pixbuf on color spec
	failure

	* src/theme.c (colorize_pixbuf): minor reformatting, raise
	function calls out of inner loop, clamp r/g/b values to uchar
	range before assigning to uchar
	(draw_op_as_pixbuf): cache the colorized pixbuf
	(meta_draw_op_free): free the cache pixbuf
This commit is contained in:
Havoc Pennington 2002-02-07 04:22:57 +00:00 committed by Havoc Pennington
parent f33a46072b
commit 8f1cfefbb2
5 changed files with 178 additions and 48 deletions

View File

@ -1,3 +1,17 @@
2002-02-06 Havoc Pennington <hp@pobox.com>
* src/theme-viewer.c: benchmark theme on startup
* src/theme-parser.c (parse_draw_op_element): fix "colorize !=
NULL" to "colorize_spec != NULL" and free pixbuf on color spec
failure
* src/theme.c (colorize_pixbuf): minor reformatting, raise
function calls out of inner loop, clamp r/g/b values to uchar
range before assigning to uchar
(draw_op_as_pixbuf): cache the colorized pixbuf
(meta_draw_op_free): free the cache pixbuf
2002-02-07 Anders Carlsson <andersca@gnu.org> 2002-02-07 Anders Carlsson <andersca@gnu.org>
* src/theme-parser.c: (parse_draw_op_element): * src/theme-parser.c: (parse_draw_op_element):

View File

@ -2071,9 +2071,10 @@ parse_draw_op_element (GMarkupParseContext *context,
{ {
colorize_spec = meta_color_spec_new_from_string (colorize, error); colorize_spec = meta_color_spec_new_from_string (colorize, error);
if (colorize == NULL) if (colorize_spec == NULL)
{ {
add_context_to_error (error, context); add_context_to_error (error, context);
g_object_unref (G_OBJECT (pixbuf));
return; return;
} }
} }

View File

@ -28,13 +28,15 @@
#include <time.h> #include <time.h>
#include <stdlib.h> #include <stdlib.h>
static int client_width = 200; #define CLIENT_WIDTH 200
static int client_height = 200; #define CLIENT_HEIGHT 200
static MetaTheme *global_theme = NULL; static MetaTheme *global_theme = NULL;
static void run_position_expression_tests (void); static void run_position_expression_tests (void);
static void run_position_expression_timings (void); static void run_position_expression_timings (void);
static void run_theme_benchmark (int client_width,
int client_height);
static MetaFrameFlags static MetaFrameFlags
get_flags (GtkWidget *widget) get_flags (GtkWidget *widget)
@ -139,8 +141,8 @@ set_widget_to_frame_size (GtkWidget *widget)
&right_width); &right_width);
gtk_widget_set_size_request (widget, gtk_widget_set_size_request (widget,
client_width + left_width + right_width, CLIENT_WIDTH + left_width + right_width,
client_height + top_height + bottom_height); CLIENT_HEIGHT + top_height + bottom_height);
} }
static gboolean static gboolean
@ -176,7 +178,7 @@ expose_handler (GtkWidget *widget,
0, 0, 0, 0,
META_FRAME_TYPE_NORMAL, META_FRAME_TYPE_NORMAL,
get_flags (widget), get_flags (widget),
client_width, client_height, CLIENT_WIDTH, CLIENT_HEIGHT,
layout, layout,
get_text_height (widget), get_text_height (widget),
button_states, button_states,
@ -189,7 +191,7 @@ expose_handler (GtkWidget *widget,
widget->style->white_gc, widget->style->white_gc,
TRUE, TRUE,
left_width, top_height, left_width, top_height,
client_width, client_height); CLIENT_WIDTH, CLIENT_HEIGHT);
g_object_unref (G_OBJECT (layout)); g_object_unref (G_OBJECT (layout));
@ -241,6 +243,8 @@ main (int argc, char **argv)
global_theme->name, global_theme->name,
(end - start) / (double) CLOCKS_PER_SEC); (end - start) / (double) CLOCKS_PER_SEC);
run_theme_benchmark (CLIENT_WIDTH, CLIENT_HEIGHT);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL); window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_default_size (GTK_WINDOW (window), 270, 270); gtk_window_set_default_size (GTK_WINDOW (window), 270, 270);
@ -285,6 +289,78 @@ main (int argc, char **argv)
return 0; return 0;
} }
static void
run_theme_benchmark (int client_width,
int client_height)
{
GtkWidget* widget;
GdkPixmap *pixmap;
int top_height, bottom_height, left_width, right_width;
MetaButtonState button_states[META_BUTTON_TYPE_LAST] =
{
META_BUTTON_STATE_NORMAL,
META_BUTTON_STATE_NORMAL,
META_BUTTON_STATE_NORMAL,
META_BUTTON_STATE_NORMAL
};
PangoLayout *layout;
clock_t start;
clock_t end;
int i;
#define ITERATIONS 100
widget = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_widget_realize (widget);
meta_theme_get_frame_borders (global_theme,
META_FRAME_TYPE_NORMAL,
get_text_height (widget),
get_flags (widget),
&top_height,
&bottom_height,
&left_width,
&right_width);
pixmap = gdk_pixmap_new (widget->window,
client_width + left_width + right_width,
client_height + top_height + bottom_height,
-1);
layout = create_title_layout (widget);
start = clock ();
i = 0;
while (i < ITERATIONS)
{
meta_theme_draw_frame (global_theme,
widget,
pixmap,
NULL,
0, 0,
META_FRAME_TYPE_NORMAL,
get_flags (widget),
client_width, client_height,
layout,
get_text_height (widget),
button_states,
get_mini_icon (),
get_icon ());
++i;
}
end = clock ();
g_print ("Drew %d frames for %dx%d clients in %g seconds (%g seconds per frame)\n",
ITERATIONS, client_width, client_height,
((double)end - (double)start) / CLOCKS_PER_SEC,
((double)end - (double)start) / CLOCKS_PER_SEC / (double) ITERATIONS);
g_object_unref (G_OBJECT (layout));
g_object_unref (G_OBJECT (pixmap));
gtk_widget_destroy (widget);
}
typedef struct typedef struct
{ {
GdkRectangle rect; GdkRectangle rect;

View File

@ -29,29 +29,38 @@
#include <stdlib.h> #include <stdlib.h>
#define GDK_COLOR_RGBA(color) \ #define GDK_COLOR_RGBA(color) \
(0xff | \ ((guint32) (0xff | \
(((color).red / 256) << 24) | \ (((color).red / 256) << 24) | \
(((color).green / 256) << 16) | \ (((color).green / 256) << 16) | \
(((color).blue / 256) << 8)) (((color).blue / 256) << 8)))
#define GDK_COLOR_RGB(color) \ #define GDK_COLOR_RGB(color) \
((((color).red / 256) << 16) | \ ((guint32) ((((color).red / 256) << 16) | \
(((color).green / 256) << 8) | \ (((color).green / 256) << 8) | \
(((color).blue / 256))) (((color).blue / 256))))
#define ALPHA_TO_UCHAR(d) ((unsigned char) ((d) * 255)) #define ALPHA_TO_UCHAR(d) ((unsigned char) ((d) * 255))
#define DEBUG_FILL_STRUCT(s) memset ((s), 0xef, sizeof (*(s))) #define DEBUG_FILL_STRUCT(s) memset ((s), 0xef, sizeof (*(s)))
#define INTENSITY(r, g, b) (r * 0.30 + g * 0.59 + b * 0.11) #define INTENSITY(r, g, b) (r * 0.30 + g * 0.59 + b * 0.11)
#define CLAMP_UCHAR(v) ((guchar) (CLAMP (((int)v), (int)0, (int)255)))
static GdkPixbuf * static GdkPixbuf *
colorize_pixbuf (GdkPixbuf *orig, GdkColor *new_color) colorize_pixbuf (GdkPixbuf *orig,
GdkColor *new_color)
{ {
GdkPixbuf *pixbuf; GdkPixbuf *pixbuf;
double intensity; double intensity;
int x, y; int x, y;
guchar r, g, b; guchar r, g, b;
guchar *src, *dest; const guchar *src;
guchar *dest;
int orig_rowstride;
int dest_rowstride;
int width, height;
gboolean has_alpha;
const guchar *src_pixels;
guchar *dest_pixels;
r = new_color->red / 256; r = new_color->red / 256;
g = new_color->green / 256; g = new_color->green / 256;
@ -61,24 +70,38 @@ colorize_pixbuf (GdkPixbuf *orig, GdkColor *new_color)
gdk_pixbuf_get_bits_per_sample (orig), gdk_pixbuf_get_bits_per_sample (orig),
gdk_pixbuf_get_width (orig), gdk_pixbuf_get_height (orig)); gdk_pixbuf_get_width (orig), gdk_pixbuf_get_height (orig));
for (y = 0; y < gdk_pixbuf_get_height (pixbuf); y++) orig_rowstride = gdk_pixbuf_get_rowstride (orig);
dest_rowstride = gdk_pixbuf_get_rowstride (pixbuf);
width = gdk_pixbuf_get_width (pixbuf);
height = gdk_pixbuf_get_height (pixbuf);
has_alpha = gdk_pixbuf_get_has_alpha (orig);
src_pixels = gdk_pixbuf_get_pixels (orig);
dest_pixels = gdk_pixbuf_get_pixels (pixbuf);
for (y = 0; y < height; y++)
{ {
src = gdk_pixbuf_get_pixels (orig) + y * gdk_pixbuf_get_rowstride (orig); src = src_pixels + y * orig_rowstride;
dest = gdk_pixbuf_get_pixels (pixbuf) + y * gdk_pixbuf_get_rowstride (pixbuf); dest = dest_pixels + y * dest_rowstride;
for (x = 0; x < gdk_pixbuf_get_width (pixbuf); x++) {
for (x = 0; x < width; x++)
{
intensity = INTENSITY (src[0], src[1], src[2]) / 255.0; intensity = INTENSITY (src[0], src[1], src[2]) / 255.0;
dest[0] = (guchar)(r * intensity); dest[0] = CLAMP_UCHAR (r * intensity);
dest[1] = g * intensity; dest[1] = CLAMP_UCHAR (g * intensity);
dest[2] = b * intensity; dest[2] = CLAMP_UCHAR (b * intensity);
if (gdk_pixbuf_get_has_alpha (orig)) if (has_alpha)
{
dest[3] = src[3]; dest[3] = src[3];
src += 4;
src += gdk_pixbuf_get_has_alpha (orig) ? 4 : 3; dest += 4;
dest += gdk_pixbuf_get_has_alpha (pixbuf) ? 4 : 3; }
else
{
src += 3;
dest += 3;
}
} }
} }
@ -2151,6 +2174,8 @@ meta_draw_op_free (MetaDrawOp *op)
g_object_unref (G_OBJECT (op->data.image.pixbuf)); g_object_unref (G_OBJECT (op->data.image.pixbuf));
if (op->data.image.colorize_spec) if (op->data.image.colorize_spec)
meta_color_spec_free (op->data.image.colorize_spec); meta_color_spec_free (op->data.image.colorize_spec);
if (op->data.image.colorize_cache_pixbuf)
g_object_unref (G_OBJECT (op->data.image.colorize_cache_pixbuf));
g_free (op->data.image.x); g_free (op->data.image.x);
g_free (op->data.image.y); g_free (op->data.image.y);
g_free (op->data.image.width); g_free (op->data.image.width);
@ -2345,7 +2370,6 @@ scale_and_alpha_pixbuf (GdkPixbuf *src,
pixbuf = NULL; pixbuf = NULL;
pixbuf = src; pixbuf = src;
if (gdk_pixbuf_get_width (pixbuf) == width && if (gdk_pixbuf_get_width (pixbuf) == width &&
gdk_pixbuf_get_height (pixbuf) == height) gdk_pixbuf_get_height (pixbuf) == height)
@ -2445,18 +2469,31 @@ draw_op_as_pixbuf (const MetaDrawOp *op,
{ {
if (op->data.image.colorize_spec) if (op->data.image.colorize_spec)
{ {
GdkPixbuf *tmp_pixbuf;
GdkColor color; GdkColor color;
meta_color_spec_render (op->data.image.colorize_spec, meta_color_spec_render (op->data.image.colorize_spec,
widget, &color); widget, &color);
tmp_pixbuf = colorize_pixbuf (op->data.image.pixbuf,
&color);
pixbuf = scale_and_alpha_pixbuf (tmp_pixbuf, if (op->data.image.colorize_cache_pixbuf == NULL ||
op->data.image.colorize_cache_pixel != GDK_COLOR_RGB (color))
{
if (op->data.image.colorize_cache_pixbuf)
g_object_unref (G_OBJECT (op->data.image.colorize_cache_pixbuf));
/* const cast here */
((MetaDrawOp*)op)->data.image.colorize_cache_pixbuf =
colorize_pixbuf (op->data.image.pixbuf,
&color);
((MetaDrawOp*)op)->data.image.colorize_cache_pixel =
GDK_COLOR_RGB (color);
}
if (op->data.image.colorize_cache_pixbuf)
{
pixbuf = scale_and_alpha_pixbuf (op->data.image.colorize_cache_pixbuf,
op->data.image.alpha, op->data.image.alpha,
width, height); width, height);
g_object_unref (tmp_pixbuf); }
} }
else else
{ {

View File

@ -260,6 +260,8 @@ struct _MetaDrawOp
char *y; char *y;
char *width; char *width;
char *height; char *height;
guint32 colorize_cache_pixel;
GdkPixbuf *colorize_cache_pixbuf;
} image; } image;
struct { struct {