ブラウザで動作するWebGLを使ったアプリケーションもよく見かけるようになりました。ライブラリやフレームワークも充実して手軽に作ることができるというのも魅力だと思います。その中で、描画処理のデバッグについて困ることがあるのでは?と思いました。私などは、OpenGLやVulkan, DirectXなどのレイヤーを見ることが多いせいか、描画コマンドを追いかけながら調査したいなーと感じるのです。
この記事はブラウザで動いているWebGLのアプリに対して、デバッグ調査をするため、RenderDocを使ってGPUコマンドをキャプチャする手順を記載したものです。これまでの過去情報もいくらかネット上にあると思いますが、ここに書いたものは 2024年7月現在で、私が手元で試したものとなっています。
環境情報
動作を確認したときの環境情報が以下の通りです。確実な動作保証をするわけではありませんが、参考情報として。
- Windows11 Professional 64ビット版 (23H2)
- GeForce RTX 3060
- ドライバは 546.33 (執筆時点の最新ではありません)
- RenderDoc
- v1.30
ブラウザとしては、Chrome と Edge を使っていきます。
- Google Chrome 126.0.6478
- Microsoft Edge 126.0.2592.87
RenderDoc の設定を変更
ブラウザのプロセスでGPUキャプチャをするためには、プロセスインジェクションが必要です。標準の状態では設定が有効になっていないので、まずは有効にするところから必要です。
- メニュー/Tools/Settings を開きます
- General のカテゴリ内にある、「Enable process injection (restart required)」のところにチェックを入れて、有効化します。
- RenderDoc を再起動します。
![](https://www.technicalife.net/wp-content/uploads/2024/07/image-10.png)
再起動後は、Fileメニューに「Inject into Process」の項目が追加されるようになります。これで一旦 RenderDoc 側の準備は完了です。
![](https://www.technicalife.net/wp-content/uploads/2024/07/image-11.png)
ブラウザの起動を変更する
Google Chrome の場合
Chrome を使っている場合、ブラウザの起動時オプション設定が必要です。管理者権限は不要で、いつものコマンドプロンプトを開いて作業を行います。
既に起動済みのChromeプロセスがいると効果がないので、まずは全Chromeプロセスを終了させます。これには以下のコマンドを実行するとよいでしょう。
taskkill /F /IM chrome.exe
そして、全てのプロセスが終了された後で、以下のコマンドを実行して Chrome を起動します。ブログ上では改行が入って表示されていると思いますが、これは1行のコマンドです。インストールされている chrome.exe の場所が違う人はその点は読み替えて下さい(多くの場合でこの場所だとは思います)。
cmd /C "set RENDERDOC_HOOK_EGL=0 && "C:\Program Files\Google\Chrome\Application\chrome.exe" --gpu-startup-dialog --disable_direct_composition=1 --disable-gpu-sandbox"
このコマンドで起動すると、ブラウザの描画処理担当プロセスのPIDが表示されたメッセージボックスが出現します(どこかにいるはずなので探して下さい)。このメッセージボックスは閉じずに次のステップに進みます。またブラウザ自身のウィンドウが真っ白な状態ですが、これは心配ありません。
Microsoft Edge の場合
Microsoft Edge を使っている場合、ブラウザの起動時オプション設定が必要です。管理者権限は不要で、いつものコマンドプロンプトを開いて作業を行います。
既に起動済みのEdgeプロセスがいると効果がないので、まずは全Edgeプロセスを終了させます。これには以下のコマンドを実行するとよいでしょう。タスクマネージャーからはなぜかEdgeの全プロセスが終了できないことがあったので、以下のコマンドを実行することを強く勧めます。
taskkill /F /IM msedge.exe
そして、全てのプロセスが終了された後で、以下のコマンドを実行して Microsoft Edge を起動します。ブログ上では改行が入って表示されていると思いますが、これは1行のコマンドです。
cmd /C "set RENDERDOC_HOOK_EGL=0 && "C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe" --gpu-startup-dialog --disable_direct_composition=1 --disable-gpu-sandbox"
このコマンドで起動すると、ブラウザの描画処理担当プロセスのPIDが表示されたメッセージボックスが出現します(どこかにいるはずなので探して下さい)。このメッセージボックスは閉じずに次のステップに進みます。またブラウザ自身のウィンドウが真っ白な状態ですが、これは心配ありません。
![](https://www.technicalife.net/wp-content/uploads/2024/07/image-12.png)
キャプチャを実行する
RenderDocのファイルメニューから、「Inject into Process」を選択します。そして使用するブラウザのプロセス名を入れてフィルタリングしておきます。
![](https://www.technicalife.net/wp-content/uploads/2024/07/image-14.png)
ブラウザを起動した際に出現していたメッセージボックスで、プロセスIDの情報が出ていました。それと同じプロセスIDを持つものをこのリストから選んで、画面右下の「Inject」ボタンを押します。このInject ボタンを押した後で、ブラウザ側で出ていたメッセージボックスを閉じてください。
メッセージボックスを閉じると、以下のようにブラウザが起動します。左上にはRenderDocからインジェクションされたことを確認できる文言が表示されています。この部分は既にRenderDocを使ったことがある人であれば、いつも見ているアレだ!とわかると思います。 Microsoft Edge であれ、Chrome であれ、同じような状態になります。
![](https://www.technicalife.net/wp-content/uploads/2024/07/image-15-1024x383.png)
![](https://www.technicalife.net/wp-content/uploads/2024/07/image-16.png)
これでRenderDocから対象のブラウザに対してインジェクションができた状態と思います。この状態で、普段RenderDocを使うときと同じようにして描画フレームのキャプチャを行い、GPUコマンドの様子をチェックすることができます。
キャプチャしたときの様子を示します。WebGLのAPIとしてキャプチャではなく、ブラウザがAngle経由でD3D11 (DirectX11) で実装しているため、キャプチャのAPIとして見えてくるのはD3D11 のものが見えてきます。それでもどのような描画ステップを辿ったかを見ることはできますし、テクスチャの内容も見ることができるので、デバッグには有用です。
![](https://www.technicalife.net/wp-content/uploads/2024/07/image-17-1024x383.png)
ブラウザのGPUキャプチャがなぜ難しいのか
ブラウザは一般的なゲームアプリケーションやGPUを使うツールなどと大きく構造が異なります。特にマルチプロセスで動作しているという点は大きいでしょう。このマルチプロセスという点では、各タブごとにプロセスが作られているのかなと考えるかもしれませんが、そういう単純なものではありません。
ブラウザを構成するものとして、メインのブラウザプロセス、描画レンダリングを担当するレンダリングプロセス、その他、という感じのものになっています。GPUコマンドの発行はこの描画プロセスから行われるので、このプロセスに対してキャプチャ処理が必要となります。ただし、現行のブラウザでは複数タブや説明した役割ごとのプロセスなどで、多くのプロセスが同時に起動しているので、どれが描画用のプロセスかの判断が少々難しいです
プロセスごとの起動引数やプロセスの親子関係などで、推測することは可能かもしれませんが、手間はかかるでしょう。
そして、ブラウザはセキュリティのことも意識されています。メインプロセス以外のものに対して、プロセスをサンドボックスの中で動かしています。OSの機能を使ってこれを実現しているようで、サンドボックスのプロセスではCPUとメモリは自由に使えますが、それ以外の操作は制限されたものとなっています。そして、サンドボックスプロセスとの通信も専用のチャネルを使って行う必要があります。こういった仕組みで内容が守られていますが、それ故に外からのキャプチャが難しいのです。
コメント