Principio 11 del código del marco de captura de pantalla de Android
/frame/base/core. El principio del código de /java/android/view/SurfaceControl.screenshot es así. java
1. Obtenga displayToken, que es un objeto de tipo IBinder.
2 Ajuste la dirección generalmente, la rotación pasada es 0. Si se pasa 1 o 3. se repetirá. Si se pasa 1 o 3, se restablecerá la orientación horizontal y vertical de la pantalla.
3. Capture todas las superficies en la pantalla y devuelva un GraphicBuffer lleno con el contenido de estas superficies
4. Pase el objeto GraphicBuffer creado al hardware para admitir el uso de búferes de gráficos en la figura y devuelve un objeto de mapa de bits
getPhysicalDisplayIds() devuelve una matriz de tipo largo, PhysicalDisplayIds[0] es el dispositivo de visualización principal y otras posiciones en la matriz pueden ser pantallas de proyección y otros dispositivos.
1. A través de una serie de llamadas, ingresará SurfaceComposerClient.cpp ComposerService::getComposerService () aquí
Obtenga el objeto ComposerService Composervice es un ComposerSerivce singleton heredado de Singleton. el tipo es ComposerService? El TIPO en el singleton es ComposerService.
2. Devuelve el objeto ComposerService. Si ComposerService ha sido creado, es decir, está vinculado, se devolverá directamente. Si no se crea, creará y ejecutará el método connectLocked.
3. Durante el proceso connectLocked, primero puede verificar el nombre de SurfaceFlinger para encontrar el servicio. Cuando hay un bucle infinito, puede buscar continuamente por nombre en ServiceMananger para obtener el servicio correspondiente.
getService es una función de plantilla que encuentra el servicio correspondiente a través del nombre del parámetro y convierte el servicio IBinder en un objeto de interfaz para salida
3.1 Cree un detector de bucle infinito y vincúlelo p >
3.2 Devuelve el objeto ISurfaceComposer del singleton ComposerService. Sabemos que SurfaceFlinger hereda de BnSurfaceFlinger y BnSurfaceFlinger hereda de BnInterfacelt;ISurfaceComposergt;. Esto significa que se devolverá el objeto SurfaceFlinger.
Sabemos que getPhysicalDisplayToken es el método implementado en SurfaceFlinger.
/frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
En SurfaceFlinger.h /frameworks/native/services/surfaceflinger/SurfaceFlinger.h
mPhysicalDisplayTokens es un tipo de mapeo, DisplayId corresponde Una pantalla, splt;IBindergt; es el objeto IBinder de SurfaceFlinger correspondiente a la pantalla. Busque IBinder a través de mPhysicalDisplayTokends.find(displayId).
Por lo tanto, una vez que se completa el procedimiento SurfaceControl.getInternalDisplayToken(), es obvio que el tipo IBinder DisplayToken devuelto es el servidor SurfaceFlinger.
El propósito de este método es capturar todas las superficies en la pantalla y devolver un GraphicBuffer lleno con el contenido de estas superficies. 1. Display es el proxy de SurfaceFlinger. El proceso de captura de pantalla más importante está en Ya está. internamente.
2. Capture el mapa de bits en la pantalla, generalmente pasado en nuevo Rect, es decir, no se realiza ningún recorte.
3. Lo siguiente es el ancho, alto, dirección y userIdentityTransform. FALSO.
nativeScreenshot llama a android _view_SurfaceControl.cpp a través de JNI. En este método, puede configurar setpripority, que es la prioridad de la aplicación de captura de pantalla, y dar prioridad a la operación de captura de pantalla.
Puedes ver un buffer clave splt;GraphicBuffer>en el que se rellenará la superficie. ScreenshotClient.capture llamará a SurfaceComposerClient.cpp.
Capturar en cpp
1. Asignación de objetos ISurfaceComposer, este proceso también se presentó anteriormente
2. Llame al método captureScreen de ISurfaceComposer, que tiene mucho contenido,
La frase clave es Status_t result= remoto()-gt; transact(BnSurfaceCompser::_CAPTURE_SCREEN, data, & Answer
llamará a la búsqueda
en el lado del servidor; onTransact CAPTURE_SCREEN
Debido a que el servidor es SurfaceFlinger, ejecutará el método captureScreen en SurfaceFlinger
El diagrama de flujo es el siguiente
1. El objeto de visualización de tipo DisplayDevice pasa getDisplayDeviceLocked( displayToken ) realiza el bloqueo de asignación,
2. Construya un objeto de tipo DisplayRenderArea renderArea
3. Ejecute el método traverseLayersInDisplay en la función de enlace, que es sf, display, std ::. Marcador de posición: _1 es un marcador de posición. Se cambió el nombre del resultado a método de capas transversales.
El contenido principal de este método es crear un GraphicBuffer a través de getFactory().createGraphicBuffer
En SurfaceFlingerDefaultFactory.cpp, puede ver un nuevo objeto GraphicBuffer y el nombre del solicitante es una captura de pantalla.
Continúe mirando el método captureScreenCommon
1. Obtenga el UID del destinatario, que es el UID de nuestra aplicación del sistema. Solo las aplicaciones del sistema pueden llamar a la interfaz de captura de pantalla.
p>2. El valor de forSystem es, por supuesto, verdadero, lo que representa la aplicación del sistema
3. La función de programación maneja las tareas ejecutadas por un hilo vinculado en la aplicación y las llama al hilo principal Para su ejecución, se puede ver en systrace. Como se muestra en la figura siguiente, una vez completada la síntesis SF del bucle vsync, se ejecutará una captura de pantalla.
Puede obtener cada capa en el método captureScreenImplLocked. procese cada capa en este bloque, como cuál El contenido no necesita ser interceptado, etc.
El siguiente paso es llamar al hilo principal para realizar la tarea.
Siguiente paso método renderScreenImplLocked
Este método tiene mucho contenido, la declaración clave es
GLESRenderEngine hereda de RenderEngine
getRenderEngine( ).drawLayers Es una llamada al método drawLayers de GLESRenderEngine. El trabajo principal de este método es
1. Sintetizar una capa de renderizado de visualización específica a través de la GPU
2. Dibujar gráficos. para la capa de renderizado
3. Dibujar gráficos para la capa de renderizado, Capas, el rango de visualización de la capa de renderizado de GPU
4. Capas, las capas dibujadas en la pantalla, z- orden de los ejes
5, Búfer, llena el contenido de la capa en el búfer
6. userFrameBufferCache El búfer está disponible como verdadero Sin el búfer, no se puede implementar.
7. bufferFence, valla Marcar para ver si está listo y listo para dibujar
Llene el búfer, que contendrá el contenido de la capa de pantalla.
Volver a SurfaceControl.java
FinalScreenshotGraphicBuffer buffer = captureToBuffer(displayToken, sourceCrop, width, height, userIdentityTransform, rotation
El buffer ahora tiene un valor); , se ha llenado, el siguiente paso es convertir el búfer a Bitmap
Llamar a Bitmap.WrapHardwareBuffer(displayToken, sourceCrop, width, height, userIdentityTransform, rotation);
Devolver SurfaceControl . java
El búfer de gráficos de pantalla final. wrapHardwareBuffer(buffer.getGraphicBuffer(),buffer.getColorSpace()); Puede obtener el mapa de bits que necesitamos y se completa el proceso de captura de pantalla.