รูปแบบพิกเซลใหม่ทั้งหมดที่เพิ่มลงใน Android ต้องรวมอยู่ใน Android Interface Definition Language (AIDL) และ Android Hardware Buffer (AHB) AIDL และ AHB มีข้อกำหนดด้านความเสถียรและมาตรฐานที่เข้มงวด ซึ่งจำเป็นต้องใช้กระบวนการที่รอบคอบเมื่อขยายฟังก์ชันการทำงาน พิกเซลรูปแบบใหม่ทั้งหมดจะต้องไปที่ AOSP และการอัปเดตทั้งหมดต้องได้รับการยืนยันจากผู้เชี่ยวชาญ AIDL และ AHB ทีละรายการ กระบวนการยืนยันอย่างระมัดระวังนี้เป็นปัจจัยสำคัญในการจัดทำรูปแบบพิกเซลใหม่ๆ บนแพลตฟอร์มให้เป็นมาตรฐานเดียวกัน
หน้านี้ระบุการเปลี่ยนแปลงโค้ด AOSP ที่จำเป็นและขั้นตอนที่จำเป็นสำหรับการเพิ่มรูปแบบพิกเซลใหม่ใน AOSP
ก่อนเพิ่มรูปแบบพิกเซลใหม่ ให้ดาวน์โหลดแหล่งที่มาและอัปโหลดแพตช์ตามที่ระบุไว้ในหัวข้อการส่งแพตช์เพิ่มรูปแบบพิกเซลใหม่ลงใน AIDL
การเพิ่มการรองรับรูปแบบพิกเซลใหม่จะต้องมีการเปลี่ยนแปลงไฟล์ PixelFormat.aidl
ทั้ง 2 ไฟล์ที่อยู่ใน AIDL ดูซอร์สโค้ด AIDL ได้ที่
hardware/interfaces/graphics/common/aidl/
หากต้องการเพิ่มพิกเซลอย่างเป็นทางการลงใน AIDL ให้ทำตามขั้นตอนต่อไปนี้
- เพิ่มรูปแบบพิกเซลใหม่เป็นรายการใหม่ต่อท้าย
PixelFormat
enum ในPixelFormat.aidl
โดยทำตามรูปแบบโค้ดที่มีอยู่และตั้งค่าเลขฐาน 16 สำหรับรายการให้มากกว่ารายการก่อนหน้า 1 รายการ จับคู่การเปลี่ยนแปลงโค้ดของคุณกับรายการก่อนหน้า ดูตัวอย่างรายการรูปแบบพิกเซล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
โปรดดูซอร์สโค้ด AHB ใน frameworks/native/libs/nativewindow
หากต้องการเพิ่มรูปแบบพิกเซลใหม่ลงใน 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_
ตามด้วยตัวย่อของช่องและความลึกของบิต และลงท้ายด้วยการเข้ารหัส รายการ Enum นี้ต้องมีค่าฐาน 16 เดียวกันกับในPixelFormat.aidl
รูปแบบพิกเซลควรมีรูปแบบ Vulkan หรือ OpenGL ES ที่เกี่ยวข้องอย่างน้อย 1 รูปแบบ ระบุรูปแบบที่เกี่ยวข้องตามความเหมาะสม หากไม่มีรูปแบบที่เชื่อมโยง ให้ระบุ
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
อย่างน้อย 1 ชุด เพิ่มค่าอื่นๆ หากจําเป็น -
ใน
AHardwareBuffer.cpp
ให้ค้นหาจุดสิ้นสุดของข้อความยืนยันแบบคงที่ที่พบภายใน// ---------------------------------------------------------------------------- // Validate hardware_buffer.h and PixelFormat.aidl agree // ----------------------------------------------------------------------------
ต่อท้าย
static_assert
ใหม่สำหรับรูปแบบพิกเซลใหม่โดยใช้ลิสต์แบบPixelFormat::
ไม่ใช่ค่าคงที่HAL_PIXEL_FORMAT
โดยใช้ตัวอย่างเดียวกันสำหรับรูปแบบพิกเซลRGBA_8888
จากหัวข้อเพิ่มรูปแบบพิกเซลใหม่ลงใน 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 };
เพิ่มรูปแบบพิกเซลใหม่ในการผสานรวมระบบ Windows
หากต้องการใช้รูปแบบพิกเซลใหม่เป็นรูปแบบสำหรับ Framebuffer ใน API กราฟิก ให้เพิ่มรูปแบบดังกล่าวไปยัง Window System Integration (WSI) ที่เหมาะสมสำหรับกราฟิก API ที่เกี่ยวข้อง สําหรับแอปหรือกระบวนการของระบบที่ใช้ Vulkan API ให้อัปเดต Vulkan Swapchain สําหรับแอปหรือกระบวนการของระบบที่ใช้ OpenGL ES API ให้อัปเดต EGL API
การเปลี่ยนแปลง Vulkan WSI สำหรับรูปแบบพิกเซลใหม่
อัปเดต WSI ของ Vulkan ดังนี้-
เพิ่มเคสใหม่ไปยังฟังก์ชัน
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 Conformance Test ใน
vktApiExternalMemoryTests.cpp
และvktExternalMemoryUtil.cpp
โดยการอนุมานการเปลี่ยนแปลงที่จำเป็นจากแหล่งที่มาที่มีอยู่ หรือติดต่อทีมสนับสนุนของ Android เพื่อขอข้อมูล
การเปลี่ยนแปลง EGL สำหรับรูปแบบพิกเซลใหม่
อัปเดต EGL ดังนี้
- ในฟังก์ชัน
getNativePixelFormat()
ให้แก้ไขต้นไม้if-else
เพื่อแสดงผลรายการ AIDL สําหรับรูปแบบพิกเซลใหม่ การใช้ตัวอย่างสำหรับรูปแบบพิกเซลRGBA_8888
ดังนี้if (a == 0) { ... } else { if (componentType == EGL_COLOR_COMPONENT_TYPE_FIXED_EXT) { if (colorDepth > 24) { ... } else { *format = PixelFormat::RGBA_8888; } } else { ... } }
- หากต้องการเพิ่มรูปแบบใหม่ไปยัง dEQP ให้เพิ่มรายการใหม่ไปยัง enum
androidFormats
ซึ่งแสดงดังต่อไปนี้static const GLenum androidFormats[] = { ... GL_RGBA8, ... };
ส่งการอัปเดต
ทําตามขั้นตอนสำหรับผู้มีส่วนร่วมเพื่อเริ่มสร้างรายการการเปลี่ยนแปลงและแชร์กับทีมที่เหมาะสม