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). O 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 lançados 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 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 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:
- 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 abaixo 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-main: 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 comando a seguir, conforme especificado na mensagem de erro, para mudar
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 ele possa ser criado normalmente.
Adicionar um novo formato de pixel ao AHB
Adicionar suporte a um novo formato de pixel exige 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 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 desta 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 em AHB, que precisa começar com
AHARDWAREBUFFER_FORMAT_
, seguido pelas abreviações do canal e pela profundidade de bits e terminar com a codificação. Essa entrada de tipo enumerado precisa ter o mesmo valor hexadecimal que o 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 nenhum formato associado existir, especifique
N/A
. -
Adicione o formato de pixel a testes opcionais no CTS se ele tiver um formato OpenGL ES associado. Para fazer isso, adicione o novo formato GL ao
AHardwareBufferGLTest.cpp
emAHBFormatAsString(int32_t format)
comFORMAT_CASE(...)
eGL_FORMAT_CASE(...)
para o novo formato, mostrado da seguinte maneira: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:// ---------------------------------------------------------------------------- // 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
de 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 apropriados 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
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 dos componentes 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 número inteiro não assinado de 16 bits precisa ser
R_16UI
, e o mesmo formato com um formato de canal verde de número inteiro não assinado de 16 bits precisa serRG_16UI16UI
. -
Adicione o novo formato de pixel como
static int
emHardwareBuffer.java
, anexando uma nova variável de membro público ao 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 que o 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-main: 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 de erro, 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 possível compilar normalmente.
-
Adicione o novo formato de pixel aos testes de Java anexando o novo formato de pixel ao final de
paramsForTestCreateOptionalFormats()
emHardwareBufferTest.java
, conforme mostrado a seguir: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 uma API de gráficos, adicione-o à integração do sistema de janelas (WSI, na sigla em inglês) adequada para a API de gráficos relevante. Para um app ou processo do sistema que usa a API Vulkan, atualize a Swapchain do Vulkan. Para um processo de app ou sistema que usa a API OpenGL ES, atualize a API EGL.
Mudanças no WSI do Vulkan para novos formatos de pixels
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 secundárias da instância, use
instance_data
, mostrado da seguinte maneira:bool colorspace_ext = instance_data.hook_extensions.test(ProcHook::EXT_swapchain_colorspace);
Para extensões no 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 instância ou extensão de dispositivo ao
swapchain.cpp
. A lista de mudanças inicial não é necessária para configurar as extensões 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ços de cores.
- Adicione o novo formato a
dEQP-VK
, localizado emexternal/deqp
. - Atualize os testes de conformidade do Vulkan em
vktApiExternalMemoryTests.cpp
evktExternalMemoryUtil.cpp
inferindo as mudanças necessárias da fonte atual ou entrando em contato com o suporte do Android para mais informações.
Mudanças na EGL para novos formatos de pixel
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 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 ao tipo enumerado
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 apropriada.