שפת הצללה של גרפיקה ב-Android‏ (AGSL)

‫Android Graphics Shading Language‏ (AGSL) משמשת ב-Android 13 ומעלה כדי להגדיר את ההתנהגות של אובייקטים RuntimeShader שניתנים לתכנות. התחביר של AGSL דומה מאוד לזה של GLSL fragment shaders, אבל הוא פועל במערכת עיבוד הגרפיקה של Android כדי להתאים אישית את הציור ב-Canvas ולסנן תוכן ב-View.

תיאוריית הפעולה

אפקטים של AGSL הם חלק מצינור העיבוד הגרפי הגדול יותר של Android. כשמערכת Android מנפיקה פעולת ציור מואצת GPU, היא מרכיבה shader של פרגמנט GPU יחיד כדי לבצע את העבודה הנדרשת. בדרך כלל, שיידר כזה כולל כמה חלקים. לדוגמה, יכול להיות שהיא תכלול:

  • הערכה אם פיקסל נמצא בתוך הצורה שמציירים או מחוצה לה (או על הגבול, במקרה כזה יכול להיות שיוחל עליו החלקת קצוות).
  • הערכה אם פיקסל נמצא בתוך אזור החיתוך או מחוצה לו (שוב, עם לוגיקה אפשרית של החלקת קצוות לפיקסלים בגבול).
  • הלוגיקה של Shader בPaint. ה-Shader יכול להיות למעשה עץ של אובייקטים (בגלל ComposeShader ותכונות אחרות שמתוארות בהמשך).
  • לוגיקה דומה חלה על ColorFilter.
  • קוד מיזוג (לסוגים מסוימים של BlendMode).
  • קוד להמרת מרחב צבעים, כחלק מניהול הצבעים ב-Android.
  • גם אם ל-Paint יש עץ מורכב של אובייקטים בשדות Shader, ColorFilter או BlendMode, עדיין יש רק shader אחד של שבר GPU. כל צומת בעץ הזה יוצר פונקציה אחת. קוד החיתוך וקוד הגיאומטריה יוצרים כל אחד פונקציה. יכול להיות שקוד המיזוג ייצור פונקציה. לאחר מכן, ה-fragment shader הכולל קורא לכל הפונקציות האלה (שיכולות לקרוא לפונקציות אחרות, למשל במקרה של עץ shader).

אפקט AGSL תורם פונקציה (או פונקציות) ל-fragment shader של ה-GPU.

תחביר בסיסי

‫AGSL (ו-GLSL) הן שפות ספציפיות לדומיין בסגנון C. סוגים כמו bool ו-int עוקבים אחרי המקבילים שלהם בשפת C; יש סוגים נוספים לתמיכה בווקטורים ובמטריצות שתומכים בפונקציונליות של הדומיין.

אפשר להחיל מסננים על סוגים כדי לתת רמזים מדויקים, באופן ייחודי לשפות הצללה. מבני בקרה כמו הצהרות if-else פועלים בדומה לאופן שבו הם פועלים ב-C. השפה גם תומכת בהצהרות switch ובלולאות for עם מגבלות. חלק ממבני הבקרה דורשים ביטויים קבועים שאפשר להעריך בזמן ההידור.

‫AGSL תומך בפונקציות. כל תוכנית Shader מתחילה בפונקציה main. יש תמיכה בפונקציות שהוגדרו על ידי המשתמש, אבל אין תמיכה ברקורס מכל סוג שהוא. הפונקציות משתמשות במוסכמת קריאה מסוג 'החזרת ערך'. הערכים שמועברים לפונקציות מועתקים לפרמטרים כשהפונקציה נקראת, והפלט מועתק בחזרה. זה נקבע על ידי המאפיינים in, out ו-inout.