כל פורמטי הפיקסלים החדשים שנוספים ל-Android צריכים להיכלל בשפת ההגדרה לבניית ממשק Android (AIDL) ובמאגר החומרה של Android (AHB). ל-AIDL ול-AHB יש דרישות מחמירות לגבי יציבות ותקנון, ולכן צריך לבצע תהליך מוקפד כשמרחיבים את הפונקציונליות שלהם. כל פורמטי הפיקסלים החדשים צריכים להיכלל ב-AOSP, וכל העדכונים צריכים לקבל אישור בנפרד ממומחים ב-AIDL וב-AHB. תהליך האישור הקפדני הזה הוא גורם חשוב בתהליך של סטנדרטיזציה של פורמטים חדשים של פיקסלים בפלטפורמה.
בדף הזה מפורטים השינויים הנדרשים בקוד AOSP והתהליך שצריך לבצע כדי להוסיף פורמטים חדשים של פיקסלים ב-AOSP.
לפני שמוסיפים פורמט פיקסלים חדש, צריך להוריד את המקור ולהעלות תיקונים כמו שמתואר במאמר בנושא שליחת תיקונים.הוספת פורמט פיקסלים חדש ל-AIDL
כדי להוסיף תמיכה בפורמט פיקסלים חדש, צריך לבצע שינויים בשני הקבצים PixelFormat.aidl
שנמצאים ב-AIDL. אפשר לראות את קוד המקור של AIDL בכתובת
hardware/interfaces/graphics/common/aidl/
.
כדי להוסיף פיקסל חדש ל-AIDL, פועלים לפי השלבים הבאים:
- מוסיפים את פורמט הפיקסל החדש כרשומה חדשה בסוף ה-enum
PixelFormat
ב-PixelFormat.aidl
. לשם כך, פועלים לפי מוסכמת הקוד הקיימת ומגדירים את הערך ההקסדצימלי של הרשומה כך שיהיה גדול ב-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-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
, מוסיפים את פורמט הפיקסל החדש כערך חדש בסוף של enumAHardwareBuffer_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
. -
אם יש פורמט OpenGL ES שמשויך לפורמט הפיקסל, מוסיפים את פורמט הפיקסל לבדיקות האופציונליות בקטע CTS. כדי לעשות את זה, מוסיפים את הפורמט החדש של 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
חדש לפורמט הפיקסלים החדש, באמצעות הערך enum 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;
הערך ההקסדצימלי של רשומה זו ב-enum חייב להיות זהה לערך ההקסדצימלי של הרשומה מ-
PixelFormat.aidl
ו-hardware_buffer.h
. פועלים לפי המוסכמות הקיימות. -
ניסיון לבצע build עם השינויים האלה בקוד יוביל לשגיאת build:
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
כדי להשתמש בפורמט הפיקסלים החדש כפורמט של מאגר מסגרות ב-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. - לאחר מכן, מפרטים את זוגות הפורמט ומרחב הצבעים:
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
כדי להחזיר את סוג ה-enum של 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, ... };
שליחת העדכון
למשתתפים כדי ליצור את רשימות השינויים ולשתף אותן עם הצוות המתאים.