- PR -

効率の良い描画方法とは?

投稿者投稿内容
かずくん
ぬし
会議室デビュー日: 2003/01/08
投稿数: 759
お住まい・勤務地: 太陽系第三惑星
投稿日時: 2003-08-19 15:38
Joshua Bloch著 Effective Javaの中に関係しそうな記述があったので引用しておきます。

引用:

複数のスレッドが可変データを共有する場合には、そのデータを読み書きするスレッドは必ずロックを獲得しなければなりません。アトミックな読み書きの保証があるからと言って、適切な同期をを行うのを思いとどまったりしないでください。



int型のデータはatmicの読み書きを保証しているので、上述のことが言えるのではないでしょうか。
ボム
ベテラン
会議室デビュー日: 2003/07/25
投稿数: 61
投稿日時: 2003-08-20 10:00
ほむら様、Ken-Lab様、かずくん様、ご意見ありがとうございました。

ほむら様より引用****************************************************************
>clearRect()をフォーカス喪失時の先頭または
>changeImage()の先頭に書き込む
>repaint()をchangeImage()の内部に統一してみてください
試してみましたが、ちらつきはpaint()内に置いた時と変わりませんでした。
>マシンパワーのせいとは思いたくないですね。。。
ハイ、そうですね・・・
*******************************************************************************

Ken-Lab様より引用***************************************************************
>これは10枚のパネルをpaintメソッド内で一気に描いてしまう、という意味です
実はその方法とっているのです、現在パネルの描画を行う時、スレッドで文字をずらす以外
のpaint()は一気に全てのパネルの描画を行っています。
本当は全てのソースを載せるべきなのですが、そうもいかず・・・
*******************************************************************************

かずくん様より引用**************************************************************
>同期を取り、作業領域をメイン領域に書き戻してやります
かずくん様のご説明に私がついていけてない気もしますが・・・
テストしてみます。
*******************************************************************************


未記入
大ベテラン
会議室デビュー日: 2003/06/28
投稿数: 219
投稿日時: 2003-08-20 10:22
おはようございます。お疲れ様です。

> 実はその方法とっているのです、現在パネルの描画を行う時、スレッドで文字をずらす以外
> のpaint()は一気に全てのパネルの描画を行っています。
> 本当は全てのソースを載せるべきなのですが、そうもいかず・・・

であれば、完璧にちらつきます。文字ずらし処理と、全体の再描画をひとつの
メソッド内で同時に行わなければ意味ないです。
シンクロナイズさせれば別ですが・・・。

# うまく要点を表現できていなかったかな??

[ メッセージ編集済み 編集者: Ken-Lab 編集日時 2003-08-20 10:31 ]
ボム
ベテラン
会議室デビュー日: 2003/07/25
投稿数: 61
投稿日時: 2003-08-20 11:14
Ken-Lab様、ご意見ありがとうございました。

Ken-Lab様より引用***************************************************************
>文字ずらし処理と、全体の再描画をひとつのメソッド内で同時に行わなければ意味ないです。
パネルはオブジェクトの配列になっているので、パネルの描画処理(文字ずらし処理、パネルの描画処理)は個々のpaint()で行うものではないのでしょうか?
理解できていなかったらすみません。

>シンクロナイズさせれば別ですが・・・。
もう少し具体的に教えていただけますか?
"synchronized"を使うという意味でしょうか?
*******************************************************************************

*付けたしです。
*"clearRect()"をpaint()に追加する前にはちらつきがありませんでしたがKen-Lab様
*のご意見だとこの場合もちらつきは発生するのではないでしょうか?



[ メッセージ編集済み 編集者: Casper 編集日時 2003-08-20 11:22 ]
未記入
大ベテラン
会議室デビュー日: 2003/06/28
投稿数: 219
投稿日時: 2003-08-20 11:36
お世話様です。
今、具体例まで書ける時間がないので概念だけ・・・

> パネルはオブジェクトの配列になっているので、パネルの描画処理(文字ずらし処理、
> パネルの描画処理)は個々のpaint()で行うものではないのでしょうか?

これがマズい点です。表現したかったのはこんな感じです。
public void paint (Graphics g){
 for (int i = 1;i < 10;i++){
 10枚のパネルを描画
 }
 文字を書く
}

public void update (Graphics g){
 paint(g);
}

> "synchronized"を使うという意味でしょうか?
はい、そうです。かずくん様のご意見と共通する点だと考えます。

> "clearRect()"をpaint()に追加する前にはちらつきがありませんでしたがKen-Lab様
> のご意見だとこの場合もちらつきは発生するのではないでしょうか?

# 以下修正
この状態でupdateメソッドがなければ激しくちらつくと思います。
それをupdateメソッドで完全に封じ込めます。
clearRectを入れない状態でちらつかなかったのは、その前の描画が残っていた
ためであり、本来の動作からすると、それ自体がおかしな状態であったのです。

[ メッセージ編集済み 編集者: Ken-Lab 編集日時 2003-08-20 11:55 ]
ocean
ベテラン
会議室デビュー日: 2003/07/06
投稿数: 65
投稿日時: 2003-08-20 12:24
スレッドの流れを断つような質問をしてすみません。
引用:

  threadOnOff(true); //スレッドを開始します。

  threadOnOff(false); //スレッドを開始します。


をコメントアウトしても、文字が重なってみえますか?

#追記

重なって見えるというのは、
1.フォーカスがないときの文字の上を、スクロール時の文字が移動する
2.フォーカスがないときの文字の上を、さらにスクロール時の文字が残像を残しながら移動する
3.フォーカスがないときの文字は消えるが、スクロール時の文字が残像を残しながら移動する
4.その他
のどれですか?


[ メッセージ編集済み 編集者: ocean 編集日時 2003-08-20 12:27 ]
ボム
ベテラン
会議室デビュー日: 2003/07/25
投稿数: 61
投稿日時: 2003-08-20 14:17
Ken-Lab様、ocean様、ご意見ありがとうございました。

Ken-Lab様のご意見について*******************************************************
細かなご説明、お手間をとらせました。ありがとうございす。
ご存知の通り、現在のpaint()は個々のパネルの描画しか行っておりません。
それを修正してからのテストに少々時間がかかる為、結果に少々お時間をください。

それからもうひとつ、現在のpaint()ロジックで(投稿日時: 2003-08-19 11:23)テストを
繰り返していた所、今まではclearRect()を入れるとちらつきはあったのですが文字列が重なるというような事は無いと思っていたのですが、先ほどテストしていたら有りました・・・
clearRect()を入れても文字列は重なります。
*******************************************************************************

ocean様より引用*****************************************************************
>コメントアウトしても、文字が重なってみえますか?
>重なって見えるというのはどれですか?
4.その他です。

処理内容をもう一度説明させてください。
1.メインパネルが一枚あり、その上に10枚のサブパネルがあります。
2.10枚のパネル内をフォーカスが移るたびに10枚のパネルをrepaint()します。
4.背景画と文字列は変更されていきます。
3.この描画はパネルクラスを配列で持ったメインパネルクラス内で行われます。
public void pnlAlbumRepaint(){
 for(int i = 0; i < 10; i++) {
  pnlAlbum[i].repaint(); //サブパネルの再描画
 }
}
4.描画内容(投稿日時: 2003-08-19 11:23)は背景画を張り、文字列を張るです。
5.フォーカスを取得したサブパネルは次に文字列のスクロールを開始します。
6.スクロール処理でrepaint()処理が走ります。

現在、処理番号2の10枚のパネルのrepaint()の時点で、前の文字列と新しい文字列が重なってしまっているのです。つまり文字列スクロール処理の前の段階で既に重なってしまっているのです。結果、フォーカスの有るパネルは重なった状態からスクロールが始まり残像?を残して文字が重なり"ABC"が"■"になってしまいます。フォーカスの無いパネルは文字列が重なったままのパネルもあれば、描画が上手くいき?正常に描画されているのもあるといった状態です。

ただ私が気になるのはこの現象が毎回おこるわけではなく、起こる事があるという所です。
また、デバック用PCではまったくそのような現象はでず、本番用の機体だとこの現象が出ることがあるのです。
このデバックPCと本番用機の違いは
デバック用PCはwindows2000でスペックは非常に良く(CPU 2G, Memory 1G)
本番用機に関してはあまり具体的に書けません、すみません。
ただLinux2.4でスペックは良くありません。


未記入
大ベテラン
会議室デビュー日: 2003/06/28
投稿数: 219
投稿日時: 2003-08-20 16:04
お疲れ様です。

> ご存知の通り、現在のpaint()は個々のパネルの描画しか行っておりません。
> それを修正してからのテストに少々時間がかかる為、結果に少々お時間をください。

了解しました。取り敢えず結果をお聞きしてから、ですね。

> ただ私が気になるのはこの現象が毎回おこるわけではなく、起こる事があるという所です。

当方でも実験プログラムを書いて確認していますが、毎回画面が崩れています。
描画内容により、目立つ、目立たないという違いがあるのかもしれませんが、
他に何か崩れないような工夫をしているところはありませんか?
(当方の環境は Win2000 PIII 1GHz 256MBです。)

> 3.この描画はパネルクラスを配列で持ったメインパネルクラス内で行われます。
public void pnlAlbumRepaint(){
 for(int i = 0; i < 10; i++) {
  pnlAlbum[i].repaint(); //サブパネルの再描画
 }
}
これは想像どおりでした。

> デバック用PCはwindows2000でスペックは非常に良く(CPU 2G, Memory 1G)
> 本番用機に関してはあまり具体的に書けません、すみません。
> ただLinux2.4でスペックは良くありません。

もし、これが原因であるとなるとマシンの構成がわからない以上、コメントが
できないと思います(機密だと思うのでやむを得ないのはわかっているんですが・・・。)

# 追記 8月8日付けの私のソースではこのような問題は発生しませんか?
# (sample5.javaで保存し、javacしてからアプレットにする)。
# これはお時間があれば、ですが。

[ メッセージ編集済み 編集者: Ken-Lab 編集日時 2003-08-20 16:21 ]

スキルアップ/キャリアアップ(JOB@IT)