Я написал функцию drawCircle ниже, но чем больше кругов нарисовано / перерисовано, тем больше увеличивается использование памяти, поэтому я предполагаю, что где-то произошла утечка памяти, но я не могу ее выяснить. Я пытался удалить экземпляр в конце функции, но это не помогает.
void drawCircle(cairo_surface_t *container, int x, int y, int radius, float r, float g, float b, float a)
{
cairo_t *cairoInstance;
cairoInstance = cairo_create(container);
cairo_set_source_rgba(cairoInstance, r, g, b, a);
cairo_arc(cairoInstance, x, y, radius, 0, 2*M_PI);
cairo_stroke_preserve(cairoInstance);
cairo_fill_preserve(cairoInstance);
//delete cairoInstance;
gtk_widget_queue_draw_area(GTK_WIDGET(frame2), 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);
}
Есть идеи?
Заранее спасибо.
Несколько моментов:
cairo_t
s ссылки подсчитаны. Вызов cairo_destroy
когда вы закончите с вашим cairo_t*
, Кроме того, вам не нужно создавать и уничтожать cairo_t
для каждого круга — рефакторинг функции, вытягивая вызов cairo_create
,cairo_X
функции к cairo_X_preserve
из них. В вашем коде cairo_fill_preserve
должно быть cairo_preserve
, (Штрих должен быть сохранен, чтобы сработала следующая заливка.)gtk_widget_queue_draw_area
может быть реорганизован, и только один раз за тираж.gtk_widget_queue_draw_area
делает недействительной прямоугольную область окна виджетов — вы можете просто gdk_window_invalidate_rect
— увидеть документацияПсевдо-код после рефакторинга (с гипотетическим типом Circle):
void drawCircle(cairo_t *cr, int x, int y, int radius, float r, float g, float b, float a) {
cairo_set_source_rgba(cr, r, g, b, a);
cairo_arc(cr, x, y, radius, 0, 2*M_PI);
cairo_stroke_preserve(cr); // keep the arc so that we can call cairo_fill
cairo_fill(cr);
}
void functionThatDrawsCircles(cairo_surface_t* surface, Circle* circles, int num) {
cairo_t* cr = cairo_create(surface);
for(int i = 0; i < num; i++) {
drawCircle(cr, circles[i].x, circles[i].y, 10, circles[i].r, circles[i].g, circles[i].b, 1.0);
}
cairo_destroy(cr);
gtk_widget_queue_draw_area(GTK_WIDGET(frame2), 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);
}
Других решений пока нет …