‫BufferQueue و Gralloc

کلاس BufferQueue مؤلفه‌هایی را که بافرهای داده‌های گرافیکی تولید می‌کنند (تولیدکنندگان) به مؤلفه‌هایی که داده‌ها را برای نمایش یا پردازش بیشتر می‌پذیرند (مصرف‌کنندگان) متصل می‌کند. تقریباً هر چیزی که بافرهای داده‌های گرافیکی را در سیستم جابه‌جا می‌کند به BufferQueue متکی است.

تخصیص‌دهنده حافظه Gralloc تخصیص‌های میان‌گیر را انجام می‌دهد و ازطریق دو میانای HIDL مختص فروشنده پیاده‌سازی می‌شود (hardware/interfaces/graphics/allocator/ و hardware/interfaces/graphics/mapper/ را ببینید). تابع allocate() آرگومان‌های موردانتظار (عرض، ارتفاع، قالب پیکسل) و همچنین مجموعه‌ای از پرچم‌های استفاده را می‌گیرد.

تولیدکنندگان و مصرف‌کنندگان BufferQueue

مصرف‌کنندگان ساختار داده BufferQueue را ایجاد می‌کنند و مالک آن هستند و می‌توانند در فرایندهای متفاوتی نسبت به تولیدکنندگان خود وجود داشته باشند. وقتی تولیدکننده به میان‌گیر نیاز دارد، با فراخوانی dequeueBuffer()، میان‌گیر رایگانی از BufferQueue درخواست می‌کند و پهنا، ارتفاع، قالب پیکسل، و پرچم‌های استفاده میان‌گیر را مشخص می‌کند. سپس تولیدکننده میان‌گیر را پر می‌کند و با فراخوانی queueBuffer()، میان‌گیر را به صف برمی‌گرداند. سپس، مصرف‌کننده با acquireBuffer() بافر را دریافت می‌کند و از محتوای بافر استفاده می‌کند. وقتی مصرف‌کننده کارش تمام شد، با فراخوانی releaseBuffer() بافر را به صف برمی‌گرداند. چارچوب همگام‌سازی کنترل می‌کند که بافرها چگونه در خط لوله گرافیک Android حرکت کنند.

برخی‌از ویژگی‌های BufferQueue، مانند حداکثر تعداد میان‌گیرهایی که می‌تواند نگه دارد، به‌طور مشترک توسط تولیدکننده و مصرف‌کننده تعیین می‌شود. بااین‌حال، BufferQueue میان‌گیرها را براساس نیاز تخصیص می‌دهد. میان‌گیرها حفظ می‌شوند مگر اینکه مشخصات تغییر کند؛ برای مثال، اگر یک تولیدکننده میان‌گیرهایی با اندازه متفاوت درخواست کند، میان‌گیرهای قدیمی آزاد می‌شوند و میان‌گیرهای جدید به‌صورت درخواستی تخصیص داده می‌شوند.

محتوای میان‌گیر هرگز توسط BufferQueue کپی نمی‌شود، زیرا جابه‌جایی این حجم از داده‌ها کارآمد نیست. درعوض، میان‌گیرها همیشه با یک دسته منتقل می‌شوند.

ردیابی کردن BufferQueue با Systrace

برای درک نحوه حرکت بافرهای گرافیکی، از Systrace استفاده کنید، ابزاری که فعالیت دستگاه را در یک دوره زمانی کوتاه ضبط می‌کند. کد گرافیک سطح سیستم به‌خوبی ابزاربندی شده است، همان‌طور که بسیاری از کدهای چارچوب برنامه مرتبط نیز ابزاربندی شده‌اند.

برای استفاده از Systrace، برچسب‌های gfx، view، و sched را فعال کنید. ‫BufferQueue هدف در ردیابی نمایش داده می‌شود. برای مثال، اگر ردیابی را درحالی‌که ویدیو Grafika's Play ‎ (SurfaceView) درحال اجرا است انجام دهید، ردیف برچسب‌گذاری‌شده با SurfaceView به شما می‌گوید در هر زمان مشخص چند میان‌گیر در صف قرار گرفته است.

مقدار درحالی‌که برنامه فعال است افزایش می‌یابد، که باعث راه‌اندازی پردازش قاب‌ها توسط کدبند MediaCodec می‌شود. وقتی SurfaceFlinger درحال کار و مصرف میان‌گیرها است، مقدار کاهش می‌یابد. هنگام نمایش ویدیو با سرعت ۳۰ فریم در ثانیه، مقدار صف از ۰ تا ۱ متغیر است زیرا نمایشگر با سرعت حدود ۶۰ فریم در ثانیه می‌تواند با منبع همگام شود. ‫SurfaceFlinger فقط زمانی بیدار می‌شود که کاری برای انجام دادن وجود داشته باشد، نه ۶۰ بار در ثانیه. اگر چیزی صفحه‌نمایش را به‌روزرسانی نکند، سیستم سعی می‌کند از کار کردن اجتناب کند و VSync را غیرفعال می‌کند.

اگر به ویدیو پخش Grafika (‏TextureView) بروید و ردیابی جدیدی بگیرید، ردیفی با برچسب com.android.grafika / com.android.grafika.PlayMovieActivity می‌بینید. این لایه اصلی واسط کاربر است که نمونه دیگری از BufferQueue است. ازآنجایی‌که TextureView در لایه واسط کاربر رندر می‌شود نه در لایه جداگانه، همه به‌روزرسانی‌های ویدیو-محور در اینجا نمایش داده می‌شود.

Gralloc

«لایه انتزاع سخت‌افزاری» تخصیص‌دهنده Gralloc hardware/libhardware/include/hardware/gralloc.h تخصیص‌های بافر را ازطریق پرچم‌های استفاده انجام می‌دهد. پرچم‌های استفاده شامل مشخصه‌هایی مثل موارد زیر است:

  • هر چند وقت یک‌بار نرم‌افزار (واحد پردازش مرکزی) به حافظه دسترسی پیدا می‌کند
  • هر چند وقت یک‌بار حافظه از سخت‌افزار (GPU) قابل‌دسترسی خواهد بود
  • اینکه آیا از حافظه به‌عنوان بافت OpenGL ES (GLES) استفاده خواهد شد یا نه
  • اینکه آیا حافظه توسط کدبند ویدیو استفاده خواهد شد یا نه

برای مثال، اگر قالب میان‌گیر تولیدکننده RGBA_8888 پیکسل را مشخص کند، و تولیدکننده نشان دهد که میان‌گیر از نرم‌افزار قابل‌دسترسی خواهد بود (یعنی یک برنامه پیکسل‌ها را در CPU لمس خواهد کرد)، Gralloc میان‌گیری با ۴ بایت در هر پیکسل به ترتیب R-G-B-A ایجاد می‌کند. If instead, a producer specifies its buffer will be only accessed from hardware and as a GLES texture, Gralloc can do anything the GLES driver wants, such as BGRA ordering, nonlinear swizzled layouts, and alternative color formats. اجازه دادن به سخت‌افزار برای استفاده از قالب ترجیحی‌اش می‌تواند عملکرد را بهبود بخشد.

برخی‌از مقادیر را نمی‌توان در پلاتفرم‌های خاصی ترکیب کرد. برای مثال، پرچم رمزگذار ویدیو ممکن است به پیکسل‌های YUV نیاز داشته باشد، بنابراین افزودن دسترسی نرم‌افزاری و مشخص کردن RGBA_8888 ناموفق است.

نام کاربری برگشت‌داده‌شده توسط Gralloc می‌تواند ازطریق Binder بین فرایندها منتقل شود.

میان‌گیری‌های محافظت‌شده

پرچم استفاده Gralloc GRALLOC_USAGE_PROTECTED اجازه می‌دهد بافر گرافیکی فقط ازطریق مسیر محافظت‌شده سخت‌افزاری نمایش داده شود. این صفحه‌های هم‌پوشانی تنها راه نمایش محتوای DRM هستند (بافرهای محافظت‌شده با DRM نمی‌توانند توسط SurfaceFlinger یا درایور OpenGL ES دسترسی پیدا کنند).

ویدیوهای محافظت‌شده با DRM فقط در صفحه هم‌پوشانی قابل ارائه است. پخش‌کننده‌های ویدیویی که از محتوای محافظت‌شده پشتیبانی می‌کنند باید با SurfaceView پیاده‌سازی شوند. نرم‌افزاری که روی سخت‌افزار محافظت‌نشده اجرا می‌شود نمی‌تواند میان‌گیر را بخواند یا بنویسد؛ مسیرهای محافظت‌شده سخت‌افزاری باید روی هم‌پوشانی Hardware Composer ظاهر شوند (یعنی اگر Hardware Composer به ترکیب‌بندی OpenGL ES تغییر کند، ویدیوهای محافظت‌شده از نمایشگر ناپدید می‌شوند).

برای جزئیات مربوط به محتوای محافظت‌شده، مدیریت حقوق دیجیتال را ببینید.