SurfaceFlinger و WindowManager

‫SurfaceFlinger بافرها را می‌پذیرد، ترکیب می‌کند، و به نمایشگر ارسال می‌کند. ‫WindowManager میان‌گیرها و فراداده‌های پنجره را برای SurfaceFlinger فراهم می‌کند و سپس SurfaceFlinger از آن‌ها برای ترکیب کردن سطوح در نمایشگر استفاده می‌کند.

SurfaceFlinger

‫SurfaceFlinger می‌تواند با دو روش بافرها را بپذیرد: ازطریق BufferQueue و SurfaceControl، یا ازطریق ASurfaceControl.

یکی از روش‌هایی که SurfaceFlinger بافرها را می‌پذیرد ازطریق BufferQueue و SurfaceControl است. وقتی برنامه‌ای به پیش‌زمینه می‌آید، میان‌گیرهایی را از WindowManager درخواست می‌کند. سپس WindowManager لایه‌ای را از SurfaceFlinger درخواست می‌کند. لایه ترکیبی از سطح است که حاوی BufferQueue است و نمونه SurfaceControl که حاوی فراداده لایه مثل قاب نمایش است. ‫SurfaceFlinger لایه را ایجاد می‌کند و آن را به WindowManager ارسال می‌کند. WindowManager سپس سطح را به برنامه ارسال می‌کند، اما نمونه SurfaceControl را برای دستکاری ظاهر برنامه در صفحه نگه می‌دارد.

از Android 10 به بعد، ASurfaceControl روش دیگری برای SurfaceFlinger فراهم می‌کند تا میان‌گیرها را بپذیرد. ASurfaceControl یک سطح و یک نمونه SurfaceControl را در یک بسته تراکنش که SurfaceFlinger دریافت می‌کند ترکیب می‌کند. ‫ASurfaceControl با لایه‌ای منسوب است که برنامه‌ها ازطریق نمونه‌های ASurfaceTransaction آن را به‌روز می‌کنند. سپس برنامه‌ها ازطریق تماس‌های برگشتی که ASurfaceTransactionStats حاوی اطلاعاتی مثل زمان قفل و زمان دریافت را منتقل می‌کنند، اطلاعاتی درباره ASurfaceTransaction نمونه دریافت می‌کنند.

جدول زیر ASurfaceControl و اجزای مرتبط آن را شرح می‌دهد:

مؤلفه شرح
ASurfaceControl SurfaceControl را می‌پیچد و به برنامه اجازه می‌دهد SurfaceControl نمونه ایجاد کند که با لایه‌های نمایشگر مطابقت دارد.
می‌تواند به‌عنوان فرزند ANativeWindow یا به‌عنوان فرزند نمونه ASurfaceControl دیگری ایجاد شود.
ASurfaceTransaction ‫Transaction را می‌پیچد تا به مشتری اجازه دهد ویژگی‌های توصیفی لایه را ویرایش کند، مثل هندسه، و بافرهای به‌روزشده را به SurfaceFlinger ارسال می‌کند.
ASurfaceTransactionStats اطلاعات مربوط به تراکنش‌هایی را که ارائه شده‌اند، مانند زمان قفل، زمان‌های دریافت، و حصار انتشار قبلی، ازطریق فراخوانی برگشتی پیش‌ثبت‌شده به برنامه ارسال می‌کند.

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

وقتی نمایشگر بین بازآوری‌ها است، نمایشگر سیگنال VSync را به SurfaceFlinger ارسال می‌کند. سیگنال VSync نشان می‌دهد که می‌تواند نمایشگر را بدون پارگی بازآوری کند. وقتی SurfaceFlinger سیگنال VSync را دریافت می‌کند، در فهرست لایه‌هایش به‌دنبال میان‌گیرهای جدید می‌گردد. اگر بافر جدیدی پیدا کند، SurfaceFlinger بافر را به‌دست می‌آورد؛ اگر بافر جدیدی پیدا نکند، به استفاده از بافر قبلی ادامه می‌دهد. SurfaceFlinger باید همیشه چیزی را نمایش دهد، بنابراین به یک میان‌گیر متصل می‌شود. اگر هیچ‌گاه هیچ بافری در لایه‌ای ارسال نشده باشد، SurfaceFlinger لایه را نادیده می‌گیرد.

پس‌از اینکه SurfaceFlinger همه میان‌گیرها را برای لایه‌های نمایان جمع‌آوری کرد، از «ترکیب‌کننده سخت‌افزاری» (HWC) می‌پرسد که چگونه باید ترکیب‌بندی را انجام دهد. اگر HWC نوع ترکیب لایه را به‌عنوان ترکیب کارخواه علامت‌گذاری کند، SurfaceFlinger آن لایه‌ها را ترکیب می‌کند. سپس، SurfaceFlinger بافر خروجی را به HWC منتقل می‌کند.

WindowManager

‫WindowManager Window شیء را کنترل می‌کند، که محفظه‌هایی برای View شیء هستند. Window شیء همیشه توسط Surface شیء پشتیبانی می‌شود. WindowManager بر چرخه‌های عمر، رویدادهای ورودی و تمرکز، جهت صفحه، گذارها، پویانمایی‌ها، موقعیت، تبدیل‌ها، ترتیب z، و بسیاری از جنبه‌های دیگر پنجره نظارت می‌کند. ‫WindowManager همه فراداده‌های پنجره را به SurfaceFlinger ارسال می‌کند تا SurfaceFlinger بتواند از آن داده‌ها برای ترکیب کردن سطوح در نمایشگر استفاده کند.

پیش‌چرخش

بسیاری از هم‌پوشانی‌های سخت‌افزاری از چرخش پشتیبانی نمی‌کنند (و حتی اگر پشتیبانی کنند، هزینه دارد قدرت پردازش)؛ راه حل این است که بافر را قبل‌از رسیدن به آن تبدیل کنید SurfaceFlinger. Android از راهنمای پُرسمان (NATIVE_WINDOW_TRANSFORM_HINT) در ANativeWindow پشتیبانی می‌کند تا محتمل‌ترین تبدیلی را که SurfaceFlinger روی میان‌گیر اعمال خواهد کرد نشان دهد. گردانندگان GL می‌توانند از این اشاره برای پیش‌تبدیل کردن بافر قبل‌از رسیدن آن به SurfaceFlinger استفاده کنند تا وقتی بافر می‌رسد، به‌درستی تبدیل شده باشد.

برای مثال، هنگام دریافت نکته‌ای برای چرخش ۹۰ درجه، ماتریسی برای بافر تولید و اعمال کنید تا از خارج شدن از انتهای صفحه جلوگیری شود. برای صرفه‌جویی در مصرف برق، این پیش‌چرخش را انجام دهید. برای جزئیات، به ANativeWindow میانای تعریف‌شده در system/core/include/system/window.h مراجعه کنید.