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 _______________________________________________ Linux-audio-dev mailing list Linux-audio-dev@lists.linuxaudio.org http://lists.linuxaudio.org/listinfo/linux-audio-dev