c - 如何快速重绘图像缓冲区

标签 c gtk cairo xorg

我正在开发某种音频应用程序,我需要在其中显示一些图表。想一想:高帧率的实时 Oscillope 类图像。

我所需要的只是以高帧率显示一些图形缓冲区。最好 >60fps 而无需花费太多时间。我现在实现它的方式太慢了。我只能以 800x800 像素的分辨率获得 10fps。绘图不是问题,Xorg 正在占用所有时间。

我现在使用的方法是创建一个cairo_image_surface,然后在需要改变的像素处操作cairo_images_surface中的数据(速度相当快)

因为我正在为示波器之类的东西编程,所以我不需要一直重绘所有像素。所以画东西不是很慢。

我认为最慢的部分是我需要调用 cairo_set_source_surface() 来实际显示一些东西。

代码最重要部分的摘要。 on_plot_event 每当有新的音频样本准备好显示时调用。

static gboolean on_plot_event(GtkWidget *widget,cairo_t *cr,gpointer user_data){
    cairo_set_source_surface(cr,crsurfplot,0,0);
    cairo_paint(cr);
    return FALSE;
}

int doplot(jack_default_audio_sample_t *in,jack_nframes_t nframes){
    cairo_surface_flush(crsurfplot);
    char *p;
    unsigned char *pixstart;
    pixstart = plotdata;
 //drawing stuff, manipulate pixels at pixstart
    cairo_surface_mark_dirty(crsurfplot);
    if(drawcount%10 ==0){
    gdk_threads_enter();
    gtk_widget_queue_draw(window);
    gdk_threads_leave();
    }
}


int main(int argc,char *argv[]){
    gdk_threads_init();
    gtk_init (&argc, &argv);
    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    window2 = gtk_window_new (GTK_WINDOW_TOPLEVEL);

    plotstride = cairo_format_stride_for_width (CAIRO_FORMAT_RGB24,plotwidth);
    plotdata = malloc (16000000);
    crsurfplot = cairo_image_surface_create_for_data    (plotdata,CAIRO_FORMAT_RGB24,plotwidth,plotheight,plotstride);
    plotdata = cairo_image_surface_get_data(crsurfplot);    

    plot = gtk_drawing_area_new();  
    gtk_container_add(GTK_CONTAINER(window),plot);

    g_signal_connect(G_OBJECT(plot),"draw",G_CALLBACK(on_plot_event),NULL);
    g_signal_connect(G_OBJECT(plot),"configure-event",G_CALLBACK(on_confev),NULL);

    gtk_widget_show_all (window);
    gtk_widget_show (window2);
    printf("test\n");

    crplot=gdk_cairo_create(gtk_widget_get_window(plot));
    cairo_set_source_surface(crplot,crsurfplot,0,0);

    gtk_main ();

    jack_client_close(client);
    return 0;

}

用 Cairo 创造我想要的东西是不可能的吗?我应该改用 openGL 或类似的东西吗?还是我只是做错了什么?

编辑:到目前为止添加了指向我的丑陋程序的链接。 http://ubuntuone.com/4dphKneXOgQPTR8fZydKpo

最佳答案

The method I use now is that I create a cairo_image_surface and then manipulate the data in the cairo_images_surface at the pixels that need to change (which is quite fast)

Because I'm programming something like an oscilloscope I don't need to redraw all the pixels all the time. So drawing things isn't very slow.

在我遇到的 99.9% 的图形应用程序(更大的显示器和帧速率)中,我不同意在背景中使用所有复杂的 Sprite 、条等重新绘制图片比一次翻转它更快。尽管这听起来有悖常理,但我还是建议您尝试一下


开罗应该能够处理你想要的。

关于c - 如何快速重绘图像缓冲区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15773965/

相关文章:

c - 将随机元素分配给函数中的 int 二维矩阵时,如何避免 C 中的 SIGSEGV 段错误?

gtk - 阻止 GTK 元素调整 parent 的大小?

R Cairo pdf 字体在 Adob​​e Illustrator 中无法读取

c - 如何将二进制数组打印为字符

c - 如何在C中将字符串格式化为排队格式?

c - GLib-关键 ** : Source ID XXX was not found when attempting to remove it

c++ - 检索 Gtk::Widget 的相对位置:get_allocation() 不起作用

c - 强制子部件尊重父部件绘图区域(如圆角)

c++ - 如何在 Opengl Windows 上使用 Cairo 加速绘图?

c - 在 MPI 中广播(共享)数组