Tất cả các định dạng pixel mới được thêm vào Android phải được bao gồm trong Ngôn ngữ định nghĩa giao diện Android (AIDL) và trong Vùng đệm phần cứng Android (AHB). AIDL và AHB có các yêu cầu nghiêm ngặt về độ ổn định và chuẩn hoá, đòi hỏi một quy trình cẩn thận khi mở rộng chức năng. Tất cả các định dạng pixel mới phải có trong AOSP (Dự án nguồn mở Android) đồng thời mọi nội dung cập nhật đều phải được các chuyên gia AIDL và AHB xác nhận riêng. Đây là quá trình xem xét kỹ là một yếu tố quan trọng trong việc chuẩn hoá bất kỳ định dạng pixel mới nào trên chủ.
Trang này trình bày AOSP cần thiết thay đổi mã và quy trình cần thiết để thêm định dạng pixel mới trên AOSP.
Trước khi thêm định dạng pixel mới, hãy tải xuống nguồn và tải bản vá lên như được nêu trong Gửi bản vá.Thêm định dạng pixel mới vào AIDL
Để thêm tính năng hỗ trợ cho một định dạng pixel mới, bạn cần thay đổi cả hai tệp PixelFormat.aidl
nằm trong AIDL. Xem
hardware/interfaces/graphics/common/aidl/
cho mã nguồn AIDL.
Để thêm một pixel mới vào AIDL, hãy làm theo các bước sau:
- Thêm định dạng pixel mới dưới dạng một mục mới vào cuối enum
PixelFormat
trongPixelFormat.aidl
bằng cách làm theo quy ước mã hiện có và đặt giá trị hex cho mục nhập của bạn là một so với mục nhập trước đó. So khớp các thay đổi về mã với các mục nhập trước đó. Hãy xem ví dụ sau đây về mục nhập định dạng 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,
Bạn sẽ thấy thông báo lỗi sau đây khi tạo mã sau khi thực hiện các thay đổi đối với
PixelFormat.aidl
: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.
-
Để xoá lỗi này, hãy chạy lệnh sau, như được chỉ định trong thông báo lỗi, để thay đổi
PixelFormat.aidl
trong thư mụcaidl_api
:m android.hardware.graphics.common-update-api
Việc chạy lệnh trên sẽ cập nhật đúng tệp để có thể tạo bản dựng bình thường.
Thêm định dạng pixel mới vào AHB
Để thêm tính năng hỗ trợ cho định dạng pixel mới, bạn phải thay đổi thành
hardware_buffer.h
và AHardwareBuffer.cpp
.
Xem frameworks/native/libs/nativewindow
cho mã nguồn AHB.
Để thêm một pixel mới vào AHB, hãy làm theo các bước sau:
- Trong
hardware_buffer.h
, hãy thêm định dạng pixel mới dưới dạng một mục mới vào cuối enumAHardwareBuffer_Format
. Tuân theo các quy ước mã hiện có.Sử dụng ví dụ về định dạng pixel
RGBA_8888
, hãy thêm mục nhập định dạng pixel mới như sau:/** * Corresponding formats: * Vulkan: VK_FORMAT_R8G8B8A8_UNORM * OpenGL ES: GL_RGBA8 */ AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM = 1,
Xin lưu ý rằng định dạng pixel mới được đặt tên trong AHB, tên này phải bắt đầu bằng
AHARDWAREBUFFER_FORMAT_
, theo sau là các chữ viết tắt của kênh và độ sâu bit, rồi kết thúc bằng mã hoá. Mục nhập enum này phải có giá trị thập lục phân giống như giá trị trongPixelFormat.aidl
.Định dạng pixel dự kiến sẽ có một hoặc cả hai định dạng Vulkan hoặc OpenGL ES liên kết. Chỉ định định dạng được liên kết khi thích hợp. Nếu không có định dạng được liên kết nào, hãy chỉ định
N/A
. -
Thêm định dạng pixel vào quy trình kiểm thử không bắt buộc trong CTS, nếu định dạng đó có liên kết với định dạng OpenGL ES. Để thực hiện việc này, hãy thêm định dạng GL mới vào
AHardwareBufferGLTest.cpp
trongAHBFormatAsString(int32_t format)
vớiFORMAT_CASE(...)
vàGL_FORMAT_CASE(...)
cho định dạng mới, được minh hoạ như sau:const char* AHBFormatAsString(int32_t format) { switch (format) { ... FORMAT_CASE(R8G8B8A8_UNORM); ... GL_FORMAT_CASE(GL_RGB8); } return ""; }
-
Tiếp theo, hãy thêm một kiểm thử mới vào
AHardwareBufferGLTest.cpp
, như sau: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);
Hãy chỉ định ít nhất một nhóm giá trị
AHardwareBuffer_Desc
. Thêm các giá trị khác nếu cần. -
Trong
AHardwareBuffer.cpp
, hãy tìm phần cuối của các xác nhận tĩnh có trong:// ---------------------------------------------------------------------------- // Validate hardware_buffer.h and PixelFormat.aidl agree // ----------------------------------------------------------------------------
Thêm
static_assert
mới cho định dạng pixel mới, sử dụng phương thức enumPixelFormat::
chứ không phải với hằng sốHAL_PIXEL_FORMAT
. Sử dụng cùng một ví dụ cho định dạng pixelRGBA_8888
từ phần Thêm định dạng pixel mới vào AIDL, thêm mục nhập định dạng pixel mới như sau:static_assert(static_cast
(aidl::android::hardware::graphics::common::PixelFormat::RGBA_8888) == AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM, "HAL and AHardwareBuffer pixel format don't match"); -
Thêm định dạng pixel mới vào các bài kiểm thử thích hợp bằng cách thêm định dạng pixel mới vào cuối
PrintAhbFormat()
trongAHardwareBufferTest.cpp
. Tuân theo quy ước mã hiện có, như minh hoạ dưới đây:void PrintAhbFormat(std::ostream& os, uint64_t format) { switch (format) { ... FORMAT_CASE(R8G8B8A8_UNORM); default: os << "unknown"; break; } }
-
Thêm định dạng pixel mới vào SDK
HardwareBuffer
trongHardwareBuffer.java
: bằng cách thêm một mục mới vào@IntDef
. Ví dụ: mục nhập cho Định dạngRGBA_8888
được hiển thị như sau:@Retention(RetentionPolicy.SOURCE) @IntDef(prefix = { "RGB", "BLOB", "YCBCR_", "D_", "DS_", "S_" }, value = { ... RGBA_8888, })
Nếu giá trị thành phần không được chuẩn hoá chưa ký, hãy chỉ định giá trị một cách rõ ràng trong tên biến. Ví dụ: tên biến cho định dạng chỉ kênh màu đỏ 16 bit số nguyên chưa ký phải là
R_16UI
và cùng định dạng với định dạng kênh màu xanh lục 16 bit số nguyên chưa ký bổ sung phải làRG_16UI16UI
. -
Thêm định dạng pixel mới dưới dạng
static int
trongHardwareBuffer.java
bằng cách thêm một biến thành viên công khai mới vào cuối@Format
:@Format ... /** Format: 8 bits each red, green, blue, alpha */ public static final int RGBA_8888 = 0x1;
Mục nhập enum này phải có cùng giá trị hex với giá trị trong
PixelFormat.aidl
vàhardware_buffer.h
. Tuân thủ các quy ước hiện có. -
Nếu cố gắng tạo bản dựng bằng các thay đổi mã này, bạn sẽ gặp lỗi bản dựng:
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. ****************************** ...
Để xoá lỗi này, hãy chạy lệnh sau, như được chỉ định trong thông báo lỗi, để thay đổi
current.txt
:m api-stubs-docs-non-updatable-update-current-api
Việc chạy lệnh trên sẽ cập nhật đúng tệp để có thể tạo bản dựng bình thường.
-
Thêm định dạng pixel mới vào các chương trình kiểm thử Java bằng cách thêm định dạng pixel mới vào cuối
paramsForTestCreateOptionalFormats()
trongHardwareBufferTest.java
, như sau:private static Object[] paramsForTestCreateOptionalFormats() { return new Integer[]{ HardwareBuffer.RGBA_8888 };
Thêm định dạng pixel mới vào tính năng tích hợp Hệ thống cửa sổ
Để sử dụng định dạng pixel mới làm định dạng cho vùng đệm khung trong Graphics API (API đồ hoạ), hãy thêm API này vào công cụ Tích hợp hệ thống cửa sổ (WSI) thích hợp để Graphics API (API đồ hoạ). Đối với ứng dụng hoặc quy trình hệ thống dùng API Vulkan, hãy cập nhật Chuỗi hoán đổi Vulkan. Đối với ứng dụng hoặc quy trình hệ thống sử dụng API OpenGL ES, hãy cập nhật EGL.
Các thay đổi đối với Vulkan WSI đối với các định dạng pixel mới
Cập nhật WSI trong Vulkan như sau:-
Thêm một trường hợp mới vào hàm
GetNativePixelFormat(VkFormat format)
trongswapchain.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; }
- Truy vấn tiện ích Vulkan nếu định dạng pixel yêu cầu tiện ích Vulkan để hoạt động.
Ví dụ: các tiện ích bên, sử dụng
instance_data
, như sau:bool colorspace_ext = instance_data.hook_extensions.test(ProcHook::EXT_swapchain_colorspace);
Đối với các tiện ích phía thiết bị, hãy sử dụng các thông tin sau:
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 xử lý cơ sở hạ tầng cần thiết để hiển thị một thực thể hoặc tiện ích thiết bị thành
swapchain.cpp
. Bạn không cần danh sách thay đổi ban đầu để thiết lập đúng cách các tiện ích từ trình tải Vulkan. - Tiếp theo, hãy liệt kê các cặp định dạng và không gian màu:
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}); }
Bạn phải có kiến thức về các cặp định dạng và không gian màu tương thích.
- Thêm định dạng mới vào
dEQP-VK
nằm tạiexternal/deqp
. - Cập nhật quy trình Kiểm thử tuân thủ Vulkan trong
vktApiExternalMemoryTests.cpp
vàvktExternalMemoryUtil.cpp
bằng cách suy luận các thay đổi bắt buộc từ nguồn hiện có hoặc liên hệ với nhóm hỗ trợ Android để biết thông tin.
Thay đổi EGL cho các định dạng pixel mới
Cập nhật EGL như sau:
- Trong
getNativePixelFormat()
hãy chỉnh sửa câyif-else
để trả về enum AIDL cho định dạng pixel mới. Sử dụng ví dụ cho định dạng pixelRGBA_8888
:if (a == 0) { ... } else { if (componentType == EGL_COLOR_COMPONENT_TYPE_FIXED_EXT) { if (colorDepth > 24) { ... } else { *format = PixelFormat::RGBA_8888; } } else { ... } }
- Để thêm định dạng mới vào dEQP, hãy thêm một mục mới vào enum
androidFormats
, như sau:static const GLenum androidFormats[] = { ... GL_RGBA8, ... };
Gửi nội dung cập nhật
Theo dõi Dành cho người đóng góp để tổng hợp danh sách thay đổi của bạn và chia sẻ chúng với nhóm phù hợp.