Tutti i nuovi formati di pixel aggiunti ad Android devono essere inclusi nell'Android Interface Definition Language (AIDL) e nell'Android Hardware Buffer (AHB). L'AIDL e l'AHB hanno requisiti rigorosi di stabilità e standardizzazione che richiedono un processo accurato per l'estensione della funzionalità. Tutti i nuovi formati di pixel devono essere inseriti in AOSP e tutti gli aggiornamenti devono essere confermati singolarmente da esperti AIDL e AHB. Questa procedura di conferma accurata è un fattore importante per standardizzare i nuovi formati dei pixel sulla piattaforma.
Questa pagina illustra le modifiche necessarie al codice AOSP e la procedura per aggiungere nuovi formati pixel su AOSP.
Prima di aggiungere un nuovo formato di pixel, scarica il codice sorgente e carica le patch come descritto in Invio di patch.Aggiungere un nuovo formato di pixel ad AIDL
L'aggiunta del supporto di un nuovo formato pixel richiede modifiche a entrambi i
file PixelFormat.aidl
che si trovano all'interno di AIDL. Consulta
hardware/interfaces/graphics/common/aidl/
per il codice sorgente AIDL.
Per aggiungere una nuova forma di pixel ad AIDL:
- Aggiungi il nuovo formato del pixel come nuova voce alla fine dell'enum
PixelFormat
inPixelFormat.aidl
seguendo la convenzione di codice esistente e impostando il valore esadecimale della voce su uno superiore alla voce precedente. Abbina le modifiche al codice alle voci precedenti. Vedi l'esempio seguente per la voce del formato 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,
Quando compili il codice dopo aver apportato modifiche a
PixelFormat.aidl
, viene visualizzato il seguente messaggio di errore: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.
-
Per eliminare questo errore, esegui questo comando, come specificato nel messaggio di errore, per modificare
PixelFormat.aidl
nella directoryaidl_api
:m android.hardware.graphics.common-update-api
L'esecuzione del comando precedente aggiorna il file corretto per poter eseguire la compilazione normalmente.
Aggiungere un nuovo formato di pixel ad AHB
L'aggiunta del supporto per un nuovo formato di pixel richiede modifiche a
hardware_buffer.h
e AHardwareBuffer.cpp
.
Consulta frameworks/native/libs/nativewindow
per il codice sorgente di AHB.
Per aggiungere una nuova forma del pixel ad AHB:
- In
hardware_buffer.h
, aggiungi il nuovo formato di pixel come nuova voce alla fine dell'enumAHardwareBuffer_Format
. Segui le convenzioni di codice esistenti.Utilizzando l'esempio di formato pixel
RGBA_8888
, aggiungi la nuova voce del formato pixel come segue:/** * Corresponding formats: * Vulkan: VK_FORMAT_R8G8B8A8_UNORM * OpenGL ES: GL_RGBA8 */ AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM = 1,
Tieni presente che al nuovo formato del pixel viene assegnato un nome in AHB, che deve iniziare con
AHARDWAREBUFFER_FORMAT_
, seguito dalle abbreviazioni dei canali e dalle profondità di bit e terminare con la codifica. Questa voce dell'enum deve avere lo stesso valore esadecimale diPixelFormat.aidl
.Il formato dei pixel deve avere uno o entrambi i formati associati Vulkan o OpenGL ES. Specifica il formato associato, se opportuno. Se non esiste un formato associato, specifica
N/A
. -
Aggiungi il formato dei pixel ai test facoltativi in CTS, se è associato a un formato OpenGL ES. A tale scopo, aggiungi il nuovo formato GL a
AHardwareBufferGLTest.cpp
inAHBFormatAsString(int32_t format)
conFORMAT_CASE(...)
eGL_FORMAT_CASE(...)
per il nuovo formato, come mostrato di seguito:const char* AHBFormatAsString(int32_t format) { switch (format) { ... FORMAT_CASE(R8G8B8A8_UNORM); ... GL_FORMAT_CASE(GL_RGB8); } return ""; }
-
Aggiungi un nuovo test a
AHardwareBufferGLTest.cpp
, come mostrato di seguito: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);
Specifica almeno un insieme di valori
AHardwareBuffer_Desc
. Se necessario, aggiungi altri valori. -
In
AHardwareBuffer.cpp
, trova la fine delle verifiche statiche trovate all'interno:// ---------------------------------------------------------------------------- // Validate hardware_buffer.h and PixelFormat.aidl agree // ----------------------------------------------------------------------------
Aggiungi un nuovo
static_assert
per il nuovo formato di pixel, utilizzando l'enumPixelFormat::
e non la costanteHAL_PIXEL_FORMAT
. Utilizzando lo stesso esempio per il formato pixelRGBA_8888
di Add a new pixel format to AIDL (Aggiungi un nuovo formato pixel ad AIDL), aggiungi la nuova voce relativa al formato pixel come segue:static_assert(static_cast
(aidl::android::hardware::graphics::common::PixelFormat::RGBA_8888) == AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM, "HAL and AHardwareBuffer pixel format don't match"); -
Aggiungi il nuovo formato del pixel ai test appropriati aggiungendolo alla fine di
PrintAhbFormat()
inAHardwareBufferTest.cpp
. Segui la convenzione di codice esistente, come mostrato di seguito:void PrintAhbFormat(std::ostream& os, uint64_t format) { switch (format) { ... FORMAT_CASE(R8G8B8A8_UNORM); default: os << "unknown"; break; } }
-
Aggiungi il nuovo formato pixel all'SDK
HardwareBuffer
inHardwareBuffer.java
aggiungendo una nuova voce a@IntDef
. Ad esempio, la voce per il formatoRGBA_8888
è mostrata come segue:@Retention(RetentionPolicy.SOURCE) @IntDef(prefix = { "RGB", "BLOB", "YCBCR_", "D_", "DS_", "S_" }, value = { ... RGBA_8888, })
Se i valori dei componenti non sono normalizzati senza segno, indica il valore esplicitamente nel nome della variabile. Ad esempio, il nome della variabile per un formato solo per il canale rosso a 16 bit con numero intero senza segno deve essere
R_16UI
e lo stesso formato con un altro formato per il canale verde a 16 bit di un numero intero senza segno deve essereRG_16UI16UI
. -
Aggiungi il nuovo formato del pixel come
static int
inHardwareBuffer.java
, aggiungendo una nuova variabile membro pubblico alla fine di@Format
:@Format ... /** Format: 8 bits each red, green, blue, alpha */ public static final int RGBA_8888 = 0x1;
Questa voce dell'enum deve avere lo stesso valore esadecimale di
PixelFormat.aidl
ehardware_buffer.h
. Segui le convenzioni esistenti. -
Il tentativo di compilazione con queste modifiche al codice genera un errore di compilazione:
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. ****************************** ...
Per correggere questo errore, esegui il seguente comando, come specificato nel messaggio di errore, per modificare
current.txt
:m api-stubs-docs-non-updatable-update-current-api
L'esecuzione del comando precedente aggiorna il file corretto per poter eseguire la compilazione normalmente.
-
Aggiungi il nuovo formato pixel ai test Java, aggiungendo il nuovo formato pixel alla fine di
paramsForTestCreateOptionalFormats()
inHardwareBufferTest.java
, come segue:private static Object[] paramsForTestCreateOptionalFormats() { return new Integer[]{ HardwareBuffer.RGBA_8888 };
Aggiungere un nuovo formato pixel all'integrazione del sistema di finestre
Per utilizzare il nuovo formato di pixel come formato per un framebuffer in un'API grafica, aggiungilo all'integrazione del sistema di finestre (WSI) appropriata per l'API grafica pertinente. Per un processo di sistema o di app che utilizza l'API Vulkan, aggiorna la Vulkan Swapchain. Per un processo di sistema o di app che utilizza l'API OpenGL ES, aggiorna l'API EGL.
Modifiche a Vulkan WSI per i nuovi formati pixel
Aggiorna il WSI Vulkan come segue:-
Aggiungi una nuova condizione alla funzione
GetNativePixelFormat(VkFormat format)
inswapchain.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; }
- Esegui una query sull'estensione Vulkan se il formato del pixel richiede un'estensione Vulkan per funzionare.
Ad esempio, per le estensioni laterali, utilizza
instance_data
, come mostrato di seguito:bool colorspace_ext = instance_data.hook_extensions.test(ProcHook::EXT_swapchain_colorspace);
Per le estensioni lato dispositivo, utilizza quanto segue:
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 gestisce l'infrastruttura necessaria per esporre un'istanza o un'estensione del dispositivo a
swapchain.cpp
. L'elenco delle modifiche iniziale non è necessario per avere le estensioni configurate correttamente dal caricatore Vulkan. - Quindi, enumera le coppie di formato e spazio colore:
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}); }
Devi conoscere le coppie di formati e spazi di colore compatibili.
- Aggiungi il nuovo formato a
dEQP-VK
, disponibile all'indirizzoexternal/deqp
. - Aggiorna i test di conformità Vulkan in
vktApiExternalMemoryTests.cpp
evktExternalMemoryUtil.cpp
deducendo le modifiche richieste dall'origine esistente o contattando l'assistenza Android per avere informazioni.
Modifiche EGL per i nuovi formati di pixel
Aggiorna l'EGL come segue:
- Nella funzione
getNativePixelFormat()
, modifica la strutturaif-else
in modo che restituisca l'enumerazione AIDL per il nuovo formato di pixel. Utilizzando l'esempio per il formato pixelRGBA_8888
:if (a == 0) { ... } else { if (componentType == EGL_COLOR_COMPONENT_TYPE_FIXED_EXT) { if (colorDepth > 24) { ... } else { *format = PixelFormat::RGBA_8888; } } else { ... } }
- Per aggiungere il nuovo formato a dEQP, aggiungi una nuova voce all'enum
androidFormats
, come mostrato di seguito:static const GLenum androidFormats[] = { ... GL_RGBA8, ... };
Invia l'aggiornamento
Segui le istruzioni riportate in Per i collaboratori per creare gli elenchi delle modifiche e condividerli con il team appropriato.