投稿されたすべてのトピック

Firefox 53 アドオン互換性情報

Mozilla では Firefox 57 へ向けたロードマップ を投稿しています。もしまだ読んでいなければ目を通してみてください。Firefox 53 は重要なマイルストーンで、AMO で旧式アドオンの「新規」受付が停止され、マルチプロセス Firefox が初期設定で有効化され、WebExtensions API を経由しないアドオンからのバイナリアクセスが制限されます。

Firefox 53 は 4 月 18 日 [日本時間同日深夜] リリース となります。Firefox 53 の変更点でアドオンの互換性に影響を及ぼす可能性のあるものを以下にまとめました。Firefox 53 for Developers により詳しい情報が載っていますので、こちらも併せてご覧ください。

一般

パスワードマネージャー

以下 3 つの変更は関連しており、アドオンが findSlotByName("") を呼び出してマスターパスワードが設定されているかどうかを確認できなくなったことが主な影響として挙げられます。該当するコードの変更方法は こちら の例を見てください。

XPCOM とモジュール

WebExtensions

この一覧に載っていない変更点や間違いを見つけたらコメント欄でお知らせください。もしあなたのアドオンが Firefox 53 で動かなくなった場合は、筆者の方でも調査したいと思います。

AMO に登録されているアドオンの 自動互換性テストと対応バージョンの更新 は数週間以内に行われますので、AMO に Firefox 52 対応のアドオンを登録している方は後日メールをチェックしてみてください。

JavaScript ゲームにおける操作方法

[この記事は、Control mechanisms in JavaScript games の翻訳です。]

ラップトップやデスクトップをはじめ、スマートフォンやタブレット、TV や冷蔵庫でさえも、共通してブラウザを持つようになりました。ということは、それらの端末上で HTML5 ゲームをプレイできるようになったという風にも思えますが、実際にプレイするためには、ゲーム画面を描画するのと同時に、何らかの方法でゲームを操作できなければなりません。キーボードやマウスはもちろん、タッチ操作、ゲームパッド、TV リモコン、さらにはバナナに至るまで、それぞれのプラットフォームごとに適した選択肢はたくさん存在します(MDN では、control mechanisms に関する一連の記事でそれらのインターフェースを取り上げています)。

captainrogers2-cover

今回は、実際のプロジェクトにおける例として、Phaser を用いて作成された Captain Rogers: Battle at Andromeda のデモを使ってぞれぞれの操作方法の実装方法について紹介します。プラットフォームの違いによってゲームの操作性がどう変わっていくかをご確認ください。また、異なるプラットフォームに対応する際に別々にビルドする必要がないということもお見せします。ウェブのマルチプラットフォームという特性によって、コーディングに多くの労力を費やすことなく複数のデバイスに対応できることがお分かりいただけると思います。

controls-purejsgame

また、GitHub には、小さいですが純粋な JavaScript によるデモがオープンソースとして公開されています。操作方法がどのように実装されているかを実際に確認できるので、ご自身のゲーム開発プロジェクトでもお使いいただけます。以下に、主な項目をハイライトでご紹介しますので、このままお読みいただいても良いですし、今すぐコーディングを開始しても良いでしょう。

モバイル タッチ

HTML5 ゲームではモバイルファースト開発が人気ですので、まずはモバイル タッチへの対応から見ていきましょう。

document.addEventListener("touchstart", touchHandler);
document.addEventListener("touchmove", touchHandler);
function touchHandler(e) {
    if(e.touches) {
        playerX = e.touches[0].pageX - canvas.offsetLeft - playerWidth / 2;
        playerY = e.touches[0].pageY - canvas.offsetTop - playerHeight / 2;
    }
}

たった数行の JavaScript コードですが、これがゲーム内でタッチ操作を実現するために必要な最低限のコードです。これだけでモバイル端末上で機能します。最初の 2 行は、タッチ操作に対するイベントリスナーの設定です。それぞれ、画面をタッチしたとき、および、指で画面をなぞったときに対応します。関数内では、タッチ操作が行われたことを確認し、プレイヤーの座標を設定しています。これにより、ゲームの Canvas 上でプレイヤーの機体が正しい位置に描画されます。

上記はベースとなるコードですので、ここからマルチタッチやジェスチャーなど様々な発展形を実装することができます(むしろ、実装した方がいいでしょう)。ゲームの種類や、何をどのように操作するかということを考慮して、実装する操作方法を決めましょう。また、移動用の矢印や発射ボタンなど、特定のアクションを起こすためのボタンを画面上に設置することもできます。詳しくは、Mobile touch controls をご覧ください。

デスクトップ マウスとキーボード

移動用の矢印について触れましたが、モバイル端末向けに画面上に矢印を表示するのはもちろん、デスクトップ向けにそれらを実装することも可能です。ゲーム内のキャラクターを動かす方法としては、カーソルキーや WASD キーがよく使われます。例えば、以下のコードではカーソルキーを使用しています。

document.addEventListener("keydown", keyDownHandler);
function keyDownHandler(e) {
    if(e.keyCode == 39) {
        rightPressed = true;
    }
    else if(e.keyCode == 37) {
        leftPressed = true;
    }
    if(e.keyCode == 40) {
        downPressed = true;
    }
    else if(e.keyCode == 38) {
        upPressed = true;
    }
}

押されたキーを定常的に検出しその情報を保存するということですので、これは描画ループとして以下のように処理することが可能です。

function draw() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    if(rightPressed) {
        playerX += 5;
    }
    else if(leftPressed) {
        playerX -= 5;
    }
    if(downPressed) {
        playerY += 5;
    }
    else if(upPressed) {
        playerY -= 5;
    }
    ctx.drawImage(img, playerX, playerY);
    requestAnimationFrame(draw);
}

プレイヤーの位置 x および y を表す変数が調整され、機体画像が新たな位置に表示されます。

controls-howtoplay

一方、デスクトップにおけるマウスは、コーディングにおいてモバイルのタッチと非常に似ています。タッチやクリックが起こった場所に関する情報を取得し、プレイヤーの位置を更新するだけです。

document.addEventListener("mousemove", mouseMoveHandler);
function mouseMoveHandler(e) {
    playerX = e.pageX - canvas.offsetLeft - playerWidth / 2;
    playerY = e.pageY - canvas.offsetTop - playerHeight / 2;
}

マウスポインターの位置が変化するたびに mousemove イベントが検出されるので、プレイヤーの位置がマウスポインターの中央の位置に来るように調整します。こうして、デスクトップのキーボードとマウスの両方で操作可能なゲームを実現することができます。さらに詳しく知りたい方は、Desktop mouse and keyboard controls をご覧ください。

ゲームパッド

個人的に大好きな操作方法です。プレゼンテーションを行う際は、HTML5 ベースの自分のスライドを Gamepad APIを使って操作しているくらいです。ゲームパッドについては、すでに数回お話したこともありますし、ゲームもいくつか実装したこともあります。詳しくは、Gamepad API Content Kit に全て記載しています。 とにかく、コンピューター上でコンソール気分を体験できることは本当に素晴らしいと思いますし、それがウェブ技術によって実現されているということも素晴らしいと思います!ゲームパッドを使用すれば、Captain Rogers のプレイ体験がさらに向上しますし、単純に良い気分になります。

controls-gamepadinfo

Gamepad API への対応はタッチやキーボードよりもやや複雑になりますが、それでも非常に簡単です。

window.addEventListener("gamepadconnected", gamepadHandler);
function gamepadHandler(e) {
    controller = e.gamepad;
}
function gamepadUpdateHandler() {
    buttonsPressed = [];
    if(controller.buttons) {
        for(var b=0; b<controller.buttons.length; b++) {
            if(controller.buttons[i].pressed) {
                buttonsPressed.push(b);
            }
        }
    }
}
function gamepadButtonPressedHandler(button) {
    var press = false;
    for(var i=0; i<buttonsPressed.length; i++) {
        if(buttonsPressed[i] == button) {
            press = true;
        }
    }
    return press;
}

ゲームパッドが接続されるとイベントが発生し、ゲームパッドに関するデータの参照が変数に保存されます。以降は、その変数を使用してゲームパッドに関するデータにアクセスします。更新が起こると、押されたボタンの配列が新たに生成されるため、常に最新の状態が保持されます。また、あるボタンが押されたかどうかを判定するために配列をループ処理する関数もあります。これらはキーボードチェックと同様に、描画ループの中で使用できます。

function draw() {
    // ...
    gamepadUpdateHandler();
    if(gamepadButtonPressedHandler(0)) {
        playerY -= 5;
    }
    else if(gamepadButtonPressedHandler(1)) {
        playerY += 5;
    }
    if(gamepadButtonPressedHandler(2)) {
        playerX -= 5;
    }
    else if(gamepadButtonPressedHandler(3)) {
        playerX += 5;
    }
    if(gamepadButtonPressedHandler(11)) {
        alert('BOOM!');
    }
    // ...
}

こうすることで、プレイヤーの機体を DPad ボタン(十字キー)で操作したり、A ボタンで爆弾を爆発させることができるようになります。このほか、スティック操作を検知することもできますし、独自の小さいライブラリを作ってゲームパッドからの入力を処理することもできます。詳しくは、Desktop gamepad controls をご覧ください。

特殊な操作方法

さらにもっと進んで、リビングにある大型 TV のリモコンを使ったり、ラップトップの前で手を振ったり、食材とPCを線で繋いでその食材を押したりすることで、ゲームをプレイすることも可能です。

controls-tvremote

例えば、Panasonic 製の TV リモコンはキーボードイベントを再利用しているので、対応が非常に簡単です。リモコンの方向矢印はキーボードのカーソルキーと全く同じコード(37383940)を使用しているので、すぐに対応できます。リモコン特有のボタンについては、こちらに一覧がありますので、詳細情報とともにご覧ください。

controls-leapmotion

また、リモコンのボタンを押す代わりに、Leap Motion 機器の機能を使用して自分の手の位置や他のパラメーターを検知することで、何にも触れることなくプレイヤーの機体を操作することもできます。あらかじめ定義されている loop 内で、手に関する情報を取得できるので、

Leap.loop({
    hand: function(hand) {
        horizontalDegree = Math.round(hand.roll() * toDegrees);
        verticalDegree = Math.round(hand.pitch() * toDegrees);
        grabStrength = hand.grabStrength;
    }
});

それを使用してプレイヤーの位置を更新します。

function draw() {
    // ...
    if(horizontalDegree > degreeThreshold) {
        playerX -= 5;
    }
    else if(horizontalDegree < -degreeThreshold) {
        playerX += 5;
    }
    if(verticalDegree > degreeThreshold) {
        playerY += 5;
    }
    else if(verticalDegree < -degreeThreshold) {
        playerY -= 5;
    }
    if(grabStrength == 1) {
        alert('BOOM!');
    }
    // ...
}

その他にも、Unconventional controlsでは、 ドップラー効果や Proximity API、MaKey MaKeyなど興味深い操作方法の実装方法を紹介しています。

まとめ

最近は、HTML5 ゲームをプレイするのに使える機器がますます増えています。ご自身の腕時計も使えるかもしれませんし、はたまた音声認識によるウェブゲームも良いかもしれません。まさに、可能性は無限です。覚えておいて頂きたいのは、多くの操作方法に対応しているほど、ゲームにとっては良いことだということです。なぜなら、幅広い種類の機器を用いて、どんなプラットフォームでもプレイ可能になるからです。ぜひ、ブラウザがもたらす可能性を存分に活用しましょう。

kvmでfirefox-build-env(Mozilla build用VM)を使用する

これは https://kusanagi.lv7777.org/2017/01/05/kvm%E3%81%A7firefox-build-envmozilla-build%E7%94%A8vm%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%99%E3%82%8B/ のクロスポストです。

 

以下のurlはmdnのfirefox-build-envについての記事。現在、筆者がtranslationしている。

https://developer.mozilla.org/ja/docs/Mozilla/Developer_Guide/Using_the_VM

が、上記の記事にはkvmによるMozilla buildの方法が書いていない。

といっても難しいことはなく、普通のova(vmware拡張子)をkvmにインポートするようにすればできる。
<ol>
<li>ovaのダウンロード</li>
<li>ovaを解答</li>
<li>vmのインポート</li>
<li>vmの起動とビルド</li>
<li>ビルドしたfirefoxの起動</li>
</ol>
まずvmのダウンロードだが上記記事(MDN)の中からダウンロードできる。黄緑のボタンで大きく書かれているためUXがいい。

このvmがかなり重い。通常の環境だと2時間ぐらいかかるかもしれない。なにせmozilla-centralとubuntuが入っているので。

次のovaの解答というステップだが、`tar  -vxf ダウンロードしてきたova`で解凍できる。

ovaはvmware専用形式(アプライアンス)だがそれの中身はvmをvmware用のメタ情報と一緒に圧縮したもの。

さて、解凍が終わればvmdkという拡張子が出てくるはず。こいつをqemu-convertでqcow2に変換する。

変換し終わったらvirt-managerを使って新規追加(星とディスプレイのアイコン)からインポートを選んで仮想マシンとして認識させる。cpu設定などはお好みで。

この辺は一般的なkvmのノウハウだが、intel-vtdを有効にしておかないとエラーが出るはず。(大抵の環境では有効になってると思うが)

また、ネットワーク関係でエラーが出た場合edit > connection details > visual networksタブ の下のスタートボタンを押せば外部(ネットワーク)にvmが繋がった状態になるはず。

次にvmの起動とビルドだが、起動させたら自動ログインが有効なため、すでにログインしてる状態になってるはず。

sublimetext2を起動させればmozilla-centralのソースを編集できる状態になっている。つまりもうfirefoxのソースをいじったりbuildすることができる。

sublimetext2の上のtoolsからbuildを選べばすぐにbuildを開始する。

“`
ビルドの処理が開始するので、お茶や美味しい食事でもして休憩しましょう。
“`

自分の場合は30分かからなかった気がする。VMがビルド用に最適化処理をかけてくれている。もちろんデバッグ用ビルドをするときも簡単に変更できる。

ビルド終わったら起動させる。tools > runを押せばfirefoxが起動できるはず。

 

割と楽にできるのでfirefox-build-envを使うのがおすすめです

A-Blast: 宇宙からの可愛い侵略者から世界を救え!

[この記事は "A-Blast: Save the World from the Cutest Creatures in the Universe!" の抄訳です]

準備できたら VR コントローラーを握って、https://aframe.io/a-blast へ行け! ブラウザーの設定確認も忘れるな。Nightly 版 Firefox なら大丈夫だ。Chromium を使っているなら、chrome://flags/#enable-webvrchrome://flags/#enable-gamepad-extensions のフラグを忘れずに on にしておけ。

A-Blast のプレー画面

次々にやってくる敵を撃つシューテイングゲームは、VR ではポピュラーなジャンルです。実装も簡単です。プレーヤーが動き回る必要がないため、 位置に関する機能を実装する必要がありませんし、視点が固定されているためステージを単純にできるためです。 また射撃と弾との衝突判定のみを考えれば良いため、敵キャラとのインタラクションの実装も簡単です。 このようなシューティングゲームは単純であるだけに、プレイして楽しく、 Raw Data のように、時にはプレーヤーキャラクターになりきってしまうことすらあります。

A-Blast
はスムースな操作性とアセットのクオリティに着目し、A-Frame とブラウザーの性能を示す例として作成されました。 また A-Frame や WebVR が搭載された Firefox といった、我々の作ったツールを自分たちで使用して評価するためでもあります。

テストをする中でパフォーマンス上の問題がいくつも見つかりました。これに対処するため、初期実装のうちのいくつかを最適化し、 pool コンポーネントのような機能を A-Frame に追加しました。 これらに関する詳細は別の記事として、後日公開します。

このゲームの遊び方はシンプルです:武器をとり、飛び回るキャラクターを狙って、トリガーを引きます。 敵弾をかわすこともできます。ライフは 5 です。 敵を倒せば倒すほど、スコアが入ります。ローカルではありますが、ハイスコアランキングもあります。

イベントでのデモでの使用を考慮して、多くの人に試してもらえるように 5 分以内でプレーできるゲームを目指しました。 短すぎるかもしれません。完全版では、より凝ったステージを用意したいと思っています。 しかしこれは技術デモなのです。何時間もプレーできるコンテンツを作成したわけではありません。

A-Blast で使用するブラスター

HTC VIVE での使用を念頭に作成しましたが、キーボードとマウスでもプレーできます。 またスマートフォンを使っても遊べます。その時はスクリーンをタップして敵を撃ちます。

このゲームは JavaScript の VR フレームワークである A-Frame を利用して、 2 人のプログラマーと 1 人のアーティストが 2 ヶ月で実装しました。 2016 年 12 月にハワイであった Mozilla All-Hands で披露され、多くの Mozillian にプレーされました。

All Hands での試遊風景

A-Blast は A-Frame の tour de force、 つまり A-Frame が複雑なアプリケーションでの利用に耐える信頼性と負荷への耐性のテストを兼ねています。 その結果を利用して、我々は A-Frame を改善してゆきます(なお A-Blast のソースコードは、A-Painter のそれよりもわずかに大きいものとなっています)。

グローバルのハイスコアランキングや、動作する可能なコントローラーやデバイスの追加といった改善のためのアイディアをお持ちであれば、 お気軽に pull request を送ってください。A-Blast のソースコードは GitHub で公開されています

最後に、サウンドトラックを作成してくれた José Manuel Pérez Paredes (JosSs) に大きな感謝の言葉を贈ります。 彼の作成した音楽のおかげで、ゲームの体験がぐっと良いものになりました。

Adobe Flash利用を削減するFirefox

この投稿は米国 Mozilla Tech Blog の記事 “Reducing Adobe Flash Usage in Firefox” の抄訳です。

ブラウザプラグイン、特にFlashは、ビデオ再生やインタラクティブなコンテンツを含む、いくつかの素晴らしい機能をウェブの世界で使えるようにしてきました。しかし、プラグインはしばしば安定性、パフォーマンスやセキュリティの課題をブラウザに引き起こして来ました。これはユーザが受け入れなければならないトレードオフではありません。

Mozillaおよびウェブ業界は、日々のブラウジングにFlashの必要性が低くなるように段階を踏んできました。2016年8月、Firefoxはユーザ体験に必須ではない、いくつかのFlashコンテンツをブロックしましたが、レガシーのFlashコンテンツはサポートを継続しております。これらの変更および将来の変更により、Firefoxユーザにとってはセキュリティの拡張、バッテリー寿命延長、ページロードの高速化や、より良いブラウザー反応性が実現する予定です。

ここ何年かに亘り、Firefoxはこれまでプラグインでしか提供されていなかった機能をWebAPIで代替する実装を行ってきました。これはビデオ・音声再生やストリーミング機能、クリップボード統合、高速2Dおよび3Dグラフィックス、WebSocketネットワーキングやマイク・カメラアクセスなどです。ウェブサイトがFlashから他のウェブ技術に移行するに従って、プラグインによるFirefoxのクラッシュレートは劇的に低下しました。

Firefoxはユーザに見えない特殊なFlashコンテンツをブロックすることにより、この傾向を継続していきます。これによりFlashのクラッシュやハングは最大10%になる見込みです。ウェブサイトの互換性問題を最小化するため、これらの変化はHTMLに置き換え可能な少なく厳選されたFlashコンテンツのリストに当初は限定されていました。私たちは時間をかけてこのリストを追加していく予定です。

2016年末、私たちは広告測定でよく使われるコンテンツの可視性(viewability)をチェックするために使われるFlashをこのリストに追加しました。これはFirefoxのパフォーマンスとデバイスバッテリー寿命を向上させます。この変更と同時にFirefoxはHTMLで同等の機能となるIntersection Observer API (Firefox bug 1243846)を実装いたします。可視性測定に現在Flashを利用されているコンテンツ製作者のみなさんには、このAPIが有効になり次第、この新しいAPIを適用いただくことをお勧めいたします。

2017年には、Firefoxはすべてのコンテンツについて、Flashプラグイン持つウェブサイトを有効にする前に、クリックによる有効化承認作業を必要とする予定です。現在ビデオやゲームでFlashやSilverlightをご利用のウェブサイトはできるだけ早期にHTML技術への適用を計画すべきです。Firefoxはビデオプラグインの代替として、Adobe PrimetimeとGoogle Widevineの暗号ビデオ再生をサポートしています。

私たちは引き続きAdobe社と密接に連携し、最適に実現可能なFlash体験をユーザのみなさんに提供していきます。この開発パートナーシップにより、パフォーマンスと安定性を改善するWindowsでの高DPIの改善や、拡張サンドボックス、高速化Flashレンダリングパイプラインを実装していきます。

これらの変更により、ユーザのみなさんが使いやすいウェブ体験を損なうことなく、ブラウジングを安全に高速にするための私たちの進めるさまざまな活動の一部です。2015年に発表しましたとおり、2017年3月にFirefoxはFlashを除くすべてのNPAPIプラグインのサポートを停止する計画です。次のメジャーバージョンであるFirefox ESR (法人向け延長サポート版)リリースは同じ2017年3月に予定されていますが、移行に時間が必要なユーザのみなさまのために、ESRではSilverlightやJavaなどのプラグインのサポートを2018年初頭まで継続する予定です。

私たちは多くのその他の機能や改善を試み、Firefoxを発見や協調のためのより素晴らしいプラットフォームにしてきます。フィードバックや機能リクエストをお待ちしています。

2017年のアドオン

この投稿は米国 Mozilla Tech Blog の記事 “Add-ons in 2017” の抄訳です。

1年以上前に私たちはアドオンはどこに向かうのか、そして将来はどんな風になるのか、について会話を開始しました。それは多忙でした。そして2017年にやりたいと考えているガイダンスをご提供し、そのアップデートをご提供したいと思いました。

2015年を通して、私たちはコミュニティとしてFirefoxとaddons.mozilla.org(AMO)のWebExtensionsサポートを追加する基礎的な作業を行うことに注力してきました。そして開発中の標準をメンテナンスする間にレビューすべきリスト化されたアドオンに関わる時間を削減し、アドオンのe10sへの準備を済ませてきました。私たちは、Signing APIやアドオンマネージャの改良版Discovery Paneのようなイニシアティブを通してアドオンの投稿、配信と発見を簡単にするプロセスや製品を数多く変革してきました。そうして、私たちは直接のコンタクトやメーリングリスト、Eメールキャンペーン、wikiやアドオンブログを通して開発者コミュニティに変革をお知らせすることに注力してきました。

私たちが申し上げてきましたとおり、WebExtensionsはFirefoxのアドオンの将来であり、2017年も集中して取り組むエリアです。WebExtensionsはプラットフォームと切り離されており、我々がFirefoxに対してこれから、そしてそれ以降の年に予定する変革はプラットフォームには影響しません。(WebExtensionsの)開発はより簡単で、起動や実行するためにFirefoxの内部処理について学ぶ必要はありません。あなたのアドオンを最小の変更で他のブラウザーからの移植や他のブラウザーへの移植を行うことも簡単です。なぜなら、これらのAPIは – 当然ですが – Opera、ChromeやEdgeのような製品と互換性があるためです。

2017年末までに、Firefox 57のリリースに伴い、私たちはWebExtensionsだけのサポートに切り替え、デスクトップ上の他の種類の拡張機能をロードしないようにします。新しい拡張機能が2017年末以降も動作できるように、Firefox 53でAMOはWebExtensionsではない新しい拡張機能の署名受付を終了いたします。本年を通して私たちはAPIセットを拡張し、Firefoxに機能を追加し、それはまだ他のブラウザでは搭載していませんが、ユーザの前にもっとたくさんのWebExtensionsをご提供します。

移行する部品はたくさんあります。Mozilla WikiのWebExtensionsセクションで、時間軸やロードマップを含むもっと詳細な情報を追跡していきます。もしあなたがアドオンコミュニティやWebExtensionsに参加するご興味がありましたら、いくつかの方法があります。私たちは2017年を楽しみにしており、更新情報や追加情報をこちらのアドオンブログでお知らせしてまいります。

Add-onやWebExtensionsについてのより詳細な情報は、こちらをご覧ください。

注意:Firefox 53の時期にはさらなる具体的な更新を行います

Firefox 52 アドオン互換性情報

[これは Mozilla Add-ons Blog の記事 Add-on Compatibility for Firefox 52 の翻訳です]

Mozilla のアドオンチームでは 2017 年の計画 を公表しています。まだ見ていない方は目を通してみてください。以下で取り上げる変更点の大半は従来の API を使ったアドオンに関するものですが、今後は WebExtensions が前へ進むべき道となります。

Firefox 52 が 3 月 7 日 [日本時間同日深夜] リリース となります。Firefox 52 の変更点でアドオンの互換性に影響を及ぼす可能性のあるものを以下にまとめました。Firefox 52 for Developers により詳しい情報が載っていますので、こちらも併せてご覧ください。

一般

XPCOM とモジュール

テーマ

この一覧に載っていない変更点や間違いを見つけたらコメント欄でお知らせください。もしあなたのアドオンが Firefox 52 で動かなくなった場合は、筆者の方でも調査したいと思います。

AMO に登録されているアドオンの 自動互換性テストと対応バージョンの更新 は数週間以内に行われますので、AMO に Firefox 51 対応のアドオンを登録している方は後日メールをチェックしてみてください。

Servo で WebVR できるまで (その1)

["WebVR Coming to Servo: Part 1" の抄訳です]

VR はウェブで普通に使えるようになるべきです。そのためには、私たちの考える未来を実装するための柔軟で高速な処理系が必要です。 Servo はモダンで、ハイパフォーマンスなブラウザエンジンです。 アプリケーションとしての用途はもちろん、組み込み用途でも利用できるように設計されており、 Mozilla が 1 から実装を行なっています。 その技術的な目標とプロジェクトを取り巻くコミュニティと文化に共感したため、 Gecko (Firefox) への実装に並行して、WebVR を Servo に実装することを決めました。

Imanol Fernandez が WebVR API を初めて Rust で実装しました。 彼の実装である rust-webvr はブラウザーから独立していたため、単体でテストや利用ができました。 例えば Rust で実装された OpenGL アプリケーションが、 ブラウザーで利用できる API と同じものを使って VR ヘッドセットをコントロールできるようになります。 その次の目標は、Servo のアーキテクチャとの統合です。そのために、私たちはスクリーンに何かを表示するところから始めました。

Linux と Mac OS X では、Valve と Oculus の提供する SDK を利用できません。 そのため現在デスクトップ向け VR は Windows でしか動作しないものとなっています。 3D コンテンツをスクリーンに表示するために、Imanol は Servo に Windows 向けの WebGL バックエンドの実装を開始しました。 単純に考えて、WGL から始めることとしました。これは他のコンポーネントによって、すでに利用されていたためです。 将来的には Angle を利用したバックエンドの提供も考えています。 これはそれぞれの GPU のパフォーマンスをもっとも引き出せる選択肢となるでしょう。 VR アプリケーションにとって、低い遅延と高いフレームレートは必須の要件です。そのためには、JavaScript で WebGL の関数を読んでからスクリーンにピクセルが表示される前での間に、 何が起きているのかをしっかりと把握しなくてはなりません。 WebGL 関数の呼び出しには、Servo 内の異なるパーツが関係しています:

Servo 内の WebGL 関連モジュール

JavaScript の評価器と、IDL バインディング

Servo は JavaScript の処理系として moz-js を利用しています。これは SpiderMonkey の派生物です。 V8JavaScriptCore と同様、moz-js は JS の評価器としての機能しか持っていません。 WebGL のような API を追加するには、JS からネイティブのクラスや関数へアクセスできるようにする必要があります。 これは仮想マシン (VM) が提供する C/C++ の API を利用して実装されます。 その結果、JS のクラスを定義し、ネイティブと JS の関数を相互に呼び出すことが可能になります。   API を追加するためには、引数のチェックや JS – C++ 間のデータのやりとりなど、 似たようなコードをたくさん書かなくてはなりません。 これに加えて Servo では、C/C++ と Rust の間のバイディングコードも書かなくてはなりません。 このコードは rust-bindgen というツールを使って WebIDL と呼ばれる言語非依存な API 仕様から自動生成されます。 このツールのおかげで API のロジックに集中することができます。

Servo で API を定義する IDL はこちらで公開されています。これには WebGL も含まれます。

WebGL に関連する DOM オブジェクトの 実装

WebIDL バイディングによって Rust と JavaScript を繋げるためのコードは、自動的に生成されました。 その次は、個別の関数やクラスの実装です。実装がないとコンパイルができません。 そのため DOM オブジェクトである WebGLRenderingContext も実装しなくてはなりません。 こちらにその実装があります。 WebGLProgramWebGLShader のような、その他の WebGL クラスの実装も同様です。

これらの DOM オブジェクトは WebGL オブジェクトの状態を表していて、検証のためのルールは全て WebGL の仕様に定められています。 ただし、レンダリングコマンドの処理は全て、WebGL スレッドという別のコンポーネントへ委譲されます。

WebGL スレッド

Servo は並列処理アーキテクチャを取っています。そのため他のコンポーネント同様、WebGL のレンダリングコマンドは他の DOM の描画処理を行うスレッドや JS の評価を行うスレッドとは独立して実行されます。 これはパフォーマンスの向上には好都合でした。なぜなら GL の GPU ドライバーに対する呼び出しが JS の実行をブロックしないためです。 ただし glReadPixelsglGetParameter のような関数をを呼び出した場合は例外です。 これらの関数を呼び出した場合、JS スレッドは WebGL スレッドからのレスポンスを待つためブロックされます。 それでも十分に最適化されてた WebGL アプリにとっては問題にはなりません。

Servo の WebGL スレッドは DOM からの WebGL メッセージを受け取り、処理するように実装されています。 今の所、2つの描画パスを利用できます。どちらを利用するかは Servo の初期化方法によって決まります:

  • Webrender: WebGL スレッドは GL 関数呼び出しを Webrenderer コンポジタースレッドへ送出します。最近 Servo の標準の描画パスとなりました
  • rust-zure: 描画の抽象化レイヤーです。以前は標準の描画パスでした。グラフィックススライブラリーである Skia を内部的に利用し、スレッド内で GL 関数の処理を行います

Webrender は最適化された WebGL の描画パスを持っています。 それは 共有の OpenGL テクスチャを使ってコンポジションを行います。 一方 Skia は readPixels を用いてテクスチャを共有するため、その WebGL 描画パスは最適化されていません。

Servo と Rust のプロセス間通信

WebGL DOM は GL 描画メッセージを異なるスレッドを送出します。 Rust の標準ライブラリではスレッド間の通信には非同期のチャンネルを利用しますが、 Servo はマルチプロセス処理を向上させるため、独自に実装した ipc チャンネルを利用します。

チャンネルと Rust の強力な列挙型を組み合わせることにより、プロセス間通信はエレガントに実装できました。 WebGL スレッドで利用される WebGL コマンドは全て webnrenderer_traits に実装されています。 このコンポーネントは WebRender と Servo で共有されています。

OpenGL の呼び出し

Webrender チャンネルは GL コマンドを受け取り、OpenGL の関数を呼び出します。 ただし、この設計は将来変更されるかもしれません。その理由は GL コマンドのバッファリング機構の実装が計画されているためです。 Webrender は 1 つの GPU プロセスで、全ての WebGL コンテキストの処理を行います。

実際に GL コールを行う前にやらなければならないことがあります。 それはプラットフォームごとに異なる実際の関数の呼び出しです。 OpenGL ドライバーを呼ぶことになるかもしれませんし、 DirectX バックエンドを利用するために Angle のような OpenGL ラッパーを呼ぶことになるかもしれません。 もしくは OSMesa を利用するかもしれません。 Windows のようなプラットフォームでは、異なる OpenGL 実装を DLL として実行時にロードすることさえ可能です。 その DLL は OS によって提供されたものかもしれませんし、GPU ドライバー由来の最適化されたものかもしれません。

これらのラッパーを動かすためには、OpenGL のシンボルを動的にロードしなくてはなりません。 Servo は gleam ライブラリを利用して、同じ OpenGL シンボルを全てのコンポーネントで共有しています。 gleam は内部的に gl_generator を利用します。これは Rust コミュニティではよく使われるユーティリティで、 OpenGL の関数ポインターのローダーとバインディング機能を提供します。

これでついに OpenGL の関数呼び出しがドライバーまで到達しました。

Servo のコンポジションにおける WebGL アクセラレーション

これまで WebIDL のバインディング、DOM の実装、WebGL コマンドのマルチスレッド化、そして実際の GL 呼び出しについて述べてきました。 ここでは、WebGL canvas がメインウィンドウの描画コンテキストへ、どのように組み合わされるかを説明します。

Servo はメインウィンドウを GLutin を利用して作成します。 これはクロスプラットフォームウィンドウやメインの描画コンテキストの作成を助け、 入力やイベントの受付を簡単にするライブラリです。

WebGL コンテキストはヘッドレスなオフスクリーンコンテキストとして実装されています。 GL コマンドは テクスチャアタッチメントされた FBO を用いてテクスチャへの描画を行います。 WebGL の描画コマンドはマルチプラットフォームなものですが、ヘッドレスの GL コンテキスト作成はそうではありません。 プラットフォーム間の差異を隠蔽するために、Servo は rust-offscreen-rendering-context を利用します。 このライブラリは、ヘッドレスコンテキストの作成を抽象化し、EGL、CGL、WGL、OSMesa といった多様な API をサポートします。

Servo のコンポジターは Web ページの全ての要素の描画を管理するコンポーネントで、 GPU レンダリングには Webrenderer を利用しています。 WebGLContext は独自の描画コンテキストを持ちますが、コンポジターレイヤーとも描画コンテキスト共有されています。 共有が効率的に行えるのは、共有されたテクスチャのおかげです。

ウェブが飛躍的に進化します

この投稿は米国 Mozilla Tech Blog の記事 “A Quantum Leap for the Web” の抄訳です。

ここ 1 年間の Firefox にとっての最優先事項は、ブラウザのマルチプロセス化を行う Electrolysis プロジェクトでした。 Firefox を複数プロセスに分割し、セキュリティとパフォーマンスを大きく向上させる、このプロジェクトは Firefox 史上最大の改良となりました。その成果は、これから数ヶ月をかけて、すべての Firefox ユーザーに提供される予定です。

しかし、このプロジェクトが Firefox 最後のセキュリティとパフォーマンス向上となるわけではありません。むしろ、 このプロジェクトによって Mozilla の次なる大きなプロジェクトの準備が整ったのです。

Quantumは次世代型ウェブエンジンを開発する取り組みです。 2017 年末にはその成果を届けられる見込みです。ウェブエンジンとはブラウザの核です。つまり、読み込んだコンテンツの実行と、描画を行うブラウザ内のパーツのことを、ブラウザエンジンと呼びます。 Quantum では並列処理を採用し、最新ハードウェアの性能を最大限活用します。 Quantumはいくつものコンポーネントからなりますが、その中には Servo プロジェクトから継承したものも含まれていまます。

これによって完成するエンジンは、モバイルとデスクトップ OS の両方において実行速度の高速化となめらかなユーザーエクスペリエンスをもたらし、パフォーマンスが飛躍的に向上するでしょう。このパフォーマンスの改良はとても著しく、ウェブ体験そのものが違ったものに感じられるほどでしょう。ページの読み込み速度は向上し、スクローリングもよりなめらかになります。アニメーションやインタラクティブアプリのレスポンスも瞬時に感じられ、フレームレートを一定に保ちながらより高度なコンテンツを処理することが可能になります。そして、ユーザーにとって重要なコンテンツが自動的に優先され、そこに処理能力が大きく配分されるようにもなっています。

これは、どのようにして可能になるのでしょうか。

ウェブブラウザは、デスクトップ PC の時代に登場しました。この時代のコンピューターにはコアを 1 つしか持たない CPU が搭載されていたため、同時に 1 つの処理しかできませんでした。今日においても、多くのブラウザはウェブページを 1 つのコア上で直列的に処理しています。

しかし時代は変わりました。スマートフォン、タブレット、ノート PC。私たちのウェブを見るために使っている端末には 2 個、 4 個、あるいはそれ以上のプロセッサが積み込まれています。また高性能な GPU を 1 つ以上搭載していることも珍しくなく、その力でレンダリングやその他の処理が高速化されています。

またウェブはハイパーリンクによって繋がった静的な文書の集まりから、インタラクティブで動的なアプリの集合へと、この 15 年で変化しました。遅延のなさや、リッチなアニメーション、リアルタイムなインタラクションを開発者だけでなく、一般の利用者も求めています。このような体験を可能なものとするためには、のは、並列処理やハードウェアに固有な複雑性に煩わされることなく、デバイスの能力を最大限まで利用できるウェブプラットフォームが必要です。

つまり Quantum とは、現代のデバイスが持つ処理能力を最大限まで利用し、未来のウェブのニーズを満たす次世代型のウェブエンジンをつくるプロジェクトです。 Gecko を出発点とし、そのコンポーネントを並列処理を利用したものや GPU へのオフロードを利用するものへ置き換えてゆきます。これを行う上で重要な要素の 1 つは、Servo の革新的なコンポーネントの取り込みです。Mozilla がスポンサーしている独立コミュニティによって開発されている、このウェブエンジンと、コンポーネントを一部共有するところから始めますが、それぞれのプロジェクトの進展に応じて、より多くの要素の組み込みも試みます。

Quantum のコンポーネントの多くは Rust で実装されています。 Rust は処理がとても速いプログラミング言語で、スレッドとメモリの安全を保証することで並列プログラムの開発を単純化します。ほとんどどの場合、安全でない Rust のコードはコンパイルできません。

Quantumの一環として、お互いに関係する取り組みをいくつも行っており、あわせて過去には当然とされてきた前提や、実装も再検討しています。つまり、ブラウザエンジンの仕組みを根本から考え直すのです。 CSS スタイルの反映や DOM 操作の実行、画面のレンダリングなど、ウェブエンジンの基礎となる部分も再開発します。

Quantum は野心的なプロジェクトですが、その成果を実感するまでに長い時間待つ必要はありません。来年には大きな改良を提供を始め、順次リリースを行います。まずは Android 、 Windows 、 Mac 、 Linux 向けの提供ですが、いつの日か iOS にも提供できることを願っています。

Quantum はブラウザのパフォーマンスマンスを飛躍的に向上させると確信しています。このプロジェクトに関わろうとお考えの開発者の方は、 Mozilla Wiki の Quantum に関するページをぜひご覧ください。一緒に飛躍的な成長を遂げましょう。

Firefox 51 アドオン互換性情報

[これは Mozilla Add-ons Blog の記事 Add-on Compatibility for Firefox 51 の翻訳です]

Firefox 51 が 1 月 24 日 [日本時間同日深夜] リリース となります。なお、12 月 13 日にはメジャーリリースではなくマイナーリリースが予定されているため、今回は普段より相当長いリリースサイクルとなります。Firefox 51 の変更点でアドオンの互換性に影響を及ぼす可能性のあるものを以下にまとめました。Firefox 51 for Developers により詳しい情報が載っていますので、こちらも併せてご覧ください。

一般

XPCOM とモジュール

新機能

  • 組み込み WebExtension: 再起動不要型アドオンに WebExtension を組み込めるようになったおかげで、この新しいプラットフォームへ徐々にコードを移行したり、保存したデータを WebExtension で扱える形式に変換したりすることが可能となりました。
  • WebExtension Experiments: これは、Mozilla (やアドオン作者の皆さん) が新しい WebExtension API を試作できるようにするための仕組みです。

この一覧に載っていない変更点や間違いを見つけたらコメント欄でお知らせください。もしあなたのアドオンが Firefox 51 で動かなくなった場合は、筆者の方でも調査したいと思います。

AMO に登録されているアドオンの 自動互換性テストと対応バージョンの更新 は数週間以内に行われますので、AMO に Firefox 50 対応のアドオンを登録している方は後日メールをチェックしてみてください。