מסגרת סינכרון

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

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

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

סנכרון מפורש

סנכרון מפורש מאפשר ליצרנים ולצרכנים של מאגרי גרפיקה לאותת כאשר הם מסיימים להשתמש במאגר. סנכרון מפורש מיושם ב- kernel-space.

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

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

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

  • sync_timeline
  • sync_pt
  • sync_fence

sync_timeline

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

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

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

sync_pt

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

sync_fence

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

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

  • תת מערכת שטח ליבה המיישמת את מסגרת הסינכרון של מנהל התקן חומרה מסוים. מנהלי התקנים שצריכים להיות מודעים לגדר הם בדרך כלל כל מה שנכנס או מתקשר עם Composer Hardware. קבצי המפתח כוללים:
    • יישום הליבה:
      • kernel/common/include/linux/sync.h
      • kernel/common/drivers/base/sync.c
    • תיעוד על kernel/common/Documentation/sync.txt
    • הספרייה כדי לתקשר עם המרחב הקרנל ב 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);

שילוב סנכרון

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

מוסכמות אינטגרציה

עקוב אחר מוסכמות ממשק Android HAL:

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

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

שילוב חומרי מלחינים

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

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