Lorsque j'exécute mon application sous iOS 10 à l'aide de xcode 8, le message suivant s'affiche dans la console de débogage et, en cas de gel de l'interface utilisateur, quelqu'un peut-il savoir pourquoi
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
réponse
Une des situations où vous pouvez obtenir cet avertissement dans Xcode est lorsque vous utilisez une application qui utilise des shaders tels que l'application Maps avec un MKMapView
. Vous constaterez que la vue Carte fonctionne comme prévu sans cet avertissement sur un périphérique réel doté d'un système d'exploitation matériel/natif réel.
Dans la sim, le SolidRibbonShader
fragment shader n'est pas en mesure de lire le résultat du v_gradient
vertex shader probablement parce qu'il est en version bêta ou il peut y avoir une incompatibilité entre la version de Xcode et la version de SIM. Cependant, les shaders sont reconnus sur un périphérique réel.
Explication
Ces shaders appartiennent à = pipeline de rendu OpenGL. Le pipeline de rendu est la séquence d'étapes qu'OpenGL effectue lors du rendu des objets.
Le pipeline de rendu est responsable de l'application de la texture, de la conversion des sommets au système de coordonnées approprié, de l'affichage du caractère à l'écran, etc.
Il y a six étapes dans ce pipeline.
Enfin, une image apparaît sur l'écran de votre appareil. Ces six étapes sont appelées OpenGL Rendering Pipeline et toutes les données utilisées pour le rendu doivent la traverser.
Qu'est-ce qu'un shader?
Un shader est un petit programme que vous avez développé et qui réside dans le GPU. Un shader est écrit dans un langage graphique spécial appelé GLGL (OpenGL Shading Language).
Un shader remplace deux étapes importantes dans le pipeline de rendu OpenGL: Traitement par sommet et Traitement par fragment. Il y a un shader pour chacune de ces deux étapes.
Le but ultime de Vertex Shader
Est de fournir la transformation finale des sommets du maillage au pipeline de rendu. Le but de Fragment shader
Est de fournir des données de coloration et de texture à chaque pixel du en-tête du tampon de mémoire.
Vertex shaders
Transforme les sommets d'un triangle d'un système de coordonnées local à la position d'écran. Fragment shaders
Calcule la couleur d'un pixel dans un triangle tramé à l'écran.
Compilation et liaison de vitesse des objets Shader séparés
De nombreuses applications OpenGL ES utilisent plusieurs vertex et fragment, et il est souvent utile de réutiliser le même fragment shader avec différents vertex shaders ou vice versa. Étant donné que la spécification OpenGL ES principale requiert l’association d’un shader vertex et fragment à un seul programme shader, le mélange et la mise en correspondance des shaders génèrent un grand nombre de programmes, ce qui augmente la total shader compile et temps de lien lorsque vous initialisez votre application.
Mise à jour: le problème semble avoir disparu maintenant sur Xcode9/iOS11.
Tout d’abord, le problème de gel ne se produit que lorsqu’il est exécuté à partir de Xcode 8 et uniquement sur iOS 1 (actuellement 10.0.2), qu’il soit en mode débogage ou publication. MKMapView semble cependant très bien lorsque l'application est distribuée via l'App Store ou des systèmes de distribution ad hoc tiers. Les avertissements que vous voyez peuvent ou peuvent ne pas être liés au problème, je ne sais pas.
Ce que j’ai trouvé, c’est que le code incriminé se trouve dans le destructeur de MKMapView, et que vous fassiez ce que vous faites avec l’objet de vue Carte ou comment vous le configurez, c’est-à-dire que vous appelez
[MKMapView new];
n'importe où dans votre code va geler l'application. Le fil principal est suspendu à un sémaphore et on ne sait pas pourquoi.
Une des choses que j'ai essayée était de détruire l'objet de vue cartographique dans un fil séparé, mais cela n'a pas aidé. Finalement, j'ai décidé de conserver mes objets de carte au moins dans les versions DEBUG.
NOTE : il s’agit d’une solution de contournement vraiment rapide, mais au moins elle vous aidera à déboguer votre application sans la geler. Si vous conservez ces objets, votre utilisation de la mémoire augmentera d'environ 45 à 50 Mo chaque fois que vous créez un contrôleur de vue avec une carte.
Donc, disons que si vous avez une propriété mapView
, vous pouvez le faire dans le dealloc de votre contrôleur de vue:
- (void)dealloc
{
#if DEBUG
// Xcode8/iOS10 MKMapView bug workaround
static NSMutableArray* unusedObjects;
if (!unusedObjects)
unusedObjects = [NSMutableArray new];
[unusedObjects addObject:_mapView];
#endif
}