Android utilise l'API OpenGL ES (GLES) pour le rendu des éléments graphiques. Pour créer des contextes GLES et fournir un système de fenêtrage pour les rendus GLES, Android utilise la bibliothèque EGL. Les appels GLES génèrent des polygones texturés, tandis que les appels EGL placent les rendus sur les écrans.
Avant de dessiner avec GLES, vous devez créer un contexte GL. Dans EGL, cela signifie créer un EGLContext et un EGLSurface. Les opérations GLES s'appliquent au contexte actuel, auquel on accède via un stockage thread-local plutôt que transmis en tant qu'argument. Le code de rendu doit s'exécuter sur un thread GLES actuel, et non sur le thread UI.
EGLSurfaces
EGLSurface peut être un tampon hors écran alloué par EGL, appelé pbuffer, ou une fenêtre allouée par le système d'exploitation. L'appel de la fonction eglCreateWindowSurface()
crée des surfaces de fenêtre EGL.
eglCreateWindowSurface()
utilise un objet de fenêtre comme argument, qui est une surface sur Android. Une surface est le côté producteur d'une BufferQueue. Les consommateurs, qui sont SurfaceView, SurfaceTexture, TextureView ou ImageReader, créent des surfaces.
Lorsque vous appelez eglCreateWindowSurface()
, EGL crée un objet EGLSurface et le connecte à l'interface du producteur de la file d'attente de tampons de l'objet de fenêtre. À partir de ce moment-là, l'affichage sur cette EGLSurface entraîne la suppression d'un tampon, son affichage et son mise en file d'attente pour être utilisé par le consommateur.
EGL ne fournit pas d'appels de verrouillage/déverrouillage. Exécutez des commandes de dessin, puis appelez eglSwapBuffers()
pour envoyer le frame actuel. Le nom de la méthode vient du remplacement traditionnel des tampons avant et arrière, mais l'implémentation réelle peut être différente.
Un seul EGLSurface peut être associé à une surface à la fois (vous ne pouvez avoir qu'un seul producteur connecté à une BufferQueue), mais si vous supprimez l'EGLSurface, il se déconnecte de la BufferQueue et permet à un autre élément de se connecter.
Un thread donné peut basculer entre plusieurs EGLSurfaces en modifiant l'élément actuel. Une EGLSurface ne doit être actuelle que sur un seul thread à la fois.
EGL n'est pas un autre aspect d'une surface (comme SurfaceHolder). EGLSurface est un concept associé, mais indépendant. Vous pouvez dessiner sur une EGLSurface qui n'est pas prise en charge par une surface, et vous pouvez utiliser une surface sans EGL. EGLSurface ne fournit à GLES qu'un espace de dessin.
Reportez-vous au document de définition de la compatibilité Android pour connaître les exigences OpenGL ES et EGL.
ANativeWindow
La classe de surface publique est implémentée dans le langage de programmation Java. L'équivalent en C/C++ est la classe ANativeWindow, semi-exposée par le NDK Android. Vous pouvez obtenir l'ANativeWindow à partir d'une surface avec l'appel ANativeWindow_fromSurface()
. Tout comme son cousin en langage Java, vous pouvez le verrouiller, l'afficher dans un logiciel, le déverrouiller et le publier. Le type de fenêtre native de base est le côté producteur d'une BufferQueue.
Pour créer une surface de fenêtre EGL à partir de code natif, transmettez une instance de EGLNativeWindowType à eglCreateWindowSurface()
. EGLNativeWindowType est un synonyme d'ANativeWindow. Vous pouvez donc caster l'un dans l'autre.