מסגרת הסנכרון מתארת במפורש יחסי תלות בין פעולות אסינכרוניות שונות במערכת הגרפיקה של 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
מספק דרך גלישת או יצירה של מתארי קבצים מקוריים של AndroidEGLSyncKHR
אובייקטים.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, הרלוונטי. במסכים וירטואליים, גדרות נוכחיות מוחזרות אפשר לקרוא אותו ממאגר הנתונים הזמני של הפלט.