Principio de código de marco de truncamiento de Android 11
/Framework/Basics/Core/java/android/View/SurfaceControl.java
1. Obtenga un objeto de tipo IBinder, displayToken.
2. Ajusta la dirección. Normalmente, la rotación al llamar es 0. Si pasa 1 o 3, se restablecerá la orientación de la pantalla.
3. Capture todas las superficies de la pantalla y devuelva un GraphicBuffer lleno de contenido.
4. Pase el objeto GraphicBuffer creado al mapa de bits compatible con el hardware y utilice el búfer de gráficos para devolver el objeto de mapa de bits.
GetPhysicalDisplayIds() devuelve una matriz larga, donde PhysicalDisplayIds[0] es el dispositivo de visualización principal y otras ubicaciones en la matriz pueden ser otros dispositivos, como pantallas de proyección.
1. A través de una serie de llamadas, irá al servicio compositor::obtener servicio compositor () de SurfaceComposerClient.cpp
Obtenga el objeto ComposerService, donde Composervice está en modo singleton y ¿ComposerSerivce hereda Singleton de tipo ComposerService? , el tipo en singleton es ComposerService.
2. Devuelve un objeto ComposerService. Si se ha creado ComposerService, significa que se ha vinculado y luego regresa directamente. Si aún no se ha creado, creará y ejecutará el método connectLocked.
3. En el proceso de connectLocked, primero puede ver que el servicio se busca por el nombre de SurfaceFlinger. Este es un bucle infinito. El nombre se busca continuamente en ServiceMananger para obtener el servicio correspondiente.
GetService es una función de plantilla que busca el servicio correspondiente a través del nombre del parámetro y convierte el IBinder del servicio en un objeto de interfaz para salida.
3.1 Crear un monitor de muerte y vincularlo.
3.2 Devuelve el objeto ISurfaceComposer en el singleton de ComposerService. Sabemos que SurfaceFlinger hereda BnSurfaceFlinger y BNInterface
Podemos saber que getPhysicalDisplayToken es el método ejecutado en SurfaceFlinger. /frameworks/native/services/surface flinger/surface flinger.CPP
se encuentra en Surface flinger.h/frameworks/native/services/surface flinger/surface flinger.h.
MPhysicalDisplayTokens es un tipo de mapa, DisplayId corresponde a una determinada pantalla, sp
De esta forma, el proceso de control de superficie. getInternalDisplayToken () está completo y es obvio que el tipo DisplayToken devuelto por IBinder es el servidor SurfaceFlinger.
El propósito de este método es capturar todas las superficies en la pantalla y devolver un GraphicBuffer lleno de estas superficies.
1 y Display son los agentes de SurfaceFlinger y el proceso de captura de pantalla más importante se realiza dentro de ellos.
2. Capture el mapa de bits en la pantalla, generalmente pase el nuevo Rect, es decir, sin recortar.
3. El siguiente paso es ancho, alto y dirección, userIdentityTransform es falso.
NativeScreenshot se llama al control de superficie _ view _ de Android a través de CPP. En este método, puede establecer setpriority, la prioridad de la aplicación de captura de pantalla, y dar prioridad a la operación de captura de pantalla.
Puedes ver un punto clave
1. Asignación de objetos ISurfaceComposer, también presentado anteriormente.
2. Llame al método captureScreen de ISurfaceComposer. Este método tiene mucho contenido.
La oración clave es status_t result = remote()-->; transact(BnSurfaceCompser::_ CAPTURE_SCREEN, data, & amp respuesta
Se llamará a serveronTransact.
Encontrado CAPTURE_SCREEN.
Debido a que el servidor es SurfaceFlinger, se ejecutará el método captureScreen en SurfaceFlinger.
El diagrama de flujo es el siguiente
1. El objeto de visualización del tipo DisplayDevice se asigna mediante getdisplaydevicelocked (token de visualización).
2. Construya un objeto renderArea de tipo DisplayrenderArea.
3. Ejecute el método traverseLayersInDisplay en la función de enlace, aquí está sf, Display, std::placeholder:_1 es el marcador de posición. El resultado pasó a llamarse método traverselayers.
El contenido principal de este método es crear un GraphicBuffer a través de getfactory(). crear buffer gráfico.
En Surfaceflingerdefaultfactory. CPP, puede ver que new tiene un objeto GraphicBuffer y requestorName es una captura de pantalla.
Continúe utilizando el método captureScreenCommon.
1. Obtenga el UID del destinatario, que es el UID de nuestra aplicación de aplicación del sistema. Solo las aplicaciones del sistema pueden llamar a la interfaz de captura de pantalla.
2. El valor de forSystem es, por supuesto, verdadero, es decir, aplicación del sistema.
3. La función de programación llama las tareas realizadas por el hilo vinculante de la aplicación de procesamiento al hilo principal para su ejecución. Se puede ver claramente en el systrace que la captura de pantalla se tomará después de la síntesis SF dentro de un ciclo vsync.
Cada capa se puede obtener en el método captureScreenImplLocked, de modo que la capa se pueda procesar en esta área, por ejemplo, qué contenido no necesita ser interceptado.
A continuación, el método renderScreenImplLocked.
Este método tiene mucho contenido. La frase clave es
GLESRenderEngine hereda RenderEngine.
GetRenderEngine(). drawLayers es el llamado método drawLayers de Glesrenderingene. Su trabajo principal es
1. Representar la capa para una visualización específica a través de síntesis de GPU.
2. Este método será llamado por cada contenido de visualización que requiera renderizado por GPU.
3. Visualización, establezca el rango de visualización antes de dibujar la capa.
4. Capas, capas dibujadas en el monitor, orden del eje z.
5. Buffer: Rellena el buffer con el contenido de la capa.
6. Si el búfer está disponible, userFrameBufferCache es verdadero. Si el búfer no está implementado, el valor es inútil.
7.bufferFence, marca de cerca, verifica si está listo, puedes dibujarlo cuando estés listo.
Llene el buffer y luego el buffer tendrá el contenido de la capa en la pantalla.
Volver a SurfaceControl.java.
FinalScreenshotGraphicBuffer buffer = captureToBuffer(display token, sourceCrop, width, height, userIdentityTransform, rotation);
El Buffer ahora tiene un valor y se ha llenado. El siguiente paso es convertir el búfer en un mapa de bits.
Llame a bitmap . wrappardwarebuffer(buffer . getgraphicbuffer(), buffer . getcolorspace()); podemos obtener el mapa de bits que necesitamos y el proceso de captura de pantalla finaliza aquí.