[LAD] memory leak assistance

hermann brummer- at web.de
Wed Dec 30 12:47:54 UTC 2009


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




More information about the Linux-audio-dev mailing list