2

いくつかのグラフを表示する必要があるオーディオ アプリケーションを開発しています。考えてみてください: 高フレームレートでリアルタイムのオシロペのような画像。

必要なのは、グラフィック バッファを高フレームレートで表示することだけです。時間をかけずに 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;

}

カイロで自分の作りたいものを作ることは不可能ですか?代わりにopenGLなどを使用する必要がありますか? それとも、私は何か間違ったことをしていますか?

編集:これまでのところ、私の醜いプログラムへのリンクを追加しました。 http://ubuntuone.com/4dphKneXOgQPTR8fZydKpo

4

3 に答える 3

1

私が現在使用している方法は、cairo_image_surface を作成してから、変更する必要があるピクセルで cairo_images_surface のデータを操作することです (これは非常に高速です)。

オシロスコープのようなものをプログラミングしているので、常にすべてのピクセルを再描画する必要はありません。そのため、ものを描くのはそれほど遅くはありません。

私が遭遇した 99.9% のグラフィック アプリケーション (より大きなディスプレイとフレーム レート) では、すべての複雑なスプライト、バーなどを使用して背景で画像を再描画し、一度にすべて反転するよりも高速です。これは直感に反するように聞こえますが、これを試してみることをお勧めします


カイロはあなたが望むものを処理できるはずです。

于 2013-04-02T20:52:23.803 に答える
0

新しいイメージ サーフェスを作成する代わりに、cairo_surface_create_similar_image() を使用する方が速い場合があります。これにより、カイロは共有メモリを使用できるようになり、画像のアップロードが大幅に高速化されます。

(また、もちろん、cairo_set_source_surface() を呼び出さない方がはるかに高速です。この場合、cairo はイメージ サーフェスをアップロードする必要はありませんが、X11 サーバーに「すべてを黒で塗りつぶす」ように伝えることができます)

また、以下はなぜですか?malloc() および ...create_for_data() を呼び出す代わりに、cairo_image_surface_create() を使用してください。

plotdata = malloc (16000000);
crsurfplot = cairo_image_surface_create_for_data    (plotdata,CAIRO_FORMAT_RGB24,plotwidth,plotheight,plotstride);
plotdata = cairo_image_surface_get_data(crsurfplot);
于 2013-04-03T15:20:07.890 に答える
0

作図領域の のダブル バッファリング システムをオフGtkWidgetにすると、解決する場合があります。

gtk_widget_set_double_buffered (GTK_WIDGET (plot), FALSE);

これにより、イメージがウィンドウに描画される前に Gtk が中間ステップを導入するのを停止します。

gtk_widget_set_double_buffered ドキュメント

于 2013-04-04T11:29:48.767 に答える