次の方法で共有


Windows CE 5.0

Jason Black、Jon Christiansen共著
1997年9月

はじめに

Microsoft(r) Windows(r) CEオペレーティング システムのグラフィック ディスプレイ アーキテクチャは、バージョン2.0ですっかり作り変えられました。バージョン1.0では、Graphics Device Interface(GDI)は、ディスプレイ ハードウェアと直接インターフェイスをとっていました。バージョン2.0では、GDIは1つまたは複数のディスプレイ ドライバとインターフェイスをとり、それらがディスプレイ ハードウェアとインターフェイスをとるようになっています。このようなディスプレイ アーキテクチャにすることで、ディスプレイ装置ごとにハードコードしたインターフェイス ルーチンを持たずに、さまざまなディスプレイ装置を使用できる機能をWindows CEに与えています。このように新しいWindows CE GDIは、多様性と小型化を兼ね備えています。

まず最初に、優れたWindows CEディスプレイ ドライバを作り上げるための要素に注目していきます。ディスプレイ ドライバが実装すべきディスプレイ ドライバ インターフェイスと、ディスプレイ ドライバの作成を容易にするグラフィック プリミティブ エンジン クラスについて説明します。さらにデバイス ドライバのためのGDIサポートについても説明します。

続いて、Windows CEがサポートするピクセル デプスごとのディスプレイ バッファの形式を詳細にまとめ、その後ディスプレイ ハードウェアについて説明します。ディスプレイ ドライバはGDIとディスプレイ装置の間の橋渡し役となるので、ディスプレイ ドライバをサポートするために必要なハードウェアは、事実上はGDIをサポートするために必要なハードウェアということになります。

Windows CEディスプレイ ドライバ

Windows CEの大部分と同様、Display Driver Interface(DDI)はMicrosoft Windows NT(r) DDIのサブセットです。Windows NT DDIに慣れていない方は、Windows CEディスプレイ ドライバを書く前に、Windows NT Device Driver Kit(DDK)のディスプレイ ドライバのセクションを読むとよいでしょう。

Windows CEは、Windows NT DDIのうち基本的なグラフィック エンジン関数とドライバ関数だけを使用します。Windows CEとWindows NTのこのような違いから、Windows CEディスプレイ ドライバには次のような制限があります。

  • Windows CEディスプレイ ドライバには常に同じ機能セットが載ります。GDIはドライバに対して、その機能の情報を問い合わせません。

  • Windows CEディスプレイ ドライバは、複雑な操作を拒否して、その操作を簡単な操作に細分化しもらうためにGDIにコールバックするということはできません。Windows CEディスプレイ ドライバはすべて同じ機能セットをサポートしているので、GDIはディスプレイ ドライバを呼び出す前に、複雑な操作を細分化できるはずです。

  • Windows CEディスプレイ ドライバは、ライブラリ(.libファイル)としてでなく、ダイナミック リンク ライブラリ(.dllファイル)としてコンパイルされます。

Windows CEディスプレイ ドライバはすべて、ディスプレイ ドライバの初期化と、ディスプレイへの描画のためにGDIによって呼び出される一連のDDI関数を実装しなければなりません。DDI関数のほかにはGraphics Primitive Engine(GPE)クラスと呼ばれる一連のMicrosoft Visual C++(r)のクラスがあり、ディスプレイ ドライバはこれを使ってハードウェアを加速できます。サンプルのディスプレイ ドライバのGPEクラスとそのメソッドの実装は、S3Trio64ベースのディスプレイ ハードウェアを加速します。使用するディスプレイ ハードウェアのビデオ チップ セットが異なる場合は、このGPEメソッドの実装をディスプレイ ハードウェアの機能に合わせて変更できます。

GPEクラスの使用は任意です。GPEクラスを使用しなくてもディスプレイ ドライバを作成できますが、その代わりDDI関数の実装はもっと複雑になります。Microsoftが提供するGPEクラスを使う場合は、フラットなフレーム バッファがディスプレイ ハードウェアに必要ですのでご注意ください。ディスプレイ ハードウェアにフレーム バッファがない場合(たとえば固定サイズの移動可能ウィンドウを使ってディスプレイ メモリ全体にアクセスしている場合など)は、GPEクラスを使用できないことがあります。詳細については、この記事の「Windows CE用ディスプレイ ハードウェアの条件」、特に「ダーティ矩形検出ドライバ」のセクションを参照してください。

Windows CEディスプレイ ドライバは、通常のデバイス ドライバとはいろいろな点で異なります。大きな違いは、ストリーム入出力(I/O)インターフェイスを公開しないことで、そのためデバイス マネージャによって管理されず、RegisterDeviceも呼び出されません。この結果、特殊デバイス ファイルなど、アクティブなディスプレイ ドライバに対応するファイル システム エントリはありません。ディスプレイ ドライバを必要としているアプリケーションがCreateDCを呼び出して、ディスプレイ ドライバの.dllファイルの名前を渡すと、そのディスプレイ ドライバがロードされます。これによりWindows CEはディスプレイ ドライバをロードし、初期化してデバイス コンテキストを呼び出し元アプリケーションに戻します。もちろん既定のディスプレイ ドライバは自動的にロードされます。

DDI関数

下記の表は、ディスプレイ ドライバ用とプリンタ ドライバ用のDDI関数の一覧です。ディスプレイ ドライバは、ここに挙げるすべてのディスプレイ関連DDI関数を実装しなければなりません。プリンタ ドライバはここに挙げるすべての印刷関連DDI関数を実装しなければなりません。ただしDrvEnableDriverだけはディスプレイ ドライバDLLから公開しなければなりません。このためDrvEnableDriverだけは名前を変えてはなりません。その他の関数はDrvEnableDriverによって戻された関数ポインタを通じてGDIへ公開されるため、自由に名前を付けることができます。どういう名前を付けたとしても、WinDDI.Hファイルで定義されているプロトタイプに従ってください。

表1:

DDI関数

関数 用途
DrvAnyBlt 伸長、透過処理を伴うビット ブロック転送。
DrvBitBlt 一般的なビットブロックの転送。クリップとマスクを処理します
DrvContrastControl ディスプレイ ハードウェアのコントラストをソフトウェアから調節できるようにします
DrvCopyBits GDIが作成した印刷データをプリンタ ドライバへ送信します
DrvCreateDeviceBitmap ビットマップを作成、管理します
DrvDeleteDeviceBitmap デバイス ビットマップを削除します
DrvDisableDriver GDIが不用になったのでアンロードしてもよいことをドライバへ通知します
DrvDisablePDEV 特定のプリント装置またはディスプレイ装置がGDIにとって不用になったことをドライバへ通知します
DrvDisableSurface 特定の描画サーフェスがGDIにとって不用になったことをドライバへ通知します
DrvEnableDriver ドライバによって公開される最初のエントリ ポイントであり、他のDDI関数へのポインタをGDIに返します
DrvEnablePDEV PDEV(物理的なディスプレイ装置を論理的に表現したもの)をGDIに戻します
DrvEnableSurface 描画サーフェスを作成し、それをPDEVと結び付けます
DrvEndDoc 文書の印刷を終了するのに必要な制御情報を送信します
DrvFillPath パスをブラシで塗りつぶします
DrvGetMasks ディスプレイ装置の現在のモードのカラー マスクを取得します
DrvGetModes ディスプレイ装置がサポートしている表示モードを一覧表示します
DrvMovePointer GDIが干渉しないという保証付きでポインタを動かします
DrvPaint 指定したリージョンをブラシで塗ります
DrvPowerHandler 電源の投入と遮断の通知を処理するために呼び出されます
DrvQueryFont フォント メトリック情報を取得します
DrvRealizeBrush GDIによって指定されたパラメータでブラシを作成します
DrvRealizeColor RGBカラーを、装置がサポートしている利用可能な色の中で最も近い色にマップします
DrvSetPalette ディスプレイ装置のパレットを設定します
DrvSetPointerShape 新しい形状のポインタを設定して表示を更新します
DrvStartDoc 文書の印刷を開始するのに必要な制御情報を送信します
DrvStartPage 新しいページの印刷を開始するのに必要な制御情報を送信します
DrvStrokePath パスをストロークします
DrvTransparentBlt 透過処理を伴うビット ブロック転送。
DrvUnrealizeColor ディスプレイ装置での形式の色をRGB値にマップします。

GPEクラスの使用

サンプルのディスプレイ ドライバはGPEクラスを使用しています。GPEクラスの使用は任意ですが、使用したほうがディスプレイ ドライバの作成は楽になります。GPEクラスを使用すれば、ディスプレイ ハードウェアを正しく機能させ、加速するために必要な新しいコードを記述するだけで済みます。

GPEクラスを使用するには、ディスプレイ ハードウェアにはフラットなフレーム バッファがなければなりません。つまりディスプレイのメモリは連続メモリ領域になければなりません。不連続なフレーム バッファを使用するようにGPEクラスを修正するには、大変な労力が必要です。

GPEに基づいてディスプレイ ドライバを作成するには、次の手順に従います。

  1. プロジェクト用のディレクトリを作成します。
  2. サンプル ドライバのディレクトリの1つ(たとえばS3Trio64ディレクトリ)のファイルを、自分のプロジェクト ディレクトリにコピーします。
  3. これらのファイル内で、"S3Trio64"のような装置固有の名前を、自分が使用する装置の名前に全置換します。
  4. ディスプレイ装置がリニア フレームバッファ モードになるようにConfig.CPPを変更します。
  5. ハードウェア固有の加速機能を無効にします。
  6. 加速なしのこのドライバをビルドしてテストします。GPEはソフトウェアのエミュレーションを使って出力を生成します。
  7. ユーザー独自のハードウェア加速コードを書き加えます。

ディスプレイ ドライバ用のGDIサポート サービス

Windows CE GDIは、ディスプレイ ドライバをサポートするために、いくつかのサービスを提供します。その形式は、ディスプレイ ドライバに作用する関数からなるあらかじめ定義された構造体と、いくつかのスタンドアロンC関数です。あらかじめ定義された構造体は、ブラシ、クリッピング リージョン、パレット、パスのストロークと塗りつぶしをサポートします。スタンドアロンC関数は装置のビットマップとサーフェスをサポートします。

表2:

GDIの構造体と関数

構造体と関数 用途
BRUSHOBJ べた塗りまたは模様付きストロークおよび塗りつぶしオペレーションに使用するブラシを表す構造体
BRUSHOBJ_pvAllocRbrush ブラシ用にメモリを割り当てる関数
BRUSHOBJ_pvGetRbrush 指定したブラシへのポインタを取得する関数
CLIPOBJ クリッピング リージョンを表す構造体
CLIPOBJ_bEnum クリッピングリージョンからクリッピング矩形を列挙する関数
CLIPOBJ_cEnumStart クリッピング リージョン内の矩形を列挙するためのパラメータを設定する関数
EngCreateDeviceBitmap GDIにデバイス ビットマップのハンドルを作成させる関数
EngCreateDeviceSurface ディスプレイ ドライバが管理するデバイス サーフェスをGDIに作成させる関数
EngDeleteSurface ディスプレイ ドライバにとってデバイス サーフェスが不用になったことをGDIに知らせる関数
PALOBJ_cGetColors 色をパレットへコピーする関数
PATHDATA 描画パスを保存する構造体
PATHOBJ_bEnum 描画パスからPATHDATAレコードを列挙する関数
PATHOBJ_vEnumStart 描画パスに、その構成要素である線分セグメントを列挙させる準備をする関数
PATHOBJ_vGetBounds ある描画パスの境界矩形を戻す関数
XLATEOBJ あるパレットから別のパレットへ色を変換するときに使用する構造体
XLATEOBJ_cGetPalette インデックスで示されたパレットから色を取得する関数

ディスプレイ バッファの形式

Windows CE GDIは、1ビット カラーから、パレットを使う色表示、トゥルー カラー32ビットRGBまで、さまざまなカラー デプス、カラー モデルのディスプレイをサポートします。各形式もまた、ディスプレイ メモリへのアクセス方法(バイト単位、2バイト ワード単位、4バイトDWORD単位)に応じて、いくつかのピクセル順序をサポートします。

ディスプレイ バッファ形式はすべて、ディスプレイ上のピクセルの順番は左から右、上から下に向かうものと想定しています。つまり、ピクセル(0,0)はディスプレイの左上隅であり、ピクセル(width-1, height-1)は右下隅です。

1ビット/ピクセル形式

1ビット/ピクセル形式は、単純な白黒ディスプレイ用です。「0」は黒を表し、「1」は白を表します。ピクセルはバイトにパック化されます。つまりピクセル(0,0)は、ディスプレイ メモリの1バイト目の最上位ビットになるようにパック化されます。この形式ではメモリは次のように配置できます。

2ビット/ピクセル形式

2ビット/ピクセル形式は一般に、4階調のグレー スケール表示用ですが、エントリが4つのパレットなら何でも動作します。

ビット1 ビット0 グレー階調
0 0
0 1 ダークグレー
1 0 ライトグレー
1 1

この形式ではメモリは次のように配置できます。

4ビット/ピクセル形式

4ビット/ピクセル形式は一般に、パレットを使う表示のための形式です。フレーム バッファを、2ピクセルを1バイトとしてパック化するか、または1ピクセルを1バイトとして実装できます。この形式ではメモリは次のように配置できます。

1ピクセルを1バイトとして実装する場合、ドライバは16色パレットを使って1ピクセル当たり8ビットとして表示モードを表現しなければなりません。各バイト中の適切なビットが下位ニブルになり、上位ニブルは常にゼロになります。

8ビット/ピクセル形式

8ビット/ピクセル形式は、8ビット値を24ビット カラーにマップする、ソフトウェアによる変更が可能なパレットを使うのが理想的です。Microsoftは、性能、互換性、画質の理由から、既定のWindows CEパレットの入ったパレットを使うことを推奨します。この形式ではメモリは次のように配列できます:

15または16ビット/ピクセル形式

15または16ビット/ピクセル形式は、マスク処理された形式で、パレット表示ではありません。15または16ビット/ピクセルのどちらの形式も、2バイト ワードに1つずつ格納されます。したがって15ビット/ピクセル形式では、各ワードの最上位ビットが不用になります。Microsoftは、赤、緑、青を引き出すのに次のマスクを使用することを推奨します。

15ビット(5-5-5 RGB) 16ビット(5-6-5 RGB)
0x7C00 0xF800
0x3E00 0x07E0
0x001F 0x001F

これらのマスクは15ビット/ピクセル用を示しているので、各ワードのうち下位15ビットにピクセルのデータが入ります。未使用ビットにはゼロを入れます。この形式ではメモリは次のように配置できます。

24ビット/ピクセル形式

24ビット/ピクセル形式は、トゥルー カラー形式であり、各ピクセルに赤、緑、青をそれぞれ表す8ビットを格納します。この形式には利点と欠点があります。利点は、画質が非常に優れていることと、各ピクセルがちょうど3バイト占有するため、メモリを無駄に浪費することなく一緒にパック化できることです。欠点は、この形式ではピクセルの半分がDWORDの境界を越えるため、ピクセルのアクセスと復号化のときに多少性能が低下することです。この形式ではメモリは次のように配置できます。

32ビット/ピクセル形式

32ビット/ピクセル形式は、もう1つのトゥルー カラー形式です。この形式では、ピクセルはDWORDの境界を越えませんが、メモリ使用の面では多少効率が悪くなります。この形式では、カラー チャンネルの配列方法は2通りあります。各ピクセルの最下位バイトに青を格納するやり方と、最下位バイトに赤を格納するやり方です。それぞれPAL_BGRモードとPAL_RGBモードに相当します。以下のマスクを使用して、各ピクセルから赤、緑、青、アルファ チャンネルを引き出せます。

PAL_RGBマスク PAL_BGRマスク
0x000000FF 0x00FF0000
0x0000FF00 0x0000FF00
0x00FF0000 0x000000FF

この形式ではメモリは次のように配置できます。

Windows CE用ディスプレイ ハードウェアの条件

Windows CEオペレーティング システムと組み合わせて使用するディスプレイ ハードウェアに関して、Microsoftが推奨する条件がいくつかあります。条件に従うことにより、パフォーマンスは向上し、ディスプレイ ドライバの開発作業も楽になります。条件に従っていなくても、機能上は申し分のないディスプレイ ドライバを作成できます。あるいは製品の設計サイクルの終わりに近い時期でハードウェアの設計を変更できないような場合は、条件に従わなくても構いませんが、その代わりドライバの実装は大変になったり、パフォーマンスが低下したりします。

メモリのレイアウト

Microsoftでは、ディスプレイ ハードウェアはリニア フレーム バッファを使用することを強く推奨します。バッファの読み書きができなければなりません。ディスプレイのメモリのすべてが連続的で、できればフレーム バッファ全体をカバーするリニア アクセス ウィンドウが1つあるとよいでしょう。この条件を満たしていないハードウェアの場合、GPEクラスを使うなら、GPEクラスをかなり変更しなければならなくなります。詳細については、この記事の「GPEクラスの使用」のセクションを参照してください。

さらにディスプレイ ハードウェアは、サポートされている組み合わせのピクセル形式、パック化形式、ピクセル順序を使用しなければなりません。詳細については、この記事の「ディスプレイ バッファの形式」のセクションを参照してください。ディスプレイ ハードウェアのフレーム バッファは次の特性を持っていなければなりません。

  1. 左上をピクセル(0,0)、右下を(width-1, height-1)とするトップダウン形式であること。
  2. フレーム バッファのストライド、すなわち、メモリ内でディスプレイの走査線1本を表現するのに使うバイト数は、4バイトの倍数であること。4バイトの倍数にならないときは、各走査線の最後を未使用バイトで埋める必要があります。
  3. フレーム バッファ全体へ、CPUがメモリ バンクの選択を実行せずにアクセスできること。
  4. フレーム バッファは、カラー チャンネルごと、あるいは輝度の成分ごとに別々のフレーム バッファを使用するようなビット プレーンを使用しないこと。

ダーティ矩形検出ドライバ

GPEクラスを使ってディスプレイ ドライバを実装したいけれども、自分のディスプレイ ハードウェアがGPEクラスに対応した設計になっていない(たとえば、フレームバッファがリニアでない)場合は、「ダーティ矩形検出ドライバ」を書くことを考えるとよいでしょう。

この方法ではGPEクラスは、フレーム バッファを表すデバイス非依存メモリ内ビットマップ(DIB)を維持します。GPEは、メモリ内DIBが変更されるたびに、ダーティ矩形検出ドライバに通知します。ダーティ矩形検出ドライバはDIBのうち変更された、つまり「汚れた」部分をディスプレイ装置へコピーしながら、必要があれば変換を実行します。

ダーティ矩形検出ドライバは、メモリの使用と実行速度を考えると非常に高くつきます。どうしてもGPEの条件に合わせることのできないハードウェアをサポートするための最後の手段として使うべきです。

加速

Microsoftでは、ディスプレイ ハードウェアが次の処理を加速できることを推奨します。重要度の高いものから順番に並べてあります。

  • ベタ塗りカラーの塗りつぶし。特に、pbo->iSolidColorのメンバが0xFFFFFFFFでないBlt処理。
  • SRCCOPY Blt処理。
  • カーソルを使うプラットフォームの場合は、カーソル表示。
  • サブピクセル精度の実線描画
  • マスク処理したSRCCOPY Blt処理。
  • その他、自分のWindows CE装置が頻繁に実行するグラフィックス処理。

まとめ

Windows CEのバージョン2.0では、ビジュアル ディスプレイ アーキテクチャにおいてディスプレイ ドライバが重要な役割を果たします。この記事で紹介した設計方法に従って作成したディスプレイ ドライバとディスプレイ ハードウェアであれば、Windows CEベースの装置は、新しいGDIで強化されたグラフィック表示機能を最大限に利用できるでしょう。

詳細

Microsoft Windows CE Embedded Toolkit for Visual C++ 5.0については、Microsoft Windows CE Webサイト(https://www.microsoft.com/windowsce/developer/prodinfo/vcceembed.htm)を参照してください。このツールキットは、MSDN Libraryのユニバーサル サブスクリプションのメンバーにも配布される予定です。

さらに次の記事もぜひご覧ください。すべてMSDN Libraryの中にあります。

"Embedded Development with Microsoft Windows CE 2.0," Franklin Fite Jr. およびRandy Kath著。

"Introducing the Windows CE Embedded Toolkit for Visual C++ 5.0," David Pellerin著。

"Microsoft Windows CE Graphics Features," Jon Christiansen著。

"Microsoft Windows CE Memory Use," John Murray著。

"The Microsoft Windows CE Communications Model," Guy Smith著。

"Real-Time Systems with Microsoft Windows CE," John Murray著。

"The Win32 Programming Model: A Primer for Embedded Software Developers," David Pellerin著。

この記事の内容は、記載してあるテーマに関する発行日現在のMicrosoft Corporationの見解を表しています。Microsoftでは、市況の変化に反応する必要があるため、これをMicrosoftの公約とは解釈すべきではなく、Microsoftは発行日以降に提供された情報の正確さについては、一切保証しません。この文書は情報を提供することだけが目的です。

このホワイト ペーパーは、情報を提供することだけが目的です。MICROSOFTはこの文書においていかなる保証、明示、暗示もしません。