گرافیک

آیکون HAL گرافیک اندروید

چارچوب اندروید، APIهای رندر گرافیکی متنوعی را برای دوبعدی و سه‌بعدی ارائه می‌دهد که با پیاده‌سازی‌های سازنده‌ی درایورهای گرافیکی تعامل دارند، بنابراین درک خوب از نحوه‌ی عملکرد این APIها در سطح بالاتر بسیار مهم است. این صفحه، لایه‌ی انتزاعی سخت‌افزار گرافیکی (HAL) را که این درایورها بر روی آن ساخته شده‌اند، معرفی می‌کند. قبل از ادامه‌ی این بخش، با اصطلاحات زیر آشنا شوید:

بوم نقاشی (اصطلاح عمومی)، Canvas (عنصر API)
یک بوم نقاشی، یک سطح ترسیم است که ترکیب بیت‌های واقعی را در برابر یک بیت‌مپ یا یک شیء Surface مدیریت می‌کند. کلاس Canvas دارای متدهایی برای ترسیم استاندارد کامپیوتری بیت‌مپ‌ها، خطوط، دایره‌ها، مستطیل‌ها، متن و غیره است و به یک بیت‌مپ یا سطح محدود می‌شود. یک بوم نقاشی ساده‌ترین و آسان‌ترین راه برای ترسیم اشیاء دوبعدی روی صفحه نمایش است. کلاس پایه Canvas است.
قابل ترسیم
یک drawable یک منبع بصری کامپایل شده است که می‌تواند به عنوان پس‌زمینه، عنوان یا بخش دیگری از صفحه نمایش استفاده شود. یک drawable معمولاً در یک عنصر رابط کاربری دیگر، مثلاً به عنوان تصویر پس‌زمینه، بارگذاری می‌شود. یک drawable نمی‌تواند رویدادها را دریافت کند، اما ویژگی‌های مختلف دیگری مانند حالت و زمان‌بندی را اختصاص می‌دهد تا زیرکلاس‌هایی مانند اشیاء انیمیشن یا کتابخانه‌های تصویر را فعال کند. بسیاری از اشیاء drawable از فایل‌های منبع drawable - فایل‌های XML یا bitmap که تصویر را توصیف می‌کنند - بارگذاری می‌شوند. منابع Drawable در زیرکلاس‌های android.graphics.drawable کامپایل می‌شوند. برای اطلاعات بیشتر در مورد drawableها و سایر منابع، به نمای کلی منابع برنامه مراجعه کنید.
منبع طرح بندی
یک منبع طرح‌بندی، یک فایل XML است که طرح‌بندی صفحه فعالیت را توصیف می‌کند. برای اطلاعات بیشتر، به منبع طرح‌بندی مراجعه کنید.
نه وصله (9 وصله، ناین‌پچ)
یک nine-patch یک منبع بیت‌مپ با قابلیت تغییر اندازه است که می‌تواند برای پس‌زمینه‌ها یا سایر تصاویر روی دستگاه استفاده شود. برای اطلاعات بیشتر، به Nine-patch مراجعه کنید.
OpenGL ES
OpenGL ES یک API چند پلتفرمی برای رندر کردن گرافیک‌های دوبعدی و سه‌بعدی است. اندروید کتابخانه‌های OpenGL ES را برای رندر کردن سه‌بعدی با شتاب‌دهنده سخت‌افزاری ارائه می‌دهد. برای رندر کردن دوبعدی، یک canvas گزینه ساده‌تر است. OpenGL ES در کیت توسعه بومی اندروید (NDK) موجود است. بسته‌های android.opengl و javax.microedition.khronos.opengles قابلیت OpenGL ES را ارائه می‌دهند.
سطح (اصطلاح عمومی)، Surface (عنصر API)
یک سطح (surface) نشان‌دهنده‌ی بلوکی از حافظه است که با صفحه نمایش ترکیب می‌شود. یک سطح (surface) یک بوم نقاشی (canvas) برای طراحی در خود نگه می‌دارد و متدهای کمکی مختلفی را برای طراحی لایه‌ها و تغییر اندازه‌ی شیء Surface ارائه می‌دهد. به جای استفاده‌ی مستقیم از کلاس Surface ، از کلاس SurfaceView استفاده کنید.
نمای سطحی (اصطلاح عمومی)، SurfaceView (عنصر API)
نمای سطحی، یک شیء View است که یک شیء Surface را برای ترسیم در بر می‌گیرد و متدهایی را برای تعیین اندازه و قالب آن به صورت پویا ارائه می‌دهد. نمای سطحی راهی برای ترسیم مستقل از نخ رابط کاربری برای عملیات فشرده‌سازی منابع، مانند بازی‌ها یا پیش‌نمایش دوربین، فراهم می‌کند، اما در نتیجه از حافظه اضافی استفاده می‌کند. نمای سطحی از هر دو گرافیک canvas و OpenGL ES پشتیبانی می‌کند. کلاس پایه برای یک شیء SurfaceView ، SurfaceView است.
تم
یک تم مجموعه‌ای از ویژگی‌ها، مانند اندازه متن و رنگ پس‌زمینه است که برای تعریف تنظیمات پیش‌فرض نمایش مختلف، با هم ترکیب شده‌اند. اندروید چند تم استاندارد ارائه می‌دهد که در R.style فهرست شده‌اند و با Theme_ آغاز می‌شوند.
نما (اصطلاح عمومی)، View (عنصر API)
یک نما (view) یک ناحیه مستطیلی روی صفحه نمایش رسم می‌کند و کلیک، ضربه کلید و سایر رویدادهای تعاملی را مدیریت می‌کند. کلاس View کلاس پایه برای اکثر اجزای طرح‌بندی یک فعالیت یا صفحه گفتگو، مانند جعبه‌های متن و پنجره‌ها است. یک شیء View از شیء والد خود (به ViewGroup مراجعه کنید) فراخوانی‌هایی برای رسم خود دریافت می‌کند و شیء والد خود را در مورد اندازه و موقعیت ترجیحی خود مطلع می‌کند، که ممکن است توسط والد رعایت نشود. برای اطلاعات بیشتر، به View مراجعه کنید.
گروه نما (اصطلاح عمومی)، ViewGroup (عنصر API)
یک گروه نما، مجموعه‌ای از نماهای فرزند را گروه‌بندی می‌کند. گروه نما مسئول تصمیم‌گیری در مورد محل قرارگیری نماهای فرزند و اندازه آنها و همچنین فراخوانی هر یک برای ترسیم خودشان در صورت لزوم است. برخی از گروه‌های نما نامرئی هستند و فقط برای طرح‌بندی استفاده می‌شوند، در حالی که برخی دیگر دارای رابط کاربری ذاتی مانند یک کادر لیست پیمایشی هستند. گروه‌های نما در بسته android.widget قرار دارند، اما از کلاس ViewGroup ارث‌بری می‌کنند.
مشاهده سلسله مراتب
سلسله مراتب نما، چیدمانی از اشیاء نما و گروه نما است که رابط کاربری هر جزء از یک برنامه را تعریف می‌کند. این سلسله مراتب شامل گروه‌های نما است که شامل یک یا چند نمای فرزند یا گروه‌های نما هستند. می‌توانید با استفاده از Hierarchy Viewer که همراه با SDK اندروید ارائه می‌شود، یک نمایش بصری از سلسله مراتب نما برای اشکال‌زدایی و بهینه‌سازی به دست آورید.
ولکان
ولکان یک رابط برنامه‌نویسی کاربردی (API) چند پلتفرمی با سربار کم برای گرافیک سه‌بعدی با کارایی بالا است.
ویجت
یک ویجت یکی از مجموعه زیرکلاس‌های view است که به طور کامل پیاده‌سازی شده‌اند و عناصر فرم و سایر اجزای رابط کاربری، مانند یک کادر متن یا یک منوی بازشو را رندر می‌کنند. از آنجا که یک ویجت به طور کامل پیاده‌سازی شده است، اندازه‌گیری، ترسیم خود و پاسخ به رویدادهای صفحه را مدیریت می‌کند. ویجت‌ها در بسته android.widget قرار دارند.
پنجره (اصطلاح عمومی)، Window (عنصر API)
در یک برنامه اندروید، یک پنجره (window) شیء‌ای مشتق شده از کلاس انتزاعی Window است که عناصر یک پنجره عمومی، مانند ظاهر و حس، متن نوار عنوان و مکان و محتوای منوها را مشخص می‌کند. دیالوگ‌ها و فعالیت‌ها (activity) از پیاده‌سازی کلاس Window برای رندر کردن یک شیء Window استفاده می‌کنند. شما نیازی به پیاده‌سازی کلاس Window یا استفاده از windows در برنامه خود ندارید.

توسعه‌دهندگان اپلیکیشن، تصاویر را به سه روش روی صفحه نمایش می‌دهند: با Canvas ، OpenGL ES یا Vulkan .

اجزای گرافیکی اندروید

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

نمودار زیر نحوه‌ی عملکرد اجزای کلیدی را نشان می‌دهد:

اجزای رندر تصویر

شکل ۱. نحوه رندر شدن سطوح.

اجزای اصلی در بخش‌های بعدی شرح داده شده‌اند.

تولیدکنندگان جریان تصویر

یک تولیدکننده‌ی جریان تصویر می‌تواند هر چیزی باشد که بافرهای گرافیکی برای مصرف تولید می‌کند. نمونه‌هایی از آن شامل OpenGL ES، Canvas 2D و رمزگشاهای ویدیویی mediaserver است.

مصرف‌کنندگان جریان تصویر

رایج‌ترین مصرف‌کننده‌ی جریان‌های تصویر، SurfaceFlinger است، سرویس سیستمی که سطوح قابل مشاهده‌ی فعلی را مصرف کرده و با استفاده از اطلاعات ارائه شده توسط Window Manager، آنها را روی صفحه نمایش ترکیب می‌کند. SurfaceFlinger تنها سرویسی است که می‌تواند محتوای صفحه نمایش را تغییر دهد. SurfaceFlinger از OpenGL و Hardware Composer (HWC) برای ترکیب گروهی از سطوح استفاده می‌کند.

سایر برنامه‌های OpenGL ES نیز می‌توانند از جریان‌های تصویر استفاده کنند، مانند برنامه دوربین که از جریان تصویر پیش‌نمایش دوربین استفاده می‌کند. برنامه‌های غیر GL نیز می‌توانند مصرف‌کننده باشند، به عنوان مثال کلاس ImageReader.

آهنگساز سخت‌افزار

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

آهنگساز سخت‌افزاری HAL نیمی دیگر از کار را انجام می‌دهد و نقطه مرکزی برای تمام رندرهای گرافیکی اندروید است. HWC باید از رویدادها پشتیبانی کند، که یکی از آنها VSync است (و دیگری hotplug برای پشتیبانی از HDMI به صورت plug-and-play است).

گرالوک

تخصیص‌دهنده حافظه گرافیکی (Gralloc) برای تخصیص حافظه درخواستی توسط تولیدکنندگان تصویر مورد نیاز است. برای جزئیات بیشتر، به BufferQueue و Gralloc مراجعه کنید.

جریان داده

نمودار زیر، نمودار گرافیکی اندروید را نشان می‌دهد:

جریان داده‌های گرافیکی

شکل 2. جریان داده‌های گرافیکی در اندروید

اشیاء سمت چپ رندرکننده‌هایی هستند که بافرهای گرافیکی مانند صفحه اصلی، نوار وضعیت و رابط کاربری سیستم را تولید می‌کنند. SurfaceFlinger آهنگساز و HWC آهنگساز است.

صف بافر

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

نمودار زیر فرآیند ارتباط BufferQueue را نشان می‌دهد:

فرآیند ارتباط BufferQueue

شکل 3. فرآیند ارتباط BufferQueue.

BufferQueue شامل منطقی است که تولیدکنندگان جریان تصویر و مصرف‌کنندگان جریان تصویر را به هم مرتبط می‌کند. برخی از نمونه‌های تولیدکنندگان تصویر، پیش‌نمایش‌های دوربین تولید شده توسط دوربین HAL یا بازی‌های OpenGL ES هستند. برخی از نمونه‌های مصرف‌کنندگان تصویر عبارتند از SurfaceFlinger یا برنامه دیگری که یک جریان OpenGL ES را نمایش می‌دهد، مانند برنامه دوربین که منظره‌یاب دوربین را نمایش می‌دهد.

BufferQueue یک ساختار داده است که یک مخزن بافر را با یک صف ترکیب می‌کند و از ارتباط بین فرآیندی Binder (IPC) برای انتقال بافرها بین فرآیندها استفاده می‌کند. رابط تولیدکننده یا آنچه که به کسی که می‌خواهد بافرهای گرافیکی تولید کند، منتقل می‌کنید IGraphicBufferProducer (بخشی از SurfaceTexture ) است. BufferQueue اغلب برای رندر کردن به یک Surface و مصرف با یک GL Consumer، در کنار سایر کارها، استفاده می‌شود.

BufferQueue می‌تواند در سه حالت مختلف عمل کند:

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

برای انجام بیشتر این کار، SurfaceFlinger فقط به عنوان یک کلاینت OpenGL ES دیگر عمل می‌کند. بنابراین، وقتی SurfaceFlinger به طور فعال یک یا دو بافر را به یک بافر سوم تبدیل می‌کند، به عنوان مثال، از OpenGL ES استفاده می‌کند.

نیمه دیگر کار را Hardware Composer HAL انجام می‌دهد. این HAL به عنوان نقطه مرکزی برای تمام رندرهای گرافیکی اندروید عمل می‌کند.