รูปแบบพิกเซลใหม่ทั้งหมดที่เพิ่มลงใน Android จะต้องรวมอยู่ใน Android Interface Definition Language (AIDL) และใน Android Hardware Buffer (AHB) AIDL และ AHB มีข้อกำหนดด้านเสถียรภาพและมาตรฐานที่เข้มงวด ซึ่งจำเป็นต้องมีกระบวนการที่ระมัดระวังเมื่อขยายฟังก์ชันการทำงาน รูปแบบพิกเซลใหม่ทั้งหมดจะต้องลงจอดใน AOSP และการอัปเดตทั้งหมดจะต้องได้รับการยืนยันเป็นรายบุคคลโดยผู้เชี่ยวชาญของ AIDL และ AHB กระบวนการยืนยันอย่างรอบคอบนี้เป็นปัจจัยสำคัญในการกำหนดมาตรฐานรูปแบบพิกเซลใหม่บนแพลตฟอร์ม
หน้านี้สรุปการเปลี่ยนแปลงโค้ด AOSP ที่จำเป็นและกระบวนการที่จำเป็นสำหรับการเพิ่มรูปแบบพิกเซลใหม่บน AOSP
ก่อนที่จะเพิ่มรูปแบบพิกเซลใหม่ ให้ดาวน์โหลดซอร์สและอัปโหลดแพตช์ตามที่ระบุไว้ใน การส่งแพตช์เพิ่มรูปแบบพิกเซลใหม่ให้กับ AIDL
การเพิ่มการรองรับรูปแบบพิกเซลใหม่จำเป็นต้องเปลี่ยนแปลงไฟล์ PixelFormat.aidl
ทั้งสองไฟล์ที่อยู่ใน AIDL ดู hardware/interfaces/graphics/common/aidl/
สำหรับซอร์สโค้ด AIDL
หากต้องการเพิ่มพิกเซลใหม่ที่เป็นทางการให้กับ AIDL ให้ทำตามขั้นตอนเหล่านี้:
- เพิ่มรูปแบบพิกเซลใหม่ต่อท้ายรายการใหม่ต่อท้าย
PixelFormat
enum ในPixelFormat.aidl
โดยปฏิบัติตามระเบียบโค้ดที่มีอยู่ และตั้งค่าเลขฐานสิบหกสำหรับรายการของคุณให้มากกว่ารายการก่อนหน้าหนึ่งรายการ จับคู่การเปลี่ยนแปลงรหัสของคุณกับรายการก่อนหน้า ดูตัวอย่างต่อไปนี้สำหรับรายการรูปแบบพิกเซลRGBA_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,
ข้อความแสดงข้อผิดพลาดต่อไปนี้จะปรากฏเมื่อคุณสร้างโค้ดหลังจากทำการเปลี่ยนแปลง
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.
หากต้องการล้างข้อผิดพลาดนี้ ให้รันคำสั่งต่อไปนี้ ตามที่ระบุไว้ในข้อความแสดงข้อผิดพลาด เพื่อเปลี่ยน
PixelFormat.aidl
ในไดเร็กทอรีaidl_api
:m android.hardware.graphics.common-update-api
การรันคำสั่งด้านบนจะอัพเดตไฟล์ที่ถูกต้องเพื่อให้สามารถสร้างได้ตามปกติ
เพิ่มรูปแบบพิกเซลใหม่ให้กับ AHB
การเพิ่มการรองรับรูปแบบพิกเซลใหม่จำเป็นต้องเปลี่ยนแปลง hardware_buffer.h
และ AHardwareBuffer.cpp
ดู frameworks/native/libs/nativewindow
สำหรับซอร์สโค้ด AHB
หากต้องการเพิ่มพิกเซลใหม่อย่างเป็นทางการให้กับ AHB ให้ทำตามขั้นตอนเหล่านี้:
- ใน
hardware_buffer.h
ให้ผนวกรูปแบบพิกเซลใหม่เป็นรายการใหม่ที่ส่วนท้ายของAHardwareBuffer_Format
enum ปฏิบัติตามแบบแผนโค้ดที่มีอยู่ใช้ตัวอย่างรูปแบบพิกเซล
RGBA_8888
เพิ่มรายการรูปแบบพิกเซลใหม่ดังต่อไปนี้:/** * Corresponding formats: * Vulkan: VK_FORMAT_R8G8B8A8_UNORM * OpenGL ES: GL_RGBA8 */ AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM = 1,
โปรดทราบว่ารูปแบบพิกเซลใหม่จะได้รับการตั้งชื่อเป็น AHB ซึ่งจะต้องขึ้นต้นด้วย
AHARDWAREBUFFER_FORMAT_
ตามด้วยตัวย่อของช่องสัญญาณและความลึกของบิต และลงท้ายด้วยการเข้ารหัส รายการแจงนับนี้ต้องมีค่าฐานสิบหกเหมือนกับค่าในPixelFormat.aidl
รูปแบบพิกเซลคาดว่าจะมีรูปแบบ Vulkan หรือ OpenGL ES หนึ่งหรือทั้งสองรูปแบบที่เกี่ยวข้องกัน ระบุรูปแบบที่เกี่ยวข้องตามความเหมาะสม หากไม่มีรูปแบบที่เกี่ยวข้อง ให้ระบุ
N/A
เพิ่มรูปแบบพิกเซลในการทดสอบเสริมภายใต้ CTS หากมีรูปแบบ OpenGL ES ที่เกี่ยวข้อง เมื่อต้องการทำเช่นนี้ ให้เพิ่มรูปแบบ GL ใหม่ลงใน
AHardwareBufferGLTest.cpp
ในAHBFormatAsString(int32_t format)
พร้อมด้วยFORMAT_CASE(...)
และGL_FORMAT_CASE(...)
สำหรับรูปแบบใหม่ ดังแสดงดังต่อไปนี้:const char* AHBFormatAsString(int32_t format) { switch (format) { ... FORMAT_CASE(R8G8B8A8_UNORM); ... GL_FORMAT_CASE(GL_RGB8); } return ""; }
ถัดไป เพิ่มการทดสอบใหม่ให้กับ
AHardwareBufferGLTest.cpp
ดังแสดงดังต่อไปนี้: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);
ระบุค่า
AHardwareBuffer_Desc
อย่างน้อยหนึ่งชุด เพิ่มค่าเพิ่มเติมหากจำเป็นใน
AHardwareBuffer.cpp
ให้ค้นหาจุดสิ้นสุดของการยืนยันแบบคงที่ที่พบภายใน:// ---------------------------------------------------------------------------- // Validate hardware_buffer.h and PixelFormat.aidl agree // ----------------------------------------------------------------------------
ผนวก
static_assert
ใหม่สำหรับรูปแบบพิกเซลใหม่ โดยใช้PixelFormat::
enum และไม่ใช่ด้วยค่าคงที่HAL_PIXEL_FORMAT
ใช้ตัวอย่างเดียวกันสำหรับรูปแบบพิกเซลRGBA_8888
จาก Add a new pixel format to AIDL ให้เพิ่มรายการรูปแบบพิกเซลใหม่ดังนี้:static_assert(static_cast
(aidl::android::hardware::graphics::common::PixelFormat::RGBA_8888) == AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM, "HAL and AHardwareBuffer pixel format don't match"); เพิ่มรูปแบบพิกเซลใหม่ให้กับการทดสอบที่เหมาะสม โดยเพิ่มรูปแบบพิกเซลใหม่ต่อท้าย
PrintAhbFormat()
ในAHardwareBufferTest.cpp
ปฏิบัติตามแบบแผนโค้ดที่มีอยู่ ดังที่แสดงด้านล่าง:void PrintAhbFormat(std::ostream& os, uint64_t format) { switch (format) { ... FORMAT_CASE(R8G8B8A8_UNORM); default: os << "unknown"; break; } }
เพิ่มรูปแบบพิกเซลใหม่ให้กับ
HardwareBuffer
SDK ในHardwareBuffer.java
: โดยต่อท้ายรายการใหม่ไปที่@IntDef
ตัวอย่างเช่น รายการสำหรับรูปแบบRGBA_8888
จะแสดงดังต่อไปนี้:@Retention(RetentionPolicy.SOURCE) @IntDef(prefix = { "RGB", "BLOB", "YCBCR_", "D_", "DS_", "S_" }, value = { ... RGBA_8888, })
หากค่าส่วนประกอบไม่ได้รับการปรับให้เป็นมาตรฐาน ให้ระบุค่าอย่างชัดเจนในชื่อตัวแปร ตัวอย่างเช่น ชื่อตัวแปรสำหรับรูปแบบช่องสีแดง 16 บิตจำนวนเต็มที่ไม่ได้ลงนามเท่านั้น ต้องเป็น
R_16UI
และรูปแบบเดียวกันกับรูปแบบช่องสีเขียว 16 บิตจำนวนเต็มที่ไม่ได้ลงนามเพิ่มเติม ต้องเป็นRG_16UI16UI
เพิ่มรูปแบบพิกเซลใหม่เป็น
static int
ในHardwareBuffer.java
โดยการต่อท้ายตัวแปรสมาชิกสาธารณะใหม่ที่ส่วนท้ายของ@Format
:@Format ... /** Format: 8 bits each red, green, blue, alpha */ public static final int RGBA_8888 = 0x1;
รายการ enum นี้ต้องมีค่าฐานสิบหกเหมือนกับค่าจาก
PixelFormat.aidl
และhardware_buffer.h
ปฏิบัติตามอนุสัญญาที่มีอยู่- การพยายามสร้างด้วยการเปลี่ยนแปลงโค้ดเหล่านี้ทำให้เกิดข้อผิดพลาดในการสร้าง:
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. ****************************** ...
หากต้องการล้างข้อผิดพลาดนี้ ให้รันคำสั่งต่อไปนี้ ตามที่ระบุไว้ในข้อความแสดงข้อผิดพลาด เพื่อเปลี่ยน
current.txt
:m api-stubs-docs-non-updatable-update-current-api
การรันคำสั่งด้านบนจะอัพเดตไฟล์ที่ถูกต้องเพื่อให้สามารถสร้างได้ตามปกติ
เพิ่มรูปแบบพิกเซลใหม่ให้กับการทดสอบ Java โดยการผนวกรูปแบบพิกเซลใหม่ต่อท้าย
paramsForTestCreateOptionalFormats()
ในHardwareBufferTest.java
ดังแสดงดังต่อไปนี้:private static Object[] paramsForTestCreateOptionalFormats() { return new Integer[]{ HardwareBuffer.RGBA_8888 };
เพิ่มรูปแบบพิกเซลใหม่ให้กับการรวมระบบ Window
หากต้องการใช้รูปแบบพิกเซลใหม่เป็นรูปแบบสำหรับ framebuffer ใน API กราฟิก ให้เพิ่มลงใน Window System Integration (WSI) ที่เหมาะสมสำหรับ API กราฟิกที่เกี่ยวข้อง สำหรับแอปหรือกระบวนการของระบบที่ใช้ Vulkan API ให้อัปเดต Vulkan Swapchain สำหรับแอปหรือกระบวนการของระบบที่ใช้ OpenGL ES API ให้อัปเดต EGL API
การเปลี่ยนแปลง Vulkan WSI สำหรับรูปแบบพิกเซลใหม่ อัพเดต Vulkan WSI ดังต่อไปนี้: เพิ่มกรณีใหม่ให้กับฟังก์ชัน GetNativePixelFormat(VkFormat format)
ใน 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;
}
- ค้นหาส่วนขยาย Vulkan หากรูปแบบพิกเซลต้องใช้ส่วนขยาย Vulkan เพื่อให้ทำงานได้ สำหรับส่วนขยายด้านข้างอินสแตนซ์ ให้ใช้
instance_data
แสดงดังต่อไปนี้:
bool colorspace_ext = instance_data.hook_extensions.test(ProcHook::EXT_swapchain_colorspace);
สำหรับส่วนขยายฝั่งอุปกรณ์ ให้ใช้ดังต่อไปนี้:
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 จัดการโครงสร้างพื้นฐานที่จำเป็นในการเปิดเผยอินสแตนซ์หรือส่วนขยายอุปกรณ์ไปยัง swapchain.cpp
รายการการเปลี่ยนแปลงเริ่มต้นไม่จำเป็นต้องมีการตั้งค่าส่วนขยายอย่างถูกต้องจากตัวโหลด 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});
}
คุณต้องมีความรู้เกี่ยวกับคู่รูปแบบและสเปซสีที่เข้ากันได้
- เพิ่มรูปแบบใหม่ให้กับ
dEQP-VK
ซึ่งอยู่ที่ external/deqp
- อัปเดตการทดสอบความสอดคล้องของ Vulkan ใน
vktApiExternalMemoryTests.cpp
และ vktExternalMemoryUtil.cpp
โดยการอนุมานการเปลี่ยนแปลงที่จำเป็นจากแหล่งที่มาที่มีอยู่หรือติดต่อฝ่ายสนับสนุน Android ของคุณเพื่อขอข้อมูล
การเปลี่ยนแปลง EGL สำหรับรูปแบบพิกเซลใหม่
เพิ่มกรณีใหม่ให้กับฟังก์ชัน GetNativePixelFormat(VkFormat format)
ใน 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
แสดงดังต่อไปนี้:bool colorspace_ext = instance_data.hook_extensions.test(ProcHook::EXT_swapchain_colorspace);
สำหรับส่วนขยายฝั่งอุปกรณ์ ให้ใช้ดังต่อไปนี้:
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 จัดการโครงสร้างพื้นฐานที่จำเป็นในการเปิดเผยอินสแตนซ์หรือส่วนขยายอุปกรณ์ไปยัง swapchain.cpp
รายการการเปลี่ยนแปลงเริ่มต้นไม่จำเป็นต้องมีการตั้งค่าส่วนขยายอย่างถูกต้องจากตัวโหลด 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}); }
คุณต้องมีความรู้เกี่ยวกับคู่รูปแบบและสเปซสีที่เข้ากันได้
dEQP-VK
ซึ่งอยู่ที่ external/deqp
vktApiExternalMemoryTests.cpp
และ vktExternalMemoryUtil.cpp
โดยการอนุมานการเปลี่ยนแปลงที่จำเป็นจากแหล่งที่มาที่มีอยู่หรือติดต่อฝ่ายสนับสนุน Android ของคุณเพื่อขอข้อมูลอัพเดต EGL ดังนี้:
- ในฟังก์ชัน
getNativePixelFormat()
ให้แก้ไขแผนผังif-else
เพื่อส่งคืน AIDL enum สำหรับรูปแบบพิกเซลใหม่ ใช้ตัวอย่างสำหรับรูปแบบพิกเซลRGBA_8888
:if (a == 0) { ... } else { if (componentType == EGL_COLOR_COMPONENT_TYPE_FIXED_EXT) { if (colorDepth > 24) { ... } else { *format = PixelFormat::RGBA_8888; } } else { ... } }
- หากต้องการเพิ่มรูปแบบใหม่ให้กับ dEQP ให้เพิ่มรายการใหม่ลงใน
androidFormats
enum ซึ่งแสดงดังนี้:static const GLenum androidFormats[] = { ... GL_RGBA8, ... };
ส่งการอัปเดตของคุณ
ติดตาม สำหรับผู้มีส่วนร่วม เพื่อหมุนรายการการเปลี่ยนแปลงของคุณและแบ่งปันกับทีมที่เหมาะสม