SurfaceFlinger و WindowManager

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

سرفیس‌فلینگر

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

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

با شروع از اندروید ۱۰، ASurfaceControl راه دیگری را برای SurfaceFlinger جهت پذیرش بافرها فراهم می‌کند. ASurfaceControl یک نمونه surface و یک نمونه SurfaceControl را در یک بسته تراکنش که SurfaceFlinger دریافت می‌کند، ترکیب می‌کند. ASurfaceControl با یک لایه مرتبط است که برنامه‌ها از طریق نمونه‌های ASurfaceTransaction آن را به‌روزرسانی می‌کنند. سپس برنامه‌ها از طریق فراخوانی‌هایی که ASurfaceTransaction را ارسال می‌کنند، اطلاعاتی در مورد نمونه‌های ASurfaceTransactionStats دریافت می‌کنند که شامل اطلاعاتی مانند زمان قفل شدن، زمان‌های دریافت و غیره است.

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

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

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

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

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

مدیر پنجره

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

پیش چرخش

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

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