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:
parent
f33a46072b
commit
8f1cfefbb2
14
ChangeLog
14
ChangeLog
@ -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):
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
119
src/theme.c
119
src/theme.c
@ -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
|
||||
{
|
||||
|
@ -260,6 +260,8 @@ struct _MetaDrawOp
|
||||
char *y;
|
||||
char *width;
|
||||
char *height;
|
||||
guint32 colorize_cache_pixel;
|
||||
GdkPixbuf *colorize_cache_pixbuf;
|
||||
} image;
|
||||
|
||||
struct {
|
||||
|
Loading…
Reference in New Issue
Block a user