Todos los formatos de píxeles nuevos que se agreguen a Android deben incluirse en el Lenguaje de definición de la interfaz de Android (AIDL) y en la Búfer de hardware de Android (AHB): El AIDL y el AHB tienen requisitos estrictos de estabilidad y estandarización que requieren un proceso cuidados cuando se extiende la funcionalidad. Todos los nuevos formatos de píxeles deben llegar al AOSP y los expertos de AIDL y AHB deben confirmar todas las actualizaciones individualmente. Este proceso de cuidado la confirmación es un factor importante para estandarizar cualquier formato de píxel nuevo en el plataforma.
En esta página, se describen las funciones de AOSP necesarias los cambios en el código y el proceso necesario para agregar nuevos formatos de píxeles en AOSP.
Antes de agregar un nuevo formato de píxeles, descarga la fuente y sube los parches como se describe en Cómo enviar parches.Cómo agregar un nuevo formato de píxeles al AIDL
Para agregar compatibilidad con un nuevo formato de píxeles, se deben realizar cambios en ambos archivos PixelFormat.aidl
ubicados dentro de AIDL. Consulta
hardware/interfaces/graphics/common/aidl/
para el código fuente de AIDL.
Para agregar un nuevo elemento de pixel formal a AIDL, sigue estos pasos:
- Agrega el nuevo formato de píxel como una entrada nueva al final de la enumeración
PixelFormat
enPixelFormat.aidl
Para ello, sigue la convención del código existente y configura el valor hexadecimal de tu entrada como uno más. que la entrada anterior. Haz coincidir los cambios de tu código con las entradas anteriores. Consulta el siguiente ejemplo para la entrada de formato de píxelesRGBA_8888
:/** * 32-bit format that has 8-bit R, G, B, and A components, in that order, * from the lowest memory address to the highest memory address. * * The component values are unsigned normalized to the range [0, 1], whose * interpretation is defined by the dataspace. */ RGBA_8888 = 0x1,
Se ve el siguiente mensaje de error cuando compilas el código después de realizar cambios en
PixelFormat.aidl
:android_developer:~/android/aosp-android-latest-release: m ... ############################################################################### # ERROR: AIDL API change detected # ############################################################################### Above AIDL file(s) has changed. Run `m android.hardware.graphics.common-update-api` to reflect the changes to the current version so that it is reviewed by android-aidl-api-council@google.com And then you need to change dependency on android.hardware.graphics.common-V(n)-* to android.hardware.graphics.common-V(n+1)-* to use new APIs.
-
Para borrar este error, ejecuta el siguiente comando, como se especifica en el mensaje de error, para cambiar
PixelFormat.aidl
en el directorioaidl_api
:m android.hardware.graphics.common-update-api
Ejecutar el comando anterior actualiza el archivo correcto para que se pueda compilar de forma normal.
Se agregó un nuevo formato de píxeles a AHB
Para agregar compatibilidad con un nuevo formato de píxeles, se deben realizar cambios en hardware_buffer.h
y AHardwareBuffer.cpp
.
Consulta frameworks/native/libs/nativewindow
para ver el código fuente de AHB.
Para agregar un nuevo píxel formal a AHB, sigue estos pasos:
- En
hardware_buffer.h
, agrega el nuevo formato de píxeles como una entrada nueva al final de la enumeraciónAHardwareBuffer_Format
. Sigue las convenciones de código existentes.Con el ejemplo de formato de píxel
RGBA_8888
, agrega la nueva entrada de formato de píxel como sigue:/** * Corresponding formats: * Vulkan: VK_FORMAT_R8G8B8A8_UNORM * OpenGL ES: GL_RGBA8 */ AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM = 1,
Ten en cuenta que al nuevo formato de píxeles se le asigna un nombre en AHB, que debe comenzar con
AHARDWAREBUFFER_FORMAT_
, seguido de las abreviaturas de los canales y las profundidades de bits, y terminar con la codificación. Esta entrada de enumeración debe tener el mismo valor hexadecimal que el dePixelFormat.aidl
.Se espera que el formato de píxeles tenga uno o ambos formatos asociados de Vulkan o OpenGL ES. Especifica el formato asociado cuando corresponda. Si no existe ningún formato asociado, especifica
N/A
-
Agrega el formato de píxeles a las pruebas opcionales de CTS, si tiene un formato OpenGL ES asociado. Para ello, agrega el nuevo formato GL
AHardwareBufferGLTest.cpp
enAHBFormatAsString(int32_t format)
conFORMAT_CASE(...)
yGL_FORMAT_CASE(...)
para el nuevo formato, que se muestran de la siguiente manera:const char* AHBFormatAsString(int32_t format) { switch (format) { ... FORMAT_CASE(R8G8B8A8_UNORM); ... GL_FORMAT_CASE(GL_RGB8); } return ""; }
-
A continuación, agrega una prueba nueva a
AHardwareBufferGLTest.cpp
, como se muestra a continuación:class RGBA8Test : public AHardwareBufferGLTest {}; // Verify that if we can allocate an RGBA8 AHB we can render to it. TEST_P(RGBA8Test, Write) { AHardwareBuffer_Desc desc = GetParam(); desc.usage = AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER; if (!SetUpBuffer(desc)) { return; } ASSERT_NO_FATAL_FAILURE(SetUpFramebuffer(desc.width, desc.height, 0, kBufferAsRenderbuffer)); ASSERT_NO_FATAL_FAILURE( SetUpProgram(kVertexShader, kColorFragmentShader, kPyramidPositions, 0.5f)); glDrawArrays(GL_TRIANGLES, 0, kPyramidVertexCount); ASSERT_EQ(GLenum{GL_NO_ERROR}, glGetError()); } INSTANTIATE_TEST_CASE_P( SingleLayer, RGBA8Test, ::testing::Values( AHardwareBuffer_Desc{57, 33, 1, AHARDWAREBUFFER_FORMAT_R16G16_UINT, 0, 0, 0, 0}), &GetTestName);
Especifica al menos un conjunto de valores
AHardwareBuffer_Desc
. Agrega más valores si es necesario. -
En
AHardwareBuffer.cpp
, busca el final de las aserciones estáticas que se encuentran dentro de lo siguiente:// ---------------------------------------------------------------------------- // Validate hardware_buffer.h and PixelFormat.aidl agree // ----------------------------------------------------------------------------
Agrega un nuevo
static_assert
para el nuevo formato de píxeles con la enumeraciónPixelFormat::
y no con la constanteHAL_PIXEL_FORMAT
. Con el mismo ejemplo del formato de píxelesRGBA_8888
de Cómo agregar un nuevo formato de píxeles a AIDL, agrega la nueva entrada de formato de píxeles de la siguiente manera:static_assert(static_cast
(aidl::android::hardware::graphics::common::PixelFormat::RGBA_8888) == AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM, "HAL and AHardwareBuffer pixel format don't match"); -
Agrega el nuevo formato de píxel a las pruebas correspondientes. Para ello, agrega el nuevo formato de píxeles al final de
PrintAhbFormat()
enAHardwareBufferTest.cpp
Sigue la convención de código existente, como se muestra a continuación:void PrintAhbFormat(std::ostream& os, uint64_t format) { switch (format) { ... FORMAT_CASE(R8G8B8A8_UNORM); default: os << "unknown"; break; } }
-
Agrega el nuevo formato de píxeles al SDK de
HardwareBuffer
enHardwareBuffer.java
: Agrega una entrada nueva a@IntDef
. Por ejemplo, la entrada para laRGBA_8888
se muestra de la siguiente manera:@Retention(RetentionPolicy.SOURCE) @IntDef(prefix = { "RGB", "BLOB", "YCBCR_", "D_", "DS_", "S_" }, value = { ... RGBA_8888, })
Si los valores de los componentes no están normalizados sin firmar, indica el valor de forma explícita en el nombre de la variable. Por ejemplo, el nombre de la variable para un canal rojo de 16 bits de número entero sin firma El único formato debe ser
R_16UI
, y debe tener el mismo formato con un número entero de 16 bits adicional sin firma el formato del canal verde debe serRG_16UI16UI
. -
Agrega el nuevo formato de píxeles como un
static int
enHardwareBuffer.java
. Para ello, agrega una nueva variable de miembro pública al final de@Format
:@Format ... /** Format: 8 bits each red, green, blue, alpha */ public static final int RGBA_8888 = 0x1;
Esta entrada enum debe tener el mismo valor hexadecimal que el de
PixelFormat.aidl
yhardware_buffer.h
. Sigue las convenciones existentes. -
Si intentas compilar con estos cambios de código, se generará un error de compilación:
android_developer:~/android/aosp-android-latest-release: m ... ****************************** You have tried to change the API from what has been previously approved. To make these errors go away, you have two choices: 1. You can add '@hide' javadoc comments (and remove @SystemApi/@TestApi/etc) to the new methods, etc. shown in the above diff. 2. You can update current.txt and/or removed.txt by executing the following command: m api-stubs-docs-non-updatable-update-current-api To submit the revised current.txt to the main Android repository, you will need approval. ****************************** ...
Para borrar este error, ejecuta el siguiente comando, como se especifica en el mensaje de error, para cambiar
current.txt
:m api-stubs-docs-non-updatable-update-current-api
Cuando ejecutas el comando anterior, se actualiza el archivo correcto para poder compilar con normalidad.
-
Agregar el nuevo formato de píxeles a las pruebas de Java; para ello, agrega el nuevo formato de píxeles al final de
paramsForTestCreateOptionalFormats()
enHardwareBufferTest.java
, como se muestra a continuación:private static Object[] paramsForTestCreateOptionalFormats() { return new Integer[]{ HardwareBuffer.RGBA_8888 };
Se agregó un nuevo formato de píxeles a la integración del sistema de ventanas
Para usar el nuevo formato de píxeles como el formato de un búfer de fotogramas en una de gráficos, agregarla a la integración de sistema de ventanas (Window System Integration, WSI) correspondiente para los la API de Graphics. Para una app o un proceso del sistema que use la API de Vulkan, actualiza el Swapchain de Vulkan. Para una app o un proceso del sistema que use la API de OpenGL ES, actualiza el archivo EGL.
Cambios en la WSI de Vulkan para nuevos formatos de píxeles
Actualiza el WSI de Vulkan de la siguiente manera:-
Agrega un caso nuevo a la función
GetNativePixelFormat(VkFormat format)
enswapchain.cpp
:android::PixelFormat GetNativePixelFormat(VkFormat format) { ... switch (format) { ... case VK_FORMAT_R8G8B8A8_UNORM: native_format = PixelFormat::RGBA_8888; break; ... default: ALOGV("unsupported swapchain format %d", format); break; } return native_format; }
- Consulta la extensión de Vulkan si el formato de píxeles requiere una extensión de Vulkan para funcionar.
Por ejemplo, para las extensiones laterales, usa
instance_data
, como se muestra a continuación:bool colorspace_ext = instance_data.hook_extensions.test(ProcHook::EXT_swapchain_colorspace);
Para las extensiones del dispositivo, usa lo siguiente:
bool rgba10x6_formats_ext = false; uint32_t exts_count; const auto& driver = GetData(pdev).driver; driver.EnumerateDeviceExtensionProperties(pdev, nullptr, &exts_count, nullptr); std::vector
props(exts_count); driver.EnumerateDeviceExtensionProperties(pdev, nullptr, &exts_count, props.data()); for (uint32_t i = 0; i < exts_count; i++) { VkExtensionProperties prop = props[i]; if (strcmp(prop.extensionName, VK_EXT_RGBA10X6_FORMATS_EXTENSION_NAME) == 0) { rgba10x6_formats_ext = true; } } Google controla la infraestructura necesaria para exponer una instancia o extensión de dispositivo. a
swapchain.cpp
. La lista de cambios inicial no necesita configurar correctamente las extensiones desde el cargador de Vulkan - A continuación, enumera los pares de formato y espacio de color:
desc.format = AHARDWAREBUFFER_FORMAT_R10G10B10A10_UNORM; if (AHardwareBuffer_isSupported(&desc) && rgba10x6_formats_ext) { all_formats.emplace_back( VkSurfaceFormatKHR{VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR}); if (colorspace_ext) { all_formats.emplace_back( VkSurfaceFormatKHR{VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16, VK_COLOR_SPACE_PASS_THROUGH_EXT}); all_formats.emplace_back( VkSurfaceFormatKHR{VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16, VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT}); }
Debes conocer los pares de formato y espacio de color compatibles.
- Agrega el nuevo formato a
dEQP-VK
, ubicado enexternal/deqp
- Actualizar pruebas de cumplimiento de Vulkan en
vktApiExternalMemoryTests.cpp
yvktExternalMemoryUtil.cpp
infiriendo los cambios necesarios de la fuente existente o comunicándote con el equipo de asistencia de Android para obtener información.
Cambios en EGL para los nuevos formatos de píxeles
Actualiza el EGL de la siguiente manera:
- En la
getNativePixelFormat()
modifica el árbolif-else
con el objetivo de mostrar la enumeración del AIDL para el nuevo formato de píxeles. Este es el ejemplo del formato de píxelesRGBA_8888
:if (a == 0) { ... } else { if (componentType == EGL_COLOR_COMPONENT_TYPE_FIXED_EXT) { if (colorDepth > 24) { ... } else { *format = PixelFormat::RGBA_8888; } } else { ... } }
- Para agregar el nuevo formato a dEQP, agrega una entrada nueva a la enumeración
androidFormats
, como se muestra a continuación:static const GLenum androidFormats[] = { ... GL_RGBA8, ... };
Envía tu actualización
Sigue las instrucciones de Para colaboradores para crear tus listas de cambios y compartirlas con el equipo adecuado.