يجب تضمين جميع تنسيقات البكسل الجديدة التي تمت إضافتها إلى Android في لغة تعريف واجهة Android (AIDL) وفي مخزن Android للأجهزة (AHB). يفرض كل من AIDL وAHB متطلبات صارمة بشأن الثبات والتوحيد القياسي، ما يستلزم اتّباع عملية دقيقة عند توسيع الوظائف. يجب أن تتوفّر جميع تنسيقات وحدات البكسل الجديدة في مشروع Android مفتوح المصدر (AOSP)، ويجب أن يؤكّد خبراء AIDL وAHB كل التحديثات بشكل فردي. وتُعدّ عملية التأكيد الدقيق هذه عاملاً مهمًا في توحيد أي تنسيقات جديدة لوحدات البكسل على المنصة.
توضّح هذه الصفحة تغييرات رمز AOSP الضرورية والعملية المطلوبة لإضافة تنسيقات بكسل جديدة على AOSP.
قبل إضافة تنسيق بكسل جديد، نزِّل المصدر وحمِّل رموز التصحيح كما هو موضّح في إرسال رموز التصحيح.إضافة تنسيق بكسل جديد إلى AIDL
تتطلّب إضافة دعم لتنسيق بكسل جديد إجراء تغييرات على كلا الملفين PixelFormat.aidl
الموجودَين في AIDL. راجِع
hardware/interfaces/graphics/common/aidl/
للاطّلاع على رمز مصدر 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
.
يمكنك الاطّلاع على 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_
، متبوعًا باختصارات القنوات وعمق البتات، وينتهي بالترميز. يجب أن تتضمّن إدخالات التعداد الثابت هذه القيمة السداسية العشرية نفسها الواردة في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; } }
-
أضِف تنسيق البكسل الجديد إلى حزمة تطوير البرامج (SDK)
HardwareBuffer
في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 };
إضافة تنسيق بكسل جديد إلى عملية الدمج مع "نظام التشغيل Windows"
لاستخدام تنسيق البكسل الجديد كتنسيق لإطار مخزن مؤقت في واجهة برمجة تطبيقات رسومات، أضِفه إلى Window System Integration (WSI) المناسب لواجهة برمجة تطبيقات الرسومات ذات الصلة. بالنسبة إلى تطبيق أو عملية نظام تستخدم Vulkan API، يجب تعديل 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::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 لتنسيقات البكسل الجديدة
عدِّل 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
enum، كما هو موضّح أدناه:static const GLenum androidFormats[] = { ... GL_RGBA8, ... };
إرسال التعديل
اتّبِع الخطوات الواردة في مقالة للمساهمين لإنشاء قوائم التغيير ومشاركتها مع الفريق المناسب.