คลาส BufferQueue เชื่อมต่อส่วนประกอบที่สร้างบัฟเฟอร์ของข้อมูลกราฟิก ( ผู้ผลิต ) กับส่วนประกอบที่ยอมรับข้อมูลสำหรับการแสดงผลหรือการประมวลผลเพิ่มเติม ( ผู้บริโภค ) เกือบทุกอย่างที่ย้ายบัฟเฟอร์ของข้อมูลกราฟิกผ่านระบบอาศัย BufferQueue
ตัวจัดสรรหน่วยความจำ Gralloc ดำเนินการจัดสรรบัฟเฟอร์และใช้งานผ่านอินเทอร์เฟซ HIDL เฉพาะผู้จำหน่ายสองอินเทอร์เฟซ (ดู hardware/interfaces/graphics/allocator/
และ hardware/interfaces/graphics/mapper/
) ฟังก์ชัน allocate()
รับอาร์กิวเมนต์ที่คาดไว้ (ความกว้าง ความสูง รูปแบบพิกเซล) เช่นเดียวกับชุดของแฟล็กการใช้งาน
ผู้ผลิตและผู้บริโภค BufferQueue
ผู้บริโภคสร้างและเป็นเจ้าของโครงสร้างข้อมูล BufferQueue และสามารถอยู่ในกระบวนการที่แตกต่างจากผู้ผลิต เมื่อผู้ผลิตต้องการบัฟเฟอร์ จะขอบัฟเฟอร์ฟรีจาก BufferQueue โดยการเรียก dequeueBuffer()
โดยระบุความกว้าง ความสูง รูปแบบพิกเซล และแฟล็กการใช้งานของบัฟเฟอร์ จากนั้นผู้ผลิตจะเติมบัฟเฟอร์และส่งกลับบัฟเฟอร์ไปยังคิวโดยเรียก queueBuffer()
ถัดไป ผู้บริโภคได้รับบัฟเฟอร์ด้วย acquireBuffer()
และใช้เนื้อหาบัฟเฟอร์ เมื่อผู้ใช้บริการเสร็จสิ้น มันจะส่งคืนบัฟเฟอร์ไปยังคิวโดยเรียก releaseBuffer()
กรอบการซิงค์ จะควบคุมวิธีที่บัฟเฟอร์เคลื่อนที่ผ่านไปป์ไลน์กราฟิก Android
คุณลักษณะบางอย่างของ BufferQueue เช่น จำนวนบัฟเฟอร์สูงสุดที่สามารถเก็บได้นั้นถูกกำหนดโดยผู้ผลิตและผู้บริโภคร่วมกัน อย่างไรก็ตาม BufferQueue จะจัดสรรบัฟเฟอร์ตามที่ต้องการ บัฟเฟอร์จะถูกเก็บไว้เว้นแต่ลักษณะจะเปลี่ยนแปลง ตัวอย่างเช่น หากผู้ผลิตร้องขอบัฟเฟอร์ที่มีขนาดต่างกัน บัฟเฟอร์เก่าจะว่างและบัฟเฟอร์ใหม่จะได้รับการจัดสรรตามความต้องการ
BufferQueue จะไม่คัดลอกเนื้อหาบัฟเฟอร์ เนื่องจากการย้ายข้อมูลจำนวนมากไปรอบๆ นั้นไม่มีประสิทธิภาพ บัฟเฟอร์จะถูกส่งผ่านโดยแฮนเดิลแทนเสมอ
ติดตามบัฟเฟอร์คิวด้วย Systrace
เพื่อให้เข้าใจว่าบัฟเฟอร์กราฟิกเคลื่อนที่ไปอย่างไร ให้ใช้ Systrace ซึ่งเป็นเครื่องมือที่บันทึกกิจกรรมของอุปกรณ์ในช่วงเวลาสั้นๆ โค้ดกราฟิกระดับระบบมีเครื่องมือที่ดี เช่นเดียวกับโค้ดเฟรมเวิร์กของแอปที่เกี่ยวข้อง
ในการใช้ Systrace ให้เปิดใช้งานแท็ก gfx
, view
และ sched
ออบเจ็กต์ BufferQueue จะแสดงในการสืบค้นกลับ ตัวอย่างเช่น หากคุณติดตามขณะที่ เล่นวิดีโอ (SurfaceView) ของ Grafika อยู่ แถวที่มีป้ายกำกับว่า SurfaceView จะบอกคุณว่ามีการจัดคิวบัฟเฟอร์จำนวนเท่าใดในช่วงเวลาหนึ่งๆ
ค่าที่เพิ่มขึ้นในขณะที่แอปทำงานอยู่ ซึ่งจะทริกเกอร์การเรนเดอร์เฟรมโดยตัวถอดรหัส MediaCodec ค่าจะลดลงในขณะที่ SurfaceFlinger กำลังทำงานและใช้บัฟเฟอร์ เมื่อแสดงวิดีโอที่ 30 fps ค่าของคิวจะแตกต่างกันไปตั้งแต่ 0 ถึง 1 เนื่องจากการแสดงผล ~60 fps สามารถติดตามแหล่งที่มาได้ SurfaceFlinger จะปลุกเมื่อมีงานต้องทำเท่านั้น ไม่ใช่ 60 ครั้งต่อวินาที ระบบพยายามหลีกเลี่ยงการทำงานและปิดใช้งาน VSYNC หากไม่มีอะไรอัปเดตหน้าจอ
หากคุณเปลี่ยนไปใช้ วิดีโอ Grafika's Play (TextureView) และดึงการติดตามใหม่ คุณจะเห็นแถวที่ระบุว่า com.android.grafika
/ com.android.grafika.PlayMovieActivity
นี่คือเลเยอร์ UI หลัก ซึ่งเป็นอีกบัฟเฟอร์คิว เนื่องจาก TextureView แสดงผลในเลเยอร์ UI แทนที่จะเป็นเลเยอร์ที่แยกจากกัน การอัปเดตที่ขับเคลื่อนด้วยวิดีโอทั้งหมดจึงแสดงที่นี่
Gralloc
hardware/libhardware/include/hardware/gralloc.h
ดำเนินการจัดสรรบัฟเฟอร์ผ่านแฟล็กการใช้งาน แฟล็กการใช้งานรวมถึงแอตทริบิวต์เช่น:
- ความถี่ที่จะเข้าถึงหน่วยความจำจากซอฟต์แวร์ (CPU)
- ความถี่ที่จะเข้าถึงหน่วยความจำจากฮาร์ดแวร์ (GPU)
- หน่วยความจำจะถูกใช้เป็นพื้นผิว OpenGL ES (GLES) หรือไม่
- หน่วยความจำจะถูกใช้โดยตัวเข้ารหัสวิดีโอหรือไม่
ตัวอย่างเช่น หากรูปแบบบัฟเฟอร์ของผู้ผลิตระบุ RGBA_8888
พิกเซล และผู้ผลิตระบุว่าจะเข้าถึงบัฟเฟอร์จากซอฟต์แวร์ (หมายความว่าแอปจะแตะพิกเซลบน CPU) Gralloc จะสร้างบัฟเฟอร์ที่มี 4 ไบต์ต่อพิกเซลในลำดับ RGBA หากผู้ผลิตระบุบัฟเฟอร์จะเข้าถึงได้จากฮาร์ดแวร์เท่านั้นและในฐานะพื้นผิว GLES Gralloc สามารถทำทุกอย่างที่ไดรเวอร์ GLES ต้องการ เช่น การสั่งซื้อ BGRA เลย์เอาต์ swizzled แบบไม่เชิงเส้น และรูปแบบสีทางเลือก การอนุญาตให้ฮาร์ดแวร์ใช้รูปแบบที่ต้องการสามารถปรับปรุงประสิทธิภาพได้
ไม่สามารถรวมค่าบางค่าบนบางแพลตฟอร์มได้ ตัวอย่างเช่น การตั้งค่าสถานะตัวเข้ารหัสวิดีโออาจต้องใช้พิกเซล YUV ดังนั้นการเพิ่มการเข้าถึงซอฟต์แวร์และการระบุ RGBA_8888
ล้มเหลว
แฮนเดิลที่ส่งคืนโดย Gralloc สามารถส่งผ่านระหว่างกระบวนการต่างๆ ผ่าน Binder
บัฟเฟอร์ที่มีการป้องกัน
ค่าสถานะการใช้งาน GRALLOC_USAGE_PROTECTED
อนุญาตให้แสดงบัฟเฟอร์กราฟิกผ่านพาธที่มีการป้องกันด้วยฮาร์ดแวร์เท่านั้น ระนาบการซ้อนทับเหล่านี้เป็นวิธีเดียวในการแสดงเนื้อหา DRM (ไม่สามารถเข้าถึงบัฟเฟอร์ที่มีการป้องกัน DRM โดย SurfaceFlinger หรือไดรเวอร์ OpenGL ES)
วิดีโอที่ป้องกันด้วย DRM สามารถนำเสนอได้บนระนาบโอเวอร์เลย์เท่านั้น เครื่องเล่นวิดีโอที่รองรับเนื้อหาที่ได้รับการคุ้มครองจะต้องใช้กับ SurfaceView ซอฟต์แวร์ที่ทำงานบนฮาร์ดแวร์ที่ไม่มีการป้องกันไม่สามารถอ่านหรือเขียนบัฟเฟอร์ได้ เส้นทางที่มีการป้องกันด้วยฮาร์ดแวร์จะต้องปรากฏบนโอเวอร์เลย์ของ Hardware Composer (นั่นคือ วิดีโอที่มีการป้องกันจะหายไปจากจอแสดงผลหาก Hardware Composer เปลี่ยนเป็นองค์ประกอบ OpenGL ES)
สำหรับรายละเอียดเกี่ยวกับเนื้อหาที่ได้รับการคุ้มครอง โปรดดูที่ DRM