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 แทนที่จะเป็นเลเยอร์ที่แยกจากกัน การอัปเดตจากวิดีโอทั้งหมดจึงแสดงที่นี่

กราลอค

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

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

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

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

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

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

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

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

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