マルチスレッド、GTK3、カイロ:カイロ表面に描く
質問
スレッドからカイロイメージサーフェスを描こうとしていて、私は主張エラーを受けています:
gtk_mt:/build/buildd / cairo-1.10.2/src/cailo-surface.c:385: _cailo_surface_begin_modification:アサーション `!表面 - >完成しました。中止された(コアダンプ)
これは私のプログラムです:
.#include <stdlib.h> #include <gtk/gtk.h> #include <gdk/gdk.h> #include <cairo.h> #define IMAGE_WIDTH 320 #define IMAGE_HEIGHT 200 gpointer thread_func(gpointer data) { int x, y; unsigned char rgb_r, rgb_g, rgb_b; GtkWidget *widget = (GtkWidget*)data; GdkWindow *window; cairo_t *cr; cairo_format_t format = CAIRO_FORMAT_ARGB32; cairo_surface_t *surface; unsigned char *image_data, *rgbptr; int width = IMAGE_WIDTH; int height = IMAGE_HEIGHT; int stride; gdk_threads_enter(); stride = cairo_format_stride_for_width(format, width); image_data = malloc(stride * height); surface = cairo_image_surface_create_for_data(image_data, format, width, height, stride); window = gtk_widget_get_window(widget); cr = gdk_cairo_create(window); gdk_threads_leave(); while(1) { rgb_r = random() & 0xff; rgb_g = random() & 0xff; rgb_b = random() & 0xff; for(y = 0; y < height; ++y) { rgbptr = &image_data[y * stride]; if(!(random() & 0x3f)) { rgb_r = random() & 0xff; rgb_g = random() & 0xff; rgb_b = random() & 0xff; } for(x = 0; x < width; ++x) { *rgbptr++ = rgb_r; *rgbptr++ = rgb_g; *rgbptr++ = rgb_b; *rgbptr = 0xff; } } gdk_threads_enter(); cairo_set_source_surface(cr, surface, 0, 0); cairo_paint(cr); gdk_threads_leave(); sleep(2); } return( NULL ); } int main(int argc, char **argv) { GtkWidget *window; GtkWidget *darea; GThread *thread; GError *error = NULL; if(! g_thread_supported()) g_thread_init(NULL); gdk_threads_init(); gdk_threads_enter(); gtk_init(&argc, &argv); window = gtk_window_new(GTK_WINDOW_TOPLEVEL); darea = gtk_drawing_area_new(); gtk_widget_set_size_request(darea, IMAGE_WIDTH, IMAGE_HEIGHT); gtk_container_add(GTK_CONTAINER (window), darea); gtk_widget_show_all (window); thread = g_thread_create(thread_func, (gpointer)darea, FALSE, &error); if(!thread) { g_print("Error: %s\n", error->message); return(-1); } gtk_main(); gdk_threads_leave(); return( 0 ); }
あらゆる助けがあります!
解決
大丈夫、表面とCRを再利用することは不可能であるようです。私は、それらの呼び出しをGDK_THREADS_ENTER() - ループの一部に移動してから機能します。(* RGBPTR= 0xFFを実行してAチャンネルに書き込むバグがあります。)
所属していません StackOverflow