لایه ها و نمایشگرها

لایه‌ها و نمایشگرها دو عنصر اولیه هستند که کار ترکیب‌بندی و تعامل با سخت‌افزار نمایشگر را نشان می‌دهند.

لایه‌ها

یک لایه مهمترین واحد ترکیب است. یک لایه ترکیبی از یک سطح و یک نمونه از SurfaceControl است. هر لایه مجموعه‌ای از ویژگی‌ها دارد که نحوه تعامل آن با سایر لایه‌ها را تعریف می‌کند. ویژگی‌های لایه در جدول زیر شرح داده شده است:

ملک توضیحات
موقعیتی محل نمایش لایه را مشخص می‌کند. شامل اطلاعاتی مانند موقعیت لبه‌های یک لایه و ترتیب Z آن نسبت به سایر لایه‌ها (اینکه آیا باید جلوی لایه‌های دیگر باشد یا پشت آنها) است.
محتوا نحوه نمایش محتوای لایه را در محدوده تعیین شده توسط ویژگی‌های موقعیتی مشخص می‌کند. این شامل برش (برای گسترش محتوا و پر کردن محدوده لایه) و تبدیل (برای نمایش محتوای چرخانده شده یا وارونه) می‌شود.
ترکیب نحوه ترکیب لایه با سایر لایه‌ها را تعریف می‌کند. شامل اطلاعاتی مانند حالت ترکیب و مقدار آلفا در سطح لایه برای ترکیب آلفا است.
بهینه‌سازی اطلاعاتی را ارائه می‌دهد که لزوماً برای ترکیب صحیح لایه مورد نیاز نیست، اما دستگاه سخت‌افزاری آهنگساز (HWC) می‌تواند از آنها برای بهینه‌سازی عملکرد ترکیب استفاده کند. این شامل ناحیه قابل مشاهده لایه و بخشی است که از فریم قبلی به‌روزرسانی شده است.

نمایشگرها

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

دستگاه HWC درخواست می‌کند که نمایشگرها هنگام اتصال یا قطع یک نمایشگر خارجی از دستگاه، که به آن اتصال داغ (hotplugging) می‌گویند، اضافه یا حذف شوند. کلاینت‌ها نمایشگرهای مجازی را درخواست می‌کنند که محتوای آنها به جای نمایش در یک نمایشگر فیزیکی، در یک بافر خارج از صفحه نمایش رندر می‌شود.

نمایشگرهای مجازی

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

نمایشگرهای مجازی ممکن است همان مجموعه لایه‌ها را با نمایشگر اصلی (پشته لایه‌ها) به اشتراک بگذارند یا مجموعه لایه‌های مخصوص به خود را داشته باشند. هیچ VSync برای نمایشگر مجازی وجود ندارد، بنابراین VSync برای نمایشگر داخلی، ترکیب‌بندی را برای همه نمایشگرها آغاز می‌کند.

در پیاده‌سازی‌های HWC که از آنها پشتیبانی می‌کنند، نمایشگرهای مجازی می‌توانند با OpenGL ES (GLES)، HWC یا هر دو GLES و HWC ترکیب شوند. در پیاده‌سازی‌های غیرپشتیبانی‌کننده، نمایشگرهای مجازی همیشه با استفاده از GLES ترکیب می‌شوند.

مطالعه موردی: اسکرین رکورد

دستور screenrecord به کاربر اجازه می‌دهد تا هر چیزی را که روی صفحه نمایش ظاهر می‌شود، به عنوان یک فایل MP4 روی دیسک ضبط کند. برای پیاده‌سازی این، سیستم فریم‌های ترکیبی را از SurfaceFlinger دریافت می‌کند، آنها را در رمزگذار ویدیو می‌نویسد و سپس داده‌های ویدیویی رمزگذاری شده را در یک فایل می‌نویسد. کدک‌های ویدیو توسط یک فرآیند جداگانه ( mediaserver ) مدیریت می‌شوند، بنابراین بافرهای گرافیکی بزرگ باید در سیستم جابجا شوند. برای چالش‌برانگیزتر کردن این کار، هدف ضبط ویدیوی 60 فریم در ثانیه با وضوح کامل است. کلید کارآمد کردن این کار BufferQueue است.

کلاس MediaCodec به یک برنامه اجازه می‌دهد تا داده‌ها را به صورت بایت‌های خام در بافرها یا از طریق یک سطح ارائه دهد. وقتی screenrecord درخواست دسترسی به یک رمزگذار ویدیو را می‌دهد، فرآیند mediaserver یک BufferQueue ایجاد می‌کند، خود را به سمت مصرف‌کننده متصل می‌کند، سپس سمت تولیدکننده را به عنوان یک سطح به screenrecord برمی‌گرداند.

سپس ابزار screenrecord از SurfaceFlinger می‌خواهد که یک نمایشگر مجازی ایجاد کند که نمایشگر اصلی را منعکس کند (یعنی تمام لایه‌های یکسان را داشته باشد) و آن را هدایت می‌کند تا خروجی را به سطحی که از فرآیند mediaserver آمده است، ارسال کند. در این حالت، SurfaceFlinger تولیدکننده بافرها است، نه مصرف‌کننده.

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

مطالعه موردی: شبیه‌سازی نمایشگرهای ثانویه

WindowManager می‌تواند از SurfaceFlinger بخواهد که یک لایه قابل مشاهده ایجاد کند که SurfaceFlinger برای آن به عنوان مصرف‌کننده BufferQueue عمل کند. همچنین می‌توان از SurfaceFlinger خواست که یک نمایشگر مجازی ایجاد کند که SurfaceFlinger برای آن به عنوان تولیدکننده BufferQueue عمل کند.

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