Semua format piksel baru yang ditambahkan ke Android harus disertakan dalam Android Interface Definition Language (AIDL) dan Android Hardware Buffer (AHB) . AIDL dan AHB memiliki persyaratan stabilitas dan standardisasi yang ketat sehingga memerlukan proses yang hati-hati saat memperluas fungsionalitas. Semua format piksel baru harus ada di AOSP dan semua pembaruan harus dikonfirmasi secara individual oleh pakar AIDL dan AHB. Proses konfirmasi yang cermat ini merupakan faktor penting dalam standarisasi format piksel baru pada platform.
Halaman ini menguraikan perubahan kode AOSP yang diperlukan dan proses yang diperlukan untuk menambahkan format piksel baru pada AOSP.
Sebelum menambahkan format piksel baru, unduh sumber dan unggah tambalan seperti yang dijelaskan dalam Mengirimkan tambalan .Tambahkan format piksel baru ke AIDL
Menambahkan dukungan untuk format piksel baru memerlukan perubahan pada kedua file PixelFormat.aidl
yang terletak di dalam AIDL. Lihat hardware/interfaces/graphics/common/aidl/
untuk kode sumber AIDL.
Untuk menambahkan piksel formal baru ke AIDL, ikuti langkah-langkah berikut:
- Tambahkan format piksel baru sebagai entri baru ke akhir enum
PixelFormat
diPixelFormat.aidl
dengan mengikuti konvensi kode yang ada dan atur nilai hex untuk entri Anda menjadi satu lebih banyak dari entri sebelumnya. Cocokkan perubahan kode Anda dengan entri sebelumnya. Lihat contoh berikut untuk entri format pikselRGBA_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,
Pesan kesalahan berikut terlihat ketika Anda membuat kode setelah melakukan perubahan pada
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.
Untuk mengatasi kesalahan ini, jalankan perintah berikut, seperti yang ditentukan dalam pesan kesalahan, untuk mengubah
PixelFormat.aidl
di direktoriaidl_api
:m android.hardware.graphics.common-update-api
Menjalankan perintah di atas akan memperbarui file yang benar agar dapat dibangun secara normal.
Tambahkan format piksel baru ke AHB
Menambahkan dukungan untuk format piksel baru memerlukan perubahan pada hardware_buffer.h
dan AHardwareBuffer.cpp
. Lihat frameworks/native/libs/nativewindow
untuk kode sumber AHB.
Untuk menambahkan piksel formal baru ke AHB, ikuti langkah-langkah berikut:
- Di
hardware_buffer.h
, tambahkan format piksel baru sebagai entri baru di akhir enumAHardwareBuffer_Format
. Ikuti konvensi kode yang ada.Dengan menggunakan contoh format piksel
RGBA_8888
, tambahkan entri format piksel baru sebagai berikut:/** * Corresponding formats: * Vulkan: VK_FORMAT_R8G8B8A8_UNORM * OpenGL ES: GL_RGBA8 */ AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM = 1,
Perhatikan bahwa format piksel baru diberi nama dalam AHB, yang harus dimulai dengan
AHARDWAREBUFFER_FORMAT_
, diikuti dengan singkatan saluran dan kedalaman bit, dan diakhiri dengan pengkodean. Entri enum ini harus memiliki nilai hex yang sama denganPixelFormat.aidl
.Format piksel diharapkan memiliki salah satu atau kedua format Vulkan atau OpenGL ES yang terkait. Tentukan format terkait jika sesuai. Jika tidak ada format terkait, tentukan
N/A
. Tambahkan format piksel ke pengujian opsional pada CTS, jika format tersebut memiliki format OpenGL ES yang terkait. Untuk melakukannya, tambahkan format GL baru ke
AHardwareBufferGLTest.cpp
dalamAHBFormatAsString(int32_t format)
denganFORMAT_CASE(...)
danGL_FORMAT_CASE(...)
untuk format baru, ditampilkan sebagai berikut:const char* AHBFormatAsString(int32_t format) { switch (format) { ... FORMAT_CASE(R8G8B8A8_UNORM); ... GL_FORMAT_CASE(GL_RGB8); } return ""; }
Selanjutnya, tambahkan pengujian baru ke
AHardwareBufferGLTest.cpp
, yang ditampilkan sebagai berikut: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);
Tentukan setidaknya satu set nilai
AHardwareBuffer_Desc
. Tambahkan lebih banyak nilai jika diperlukan.Di
AHardwareBuffer.cpp
, temukan akhir dari pernyataan statis yang ditemukan di dalam:// ---------------------------------------------------------------------------- // Validate hardware_buffer.h and PixelFormat.aidl agree // ----------------------------------------------------------------------------
Tambahkan
static_assert
baru untuk format piksel baru, menggunakanPixelFormat::
enum dan bukan dengan konstantaHAL_PIXEL_FORMAT
. Menggunakan contoh yang sama untuk format pikselRGBA_8888
dari Tambahkan format piksel baru ke AIDL , tambahkan entri format piksel baru sebagai berikut:static_assert(static_cast
(aidl::android::hardware::graphics::common::PixelFormat::RGBA_8888) == AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM, "HAL and AHardwareBuffer pixel format don't match"); Tambahkan format piksel baru ke pengujian yang sesuai, dengan menambahkan format piksel baru ke akhir
PrintAhbFormat()
diAHardwareBufferTest.cpp
. Ikuti konvensi kode yang ada, seperti yang ditunjukkan di bawah ini:void PrintAhbFormat(std::ostream& os, uint64_t format) { switch (format) { ... FORMAT_CASE(R8G8B8A8_UNORM); default: os << "unknown"; break; } }
Tambahkan format piksel baru ke
HardwareBuffer
SDK diHardwareBuffer.java
: dengan menambahkan entri baru ke@IntDef
. Misalnya, entri untuk formatRGBA_8888
ditampilkan sebagai berikut:@Retention(RetentionPolicy.SOURCE) @IntDef(prefix = { "RGB", "BLOB", "YCBCR_", "D_", "DS_", "S_" }, value = { ... RGBA_8888, })
Jika nilai komponen tidak dinormalisasi, maka tunjukkan nilai secara eksplisit dalam nama variabel. Misalnya, nama variabel untuk format saluran merah 16-bit integer unsigned saja harus
R_16UI
, dan format yang sama dengan format saluran hijau 16-bit integer unsigned tambahan harusRG_16UI16UI
.Tambahkan format piksel baru sebagai
static int
diHardwareBuffer.java
, dengan menambahkan variabel anggota publik baru di akhir@Format
:@Format ... /** Format: 8 bits each red, green, blue, alpha */ public static final int RGBA_8888 = 0x1;
Entri enum ini harus memiliki nilai hex yang sama dengan nilai dari
PixelFormat.aidl
danhardware_buffer.h
. Ikuti konvensi yang ada.- Mencoba membangun dengan perubahan kode ini menghasilkan kesalahan pembangunan:
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. ****************************** ...
Untuk mengatasi kesalahan ini, jalankan perintah berikut, seperti yang ditentukan dalam pesan kesalahan, untuk mengubah
current.txt
:m api-stubs-docs-non-updatable-update-current-api
Menjalankan perintah di atas akan memperbarui file yang benar agar dapat dibangun secara normal.
Tambahkan format piksel baru ke pengujian Java, dengan menambahkan format piksel baru ke akhir
paramsForTestCreateOptionalFormats()
diHardwareBufferTest.java
, yang ditampilkan sebagai berikut:private static Object[] paramsForTestCreateOptionalFormats() { return new Integer[]{ HardwareBuffer.RGBA_8888 };
Tambahkan format piksel baru ke integrasi Sistem Jendela
Untuk menggunakan format piksel baru sebagai format framebuffer di API grafis, tambahkan format tersebut ke Integrasi Sistem Jendela (WSI) yang sesuai untuk API grafis yang relevan. Untuk aplikasi atau proses sistem yang menggunakan Vulkan API, perbarui Vulkan Swapchain. Untuk aplikasi atau proses sistem yang menggunakan OpenGL ES API, perbarui EGL API.
Perubahan Vulkan WSI untuk format piksel baru Perbarui Vulkan WSI sebagai berikut: Tambahkan kasus baru ke fungsi GetNativePixelFormat(VkFormat format)
di 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;
}
- Kueri ekstensi Vulkan jika format piksel memerlukan ekstensi Vulkan agar berfungsi. Misalnya ekstensi samping, gunakan
instance_data
, yang ditampilkan sebagai berikut:
bool colorspace_ext = instance_data.hook_extensions.test(ProcHook::EXT_swapchain_colorspace);
Untuk ekstensi sisi perangkat, gunakan yang berikut ini:
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 menangani infrastruktur yang diperlukan untuk mengekspos sebuah instance atau ekstensi perangkat ke swapchain.cpp
. Daftar perubahan awal tidak diperlukan agar ekstensi dikonfigurasi dengan benar dari pemuat Vulkan.
- Selanjutnya, sebutkan pasangan format dan ruang warna:
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});
}
Anda harus memiliki pengetahuan tentang format dan pasangan ruang warna yang kompatibel.
- Tambahkan format baru ke
dEQP-VK
yang terletak di external/deqp
. - Perbarui Pengujian Kesesuaian Vulkan di
vktApiExternalMemoryTests.cpp
dan vktExternalMemoryUtil.cpp
dengan menyimpulkan perubahan yang diperlukan dari sumber yang ada atau menghubungi dukungan Android Anda untuk mendapatkan informasi.
Perubahan EGL untuk format piksel baru
Tambahkan kasus baru ke fungsi GetNativePixelFormat(VkFormat format)
di 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
, yang ditampilkan sebagai berikut:bool colorspace_ext = instance_data.hook_extensions.test(ProcHook::EXT_swapchain_colorspace);
Untuk ekstensi sisi perangkat, gunakan yang berikut ini:
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 menangani infrastruktur yang diperlukan untuk mengekspos sebuah instance atau ekstensi perangkat ke swapchain.cpp
. Daftar perubahan awal tidak diperlukan agar ekstensi dikonfigurasi dengan benar dari pemuat 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}); }
Anda harus memiliki pengetahuan tentang format dan pasangan ruang warna yang kompatibel.
dEQP-VK
yang terletak di external/deqp
.vktApiExternalMemoryTests.cpp
dan vktExternalMemoryUtil.cpp
dengan menyimpulkan perubahan yang diperlukan dari sumber yang ada atau menghubungi dukungan Android Anda untuk mendapatkan informasi.Perbarui EGL sebagai berikut:
- Dalam fungsi
getNativePixelFormat()
, ubah pohonif-else
untuk mengembalikan enum AIDL untuk format piksel baru. Menggunakan contoh untuk format pikselRGBA_8888
:if (a == 0) { ... } else { if (componentType == EGL_COLOR_COMPONENT_TYPE_FIXED_EXT) { if (colorDepth > 24) { ... } else { *format = PixelFormat::RGBA_8888; } } else { ... } }
- Untuk menambahkan format baru ke dEQP, tambahkan entri baru ke enum
androidFormats
, yang ditampilkan sebagai berikut:static const GLenum androidFormats[] = { ... GL_RGBA8, ... };
Kirim pembaruan Anda
Ikuti Untuk kontributor untuk membuat daftar perubahan Anda dan membaginya dengan tim yang sesuai.