تمام قالبهای پیکسل جدید اضافه شده به Android باید در زبان تعریف رابط Android (AIDL) و در بافر سختافزار Android (AHB) گنجانده شوند. AIDL و AHB دارای الزامات پایداری و استانداردسازی دقیقی هستند که نیاز به یک فرآیند دقیق در هنگام گسترش عملکرد دارد. همه فرمتهای پیکسل جدید باید در AOSP قرار بگیرند و همه بهروزرسانیها باید به صورت جداگانه توسط کارشناسان AIDL و AHB تأیید شوند. این فرآیند تأیید دقیق عامل مهمی در استانداردسازی هر فرمت پیکسلی جدید در پلتفرم است.
در این صفحه تغییرات کد AOSP ضروری و فرآیند مورد نیاز برای افزودن فرمتهای پیکسل جدید در AOSP توضیح داده شده است.
قبل از افزودن یک قالب پیکسلی جدید، منبع را دانلود کنید و وصلههای آپلود شده را همانطور که در ارسال وصلهها توضیح داده شده است.یک قالب پیکسلی جدید به AIDL اضافه کنید
افزودن پشتیبانی برای قالب پیکسل جدید نیازمند تغییرات در هر دو فایل PixelFormat.aidl
است که در AIDL قرار دارند. برای کد منبع AIDL به hardware/interfaces/graphics/common/aidl/
مراجعه کنید.
برای افزودن یک پیکسل رسمی جدید به AIDL، مراحل زیر را دنبال کنید:
- قالب پیکسل جدید را به عنوان ورودی جدید به انتهای فهرست
PixelFormat
در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
اضافه کنید. قوانین کد موجود را دنبال کنید.با استفاده از نمونه فرمت پیکسلی
RGBA_8888
، ورودی فرمت پیکسل جدید را به صورت زیر اضافه کنید:/** * Corresponding formats: * Vulkan: VK_FORMAT_R8G8B8A8_UNORM * OpenGL ES: GL_RGBA8 */ AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM = 1,
توجه داشته باشید که فرمت پیکسل جدید یک نام در AHB داده شده است، که باید با
AHARDWAREBUFFER_FORMAT_
شروع شود، سپس اختصارات کانال و عمق بیت و با رمزگذاری ختم شود. این ورودی enum باید همان مقدار هگز را در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 // ----------------------------------------------------------------------------
با استفاده از
PixelFormat::
enum و نه با ثابتHAL_PIXEL_FORMAT
، یکstatic_assert
جدید برای قالب پیکسل جدید اضافه کنید. با استفاده از همین مثال برای قالب پیکسل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
اجرای دستور بالا فایل صحیح را به روز می کند تا بتوان به طور عادی ساخت.
با اضافه کردن قالب پیکسل جدید به انتهای
paramsForTestCreateOptionalFormats()
درHardwareBufferTest.java
، فرمت پیکسل جدید را به تست های جاوا اضافه کنید، که به صورت زیر نشان داده شده است:private static Object[] paramsForTestCreateOptionalFormats() { return new Integer[]{ HardwareBuffer.RGBA_8888 };
یک قالب پیکسلی جدید به یکپارچه سازی سیستم پنجره اضافه کنید
برای استفاده از قالب پیکسل جدید به عنوان فرمت فریم بافر در یک API گرافیکی، آن را به یکپارچه سازی سیستم پنجره (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 لازم نیست.
- بعد، جفت فرمت و colorspace را برشمارید:
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});
}
شما باید از فرمت سازگار و جفت های colorspace آگاهی داشته باشید.
- قالب جدید را به
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}); }
شما باید از فرمت سازگار و جفت های colorspace آگاهی داشته باشید.
dEQP-VK
واقع در external/deqp
اضافه کنید.vktApiExternalMemoryTests.cpp
و vktExternalMemoryUtil.cpp
با استنباط تغییرات مورد نیاز از منبع موجود یا تماس با پشتیبانی Android خود برای کسب اطلاعات بهروزرسانی کنید.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, ... };
آپدیت خود را ارسال کنید
برای مشارکتکنندگان دنبال کنید تا فهرستهای تغییرات خود را بچرخانید و آنها را با تیم مناسب به اشتراک بگذارید.