מסגרת סנכרון

מסגרת הסנכרון מתארת במפורש יחסי תלות בין פעולות אסינכרוניות שונות במערכת הגרפיקה של Android. המסגרת מספק API שמאפשר לרכיבים לציין מתי שוחררים מאגרי נתונים זמניים. המסגרת גם מאפשר העברה של רכיבי סנכרון בין מנהלי התקנים מהליבה למרחב המשתמשים ובין תהליכים של מרחב משתמשים עצמם.

לדוגמה, אפליקציה עשויה להוסיף לתור פעולות לביצוע ב-GPU. ה-GPU מתחיל לשרטט את התמונה. למרות שהתמונה לא צונזרה בזיכרון עדיין, הסמן של מאגר הנתונים הזמני מועבר לחלון יחד עם גדר שמציינת מתי ה-GPU יפעל לסיים. מחבר החלונות מתחיל לעבד מראש את הזמן מעביר את העבודה לבקר התצוגה. באותו אופן, ה-CPU מתבצעת מראש. לאחר שה-GPU מסתיים, בקר התצוגה מציג מיד את התמונה.

מסגרת הסנכרון מאפשרת גם לספקי הטמעה למנף סנכרון משאבים ברכיבי החומרה שלהם. לבסוף, ה-framework מאפשר לראות את צינור עיבוד הנתונים הגרפי כדי לעזור ניפוי באגים.

סנכרון מפורש

סנכרון מפורש מאפשר למפיקים ולצרכנים של מאגרי נתונים גרפיים כדי לאותת כשהם מסיימים להשתמש במאגר הנתונים הזמני. סנכרון מפורש הוא הוטמעו בליבה (kernel-space).

היתרונות של סנכרון מפורש כוללים:

  • פחות הבדלים בהתנהגות בין מכשירים
  • תמיכה טובה יותר בניפוי באגים
  • מדדי בדיקה משופרים

מסגרת הסנכרון כוללת שלושה סוגי אובייקטים:

  • sync_timeline
  • sync_pt
  • sync_fence

Sync_timeline

sync_timeline הוא ציר זמן בעלייה מונוטונית על הספקים להטמיע עבור כל מופע של מנהל התקן, כמו הקשר GL, שלט רחוק או נצנצים בדו-ממד. sync_timeline ספירות משימות שנשלחו לליבה (kernel) של חומרה מסוימת. הספק sync_timeline מספק אחריות לגבי סדר הפעילות ומאפשרת הטמעות ספציפיות לחומרה.

יש לפעול לפי ההנחיות הבאות כשמטמיעים את sync_timeline:

  • מספקים שמות שימושיים לכל הנהגים, צירי הזמן והגדרות כדי לפשט את התהליך ניפוי באגים.
  • יישום של timeline_value_str ושל pt_value_str אופרטורים בלוחות הזמנים כדי להפוך את פלט ניפוי הבאגים לקריא יותר.
  • הטמעת המילוי driver_data כדי לתת לספריות של מרחב משתמשים, כמו ספריית GL, גישה לנתונים פרטיים בציר הזמן, אם רוצים. data_driver מאפשר לספקים להעביר מידע על הפריטים שלא ניתנים לשינוי sync_fence ו-sync_pts כדי לבנות שורות פקודה שמבוססים עליהם.
  • אסור לאפשר למרחב המשתמשים ליצור גדר או לסמן אותה באופן מפורש. במפורש יצירת אותות/הגדרות מובילה להתקפת מניעת שירות (DoS) עצירת הפונקציונליות של צינור עיבוד הנתונים.
  • אין גישה אל sync_timeline, sync_pt או sync_fence באופן מפורש. ממשק ה-API מספק את כל למשימות ספציפיות.

Sync_pt

sync_pt הוא ערך יחיד או נקודה אחת על sync_timeline. נקודה יש שלושה מצבים: פעיל, מסומן ושגיאה. הנקודות מתחילות במצב פעיל ולעבור למצב מסומן או שגיאה. לדוגמה, כשתמונה הצרכן כבר לא זקוק למאגר נתונים זמני, מסומן כ-sync_pt כדי שמפיק התמונה יוכל לדעת שמותר לכתוב למאגר הנתונים הזמני שוב.

סנכרון_גדר

sync_fence הוא אוסף של sync_pt ערכים שלעיתים קרובות יש להם sync_timeline תבניות הורה שונות (למשל, ו-GPU). sync_fence, sync_pt וגם sync_timeline הם הבסיסים העיקריים שנהגים ומרחב המשתמשים שבהם משתמשים כדי להסביר את יחסי התלות שלהם. כשהמערכת מסמנת את גדר, כל הפקודות שהונפקו לפני הגדר מובטחות שהושלמו, מנהל התקן ליבה או בלוק חומרה מריצים פקודות לפי הסדר.

מסגרת הסנכרון מאפשרת לצרכנים או למפיקים מרובים לסמן מתי הם לסיים להשתמש במאגר הנתונים הזמני, להעביר את נתוני התלות באמצעות פונקציה אחת הפרמטר. הגדרות מגובות על ידי מתאר קובץ ומועברים מ: מרחב ליבה למרחב המשתמשים. לדוגמה, גדר יכולה להכיל ערכי sync_pt המעידים על כך ששני צרכני תמונות נפרדים לקרוא מאגר נתונים זמני. כשהמערכת מסמנת את המסגרת, מפיקי התמונה יודעים שהצרכנים צריכים לצרוך.

גדרות, כמו ערכים של sync_pt, מתחילים לפעול ומשנים מצב על סמך את מצב הנקודות שלהם. אם כל הערכים של sync_pt מסומנים, מתבצע אות sync_fence. אם נופל sync_pt אחד במצב שגיאה, כל sync_fence במצב שגיאה.

אי אפשר לשנות את החברות בקבוצת sync_fence אחרי שחומת השירות נוצר. כדי לקבל יותר מנקודה אחת בגדר, מיזוג כאשר נקודות משתי גדרות נפרדות מתווספות לגדר שלישית. אם אחת מהנקודות האלה מסומנת בגדר המקור והשנייה לא, גם גדר שלישית לא תהיה במצב של סימון.

כדי להטמיע סנכרון מפורש, צריך לספק את הפרטים הבאים:

  • מערכת משנה של מרחב ליבה (kernel) שמטמיעה את מסגרת הסנכרון עבור מנהל התקן חומרה מסוים. נהגים שצריכים להיות מודעים לקירות הם: בדרך כלל כל דבר שניגש ל'מלחין החומרה' או מתקשר איתו. הקבצים העיקריים כוללים:
    • הטמעה מרכזית:
      • kernel/common/include/linux/sync.h
      • kernel/common/drivers/base/sync.c
    • תיעוד בכתובת kernel/common/Documentation/sync.txt
    • ספרייה שמשמשת לתקשורת עם מרחב הליבה (kernel) שבה platform/system/core/libsync
  • הספק צריך לספק את הסנכרון המתאים גדרות כפרמטרים של validateDisplay() הפונקציה presentDisplay() ב-HAL.
  • שני תוספי GL שקשורים לגדרות (EGL_ANDROID_native_fence_sync) ו-EGL_ANDROID_wait_sync) ותמיכה בגדרות. לנהגים.

מקרה לדוגמה: הטמעת מנהל התקן של רשת המדיה

כדי להשתמש ב-API שתומך בפונקציית הסנכרון: תפתח מנהל התקן של מסך עם פונקציה של מאגר נתונים זמני במסך. לפני קיימת מסגרת סנכרון, הפונקציה הזו תקבל dma-buf אחר כך, מניחים את מאגר הנתונים הזמני על המסך וחוסמים כשאפשר לראות את מאגר הנתונים הזמני. עבור דוגמה:

/*
 * assumes buffer is ready to be displayed.  returns when buffer is no longer on
 * screen.
 */
void display_buffer(struct dma_buf *buffer);

עם מסגרת הסנכרון, הפונקציה display_buffer הוא מורכב יותר. בזמן הצגה של מאגר נתונים זמני, הוא משויך עם גדר שמציינת מתי מאגר הנתונים הזמני יהיה מוכן. אפשר להצטרף לתור ולהתחיל את העבודה אחרי שהפעילות תתרוקן.

הוספה של עבודות לרשימת 'הבאים בתור' והתחלת עבודה אחרי שמחליטים סתים את המסגרת לא חוסמת כלום. אתם מחזירים מיד את הגדר שיצרתם, כך שתמיד תוכלו לראות את שטח האחסון הזמני לא יוצג. בזמן ההמתנה למאגרי נתונים זמניים, הליבה מופיעה יחסי תלות עם מסגרת הסנכרון:

/*
 * displays buffer when fence is signaled.  returns immediately with a fence
 * that signals when buffer is no longer displayed.
 */
struct sync_fence* display_buffer(struct dma_buf *buffer, struct sync_fence
*fence);

סנכרון השילוב

כאן מוסבר איך לשלב את מסגרת הסנכרון בין ליבה ומרחב עם חלקי מרחב המשתמשים ב-framework של Android והנהגים שחייבים לתקשר שתי רשתות נוירונים זו מול זו. אובייקטים של מרחב ליבה מיוצגים כמתארי קבצים מרחב המשתמשים.

מוסכמות השילוב

יש לפעול בהתאם למוסכמות בנוגע לממשקי HAL של Android:

  • אם ה-API מספק מתאר קובץ שמפנה אל sync_pt, על מנהל ההתקן של הספק או על ממשק ה-HAL שמשתמשים ב-API לסגור את מתאר הקובץ.
  • אם מנהל ההתקן של הספק או ה-HAL מעבירים מתאר קובץ שמכיל sync_pt לפונקציית API, מנהל התקן של הספק או HAL לא יכולים סוגרים את מתאר הקובץ.
  • כדי להמשיך להשתמש במתאר קובץ הגדר, במנהל ההתקן של הספק או HAL חייב לשכפל את המתאר.

השם של אובייקט גדר משתנה בכל פעם שהוא עובר דרך BufferQueue. תמיכה בגדר ליבה מאפשרת לגדרות לקבל מחרוזות לשמות, כך שהסנכרון framework משתמש בשם החלון ובאינדקס מאגר הנתונים הזמני שממתינים בתור לשם גדר, למשל SurfaceView:0. הזה הוא שימושי לניפוי באגים כדי לזהות את המקור של קיפאון כפי שהשמות מופיעים בפלט של /d/sync ובדוחות על באגים.

שילוב ANativeWindow

ב-ANativeWindow יש מוּדעוּת לגדר. dequeueBuffer, ב-queueBuffer וב-cancelBuffer יש פרמטרים של גדר.

שילוב OpenGL ES

שילוב הסנכרון של OpenGL ES מסתמך על שני תוספי EGL:

  • EGL_ANDROID_native_fence_sync מספק דרך גלישת או יצירה של מתארי קבצים מקוריים של Android EGLSyncKHR אובייקטים.
  • EGL_ANDROID_wait_sync מאפשר דוכנים בצד ה-GPU במקום בצד המעבד (CPU), ולגרום ל-GPU להמתין ל-EGLSyncKHR. התוסף EGL_ANDROID_wait_sync זהה ל התוסף EGL_KHR_wait_sync.

כדי להשתמש בתוספים האלה בנפרד, מטמיעים את תוסף EGL_ANDROID_native_fence_sync עם הנכס המשויך תמיכה בליבה (kernel). בשלב הבא, מפעילים את EGL_ANDROID_wait_sync במנהל ההתקן. EGL_ANDROID_native_fence_sync התוסף מורכב מאובייקט גדר מקורי ייחודי EGLSyncKHR מהסוג הזה. כתוצאה מכך, תוספים שחלים על EGLSyncKHR קיים סוגי האובייקטים לא בהכרח חלים על EGL_ANDROID_native_fence אובייקטים, כדי להימנע מאינטראקציות לא רצויות.

התוסף EGL_ANDROID_native_fence_sync כולל רכיב מותאם תואם מאפיין שמתאר קובץ גדר שניתן להגדיר רק בזמן היצירה לא ניתן לשלוח שאילתות ישירות מאובייקט סנכרון קיים. המאפיין הזה ניתן להגדיר אחד משני מצבים:

  • מתאר קובץ גדר חוקי אורז תוכן מקורי קיים מתאר קובץ גידור של Android באובייקט EGLSyncKHR.
  • האפשרות -1 יוצרת מתאר קובץ גדר מקורי של Android אובייקט EGLSyncKHR.

משתמשים בקריאה לפונקציה DupNativeFenceFD() כדי לחלץ את אובייקט EGLSyncKHR מתיאור קובץ הגדר המקורי של Android. התוצאה זהה לזו של שאילתה על המאפיין שהוגדר, אבל היא פועלת לפי המוסכמה שהנמען סוגר את הגדרות (כלומר, הכפילות ). לבסוף, השמדת את האובייקט EGLSyncKHR נסגרת את מאפיין הגדר הפנימית.

שילוב חומרה של Composer

הכלי ליצירת חומרה מטפל בשלושה סוגים של גדרות סנכרון:

  • הגדרות רכישה מועברות יחד עם חוצצי קלט אל השיחות setLayerBuffer ו-setClientTarget. הם מייצגים כתיבה בהמתנה למאגר הנתונים הזמני, והם חייבים לסמן לפני ה - SurfaceFlinger או HWC מנסה לקרוא מהמאגר המשויך כדי לבצע הרכבה.
  • הגדרות השחרור מאוחזרות אחרי הקריאה אל presentDisplay באמצעות הקריאה ל-getReleaseFences. המחרוזות האלה מייצגות קריאה בהמתנה מהמאגר הקודם באותה שכבה. א' לשחרור אותות הגדר כשמערכת HWC כבר לא משתמשת במאגר הנתונים הזמני כי מאגר הנתונים הזמני החליף את המאגר הקודם במסך. הגדרות החסימה מועברות בחזרה לאפליקציה יחד עם מאגרי הנתונים הזמניים הקודמים יוחלף במהלך היצירה הנוכחית. האפליקציה חייבת להמתין עד לשחרר אותות גדר לפני כתיבת תוכן חדש למאגר הנתונים הזמני הוחזרו.
  • הגדרות הקיימות מוחזרות, אחת לכל פריים, כחלק מ את הקריאה אל presentDisplay. גדרות נוכחיות מייצגות כאשר של המסגרת הזו הסתיים, או לחילופין, לאחר כבר לא צריך את תוצאת היצירה של הפריים הקודם. לפיזי מוצגת, presentDisplay מחזירה את גדרות הקיימות המסגרת הנוכחית מופיעה במסך. אחרי שההגדרות הקיימות מוחזרות אפשר לכתוב שוב למאגר הנתונים הזמני SurfaceFlinger, הרלוונטי. במסכים וירטואליים, גדרות נוכחיות מוחזרות אפשר לקרוא אותו ממאגר הנתונים הזמני של הפלט.