Surface ו-SurfaceHolder

אובייקטים של Surface מאפשרים לאפליקציות לעבד תמונות שיוצגו במסכים. ממשקי SurfaceHolder מאפשרים לאפליקציות לערוך ולשלוט בפלטפורמות.

פלטפורמה

משטח הוא ממשק שמאפשר ליצרן להחליף מאגרי נתונים זמניים עם צרכן.

בדרך כלל, פלטפורמות תצוגה משתמשות ב-BufferQueues שמוגדרות לשימוש בזיכרון מטמון משולש. ההקצאה של מאגרי הנתונים הזמניים מתבצעת לפי דרישה, כך שאם היצרן יוצר מאגרי נתונים זמניים בקצב איטי מספיק, למשל בקצב של 30 fps במסך של 60 fps, יכול להיות שיהיו בתור רק שני מאגרי נתונים זמניים שהוקצו. הקצאת מאגרי נתונים לפי דרישה עוזרת לצמצם את צריכת הזיכרון. אפשר לראות סיכום של המאגרים שמשויכים לכל שכבה בפלט dumpsys SurfaceFlinger.

רוב הלקוחות מבצעים רינדור על משטחים באמצעות OpenGL ES או Vulkan. עם זאת, חלק מהלקוחות מבצעים רינדור בפלטפורמות באמצעות בד ציור.

רינדור של קנבס

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

  • lockCanvas() נועל את המאגר לצורך עיבוד ב-CPU ומחזיר Canvas לשימוש בציור.
  • unlockCanvasAndPost() מבטל את הנעילה של המאגר ושולח אותו למרכיב.
  • lockHardwareCanvas() נועל את המאגר לצורך עיבוד ב-GPU ומחזיר קנבס לשימוש בציור.

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

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

SurfaceHolder

SurfaceHolder הוא ממשק שהמערכת משתמשת בו כדי לשתף בעלות על משטחים עם אפליקציות. חלק מהלקוחות שעובדים עם פלטפורמות רוצים SurfaceHolder, כי ממשקי ה-API לקבלת פרמטרים של פלטפורמה ולהגדרתם מיושמים דרך SurfaceHolder. ‫SurfaceView מכיל SurfaceHolder.

רוב הרכיבים שפועלים עם תצוגה כוללים SurfaceHolder. ממשקי API אחרים, כמו MediaCodec, פועלים על המשטח עצמו.