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