BufferQueue و Gralloc

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

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

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

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

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

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

ردیابی BufferQueue با Systrace

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

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

در حالی که برنامه فعال است، مقدار افزایش می یابد، که باعث می شود فریم ها توسط رمزگشا MediaCodec ارائه شوند. هنگامی که SurfaceFlinger کار می کند و بافرها را مصرف می کند، مقدار کاهش می یابد. هنگام نمایش ویدیو با سرعت 30 فریم در ثانیه، مقدار صف از 0 تا 1 متغیر است زیرا نمایشگر 60 فریم در ثانیه می تواند با منبع مطابقت داشته باشد. SurfaceFlinger فقط زمانی بیدار می شود که کاری برای انجام دادن وجود داشته باشد، نه 60 بار در ثانیه. سیستم سعی می کند از کار جلوگیری کند و اگر چیزی صفحه را به روز نمی کند VSYNC را غیرفعال می کند.

اگر به ویدیوی Grafika's Play (TextureView) بروید و یک ردیابی جدید بگیرید، ردیفی با برچسب com.android.grafika / com.android.grafika.PlayMovieActivity می بینید. این لایه UI اصلی است که یک BufferQueue دیگر است. از آنجایی که TextureView به جای یک لایه جداگانه در لایه UI رندر می شود، همه به روز رسانی های مبتنی بر ویدیو در اینجا نمایش داده می شوند.

گرالوک

تخصیص دهنده Gralloc HAL hardware/libhardware/include/hardware/gralloc.h تخصیص بافر را از طریق پرچم های استفاده انجام می دهد. پرچم های استفاده شامل ویژگی هایی مانند:

  • هر چند وقت یکبار به حافظه از طریق نرم افزار (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 را ببینید.