กราฟิก

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

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

canvas (คำทั่วไป), Canvas (องค์ประกอบ API)
ผืนผ้าใบเป็นพื้นผิวรูปวาดที่จัดการการผสมบิตจริงกับบิตแมปหรือวัตถุ Surface Canvas มีวิธีการสำหรับการวาดภาพบิตแมป เส้น วงกลม สี่เหลี่ยม ข้อความ และอื่นๆ โดยใช้คอมพิวเตอร์มาตรฐาน และผูกไว้กับบิตแมปหรือพื้นผิว ผืนผ้าใบเป็นวิธีที่ง่ายที่สุดและง่ายที่สุดในการวาดวัตถุ 2 มิติบนหน้าจอ คลาสพื้นฐานคือ Canvas
วาดได้
Drawable เป็นทรัพยากรภาพที่รวบรวมซึ่งสามารถใช้เป็นพื้นหลัง ชื่อ หรือส่วนอื่นๆ ของหน้าจอได้ โดยทั่วไปแล้ว Drawable จะถูกโหลดลงในองค์ประกอบ UI อื่น เช่น เป็นภาพพื้นหลัง Drawable ไม่สามารถรับเหตุการณ์ได้ แต่จะกำหนดคุณสมบัติอื่นๆ มากมาย เช่น สถานะและการกำหนดเวลา เพื่อเปิดใช้งานคลาสย่อย เช่น ออบเจ็กต์แอนิเมชันหรือไลบรารีรูปภาพ วัตถุที่วาดได้จำนวนมากถูกโหลดจากไฟล์ทรัพยากรที่วาดได้ — ไฟล์ XML หรือบิตแมปที่อธิบายรูปภาพ ทรัพยากรที่ดึงออกมาได้จะถูกคอมไพล์เป็นคลาสย่อยของ android.graphics.drawable สำหรับข้อมูลเพิ่มเติมเกี่ยวกับสิ่งที่ถอนออกได้และทรัพยากรอื่นๆ โปรดดูที่ แหล่งข้อมูล
ทรัพยากรเค้าโครง
ทรัพยากรโครงร่างคือไฟล์ XML ที่อธิบายโครงร่างของหน้าจอกิจกรรม สำหรับข้อมูลเพิ่มเติม โปรดดูที่ ทรัพยากรเค้าโครง
เก้าแพทช์ (9-แพทช์, NinePatch)
เก้าแพตช์เป็นทรัพยากรบิตแมปที่ปรับขนาดได้ซึ่งสามารถใช้สำหรับพื้นหลังหรือรูปภาพอื่นๆ บนอุปกรณ์ได้ สำหรับข้อมูลเพิ่มเติม โปรดดูที่ Nine-patch
OpenGL ES
OpenGL ES เป็น API ข้ามแพลตฟอร์มสำหรับการเรนเดอร์กราฟิก 2D และ 3D Android มีไลบรารี OpenGL ES สำหรับการเรนเดอร์ 3 มิติที่เร่งด้วยฮาร์ดแวร์ สำหรับการเรนเดอร์ 2D แคนวาสเป็นตัวเลือกที่ง่ายกว่า 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 สำหรับการดำเนินการที่ต้องใช้ทรัพยากรมาก เช่น เกมหรือการแสดงตัวอย่างกล้อง แต่ส่งผลให้ใช้หน่วยความจำเพิ่มเติม มุมมองพื้นผิวรองรับทั้งกราฟิก Canvas และ OpenGL ES คลาสพื้นฐานสำหรับวัตถุ SurfaceView คือ SurfaceView
ธีม
ธีมคือชุดของคุณสมบัติ เช่น ขนาดข้อความและสีพื้นหลัง ที่รวมเข้าด้วยกันเพื่อกำหนดการตั้งค่าการแสดงผลเริ่มต้นต่างๆ Android มีธีมมาตรฐานอยู่บ้าง โดยอยู่ในรายการ R.style และนำหน้าด้วย Theme_
มุมมอง (คำทั่วไป), View (องค์ประกอบ API)
มุมมองจะวาดพื้นที่สี่เหลี่ยมบนหน้าจอและจัดการการคลิก การกดแป้นพิมพ์ และเหตุการณ์การโต้ตอบอื่นๆ คลาส View เป็นคลาสพื้นฐานสำหรับองค์ประกอบโครงร่างส่วนใหญ่ของหน้าจอกิจกรรมหรือกล่องโต้ตอบ เช่น กล่องข้อความและหน้าต่าง วัตถุ View ได้รับการเรียกจากวัตถุแม่ (ดู ViewGroup ) เพื่อวาดตัวเอง และแจ้งให้วัตถุแม่ทราบเกี่ยวกับขนาดและตำแหน่งที่ต้องการ ซึ่งผู้ปกครองอาจไม่เคารพ สำหรับข้อมูลเพิ่มเติม โปรดดู View
กลุ่มมุมมอง (คำทั่วไป), ViewGroup (องค์ประกอบ API)
กลุ่มมุมมองจัดกลุ่มชุดของมุมมองย่อย กลุ่มมุมมองมีหน้าที่รับผิดชอบในการตัดสินใจว่าจะจัดวางมุมมองของเด็กไว้ที่ใดและจะใหญ่แค่ไหน รวมถึงการเรียกร้องให้แต่ละมุมมองดึงตนเองออกมาเมื่อเหมาะสม กลุ่มมุมมองบางกลุ่มจะมองไม่เห็นและมีไว้สำหรับเค้าโครงเท่านั้น ในขณะที่กลุ่มอื่นๆ มี UI ภายใน เช่น กล่องรายการแบบเลื่อน กลุ่มมุมมองอยู่ในแพ็คเกจ widget แต่ขยายคลาส ViewGroup
ดูลำดับชั้น
ลำดับชั้นของมุมมองคือการจัดเรียงออบเจ็กต์มุมมองและกลุ่มมุมมองที่กำหนดอินเทอร์เฟซผู้ใช้สำหรับแต่ละองค์ประกอบของแอป ลำดับชั้นประกอบด้วยกลุ่มมุมมองที่มีมุมมองย่อยหรือกลุ่มมุมมองตั้งแต่หนึ่งรายการขึ้นไป คุณสามารถรับภาพการแสดงลำดับชั้นของมุมมองสำหรับการดีบักและการปรับให้เหมาะสมได้โดยใช้ โปรแกรมดูลำดับชั้น ที่มาพร้อมกับ Android SDK
วัลแคน
Vulkan เป็น API ข้ามแพลตฟอร์มที่มีค่าใช้จ่ายต่ำสำหรับกราฟิก 3 มิติประสิทธิภาพสูง
วิดเจ็ต
วิดเจ็ตเป็นหนึ่งในชุดของคลาสย่อยมุมมองที่นำไปใช้งานอย่างสมบูรณ์ ซึ่งแสดงองค์ประกอบแบบฟอร์มและส่วนประกอบ UI อื่นๆ เช่น กล่องข้อความหรือเมนูป๊อปอัป เนื่องจากวิดเจ็ตได้รับการติดตั้งใช้งานอย่างสมบูรณ์ จึงสามารถจัดการการวัด การวาดตัวเอง และตอบสนองต่อเหตุการณ์บนหน้าจอได้ วิดเจ็ตอยู่ในแพ็คเกจ android.widget
หน้าต่าง (คำทั่วไป), Window (องค์ประกอบ API)
ในแอป Android หน้าต่างคือออบเจ็กต์ที่ได้มาจากคลาสนามธรรมของ Window ที่ระบุองค์ประกอบของหน้าต่างทั่วไป เช่น รูปลักษณ์ ข้อความในแถบชื่อเรื่อง ตลอดจนตำแหน่งและเนื้อหาของเมนู กล่องโต้ตอบและกิจกรรมใช้การดำเนินการของคลาส Window เพื่อแสดงวัตถุ Window คุณไม่จำเป็นต้องใช้คลาส Window หรือใช้ windows ในแอปของคุณ

นักพัฒนาแอปวาดภาพลงบนหน้าจอได้สามวิธี: ด้วย Canvas , OpenGL ES หรือ Vulkan

ส่วนประกอบกราฟิกของ Android

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

แผนภาพต่อไปนี้แสดงวิธีการทำงานร่วมกันของส่วนประกอบหลัก:

ส่วนประกอบการแสดงภาพ

รูปที่ 1 วิธีการเรนเดอร์พื้นผิว

ส่วนประกอบหลักมีการอธิบายไว้ด้านล่าง:

ผู้ผลิตสตรีมรูปภาพ

ผู้ผลิตสตรีมรูปภาพสามารถเป็นอะไรก็ได้ที่สร้างบัฟเฟอร์กราฟิกสำหรับการบริโภค ตัวอย่าง ได้แก่ OpenGL ES, Canvas 2D และตัวถอดรหัสวิดีโอมีเดียเซิร์ฟเวอร์

ผู้บริโภคสตรีมรูปภาพ

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

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

นักแต่งเพลงฮาร์ดแวร์

นามธรรมฮาร์ดแวร์สำหรับระบบย่อยการแสดงผล SurfaceFlinger สามารถมอบหมายงานองค์ประกอบบางอย่างให้กับ Hardware Composer เพื่อถ่ายโอนงานจาก OpenGL และ GPU SurfaceFlinger ทำหน้าที่เป็นไคลเอนต์ OpenGL ES อื่น ดังนั้น เมื่อ SurfaceFlinger กำลังรวมบัฟเฟอร์หนึ่งหรือสองลงในบัฟเฟอร์ที่สาม ตัวอย่างเช่น บัฟเฟอร์นั้นกำลังใช้ OpenGL ES ทำให้การประกอบพลังงานต่ำกว่าการให้ GPU ทำการคำนวณทั้งหมด

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

กราลอค

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

การไหลของข้อมูล

ดูไดอะแกรมต่อไปนี้สำหรับการพรรณนาของไปป์ไลน์กราฟิก Android:

การไหลของข้อมูลกราฟิก

รูปที่ 2 ข้อมูลกราฟิกไหลผ่าน Android

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

บัฟเฟอร์คิว

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

ดูไดอะแกรมต่อไปนี้สำหรับกระบวนการสื่อสาร BufferQueue

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

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

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

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

BufferQueue สามารถทำงานในสามโหมดที่แตกต่างกัน:

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

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

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

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

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