กราฟิก

ไอคอน HAL กราฟิกของ Android

เฟรมเวิร์ก Android มี API การเรนเดอร์กราฟิก 2 มิติและ 3 มิติที่หลากหลายซึ่งโต้ตอบกับการใช้งานโปรแกรมควบคุมกราฟิกของผู้ผลิต จึงจำเป็นต้องทำความเข้าใจวิธีการทำงานของ API เหล่านั้นในระดับที่สูงขึ้น หน้านี้จะแนะนำเลเยอร์การจัดการฮาร์ดแวร์โดยตรง (HAL) ของกราฟิกที่ไดรเวอร์เหล่านั้นสร้างขึ้น ก่อนดำเนินการต่อในส่วนนี้ โปรดทำความคุ้นเคยกับคำศัพท์ต่อไปนี้

canvas (คําทั่วไป), Canvas (องค์ประกอบ API)
Canvas คือพื้นผิวการวาดที่จัดการการคอมโพสิตของบิตจริงกับบิตแมปหรือออบเจ็กต์ Surface คลาส Canvas มีเมธอดสําหรับการวาดภาพคอมพิวเตอร์มาตรฐานของบิตแมป เส้น วงกลม สี่เหลี่ยมผืนผ้า ข้อความ และอื่นๆ และเชื่อมโยงกับบิตแมปหรือพื้นผิว ภาพพิมพ์แคนวาสเป็นวิธีที่ง่ายที่สุดในการวาดวัตถุ 2 มิติบนหน้าจอ คลาสพื้นฐานคือ Canvas
ถอนออกได้
ไฟล์วาดคือทรัพยากรภาพแบบคอมไพล์ที่ใช้เป็นพื้นหลัง ชื่อ หรือส่วนอื่นๆ ของหน้าจอได้ โดยปกติแล้ว ระบบจะโหลดรายการที่วาดได้ในองค์ประกอบ UI อื่น เช่น เป็นภาพพื้นหลัง องค์ประกอบที่วาดได้จะรับเหตุการณ์ไม่ได้ แต่กําหนดพร็อพเพอร์ตี้อื่นๆ เช่น สถานะและการกําหนดเวลา เพื่อเปิดใช้คลาสย่อย เช่น ออบเจ็กต์ภาพเคลื่อนไหวหรือคลังรูปภาพ ระบบจะโหลดออบเจ็กต์ที่วาดได้จำนวนมากจากไฟล์ทรัพยากรที่วาดได้ — ไฟล์ XML หรือบิตแมปที่อธิบายรูปภาพ ทรัพยากรที่วาดได้จะคอมไพล์เป็นคลาสย่อยของ android.graphics.drawable ดูข้อมูลเพิ่มเติมเกี่ยวกับไฟล์วาดและทรัพยากรอื่นๆ ได้ที่ภาพรวมแหล่งข้อมูลของแอป
ทรัพยากรเลย์เอาต์
ทรัพยากรเลย์เอาต์คือไฟล์ XML ที่อธิบายเลย์เอาต์ของหน้าจอกิจกรรม ดูข้อมูลเพิ่มเติมได้ที่ทรัพยากรเลย์เอาต์
9 แพตช์ (9-patch, NinePatch)
Nine-Patch คือทรัพยากรบิตแมปที่ปรับขนาดได้ ซึ่งสามารถใช้เป็นพื้นหลังหรือรูปภาพอื่นๆ ในอุปกรณ์ ดูข้อมูลเพิ่มเติมได้ที่Nine-patch
OpenGL ES
OpenGL ES เป็น API แบบข้ามแพลตฟอร์มสำหรับการเรนเดอร์กราฟิก 2 มิติและ 3 มิติ Android มีไลบรารี OpenGL ES สําหรับการแสดงผล 3 มิติที่เร่งด้วยฮาร์ดแวร์ สําหรับการแสดงผล 2 มิติ แคนวาสเป็นตัวเลือกที่ง่ายกว่า OpenGL ES มีอยู่ใน Android Native Development Kit (NDK) แพ็กเกจ android.opengl และ javax.microedition.khronos.opengles แสดงฟังก์ชันการทำงานของ OpenGL ES
แพลตฟอร์ม (คำทั่วไป), Surface (องค์ประกอบ API)
พื้นผิวแสดงบล็อกหน่วยความจําที่คอมโพสิทกับหน้าจอ พื้นผิวจะเก็บภาพพิมพ์แคนวาสไว้สําหรับวาดภาพ และมีเมธอดตัวช่วยต่างๆ ในการวาดเลเยอร์และปรับขนาดออบเจ็กต์ Surface ใช้คลาส SurfaceView แทนคลาส Surface โดยตรง
มุมมองแพลตฟอร์ม (คําทั่วไป), SurfaceView (องค์ประกอบ API)
มุมมองพื้นผิวคือออบเจ็กต์ View ที่รวมออบเจ็กต์ Surface ไว้สำหรับการวาด และแสดงเมธอดในการระบุขนาดและรูปแบบแบบไดนามิก มุมมองพื้นผิวเป็นวิธีวาดภาพที่ไม่ขึ้นอยู่กับเธรด UI สําหรับการดำเนินการที่ต้องใช้ทรัพยากรมาก เช่น เกมหรือการแสดงตัวอย่างจากกล้อง แต่จะใช้หน่วยความจําเพิ่มขึ้น มุมมองพื้นผิวรองรับทั้งกราฟิกแคนวาสและ OpenGL ES คลาสพื้นฐานสําหรับออบเจ็กต์ SurfaceView คือ SurfaceView
ธีม [theme]
ธีมคือชุดของพร็อพเพอร์ตี้ เช่น ขนาดข้อความและสีพื้นหลัง ที่รวมเข้าด้วยกันเพื่อกำหนดการตั้งค่าการแสดงผลเริ่มต้นต่างๆ Android มีธีมมาตรฐาน 2-3 ธีม ซึ่งแสดงอยู่ใน R.style และขึ้นต้นด้วย Theme_
view (คําทั่วไป), View (องค์ประกอบ API)
มุมมองจะวาดพื้นที่สี่เหลี่ยมผืนผ้าบนหน้าจอและจัดการกับการคลิก การกดแป้นพิมพ์ และเหตุการณ์การโต้ตอบอื่นๆ คลาส View เป็นคลาสพื้นฐานสำหรับคอมโพเนนต์เลย์เอาต์ส่วนใหญ่ของกิจกรรมหรือหน้าจอโต้ตอบ เช่น กล่องข้อความและหน้าต่าง ออบเจ็กต์ View ได้รับการเรียกใช้จากออบเจ็กต์หลัก (ดูViewGroup) เพื่อวาดตัวเอง และแจ้งให้ออบเจ็กต์หลักทราบเกี่ยวกับขนาดและตำแหน่งที่ต้องการ ซึ่งออบเจ็กต์หลักอาจไม่สนใจ ดูข้อมูลเพิ่มเติมได้ที่ View
กลุ่มมุมมอง (คําทั่วไป), ViewGroup (องค์ประกอบ API)
กลุ่มมุมมองจะจัดกลุ่มชุดมุมมองย่อย กลุ่มมุมมองมีหน้าที่รับผิดชอบในการตัดสินใจเกี่ยวกับตําแหน่งของมุมมองย่อยและขนาดของมุมมองย่อย รวมถึงการเรียกให้แต่ละมุมมองวาดตัวเองเมื่อเหมาะสม กลุ่มมุมมองบางกลุ่มจะมองไม่เห็นและใช้สําหรับเลย์เอาต์เท่านั้น ขณะที่กลุ่มอื่นๆ มี UI ในตัว เช่น กล่องรายการแบบเลื่อน กลุ่มมุมมองอยู่ในแพ็กเกจ android.widget แต่ขยายคลาส ViewGroup
ลำดับชั้นการแสดงผล
ลําดับชั้นของมุมมองคือการจัดเรียงออบเจ็กต์มุมมองและกลุ่มมุมมองที่กําหนดอินเทอร์เฟซผู้ใช้สําหรับคอมโพเนนต์แต่ละรายการของแอป ลําดับชั้นประกอบด้วยกลุ่มมุมมองที่มีมุมมองย่อยหรือกลุ่มมุมมองย่อยอย่างน้อย 1 รายการ คุณสามารถดูภาพลำดับชั้นของมุมมองสำหรับการแก้ไขข้อบกพร่องและการเพิ่มประสิทธิภาพได้โดยใช้ Hierarchy Viewer ที่มาพร้อมกับ Android SDK
Vulkan
Vulkan เป็น API แบบข้ามแพลตฟอร์มที่มีค่าใช้จ่ายต่ำสำหรับกราฟิก 3 มิติที่มีประสิทธิภาพสูง
วิดเจ็ต
วิดเจ็ตเป็นหนึ่งในชุดคลาสย่อยของมุมมองที่ใช้งานอย่างเต็มรูปแบบซึ่งแสดงผลองค์ประกอบของแบบฟอร์มและองค์ประกอบ UI อื่นๆ เช่น กล่องข้อความหรือเมนูป๊อปอัป เนื่องจากวิดเจ็ตติดตั้งใช้งานอย่างสมบูรณ์แล้ว จึงจัดการการวัด การวาดภาพ และการตอบสนองต่อเหตุการณ์บนหน้าจอได้ วิดเจ็ตอยู่ในแพ็กเกจ android.widget
window (คําทั่วไป), Window (องค์ประกอบ API)
ในแอป Android หน้าต่างคือออบเจ็กต์ที่มาจากคลาส抽象 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 และเครื่องมือจัดเรียงฮาร์ดแวร์ (HWC) เพื่อจัดเรียงกลุ่มพื้นผิว

แอป OpenGL ES อื่นๆ สามารถใช้สตรีมรูปภาพได้เช่นกัน เช่น แอปกล้องที่ใช้สตรีมรูปภาพตัวอย่างจากกล้อง แอปที่ไม่ใช่ GL อาจเป็นผู้บริโภคได้เช่นกัน เช่น คลาส ImageReader

เครื่องมือสร้างฮาร์ดแวร์

การแยกแยะฮาร์ดแวร์สำหรับระบบย่อยของจอแสดงผล SurfaceFlinger สามารถมอบหมายงานบางอย่างของการจัดองค์ประกอบให้กับ HWC เพื่อลดภาระงานจาก OpenGL และ GPU SurfaceFlinger ทำหน้าที่เป็นไคลเอ็นต์ OpenGL ES เพียงตัวเดียว ดังนั้นเมื่อ SurfaceFlinger กำลังคอมโพสบัฟเฟอร์ 1 หรือ 2 รายการเป็นบัฟเฟอร์ที่ 3 อยู่ แสดงว่ากำลังใช้ OpenGL ES วิธีนี้ทำให้การคอมโพสมีประสิทธิภาพน้อยกว่า GPU ที่ใช้การประมวลผลทั้งหมด

Hardware Composer HAL จะทำหน้าที่อีกครึ่งหนึ่งและเป็นจุดศูนย์กลางในการเรนเดอร์กราฟิกทั้งหมดของ Android HWC ต้องรองรับเหตุการณ์ ซึ่งหนึ่งในนั้นคือ VSync (อีกอย่างหนึ่งคือ hotplug สําหรับการรองรับ HDMI แบบพลักแอนด์เพลย์)

Gralloc

จำเป็นต้องใช้ตัวจัดสรรหน่วยความจำกราฟิก (Gralloc) เพื่อจัดสรรหน่วยความจำที่ผู้ผลิตรูปภาพขอ โปรดดูรายละเอียดที่ BufferQueue และ Gralloc

โฟลว์ข้อมูล

แผนภาพต่อไปนี้แสดงไปป์ไลน์กราฟิก Android

โฟลว์ข้อมูลกราฟิก

รูปที่ 2 การรับส่งข้อมูลกราฟิกผ่าน Android

ออบเจ็กต์ทางด้านซ้ายคือโปรแกรมแสดงผลที่สร้างบัฟเฟอร์กราฟิก เช่น หน้าจอหลัก แถบสถานะ และ UI ของระบบ SurfaceFlinger เป็นตัวจัดเรียง และ HWC เป็นตัวจัดเรียง

BufferQueue

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

แผนภาพต่อไปนี้แสดงกระบวนการสื่อสารของ BufferQueue

กระบวนการสื่อสารของ BufferQueue

รูปที่ 3 กระบวนการสื่อสาร BufferQueue

BufferQueue มีตรรกะที่เชื่อมโยงผู้ผลิตสตรีมรูปภาพและผู้บริโภคสตรีมรูปภาพเข้าด้วยกัน ตัวอย่างของโปรแกรมสร้างรูปภาพ ได้แก่ ตัวอย่างภาพจากกล้องที่ HAL ของกล้องหรือเกม OpenGL ES สร้างขึ้น ตัวอย่างผู้บริโภคภาพ ได้แก่ SurfaceFlinger หรือแอปอื่นที่แสดงสตรีม OpenGL ES เช่น แอปกล้องที่แสดงช่องมองภาพ

BufferQueue คือโครงสร้างข้อมูลที่รวมพูลบัฟเฟอร์เข้ากับคิว และใช้ Binder IPC เพื่อส่งบัฟเฟอร์ระหว่างกระบวนการ อินเทอร์เฟซของผู้ผลิตหรือสิ่งที่คุณส่งให้บุคคลที่ต้องการสร้างบัฟเฟอร์กราฟิกคือ IGraphicBufferProducer (เป็นส่วนหนึ่งของ SurfaceTexture) BufferQueue มักใช้เพื่อแสดงผลไปยัง Surface และใช้งานด้วย GL Consumer นอกเหนือจากงานอื่นๆ

BufferQueue สามารถทํางานได้ 3 โหมด ดังนี้

โหมดแบบซิงโครนัส
โดยค่าเริ่มต้น BufferQueue จะทํางานในโหมดแบบซิงค์ ซึ่งบัฟเฟอร์ทั้งหมดที่มาจากผู้ผลิตจะส่งไปยังผู้บริโภค ระบบจะไม่ทิ้งบัฟเฟอร์ในโหมดนี้ และหากตัวสร้างทำงานเร็วเกินไปและสร้างบัฟเฟอร์เร็วกว่าที่ระบบจะดูดซับได้ ก็จะบล็อกและรอบัฟเฟอร์ว่าง
โหมดไม่บล็อก
BufferQueue ยังทำงานในโหมดที่ไม่มีการบล็อกได้ ซึ่งจะสร้างข้อผิดพลาดแทนการรอบัฟเฟอร์ในกรณีดังกล่าว และจะไม่มีการนำบัฟเฟอร์ออกในโหมดนี้เช่นกัน ซึ่งมีประโยชน์ในการหลีกเลี่ยงการหยุดทำงานพร้อมกันที่อาจเกิดขึ้นในซอฟต์แวร์แอปพลิเคชันที่อาจไม่เข้าใจการพึ่งพาที่ซับซ้อนของเฟรมเวิร์กกราฟิก
โหมดทิ้ง
BufferQueue อาจได้รับการกําหนดค่าให้ทิ้งบัฟเฟอร์เก่าแทนที่จะสร้างข้อผิดพลาดหรือรอ ตัวอย่างเช่น หากทำการเรนเดอร์ GL ไปยังมุมมองพื้นผิวและการวาดภาพโดยเร็วที่สุด จะต้องทิ้งบัฟเฟอร์

SurfaceFlinger จะทําหน้าที่เป็นไคลเอ็นต์ OpenGL ES อีกตัวหนึ่งเพื่อดําเนินการส่วนใหญ่นี้ ดังนั้นเมื่อ SurfaceFlinger กำลังคอมโพสบัฟเฟอร์ 1 หรือ 2 รายการเป็นบัฟเฟอร์ที่ 3 อยู่ แสดงว่ากำลังใช้ OpenGL ES

HAL เครื่องมือแต่งฮาร์ดแวร์จะดำเนินการอีกครึ่งหนึ่ง HAL นี้ทำหน้าที่เป็นจุดศูนย์กลางสำหรับการเรนเดอร์กราฟิกทั้งหมดของ Android