Surface و SurfaceHolder

اشیاء سطحی به برنامه ها امکان می دهند تصاویر را برای نمایش روی صفحه نمایش ارائه دهند. رابط های SurfaceHolder برنامه ها را قادر می سازد تا سطوح را ویرایش و کنترل کنند.

سطح

سطح یک رابط برای یک تولید کننده برای تبادل بافر با مصرف کننده است.

BufferQueue برای سطح نمایش معمولاً برای بافر سه گانه پیکربندی می شود. بافرها بر اساس تقاضا تخصیص داده می شوند، بنابراین اگر تولید کننده بافرها را به اندازه کافی آهسته تولید کند، مثلاً با سرعت 30 فریم در ثانیه در یک نمایشگر 60 فریم در ثانیه، ممکن است فقط دو بافر اختصاص داده شده در صف وجود داشته باشد. تخصیص بافرهای درخواستی به به حداقل رساندن مصرف حافظه کمک می کند. می توانید خلاصه ای از بافرهای مرتبط با هر لایه را در خروجی dumpsys SurfaceFlinger مشاهده کنید.

اکثر مشتریان با استفاده از OpenGL ES یا Vulkan روی سطوح رندر می دهند. با این حال، برخی از مشتریان با استفاده از بوم بر روی سطوح نمایش می دهند.

رندر بوم

اجرای بوم توسط کتابخانه گرافیک اسکیا ارائه شده است. اگر می خواهید یک مستطیل بکشید، Canvas API را فراخوانی می کنید که بایت ها را به طور مناسب در یک بافر تنظیم می کند. برای اطمینان از اینکه یک بافر توسط دو کلاینت به‌طور هم‌زمان به‌روزرسانی نمی‌شود یا هنگام نمایش روی آن نوشته نمی‌شود، بافر را قفل کنید تا به آن دسترسی داشته باشید. برای کار با قفل های بوم از دستورات زیر استفاده کنید:

  • lockCanvas() بافر را برای رندر کردن در CPU قفل می کند و یک Canvas را برای استفاده برای ترسیم برمی گرداند.
  • unlockCanvasAndPost() قفل بافر را باز می کند و آن را به کامپوزیتور می فرستد.
  • lockHardwareCanvas() بافر را برای رندر در GPU قفل می کند و یک بوم را برای استفاده برای طراحی برمی گرداند.

اولین باری که سازنده از یک BufferQueue درخواست بافر می کند، بافر تخصیص داده می شود و مقدار اولیه آن صفر می شود. برای جلوگیری از به اشتراک گذاری ناخواسته داده ها بین فرآیندها، مقداردهی اولیه ضروری است. با این حال، اگر از یک بافر دوباره استفاده کنید، محتویات قبلی همچنان وجود دارند. اگر مکرراً lockCanvas() و unlockCanvasAndPost() بدون ترسیم چیزی فراخوانی کنید، تولید کننده بین فریم های قبلی رندر شده چرخه می زند.

کد قفل/بازکردن سطح، ارجاعی به بافر رندر شده قبلی نگه می دارد. اگر هنگام قفل کردن سطح یک منطقه کثیف را مشخص کنید، پیکسل های غیر کثیف را از بافر قبلی کپی می کند. SurfaceFlinger یا HWC معمولاً بافر را مدیریت می کنند. اما از آنجایی که ما فقط باید از بافر بخوانیم، نیازی به منتظر ماندن برای دسترسی انحصاری نیست.

SurfaceHolder

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

اکثر کامپوننت هایی که با یک view تعامل دارند، یک SurfaceHolder دارند. برخی از API های دیگر مانند MediaCodec روی خود سطح کار می کنند.