本文へスキップ
Device MCP
← ブログ

エンジニアリング · 2026/11/04 · 5 分で読めます

Android エミュレータのミラーリングが 60 fps に

Device MCP は、Android エミュレータが描画するすべてのフレームを 60 fps で表示するようになりました。エミュレータのミラーリングがカクついていた理由、計測結果、そして何を変えたかを紹介します。

執筆:Device MCP チーム

Device MCP が Android エミュレータに対応したとき、iPhone と iOS シミュレータはすでに 60 fps でミラーリングできていました。エミュレータはそうではありませんでした。スクロールはカクつき、動画はコマ落ちし、動きの多い画面では 10 fps まで落ちることもありました。

Android エミュレータのミラーリングが 60 fps になりました。Device MCP は、エミュレータが描画するすべてのフレームを、Mac の GPU で描画して表示します。同じエミュレータで再生した同じ YouTube 動画の、以前と現在の比較です。

Device MCP の同じ Pixel 9 Pro エミュレータで再生した同じ YouTube 動画。以前の scrcpy の映像は約 23 fps、現在のエミュレータ自身のストリームは 60 fps

動画内の数字は手で入力したものではありません。それぞれの録画に含まれる新しい画を、1 秒ごとに数えたものです。

計測したもの

M5 Max 搭載の MacBook Pro で、Android 16 の Pixel 9 Pro エミュレータを 1 台使い、YouTube で Big Buck Bunny を 1080p60 の全画面で再生しました。それぞれの構成で、2 つの数値を読み取りました。Android 自身が動画の新しいフレームを画面に出した頻度(SurfaceFlinger 自身のタイムスタンプ)と、Mac に届いた新しい画の数です。

構成Android の描画ミラーの表示
以前の Device MCP:ウインドウなしのエミュレータ、scrcpy の H.264 映像約 44 fps約 23 fps
Android 16 での Android Studio のデフォルト(Automatic グラフィックス)約 45 fps約 45 fps
現在の Device MCP:Mac の GPU、エミュレータ自身のストリーム60 fps60 fps

動画は公平なテストですが、いちばん厳しいテストではありません。canvas のアニメーションのように画面全体を描き直すページは、ソフトウェア描画の構成では 10〜15 fps しか出ませんでした。「10 fps」という報告は、ここから来ていました。

以前のミラーリングの足を引っ張っていたのは 2 つ。エミュレータの描画方法と、その画が Mac に届くまでの経路です。

問題 1:ソフトウェアでの描画

Android エミュレータは、Mac の GPU で描画することも、ソフトウェア(CPU)で描画することもできます。Device MCP はこれまで、エミュレータを -no-window で起動していました。Device MCP のミラーが、エミュレータのウインドウの役割を果たしていたからです。自分のウインドウがないと、エミュレータはソフトウェアレンダラ(SwiftShader または Lavapipe)を選びます。

Android 16 では、さらに悪くなります。Mac では、エミュレータのグラフィックス設定 Automatic が、Android 16 のイメージでもソフトウェアを選びます(「API level 36 requires GLES 3.1」)。つまり、Android Studio からデフォルト設定で起動したエミュレータも、ソフトウェアで描画しているのです。たいていの画面ならそれで問題ありませんが、全画面の動画やアニメーションは、使える CPU コアをすべて使い切ってしまいます。

問題 2:Android の中でのエンコード

Device MCP は、画面の取得に scrcpy を使っていました。scrcpy は実機のスマートフォンでは非常に優秀です。Android の中で動き、ディスプレイをキャプチャして、スマートフォンのハードウェアビデオエンコーダで H.264 にエンコードします。

エミュレータにはハードウェアエンコーダがありません。scrcpy は Android のソフトウェアエンコーダにフォールバックします。これはエミュレータ自身の仮想 CPU、つまり見ているアプリを描画しているのと同じ CPU の上で動きます。上のテストでは、エンコーダがエミュレータ内のどの処理よりも多くの CPU を使い、ミラーに届いたのは Android が描画したフレームの約半分でした。GPU をオンにしても改善しませんでした。その場合、scrcpy はエンコードの前に各フレームを GPU からコピーし戻す必要があり、ミラーは 3〜5 fps まで落ちました。

解決策:エミュレータ自身の画面

Android エミュレータには、もともと高速な抜け道がありました。エミュレータは Mac 上で gRPC サービスを動かしていて、その呼び出しの 1 つ streamScreenshot は、エミュレータが新しいフレームを描画した瞬間に、それをそのままの RGB ピクセルとして送ります。Android Studio が Running Devices ウインドウでエミュレータを表示しているのも、この仕組みです。

Device MCP も同じ方法をとるようになりました。

  • エミュレータのフレームを直接読み取ります。エンコードもデコードもしません。Device MCP は、どのエミュレータも書き出す検出用ファイルからエミュレータのサービスを見つけ、各フレームを Mac のピクセル形式に変換して画面に表示します。Pixel 9 Pro のフレームは 1 枚 11 MB なので、毎秒 60 枚で約 660 MB/s になります。ネットワーク越しなら大きな量ですが、1 台の Mac の中でのやり取りなら何でもありません。
  • ウインドウを隠したまま、GPU でエミュレータを起動します。Device MCP は emulator -avd <name> -qt-hide-window -gpu host -grpc-use-token を実行するようになりました。Android Studio が埋め込みエミュレータに使うフラグに、ハードウェアグラフィックスを加えたものです。Android Studio で AVD を Software に設定している場合は、Device MCP もその設定に従います。
  • scrcpy は入力専用として残ります。scrcpy のサーバーは映像をオフにしたまま、クリック、キー、テキスト、クリップボードを引き続き送ります。タッチの位置は以前とまったく同じです。

ミラーがどの経路を使っているかは、Inspector に表示されます。エミュレータの場合、Mirror には emulator gRPC と表示され、Quality にはパネル全体の解像度と RGB が表示されます。

動画を再生中の Pixel 9 Pro エミュレータを表示した Device MCP の Inspector:Mirror は emulator gRPC、Quality は RGB 2856×1280、Frame rate は 60 fps

ほかの方法で起動したエミュレータ

何も変える必要はありません。60 fps でストリーミングできないエミュレータ(Android Studio がソフトウェア描画で起動したものや、スクリプトが -no-window で起動したもの)をミラーリングしようとすると、Device MCP はそのエミュレータを高速な方法で自動的に起動し直します。起動画面が 15〜20 秒表示され、エージェントの MCP 呼び出しはエミュレータが戻るまで待ちます。これは Device MCP を起動するたびに、エミュレータごとに 1 回だけ行われます。

知っておきたいことがいくつかあります。

  • 最初の再起動はコールドブートです。ソフトウェア描画中に保存された Quick Boot のスナップショットは GPU では読み込めないため、開いていたアプリは閉じます。インストール済みのアプリとそのデータは残ります。2 回目以降の再起動では、スナップショットが保たれます。
  • デバッグセッションは終了します。Android Studio がそのエミュレータでアプリを実行またはデバッグしていた場合、Device MCP が再起動するとそのセッションは止まります。Android Studio の Running Devices ウインドウは、自動的にエミュレータを再び表示します。
  • 自分で指定したフラグが優先されます。-writable-system、-http-proxy、-port、ソフトウェアの -gpu など、Device MCP が渡さないオプションで起動したエミュレータは、そのままにしておきます。その場合は、出せる範囲の速度でミラーリングします。

エージェントにとっての意味

エージェントのスクリーンショットは、これまでどおり Android 自身から取得します。ただし、ゲームや Web ビューのように、エージェントが画面の内容を尋ねてもアクセシビリティツリーでは答えられない場合、Device MCP はミラーの画を読み取り、そこに写っている文字を認識します。その画が、2048 ピクセルに縮小された H.264 のフレームから、2856×1280 のパネル全体を圧縮なしで使ったものに変わったので、小さな文字もよりきれいに読み取れます。

計測方法

動画は、Device MCP のウインドウを続けて 2 回録画したものです。同じエミュレータ、同じ YouTube 動画、同じ品質設定で録画し、映画のシーンの切り替わりで位置を合わせました。エミュレータのストリームは画面が変わったときにしかフレームを送らないので、更新はすべて新しい画として数えます。scrcpy のデコーダは直前とほとんど変わらないフレームも表示するため、以前の経路では、目に見えて変化したフレームだけを数えました。画面収録そのものが 60 フレーム中 57〜58 フレームしか取り込めないため、動画のカウンターは 60 の少し手前で止まります。「Android の描画」の列は SurfaceFlinger のフレームタイムスタンプから、Android Studio の数値は Running Devices ウインドウが読むのと同じストリームを読み取って得たものです。数値は Mac や AVD、画面の内容によって変わりますが、この差は変わりません。

試してみる

Device MCP をアップデートして、サイドバーからエミュレータを起動し、何か動くものを再生してみてください。

Big Buck Bunny © copyright 2008, Blender Foundation, peach.blender.org。CC BY 3.0 ライセンスのもとで提供されています。

次に読む

Device MCP は、Proxyman、Tiny Shield、TCP Viewer を開発する Proxyman LLC が作っています。