Am Mittwoch, den 30.12.2009, 22:50 +1100 schrieb Patrick Shirkey:
Thanks for your ideas on nailing this bug.
Below is what I have come up with now thanks to your input. I am still
seeing a leak after about 8 mins. The slightly annoying thing to me is
that it increments in a block of 200MB and not gradually. It's as though
pango/gtk is requesting an additional block of memory cache to fill up
each time.
The widget class is a custom class called gtkmeter.c which doesn't have
an internal font description or text value. The code below is for
writing the notch values onto the gtkmeter so this method is called
multiple times for each redraw of the widget. There are 16 instances of
the widget with 11 notch values on each one making a total of 176
requests to this method every 500ms. At 200MB/8 mins that is about 20kb
leak per redraw or approx 120 bytes per request.
db is a float value passed in the method variables.
+++++++++++++++++++++++++++++++++++++++
PangoLayout *pl;
PangoRectangle rect;
GtkStyle *style = gtk_widget_get_style(widget);
char text[3];
snprintf(text, 3, "%.0f", fabs(db));
pl = gtk_widget_create_pango_layout(widget,text);
pango_layout_get_pixel_extents(pl, &rect, NULL);
x = pos - rect.width/2 + 1;
y = width/2 - rect.height / 2 + 1;
if (x < 1) {
x = 1;
} else if (x + rect.width > length) {
x = length - rect.width + 1;
}
gdk_draw_layout(widget->window, widget->style->black_gc, x, y, pl);
last_label_rect->width = rect.width;
last_label_rect->height = rect.height;
last_label_rect->x = x;
last_label_rect->y = y;
g_object_unref (pl);
+++++++++++++++++++++++++++++++++++++++
Patrick Shirkey
Boost Hardware Ltd
We use also level meters in guitarix and jcgui, what we do to create the
notch scale is, move it to a background box, a simple hbox, witch we
connect with a expose call. This way the values and scale only redraw
when needed. This is the call we use:
gboolean meter_scale_expose(GtkWidget *wi, GdkEventExpose *ev, gpointer
user_data)
{
cairo_t *cr;
/* create a cairo context */
cr = gdk_cairo_create(wi->window);
cairo_set_font_size (cr, 7.0);
double x0 = wi->allocation.x+1;
double y0 = wi->allocation.y+2;
double rect_width = wi->allocation.width-2;
double rect_height = wi->allocation.height-4;
int db_points[] = { -50, -40, -20, -30, -10, -3, 0, 4 };
char buf[32];
cairo_rectangle (cr, x0,y0,rect_width,rect_height+2);
cairo_set_source_rgb (cr, 0, 0, 0);
cairo_fill (cr);
cairo_pattern_t*pat =
cairo_pattern_create_radial (-50, y0, 5,rect_width-10,
rect_height, 20.0);
cairo_pattern_add_color_stop_rgb (pat, 0, 0.2, 0.2, 0.3);
cairo_pattern_add_color_stop_rgb (pat, 1, 0.05, 0.05, 0.05);
cairo_set_source (cr, pat);
cairo_rectangle (cr, x0+1,y0+1,rect_width-2,rect_height-2);
cairo_fill (cr);
for (uint32_t i = 0; i < sizeof (db_points)/sizeof (db_points[0]);
++i)
{
float fraction = log_meter (db_points[i]);
cairo_set_source_rgb (cr, 0.12*i, 1, 0.1);
cairo_move_to (cr, x0+rect_width*0.2,y0+rect_height -
(rect_height * fraction));
cairo_line_to (cr, x0+rect_width*0.8 ,y0+rect_height -
(rect_height * fraction));
if (i<6)
{
snprintf (buf, sizeof (buf), "%d", db_points[i]);
cairo_move_to (cr, x0+rect_width*0.32,y0+rect_height -
(rect_height * fraction));
}
else
{
snprintf (buf, sizeof (buf), " %d", db_points[i]);
cairo_move_to (cr, x0+rect_width*0.34,y0+rect_height -
(rect_height * fraction));
}
cairo_show_text (cr, buf);
}
cairo_set_source_rgb (cr, 0.4, 0.8, 0.4);
cairo_set_line_width (cr, 0.5);
cairo_stroke (cr);
cairo_pattern_destroy (pat);
cairo_destroy(cr);
return FALSE;
}
it draw a black box with light in the upper left corner, and a scale
with values draw in dark green over light green to red.
regards hermann