Alle neuen Pixelformate, die Android hinzugefügt werden, müssen in der Android Interface Definition Language (AIDL) und im Android Hardware Buffer (AHB) enthalten sein. Die AIDL und die AHB haben strenge Stabilitäts- und Standardisierungsanforderungen, die bei der Erweiterung der Funktionen einen sorgfältigen Prozess erfordern. Alle neuen Pixelformate müssen in AOSP landen und alle Updates müssen einzeln von AIDL- und AHB-Experten bestätigt werden. Dieser sorgfältige Bestätigungsprozess ist ein wichtiger Faktor bei der Standardisierung neuer Pixelformate auf der Plattform.
Auf dieser Seite werden die erforderlichen Änderungen am AOSP-Code und der Prozess zum Hinzufügen neuer Pixelformate in AOSP beschrieben.
Bevor Sie ein neues Pixelformat hinzufügen, laden Sie die Quelle herunter und laden Sie die Patches wie unter Patches einreichen beschrieben hoch.AIDL ein neues Pixelformat hinzufügen
Wenn Sie die Unterstützung für ein neues Pixelformat hinzufügen möchten, müssen Sie beide PixelFormat.aidl
-Dateien in AIDL ändern. Den AIDL-Quellcode finden Sie unter hardware/interfaces/graphics/common/aidl/
.
So fügen Sie AIDL ein neues Pixelformat hinzu:
- Fügen Sie das neue Pixelformat als neuen Eintrag an das Ende der
PixelFormat
-Enumeration inPixelFormat.aidl
an. Folgen Sie dabei der bestehenden Codekonvention und legen Sie den Hexadezimalwert für Ihren Eintrag um eins höher als den des vorherigen Eintrags fest. Ordnen Sie die Codeänderungen den vorherigen Einträgen zu. Im folgenden Beispiel wird der Eintrag für das PixelformatRGBA_8888
gezeigt:/** * 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,
Wenn Sie den Code nach Änderungen an
PixelFormat.aidl
erstellen, wird die folgende Fehlermeldung angezeigt: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.
-
Führen Sie den folgenden Befehl aus, um diesen Fehler zu beheben, wie in der Fehlermeldung angegeben, um
PixelFormat.aidl
im Verzeichnisaidl_api
zu ändern:m android.hardware.graphics.common-update-api
Durch Ausführen des Befehls oben wird die richtige Datei aktualisiert, damit der Build normal ausgeführt werden kann.
AHB ein neues Pixelformat hinzufügen
Wenn Sie die Unterstützung für ein neues Pixelformat hinzufügen möchten, müssen Sie hardware_buffer.h
und AHardwareBuffer.cpp
ändern.
Den AHB-Quellcode finden Sie unter frameworks/native/libs/nativewindow
.
So fügen Sie AHB ein neues Pixelformat hinzu:
- Fügen Sie in
hardware_buffer.h
das neue Pixelformat als neuen Eintrag an das Ende desAHardwareBuffer_Format
-Eintrags hinzu. Beachten Sie die bestehenden Codekonventionen.Fügen Sie anhand des Beispiels für das Pixelformat
RGBA_8888
den neuen Eintrag für das Pixelformat so hinzu:/** * Corresponding formats: * Vulkan: VK_FORMAT_R8G8B8A8_UNORM * OpenGL ES: GL_RGBA8 */ AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM = 1,
Dem neuen Pixelformat wird in AHB ein Name zugewiesen, der mit
AHARDWAREBUFFER_FORMAT_
beginnen, gefolgt von den Kanalabkürzungen und Bittiefen und mit der Codierung enden muss. Dieser Enum-Eintrag muss denselben Hexadezimalwert wiePixelFormat.aidl
haben.Das Pixelformat muss mit einem oder beiden der Formate Vulkan oder OpenGL ES verknüpft sein. Geben Sie gegebenenfalls das zugehörige Format an. Wenn kein zugeordnetes Format vorhanden ist, geben Sie
N/A
an. -
Fügen Sie das Pixelformat den optionalen Tests unter CTS hinzu, wenn es ein zugehöriges OpenGL ES-Format hat. Fügen Sie dazu das neue GL-Format
AHardwareBufferGLTest.cpp
inAHBFormatAsString(int32_t format)
mitFORMAT_CASE(...)
undGL_FORMAT_CASE(...)
für das neue Format hinzu. Das sieht dann so aus:const char* AHBFormatAsString(int32_t format) { switch (format) { ... FORMAT_CASE(R8G8B8A8_UNORM); ... GL_FORMAT_CASE(GL_RGB8); } return ""; }
-
Fügen Sie als Nächstes
AHardwareBufferGLTest.cpp
einen neuen Test hinzu: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);
Geben Sie mindestens einen Satz von
AHardwareBuffer_Desc
-Werten an. Fügen Sie bei Bedarf weitere Werte hinzu. -
Suchen Sie in
AHardwareBuffer.cpp
nach dem Ende der statischen Assertions:// ---------------------------------------------------------------------------- // Validate hardware_buffer.h and PixelFormat.aidl agree // ----------------------------------------------------------------------------
Fügen Sie eine neue
static_assert
für das neue Pixelformat an, wobei Sie dasPixelFormat::
-Enum und nicht die KonstanteHAL_PIXEL_FORMAT
verwenden. Verwenden Sie dasselbe Beispiel für das PixelformatRGBA_8888
aus Add a new pixel format to AIDL (Neues Pixelformat zu AIDL hinzufügen), um den neuen Eintrag für das Pixelformat so hinzuzufügen:static_assert(static_cast
(aidl::android::hardware::graphics::common::PixelFormat::RGBA_8888) == AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM, "HAL and AHardwareBuffer pixel format don't match"); -
Fügen Sie das neue Pixelformat den entsprechenden Tests hinzu, indem Sie es in
AHardwareBufferTest.cpp
am Ende vonPrintAhbFormat()
anhängen. Beachten Sie die vorhandene Codekonvention, wie unten dargestellt:void PrintAhbFormat(std::ostream& os, uint64_t format) { switch (format) { ... FORMAT_CASE(R8G8B8A8_UNORM); default: os << "unknown"; break; } }
-
Fügen Sie das neue Pixelformat dem
HardwareBuffer
SDK inHardwareBuffer.java
hinzu: Fügen Sie@IntDef
einen neuen Eintrag hinzu. Der Eintrag für dasRGBA_8888
-Format sieht beispielsweise so aus:@Retention(RetentionPolicy.SOURCE) @IntDef(prefix = { "RGB", "BLOB", "YCBCR_", "D_", "DS_", "S_" }, value = { ... RGBA_8888, })
Wenn die Komponentenwerte nicht signaturlos normalisiert sind, geben Sie den Wert explizit im Variablennamen an. Beispiel: Der Variablenname für ein Format mit nur einem 16‑Bit-Rotkanal mit einer ungeprüften Ganzzahl muss
R_16UI
sein. Das gleiche Format mit einem zusätzlichen 16‑Bit-Grünkanal mit einer ungeprüften Ganzzahl mussRG_16UI16UI
sein. -
Fügen Sie das neue Pixelformat als
static int
inHardwareBuffer.java
hinzu, indem Sie am Ende von@Format
eine neue öffentliche Mitgliedsvariable anhängen:@Format ... /** Format: 8 bits each red, green, blue, alpha */ public static final int RGBA_8888 = 0x1;
Dieser Enum-Eintrag muss denselben Hexadezimalwert wie
PixelFormat.aidl
undhardware_buffer.h
haben. Beachten Sie die bestehenden Konventionen. -
Wenn Sie versuchen, mit diesen Codeänderungen zu erstellen, wird ein Buildfehler ausgegeben:
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. ****************************** ...
Führen Sie den folgenden Befehl aus, um
current.txt
zu ändern, wie in der Fehlermeldung angegeben, um diesen Fehler zu beheben:m api-stubs-docs-non-updatable-update-current-api
Durch Ausführen des Befehls oben wird die richtige Datei aktualisiert, damit der Build normal ausgeführt werden kann.
-
Fügen Sie das neue Pixelformat den Java-Tests hinzu, indem Sie es in
HardwareBufferTest.java
am Ende vonparamsForTestCreateOptionalFormats()
anhängen. Das sieht dann so aus:private static Object[] paramsForTestCreateOptionalFormats() { return new Integer[]{ HardwareBuffer.RGBA_8888 };
Fenstersystemintegration ein neues Pixelformat hinzufügen
Wenn Sie das neue Pixelformat als Format für einen Framebuffer in einer Grafik-API verwenden möchten, fügen Sie es der entsprechenden Window System Integration (WSI) für die entsprechende Grafik-API hinzu. Aktualisieren Sie für eine App oder einen Systemprozess, der die Vulkan API verwendet, die Vulkan-Swapchain. Aktualisieren Sie für eine App oder einen Systemprozess, der die OpenGL ES API verwendet, die EGL API.
Änderungen bei Vulkan-WSI für neue Pixelformate
Aktualisieren Sie die Vulkan-WSI so:-
Fügen Sie der Funktion
GetNativePixelFormat(VkFormat format)
inswapchain.cpp
einen neuen Fall hinzu: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; }
- Rufe die Vulkan-Erweiterung ab, wenn für das Pixelformat eine Vulkan-Erweiterung erforderlich ist.
Verwenden Sie beispielsweise
instance_data
für seitliche Erweiterungen, wie hier dargestellt:bool colorspace_ext = instance_data.hook_extensions.test(ProcHook::EXT_swapchain_colorspace);
Verwenden Sie für geräteseitige Erweiterungen Folgendes:
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 kümmert sich um die Infrastruktur, die erforderlich ist, um eine Instanz oder Geräteerweiterung für
swapchain.cpp
freizugeben. Die ursprüngliche Änderungsliste ist nicht erforderlich, damit die Erweiterungen vom Vulkan-Ladeprogramm richtig eingerichtet werden. - Geben Sie als Nächstes die Format- und Farbraumpaare an:
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}); }
Sie müssen die kompatiblen Format- und Farbraumpaare kennen.
- Fügen Sie das neue Format zu
dEQP-VK
unterexternal/deqp
hinzu. - Aktualisieren Sie die Vulkan-Konformitätstests in
vktApiExternalMemoryTests.cpp
undvktExternalMemoryUtil.cpp
. Ermitteln Sie dazu die erforderlichen Änderungen anhand der vorhandenen Quelle oder wenden Sie sich an den Android-Support.
EGL-Änderungen für neue Pixelformate
Aktualisieren Sie die EGL so:
- Ändern Sie in der Funktion
getNativePixelFormat()
denif-else
-Baum, damit das AIDL-Enum für das neue Pixelformat zurückgegeben wird. Beispiel für das PixelformatRGBA_8888
:if (a == 0) { ... } else { if (componentType == EGL_COLOR_COMPONENT_TYPE_FIXED_EXT) { if (colorDepth > 24) { ... } else { *format = PixelFormat::RGBA_8888; } } else { ... } }
- Wenn du dEQP das neue Format hinzufügen möchtest, füge dem Enum
androidFormats
einen neuen Eintrag hinzu:static const GLenum androidFormats[] = { ... GL_RGBA8, ... };
Update einreichen
Folgen Sie der Anleitung unter Für Mitwirkende, um Änderungslisten zu erstellen und mit dem entsprechenden Team zu teilen.