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>
* 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);
if (colorize == NULL)
if (colorize_spec == NULL)
{
add_context_to_error (error, context);
g_object_unref (G_OBJECT (pixbuf));
return;
}
}

View File

@ -28,13 +28,15 @@
#include <time.h>
#include <stdlib.h>
static int client_width = 200;
static int client_height = 200;
#define CLIENT_WIDTH 200
#define CLIENT_HEIGHT 200
static MetaTheme *global_theme = NULL;
static void run_position_expression_tests (void);
static void run_position_expression_timings (void);
static void run_theme_benchmark (int client_width,
int client_height);
static MetaFrameFlags
get_flags (GtkWidget *widget)
@ -139,8 +141,8 @@ set_widget_to_frame_size (GtkWidget *widget)
&right_width);
gtk_widget_set_size_request (widget,
client_width + left_width + right_width,
client_height + top_height + bottom_height);
CLIENT_WIDTH + left_width + right_width,
CLIENT_HEIGHT + top_height + bottom_height);
}
static gboolean
@ -176,7 +178,7 @@ expose_handler (GtkWidget *widget,
0, 0,
META_FRAME_TYPE_NORMAL,
get_flags (widget),
client_width, client_height,
CLIENT_WIDTH, CLIENT_HEIGHT,
layout,
get_text_height (widget),
button_states,
@ -189,7 +191,7 @@ expose_handler (GtkWidget *widget,
widget->style->white_gc,
TRUE,
left_width, top_height,
client_width, client_height);
CLIENT_WIDTH, CLIENT_HEIGHT);
g_object_unref (G_OBJECT (layout));
@ -241,6 +243,8 @@ main (int argc, char **argv)
global_theme->name,
(end - start) / (double) CLOCKS_PER_SEC);
run_theme_benchmark (CLIENT_WIDTH, CLIENT_HEIGHT);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_default_size (GTK_WINDOW (window), 270, 270);
@ -285,6 +289,78 @@ main (int argc, char **argv)
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
{
GdkRectangle rect;

View File

@ -28,58 +28,81 @@
#include <string.h>
#include <stdlib.h>
#define GDK_COLOR_RGBA(color) \
(0xff | \
(((color).red / 256) << 24) | \
(((color).green / 256) << 16) | \
(((color).blue / 256) << 8))
#define GDK_COLOR_RGBA(color) \
((guint32) (0xff | \
(((color).red / 256) << 24) | \
(((color).green / 256) << 16) | \
(((color).blue / 256) << 8)))
#define GDK_COLOR_RGB(color) \
((((color).red / 256) << 16) | \
(((color).green / 256) << 8) | \
(((color).blue / 256)))
#define GDK_COLOR_RGB(color) \
((guint32) ((((color).red / 256) << 16) | \
(((color).green / 256) << 8) | \
(((color).blue / 256))))
#define ALPHA_TO_UCHAR(d) ((unsigned char) ((d) * 255))
#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 CLAMP_UCHAR(v) ((guchar) (CLAMP (((int)v), (int)0, (int)255)))
static GdkPixbuf *
colorize_pixbuf (GdkPixbuf *orig, GdkColor *new_color)
colorize_pixbuf (GdkPixbuf *orig,
GdkColor *new_color)
{
GdkPixbuf *pixbuf;
double intensity;
int x, y;
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;
g = new_color->green / 256;
b = new_color->blue / 256;
pixbuf = gdk_pixbuf_new (gdk_pixbuf_get_colorspace (orig), gdk_pixbuf_get_has_alpha (orig),
gdk_pixbuf_get_bits_per_sample (orig),
gdk_pixbuf_get_width (orig), gdk_pixbuf_get_height (orig));
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 < gdk_pixbuf_get_height (pixbuf); y++)
for (y = 0; y < height; y++)
{
src = gdk_pixbuf_get_pixels (orig) + y * gdk_pixbuf_get_rowstride (orig);
dest = gdk_pixbuf_get_pixels (pixbuf) + y * gdk_pixbuf_get_rowstride (pixbuf);
src = src_pixels + y * orig_rowstride;
dest = dest_pixels + y * dest_rowstride;
for (x = 0; x < gdk_pixbuf_get_width (pixbuf); x++) {
intensity = INTENSITY (src[0], src[1], src[2]) / 255.0;
dest[0] = (guchar)(r * intensity);
dest[1] = g * intensity;
dest[2] = b * intensity;
if (gdk_pixbuf_get_has_alpha (orig))
dest[3] = src[3];
src += gdk_pixbuf_get_has_alpha (orig) ? 4 : 3;
dest += gdk_pixbuf_get_has_alpha (pixbuf) ? 4 : 3;
}
for (x = 0; x < width; x++)
{
intensity = INTENSITY (src[0], src[1], src[2]) / 255.0;
dest[0] = CLAMP_UCHAR (r * intensity);
dest[1] = CLAMP_UCHAR (g * intensity);
dest[2] = CLAMP_UCHAR (b * intensity);
if (has_alpha)
{
dest[3] = src[3];
src += 4;
dest += 4;
}
else
{
src += 3;
dest += 3;
}
}
}
return pixbuf;
@ -2151,6 +2174,8 @@ meta_draw_op_free (MetaDrawOp *op)
g_object_unref (G_OBJECT (op->data.image.pixbuf));
if (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.y);
g_free (op->data.image.width);
@ -2345,7 +2370,6 @@ scale_and_alpha_pixbuf (GdkPixbuf *src,
pixbuf = NULL;
pixbuf = src;
if (gdk_pixbuf_get_width (pixbuf) == width &&
gdk_pixbuf_get_height (pixbuf) == height)
@ -2445,18 +2469,31 @@ draw_op_as_pixbuf (const MetaDrawOp *op,
{
if (op->data.image.colorize_spec)
{
GdkPixbuf *tmp_pixbuf;
GdkColor color;
meta_color_spec_render (op->data.image.colorize_spec,
widget, &color);
tmp_pixbuf = colorize_pixbuf (op->data.image.pixbuf,
&color);
pixbuf = scale_and_alpha_pixbuf (tmp_pixbuf,
op->data.image.alpha,
width, height);
g_object_unref (tmp_pixbuf);
meta_color_spec_render (op->data.image.colorize_spec,
widget, &color);
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,
width, height);
}
}
else
{

View File

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