Todos os novos formatos de pixel adicionados ao Android precisam ser incluídos na Linguagem de definição de interface do Android (AIDL) e no Buffer de hardware do Android (AHB). A AIDL e o AHB têm requisitos rigorosos de estabilidade e padronização que exigem um processo cuidadoso ao estender a funcionalidade. Todos os novos formatos de pixel precisam ser incluídos no AOSP, e todas as atualizações precisam ser confirmadas individualmente por especialistas em AIDL e AHB. Esse processo de confirmação cuidadosa é um fator importante na padronização de novos formatos de pixel na plataforma.
Esta página descreve as mudanças necessárias no código do AOSP e o processo exigido para adicionar novos formatos de pixel no AOSP.
Antes de adicionar um novo formato de pixel, faça o download da origem e envie patches conforme descrito em Envio de patches.Adicionar um novo formato de pixel ao AIDL
Para adicionar suporte a um novo formato de pixel, é preciso fazer mudanças nos dois arquivos
PixelFormat.aidl
localizados no AIDL. Consulte
hardware/interfaces/graphics/common/aidl/
para conferir o código-fonte do AIDL.
Para adicionar um novo pixel formal à AIDL, siga estas etapas:
- Adicione o novo formato de pixel como uma nova entrada ao final da enumeração
PixelFormat
emPixelFormat.aidl
seguindo a convenção de código atual e definindo o valor hexadecimal da sua entrada como um a mais do que a entrada anterior. Faça as mudanças no código para corresponder às entradas anteriores. Confira o exemplo a seguir para a entrada do formato de pixelRGBA_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,
A seguinte mensagem de erro aparece quando você cria o código depois de fazer mudanças em
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 corrigir esse erro, execute o seguinte comando, conforme especificado na mensagem de erro, para mudar
PixelFormat.aidl
no diretórioaidl_api
:m android.hardware.graphics.common-update-api
Executar o comando acima atualiza o arquivo correto para que a criação seja feita normalmente.
Adicionar um novo formato de pixel ao AHB
Para adicionar suporte a um novo formato de pixel, é necessário fazer mudanças em
hardware_buffer.h
e AHardwareBuffer.cpp
.
Consulte frameworks/native/libs/nativewindow
para conferir o código-fonte do AHB.
Para adicionar um novo pixel formal à AHB, siga estas etapas:
- Em
hardware_buffer.h
, adicione o novo formato de pixel como uma nova entrada ao final da enumeraçãoAHardwareBuffer_Format
. Siga as convenções de código atuais.Usando o exemplo de formato de pixel
RGBA_8888
, adicione a nova entrada de formato de pixel da seguinte maneira:/** * Corresponding formats: * Vulkan: VK_FORMAT_R8G8B8A8_UNORM * OpenGL ES: GL_RGBA8 */ AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM = 1,
O novo formato de pixel recebe um nome no AHB, que precisa começar com
AHARDWAREBUFFER_FORMAT_
, seguido pelas abreviações de canal e profundidades de bits, e terminar com a codificação. Essa entrada de enumeração precisa ter o mesmo valor hexadecimal dePixelFormat.aidl
.Espera-se que o formato de pixel tenha um ou ambos os formatos associados Vulkan ou OpenGL ES. Especifique o formato associado, quando apropriado. Se não houver um formato associado, especifique
N/A
. -
Adicione o formato de pixel ao teste opcional no CTS, se ele tiver um formato OpenGL ES associado. Para fazer isso, adicione o novo formato GL a
AHardwareBufferGLTest.cpp
emAHBFormatAsString(int32_t format)
comFORMAT_CASE(...)
eGL_FORMAT_CASE(...)
para o novo formato, conforme mostrado abaixo:const char* AHBFormatAsString(int32_t format) { switch (format) { ... FORMAT_CASE(R8G8B8A8_UNORM); ... GL_FORMAT_CASE(GL_RGB8); } return ""; }
-
Em seguida, adicione um novo teste a
AHardwareBufferGLTest.cpp
, conforme mostrado abaixo: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);
Especifique pelo menos um conjunto de valores
AHardwareBuffer_Desc
. Adicione mais valores, se necessário. -
Em
AHardwareBuffer.cpp
, encontre o fim das declarações estáticas encontradas em:// ---------------------------------------------------------------------------- // Validate hardware_buffer.h and PixelFormat.aidl agree // ----------------------------------------------------------------------------
Adicione um novo
static_assert
para o novo formato de pixel usando o enumPixelFormat::
e não a constanteHAL_PIXEL_FORMAT
. Usando o mesmo exemplo do formato de pixelRGBA_8888
em Adicionar um novo formato de pixel ao AIDL, adicione a nova entrada de formato de pixel da seguinte maneira:static_assert(static_cast
(aidl::android::hardware::graphics::common::PixelFormat::RGBA_8888) == AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM, "HAL and AHardwareBuffer pixel format don't match"); -
Adicione o novo formato de pixel aos testes adequados, anexando-o ao final de
PrintAhbFormat()
emAHardwareBufferTest.cpp
. Siga a convenção de código atual, conforme mostrado abaixo:void PrintAhbFormat(std::ostream& os, uint64_t format) { switch (format) { ... FORMAT_CASE(R8G8B8A8_UNORM); default: os << "unknown"; break; } }
-
Adicione o novo formato de pixel ao SDK do
HardwareBuffer
emHardwareBuffer.java
: anexando uma nova entrada a@IntDef
. Por exemplo, a entrada para o formatoRGBA_8888
é mostrada da seguinte maneira:@Retention(RetentionPolicy.SOURCE) @IntDef(prefix = { "RGB", "BLOB", "YCBCR_", "D_", "DS_", "S_" }, value = { ... RGBA_8888, })
Se os valores de componente não forem normalizados sem sinal, indique o valor explicitamente no nome da variável. Por exemplo, o nome da variável para um formato de canal vermelho de 16 bits inteiro sem sinal precisa ser
R_16UI
, e o mesmo formato com um formato de canal verde de 16 bits inteiro sem sinal adicional precisa serRG_16UI16UI
. -
Adicione o novo formato de pixel como um
static int
emHardwareBuffer.java
, adicionando uma nova variável de membro público no final de@Format
:@Format ... /** Format: 8 bits each red, green, blue, alpha */ public static final int RGBA_8888 = 0x1;
Essa entrada de enumeração precisa ter o mesmo valor hexadecimal de
PixelFormat.aidl
ehardware_buffer.h
. Siga as convenções atuais. -
A tentativa de criar com essas mudanças no código gera um erro de build:
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 corrigir esse erro, execute o seguinte comando, conforme especificado na mensagem de erro, para mudar
current.txt
:m api-stubs-docs-non-updatable-update-current-api
Executar o comando acima atualiza o arquivo correto para que a criação seja feita normalmente.
-
Adicione o novo formato de pixel aos testes em Java anexando-o ao final de
paramsForTestCreateOptionalFormats()
emHardwareBufferTest.java
, conforme mostrado abaixo:private static Object[] paramsForTestCreateOptionalFormats() { return new Integer[]{ HardwareBuffer.RGBA_8888 };
Adicionar um novo formato de pixel à integração do sistema de janelas
Para usar o novo formato de pixel como formato de um framebuffer em uma API de gráficos, adicione-o à integração do sistema de janelas (WSI, na sigla em inglês) apropriada para a API de gráficos relevante. Para um app ou processo do sistema que usa a API Vulkan, atualize o Vulkan Swapchain. Para um app ou processo do sistema que usa a API OpenGL ES, atualize a API EGL.
Mudanças na WSI do Vulkan para novos formatos de pixel
Atualize a WSI do Vulkan da seguinte maneira:-
Adicione um novo caso à função
GetNativePixelFormat(VkFormat format)
emswapchain.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; }
- Consulte a extensão do Vulkan se o formato de pixel exigir uma extensão do Vulkan para funcionar.
Para extensões do lado da instância, use
instance_data
, conforme mostrado abaixo:bool colorspace_ext = instance_data.hook_extensions.test(ProcHook::EXT_swapchain_colorspace);
Para extensões do lado do dispositivo, use o seguinte:
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; } } O Google processa a infraestrutura necessária para expor uma extensão de instância ou dispositivo ao
swapchain.cpp
. A lista de mudanças inicial não precisa ter as extensões configuradas corretamente pelo carregador do Vulkan. - Em seguida, enumere os pares de formato e espaço de cores:
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}); }
Você precisa conhecer os formatos e espaços de cores compatíveis.
- Adicione o novo formato a
dEQP-VK
, localizado emexternal/deqp
. - Atualize os testes de conformidade do Vulkan em
vktApiExternalMemoryTests.cpp
evktExternalMemoryUtil.cpp
ao inferir as mudanças necessárias da fonte atual ou entre em contato com o suporte do Android para mais informações.
Mudanças na EGL para novos formatos de pixel
Atualize a EGL da seguinte maneira:
- Na função
getNativePixelFormat()
, modifique a árvoreif-else
para retornar a enumeração AIDL do novo formato de pixel. Usando o exemplo do formato de pixelRGBA_8888
:if (a == 0) { ... } else { if (componentType == EGL_COLOR_COMPONENT_TYPE_FIXED_EXT) { if (colorDepth > 24) { ... } else { *format = PixelFormat::RGBA_8888; } } else { ... } }
- Para adicionar o novo formato ao dEQP, adicione uma nova entrada à enumeração
androidFormats
, conforme mostrado abaixo:static const GLenum androidFormats[] = { ... GL_RGBA8, ... };
Enviar a atualização
Siga Para colaboradores para criar suas listas de mudanças e compartilhá-las com a equipe adequada.