Xcode 8を使用してiOS 10でアプリを実行すると、デバッグコンソールで次のメッセージが表示されます。
ERROR
/BuildRoot/Library/Caches/com.Apple.xbs/Sources/VectorKit/VectorKit-1228.30.7.17.9/GeoGL/GeoGL/GLCoreContext.cpp
1763: InfoLog SolidRibbonShader: ERROR
/BuildRoot/Library/Caches/com.Apple.xbs/Sources/VectorKit/VectorKit-1228.30.7.17.9/GeoGL/GeoGL/GLCoreContext.cpp
1764: WARNING: Output of vertex shader 'v_gradient' not read by
fragment shader
回答
Xcodeでこの警告が表示される状況の1つは、Maps app with MKMapView
などのシェーダーを使用するアプリを使用している場合です。実際のハードウェア/ネイティブOSを搭載した実際のデバイスでは、マップビューが警告なしで期待どおりに動作することがわかります。
Simでは、SolidRibbonShader
fragment shaderはv_gradient
vertex shaderの出力を読み取ることができません。おそらくベータ版であるか、 XcodeバージョンとSIMバージョン間の非互換性。ただし、シェーダーは実際のデバイスで認識されます。
説明
これらのシェーダーはOpenGL Rendering Pipelineに属します。レンダリングパイプラインは、オブジェクトをレンダリングするときにOpenGLが実行する一連のステップです。
レンダリングパイプラインは、テクスチャの適用、頂点の正しい座標系への変換、画面上のキャラクターの表示などの処理を行います。
このパイプラインには6つのステージがあります。
最後に、デバイスの画面に画像が表示されます。これらの6つの段階はOpenGLレンダリングパイプラインと呼ばれ、レンダリングに使用されるすべてのデータはそれを通過する必要があります。
シェーダーとは?
シェーダーは、GPUに常駐する、ユーザーが開発した小さなプログラムです。シェーダーは、OpenGL Shading Language(GLSL)と呼ばれる特別なグラフィック言語で書かれています。
シェーダーは、OpenGLレンダリングパイプラインの2つの重要な段階、つまり頂点ごとの処理および断片ごとの処理段階の代わりになります。これら2つのステージのそれぞれに1つのシェーダーがあります。
Vertex Shader
の最終目標は、メッシュの頂点の最終的な変換をレンダリングパイプラインに提供することです。 Fragment shader
の目的は、フレームバッファに向かう各ピクセルにカラーリングとテクスチャデータを提供することです。
Vertex shaders
は、三角形の頂点をローカルモデルの座標系から画面の位置に変換します。 Fragment shaders
は、画面にラスタライズされた三角形内のピクセルの色を計算します。
個別のシェーダーオブジェクトはコンパイルとリンクを高速化します
多くのOpenGL ESアプリは複数のvertexおよびfragmentシェーダーを使用し、同じfragment shaderを異なるvertexで再利用すると便利なことがよくありますシェーダーまたはその逆。コアOpenGL ES仕様ではvertexおよびfragmentシェーダーを単一のシェーダープログラムでリンクする必要があるため、シェーダーを混在させて一致させると多数のプログラムが作成され、アプリの初期化時のシェーダーのコンパイルとリンクの合計時間。
更新:この問題はXcode9/iOS11で解消されたようです。
まず、フリーズの問題は、デバッグモードでもリリースモードでも、Xcode 8からiOS 1(現在10.0.2)でのみ実行される場合に発生します。ただし、アプリがApp Storeまたはサードパーティのアドホック配信システムを介して配信される場合、MKMapViewは正常に見えます。表示されている警告は、問題に関連している場合と関連していない場合がありますが、わかりません。
私が見つけたのは、問題のコードはMKMapViewのデストラクタにあり、マップビューオブジェクトで何をするか、それをどのように構成するか、つまり単に呼び出すだけではありません
[MKMapView new];
コードのどこでもアプリがフリーズします。メインスレッドはセマフォでハングし、その理由は明らかではありません。
私が試したことの1つは、別のスレッドでマップビューオブジェクトを破棄することでしたが、それは役に立ちませんでした。最終的に、少なくともDEBUGビルドでマップオブジェクトを保持することにしました。
[〜#〜] note [〜#〜]:これは本当にsh * ttyの回避策ですが、少なくともフリーズせずにアプリをデバッグするのに役立ちます。これらのオブジェクトを保持すると、マップを使用してView Controllerを作成するたびに、メモリ使用量が約45〜50MB増加します。
したがって、プロパティmapView
がある場合、View Controllerのdeallocでこれを行うことができます。
- (void)dealloc
{
#if DEBUG
// Xcode8/iOS10 MKMapView bug workaround
static NSMutableArray* unusedObjects;
if (!unusedObjects)
unusedObjects = [NSMutableArray new];
[unusedObjects addObject:_mapView];
#endif
}