Wszystkie nowe formaty pikseli dodane do systemu Android muszą być uwzględnione w języku definicji interfejsu systemu Android (AIDL) i w buforze sprzętowym systemu Android (AHB) . AIDL i AHB mają rygorystyczne wymagania dotyczące stabilności i standaryzacji, które wymagają ostrożnego procesu przy rozszerzaniu funkcjonalności. Wszystkie nowe formaty pikseli muszą trafić do AOSP, a wszystkie aktualizacje muszą zostać indywidualnie potwierdzone przez ekspertów AIDL i AHB. Ten proces dokładnego potwierdzenia jest ważnym czynnikiem standaryzacji wszelkich nowych formatów pikseli na platformie.
Na tej stronie opisano niezbędne zmiany w kodzie AOSP i proces wymagany do dodania nowych formatów pikseli w AOSP.
Przed dodaniem nowego formatu pikseli pobierz źródło i prześlij poprawki zgodnie z opisem w sekcji Przesyłanie poprawek .Dodaj nowy format pikseli do AIDL
Dodanie obsługi nowego formatu pikseli wymaga zmian w obu plikach PixelFormat.aidl
znajdujących się w AIDL. Zobacz hardware/interfaces/graphics/common/aidl/
aby zapoznać się z kodem źródłowym AIDL.
Aby dodać nowy formalny piksel do AIDL, wykonaj następujące kroki:
- Dołącz nowy format pikseli jako nowy wpis na końcu wyliczenia
PixelFormat
w plikuPixelFormat.aidl
, postępując zgodnie z istniejącą konwencją kodu i ustawiając wartość szesnastkową wpisu o jeden większą niż poprzedni wpis. Dopasuj zmiany w kodzie do poprzednich wpisów. Zobacz następujący przykład wpisu w formacie pikseliRGBA_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,
Podczas tworzenia kodu po wprowadzeniu zmian w
PixelFormat.aidl
pojawia się następujący komunikat o błędzie: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.
Aby usunąć ten błąd, uruchom następujące polecenie zgodnie z komunikatem o błędzie, aby zmienić
PixelFormat.aidl
w kataloguaidl_api
:m android.hardware.graphics.common-update-api
Uruchomienie powyższego polecenia aktualizuje poprawny plik, aby móc normalnie budować.
Dodaj nowy format pikseli do AHB
Dodanie obsługi nowego formatu pikseli wymaga zmian w hardware_buffer.h
i AHardwareBuffer.cpp
. Zobacz frameworks/native/libs/nativewindow
aby zapoznać się z kodem źródłowym AHB.
Aby dodać nowy piksel formalny do AHB, wykonaj następujące kroki:
- W
hardware_buffer.h
dołącz nowy format pikseli jako nowy wpis na końcu wyliczeniaAHardwareBuffer_Format
. Postępuj zgodnie z istniejącymi konwencjami kodu.Korzystając z przykładowego formatu pikseli
RGBA_8888
, dodaj nowy wpis formatu pikseli w następujący sposób:/** * Corresponding formats: * Vulkan: VK_FORMAT_R8G8B8A8_UNORM * OpenGL ES: GL_RGBA8 */ AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM = 1,
Należy zauważyć, że nowy format pikseli ma nazwę w AHB, która musi zaczynać się od
AHARDWAREBUFFER_FORMAT_
, po której następują skróty kanałów i głębia bitowa, a kończyć na kodowaniu. Ten wpis wyliczeniowy musi mieć tę samą wartość szesnastkową, co wPixelFormat.aidl
.Oczekuje się, że format pikselowy będzie miał jeden lub oba powiązane formaty Vulkan lub OpenGL ES . W stosownych przypadkach określ powiązany format. Jeśli nie istnieje żaden powiązany format, określ
N/A
. Dodaj format pikselowy do opcjonalnych testów w ramach CTS, jeśli jest on powiązany z formatem OpenGL ES. Aby to zrobić, dodaj nowy format GL do
AHardwareBufferGLTest.cpp
wAHBFormatAsString(int32_t format)
zFORMAT_CASE(...)
iGL_FORMAT_CASE(...)
dla nowego formatu, jak pokazano poniżej:const char* AHBFormatAsString(int32_t format) { switch (format) { ... FORMAT_CASE(R8G8B8A8_UNORM); ... GL_FORMAT_CASE(GL_RGB8); } return ""; }
Następnie dodaj nowy test do
AHardwareBufferGLTest.cpp
, jak pokazano poniżej: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);
Określ co najmniej jeden zestaw wartości
AHardwareBuffer_Desc
. W razie potrzeby dodaj więcej wartości.W
AHardwareBuffer.cpp
znajdź koniec statycznych asercji znajdujących się w:// ---------------------------------------------------------------------------- // Validate hardware_buffer.h and PixelFormat.aidl agree // ----------------------------------------------------------------------------
Dołącz nowy
static_assert
dla nowego formatu pikseli, używając wyliczeniaPixelFormat::
, a nie stałejHAL_PIXEL_FORMAT
. Korzystając z tego samego przykładu dla formatu pikseliRGBA_8888
z Add a new pixel format to AIDL , dodaj nowy wpis formatu pikseli w następujący sposób:static_assert(static_cast
(aidl::android::hardware::graphics::common::PixelFormat::RGBA_8888) == AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM, "HAL and AHardwareBuffer pixel format don't match"); Dodaj nowy format pikseli do odpowiednich testów, dołączając nowy format pikseli na końcu
PrintAhbFormat()
wAHardwareBufferTest.cpp
. Postępuj zgodnie z istniejącą konwencją kodu, jak pokazano poniżej:void PrintAhbFormat(std::ostream& os, uint64_t format) { switch (format) { ... FORMAT_CASE(R8G8B8A8_UNORM); default: os << "unknown"; break; } }
Dodaj nowy format pikseli do zestawu SDK
HardwareBuffer
wHardwareBuffer.java
: dodając nowy wpis do@IntDef
. Na przykład wpis dla formatuRGBA_8888
jest pokazany w następujący sposób:@Retention(RetentionPolicy.SOURCE) @IntDef(prefix = { "RGB", "BLOB", "YCBCR_", "D_", "DS_", "S_" }, value = { ... RGBA_8888, })
Jeśli wartości komponentów nie są znormalizowane bez znaku, należy jawnie wskazać wartość w nazwie zmiennej. Na przykład nazwa zmiennej dla 16-bitowego formatu tylko kanału czerwonego na liczbach całkowitych bez znaku musi mieć postać
R_16UI
, a ten sam format z dodatkowym 16-bitowym formatem zielonego kanału na liczbach całkowitych bez znaku musi mieć postaćRG_16UI16UI
.Dodaj nowy format pikseli jako
static int
wHardwareBuffer.java
, dołączając nową publiczną zmienną składową na końcu@Format
:@Format ... /** Format: 8 bits each red, green, blue, alpha */ public static final int RGBA_8888 = 0x1;
Ten wpis wyliczeniowy musi mieć tę samą wartość szesnastkową, co wartość z
PixelFormat.aidl
ihardware_buffer.h
. Postępuj zgodnie z obowiązującymi konwencjami.- Próba kompilacji z tymi zmianami w kodzie generuje błąd kompilacji:
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. ****************************** ...
Aby usunąć ten błąd, uruchom następujące polecenie zgodnie z komunikatem o błędzie, aby zmienić
current.txt
:m api-stubs-docs-non-updatable-update-current-api
Uruchomienie powyższego polecenia aktualizuje poprawny plik, aby móc normalnie budować.
Dodaj nowy format pikseli do testów Java, dołączając nowy format pikseli na końcu
paramsForTestCreateOptionalFormats()
wHardwareBufferTest.java
, jak pokazano poniżej:private static Object[] paramsForTestCreateOptionalFormats() { return new Integer[]{ HardwareBuffer.RGBA_8888 };
Dodaj nowy format pikseli do integracji systemu Windows
Aby użyć nowego formatu pikseli jako formatu bufora ramki w graficznym interfejsie API, dodaj go do odpowiedniego modułu Windows System Integration (WSI) dla odpowiedniego graficznego interfejsu API. W przypadku aplikacji lub procesu systemowego korzystającego z interfejsu API Vulkan zaktualizuj Vulkan Swapchain. W przypadku aplikacji lub procesu systemowego korzystającego z interfejsu API OpenGL ES zaktualizuj interfejs API EGL .
Zmiany w Vulkan WSI dla nowych formatów pikseli Zaktualizuj Vulkan WSI w następujący sposób: Dodaj nową skrzynkę do funkcji GetNativePixelFormat(VkFormat format)
w swapchain.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;
}
- Zapytaj o rozszerzenie Vulkan, jeśli format piksela wymaga do działania rozszerzenia Vulkan. Na przykład rozszerzenia boczne użyj
instance_data
, pokazanej poniżej:
bool colorspace_ext = instance_data.hook_extensions.test(ProcHook::EXT_swapchain_colorspace);
W przypadku rozszerzeń po stronie urządzenia użyj następujących poleceń:
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 obsługuje infrastrukturę wymaganą do udostępnienia instancji lub rozszerzenia urządzenia swapchain.cpp
. Początkowa lista zmian nie jest wymagana do prawidłowej konfiguracji rozszerzeń z poziomu modułu ładującego Vulkan.
- Następnie wylicz pary formatu i przestrzeni kolorów:
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});
}
Wymagana jest wiedza na temat zgodnych formatów i par przestrzeni kolorów.
- Dodaj nowy format do
dEQP-VK
znajdującego się w external/deqp
. - Zaktualizuj testy zgodności Vulkan w
vktApiExternalMemoryTests.cpp
i vktExternalMemoryUtil.cpp
, wnioskując o wymaganych zmianach z istniejącego źródła lub kontaktując się z pomocą techniczną systemu Android w celu uzyskania informacji.
Zmiany EGL dla nowych formatów pikseli
Dodaj nową skrzynkę do funkcji GetNativePixelFormat(VkFormat format)
w swapchain.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; }
instance_data
, pokazanej poniżej:bool colorspace_ext = instance_data.hook_extensions.test(ProcHook::EXT_swapchain_colorspace);
W przypadku rozszerzeń po stronie urządzenia użyj następujących poleceń:
bool rgba10x6_formats_ext = false; uint32_t exts_count; const auto& driver = GetData(pdev).driver; driver.EnumerateDeviceExtensionProperties(pdev, nullptr, &exts_count, nullptr); std::vectorprops(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 obsługuje infrastrukturę wymaganą do udostępnienia instancji lub rozszerzenia urządzenia swapchain.cpp
. Początkowa lista zmian nie jest wymagana do prawidłowej konfiguracji rozszerzeń z poziomu modułu ładującego Vulkan.
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}); }
Wymagana jest wiedza na temat zgodnych formatów i par przestrzeni kolorów.
dEQP-VK
znajdującego się w external/deqp
.vktApiExternalMemoryTests.cpp
i vktExternalMemoryUtil.cpp
, wnioskując o wymaganych zmianach z istniejącego źródła lub kontaktując się z pomocą techniczną systemu Android w celu uzyskania informacji.Zaktualizuj EGL w następujący sposób:
- W funkcji
getNativePixelFormat()
zmodyfikuj drzewoif-else
, aby zwrócić wyliczenie AIDL dla nowego formatu pikseli. Używając przykładu dla formatu pikseliRGBA_8888
:if (a == 0) { ... } else { if (componentType == EGL_COLOR_COMPONENT_TYPE_FIXED_EXT) { if (colorDepth > 24) { ... } else { *format = PixelFormat::RGBA_8888; } } else { ... } }
- Aby dodać nowy format do dEQP, dodaj nowy wpis do wyliczenia
androidFormats
, pokazany poniżej:static const GLenum androidFormats[] = { ... GL_RGBA8, ... };
Prześlij swoją aktualizację
Obserwuj Aby współpracownicy mogli uporządkować swoje listy zmian i udostępnić je odpowiedniemu zespołowi.