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 จะไม่คัดลอกเนื้อหาบัฟเฟอร์ เนื่องจากการย้ายข้อมูลจำนวนมากไปรอบๆ นั้นไม่มีประสิทธิภาพ บัฟเฟอร์จะถูกส่งผ่านโดยแฮนเดิลแทนเสมอ

ติดตามบัฟเฟอร์คิวด้วย 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