BufferQueue และ Gralloc

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

ตัวจัดสรรหน่วยความจำ Gralloc ทำการจัดสรรบัฟเฟอร์และดำเนินการผ่านอินเทอร์เฟซ HIDL เฉพาะผู้จำหน่ายสองรายการ (ดู hardware/interfaces/graphics/allocator/ และ hardware/interfaces/graphics/mapper/ ) ฟังก์ชัน allocate() รับอาร์กิวเมนต์ที่คาดไว้ (ความกว้างความสูงรูปแบบพิกเซล) รวมทั้งชุดของแฟล็กการใช้งาน

ผู้ผลิตและผู้บริโภค BufferQueue

ผู้บริโภคสร้างและเป็นเจ้าของโครงสร้างข้อมูล BufferQueue และสามารถมีอยู่ในกระบวนการที่แตกต่างจากผู้ผลิตของตน เมื่อโปรดิวเซอร์ต้องการบัฟเฟอร์จะร้องขอบัฟเฟอร์ฟรีจาก BufferQueue โดยเรียก dequeueBuffer() ระบุความกว้างความสูงรูปแบบพิกเซลและแฟล็กการใช้งานของบัฟเฟอร์ จากนั้นผู้ผลิตจะเติมข้อมูลบัฟเฟอร์และส่งคืนบัฟเฟอร์ไปยังคิวโดยเรียกใช้ queueBuffer() จากนั้นผู้บริโภคจะได้รับบัฟเฟอร์ด้วย acquireBuffer() และใช้ประโยชน์จากเนื้อหาบัฟเฟอร์ เมื่อผู้บริโภคดำเนินการเสร็จสิ้นจะส่งคืนบัฟเฟอร์ไปยังคิวโดยเรียก releaseBuffer() กรอบการซิงค์ จะควบคุมวิธีที่บัฟเฟอร์เคลื่อนที่ผ่านไปป์ไลน์กราฟิกของ Android

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

BufferQueue จะไม่คัดลอกเนื้อหาของบัฟเฟอร์เนื่องจากการย้ายข้อมูลจำนวนมากนั้นไม่มีประสิทธิภาพ แต่บัฟเฟอร์จะถูกส่งผ่านด้วยแฮนเดิลเสมอ

ติดตาม BufferQueue ด้วย Systrace

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

ในการใช้ Systrace ให้เปิดใช้งานแท็ก gfx view และ sched วัตถุ BufferQueue จะแสดงในการติดตาม ตัวอย่างเช่นหากคุณใช้การติดตามในขณะที่ Play video (SurfaceView) ของ Grafika กำลังทำงานอยู่แถวที่มีข้อความว่า SurfaceView จะบอกจำนวนบัฟเฟอร์ที่อยู่ในคิวในช่วงเวลาใดเวลาหนึ่ง

ค่าจะเพิ่มขึ้นในขณะที่แอปทำงานอยู่ซึ่งจะทริกเกอร์การแสดงผลเฟรมโดยตัวถอดรหัส MediaCodec ค่าจะลดลงในขณะที่ SurfaceFlinger กำลังทำงานและใช้บัฟเฟอร์ เมื่อแสดงวิดีโอที่ 30 fps ค่าของคิวจะแตกต่างกันไปตั้งแต่ 0 ถึง 1 เนื่องจากการแสดงผล ~ 60 fps สามารถติดตามแหล่งที่มาได้ SurfaceFlinger จะตื่นก็ต่อเมื่อมีงานที่ต้องทำไม่ใช่ 60 ครั้งต่อวินาที ระบบพยายามหลีกเลี่ยงการทำงานและปิดใช้งาน VSYNC หากไม่มีการอัปเดตหน้าจอ

หากคุณเปลี่ยนไปใช้ Play video (TextureView) ของ Grafika และคว้าการติดตามใหม่คุณจะเห็นแถวที่ชื่อ com.android.grafika / com.android.grafika.PlayMovieActivity นี่คือเลเยอร์ UI หลักซึ่งเป็น BufferQueue อื่น เนื่องจาก TextureView แสดงผลในเลเยอร์ UI แทนที่จะเป็นเลเยอร์แยกการอัปเดตที่ขับเคลื่อนด้วยวิดีโอทั้งหมดจะแสดงที่นี่

Gralloc

ตัวจัดสรร Gralloc HAL hardware/libhardware/include/hardware/gralloc.h ทำการจัดสรรบัฟเฟอร์ผ่านแฟล็กการใช้งาน แฟล็กการใช้งานประกอบด้วยแอตทริบิวต์เช่น:

  • ความถี่ในการเข้าถึงหน่วยความจำจากซอฟต์แวร์ (CPU)
  • ความถี่ในการเข้าถึงหน่วยความจำจากฮาร์ดแวร์ (GPU)
  • หน่วยความจำจะใช้เป็นพื้นผิว OpenGL ES (GLES) หรือไม่
  • ตัวเข้ารหัสวิดีโอจะใช้หน่วยความจำหรือไม่

ตัวอย่างเช่นหากรูปแบบบัฟเฟอร์ของผู้ผลิตระบุ RGBA_8888 พิกเซลและผู้ผลิตระบุว่าจะเข้าถึงบัฟเฟอร์จากซอฟต์แวร์ (หมายถึงแอปจะสัมผัสพิกเซลบน CPU) Gralloc จะสร้างบัฟเฟอร์ที่มี 4 ไบต์ต่อพิกเซลตามลำดับ RGBA หาก แต่โปรดิวเซอร์ระบุว่าบัฟเฟอร์จะสามารถเข้าถึงได้จากฮาร์ดแวร์เท่านั้นและในฐานะพื้นผิวของ GLES Gralloc สามารถทำอะไรก็ได้ที่ไดรเวอร์ GLES ต้องการเช่นการสั่งซื้อ BGRA รูปแบบที่ไม่เป็นเชิงเส้นและรูปแบบสีอื่น การอนุญาตให้ฮาร์ดแวร์ใช้รูปแบบที่ต้องการสามารถปรับปรุงประสิทธิภาพได้

ไม่สามารถรวมค่าบางค่าในบางแพลตฟอร์มได้ ตัวอย่างเช่นแฟ RGBA_8888 กตัวเข้ารหัสวิดีโออาจต้องใช้พิกเซล YUV ดังนั้นการเพิ่มการเข้าถึงซอฟต์แวร์และการระบุ RGBA_8888 ล้มเหลว

หมายเลขอ้างอิงที่ส่งคืนโดย Gralloc สามารถส่งผ่านระหว่างกระบวนการต่างๆผ่าน Binder

บัฟเฟอร์ที่ได้รับการป้องกัน

แฟล็กการใช้งาน GRALLOC_USAGE_PROTECTED อนุญาตให้แสดงบัฟเฟอร์กราฟิกผ่านเส้นทางที่ป้องกันด้วยฮาร์ดแวร์เท่านั้น เครื่องบินซ้อนทับเหล่านี้เป็นวิธีเดียวในการแสดงเนื้อหา DRM (ไม่สามารถเข้าถึงบัฟเฟอร์ที่ป้องกัน DRM ได้โดย SurfaceFlinger หรือไดรเวอร์ OpenGL ES)

วิดีโอที่มีการป้องกัน DRM สามารถนำเสนอได้บนระนาบซ้อนทับเท่านั้น เครื่องเล่นวิดีโอที่รองรับเนื้อหาที่ได้รับการป้องกันจะต้องติดตั้งกับ SurfaceView ซอฟต์แวร์ที่ทำงานบนฮาร์ดแวร์ที่ไม่มีการป้องกันไม่สามารถอ่านหรือเขียนบัฟเฟอร์ได้ เส้นทางที่มีการป้องกันฮาร์ดแวร์จะต้องปรากฏบนภาพซ้อนทับ Hardware Composer (นั่นคือวิดีโอที่ได้รับการป้องกันจะหายไปจากจอแสดงผลหาก Hardware Composer เปลี่ยนไปใช้องค์ประกอบ OpenGL ES)

สำหรับรายละเอียดเกี่ยวกับเนื้อหาที่มีการป้องกันโปรดดู DRM