Tất cả các định dạng pixel mới được thêm vào Android phải được đưa vào Ngôn ngữ định nghĩa giao diện Android (AIDL) và trong Bộ đệm phần cứng Android (AHB) . AIDL và AHB có các yêu cầu nghiêm ngặt về tính ổn định và tiêu chuẩn hóa, đòi hỏi phải có 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 và tất cả các bản cập nhật phải được các chuyên gia AIDL và AHB xác nhận riêng lẻ. Quá trình xác nhận cẩn thận này là một yếu tố quan trọng trong việc chuẩn hóa mọi định dạng pixel mới trên nền tảng.
Trang này phác thảo những thay đổi mã AOSP cần thiết và quy trình cần thiết để thêm các đị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 lên các bản vá như được nêu trong Gửi bản vá .Thêm định dạng pixel mới vào AIDL
Việc thêm hỗ trợ cho định dạng pixel mới yêu cầu thay đổi đối với cả hai tệp PixelFormat.aidl
nằm trong AIDL. Xem hardware/interfaces/graphics/common/aidl/
để biết mã nguồn AIDL.
Để thêm pixel chính thức 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ục nhập mới vào cuối enum
PixelFormat
trongPixelFormat.aidl
bằng cách tuân theo quy ước mã hiện có và đặt giá trị hex cho mục nhập của bạn lớn hơn một mục nhập trước đó. Khớp các thay đổi mã của bạn với các mục trước đó. Xem ví dụ sau để biết 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,
Thông báo lỗi sau đây xuất hiện khi bạn tạo mã sau khi thực hiện các thay đổi đối với
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.
Để xóa 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
Chạy lệnh trên sẽ cập nhật đúng file để có thể build bình thường.
Thêm định dạng pixel mới vào AHB
Việc thêm hỗ trợ cho định dạng pixel mới yêu cầu thay đổi đối với hardware_buffer.h
và AHardwareBuffer.cpp
. Xem frameworks/native/libs/nativewindow
để biết mã nguồn AHB.
Để thêm pixel chính thức 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 làm mục nhập mới vào cuối enumAHardwareBuffer_Format
. Thực hiện theo các quy ước mã hiện có.Sử dụng ví dụ về định dạng pixel
RGBA_8888
, 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,
Lưu ý rằng định dạng pixel mới được đặt tên bằng AHB, tên này phải bắt đầu bằng
AHARDWAREBUFFER_FORMAT_
, theo sau là tên viết tắt của kênh và độ sâu bit và kết thúc bằng mã hóa. Mục nhập enum này phải có cùng giá trị hex như 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 được liên kết. Chỉ định định dạng liên quan khi thích hợp. Nếu không có định dạng liên quan nào tồn tại, hãy chỉ định
N/A
. Thêm định dạng pixel vào thử nghiệm tùy chọn trong CTS, nếu nó có định dạng OpenGL ES được liên kết. Để 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 hiển thị như sau:const char* AHBFormatAsString(int32_t format) { switch (format) { ... FORMAT_CASE(R8G8B8A8_UNORM); ... GL_FORMAT_CASE(GL_RGB8); } return ""; }
Tiếp theo, thêm một thử nghiệm mới vào
AHardwareBufferGLTest.cpp
, hiển thị 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);
Chỉ định ít nhất một bộ giá trị
AHardwareBuffer_Desc
. Thêm nhiều giá trị hơn nếu cần.Trong
AHardwareBuffer.cpp
, tìm phần cuối của các xác nhận tĩnh được tìm thấy trong:// ---------------------------------------------------------------------------- // Validate hardware_buffer.h and PixelFormat.aidl agree // ----------------------------------------------------------------------------
Thêm một
static_assert
mới cho định dạng pixel mới, sử dụngPixelFormat::
enum chứ không phải với hằng sốHAL_PIXEL_FORMAT
. Sử dụng ví dụ tương tự cho định dạng pixelRGBA_8888
từ 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 thử nghiệm thích hợp bằng cách thêm định dạng pixel mới vào cuối
PrintAhbFormat()
trongAHardwareBufferTest.cpp
. Thực hiện theo quy ước mã hiện có, như được hiển thị bên dưới: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 các giá trị thành phần không được chuẩn hóa không dấu thì hãy chỉ ra 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 không dấu phải là
R_16UI
và định dạng tương tự với định dạng kênh màu xanh lục 16 bit số nguyên không dấu 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ị hex từ
PixelFormat.aidl
vàhardware_buffer.h
. Thực hiện theo các quy ước hiện có.- Việc cố gắng xây dựng bằng những thay đổi mã này sẽ tạo ra lỗi xây dựng:
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. ****************************** ...
Để xóa 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
Chạy lệnh trên sẽ cập nhật đúng file để có thể build bình thường.
Thêm định dạng pixel mới vào các thử nghiệm Java, bằng cách thêm định dạng pixel mới vào cuối
paramsForTestCreateOptionalFormats()
trongHardwareBufferTest.java
, được hiển thị như sau:private static Object[] paramsForTestCreateOptionalFormats() { return new Integer[]{ HardwareBuffer.RGBA_8888 };
Thêm định dạng pixel mới vào 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 bộ đệm khung trong API đồ họa, hãy thêm nó vào Tích hợp hệ thống cửa sổ (WSI) thích hợp cho API đồ họa có liên quan. Đối với một ứng dụng hoặc quy trình hệ thống sử dụng API Vulkan, hãy cập nhật Vulkan Swapchain. Đối với một ứng dụng hoặc quy trình hệ thống sử dụng API OpenGL ES, hãy cập nhật API EGL .
Vulkan WSI thay đổi cho các định dạng pixel mới Cập nhật Vulkan WSI như sau: Thêm một trường hợp mới vào hàm GetNativePixelFormat(VkFormat format)
trong 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;
}
- Truy vấn tiện ích mở rộng Vulkan nếu định dạng pixel yêu cầu tiện ích mở rộng Vulkan hoạt động. Đối với các phần mở rộng bên của phiên bản, hãy sử dụng
instance_data
, được hiển thị như sau:
bool colorspace_ext = instance_data.hook_extensions.test(ProcHook::EXT_swapchain_colorspace);
Đối với tiện ích mở rộng phía thiết bị, hãy sử dụng như 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 phiên bản hoặc tiện ích mở rộng thiết bị cho swapchain.cpp
. Danh sách thay đổi ban đầu không bắt buộc phải có các tiện ích mở rộng được thiết lập chính xác từ trình tải Vulkan.
- Tiếp theo, 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 ở external/deqp
. - Cập nhật Kiểm tra sự phù hợp của Vulkan trong
vktApiExternalMemoryTests.cpp
và vktExternalMemoryUtil.cpp
bằng cách suy ra những thay đổi bắt buộc từ nguồn hiện có hoặc liên hệ với bộ phận hỗ trợ Android của bạn để biết thông tin.
Thay đổi EGL cho các định dạng pixel mới
Thêm một trường hợp mới vào hàm GetNativePixelFormat(VkFormat format)
trong 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
, được hiển thị như sau:bool colorspace_ext = instance_data.hook_extensions.test(ProcHook::EXT_swapchain_colorspace);
Đối với tiện ích mở rộng phía thiết bị, hãy sử dụng như sau:
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 xử lý cơ sở hạ tầng cần thiết để hiển thị một phiên bản hoặc tiện ích mở rộng thiết bị cho swapchain.cpp
. Danh sách thay đổi ban đầu không bắt buộc phải có các tiện ích mở rộng được thiết lập chính xác từ trình tải 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}); }
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.
dEQP-VK
nằm ở external/deqp
.vktApiExternalMemoryTests.cpp
và vktExternalMemoryUtil.cpp
bằng cách suy ra những thay đổi bắt buộc từ nguồn hiện có hoặc liên hệ với bộ phận hỗ trợ Android của bạn để biết thông tin.Cập nhật EGL như sau:
- Trong hàm
getNativePixelFormat()
, hãy sửa đổi 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ục nhập mới vào enum
androidFormats
, hiển thị như sau:static const GLenum androidFormats[] = { ... GL_RGBA8, ... };
Gửi bản cập nhật của bạn
Theo dõi Dành cho những người đóng góp để cập nhật danh sách thay đổi của bạn và chia sẻ chúng với nhóm thích hợp.