اندروید از رابط برنامهنویسی OpenGL ES (GLES) برای رندر کردن گرافیک استفاده میکند. برای ایجاد زمینههای GLES و ارائه یک سیستم پنجرهبندی برای رندرهای GLES، اندروید از کتابخانه EGL استفاده میکند. GLES چندضلعیهای بافتدار را رندر میکند، در حالی که فراخوانیهای EGL رندرها را روی صفحه نمایش قرار میدهد.
قبل از اینکه با GLES ترسیم کنید، باید یک GL context ایجاد کنید. در EGL، این به معنای ایجاد یک EGLContext و یک EGLSurface است. عملیات GLES بر روی context فعلی اعمال میشود که از طریق ذخیرهسازی محلی thread قابل دسترسی است، نه اینکه به عنوان یک آرگومان ارسال شود. کد رندر باید روی یک thread GLES اجرا شود، نه روی thread UI.
سطوح EGL
EGLSurface میتواند یک بافر خارج از صفحه باشد که توسط EGL به نام pbuffer اختصاص داده شده است، یا یک پنجره باشد که توسط سیستم عامل اختصاص داده شده است. فراخوانی تابع eglCreateWindowSurface()
سطوح پنجره EGL را ایجاد میکند. eglCreateWindowSurface()
یک شیء پنجره را به عنوان آرگومان میگیرد که در اندروید یک سطح است. یک سطح، سمت تولیدکننده یک BufferQueue است. مصرفکنندگان ، که SurfaceView، SurfaceTexture، TextureView یا ImageReader هستند، سطوح را ایجاد میکنند. وقتی eglCreateWindowSurface()
را فراخوانی میکنید، EGL یک شیء EGLSurface جدید ایجاد میکند و آن را به رابط تولیدکننده BufferQueue شیء پنجره متصل میکند. از آن نقطه به بعد، رندر کردن به آن EGLSurface یک بافر را از صف خارج میکند، در آن رندر میکند و آن را برای استفاده توسط مصرفکننده در صف قرار میدهد.
EGL فراخوانیهای قفل/باز کردن قفل را ارائه نمیدهد. دستورات ترسیم را صادر کنید و سپس eglSwapBuffers()
را برای ارسال فریم فعلی فراخوانی کنید. نام این متد از تعویض سنتی بافرهای جلویی و پشتی گرفته شده است، اما پیادهسازی واقعی ممکن است متفاوت باشد.
فقط یک EGLSurface میتواند در یک زمان به یک سطح مرتبط باشد (شما فقط میتوانید یک تولیدکننده متصل به BufferQueue داشته باشید)، اما اگر EGLSurface را از بین ببرید، از BufferQueue جدا میشود و به چیز دیگری اجازه اتصال میدهد.
یک نخ داده شده میتواند با تغییر آنچه در حال حاضر است، بین چندین EGLSurface جابجا شود. یک EGLSurface باید در هر زمان فقط روی یک نخ در حال حاضر باشد.
EGL جنبهی دیگری از یک سطح، مانند SurfaceHolder، نیست. EGLSurface یک مفهوم مرتبط اما مستقل است. شما میتوانید روی یک EGLSurface که توسط یک سطح پشتیبانی نمیشود، رسم کنید و میتوانید از یک سطح بدون EGL استفاده کنید. EGLSurface مکانی برای رسم در GLES فراهم میکند.
برای الزامات OpenGL ES و EGL به سند تعریف سازگاری اندروید مراجعه کنید.
پنجره پویا
کلاس عمومی surface در زبان برنامهنویسی جاوا پیادهسازی شده است. معادل آن در C/C++ کلاس ANativeWindow است که توسط Android NDK به صورت نیمهرسمی ارائه شده است. میتوانید ANativeWindow را از یک surface با فراخوانی ANativeWindow_fromSurface()
دریافت کنید. درست مانند پسرعموی جاوایی آن، میتوانید آن را قفل کنید، در نرمافزار رندر کنید و unlock-and-post کنید. نوع پنجره بومی پایه، سمت تولیدکننده BufferQueue است.
برای ایجاد یک سطح پنجره EGL از کد بومی، یک نمونه از EGLNativeWindowType را به eglCreateWindowSurface()
ارسال کنید. EGLNativeWindowType مترادف ANativeWindow است، بنابراین میتوانید یکی را به دیگری تبدیل کنید.