[Armadillo:06679] Re: GDK 画像表示の縮小でのメモリ問題

Yasushi SHOJI email@hidden
2011年 1月 28日 (金) 17:55:40 JST


At Fri, 28 Jan 2011 14:15:39 +0900,
MasakiAoyama wrote:
> 
> 先ほどのソースで、gdk_pixbuf_render_to_drawableのあとに
> 
> gdk_pixbuf_unref (pixbuf);
> 
> とだけ書いてたら落ちるので、てっきりやったらいかんのかと思ってしまってま
> したが、
> gdk_pixbuf_scale_simpleのときは新しく作ってるから解放がいるが、
> gdk_pixbuf_copy_areaのときはやらなくていい(表示に使っているのをそのまま
> 使っている?)
> ってことだったんですね。

その通りですね。

image_expose_event()をどのように呼び出しているか分らないので、なんとも
言えませんが適当に考えてみました。コードの中には g_pixbuf_base_image,
pixbuf という二つの変数があり、それぞれ

 - g_pixbuf_base_image: 原寸サイズの元イメージのpixbuf (global 変数)
 - pixbuf: gdk_pixbuf_render_to_drawable用の一時的な pixbuf

という用途に使おうとしているわけですよね?

たぶん image_expose_event() の中で毎回 pixbuf を生成していては、速度的
に遅いため、一時的なバッファとしての pixbuf を引数で渡しているのだと想
像しました。ところが、gdk_pixbuf_scale_simple()は、スケールしたpixbuf
のコピーを新しく生成し、その pixbuf へのアドレスを戻してしまうため、今
回のリークに繋っています。

逆に gdk_pixbuf_copy_area() では、渡された元 pixbuf の一部を、書き込み
先 pixbuf にコピーするという処理をします。そのため、新しい pixbuf が生
成されるわけではありません。それなのに、unref してしまうと次の expose
時に unref された pixbuf を使おうとして落ると思います。

であれば、scale する時に新しい pixbuf を生成しない gdk_pixbuf_scalel()
を使うというのはどうでしょうか? 新しく pixbuf を生成しない、つまりメモ
リの確保を行なわないので処理が(ほんの少しだけ)早くなりますし、copy 時と
同じように「渡された pixbuf を一時的なバッファとして使う」ことができる
のではないでしょうか?

ちなみに、scale しないのであれば、わざわざ一時的な pixbuf に copy しな
くても、gdk_pixbuf_render_to_drawable() でオフセットを指定すれば
widget->window に直接 g_pixbuf_base_image の一部を書き込むことが
できますよ。オフセットは第4引数と第5引数です。

scale しながら drawable に書く処理は、前に探したときになかったように記
憶しています。間違ってたらごめんなさい。
-- 
            yashi




armadillo メーリングリストの案内