2007 年 2 月 5 日 18 時 51 分

描画処理の設計


このアーカイブは同期化されません。 mixi の日記が更新されても、このアーカイブには反映されません。


役者は揃ったので、クラスの基本設計に進むことにしよう。

クラス名は RFBCanvas とし RFBDisplay を実装する。
RFBDisplay のベース実装は BaseRFBDisplay から借りてくる。

描画系の機能を達成するために、
外向けには以下のメソッドを用意する。

・public void repaint()
・public void repaint(int x, int y, int width, int height)
・protected void paint(Graphics2D g)
・protected void update(Graphics2D g)

paint/update の引数は Graphics2D にしておいた。
各メソッドの役割は自明である。

さて、描画処理の入り口となるメソッドは、
RFBDisplay の handleFramebufferUpdateRequest と、
外部から呼び出せる repaint の 2 つとなる。

handleFramebufferUpdateRequest では、
まずクライアントから要求があった範囲を記憶する。

そして、完全な更新が要求された場合は、
その範囲に対して paint コールバックを発行したあと、
即座に画面データをクライアントに送信する。

もし、増分の更新が要求された場合は、
描画された範囲のうち、未送信である部分があれば、
その分の画面データだけをクライアントに送信する。

repaint では、内部で Timer を使うことで、
repaint の呼び出しをブロックさせずに、
update を呼び出すような方法をとる。
これで、擬似的に描画システムを介したような感じになる。

また、repaint では、update を呼ぶだけではなく、
もし FramebufferUpdateRequest で要求されていれば、
クライアントに対して画面データの送信も行う。

repaint は、素早く画面に反映させるためのメソッドなので、
RFB に置き換えて考えた場合、「画面への反映」は、
update を呼び出すだけでは不足しており、
クライアントに送信する処理も含んでいなければならない。

そして、これらの処理を支えるため、
以下のようなフィールドを持たせる。

・private BufferedImage displayBuffer;
・private Shape unsentRegion;
・private Rectangle requestedRegion;

displayBuffer は、常に(仮想)画面のデータを保持する。
これは update や paint に Graphics2D を提供すると共に、
paint で描画したデータを常に記憶しておき、
update 時に現在の画面上に描画できるようにするためだ。

unsentRegion は、RFB の増分更新に対応するためにある。
paint や update で描画された範囲の形状を記憶しておき、
増分更新時にデータの送信が必要かどうかを判断する。

requestedRegion は、FramebufferUpdateRequest 時に、
クライアントから指示された範囲だ。
RFB では、クライアントからの要求がない限り、
画面データを送ってはならないため、
クライアントから要求があった範囲を記憶すると共に、
画面データの送信の可否を表す情報となる。

明日はこの方針でコードを書いてみよう。



Copyright (c) 1994-2007 Project Loafer. All rights reserved.