Garminウォッチフェイスの作成-AMOLEDへの対応

ForeAthlete 45が壊れてしまい新しくForerunner 165を購入したのだけど、画面がMIPからAMOLEDになってしまったため、今までと異なる状態になってしまった。

それに対応するため、作ったウォッチフェイスをAMOLED対応にして見た。

MIPとAMOLED

MIPとAMOLEDの物理的な違いについて

  • MIP(Memory In Pixel)
    反射型の液晶ディスプレイで、画面の更新時のみ電力を消費し、更新していない間の電力消費量はゼロ。
    自発光ではないので暗い場所ではバックライトが必要だけど、反射型なので晴天時の視認性が良いなどの利点はある。
  • AMOLED
    アクティブマトリックスの有機ELディスプレイの略らしい。
    自発光なので明るく視認性もいい。どの角度から見ても識別ができる。
    ドットの小型化が容易なので、高精細化が可能。
    また過去の機種では、焼き付きという現象が起こる場合がある。
    焼き付きは、同一ドットが長時間高輝度な状態に維持されると、その部分が残像が残ってしまうというもの。最新機種もしくは最新ソフトバージョンでは発生しないらしい。

表示の違いは以下の写真のような感じ。
左が165、右が45。

ソフトウェアを取り扱う上での違いについて

  • MIP
    高電力モードでは1秒周期でonUpdateが呼び出されて画面更新が行われる。
    低電力モード(onEnterSleepが呼び出された後)では1分周期でonUpdateが呼び出され画面更新が行われる。
    API Level 2.3.0以上対応の機種の場合、低電力モードでも1秒周期でonPartialUpdateが呼び出され、部分変更による秒情報などの描画を行えることができる。
  • AMOLED
    高電力モードでは1秒周期でonUpdateが呼び出されて画面更新が行われる。
    低電力モードでかつToybox.System.DeviceSettings.requiresBurnInProtectionがtrueの場合には、1分周期でonUpdateが呼び出され画面更新が行われる。requiresBurnInProtectionがfalseの場合は画面更新が行われず、画面は真っ黒になる。
    なおrequiresBurnInProtectionはAPI Level 3.0.12以上の機種のみ利用できる。
    また、AMOLED側ではonPartialUpdateの部分更新は行われない。

常時表示モード

AMOLEDにはMIPにない、「常時表示」のON/OFFという項目がある。

これは先に書いたAMOLEDの消費電力または焼き付き防止のための処置で、この設定がOFFの場合低電力モードでは画面の更新が行われず、画面が黒いままになる。

設定をONにすることでMIPと同様に低電力モードで画面更新が行われるが、この時画面の更新内容により、常時表示がOFFと同様に更新が停止されることがある。
気を付けなければいけない画面の更新が以下の通り。

  • 消費電力が増加するような画面更新
    画面に何かしら表示することで、電力を消費するという仕様上できるだけ表示量を抑える必要がある。
    低電力状態では表示されるピクセルが画面全体の10%未満になるように調整したものにする必要がある。
  • 焼き付き防止
    こちらの方は最新機種もしくは最新ファームでは気にする必要はないらしい。
    仕様としては、同じ個所をずっと表示し続けると問題となる。

実装方法

画面設計

低電力モードでは画面の10%未満しか描画しないような設計にする必要がある。

すでに作成済みウォッチフェイスの場合は、AMOLEDの機種でシミュレート実行しLOWモードにしFile-View Screen Heat Mapを指定することで、状況を確認できる。またすでに逸脱した設計になっている場合はLOWモード直後にScreen Heat Mapが表示される。


これが自作ウォッチフェイスの結果。
日付・時間に関しては、一番ピクセル使用量が多そうな12/29 23:59にして見た。
これによると、ピクセル使用率は14.1%。
画面中にあるStartボタンを押すことで、24時間分、高速動作させて使用率の変化なども確認できる。

個人的に、低電力モードではチラ見で時間を確認するだけでいいと思うので、低電力モードでの表示部分は、以下の赤丸部分だけにする仕様にして見た。

デフォルトで入っているウォッチフェイスでは、文字の肉抜きをしたり、輝度を落としたりとした感じにしていた。

コード

ベースとなるのはこちらで作った物。これにAMOLED対応を入れる。

baseクラス

bpView()というboolを返す関数を用意する。
これがtrueの場合、常時表示ONかつ低電力モードで表示するAMOLED用の画面表示をするようにする。

bpViewはBurnInProtection用のViewを表示するかどうか、という意味でつけた。

中身の実装は、「Toybox.System.DeviceSettings.requiresBurnInProtection && !doViewSec()」の結果を返すようにしている。

  • 補足
    Toybox.System.DeviceSettings.requiresBurnInProtectionはAPI Level 3.0.12以上で利用可能になる。それ以下のAPIレベルの機種では、そのままアクセスすると例外でウォッチフェイスが止まってしまう。
    そこで、初期処理などで、Toybox.System.DeviceSettings.requiresBurnInProtectionが存在すればその値を取得、なければfalseだったという処理で実装するようにするのが良いかもしれない。

partialクラス

こちらはMIPの部分更新対応のための表示クラスになるため、AMOLED用の画面にすることはない。そのためbpView()をオーバーライドしてfalseを返すようにしておく。

実装例

baseクラスの初期処理とbpView実装、表示部分の実装例。

    var allwaysView = false;	// 常時表示モードかどうか

    function initialize() {
	var device = System.getDeviceSettings();
	if (device has :requiresBurnInProtection) {
	    if (device.requiresBurnInProtection) {
		allwaysView = device.requiresBurnInProtection;
	    }
	}
    }

    // AMOLEDの焼き付き防止のビューをする場合trueそうでない場合false
    function bpView() {
	// 常時表示モードがONでかつローパワーモードの場合trueにする
	return allwaysView && !doViewSec();
    }
    // Update the view
    function onUpdate(dc) {
        dc.setColor(Graphics.COLOR_BLACK, Graphics.COLOR_BLACK);
    	dc.clear();
    	var now = Time.now();
        var nowM = Time.Gregorian.info(now, Time.FORMAT_MEDIUM);
        var nowS = Time.Gregorian.info(now, Time.FORMAT_SHORT);
        dc.setColor(Graphics.COLOR_WHITE, Graphics.COLOR_TRANSPARENT);
	drawTime(dc, nowM, nowS);
	if (!bpView()) {
            // MIP時の低電力モードで追加表示するデータ
	   drawInformation(dc, ActivityMonitor.getInfo());
	   drawNotify(dc, System.getDeviceSettings());		// 色の変更有
	   drawBattery(dc, System.getSystemStats().battery);	// 色の変更有
	   drawSun(dc, nowS);	// 色・幅の変更有
	}
    }

partialクラスの追加実装

    function bpView() {
	return false;
    }

実際の表示


高電力モード。こちらは今までと同じ。


低電力モードかつ常時表示がONの場合の表示。

コメント

タイトルとURLをコピーしました