הכיתה BufferQueue
מחברת בין רכיבים שיוצרים מאגרים של נתונים גרפיים (בעלי תוכן דיגיטלי) לבין רכיבים שמקבלים את הנתונים כדי להציג אותם או לעבד אותם (צרכנים). כמעט כל מה שנעביר מאגרים של נתונים גרפיים דרך המערכת מסתמך על BufferQueue
.
מנהל הזיכרון של Gralloc מבצע הקצאות של מאגרים, והוא מיושם באמצעות שני ממשקי HIDL ספציפיים לספק (ראו hardware/interfaces/graphics/allocator/
ו-hardware/interfaces/graphics/mapper/
). הפונקציה allocate()
מקבלת את הארגומנטים הצפויים (רוחב, גובה, פורמט פיקסלים) וגם קבוצה של דגלים לשימוש.
יוצרים ומשתמשים של BufferQueue
הצרכנים יוצרים את מבנה הנתונים של BufferQueue
, והוא בבעלות שלהם. הם יכולים להתקיים בתהליכים שונים מאלה של היוצרים שלהם. כשבעלים של מקור נתונים זקוק למאגר, הוא מבקש מאגר פנוי מ-BufferQueue
באמצעות קריאה ל-dequeueBuffer()
, ומציין את רוחב המאגר, גובהו, פורמט הפיקסלים ודגלי השימוש שלו. לאחר מכן המפיק מאכלס את המאגר ומחזיר אותו לתור באמצעות קריאה ל-queueBuffer()
. לאחר מכן, הצרכן מקבל את המאגר באמצעות acquireBuffer()
ומשתמש בתוכן המאגר. כשהצרכן מסיים, הוא מחזיר את המאגר לתור באמצעות קריאה ל-releaseBuffer()
. מסגרת הסנכרון קובעת איך מאגרי נתונים נעים בצינור עיבוד הנתונים הגרפי של Android.
מאפיינים מסוימים של BufferQueue
, כמו המספר המקסימלי של מאגרי נתונים שאפשר לאחסן בו, נקבעים במשותף על ידי היצרן והצרכן.
עם זאת, BufferQueue
מקצה מאגרים לפי הצורך.
מאגרי הנתונים נשמרים אלא אם המאפיינים שלהם משתנים. לדוגמה, אם היוצר מבקש מאגרי נתונים בגודל שונה, מאגרי הנתונים הישנים משוחררים ומאגרי נתונים חדשים מוקצים על פי דרישה.
BufferQueue
אף פעם לא מעתיק את תוכן המאגר, כי העברת כמות כה גדולה של נתונים היא לא יעילה. במקום זאת, מאגרים תמיד מועברים באמצעות אחיזה (handle).
מעקב אחר BufferQueue באמצעות Systrace
כדי להבין איך מאגרי הגרפיקה נעים, אפשר להשתמש ב- Systrace, כלי שמתעדה את פעילות המכשיר בפרק זמן קצר. קוד הגרפיקה ברמת המערכת מצויד בכלים מתאימים, וכך גם חלק גדול מקוד מסגרת האפליקציה הרלוונטי.
כדי להשתמש ב-Systrace, מפעילים את התגים gfx
, view
ו-sched
. אובייקטים מסוג BufferQueue
מוצגים במעקב.
לדוגמה, אם מבצעים מעקב בזמן הפעלת הווידאו של Grafika (SurfaceView), בשורה SurfaceView מוצג מספר המאגרים שנמצאים בתור בכל רגע נתון.
הערך הזה עולה בזמן שהאפליקציה פעילה, וכתוצאה מכך מתבצע עיבוד של התמונות על ידי המפענח של MediaCodec. הערך יורד בזמן ש-SurfaceFlinger פועל ומשתמש במאגרים. כשמציגים סרטון ב-30 fps, הערך של התור משתנה מ-0 ל-1 כי התצוגה של 60 fps בערך יכולה לעמוד בקצב של המקור. SurfaceFlinger מתעורר רק כשיש עבודה לעשות, ולא 60 פעמים בשנייה. המערכת מנסה להימנע מעבודה ומשביתת את VSync אם אין דבר שמעדכן את המסך.
אם עוברים לסרטון ה-Play של Grafika (TextureView) ומבצעים מעקב חדש, מופיעה שורה עם הכיתוב com.android.grafika
 / com.android.grafika.PlayMovieActivity
.
זוהי שכבת ממשק המשתמש הראשית, שהיא מופע נוסף של BufferQueue
. מכיוון ש-TextureView מבצע עיבוד ברמת שכבת ממשק המשתמש ולא בשכבה נפרדת, כל העדכונים שמבוססים על וידאו מוצגים כאן.
Gralloc
מנהל הקצאות ה-HAL של Gralloc hardware/libhardware/include/hardware/gralloc.h
מבצע הקצאות של מאגרים באמצעות דגלי שימוש. דגלי השימוש כוללים מאפיינים כמו:
- באיזו תדירות תהיה גישה לזיכרון מהתוכנה (מעבד)
- תדירות הגישה לזיכרון מהחומרה (GPU)
- אם הזיכרון ישמש כמרקם של OpenGL ES (GLES)
- אם הזיכרון ישמש מקודד וידאו
לדוגמה, אם פורמט המאגר של המפיק מציין RGBA_8888
פיקסלים, והמפיק מציין שהגישה למאגר תתבצע מתוכנה (כלומר אפליקציה תגע בפיקסלים ב-CPU), Gralloc יוצר מאגר עם 4 בייטים לכל פיקסל בסדר R-G-B-A. אם במקום זאת, המפיק מציין שהגישה למאגר שלו תהיה רק מהחומרה וכטקסטורה של GLES, Gralloc יכול לעשות כל מה שמתאים למנהל ה-GLES, כמו סדר BGRA, פריסות swizzled לא לינאריות ופלטפורמות צבע חלופיות. כדי לשפר את הביצועים, כדאי לאפשר לחומרה להשתמש בפורמט המועדף עליה.
לא ניתן לשלב ערכים מסוימים בפלטפורמות מסוימות. לדוגמה, יכול להיות שדגל המקודד של הסרטון מחייב פיקסלים מסוג YUV, ולכן הוספת גישה לתוכנה והצגת הערך RGBA_8888
נכשלים.
אפשר להעביר את ה-handle שמוחזר על ידי Gralloc בין תהליכים באמצעות Binder.
מאגרי אחסון מוגנים
דגל השימוש של Gralloc GRALLOC_USAGE_PROTECTED
מאפשר להציג את מאגר הגרפיקה רק דרך נתיב שמוגן בחומרה. אלה הדרכים היחידות להציג תוכן DRM (לא ניתן לגשת למאגרים שמוגנים על ידי DRM באמצעות SurfaceFlinger או באמצעות מנהל ההתקן של OpenGL ES).
אפשר להציג סרטון שמוגן באמצעות DRM רק בשכבת-על. נגני וידאו שתומכים בתוכן מוגן חייבים להיות מוטמעים באמצעות SurfaceView. תוכנה שפועלת בחומרה לא מוגנת לא יכולה לקרוא או לכתוב במאגר. נתיבים שמוגנים בחומרה חייבים להופיע בשכבת-העל של Hardware Composer (כלומר, סרטונים מוגנים נעלמים מהמסך אם Hardware Composer עובר ליצירת קומפוזיציה ב-OpenGL ES).
פרטים על תוכן מוגן זמינים במאמר DRM.