پیاده سازی Hardware Composer HAL

لایه های کامپوزیت Hardware Composer (HWC) HAL دریافت شده از SurfaceFlinger، میزان ترکیب بندی OpenGL ES (GLES) و GPU را کاهش می دهد.

HWC انتزاع اشیاء، مانند روکش ها و تابش های دوبعدی را به سطوح کامپوزیت می دهد و با سخت افزار ترکیب بندی پنجره های تخصصی با پنجره های کامپوزیت ارتباط برقرار می کند. به جای استفاده از کامپوزیت SurfaceFlinger با پردازنده گرافیکی، از HWC برای کامپوزیت ویندوز استفاده کنید. اکثر پردازنده‌های گرافیکی برای ترکیب بهینه‌سازی نشده‌اند، و وقتی GPU لایه‌هایی را از SurfaceFlinger می‌سازد، برنامه‌ها نمی‌توانند از GPU برای رندرینگ خود استفاده کنند.

پیاده سازی HWC باید پشتیبانی کند:

  • حداقل چهار همپوشانی:
    • نوار وضعیت
    • نوار سیستم
    • برنامه
    • تصویر زمینه / پس زمینه
  • لایه هایی که بزرگتر از صفحه نمایش هستند (مثلاً کاغذ دیواری)
  • ترکیب آلفای پیش ضرب شده همزمان و ترکیب آلفا در هر صفحه
  • مسیر سخت افزاری برای پخش ویدیوی محافظت شده
  • سفارش بسته‌بندی RGBA، فرمت‌های YUV، و ویژگی‌های کاشی کاری، چرخش و گام برداشتن

برای اجرای HWC:

  1. یک HWC غیرعملیاتی را اجرا کنید و تمام کارهای ترکیبی را به GLES ارسال کنید.
  2. اجرای یک الگوریتم برای تفویض تدریجی ترکیب به HWC. به عنوان مثال، تنها سه یا چهار سطح اول را به سخت افزار پوشش HWC واگذار کنید.
  3. HWC را بهینه کنید. این ممکن است شامل موارد زیر باشد:
    • انتخاب سطوحی که بار برداشته شده از GPU را به حداکثر می رساند و آنها را به HWC ارسال می کند.
    • تشخیص اینکه آیا صفحه در حال به روز رسانی است یا خیر. اگر اینطور نیست، برای صرفه جویی در مصرف برق، ترکیب را به جای HWC به GLES واگذار کنید. وقتی صفحه دوباره به‌روزرسانی شد، به بارگیری ترکیب در HWC ادامه دهید.
    • آماده سازی برای موارد استفاده رایج مانند:
      • صفحه اصلی که شامل نوار وضعیت، نوار سیستم، پنجره برنامه و تصاویر پس زمینه زنده است
      • بازی های تمام صفحه در حالت عمودی و افقی
      • ویدیوی تمام صفحه با زیرنویس بسته و کنترل پخش
      • پخش ویدیو محافظت شده
      • چند پنجره ای با صفحه تقسیم

HWC اولیه

HWC دو لایه اولیه، لایه ها و نمایشگرها را برای نمایش کار ترکیب بندی و تعامل آن با سخت افزار نمایشگر ارائه می دهد. HWC همچنین کنترل VSYNC و یک تماس به SurfaceFlinger را فراهم می کند تا در صورت وقوع یک رویداد VSYNC به آن اطلاع دهد.

رابط HIDL

Android 8.0 و بالاتر از یک رابط HIDL به نام Composer HAL برای IPC بایندر شده بین HWC و SurfaceFlinger استفاده می‌کند. Composer HAL جایگزین رابط قدیمی hwcomposer2.h می شود. اگر فروشندگان یک اجرای Composer HAL از HWC ارائه دهند، Composer HAL مستقیماً تماس‌های HIDL را از SurfaceFlinger می‌پذیرد. اگر فروشندگان یک پیاده‌سازی قدیمی از HWC ارائه دهند، Composer HAL نشانگرهای تابع را از hwcomposer2.h بارگیری می‌کند و تماس‌های HIDL را به فراخوان‌های اشاره‌گر تابع ارسال می‌کند.

HWC عملکردهایی را برای تعیین ویژگی های یک صفحه نمایش داده شده ارائه می دهد. برای جابه‌جایی بین پیکربندی‌های مختلف نمایش (مانند وضوح 4k یا 1080p) و حالت‌های رنگی (مانند رنگ اصلی یا sRGB واقعی)؛ و در صورت پشتیبانی، نمایشگر را روشن، خاموش یا به حالت کم مصرف تبدیل کنید.

نشانگرهای تابع

اگر فروشندگان Composer HAL را مستقیماً پیاده سازی کنند، SurfaceFlinger توابع آن را از طریق HIDL IPC فراخوانی می کند. برای مثال، SurfaceFlinger برای ایجاد یک لایه، createLayer() را در Composer HAL فراخوانی می‌کند.

اگر فروشندگان رابط hwcomposer2.h را پیاده سازی کنند، Composer HAL به نشانگرهای تابع hwcomposer2.h فراخوانی می کند. در نظرات hwcomposer2.h ، توابع رابط HWC با نام های LowCamelCase که در رابط وجود ندارند به عنوان فیلدهای نامگذاری شده نامیده می شوند. تقریباً هر تابعی با درخواست اشاره گر تابع با استفاده از getFunction ارائه شده توسط hwc2_device_t بارگیری می شود. به عنوان مثال، تابع createLayer یک نشانگر تابع از نوع HWC2_PFN_CREATE_LAYER است که وقتی مقدار شمارش شده HWC2_FUNCTION_CREATE_LAYER به getFunction ارسال می شود، برگردانده می شود.

برای مستندات دقیق در مورد عملکردهای HAL Composer و عملکردهای عبور عملکرد HWC، به composer مراجعه کنید. برای مستندات دقیق در مورد نشانگرهای عملکرد HWC، به hwcomposer2.h مراجعه کنید.

دسته های لایه و نمایشگر

لایه ها و نمایشگرها توسط دسته های تولید شده توسط HWC دستکاری می شوند. دستگیره ها نسبت به SurfaceFlinger مات هستند.

هنگامی که SurfaceFlinger یک لایه جدید ایجاد می کند، createLayer را فراخوانی می کند که از نوع Layer برای پیاده سازی های مستقیم یا hwc2_layer_t برای پیاده سازی های گذرا برمی گردد. هنگامی که SurfaceFlinger یک ویژگی آن لایه را اصلاح می کند، SurfaceFlinger مقدار hwc2_layer_t را به همراه هر اطلاعات دیگری که برای انجام اصلاح لازم است به تابع اصلاح مناسب منتقل می کند. نوع hwc2_layer_t به اندازه کافی بزرگ است که یک اشاره گر یا یک شاخص را در خود جای دهد.

نمایشگرهای فیزیکی با اتصال هات پلاگ ایجاد می شوند. هنگامی که یک صفحه نمایش فیزیکی هات پلاگ می شود، HWC یک دسته ایجاد می کند و دسته را از طریق تماس برگشتی هات پلاگ به SurfaceFlinger می دهد. نمایشگرهای مجازی توسط SurfaceFlinger با فراخوانی createVirtualDisplay() برای درخواست نمایش ایجاد می شوند. اگر HWC از ترکیب نمایش مجازی پشتیبانی کند، یک دسته را برمی‌گرداند. سپس، SurfaceFlinger ترکیب نمایشگرها را به HWC واگذار می کند. اگر HWC از ترکیب نمایشگر مجازی پشتیبانی نمی کند، SurfaceFlinger دسته را ایجاد می کند و نمایشگر را ترکیب می کند.

نمایش عملیات ترکیب بندی

یک بار در هر VSYNC، SurfaceFlinger اگر محتوای جدیدی برای ترکیب داشته باشد، بیدار می شود. این محتوای جدید می تواند بافرهای تصویر جدید از برنامه ها یا تغییر در ویژگی های یک یا چند لایه باشد. وقتی SurfaceFlinger آن را بیدار می کند:

  1. معاملات را در صورت وجود انجام می دهد.
  2. در صورت وجود بافرهای گرافیکی جدید را می‌بندد.
  3. اگر مرحله 1 یا 2 منجر به تغییر در محتویات نمایشی شود، ترکیب جدیدی را انجام می دهد.

برای اجرای یک ترکیب جدید، SurfaceFlinger لایه‌ها را ایجاد و از بین می‌برد یا حالت‌های لایه را تغییر می‌دهد. همچنین با استفاده از فراخوانی هایی مانند setLayerBuffer یا setLayerColor ، لایه ها را با محتوای فعلی به روز می کند. پس از به‌روزرسانی همه لایه‌ها، SurfaceFlinger validateDisplay را فراخوانی می‌کند که به HWC می‌گوید وضعیت لایه‌ها را بررسی کند و تعیین کند که ترکیب‌بندی چگونه پیش می‌رود. به طور پیش فرض، SurfaceFlinger تلاش می کند تا هر لایه را به گونه ای پیکربندی کند که لایه توسط HWC ترکیب شود. اگرچه در برخی شرایط، SurfaceFlinger لایه‌ها را از طریق بک گراند GPU ترکیب می‌کند.

پس از فراخوانی به validateDisplay ، SurfaceFlinger getChangedCompositionTypes را فراخوانی می‌کند تا ببیند آیا HWC می‌خواهد هر یک از انواع ترکیب لایه‌ها قبل از اجرای ترکیب تغییر کند یا خیر. برای پذیرش تغییرات، SurfaceFlinger با acceptDisplayChanges تماس می گیرد.

اگر هر لایه ای برای ترکیب SurfaceFlinger علامت گذاری شده باشد، SurfaceFlinger آنها را در بافر هدف ترکیب می کند. سپس SurfaceFlinger setClientTarget فراخوانی می‌کند تا بافر را به نمایشگر بدهد تا بافر روی صفحه نمایش داده شود یا با لایه‌هایی که برای ترکیب SurfaceFlinger علامت‌گذاری نشده‌اند ترکیب شود. اگر هیچ لایه ای برای ترکیب SurfaceFlinger علامت گذاری نشده باشد، SurfaceFlinger مرحله ترکیب را دور می زند.

در نهایت، SurfaceFlinger presentDisplay را فراخوانی می کند تا به HWC بگوید فرآیند ترکیب بندی را تکمیل کند و نتیجه نهایی را نمایش دهد.

نمایشگرهای متعدد

اندروید 10 از نمایشگرهای فیزیکی متعدد پشتیبانی می کند. هنگام طراحی یک پیاده سازی HWC که برای استفاده در اندروید 7.0 و بالاتر در نظر گرفته شده است، محدودیت هایی در تعریف HWC وجود ندارد:

  • فرض بر این است که دقیقا یک صفحه نمایش داخلی وجود دارد. صفحه نمایش داخلی نمایشگری است که هات پلاگ اولیه در هنگام بوت شدن گزارش می دهد. پس از وصل شدن صفحه نمایش داخلی، نمی توان آن را جدا کرد.
  • علاوه بر نمایشگر داخلی، هر تعداد نمایشگر خارجی ممکن است در حین کارکرد عادی دستگاه به برق متصل شوند. چارچوب فرض می کند که همه هات پلاگ ها بعد از اولین نمایش داخلی نمایشگرهای خارجی هستند، بنابراین اگر نمایشگرهای داخلی بیشتری اضافه شوند، به اشتباه به جای Display.TYPE_HDMI به عنوان Display.TYPE_BUILT_IN دسته بندی می شوند.

در حالی که عملیات SurfaceFlinger که در بالا توضیح داده شد در هر صفحه نمایش انجام می شود، آنها به صورت متوالی برای همه نمایشگرهای فعال انجام می شوند، حتی اگر محتوای تنها یک نمایشگر به روز شود.

به عنوان مثال، اگر صفحه نمایش خارجی به روز شود، دنباله آن به صورت زیر است:

// In Android 9 and lower:

// Update state for internal display
// Update state for external display
validateDisplay(<internal display>)
validateDisplay(<external display>)
presentDisplay(<internal display>)
presentDisplay(<external display>)

// In Android 10 and higher:

// Update state for internal display
// Update state for external display
validateInternal(<internal display>)
presentInternal(<internal display>)
validateExternal(<external display>)
presentExternal(<external display>)

ترکیب نمایش مجازی

ترکیب نمایش مجازی شبیه ترکیب نمایشگر خارجی است. تفاوت بین ترکیب نمایشگر مجازی و ترکیب نمایش فیزیکی در این است که نمایشگرهای مجازی خروجی را به جای نمایشگر به بافر Gralloc ارسال می کنند. Hardware Composer (HWC) خروجی را در بافر می نویسد، حصار تکمیل را فراهم می کند و بافر را برای مصرف کننده می فرستد (مانند رمزگذار ویدیو، GPU، CPU و غیره). اگر خط لوله نمایش در حافظه بنویسد، نمایشگرهای مجازی می توانند از 2D/blitter یا روکش استفاده کنند.

حالت ها

هر فریم در یکی از سه حالت بعد از فراخوانی متد validateDisplay() HWC توسط SurfaceFlinger قرار دارد:

  • GLES - GPU همه لایه ها را ترکیب می کند و مستقیماً در بافر خروجی می نویسد. HWC در ترکیب دخالتی ندارد.
  • مخلوط : GPU چند لایه را به فریم بافر ترکیب می کند و HWC فریم بافر و لایه های باقی مانده را ترکیب می کند و مستقیماً روی بافر خروجی می نویسد.
  • HWC - HWC تمام لایه ها را ترکیب می کند و مستقیماً در بافر خروجی می نویسد.

فرمت خروجی

فرمت های خروجی بافر نمایش مجازی به حالت آنها بستگی دارد:

  • حالت GLES - درایور EGL فرمت بافر خروجی را در dequeueBuffer() تنظیم می‌کند، معمولاً RGBA_8888 . مصرف کننده باید بتواند فرمت خروجی را که درایور تنظیم می کند بپذیرد یا بافر قابل خواندن نباشد.
  • حالت های مختلط و HWC - اگر مصرف کننده نیاز به دسترسی به CPU داشته باشد، مصرف کننده قالب را تنظیم می کند. در غیر این صورت، قالب IMPLEMENTATION_DEFINED است و Gralloc بهترین قالب را بر اساس پرچم‌های استفاده تنظیم می‌کند. به عنوان مثال، اگر مصرف کننده رمزگذار ویدئو باشد، Gralloc یک فرمت YCbCr را تنظیم می کند و HWC می تواند فرمت را به طور موثر بنویسد.

نرده های همگام سازی

نرده های همگام سازی (همگام سازی) یک جنبه حیاتی از سیستم گرافیکی اندروید هستند. حصارها به CPU اجازه می دهند مستقل از کار همزمان GPU پیش برود و فقط زمانی که وابستگی واقعی وجود داشته باشد مسدود می شود.

به عنوان مثال، هنگامی که یک برنامه بافری را ارسال می کند که در GPU تولید می شود، یک شی حصار همگام سازی نیز ارسال می کند. این حصار زمانی سیگنال می دهد که GPU نوشتن در بافر تمام شود.

HWC مستلزم آن است که GPU قبل از نمایش بافرها، بافرهای نوشتن را تمام کند. حصارهای همگام سازی از طریق خط لوله گرافیکی با بافرها عبور داده می شوند و هنگام نوشتن بافرها سیگنال می دهند. قبل از نمایش بافر، HWC بررسی می‌کند که آیا حصار همگام‌سازی سیگنال داده است یا خیر، و اگر داشته باشد، بافر را نمایش می‌دهد.

برای اطلاعات بیشتر در مورد حصارهای همگام سازی، به یکپارچه سازی آهنگساز سخت افزار مراجعه کنید.