Macに外部ディスプレイを接続して上下左右にアンダースキャンが発生したときに試してみたいこと

2019.02.28

はじめに

清水です。先日、会社のフリーアドレス席に座り、備え付けられているディスプレイと支給されているMacBook Pro(13-inch, 2017, Four Thunderbolt 3 Ports)を接続したところ、上下左右に黒い帯が表示されるアンダースキャンが発生しました。ディスプレイはフルHDの解像度(1920x1080)の製品なのですが、これをフルに利用できないのはちょっと残念です。いくつか解決策を試し、アンダースキャン現象を解決することができたので内容をまとめてみたいと思います。

現象: アンダースキャンはどんな状態か

まずはこのアンダースキャンが発生している状態を確認しておきましょう。実際にアンダースキャンが発生した状態が下記になります。ベゼルが大きいディスプレイのようにも見えなくはないですが、実際はベゼルではなく液晶部分の上下左右に黒帯が入ってしまい、実際に表示できる領域をフルに利用できていない状態です。

拡大し、わかりやすいように加工したものがこちらです。

例えばPCからの映像出力が4:3のアスペクト比、対してディスプレイが16:9で左右にアンダースキャンが発生する、もしくはその逆で上下にアンダースキャンが発生する、というケースであれば仕方ないのですが、この状態はどちらも16:9の比率です。単純にPCからの出力が縮小して表示されてしまっている状態となります。

なお、関連項目にオーバースキャンというものもあります。Appleのサポートサイト載っている比較がわかりやすいです。

解決策1: 左右反対のThunderbolt 3(USB-C)ポートに接続する

1つ目の解決策です。シンプルですが左右反対のThunderbolt 3(USB-C)ポートに接続してみます。以下は実際に右側のポートに接続して解決した例です。

なぜ?と思いますが、後述します設定ファイル等から想像するに、左右のThunderbolt 3(USB-C)ポートでは別々の設定を持っているようです。今回であれば左側のThunderbolt 3(USB-C)ポートではアンダースキャン状態になってしまいましたが、右側のThunderbolt 3(USB-C)ポートではアンダースキャン状態となっておらず、問題を回避できたのではないかと考えられます。

解決策2: OS設定ファイルでディスプレイ設定を初期化する

2つ目の解決策です。こちらはmacOSの設定ファイルを操作することになりますので、自己責任で行ってください。 なお使用しているmacOSのバージョンは10.13.6となります。

調べてみたところ、macOS上でディスプレイ設定は/private/var/db/.com.apple.iokit.graphicsというファイルで行われているようです。以下のようなフォーマットで記載されています。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
        <key>IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/IGPU@2/AppleIntelFramebuffer@0/display0/AppleBacklightDisplay-610-a034</key>
        <dict>
                <key>startup-timing</key>
                <data>
                AAAAAAAAAIAQcACAAAAAAAAAAAAAAAAAAAAAAAAAAAAADwAAYAkAAAIAAAAB
                AAAAkGyKDwAAAACQbIoPAAAAAJBsig8AAAAAAAoAAFAAAAAIAAAAIAAAAEAG
                AAAuAAAAIAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAA
                AAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
                </data>
                <key>version</key>
                <integer>2</integer>
        </dict>
        <key>IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/IGPU@2/AppleIntelFramebuffer@1/display0/AppleDisplay-1e6d-5ab8</key>
        <dict>
                <key>cyuv</key>
                <integer>268435456</integer>
                <key>pscn</key>
                <integer>10000</integer>
                <key>startup-timing</key>
                <data>
                AAAAAAAAAIAAcACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
                AAAAIO7ZCAAAAAAg7tkIAAAAACDu2QgAAAAAgAcAABgBAABYAAAALAAAADgE
                AAAtAAAABAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAABAAAAAAAA
                AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
                </data>
                <key>version</key>
                <integer>2</integer>
        </dict>
… 以下、複数の<key>~</key>、<dict>~</dict>が続く …
</dict>
</plist>

接続した外部ディスプレイのKeyを確認する

この/private/var/db/.com.apple.iokit.graphicsファイルを編集するにあたり、まずは接続した外部ディスプレイのKeyを確認する必要があります。この確認にはioreg -lw0コマンドを実行し、IODisplayPrefsKeyでgrepします。

まずは外部ディスプレイを接続していない状態で、ioreg -lw0 | grep IODisplayPrefsKeyを実行します。

$ ioreg -lw0 | grep IODisplayPrefsKey
    | |   | |         "IODisplayPrefsKey" = "IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/IGPU@2/AppleIntelFramebuffer@0/display0/AppleBacklightDisplay-610-a034"

続いて、外部ディスプレイを接続した状態で同じコマンドを実行します。

$ ioreg -lw0 | grep IODisplayPrefsKey
    | |   | |         "IODisplayPrefsKey" = "IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/IGPU@2/AppleIntelFramebuffer@0/display0/AppleBacklightDisplay-610-a034"
    | |   | |         "IODisplayPrefsKey" = "IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/IGPU@2/AppleIntelFramebuffer@1/display0/AppleDisplay-26cd-6616"

最後が26cd-6616で終わるものが増えていますね、こちらが対象の外部ディスプレイのKeyとなります。

対象の外部ディスプレイの設定を初期化する

確認できたディスプレイのKeyをもとにファイル/private/var/db/.com.apple.iokit.graphicsを確認してみると、以下のようになっていました。

	<key>IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/IGPU@2/AppleIntelFramebuffer@1/display0/AppleDisplay-26cd-6616</key>
	<dict>
		<key>cyuv</key>
		<integer>268435456</integer>
		<key>pscn</key>
		<integer>9497</integer>
		<key>startup-timing</key>
		<data>
		AAAAAAAAAIAAMACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
		AAAAIO7ZCAAAAAAg7tkIAAAAACDu2QgAAAAAgAcAABgBAABYAAAALAAAADgE
		AAAtAAAABAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAABAAAAAAAA
		AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
		</data>
		<key>version</key>
		<integer>2</integer>
	</dict>

pscnに続くinteger部分が9497となっていますが、本来アンダースキャンが発生しない状態であれば、この箇所が10000となるようです。そのため解決策としてはこの部分を10000に書き換える、もしくは対象の~, ~部分をまるっと削除する(今回であれば、上記の引用した箇所)、となります。/private/var/db/.com.apple.iokit.graphicsファイルの書き換えにはroot権限が必要です。

繰り返しになりますがOSの設定ファイルを書き換える作業となります。ファイル構造を破損してしまった場合の動作はどうなるかわかりません。自己責任で編集してください。

ファイルを変更した後、macOSを再起動し再度ディスプレイを接続してみるとアンダースキャン現象が解消されていました。

アンダースキャンの原因を予想してみる

さてこのアンダースキャン現象、昨年春に会社支給PCがそれまでのMacBook Pro (Retina, 13-inch, Early 2015)からMacBook Pro (13-inch, 2017, Four Thunderbolt 3 Ports)にアップグレードされてから、私個人では数回発生しています。とはいえ、他にあまり発生したということも聞かず、Webに情報もあまりありませんでした。(日本語で見つかった情報は参考サイトに挙げたサイトぐらいです。Bookmarkせずにいて、再度発生したときに見つけるのに苦労しました…)

なにか個人的にアンダースキャンにつながることがあるかな…、と考えたところ、1点、MacBook Pro (13-inch, 2017, Four Thunderbolt 3 Ports)に変わった後、自宅で使用している外部ディスプレイ兼テレビに接続した際にオーバースキャン設定をしていたことを思い出しました。この設定の経緯がやや複雑で、ただ接続するだけだと外部ディスプレイ兼TVのそのままの1360x768の解像度で認識されます。ただこのHD(720p)相当の解像度だと操作がし辛いので、フォントが潰れるなどデメリットもありますが、macOS上からディスプレイの解像度を1080pに変更して使用しています。MacBook Pro (13-inch, 2017, Four Thunderbolt 3 Ports)では、この1080pに変更した際にオーバースキャンが発生し、アンダースキャンする設定を有効にしていました。

この自宅用外部ディスプレイ兼TVに該当する/private/var/db/.com.apple.iokit.graphicsファイルを確認してみたところ、下記のようにpscnの値が10000ではなく9497となっていました。(Keyが4dd9-f401のものです。)つまりこの自宅で使用している外部ディスプレイ兼TVのオーバースキャン解決のためのアンダースキャン設定が他のディスプレイにも影響し、結果としてアンダースキャンを生み出しているのでは?と推測できました。

	<key>IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/IGPU@2/AppleIntelFramebuffer@1/display0/AppleDisplay-4dd9-f401</key>
	<dict>
		<key>cyuv</key>
		<integer>268435456</integer>
		<key>pscn</key>
		<integer>9497</integer>
		<key>startup-timing</key>
		<data>
		AAAAAAAAAIACMACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
		AAAAIO7ZCAAAAAAg7tkIAAAAACDu2QgAAAAAgAcAABgBAABYAAAALAAAADgE
		AAAtAAAABAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAABAAAAAAAA
		AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
		</data>
		<key>version</key>
		<integer>2</integer>
	</dict>

左右のThunderbolt 3(USB-C)ポートでは別々の設定を持っている?

上記の通り、自宅で使用している外部ディスプレイ兼TVのオーバースキャンを解決するためにアンダースキャン設定をしていたのですが、左右反対のThunderbolt 3(USB-C)ポートにつなぐとオーバースキャンが再発し、アンダースキャン設定はリセットされていました。この点をちょっと深追いしてみます。まずはディスプレイ設定のKeyの確認です。外部ディスプレイ兼TVを接続していない状態のioreg -lw0 | grep IODisplayPrefsKeyの結果は以下となります。

$ ioreg -lw0 | grep IODisplayPrefsKey
    | |   | |         "IODisplayPrefsKey" = "IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/IGPU@2/AppleIntelFramebuffer@0/display0/AppleBacklightDisplay-610-a034"

続いて、左側のThunderbolt 3(USB-C)ポートに接続したときの結果です。こちらがオーバースキャン解決のためにアンダースキャン設定が有効になっているほうです。

$ ioreg -lw0 | grep IODisplayPrefsKey
    | |   | |         "IODisplayPrefsKey" = "IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/IGPU@2/AppleIntelFramebuffer@0/display0/AppleBacklightDisplay-610-a034"
    | |   | |         "IODisplayPrefsKey" = "IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/IGPU@2/AppleIntelFramebuffer@1/display0/AppleDisplay-4dd9-f401"

そして右側のThunderbolt 3(USB-C)ポートに接続したときです。こちらはアンダースキャン設定がリセットされていたほうですね。

$ ioreg -lw0 | grep IODisplayPrefsKey
    | |   | |         "IODisplayPrefsKey" = "IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/IGPU@2/AppleIntelFramebuffer@0/display0/AppleBacklightDisplay-610-a034"
    | |   | |         "IODisplayPrefsKey" = "IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/IGPU@2/AppleIntelFramebuffer@2/display0/AppleDisplay-4dd9-f401"

末尾の4dd9-f401は同じなのですが、途中AppleIntelFramebuffer@1AppleIntelFramebuffer@2か、違いがあることがわかります。さらに/private/var/db/.com.apple.iokit.graphicsファイルも確認してみると、以下2つの~,~が存在し、pscnの値が異なることがわかりました。

	<key>IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/IGPU@2/AppleIntelFramebuffer@1/display0/AppleDisplay-4dd9-f401</key>
	<dict>
		<key>cyuv</key>
		<integer>268435456</integer>
		<key>pscn</key>
		<integer>9497</integer>
		<key>startup-timing</key>
		<data>
		AAAAAAAAAIACMACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
		AAAAIO7ZCAAAAAAg7tkIAAAAACDu2QgAAAAAgAcAABgBAABYAAAALAAAADgE
		AAAtAAAABAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAABAAAAAAAA
		AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
		</data>
		<key>version</key>
		<integer>2</integer>
	</dict>
	<key>IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/IGPU@2/AppleIntelFramebuffer@2/display0/AppleDisplay-4dd9-f401</key>
	<dict>
		<key>cyuv</key>
		<integer>268435456</integer>
		<key>pscn</key>
		<integer>10000</integer>
		<key>startup-timing</key>
		<data>
		AAAAAAAAAIACMACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
		AAAAIO7ZCAAAAAAg7tkIAAAAACDu2QgAAAAAgAcAABgBAABYAAAALAAAADgE
		AAAtAAAABAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAABAAAAAAAA
		AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
		</data>
		<key>version</key>
		<integer>2</integer>
	</dict>

以上から、左右のThunderbolt 3(USB-C)ポートでは別々の設定を持っていると判断しています。なお、左右それぞれ2箇所あるThunderbolt 3(USB-C)ポートについては、どちらに接続してもオーバースキャン/アンダースキャン設定の状態に変化はありませんでした。

まとめ

MacBook Pro (13-inch, 2017, Four Thunderbolt 3 Ports)で外部ディスプレイを接続した際に発生した、アンダースキャン現象の解決策を2つまとめてみました。Appleの公式サイトにもオーバースキャン、アンダースキャンについては記載があるのですが、オーバースキャンしか解決方法が提供されていないように見えます。たしかにアンダースキャン状態ではオーバースキャンと違い、情報はすべて見えているので操作自体に支障はないといえばないのですが… できることならディスプレイはフル活用したいですもんね。ということでブログにまとめられたので、今度は再発してもすぐに対応できるかと思います!

参考サイト