يجب تضمين جميع تنسيقات البكسل الجديدة المضافة إلى Android في الـ لغة تعريف واجهة نظام Android (AIDL) وفي الـ مخزن مؤقت للأجهزة في Android (AHB). تتضمّن AIDL وAHB متطلبات صارمة بشأن الثبات والتنظيم، ما يستدعي اتّباع عملية دقيقة عند توسيع الوظائف. يجب أن يتم إدراج جميع تنسيقات البكسل الجديدة في مشروع Android مفتوح المصدر (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-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.
-
لإزالة هذا الخطأ، نفِّذ الأمر التالي، كما هو موضّح في رسالة الخطأ، لتغيير
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. اتّبِع اصطلاحات الرمز الحالية.باستخدام مثال تنسيق البكسل
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::وليس باستخدام الثابت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; } } -
أضِف تنسيق البكسل الجديد إلى
HardwareBufferSDK في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;
يجب أن يتضمّن إدخال التعداد هذا القيمة السداسية العشرية نفسها من
PixelFormat.aidlوhardware_buffer.h. اتّبِع الاصطلاحات الحالية. -
ستؤدي محاولة الإنشاء باستخدام تغييرات الرمز هذه إلى ظهور خطأ في الإنشاء:
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. ****************************** ...لإزالة هذا الخطأ، نفِّذ الأمر التالي، كما هو موضّح في رسالة الخطأ، لتغيير
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 };
إضافة تنسيق بكسل جديد إلى عملية دمج "نظام النوافذ"
لاستخدام تنسيق البكسل الجديد كتنسيق لمخزن مؤقت للإطارات في واجهة برمجة تطبيقات للرسومات، أضِفه إلى عملية دمج "نظام النوافذ" (WSI) المناسبة لواجهة برمجة التطبيقات ذات الصلة للرسومات. بالنسبة إلى تطبيق أو عملية نظام تستخدم واجهة برمجة تطبيقات Vulkan، عدِّل Vulkan Swapchain. بالنسبة إلى تطبيق أو عملية نظام تستخدم واجهة برمجة تطبيقات OpenGL ES، عدِّل واجهة برمجة تطبيقات EGL.
تغييرات 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::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. - عدِّل اختبارات التوافق مع Vulkan في
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، أضِف إدخالاً جديدًا إلى الـ
androidFormatsتعداد، كما هو موضّح أدناه:static const GLenum androidFormats[] = { ... GL_RGBA8, ... };
إرسال التعديل
اتّبِع مقالة للمساهمين لإنشاء قوائم التغييرات ومشاركتها مع الفريق المناسب.