הכיתה 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.