
เฟรมเวิร์ก Android มี API การเรนเดอร์กราฟิก 2 มิติและ 3 มิติที่หลากหลายซึ่งโต้ตอบกับการใช้งานโปรแกรมควบคุมกราฟิกของผู้ผลิต จึงจําเป็นต้องทําความเข้าใจวิธีทํางานของ API เหล่านั้นในระดับที่สูงขึ้น หน้านี้จะแนะนำเลเยอร์การจัดการฮาร์ดแวร์โดยตรง (HAL) ของกราฟิกที่สร้างขึ้นจากไดรเวอร์เหล่านั้น ก่อนดำเนินการต่อในส่วนนี้ โปรดทำความคุ้นเคยกับคำศัพท์ต่อไปนี้
Canvas
(องค์ประกอบ API)Surface
Canvas
มีเมธอดสําหรับการวาดภาพคอมพิวเตอร์มาตรฐานของบิตแมป เส้น วงกลม สี่เหลี่ยมผืนผ้า ข้อความ และอื่นๆ และเชื่อมโยงกับบิตแมปหรือพื้นผิว ภาพพิมพ์แคนวาสเป็นวิธีที่ง่ายที่สุดในการวาดวัตถุ 2 มิติบนหน้าจอ คลาสพื้นฐานคือ
Canvas
android.graphics.drawable
ดูข้อมูลเพิ่มเติมเกี่ยวกับไฟล์วาดและทรัพยากรอื่นๆ ได้ที่แหล่งข้อมูล
android.opengl
และ javax.microedition.khronos.opengles
แสดงฟังก์ชันการทำงานของ OpenGL ESSurface
(องค์ประกอบ API)Surface
ใช้คลาส
SurfaceView
แทนคลาส
Surface
โดยตรง
SurfaceView
(องค์ประกอบ API)View
ที่รวมออบเจ็กต์ Surface
ไว้สำหรับการวาด และแสดงเมธอดในการระบุขนาดและรูปแบบแบบไดนามิก มุมมอง Surface มีวิธีวาดภาพโดยอิสระจากเธรด UI สำหรับการดำเนินการที่ต้องใช้ทรัพยากรมาก เช่น เกมหรือการแสดงตัวอย่างจากกล้อง แต่จะใช้หน่วยความจำเพิ่มขึ้น มุมมองพื้นผิวรองรับทั้งกราฟิกแคนวาสและ OpenGL ES คลาสพื้นฐานสําหรับออบเจ็กต์ SurfaceView
คือ SurfaceView
R.style
และขึ้นต้นด้วย Theme_
View
(องค์ประกอบ API)View
เป็นคลาสพื้นฐานสำหรับคอมโพเนนต์เลย์เอาต์ส่วนใหญ่ของกิจกรรมหรือหน้าจอโต้ตอบ เช่น กล่องข้อความและหน้าต่าง ออบเจ็กต์ View
ได้รับการเรียกใช้จากออบเจ็กต์หลัก (ดูViewGroup
) เพื่อวาดตัวเอง และแจ้งให้ออบเจ็กต์หลักทราบเกี่ยวกับขนาดและตำแหน่งที่ต้องการ ซึ่งออบเจ็กต์หลักอาจไม่สนใจ ดูข้อมูลเพิ่มเติมได้ที่
View
ViewGroup
(องค์ประกอบ API)widget
แต่ขยายคลาส ViewGroup
android.widget
Window
(องค์ประกอบ API)Window
ที่ระบุองค์ประกอบของหน้าต่างทั่วไป เช่น รูปลักษณ์ ข้อความในแถบชื่อ และตำแหน่งและเนื้อหาของเมนู กล่องโต้ตอบและกิจกรรมใช้การติดตั้งใช้งานคลาส Window
เพื่อแสดงผลออบเจ็กต์ Window
คุณไม่จำเป็นต้องใช้คลาส Window
หรือใช้หน้าต่างในแอปนักพัฒนาแอปวาดรูปภาพบนหน้าจอได้ 3 วิธี ได้แก่ Canvas, OpenGL ES หรือ Vulkan
คอมโพเนนต์กราฟิกของ Android
ไม่ว่านักพัฒนาซอฟต์แวร์จะใช้ API การเรนเดอร์ใด ทุกอย่างก็จะแสดงผลบนแพลตฟอร์ม พื้นผิวแสดงฝั่งผู้ผลิตของคิวบัฟเฟอร์ที่ SurfaceFlinger มักใช้ หน้าต่างทุกบานที่สร้างขึ้นบนแพลตฟอร์ม Android ได้รับการรองรับจาก Surface SurfaceFlinger จะคอมโพสิทพื้นผิวที่มองเห็นได้ทั้งหมดที่ผ่านการจัดการแสดงผล
แผนภาพต่อไปนี้แสดงวิธีที่คอมโพเนนต์หลักทํางานร่วมกัน

รูปที่ 1 วิธีแสดงผลแพลตฟอร์ม
องค์ประกอบหลักมีคำอธิบายอยู่ด้านล่าง
ผู้ผลิตสตรีมรูปภาพ
โปรแกรมสร้างสตรีมรูปภาพอาจเป็นอะไรก็ได้ที่สร้างบัฟเฟอร์กราฟิกเพื่อใช้งาน เช่น OpenGL ES, Canvas 2D และโปรแกรมถอดรหัสวิดีโอของ Media Server
ผู้บริโภคสตรีมรูปภาพ
ผู้บริโภคสตรีมรูปภาพที่พบได้ทั่วไปที่สุดคือ SurfaceFlinger ซึ่งเป็นบริการของระบบที่บริโภคพื้นผิวที่มองเห็นได้ในปัจจุบันและประกอบพื้นผิวเหล่านั้นลงในจอแสดงผลโดยใช้ข้อมูลที่ได้จาก Window Manager SurfaceFlinger เป็นบริการเดียวที่แก้ไขเนื้อหาของจอแสดงผลได้ SurfaceFlinger ใช้ OpenGL และเครื่องมือจัดเรียงฮาร์ดแวร์เพื่อจัดเรียงกลุ่มพื้นผิว
แอป OpenGL ES อื่นๆ สามารถใช้สตรีมรูปภาพได้เช่นกัน เช่น แอปกล้องที่ใช้สตรีมรูปภาพตัวอย่างจากกล้อง แอปที่ไม่ใช่ GL อาจเป็นผู้บริโภคได้เช่นกัน เช่น คลาส ImageReader
เครื่องมือสร้างฮาร์ดแวร์
การแยกแยะฮาร์ดแวร์สำหรับระบบย่อยของจอแสดงผล SurfaceFlinger สามารถมอบหมายงานบางอย่างเกี่ยวกับการวางองค์ประกอบให้กับเครื่องมือจัดองค์ประกอบฮาร์ดแวร์เพื่อลดภาระงานจาก OpenGL และ GPU SurfaceFlinger ทำหน้าที่เป็นไคลเอ็นต์ OpenGL ES เพียงตัวเดียว ดังนั้นเมื่อ SurfaceFlinger กำลังคอมโพสบัฟเฟอร์ 1 หรือ 2 รายการเป็นบัฟเฟอร์ที่ 3 อยู่ แสดงว่ากำลังใช้ OpenGL ES วิธีนี้ทำให้การคอมโพสิตใช้พลังงานน้อยกว่าการให้ GPU ทำการประมวลผลทั้งหมด
Hardware Composer HAL จะทำหน้าที่อีกครึ่งหนึ่งและเป็นจุดศูนย์กลางในการเรนเดอร์กราฟิกทั้งหมดของ Android โปรแกรมคอมโพสิเตอร์ฮาร์ดแวร์ต้องรองรับเหตุการณ์ ซึ่งหนึ่งในนั้นคือ VSYNC (อีกอย่างหนึ่งคือ hotplug สําหรับการรองรับ HDMI แบบพลักแอนด์เพลย์)
Gralloc
จำเป็นต้องใช้ตัวจัดสรรหน่วยความจำกราฟิก (Gralloc) เพื่อจัดสรรหน่วยความจำที่ผู้ผลิตรูปภาพขอ โปรดดูรายละเอียดที่ Gralloc HAL
โฟลว์ข้อมูล
ดูภาพแสดงไปป์ไลน์กราฟิก Android ได้ในแผนภาพต่อไปนี้

รูปที่ 2 การรับส่งข้อมูลกราฟิกผ่าน Android
ออบเจ็กต์ทางด้านซ้ายคือโปรแกรมแสดงผลที่สร้างบัฟเฟอร์กราฟิก เช่น หน้าจอหลัก แถบสถานะ และ UI ของระบบ SurfaceFlinger คือคอมโพสิตอร์ และ Hardware Composer คือคอมโพเซอร์
BufferQueue
BufferQueues เป็นกาวเชื่อมระหว่างคอมโพเนนต์กราฟิก Android รายการเหล่านี้เป็นคิวคู่ที่สื่อกลางบัฟเฟอร์รอบอย่างต่อเนื่องจากผู้ผลิตไปยังผู้บริโภค เมื่อผู้ผลิตส่งบัฟเฟอร์แล้ว SurfaceFlinger จะมีหน้าที่รับผิดชอบในการคอมโพสทุกอย่างบนจอแสดงผล
ดูกระบวนการสื่อสารของ BufferQueue ได้ในแผนภาพต่อไปนี้

รูปที่ 3 กระบวนการสื่อสาร BufferQueue
BufferQueue มีตรรกะที่เชื่อมโยงผู้ผลิตสตรีมรูปภาพและผู้บริโภคสตรีมรูปภาพเข้าด้วยกัน ตัวอย่างของโปรแกรมสร้างรูปภาพ ได้แก่ ตัวอย่างภาพจากกล้องที่ HAL ของกล้องหรือเกม OpenGL ES สร้างขึ้น ตัวอย่างผู้บริโภคภาพ ได้แก่ SurfaceFlinger หรือแอปอื่นที่แสดงสตรีม OpenGL ES เช่น แอปกล้องที่แสดงช่องมองภาพ
BufferQueue คือโครงสร้างข้อมูลที่รวมพูลบัฟเฟอร์เข้ากับคิว และใช้ Binder IPC เพื่อส่งบัฟเฟอร์ระหว่างกระบวนการ อินเทอร์เฟซของผู้ผลิตหรือสิ่งที่คุณส่งให้บุคคลที่ต้องการสร้างบัฟเฟอร์กราฟิกคือ IGraphicBufferProducer (เป็นส่วนหนึ่งของ SurfaceTexture) BufferQueue มักใช้เพื่อแสดงผลไปยัง Surface และใช้งานด้วย GLConsumer รวมไปถึงงานอื่นๆ
BufferQueue ทำงานได้ 3 โหมด ดังนี้
โหมดแบบซิงค์ - โดยค่าเริ่มต้น BufferQueue จะทํางานในโหมดแบบซิงค์ ซึ่งบัฟเฟอร์ทั้งหมดที่มาจากผู้ผลิตจะส่งไปยังผู้บริโภค ระบบจะไม่ทิ้งบัฟเฟอร์ในโหมดนี้ และหากตัวสร้างทำงานเร็วเกินไปและสร้างบัฟเฟอร์เร็วกว่าที่ระบบจะดูดซับได้ ก็จะบล็อกและรอบัฟเฟอร์ว่าง
โหมดที่ไม่มีการบล็อก - BufferQueue ยังทํางานในโหมดที่ไม่มีการบล็อกได้ ซึ่งจะสร้างข้อผิดพลาดแทนการรอบัฟเฟอร์ในกรณีเหล่านั้น และระบบจะไม่ทิ้งบัฟเฟอร์ในโหมดนี้เช่นกัน ซึ่งมีประโยชน์ในการหลีกเลี่ยงการหยุดทำงานพร้อมกันที่อาจเกิดขึ้นในซอฟต์แวร์แอปพลิเคชันที่อาจไม่เข้าใจการพึ่งพาที่ซับซ้อนของเฟรมเวิร์กกราฟิก
โหมดทิ้ง - สุดท้าย คุณอาจกำหนดค่า BufferQueue ให้ทิ้งบัฟเฟอร์เก่าแทนที่จะสร้างข้อผิดพลาดหรือรอ ตัวอย่างเช่น หากทำการเรนเดอร์ GL ไปยังมุมมองพื้นผิวและการวาดภาพโดยเร็วที่สุด จะต้องทิ้งบัฟเฟอร์
SurfaceFlinger จะทําหน้าที่เป็นไคลเอ็นต์ OpenGL ES อีกตัวหนึ่งเพื่อดําเนินการส่วนใหญ่นี้ ดังนั้นเมื่อ SurfaceFlinger กำลังคอมโพสบัฟเฟอร์ 1 หรือ 2 รายการเป็นบัฟเฟอร์ที่ 3 อยู่ แสดงว่าแอปกำลังใช้ OpenGL ES
HAL เครื่องมือแต่งฮาร์ดแวร์จะดำเนินการอีกครึ่งหนึ่ง HAL นี้ทำหน้าที่เป็นจุดศูนย์กลางของการแสดงผลกราฟิก Android ทั้งหมด