כל הפורמטים החדשים של פיקסלים שנוספים ל-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-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
הרצת הפקודה שלמעלה מעדכנת את הקובץ הנכון כדי שאפשר יהיה לבצע build באופן תקין.
הוספה של פורמט פיקסלים חדש ל-AHB
כדי להוסיף תמיכה בפורמט פיקסלים חדש, צריך לבצע שינויים ב-hardware_buffer.h
וב-AHardwareBuffer.cpp
.
ראו frameworks/native/libs/nativewindow
ל-AHB.
כדי להוסיף פורמט פיקסל חדש ל-AHB:
- ב-
hardware_buffer.h
, יש לצרף את פורמט הפיקסל החדש כרשומה חדשה בסוף טיפוסים בני מנייה (enum)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
, מחפשים את סוף טענות הנכונות (assertions) הסטטיים שנמצאים בתוך:// ---------------------------------------------------------------------------- // Validate hardware_buffer.h and PixelFormat.aidl agree // ----------------------------------------------------------------------------
מוסיפים
static_assert
חדש לפורמט הפיקסל החדש, באמצעות enumPixelFormat::
ולא עם קבוע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
הרצת הפקודה שלמעלה מעדכנת את הקובץ הנכון כדי שאפשר יהיה לבצע build באופן תקין.
-
מוסיפים את פורמט הפיקסל החדש לבדיקות Java על ידי הוספת פורמט הפיקסלים החדש לסוף
paramsForTestCreateOptionalFormats()
ב-HardwareBufferTest.java
, מוצגת באופן הבא:private static Object[] paramsForTestCreateOptionalFormats() { return new Integer[]{ HardwareBuffer.RGBA_8888 };
הוספת פורמט פיקסלים חדש לשילוב עם מערכת Windows
כדי להשתמש בפורמט הפיקסלים החדש כפורמט של מאגר נתונים זמני ב- Graphics API, יש להוסיף אותו לשילוב המתאים של window System (WSI) עבור גרפיקת API. לגבי אפליקציה או תהליך מערכת שמשתמשים ב-Vulkan API, צריך לעדכן את Vulkan Swapchain. לגבי אפליקציה או תהליך מערכת שמשתמשים ב-OpenGL ES API, צריך לעדכן את API של 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 enum עבור פורמט הפיקסל החדש. בהמשך לדוגמה של פורמט הפיקסל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, ... };
שליחת העדכון
הוספה למעקב לתורמי תוכן כדי להפעיל את רשימות השינויים ולשתף אותן עם הצוות המתאים.