Saltar al contenido principal

Nuevas APIs para plugins de Android que renderizan en un Surface

Añade una nueva API, SurfaceProducer, a la API de embedding de Android, la cual maneja de forma opaca la creación y gestión de un `Surface` para plugins. Para Impeller, se recomienda el uso de esta API.

Resumen

#

El embedder de Android para Flutter presenta una nueva API, SurfaceProducer, la cual permite a los plugins renderizar en un Surface sin necesidad de gestionar cuál es la implementación subyacente. Los plugins que utilizan la API anterior createSurfaceTexture seguirán funcionando con Impeller después del próximo lanzamiento estable, pero se recomienda que migren a la nueva API.

Contexto

#

Un SurfaceTexture de Android es una implementación de soporte para un Surface que utiliza una textura OpenGLES como almacenamiento de respaldo.

Por ejemplo, un plugin podría mostrar fotogramas de un plugin de cámara:

Diagrama de flujo

En las versiones más recientes de la API de Android (>= 29), Android introdujo un HardwareBuffer independiente del backend, lo cual coincide con la versión mínima en la que Flutter intentará utilizar el renderizador Vulkan. La API de embedding de Android necesitaba actualizarse para soportar una API de creación de Surface más genérica que no dependa de OpenGLES.

Guía de migración

#

Si estás utilizando la API anterior createSurfaceTexture, deberías migrar a la nueva API createSurfaceProducer. La nueva API es más flexible y permite al motor de Flutter elegir de forma opaca la mejor implementación para la plataforma y el nivel de API actuales.

  1. En lugar de crear un SurfaceTextureEntry, crea un SurfaceProducer:

    java
    TextureRegistry.SurfaceTextureEntry entry = textureRegistry.createSurfaceTexture();
    TextureRegistry.SurfaceProducer producer = textureRegistry.createSurfaceProducer();
    
  2. En lugar de crear un new Surface(...), llama a getSurface() en el SurfaceProducer:

    java
    Surface surface = new Surface(entry.surfaceTexture());
    Surface surface = producer.getSurface();
    

Con el fin de conservar memoria cuando la aplicación se suspende en segundo plano, Android y Flutter pueden destruir un surface cuando ya no sea visible. Para asegurar que el surface se vuelva a crear cuando se reanude la aplicación, deberías usar el método setCallback proporcionado para escuchar los eventos del ciclo de vida del surface:

java
surfaceProducer.setCallback(
   new TextureRegistry.SurfaceProducer.Callback() {
      @Override
      public void onSurfaceAvailable() {
         // Do surface initialization here, and draw the current frame.
      }

      @Override
      public void onSurfaceDestroyed() {
         // Do surface cleanup here, and stop drawing frames.
      }
   }
);

Un ejemplo completo del uso de esta nueva API se puede encontrar en el PR 6989 para el plugin video_player_android.

Nota sobre las vistas previas de la cámara

#

Si tu plugin implementa una vista previa de la cámara, tu migración también podría requerir corregir la rotación de esa vista previa. Esto se debe a que los Surfaces producidos por el SurfaceProducer podrían no contener la información de transformación que las bibliotecas de Android necesitan para rotar la vista previa de forma automática y correcta.

Para corregir la rotación, necesitas rotar la vista previa con respecto a la orientación del sensor de la cámara y la orientación del dispositivo según la ecuación:

rotation = (sensorOrientationDegrees - deviceOrientationDegrees * sign + 360) % 360

donde deviceOrientationDegrees son grados en sentido contrario a las agujas del reloj y sign es 1 para cámaras frontales y -1 para cámaras traseras.

Para calcular esta rotación,

Para aplicar esta rotación, puedes utilizar un Widget RotatedBox.

Para obtener más información sobre este cálculo, consulta la documentación de cálculo de orientación de Android. Para ver un ejemplo completo de cómo realizar esta corrección, consulta este PR de camera_android_camerax.

Timeline

#

Llegó en la versión: 3.22

En la versión estable: 3.24

En la próxima versión estable, 3.27, onSurfaceCreated está en desuso y se añaden onSurfaceAvailable y handlesCropAndRotation.

Referencias

#

Documentación de la API:

Issues relevantes:

PRs relevantes:

  • PR 51061, donde probamos la nueva API en las pruebas del motor.
  • PR 6456, donde migramos el plugin video_player para usar la nueva API.
  • PR 6461, donde migramos el plugin camera_android para usar la nueva API.
  • PR 6989, donde añadimos un ejemplo completo del uso de la nueva API en el plugin video_player_android.