トップページ > 記事閲覧
DXライブラリ内部でのフォントキャッシュ利用法について
名前:さがわ 日時: 2014/01/31 23:42

はじめまして、こんにちは。 DXライブラリ内部のフォントキャッシュの処理に不適切な点があり、Wine上で文字化けが起こりました。Wine固有の問題かもしれませんが、現状のDxライブラリは仕様上保証されていない動作に依存しているため報告いたします。 ■要点 BltBmpOrBaseImageToGraph3関数においてIDirect3DDevice9::UpdateTexture[1]はIDirect3DTexture9::LockRect[2]で作成したダーティ領域 *のみ* をコピーすることをDXライブラリは期待しているが、仕様上ダーティ領域だけコピーすることは保証されていない。実際、Wineでは仮テクスチャ全体を転送するため文字化けする。 [1] ttp://msdn.microsoft.com/ja-jp/library/cc324250.aspx [2] ttp://msdn.microsoft.com/ja-jp/library/cc324038.aspx ■背景 WineでGPUレンダリングを有効にしたWOLF RPGエディタ2.10のテキストが文字化けするようになったというバグ報告(#35205)があり、こちらで調査したところ上記処理が原因との考えに至りました。 以下のシナリオにより上記処理が発生し、フォントのキャッシュ内容が破壊されていると思われます。 ステップ1: フォントハンドルXのキャッシュとして、テクスチャXを作成する(CreateFontToHandle) ステップ2: フォントハンドルXを用いて文字を描画するときに、キャッシュにない文字のため字形ビットマップを仮テクスチャの(1,1)に描画し、テクスチャXに転送する ステップ3: フォントハンドルYのキャッシュとして、テクスチャYを作成する(CreateFontToHandle) ステップ4: フォントハンドルYを用いて文字を描画するときに、キャッシュにない文字のため字形ビットマップを仮テクスチャの(1,1)に描画し、テクスチャYに転送する ステップ5: フォントハンドルXを用いて文字を描画するときに、キャッシュにない文字のため字形ビットマップを仮テクスチャの(1,10)に描画し、テクスチャXに転送する ステップ6: フォントハンドルXを用いて文字を描画するときに、キャッシュにある文字をテクスチャXの(1,1)から転送する。 Wineではステップ4で仮テクスチャの(1,1)に描画した内容が、ステップ5でテクスチャXにも転送されます。この結果、ステップ6で得られる字形ビットマップがステップ1で描画した字形ビットマップと異なるものになり、文字化けが生じたようです。 多くのWindowsではステップ5でテクスチャXに転送される領域はダーティとなった領域に限られるため、ステップ4で(1,1)に描画した情報は転送時に無視されるようです。 ■対処 UpdateTextureの代わりにUpdateSurfaceを用いることで解決できるかもしれません。ただし、Direct3Dに詳しくないので上記対応は適切か自信ありません。別途検討をお願いします。 報告は以上となります。説明について補足が必要であったり、誤りがありましたら、何なりとご指摘ください。 よろしくお願いします。
メンテ

Page: 1 |

Re: DXライブラリ内部でのフォントキャッシュ利用法について ( No.1 )
名前:管理人 日時:2014/02/01 19:15

ご報告ありがとうございます 恐らくこちらのスレッド http://hpcgi2.nifty.com/natupaji/bbs/patio.cgi?mode=view&no=3218 の No.8 でご報告いただいた不具合と同様の現象だと思います 暫定バージョンでは既に修正されていて、正式バージョンについても 本日アップした最新バージョンで修正されています > ■要点 > BltBmpOrBaseImageToGraph3関数においてIDirect3DDevice9::UpdateTexture[1]は > IDirect3DTexture9::LockRect[2]で作成したダーティ領域 *のみ* をコピーすることを > DXライブラリは期待しているが、仕様上ダーティ領域だけコピーすることは保証されていない。 > 実際、Wineでは仮テクスチャ全体を転送するため文字化けする。 ご指摘の通りです、しかも太刀の悪いことに私も UpdateTexture はテクスチャー全体が 転送されると思っています、つまりその認識がある状態で色々なビデオメモリテクスチャへの 画像転送に使いまわされるシステムメモリテクスチャを部分転送でも使用していました これは最初、全てのビデオメモリテクスチャにそれぞれ同じサイズ・フォーマットの 『ビデオメモリへ画像データを転送するためのシステムメモリテクスチャ』を割り当てて いたのですが、部分転送の存在と UpdateTexture で常にテクスチャ全体を転送していることを 失念したタイミングで『あれ?ただ必要な部分をビデオメモリに転送するだけだったら全部の ビデオメモリテクスチャに専用のシステムメモリテクスチャを持っておく必要ないんじゃないだろうか?』 などと考えてしまったのが本件のバグを埋め込むに至った原因です > UpdateTextureの代わりにUpdateSurfaceを用いることで解決できるかもしれません。 > ただし、Direct3Dに詳しくないので上記対応は適切か自信ありません。別途検討をお願いします。 ご指摘ありがとうございます、UpdateSurface を見落としていました 一旦問題が無かった頃の方式に戻して対応したのですが UpdateSurface を使用すれば 再度システムメモリを節約する方式にできそうです
メンテ
Re: DXライブラリ内部でのフォントキャッシュ利用法について ( No.2 )
名前:管理人 日時:2014/02/01 23:51

UpdateSurface を使用して再度システムメモリを節約する方式にできました さがわさんのご助言のお陰です、ありがとうございます こちらにその変更を施したバージョンをアップしましたので、 よろしければお試しになってみてください http://homepage2.nifty.com/natupaji/DxLib/DxLibVCTest.exe // VisualC++ 用 http://homepage2.nifty.com/natupaji/DxLib/DxLibBCCTest.exe // BorlandC++ 用 http://homepage2.nifty.com/natupaji/DxLib/DxLibGCC_DevCppTest.exe // Dev-C++ 用 http://homepage2.nifty.com/natupaji/DxLib/DxLibGCC_MinGWTest.exe // MinGW 用 http://homepage2.nifty.com/natupaji/DxLib/DxLibDotNet.zip // .NET用 http://homepage2.nifty.com/natupaji/DxLib/DxLibMakeTest.exe // ソース (中身を既存のライブラリのファイルに上書きして、BCCをお使いの 場合は『再構築』を、VCをお使いの場合は『リビルド』を、 Dev-C++をお使いの方は「Rebuild All(Ctrl+F11)」をして下さい)
メンテ
Re: DXライブラリ内部でのフォントキャッシュ利用法について ( No.3 )
名前:さがわ 日時:2014/02/03 23:30

掲示板の調査不足で報告時で、すでに対応済みであったとのことに気づかず 報告が重複することとなってしまい恐縮です。 公開版(3.11d)では手元のテストプログラムにおいて現象が発生しないこと を確認しました。 対応頂きありがとうございました。
メンテ
Re: DXライブラリ内部でのフォントキャッシュ利用法について ( No.4 )
名前:さがわ 日時:2014/02/10 18:48

システムメモリを節約する方式にした3.11eでも、 手元のテストプログラムでは問題が発生しないことを 確認しました。 以上よろしくお願いします。
メンテ
Re: DXライブラリ内部でのフォントキャッシュ利用法について ( No.5 )
名前:管理人 日時:2014/02/11 00:10

お試しいただき&ご報告ありがとうございます m(_ _)m
メンテ

Page: 1 |

題名
名前
コメント
パスワード (記事メンテ時に使用)

   クッキー保存