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 rígidos de estabilidade e padronização que necessitam um processo cuidadoso ao estender a funcionalidade. Todos os novos formatos de pixel precisam ser lançados no AOSP e todas as atualizações precisam ser confirmadas individualmente por especialistas da AIDL e do AHB. Esse processo de confirmação cuidadosa é um fator importante para padronizar novos formatos de pixel na plataforma.
Esta página descreve o AOSP necessário mudanças de código e o processo necessário para adicionar novos formatos de pixel no AOSP.
Antes de adicionar um novo formato de pixel, faça o download da origem e envie os patches conforme descrito em Enviar patches.Adicionar um novo formato de pixel ao AIDL
Adicionar suporte a um novo formato de pixel exige alterações em ambos os
Arquivos PixelFormat.aidl
localizados na AIDL. Consulte
hardware/interfaces/graphics/common/aidl/
para o código-fonte da AIDL.
Para adicionar um novo pixel formal à AIDL, siga estas etapas:
- Anexe o novo formato de pixel como uma nova entrada ao final do tipo enumerado
PixelFormat
emPixelFormat.aidl
, seguindo a convenção de código atual e definindo o valor hexadecimal da entrada como um número maior do que a anterior. Corresponda as alterações de código às entradas anteriores. Confira o exemplo a seguir para a entrada de 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 limpar esse erro, execute o seguinte comando, conforme especificado na mensagem de erro, para alterar
PixelFormat.aidl
no diretórioaidl_api
:m android.hardware.graphics.common-update-api
A execução do comando acima atualiza o arquivo correto para que seja possível compilar normalmente.
Adicionar um novo formato de pixel ao AHB
Adicionar suporte a um novo formato de pixel exige alterações 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 ao AHB, siga estas etapas:
- Em
hardware_buffer.h
, anexe 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 como segue:/** * 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 do canal e profundidades de bits, e terminar com a codificação. Essa entrada de tipo enumerado precisa ter o mesmo valor hexadecimal que o dePixelFormat.aidl
.O formato de pixel precisa ter um ou ambos os formatos Vulkan ou OpenGL ES associados. Especifique o formato associado quando apropriado. Se não houver um formato associado, especifique
N/A
. -
O formato de pixel foi adicionado aos testes opcionais do 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
, mostrado da seguinte maneira: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 // ----------------------------------------------------------------------------
Anexe um novo
static_assert
para o novo formato de pixel usando o enumPixelFormat::
e não a constanteHAL_PIXEL_FORMAT
. Usando o mesmo exemplo para o formato de pixelRGBA_8888
da Adicione um novo formato de pixel à AIDL, adicione a nova entrada de formato de pixel da seguinte forma: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 apropriados anexando-o ao final de
PrintAhbFormat()
emAHardwareBufferTest.cpp
. Siga a convenção de código existente, 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
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 do componente não estiverem normalizados sem sinal, indique o valor explicitamente no nome da variável. Por exemplo, o nome da variável para um número inteiro não assinado de canal vermelho de 16 bits O único formato precisa ser
R_16UI
, e o mesmo formato com um número inteiro não assinado adicional de 16 bits o formato de canal verde precisa serRG_16UI16UI
. -
Adicione o novo formato de pixel como um
static int
emHardwareBuffer.java
, anexando uma nova variável de membro pública ao final de@Format
:@Format ... /** Format: 8 bits each red, green, blue, alpha */ public static final int RGBA_8888 = 0x1;
Essa entrada de tipo enumerado precisa ter o mesmo valor hexadecimal de
PixelFormat.aidl
ehardware_buffer.h
. Siga as convenções existentes. -
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 limpar esse erro, execute o seguinte comando, conforme especificado na mensagem: para alterar
current.txt
:m api-stubs-docs-non-updatable-update-current-api
A execução do comando acima atualiza o arquivo correto para que seja criado normalmente.
-
Adicione o novo formato de pixel aos testes Java anexando-o ao final de
paramsForTestCreateOptionalFormats()
emHardwareBufferTest.java
, conforme mostrado abaixo:private static Object[] paramsForTestCreateOptionalFormats() { return new Integer[]{ HardwareBuffer.RGBA_8888 };
Adicionamos um novo formato de pixel à integração do sistema de janelas
Para usar o novo formato de pixel como o formato de um framebuffer em um da API de gráficos do Google, adicione-a à Integração do sistema de janelas (WSI, na sigla em inglês) apropriada para o API de gráficos do Google. Para um app ou processo do sistema que usa a API Vulkan, atualize a Swapchain do Vulkan. Para um app ou processo do sistema que usa a API OpenGL ES, atualize a API EGL.
Mudanças no WSI do Vulkan para novos formatos de pixel
Atualize o 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; }
- Consultar a extensão do Vulkan se o formato de pixel exigir uma extensão do Vulkan para funcionar.
Para extensões laterais de exemplo, use
instance_data
, mostrado da seguinte maneira:bool colorspace_ext = instance_data.hook_extensions.test(ProcHook::EXT_swapchain_colorspace);
Para extensões no 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 instância ou extensão de dispositivo para
swapchain.cpp
. A lista de alterações inicial não é necessária para ter as extensões configuradas corretamente no 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ê deve ter conhecimento do formato compatível e dos pares de espaço de cores.
- Adicione o novo formato ao
dEQP-VK
, localizado emexternal/deqp
. - Atualizar testes de conformidade do Vulkan em
vktApiExternalMemoryTests.cpp
evktExternalMemoryUtil.cpp
inferindo as mudanças necessárias a partir da fonte existente ou entrando em contato com o suporte do Android para mais informações.
Mudanças na EGL para novos formatos de pixels
Atualize o EGL da seguinte maneira:
- Na função
getNativePixelFormat()
, modifique a árvoreif-else
para retornar a enumeração AIDL para o novo formato de pixel. Usando o exemplo para o 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 ao
androidFormats
enumeração, mostrada da seguinte maneira:static const GLenum androidFormats[] = { ... GL_RGBA8, ... };
Envie sua atualização
Siga Para colaboradores para criar suas listas de mudanças e compartilhá-las com a equipe apropriada.