1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

なぜWine上でChromium/CEFアプリの画面が真っ黒になるのか ― cross-process presentをmacOSのIOSurfaceで解く

1
Posted at

はじめに

Apple Silicon Mac で、自前ビルドの Wine + DXMT(D3D11→Metal)を使って Windows専用の Steam ゲームを動かそうとしたとき、最後まで残ったのが「ウィンドウは出るのに中身が真っ黒」という問題でした。

同じ症状は Steam クライアント本体や、CEF(Chromium Embedded Framework)を埋め込んだ多くのアプリでも起きます。この記事では原因と、macOS の IOSurface を使った解決の"考え方"を、コード全文ではなく「なぜそうなるか/どこを橋渡しすればいいか」に絞って解説します。

症状:ウィンドウは出る、中身だけ黒い

起動するとウィンドウ枠は生成される。でも中身が真っ黒のまま。クラッシュはしていない。ログにも致命的なエラーは出ない――この「動いてるのに映らない」が厄介でした。

根本原因:絵を描くプロセスと、窓を持つプロセスが別

  • 最近の Chromium / CEF は「GPU合成を必ず別プロセスで動かす」設計
  • GPUプロセスが描画し、browserプロセスがウィンドウを所有する
  • 両者の間に「合成済みフレームを転送する経路(present path)」が必要
  • ところが mainline Wine にはこの cross-process present 相当の機能がなく、D3D→Metal 変換層(DXMT)も「cross-process swapchain は未対応」とエラーを返す
  • 結果、ウィンドウは生成されてもフレームが届かず黒のまま

-cef-disable-gpu が"逃げ"である理由

GPU合成を切ってソフト描画に落とせば一応は映ります。が、パフォーマンスが大きく落ちてゲーム用途では実用になりません。正面から「フレーム転送経路」を作るべきだと判断しました。

解法の考え方:IOSurface でプロセス間を橋渡しする

macOS にはプロセス間で GPU メモリを共有できる IOSurface があります。これで:

  1. GPUプロセス側:合成フレームを IOSurface 裏打ちの Metal テクスチャに blit
  2. プロセス間で「グローバルな IOSurfaceID」を受け渡す(IPC/ファイル経由)
  3. ウィンドウプロセス側:IOSurfaceLookup(id) で surface を取得し、可視レイヤーの contents に貼る
  4. consumer 側に約16ms(60fps相当)の poll タイマーを置き setNeedsDisplay

効いた重要設定

  • IOSurfaceCreate の辞書に IOSurfaceIsGlobal = YES を必ず設定(別プロセスから Lookup するため。これが無いと取得できない)
  • producer 側はキーに GetAncestor(hWnd, GA_ROOT) で取った root HWND を使う(子ウィンドウ単位だと取り違える)

透明の壁(ハマりどころ)

そのままだと不透明合成になり重なりがおかしくなる。DXMT・winemac 側の計3箇所で opaque フラグを非opaque化して解決しました。

どこまでが「珍しい」のか(正直に)

これは完成品ではなく既知の制限があります。また CrossOver は実際よく出来ていて、これは「商用ツールを買わずにどこまで行けるか」を詰めた記録です。

完全な再現手順・パッチ全文

この記事は概念に絞りました。実際のパッチ全文・自前 Wine のビルド手順・起動スクリプト・段階検証は Zenn にまとめています。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?