Per-Monitor DPI

  1. いつもお世話になっております。
    連休中にスミマセン。。。
    いくつかPer-Monitor DPIがらみの問題の報告です。

    OS: Win10
    メインモニタ:1920×1080 表示倍率150%
    サブモニタ:1600×1400 表示倍率100%

    1) Ver 2.6.7で修正いただいた「Per-Monitor DPI でモニタ間を移動時にコンボボックスの補完が動作することがある問題」が、いつの間にか(Ver2.6.12~VerVer2.6.14くらい?)復活しているようです。

    2) 保存しますか?等のメッセージボックスが、ぼやけて表示されるようになりました。

    3) Per-Monitor DPI がらみの問題かどうかはわかりませんが、以下の条件
     ・カスタムフォントを使用
     ・DirectWrite有効
     にて、Meryのウィンドウをモニタ間を移動させると、高頻度でキャレットの移動速度が遅くなってしまいます。矢印キーを押しっぱで、体感で1秒間に3行 or 3文字程度の移動速度です。
     上記条件のどちらかが不成立の場合は、現象が発生しないっぽいです。

     |  Dainty  |  返信
  2. ご報告ありがとうございます。

    > 1) Ver 2.6.7で修正いただいた「Per-Monitor DPI でモニタ間を移動時にコンボボックスの補完が動作することがある問題」が、いつの間にか(Ver2.6.12~VerVer2.6.14くらい?)復活しているようです。
    確認してみましたところ、現象を再現することができました。

    Per-Monitor DPI における Windows のコンボボックスの仕様ということで、以前は無理やり対策を施していたのですが、Ver 2.6.12 にて Windows 10 の PerMonitorV2 に対応したため、PerMonitorV2 では従来の対策だけでは効果がなくなってしまっているようです。

    現在のところ関連する情報が見つからないため、対応が可能かどうかわかりませんが、引き続き調査してみたいと思います。

    > 2) 保存しますか?等のメッセージボックスが、ぼやけて表示されるようになりました。
    これは Windows 10 の仕様ですが、従来の Per-Monitor DPI ではメッセージボックスは拡大・縮小されずそのまま表示されていました。

    PerMonitorV2 では、メッセージボックスがぼやけながらも拡大・縮小されるようになった模様ですので進化といえば進化ですが、こればっかりはマイクロソフトの対応を待つしかなさそうです。

    一応、アプリケーション側で MessageBox ではなく Vista 以降で使用できる新しいダイアログ (TaskDialog) の仕組みを採用することで綺麗な拡大・縮小に対応できるのですが、XP のサポートを終了することになりますので、ちょっとまだ決断できないところです。

    > 3) Per-Monitor DPI がらみの問題かどうかはわかりませんが、以下の条件
    >  ・カスタムフォントを使用
    >  ・DirectWrite有効
    >  にて、Meryのウィンドウをモニタ間を移動させると、高頻度でキャレットの移動速度が遅くなってしまいます。矢印キーを押しっぱで、体感で1秒間に3行 or 3文字程度の移動速度です。

    カスタムフォントを使用した DirectWrite はそもそも動作速度が遅いです。また、グラフィックカードの性能や種類、同時に起動している DirectWrite を使用するアプリなど、環境によっては極端に動作が遅くなるケースもございます。

    上記の条件で試してみましたところ、確かに、色分けの多いテキストなどではもっさりした動作になりますが、技術的にこれ以上の高速化は厳しいと思いますので、今後の課題とさせてください。

     |  Kuro  |  返信
  3. ご確認ありがとうございます。

    1), 2)については了解しました。

    3) について、念のため補足です。
    ・モニタ間を移動した時に、キャレットの移動速度が遅くなるときとならないときがある。
    ・同じファイルの同じ範囲を表示させている状態でも同上。
    ・カスタムフォント機能が搭載されてからカスタムフォント+DirectWrireで使用していますが、この現象が発生しはじめたのは、Ver2.6.12かVer2.7.0からかも?
    ・現象発生時、他のタブを一旦アクティブにすると復活する場合がある。

    Kuroさんの仰る「もっさり」とはちょっと違うような気がしたので補足してみました。

     |  Dainty  |  返信
  4. ご返信ありがとうございます。

    3) については、モニタ間を移動したことでフォントサイズが変更されるので、1 ページに描画する文字数が増えることで速度に影響が出るのかと思いましたが、同じ範囲を表示させていても遅くなるということは、別の問題かもしれないですね。

    フォントサイズの違いで速度に差がでることも考えられますが。

    私の環境では現象を再現できないようなので、よろしければもう少し詳細な環境を教えていただけますでしょうか。

    こちらでもできるだけ近い環境を用意して検証してみたいと思いますので、ちょっと項目が多いですが、わかる部分だけでも結構ですのでご協力いただけると助かります。

    ■お使いのパソコンのスペック
    CPU、メモリ。ノート PC の場合は型番でも良いです。

    ■お使いの OS とそのバージョン、ビット数
    検証したのは Windows 10 1809 64bit

    ■Mery のバージョンとビット数
    検証したのは Mery 2.7.4 64bit

    ■グラフィックボード
    検証したのは NVIDIA GeForce GTX 750 Ti

    ■カスタムフォントとして Mery の Fonts フォルダに入れているフォント (の数)
    フォント名の一覧までは必要ないですが、大量に導入されている場合は動作速度に影響があるかもしれません。

    ■Mery で設定しているフォント名
    ■Mery の DirectWrite の設定の [レンダリングモード]
    ■Mery の DirectWrite の設定の [カラーフォントを有効にする] のオン・オフ状態
    ■縦書きを使用しているかどうか

    ↑ この辺りは DirectWrite の動作速度に直接関係します。

    ■導入しているプラグイン
    ■導入しているマクロ
    ■現象が発生したときの [編集モード]

    ↑ それほど関係はありませんが、できればプラグイン、マクロを除いて、[編集モード] が [Text] で発生するかどうかご確認いただけると参考になります。

    ■ウイルスチェックソフト
    ■常駐しているアプリケーション

    ↑ 意外とこのあたりはあり得ます。MacType が導入されていたり、ウイルスチェックソフトで動作を制限されていたり。

    あとは、秀〇エディタさんの DirectWrite が遅くなるという記事がありまして、そちらでは OS の「フォールトトレラントヒープ」という機能が働くことで動作速度が低下するということが書かれていました。(が、詳細は長くなるので割愛)

    お手数をおかけしますが、よろしくお願いいたします。

     |  Kuro  |  返信
  5. せっかくのGWにお手数をおかけします。

    > 私の環境では現象を再現できないようなので、よろしければもう少し詳細な環境を教えていただけますでしょうか。

    実は会社のパソコンでして。。。
    わかる範囲で部分的にお答えしようかと思いましたが、いい加減な返答をしてKuroさんのGWを台無しにしてしまうとまずいので、GW明けに回答します。

    よいGWを!そして、よい令和を!

     |  Dainty  |  返信
  6. ご返信ありがとうございます。

    > せっかくのGWにお手数をおかけします。
    いいえー、こちらは雨なので特に楽しいこともなく…。Mery 関連で DirectWrite の研究をしながら過ごしております。

    > 実は会社のパソコンでして。。。
    > わかる範囲で部分的にお答えしようかと思いましたが、いい加減な返答をしてKuroさんのGWを台無しにしてしまうとまずいので、GW明けに回答します。
    そうでしたか、お手数をおかけして恐縮です。
    気がかりなのは、こちらでは動作検証できる環境が GeForce 系のグラボしかないので、もし Radeon だったらどうしようかと…。

    > よいGWを!そして、よい令和を!
    はい!よい令和を!
    平成最後の日に Mery を開発しています。

     |  Kuro  |  返信
  7. ご無沙汰しております。
    休み明けで仕事をする気にならないので、調べてみました。

    > ■パソコンのスペック
    Core i5 7300U / 8GB RAM / 256GB SSD

    > ■OS とそのバージョン、ビット数
    Windows 10 Pro / 1803 / 64bit

    > ■Mery のバージョンとビット数
    Mery 2.7.2 64bit

    > ■グラフィックボード
    Intel HD Graphics 620

    > ■カスタムフォントとして Mery の Fonts フォルダ
    Cica-Regular
    Ricty Diminished-Regular

    > ■Mery で設定しているフォント名
    Ricty Diminished-Regular

    > ■Mery の DirectWrite の設定の [レンダリングモード]
    Natural Symmetric

    > ■Mery の DirectWrite の設定の [カラーフォントを有効にする] のオン・オフ状態
    オン

    > ■縦書きを使用しているかどうか
    不使用

    > ■導入しているプラグイン
    クラスビュー

    > ■導入しているマクロ
    MeryWikiにあるkazyさん作のctagsジャンプマクロや、自作のマクロをいくつか使用していますが、イベント駆動のマクロはありません。

    > ■現象が発生したときの [編集モード]
    C#, C++

    > ↑ それほど関係はありませんが、できればプラグイン、マクロを除いて、[編集モード] が [Text] で発生するかどうかご確認いただけると参考になります。

    プラグイン無効でtextの場合は、発生しているような発生していないような微妙なところです。

    で、色々設定を弄ってみたのですが、自動マーカーを有効にすると現象が発生するようです。
    (大文字と小文字を区別のみチェック)

    お手数をおかけしますが、よろしくお願いいたします。

     |  Dainty  |  返信
  8. ご無沙汰しております、ご確認いただきありがとうございます。
    ハイスペックマシンですね。これじゃスペックのせいにできません… (w

    いただいた情報をもとに検証してみましたところ、自動マーカーがオンのときに何らかのタイミングで描画が非常に遅くなる場合があることが確認できました。

    調査してみましたところ、以下のことがわかりました。

    まず、1 つめ。
    ----
    カスタムフォントを使用していると、DirectWrite の描画速度は通常より遅いです。
    ----

    そして 2 つめ。
    ----
    自動マーカー機能がオンになっている場合、キャレットが移動するたびに画面に表示されている全行が再描画されてしまうため描画速度が遅いです。それにカスタムフォントの遅さが加わるのでさらに遅くなります。

    自動マーカーの [カーソル位置の単語を取得する] オプションがオンの場合は全行を再描画してマーカーを表示する必要がありますが、これがオフの場合でも全行の再描画が発動していました。

    この部分につきましては [カーソル位置の単語を取得する] オプションがオフの場合は、通常のキャレット移動のたびに全行を再描画する必要はないと思いますので若干速度改善の余地はありそうです。
    ----

    状況によっては非常に遅くなることがあるという現象についてですが、これは DirectWrite の仕様によるものなので内部までは知りようがありませんが、下記のような場合に発生することがあるようです。

    Windows では通常、 Windows Font Cache というサービスが動作しており、これはシステムキャッシュとユーザーごとのキャッシュを管理しています。

    アプリケーションが DirectWrite の API を呼び出すときに Font Cache サービスはユーザごとのキャッシュを読み込むのですが、この時に 0.5 秒間待機 (以下、この時間切れを "タイムアウト" と呼びます) しますが、タイムアウトした場合はキャッシュを使うのを諦めて、直接フォントを読みに行くため動作速度が遅くなるそうです。

    [KB2505438 より]
    https://support.microsoft.com/ja-jp/help/2505438/slow-performance-in-applications-that-use-the-directwrite-api-on-a-com

    ここからは推測ですが…

    通常、DirectWrite でテキストを描画するにあたって、フォントを読み込む際、最初にフォントの一覧 (フォントコレクション) を使って書式の情報を作成しますが、普通はここでシステムフォントコレクションを使用するので短時間で済みます。

    カスタムフォントを使用した場合、ここの処理でカスタムフォントコレクションを使用するため、処理に時間がかかり 0.5 秒のタイムアウト時間を超えてしまい、キャッシュが使用されない状態になっているように思います。

    バックグラウンドで動作しているプロセスの影響も受けますので、CPU の負荷状況によってタイムアウトが発生している可能性もあります。

    アプリケーション側からこのタイムアウト時間を制御する方法や、Font Cache サービスを制御する方法などはないようです。

    そういうわけでアプリケーション側でできる対応としては…。

    (1) Font Cache サービスに頼らず、自前でキャッシュする仕組みを設ける

    正確なことはわかりませんが Chrome ではそんなことしているような情報が…
    https://www.chromium.org/developers/design-documents/directwrite-font-cache

    (2) フォントキャッシュが使われない場合でも高速に動作するように、そもそも根本的な動作速度を改善する

    現在の Mery は GDI (DirectWrite オフ) が標準となっており、GDI と DirectWrite を共存 (適宜、切り替えて描画) させていますが、この GDI ←→ DirectWrite の切り替えが動作速度のボトルネックになっています。

    根本的な動作速度を改善する場合、GDI を捨てて完全に DirectWrite に移行することで大幅な速度の改善が見込めます。

    が、XP ~ 10 まで対応、国産の昔ながらの機能を継承したテキストエディタという性質上、ビットマップフォントを切り捨てることもできず、DirectWrite だとバグのあるフォントもあったりして、完全に DirectWrite に移行するのは現状では困難です。

    技術的に興味深いのは (1) の作戦ですが、世界の Google 先生の技術を私が再現できる自信はありません…。

    GDI と DirectWrite のプログラムを完全に分離して、DirectWrite 専用で動作する仕組みを構築できれば高速化できるはずなので、やるとしたら (2) の方法になると思いますが、描画ロジックの全体的な作り直しとなりますので対応には非常に時間がかかります。

    ご不便をおかけして申し訳ございませんが、将来的に改善したい事項ということで課題とさせていただければと思います。

     |  Kuro  |  返信
  9. 丁寧な解説、ありがとうございます。

    レアケース(?)の検証に時間を割いていただき申し訳ないです。

    いつの日かKuroさんが(1)の方法を実装してくれるのを楽しみにしておきますヾ(・д・`;)

     |  Dainty  |  返信
スポンサーリンク