モバイル GPU でのハイエンド レンダリングエンジン開発事例
-
Upload
jolene-riley -
Category
Documents
-
view
68 -
download
1
description
Transcript of モバイル GPU でのハイエンド レンダリングエンジン開発事例
![Page 1: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/1.jpg)
モバイル GPU でのハイエンドレンダリングエンジン開発事例
(株)トライエース 研究開発部永野和博 大嶋貴史 Elliott Davis
![Page 2: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/2.jpg)
コンテンツ
• 開発を始める前に• 実装• 最適化手法
![Page 3: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/3.jpg)
コンテンツ
• 開発を始める前に– 達成目標 – 開発環境– スケーラビリティを意識する– 具体的な作業箇所
![Page 4: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/4.jpg)
達成目標
• 達成目標– 自社開発の PS3, XBOX360 等スマートフォ
ンよりも高性能な機器で動作する , マルチプラットフォームエンジンをスマートフォン上でも動作するようにポーティングを行う
• 対応プラットフォーム– iOS5.0 以上 – Android 2.3 以上
![Page 5: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/5.jpg)
達成目標
検証 GPU の種類Vendor Imagination Technologies Qualcomm NVIDIA ARM
PoweVR SGX 540 (200MHz) Adreno 205 Tegra 2 Mali-400 MPPoweVR SGX 540 (384MHz) Adreno 220 Tegra 3 Mali-T604
PoweVR SGX 535 Adreno 225 Tegra 4PoweVR SGX 543MP2 Adreno 320PoweVR SGX 543MP4 Adreno 330PoweVR SGX 554MP4
GPU
上記の GPU の種類だけではなく , 更に CPU/OS の組み合わせがあるため対応すべきデバイスの種類は数え切れず , これからも増え続けていく
iOS Device
Android
![Page 6: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/6.jpg)
達成目標
検証 GPU の種類
上記の GPU の種類だけではなく , 更に CPU/OS の組み合わせがあるため対応すべきデバイスの種類は数え切れず , これからも増え続けていく
iOS Device
Android
今後の事を見据えたしっかりとした事前準備はとても大切
Vendor Imagination Technologies Qualcomm NVIDIA ARMPoweVR SGX 540 (200MHz) Adreno 205 Tegra 2 Mali-400 MPPoweVR SGX 540 (384MHz) Adreno 220 Tegra 3 Mali-T604
PoweVR SGX 535 Adreno 225 Tegra 4PoweVR SGX 543MP2 Adreno 320PoweVR SGX 543MP4 Adreno 330PoweVR SGX 554MP4
GPU
![Page 7: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/7.jpg)
コンテンツ
• 開発を始める前に– 達成目標 – 開発環境– スケーラビリティを意識する– 具体的な作業箇所
![Page 8: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/8.jpg)
IDE 言語 グラフィックスAPI その他
iOS Xcode Objective C++ OpenGL ES 2.0Android Eclipse C++ (一部J ava) OpenGL ES 2.0 Native Activity
開発環境
• 何を用いて開発するか?
![Page 9: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/9.jpg)
IDE 言語 グラフィックスAPI その他
iOS Xcode Objective C++ OpenGL ES 2.0Android Eclipse C++ (一部J ava) OpenGL ES 2.0 Native Activity
開発環境
• Xcode 上で問題なくデバッグできる
• 端末内の CPU/GPU の比較的統一されている
• こちらの方が開発は容易と予想
• 何を用いて開発するか?
![Page 10: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/10.jpg)
IDE 言語 グラフィックスAPI その他
iOS Xcode Objective C++ OpenGL ES 2.0Android Eclipse C++ (一部J ava) OpenGL ES 2.0 Native Activity
開発環境
• Eclipse 上でデバッグが困難– ブレイクポイントに止まらないことがある
– C++ を用いない箇所ではブレイクに止まる
• CPU/GPU のバリエーションが多すぎる
• こちらの開発はかなり大変
• 何を用いて開発するか?
![Page 11: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/11.jpg)
開発環境
• 開発スタイル– iOS の開発を先行して行い Android に移植– iOS 側で主要な実装と不具合を除去– Android 側は端末毎の固有の問題解決に注力
![Page 12: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/12.jpg)
開発環境
• 現在の EGL と GLES2 の状態を出力する関数を作る– 特に Android に有用
• 妥当性 : – glIsOOOO()– glValidateProgram()– glCheckFramebufferStatus()
• エラー : – glGetError()– eglGetError()
• エラーを出力する際は , 現在のスレッド情報も含める– ID 又は名前– GLES2 のコンテキスト ID
![Page 13: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/13.jpg)
コンテンツ
• 開発を始める前に– 達成目標 – 開発環境– スケーラビリティを意識する– 具体的な作業箇所
![Page 14: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/14.jpg)
• どれくらいの性能差があるのだろう?– 新製品発売のスパンが短い
• 市場はローエンド機とハイエンド機が混在している
– ローエンドとハイエンドの性能差は 10 倍~15 倍程度はある
スケーラビリティを意識する
![Page 15: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/15.jpg)
ローエンド機に合わせてエンジンを作成
• どれくらいの性能差があるのだろう?– 新製品発売のスパンが短い
• 市場はローエンド機とハイエンド機が混在している
– ローエンドとハイエンドの性能差は 10 倍~15 倍程度はある
スケーラビリティを意識する
![Page 16: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/16.jpg)
• どれくらいの性能差があるのだろう?– 新製品発売のスパンが短い
• 市場はローエンド機とハイエンド機が混在している
– ローエンドとハイエンドの性能差は 10 倍~15 倍程度はある
スケーラビリティを意識する
ローエンド機に合わせてエンジンを作成
可能な限り端末毎の最大性能を出させて良い映像を出す
![Page 17: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/17.jpg)
• 方法– 端末の性能毎にポストプロセスの設定を調整
する• ブルームの解像度
スケーラビリティを意識する
![Page 18: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/18.jpg)
• 方法– 端末の性能毎にポストプロセスの設定を調整
する• ブルームの解像度
– 端末の性能毎にシェーダの複雑さを調整する• ライト個数• ライティングをフラグメントシェーダからバー
テックスシェーダへ
• など
スケーラビリティを意識する
![Page 19: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/19.jpg)
• 方法– 端末の性能毎にポストプロセスの設定を調整
する• ブルームの解像度
– 端末の性能毎にシェーダの複雑さを調整する• ライト個数• ライティングをフラグメントシェーダからバー
テックスシェーダへ
• など– 端末の性能毎にランタイム内にてフロント
バッファ , バックバッファ解像度を調整できるようにする
スケーラビリティを意識する
![Page 20: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/20.jpg)
• どのようにして性能値を導くか?– あらかじめ主要な端末を調査し , ある程度
テーブル化しておきそこから外れるものは端末のデバイス情報とテーブルを参考に計算で求める
–初期化時にベンチマークを走らせて取得する
スケーラビリティを意識する
![Page 21: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/21.jpg)
• パフォーマンス変動をもたらす特殊な要因–温度変化
• 端末の温度上昇に連動して CPU/GPU のクロックが調整されている
–節電モード• リフレッシュレートが半分に抑制される
– BlueTooth• 原因は不明だが OFF にすることによりパフォー
マンスが劇的に改善するケースがあった
スケーラビリティを意識する
![Page 22: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/22.jpg)
コンテンツ
• 開発を始める前に– 達成目標 – 開発環境– スケーラビリティを意識する– 具体的な作業箇所
![Page 23: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/23.jpg)
• 当初の予想–ネイティブ API にかかわる箇所とシェーダに
関する修正を行う程度で問題ない– iOS から Android への移植もそれほど困難で
はない
具体的な作業箇所
![Page 24: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/24.jpg)
• 当初の予想–ネイティブ API にかかわる箇所とシェーダに
関する修正を行う程度で問題ない– iOS から Android への移植もそれほど困難で
はない
当初の予想に反し数々の問題が発生
具体的な作業箇所
![Page 25: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/25.jpg)
具体的な作業箇所
N+1 N+2
N
N+1 N+2
N+1
VSync (垂直同期)
N+3
VSync (垂直同期)
VSync (垂直同期)
N+2
N+3メインスレッド
ワーカースレッド 1
レンダースレッド
… …N+1 N+2 N+3ワーカースレッ
ド N
• エンジン内部の動作
![Page 26: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/26.jpg)
具体的な作業箇所
PrepareForRendering RenderContext生成
(Shader, Texture, State, etc)
Task処理
PreRender
WaitDraw
VSync
Dynamics, Collision, Animation
その他
Matrix, Culling
その他レンダリング準備
… DrawCall
Flush
Swap
メインスレッド
ワーカースレッド
レンダースレッド
![Page 27: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/27.jpg)
• 変更が必要だった箇所
– 画面更新のタイミング端末毎に異なっている事が判明
具体的な作業箇所
![Page 28: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/28.jpg)
• 変更が必要だった箇所
– 画面更新のタイミング端末毎に異なっている事が判明
– マルチスレッドレンダリングレンダリングコンテキストの問題
具体的な作業箇所
![Page 29: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/29.jpg)
• 変更が必要だった箇所
– 画面更新のタイミング端末毎に異なっている事が判明
– マルチスレッドレンダリングレンダリングコンテキストの問題
– シェーダ関連GPU に依存する問題
具体的な作業箇所
![Page 30: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/30.jpg)
• 変更が必要だった箇所
– 画面更新のタイミング端末毎に異なっている事が判明
– マルチスレッドレンダリング
レンダリングコンテキストの問題
– シェーダ関連GPU に依存する問題
– レンダーターゲット関連GPU, 端末種に依存する問題
具体的な作業箇所
![Page 31: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/31.jpg)
• 変更が必要だった箇所
– 画面更新のタイミング端末毎に異なっている事が判明
– マルチスレッドレンダリング
レンダリングコンテキストの問題
– シェーダ関連GPU に依存する問題
– レンダーターゲット関連GPU, 端末種に依存する問題
– 最適化GPU 毎に適した方法
具体的な作業箇所
![Page 32: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/32.jpg)
実装
![Page 33: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/33.jpg)
コンテンツ
• 実装– リフレッシュレート– マルチスレッドレンダリング– GPU 毎の Uniforms– フレームバッファ
![Page 34: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/34.jpg)
リフレッシュレート
• 画面更新のタイミング– VSync(垂直同期 ) のシグナルを利用
![Page 35: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/35.jpg)
リフレッシュレート
• 画面更新のタイミング– VSync(垂直同期 ) のシグナルを利用
ここで問題発生 !!
![Page 36: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/36.jpg)
リフレッシュレート
• 問題の概要– Vsync(垂直同期 ) のシグナルが取得できな
い• Android 4.0 以下のみの問題• iOS デバイスでは問題ない
– Android ではリフレッシュレートが端末毎に変化
–アニメーション等アセットが基準フレームレートに基づいて作成されている場合 , 再生速度が変化してしまう
リフレッシュレート1秒間に画面の更新が何回行われるかの事で単位はHz
![Page 37: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/37.jpg)
リフレッシュレート
• リフレッシュレートを確認– JNI(Java Native Interface) を用いて端末に
問い合わせる– 自分で計測する
![Page 38: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/38.jpg)
• リフレッシュレートを確認– JNI(Java Native Interface) を用いて端末に
問い合わせる– 自分で計測する
public float GetRefreshRate(){WindowManager windowManager = getWindowManager();Display display = windowManager.getDefaultDisplay();return display.getRefreshRate();
}
JNIEnv* pEnv = GetJNIEnv();Android_app* pApp = GetAndroidApp();jmethodID ID = pEnv->GetMethodID("GetRefreshRate", "()F");float fRefreshRate =(float)pEnv->CallFloatMethod(pApp()->activity->clazz, mID);
リフレッシュレート
C++ 側
Java 側
![Page 39: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/39.jpg)
リフレッシュレート
uPrevTime = getCurrentTime();for( int i = 0; i < COUNT; i++ ) { glClear( GL_DEPTH_BUFFER_BIT|
GL_COLOR_BUFFER_BIT|GL_STENCIL_BUFFER_BIT );
eglSwapBuffers(EGLData.display,EGLData.surface);}uAfterTime = getCurrentTime();uTotal = AfterTime – uPrevTime; sRefreshRate = uTotal / COUNT;
• リフレッシュレートを確認– JNI(Java Native Interface) を用いて端末に
問い合わせる– 自分で計測する
![Page 40: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/40.jpg)
リフレッシュレート
問い合わせ値 68Hz 60.382Hz 55Hz 60Hz 60Hz 60.382Hz
計測値 53Hz 59Hz 57Hz 61Hz 59Hz 30Hz
GalaxyS2(ISW11SC)節電モード
GalaxyS(SC-02B)
Arrowsμ(F-07D)
MediasLTE(N-04D)
GalaxyS2(ISW11SC)
ArrowsZ(ISW13F)
計測値と問い合わせた値が一致しない
• 取得結果
![Page 41: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/41.jpg)
以前の実装
• 基準フレームレートをもとにした可変フレームレート方式–アプリケーション起動時 , 基準フレームレー
トを設定– フレームレートは基準フレームレートの整数分の1で可変
• 基準フレームレートが 30 の時– 30, 15, 10, 7.5… の範囲で可変
![Page 42: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/42.jpg)
リフレッシュレート
• 解決策–完全可変フレームレート方式
• 1フレームにかかった時間を計測し , その時間を用いてアニメーションを再生
– フレームドロップ方式• 1フレーム時間と基準フレーム時間の差分を蓄積
し , 差分が基準フレーム分蓄積した際にフレームドロップを行う
![Page 43: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/43.jpg)
リフレッシュレート
• 完全可変フレームレート方式–長所
• アニメーションが滑らか– 短所
• アセットが可変フレームレートを想定していない場合想定どおりの再生ができない
• フレームドロップ方式–長所
• アセットが基準フレームレートに基づいて作成されていても想定どおりの時間で再生可能
– 短所• アニメーションが滑らかではない
![Page 44: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/44.jpg)
コンテンツ
• 実装– リフレッシュレート– マルチスレッドレンダリング– GPU 毎の Uniforms– フレームバッファ
![Page 45: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/45.jpg)
マルチスレッドレンダリング
• 概要1.複数の GLES2 のコンテキスト2.パフォーマンス調査
![Page 46: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/46.jpg)
EGL の仕様
• 複数のコンテキストが作成可能• 各スレッド間でどのコンテキストも使用可
能• 作成したリソースは共有可能
– テクスチャ– レンダーバッファ– シェーダ– バーテックスバッファ– インデックスバッファ– 等
![Page 47: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/47.jpg)
一般の実装
シェーダコンパイル
レンダー
ゲームオブジェクト更新
• コンテキストが必要なスレッド
![Page 48: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/48.jpg)
iOS での最初の実装• 複数のコンテキスト
を使用
• コンテキストが必要なスレッド
シェーダコンパイル
レンダー
ゲームオブジェクト更新
アプリメイン
![Page 49: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/49.jpg)
iOS での最初の実装• 複数のコンテキスト
を使用
• EAGLContext のrenderbufferStorage() を呼ぶタイミング問題の影響でアプリメインスレッドで呼ぶ
• コンテキストが必要なスレッド
シェーダコンパイル
レンダー
ゲームオブジェクト更新
アプリメイン
![Page 50: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/50.jpg)
Android の実装
• iOS と同様に複数のコンテキストを使おうとしたが
• いくつかの Android端末はコンテキストを一つしか使えない !
• このままではマルチスレッドレンダリング不可能
シェーダコンパイル
レンダー
ゲームオブジェクト更新
• コンテキストが必要なスレッド
![Page 51: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/51.jpg)
Android の実装
• いくつかの Android端末はコンテキストを一つしか使えない !
• このままではマルチスレッドレンダリング不可能
• スレッド:
シェーダコンパイル
レンダー
ゲームオブジェクト更新
使えない
![Page 52: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/52.jpg)
Android の実装 ー 解決方法
シェーダコンパイル
ゲームオブジェクト更新
• スレッド:
レンダー
使えない
![Page 53: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/53.jpg)
Android の実装 ー 解決方法
1. コンテキストをレンダースレッドにバインドする
シェーダコンパイル
レンダー
ゲームオブジェクト更新
• スレッド:コンテキストが必要
使えない
![Page 54: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/54.jpg)
レンダー
シェーダコンパイル
Android の実装 ー 解決方法
1. コンテキストをレンダースレッドにバインドする
2. シェーダコンパイルをレンダースレッドで行う
シェーダコンパイル
レンダー
ゲームオブジェクト更新
• スレッド:コンテキストが必要
使えない
![Page 55: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/55.jpg)
Android の実装 ー 解決方法
1. コンテキストをレンダースレッドにバインドする
2. シェーダコンパイルをレンダースレッドで行う
3. GLES2 リソースのラッパークラスの実装を変更
レンダー
シェーダコンパイル
• スレッド:コンテキストが必要使える使えない
ゲームオブジェクト更新
![Page 56: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/56.jpg)
Android の実装 ー 解決方法
• スレッド:コンテキストが必要使える使えない
レンダー
シェーダコンパイル
3. GLES2 リソースのラッパークラスの実装を変更
• リソースを作成や変更の場合– GLES2 関数を呼ばな
い– その為のデータを保持
ゲームオブジェクト更新
![Page 57: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/57.jpg)
Android の実装 ー 解決方法
レンダー
シェーダコンパイル
• スレッド:コンテキストが必要使える使えない
3. GLES2 リソースのラッパークラスの実装を変更
• GLES2 リソースを使う前に– 保持したデータを
GLES2 関数に渡して、リソースを作成や更新• 必要な時だけ
ゲームオブジェクト更新
![Page 58: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/58.jpg)
最終結果
レンダー
シェーダコンパイル シェーダコンパイル
レンダー
ゲームオブジェクト更新
アプリメイン
シェーダコンパイル
レンダー
アプリメイン
シェーダコンパイル
レンダー
アプリメイン
シェーダコンパイル
レンダー
シェーダコンパイル
アプリメイン
レンダー
シェーダコンパイル
コンテキストが必要 使える 使えない
Android iOS
ゲームオブジェクト更新
![Page 59: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/59.jpg)
マルチスレッドレンダリング
• 概要1.複数の GLES2 のコンテキスト2.パフォーマンス調査
![Page 60: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/60.jpg)
• CPU処理が重いシーンで測定– 最大パーティクル数を高くする–放出率を高くする– パーティクルデータの更新:
• ワーカースレッドで行う
• レンダースレッドで行わない
パフォーマンス
![Page 61: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/61.jpg)
20
34
18
43.5
0
10
20
30
40
50
Xperia SO- 02C( )シングルコア
MEDIAS N- 04D( )マルチコア
iPhone4( )シングルコア
iPhone4S( )マルチコア
レンダースレッド無し レンダースレッド有り
パフォーマンス結果
fps
fps
![Page 62: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/62.jpg)
20
34
18
43.5
0
10
20
30
40
50
Xperia SO- 02C( )シングルコア
MEDIAS N- 04D( )マルチコア
iPhone4( )シングルコア
iPhone4S( )マルチコア
レンダースレッド無し レンダースレッド有り
パフォーマンス結果
マルチコアで高速化に成功fps
fps
![Page 63: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/63.jpg)
20
34
18
43.5
0
10
20
30
40
50
Xperia SO- 02C( )シングルコア
MEDIAS N- 04D( )マルチコア
iPhone4( )シングルコア
iPhone4S( )マルチコア
レンダースレッド無し レンダースレッド有り
パフォーマンス結果
シングルコアでも速度向上に成功• GLES2 の API 内で発生するブロッキング中にメインスレッドへスイッチしたため , その分速度を向上させることができている模様
fps
fps
![Page 64: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/64.jpg)
20
34
18
43.5
0
10
20
30
40
50
Xperia SO- 02C( )シングルコア
MEDIAS N- 04D( )マルチコア
iPhone4( )シングルコア
iPhone4S( )マルチコア
レンダースレッド無し レンダースレッド有り
パフォーマンス結果
シングルコアでは速度が多少減少• スレッド切り替えコストが高く、速度が上がらない
fps
fps
![Page 65: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/65.jpg)
20
34
18
43.5
0
10
20
30
40
50
Xperia SO- 02C( )シングルコア
MEDIAS N- 04D( )マルチコア
iPhone4( )シングルコア
iPhone4S( )マルチコア
レンダースレッド無し レンダースレッド有り
パフォーマンス結果
シングルコアでは端末によってメリット又は
デメリットがある• 解決方法:ランタイム中に端末毎にレン
ダースレッドを使用するかどうかを決定
fps
fps
![Page 66: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/66.jpg)
• ドローコール数が多いシーンで測定– 複数のボックスを配置– 先程と同じく CPU負荷を意図的に高くして
おく
パフォーマンス
![Page 67: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/67.jpg)
19
28
15
35.5
0
10
20
30
40
50
Xperia SO- 02C(シングルコア)
MEDIAS N- 04D(マルチコア)
iPhone4(シングルコア)
iPhone4S(マルチコア)
レンダースレッド無し レンダースレッド有り
パフォーマンス結果fps
fps
![Page 68: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/68.jpg)
コンテンツ
• 実装– リフレッシュレート– マルチスレッドレンダリング– GPU 毎の Uniforms– フレームバッファ
![Page 69: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/69.jpg)
Uniform とは ?• シェーダで利用される定数データ
• HLSL の場合、シェーダコンスタントと呼ばれる
![Page 70: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/70.jpg)
• glGetActiveUniform ()で情報が取得– 名前–配列サイズ–型
ここで問題発生
Uniform とは ?
![Page 71: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/71.jpg)
• glGetActiveUniform ()で情報が取得– 名前–配列サイズ–型
ここで問題発生
Uniform とは ?
![Page 72: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/72.jpg)
• glGetActiveUniform ()で情報が取得– 名前–配列サイズ–型
GLES2 の仕様によるとGPU によって変化しない
問題の概要
![Page 73: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/73.jpg)
• glGetActiveUniform ()で情報が取得– 名前–配列サイズ–型
実際には変化してしまう
問題の概要
![Page 74: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/74.jpg)
• シェーダ内に構造体を作成• 構造体内に配列型のメンバがある• それを uniform データとして用いた時
struct mat3x4{
vec4 highp m[3]; }; uniform mat3x4 cmWorld;
実例1
![Page 75: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/75.jpg)
• シェーダ内に構造体を作成• 構造体内に配列型のメンバがある• それを uniform データとして用いた時
struct mat3x4{
vec4 highp m[3]; }; uniform mat3x4 cmWorld;
実例1
![Page 76: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/76.jpg)
struct mat3x4{
vec4 highp m[3]; }; uniform mat3x4 cmWorld;
• シェーダ内に構造体を作成• 構造体内に配列型のメンバがある• それを uniform として用いた時
実例1
![Page 77: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/77.jpg)
名前 配列サイズ 名前 配列サイズcmWorld.m[0] 3 cmWorld.m[0] 3
cmWorld.m[1] 2cmWorld.m[2] 1
iOS / Adreno205/ Tegra3端末 Adreno220/ 225/ 320
struct mat3x4{ vec4 highp m[3]; }; uniform mat3x4 cmWorld;
実例1の取得結果
![Page 78: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/78.jpg)
GLES2 の仕様と一致
名前1つに、配列サイズ=3
名前 配列サイズ 名前 配列サイズcmWorld.m[0] 3 cmWorld.m[0] 3
cmWorld.m[1] 2cmWorld.m[2] 1
iOS / Adreno205/ Tegra3端末 Adreno220/ 225/ 320
実例1の取得結果
struct mat3x4{ vec4 highp m[3]; }; uniform mat3x4 cmWorld;
![Page 79: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/79.jpg)
特殊
名前3つに、それぞれにデクリメントされた配列サイズ
特殊
名前 配列サイズ 名前 配列サイズcmWorld.m[0] 3 cmWorld.m[0] 3
cmWorld.m[1] 2cmWorld.m[2] 1
iOS / Adreno205/ Tegra3端末 Adreno220/ 225/ 320
実例1の取得結果
struct mat3x4{ vec4 highp m[3]; }; uniform mat3x4 cmWorld;
![Page 80: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/80.jpg)
名前 配列サイズ 名前 配列サイズcmWorld.m[0] 3 cmWorld.m[0] 3
cmWorld.m[1] 2cmWorld.m[2] 1
iOS / Adreno205/ Tegra3端末 Adreno220/ 225/ 320
配列サイズとは
struct mat3x4{ vec4 highp m[3]; }; uniform mat3x4 cmWorld;
• 取得した配列サイズはいつも– X 変数の宣言と同じ– O シェーダ内に使用している要素だけ
![Page 81: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/81.jpg)
名前 使用中の配列サイズ 名前 使用中の配列サイズcmWorld.m[0] 1~3 cmWorld.m[0] 1~3
cmWorld.m[1] 1~2cmWorld.m[2] 1
iOS / Adreno205/ Tegra3端末 Adreno220/ 225/ 320
配列サイズ → 使用中の配列サイズ
struct mat3x4{ vec4 highp m[3]; }; uniform mat3x4 cmWorld;
配列サイズとは
![Page 82: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/82.jpg)
実例2
• テクスチャサンプラ配列のみ• 構造体と無関係
uniform vec4 vCoef[4]uniform sampler2D asTexStage[16];
![Page 83: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/83.jpg)
名前 使用中の配列サイズ 名前 使用中の配列サイズvCoef[0] 1~4* vCoef[0] 1~4*asTexStage[0] 1~16* asTexStage[0] 1
asTexStage[1] 1…asTexStage[15]** 1
iOS端末/Adreno 205/Tegra 3 Adreno 220/225/320
• テクスチャサンプラ配列のみ• 構造体と無関係
実例2の取得結果
• テクスチャサンプラ配列のみ• 構造体と無関係
uniform vec4 vCoef[4]uniform sampler2D asTexStage[16];
• テクスチャサンプラ配列のみ• 構造体と無関係
![Page 84: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/84.jpg)
名前 使用中の配列サイズ 名前 使用中の配列サイズvCoef[0] 1~4* vCoef[0] 1~4*asTexStage[0] 1~16* asTexStage[0] 1
asTexStage[1] 1…asTexStage[15]** 1
iOS端末/Adreno 205/Tegra 3 Adreno 220/225/320
* 名前1つにつき使用中の配列サイズが一致GLES2 の仕様と一致
実例2の取得結果
• テクスチャサンプラ配列のみ• 構造体と無関係
uniform vec4 vCoef[4]uniform sampler2D asTexStage[16];
![Page 85: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/85.jpg)
名前 使用中の配列サイズ 名前 使用中の配列サイズvCoef[0] 1~4* vCoef[0] 1~4*asTexStage[0] 1~16* asTexStage[0] 1
asTexStage[1] 1…asTexStage[15]** 1
iOS端末/Adreno 205/Tegra 3 Adreno 220/225/320
** 名前の数は実際に使用されている sampler2D 数になり、
全ての配列サイズが1になる
特殊
実例2の取得結果
• テクスチャサンプラ配列のみ• 構造体と無関係
uniform vec4 vCoef[4]uniform sampler2D asTexStage[16];
![Page 86: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/86.jpg)
実例3
uniform vec4 vCoef[4]uniform sampler2D asTexStage[16];uniform int aInteger[16];uniform bool aBool[16];
• 配列を使う• 型と無関係• 構造体と無関係
![Page 87: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/87.jpg)
名前 使用中の配列サイズ 名前 使用中の配列サイズvCoef[0] 1~4* vCoef[0] 4asTexStage[0] 1~16* asTexStage[0] 16aInteger[0] 1~16* aInteger[0] 16aBool[0] 1~16* aBool[0] 16
iOS端末/Adreno 205/Tegra 3 Mali-400 MP
シェーダ内で全ての要素を使用してなくても配列の最大要素数が返ってくる
• 配列を使う• 型と無関係• 構造体と無関係
特殊
実例3の取得結果
uniform vec4 vCoef[4]uniform sampler2D asTexStage[16];uniform int aInteger[16];uniform bool aBool[16];
![Page 88: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/88.jpg)
• Uniform処理に合わせて
– シェーダ内の uniform宣言を変更• 構造体を利用しない• テクスチャサンプラの配列を利用しない
– ランタイムで取得した uniform 情報の違いを考慮
解決方法
![Page 89: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/89.jpg)
• Uniform処理に合わせて
– シェーダ内の uniform宣言を変更• 構造体を利用しない• テクスチャサンプラの配列を利用しない
– ランタイムで取得した uniform 情報の違いを考慮
解決方法
![Page 90: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/90.jpg)
コンテンツ
• 実装– リフレッシュレート– マルチスレッドレンダリング– GPU 毎の Uniforms– フレームバッファ
![Page 91: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/91.jpg)
フレームバッファ
• 概要– フロントバッファのスワップの最適化– レンダターゲットの最適化
![Page 92: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/92.jpg)
スワップの内部動作
1. フロントバッファのカラーを端末の画面に表示
2. EGL の設定によりスワップ後のフロントバッファのカラーの挙動が変化
• 保持する (変わらない)• 保持しない (壊れているか変えられている可能
性あり)
上記の設定はデフォルトが GPU と OS に依存
![Page 93: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/93.jpg)
スワップの内部動作
1. フロントバッファのカラーを端末の画面に表示
2. EGL の設定によりスワップ後のフロントバッファのカラーの挙動が変化
• 保持する (変わらない)• 保持しない (壊れているか変えられている可能
性あり)
上記の設定はデフォルト値がGPU と OS に依存
![Page 94: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/94.jpg)
• カラーバッファを保持しない方が速い– 多くのアプリは画面全体をフレーム毎に描画するの
でカラーバッファを保存しなくても良い
• デフォルト設定が「保持」の GPU を「保持しない」ように変更すれば最適化が測れる
• 概要– 設定のデフォルト値と変更仕方の紹介– パフォーマンスの結果
スワップの内部動作
![Page 95: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/95.jpg)
• カラーバッファを保持しない方が速い– 多くのアプリは画面全体をフレーム毎に描画するの
でカラーバッファを保存しなくても良い
• デフォルト設定が「保持」の GPU を「保持しない」ように変更すれば最適化が図れる
• 概要– 設定のデフォルト値と変更仕方の紹介– パフォーマンスの結果
スワップの内部動作
![Page 96: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/96.jpg)
iOS の場合
• kEAGLDrawablePropertyRetainedBacking• YES = 保持する• NO = 保持しない
• デフォルト値 = NO
![Page 97: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/97.jpg)
Android の場合 (EGL1.4 以上 )• eglSurfaceAttrib( EGL_SWAP_BEHAVIOR, EGL_BUFFER_*** )
– EGL_BUFFER_DESTROYED = 保持しない– EGL_BUFFER_PRESERVED = 保持する
• デフォルト値は GPU 毎に異なる
• EGL_SWAP_BEHAVIOR が設定できないことがある– EGL 1.4 以上が必要
• 公式には NDK r5 以上でサポート
– EGL仕様によると EGL Surface のコンフィギュレーションを作る時にEGL_SWAP_BEHAVIOR_PRESERVED_BIT が必要
![Page 98: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/98.jpg)
• eglSurfaceAttrib( EGL_SWAP_BEHAVIOR, EGL_BUFFER_*** )– EGL_BUFFER_DESTROYED = 保持しない– EGL_BUFFER_PRESERVED = 保持する
• デフォルト値は GPU 毎に異なる
端末名 端末ID GPU EGL_SWAP_BEHAVIORデフォルト値
GALAXY S SC-02B Power VR SGX 540 200MHzAQUOS PHONE SH06-D Power VR SGX 540 384MHzARROWS μ F-07D Adreno 205Xperia SO-02E Adreno 320GALAXY S II WiMAX ISW11SC Mali-400 MPGALAXY S II LTE SC-03D Adreno 220ARROWS Z ISW13F NVIDIA Tegra 3
EGL_BUFFER_DESTROYED
EGL_BUFFER_PRESERVED
Android の場合 (EGL1.4 以上 )
![Page 99: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/99.jpg)
• EGL_SWAP_BEHAVIOR が設定できないことがある– EGL 1.4 以上が必要
• 公式には NDK r5 以上でサポート– OS 2.3 と同時に出た
– EGL仕様によると EGL Surface のコンフィギュレーションに EGL_SWAP_BEHAVIOR_PRESERVED_BIT が必要
• ビットフラッグ設定の意味は– 設定している = EGL_SWAP_BEHAVIOR が変更可能– 設定しない = EGL_SWAP_BEHAVIOR が変更不可能
Android の場合 (EGL1.4 以上 )
![Page 100: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/100.jpg)
• EGL_SWAP_BEHAVIOR が設定できないことがある– EGL 1.4 以上が必要
• 公式には NDK r5 以上でサポート– OS 2.3 と同時に出た
– EGL仕様によると EGL Surface のコンフィギュレーションに EGL_SWAP_BEHAVIOR_PRESERVED_BIT が必要
• ビットフラグ設定の意味は– 設定している = EGL_SWAP_BEHAVIOR が変更可能– 設定しない = EGL_SWAP_BEHAVIOR が変更不可
能
Android の場合 (EGL1.4 以上 )
![Page 101: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/101.jpg)
• PowerVR SGX 540 は「不可能」でも EGL_SWAP_BEHAVIOR の値が変更できる– EGL の仕様の例外
EGL_SWAP_BEHAVIOR_PRESERVED_BIT に対応している EGL Surface コンフィギュレー
ションを eglGetConfigs ()から取得可能
端末名 端末ID GPU EGL_SWAP_BEHAVIOR_PRESERVED_BIT
GALAXY S SC-02B Power VR SGX 540 200MHzAQUOS PHONE SH06-D Power VR SGX 540 384MHzARROWS μ F-07D Adreno 205Xperia SO-02E Adreno 320GALAXY S II WiMAX ISW11SC Mali-400 MPGALAXY S II LTE SC-03D Adreno 220ARROWS Z ISW13F NVIDIA Tegra 3
可能
不可能
Android の場合 (EGL1.4 以上 )
![Page 102: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/102.jpg)
• PowerVR SGX 540 は「不可能」でも EGL_SWAP_BEHAVIOR の値が変更できる– EGL の仕様の例外
EGL_SWAP_BEHAVIOR_PRESERVED_BIT に対応している EGL Surface コンフィギュレー
ションを eglGetConfigs ()から取得可能
端末名 端末ID GPU EGL_SWAP_BEHAVIOR_PRESERVED_BIT
GALAXY S SC-02B Power VR SGX 540 200MHzAQUOS PHONE SH06-D Power VR SGX 540 384MHzARROWS μ F-07D Adreno 205Xperia SO-02E Adreno 320GALAXY S II WiMAX ISW11SC Mali-400 MPGALAXY S II LTE SC-03D Adreno 220ARROWS Z ISW13F NVIDIA Tegra 3
可能
不可能
Android の場合 (EGL1.4 以上 )
![Page 103: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/103.jpg)
Android のパフォーマンス結果
35
38
41
44
Galaxy S (Power VR SGX 540)
EGL_BUFFER_PRESERVEDEGL_BUFFER_DESTROYED
• 効果が見られず
fps
fps
![Page 104: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/104.jpg)
フレームバッファ
• 概要– フロントバッファのスワップの最適化– レンダターゲットの最適化
![Page 105: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/105.jpg)
レンダターゲットの最適化
• 遅い GPU のため– フロントバッファの形式
• RGBA8888 → RGB565
• 解像度を下げる– バックバッファ– フロントバッファ
• 可能な場合のみ。変更出来ない端末もある
![Page 106: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/106.jpg)
レンダターゲットの最適化
• 遅い GPU のため– フロントバッファの形式
• RGBA8888 → RGB565
– 解像度を下げる• バックバッファ• フロントバッファ
– 可能な場合のみ。変更出来ない端末もある
![Page 107: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/107.jpg)
フロントバッファ解像度変更条件
Android の場合
• 変更可能– ただし全てではない– OS のバージョンに依存
• ANativeWindow_setBuffersGeometory()または eglCreateWindowSurface() を利用
![Page 108: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/108.jpg)
フロントバッファ解像度変更条件
iOS の場合
• 変更可能– ただし全てではない– “Retina ディスプレイ”に限られる– 解像度指定はできず Scaling のみ可能
• UIView::contentScaleFactor を利用
![Page 109: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/109.jpg)
バックバッファ解像度
• GPU によって –初期化時にパフォーマンスを計測– 事前に計測した値を使用
• テーブルに保持してある
• 結果を利用してディスプレイ解像度に対してのバックバッファのスケール係数を決定する
![Page 110: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/110.jpg)
最適化手法
![Page 111: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/111.jpg)
検証した GPU• Adreno
– 205, 220, 225, 320• Mali
– 400 MP• PowerVR (SGX)
– 535, 540, 543, 554• Tegra
– Tegra 3
![Page 112: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/112.jpg)
コンテンツ
• 最適化手法– タイルベース GPU 最適化–オブジェクト描画順– テクスチャフェッチ最適化
![Page 113: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/113.jpg)
タイルベース GPU• タイルベースレンダリングを採用した
GPU– PowerVR, Adreno, Mali
• タイルベースレンダリング (TBR)– フレームバッファへのアクセス
• レンダリング中はフレームバッファにアクセスせず GPU 内のタイルバッファにアクセスする
• 各タイルのレンダリング– 開始時 ⇒ GPU のタイルバッファにロード– 終了時 ⇒ GPU のタイルバッファからストア
![Page 114: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/114.jpg)
タイルのロード , ストア
• 通常のレンダリングでは描画開始時のロードは不必要– 一般的にはレンダリング開始直後にすべてク
リア• OpenGL ES + TBR ではデフォルトではロードが
発生• ストア
– レンダリング後のフレームバッファの内容を使用しない場合
• 例) カラーは必要 , デプス , ステンシルは不必要
• ロード , ストアを制御する GL_EXT がある
![Page 115: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/115.jpg)
GL_EXT_discard_framebuffer• 対応 GPU:Mali, PowerVR
– 古いバージョンの Android OS ではサポートされない
• glDiscardFramebufferEXT()–破棄するカラー , デプス , ステンシルを指定
• 破棄された場合 dirty になる
![Page 116: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/116.jpg)
GL_QCOM_tiled_rendering• 対応 GPU: Adreno• StartTilingQCOM()EndTilingQCOM()– 状態を保持するカラー , デプス , ステンシル
を指定• 保持しないものは dirty になる
– StartTilingQCOM(), EndTilingQCOM()は対にして使用する必要がある
![Page 117: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/117.jpg)
最適化方法
• ロードの必要がない場合– PowerVR, Mali
• レンダリング開始時に glClear を使用してクリア– Adreno
• レンダリング開始時に dirty にする– StartTilingQCOM()
• dirty の場合はロードされない
• ストアの必要がない場合– レンダリングの最後にタイルバッファを dirty にす
る• glDiscardFramebufferEXT()EndTilingQCOM()
• dirty の場合はストアされない
![Page 118: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/118.jpg)
コンテンツ
• 最適化手法– タイルベース GPU 最適化–オブジェクト描画順– テクスチャフェッチ最適化
![Page 119: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/119.jpg)
オブジェクト描画順
• ここでのオブジェクトの単位は描画順のソートを行う単位– レンダリングエンジンの実装に依存–本セッションではドローコール単位でソート
![Page 120: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/120.jpg)
不透明オブジェクトパンチスルーオブジェク
トearly-z を考慮し , 手前から順に描画
一般的なケース
半透明オブジェクト奥から順に描画
![Page 121: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/121.jpg)
不透明オブジェクト
• early-z cull 調査– オーバードローテスト
• Z テスト : near • 1ポリゴン 30 fps になる負荷のフラグメントシェーダを使
用• 手前から描画した場合と、奥から描画した場合で比較
![Page 122: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/122.jpg)
不透明オブジェクト
05
101520253035
Adreno Mali PowerVR Tegra
fps 1ポリゴン 6手前から ポリゴン 6奥から ポリゴン
• early-z cull 調査– オーバードローテスト
• Z テスト : near • 1ポリゴン 30 fps になる負荷のフラグメントシェーダを使
用• 手前から描画した場合と、奥から描画した場合で比較
![Page 123: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/123.jpg)
不透明オブジェクト描画順
• Adreno, Mali, Tegra– 手前から順に描画
• オーバードローが発生する可能性がある– オブジェクトが重なっている– オブジェクト内のポリゴンがソートされていない– ポリゴンが交差している
• PowerVR–描画順は考慮しなくてよい
• オーバードローは発生しない– ただし例外あり
» タイル内のポリゴン数が一定を超えるとオーバードローが発生する等
![Page 124: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/124.jpg)
不透明オブジェクト描画順
• Adreno, Mali, Tegra– 手前から順に描画
• オーバードローは発生する– オブジェクト同士が重なっている– オブジェクト内のポリゴンの並びが手前から順になっ
ていない– ポリゴンが交差している
• PowerVR–描画順は考慮しなくてよい
• 基本的にオーバードローは発生しない– タイル内のポリゴン数が一定を超えるとオーバードローが発生するなど、例外あり
![Page 125: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/125.jpg)
パンチスルーオブジェクト• early-z cull 調査
– オーバードローテスト• 不透明オブジェクトのテストと同じ条件• 不透明オブジェクトテスト時のシェーダに discard命令を追加
– 破棄されるピクセルは無し
![Page 126: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/126.jpg)
パンチスルーオブジェクト
05
101520253035
Adreno Mali PowerVR Tegra
fps 1ポリゴン 6手前から ポリゴン 6奥から ポリゴン
• early-z cull 調査– オーバードローテスト
• 不透明オブジェクトのテストと同じ条件• 不透明オブジェクトテスト時のシェーダに discard命令を追加
– 破棄されるピクセルは無し
![Page 127: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/127.jpg)
不透明&パンチスルー• early-z cull 調査
– オーバードローテスト• 不透明オブジェクト , パンチスルーオブジェクトを交互に6ポリゴ
ン描画• パンチスルーオブジェクトから描画した場合と、不透明オブジェク
トから描画した場合を比較
![Page 128: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/128.jpg)
不透明&パンチスルー
05
101520253035
Adreno Mali PowerVR Tegra
fps 奥から順 (手前から順 不透明から) (手前から順 パンチスルーから)
• early-z cull 調査– オーバードローテスト
• 不透明オブジェクト , パンチスルーオブジェクトを交互に6ポリゴン描画
• パンチスルーオブジェクトから描画した場合と、不透明オブジェクトから描画した場合を比較
![Page 129: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/129.jpg)
パンチスルーオブジェクト描画順• Mali
– 不透明オブジェクトの後に描画• 描画順は考慮しない
• Adreno, Tegra– 不透明オブジェクトより先に描画
• 不透明はパンチスルーに陰面消去された場合オーバードローが発生しないため
• 常にオーバードローが発生する– 描画順を考慮する必要はない
![Page 130: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/130.jpg)
パンチスルーオブジェクト描画順• PowerVR
– 不透明とパンチスルーオブジェクトを分けて描画
• 不透明オブジェクトのみの場合はオーバードローが発生しないため
• 不透明オブジェクトの前後どちらで描画するのかは不透明オブジェクトとのオーバードロー次第
• 手前から描画
![Page 131: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/131.jpg)
Adreno, Tegra
オブジェクト描画順まとめ
Maliパンチスルー手前から順に描画
PowerVR
半透明奥から順に描画
不透明描画順は考慮しない
パンチスルー手前から順に描画
パンチスルー描画順は考慮しない
半透明奥から順に描画
不透明手前から順に描画
パンチスルー描画順は考慮しない
半透明奥から順に描画
不透明手前から順に描画
![Page 132: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/132.jpg)
コンテンツ
• 最適化手法– タイルベース GPU 最適化–オブジェクト描画順– テクスチャフェッチ最適化
![Page 133: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/133.jpg)
PowerVR テクスチャプリフェッチ• プリフェッチ条件
– UV を varying から値を変えずに使用
– varying のスィズルを x から順に使用
• PowerVR 以外でこのフェッチの有効性をポストプロセスで調査– ¼ ダウンサンプリング– ガウスフィルタ
uniform sampler2D s0;varying vec2 uv0;varying vec4 uv1;
texture2D(s0, uv0); // ○
vec2 uv2 = uv0;uv2 += vec2(0.1, 0.2);texture2D(s0, uv2); // ×
texture2D(s0, uv1.xy); // ○
texture2D(s0, uv1.zw); // ×
![Page 134: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/134.jpg)
PowerVR テクスチャプリフェッチ• プリフェッチ条件
– UV を varying から値を変えずに使用
– varying のスィズルを x から順に使用
• PowerVR 以外でこのフェッチの有効性をポストプロセスで調査– ¼ ダウンサンプリング– ガウスフィルタ
uniform sampler2D s0;varying vec2 uv0;varying vec4 uv1;
texture2D(s0, uv0); // ○
vec2 uv2 = uv0;uv2 += vec2(0.1, 0.2);texture2D(s0, uv2); // ×
texture2D(s0, uv1.xy); // ○
texture2D(s0, uv1.zw); // ×
![Page 135: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/135.jpg)
PowerVR テクスチャプリフェッチ• プリフェッチ条件
– UV を varying から値を変えずに使用
– varying のスィズルを x から順に使用
• PowerVR 以外でこのフェッチの有効性をポストプロセスで調査– ¼ ダウンサンプリング– ガウスフィルタ
uniform sampler2D s0;varying vec2 uv0;varying vec4 uv1;
texture2D(s0, uv0); // ○
vec2 uv2 = uv0;uv2 += vec2(0.1, 0.2);texture2D(s0, uv2); // ×
texture2D(s0, uv1.xy); // ○
texture2D(s0, uv1.zw); // ×
![Page 136: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/136.jpg)
PowerVR テクスチャプリフェッチ• プリフェッチ条件
– UV を varying から値を変えずに使用
– varying のスィズルを x から順に使用
• PowerVR 以外でこのフェッチの性能をポストプロセスで調査– ¼ ダウンサンプリング– ガウスフィルタ
uniform sampler2D s0;varying vec2 uv0;varying vec4 uv1;
texture2D(s0, uv0); // ○
vec2 uv2 = uv0;uv2 += vec2(0.1, 0.2);texture2D(s0, uv2); // ×
texture2D(s0, uv1.xy); // ○
texture2D(s0, uv1.zw); // ×
![Page 137: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/137.jpg)
テクスチャフェッチ比較対象
• バーテックスシェーダ UV生成– varying の値を変えずに使
用– varying 数をできるだけ削減
uniform sampler2D s0;varying vec4 uv0;varying vec4 uv1;
texture2D(s0, uv0.xy);texture2D(s0, uv0.zw);texture2D(s0, uv1.xy);texture2D(s0, uv1.zw);
uniform sampler2D s0;varying vec2 uv;uniform vec2 ofs0;uniform vec2 ofs1;Uniform vec2 ofs2;
texture2D(s0, uv+ofs0);texture2D(s0, uv+ofs1);texture2D(s0, uv+ofs2);
• フラグメントシェーダ UV生成– varying は1つ
![Page 138: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/138.jpg)
テクスチャフェッチ検証環境
• カラーフォーマット: ARGB8888• Precision
– バーテックスシェーダ: highp– フラグメントシェーダ: mediump
• パフォーマンス計測方法– フレームレートから計測– 60fps 以下にするため解像度を調整
![Page 139: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/139.jpg)
1/4 ダウンサンプリング• テクスチャフェッチ4回
![Page 140: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/140.jpg)
1/4 ダウンサンプリング結果
0
0.2
0.4
0.6
0.8
1
1.2
205 220 225 320 400 MP T604 540
PowerVRプリフェッチ UVバーテックス 生成 UVフラグメント 生成↑Fast
PowerVR
MaliAdreno Tegra 3
![Page 141: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/141.jpg)
ガウスフィルタ• テクスチャフェッチ7回
![Page 142: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/142.jpg)
ガウスフィルタ結果
0
0.2
0.4
0.6
0.8
1
1.2
205 220 225 320 400 MP T604 540
PowerVRプリフェッチ UVバーテックス 生成 UVフラグメント 生成
PowerVR
MaliAdreno Tegra 3
↑Fast
![Page 143: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/143.jpg)
テクスチャフェッチ結果
• Mali-400 MP– PowerVR プリフェッチが有効
• UV精度も向上する
• Adreno 200 シリーズ , Tegra 3– PowerVR プリフェッチの有効性は見られない– varying 数増加によるパフォーマンス低下は確認で
きず• フラグメントシェーダ負荷の少ないバーテックス UV生成推奨
– PowerVR のプリフェッチを使用して問題ない
• Adreno 320, Mali-T604– varying 数削減が効果的
![Page 144: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/144.jpg)
まとめ
• 性能差が大幅に異なる GPU に対応が必要• OS, GPU, 端末の違いによるさまざまな
問題が発生– 特に Android では仕様書などのドキュメン
トが信用できないことが多い• 各 GPU の最適化手法の調査 , 検証が必要
![Page 145: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/145.jpg)
謝辞
• (株)トライエース研究開発部–五反田 義治
![Page 146: モバイル GPU でのハイエンド レンダリングエンジン開発事例](https://reader030.fdocument.pub/reader030/viewer/2022033014/56813316550346895d99d77a/html5/thumbnails/146.jpg)
ご質問は?
http://research.tri-ace.com