部分内容摘自其他博客,请见最下[参考资料]

首先来看看Android官方对EGL的解释:

OpenGL ES 定义了一个渲染图形的 API,但没有定义窗口系统。为了让 GLES 能够适合各种平台,GLES 将与知道如何通过操作系统创建和访问窗口的库结合使用。用于 Android 的库称为 EGL。如果要绘制纹理多边形,应使用 GLES 调用;如果要在屏幕上进行渲染,应使用 EGL 调用。

OpenGL ES 是Android绘图API,但OpenGL ES是平台通用的,在特定设备上使用需要一个中间层做适配,这个中间层就是EGL。

EGL架构

Display(EGLDisplay) 是对实际显示设备的抽象。

Surface(EGLSurface)是对用来存储图像的内存区域 FrameBuffer 的抽象,包括 Color Buffer, Stencil Buffer ,Depth Buffer。

Context (EGLContext) 存储 OpenGL ES绘图的一些状态信息。

Android中的OpenGL 与EGL

Android 2.0版本之后图形系统的底层渲染均由OpenGL负责,OpenGL除了负责处理3D API调用,还需负责管理显示内存及处理Android SurfaceFlinger或上层应用对其发出的2D API调用请求。

本地代码:

frameworks/native/opengl/libs/EGL

Android EGL框架,负责加载OpenGL函数库和EGL本地实现。

frameworks/native/opengl/libagl

Android提供的OpenGL软件库

JNI代码:

frameworks/base/core/jni/com_google_android_gles_jni_EGLImpl.cpp

EGL本地代码的JNI调用接口

frameworks/base/core/jni/com_google_android_gles_jni_GLImpl.cpp

frameworks/base/core/jni/android_opengl_GLESXXX.cpp

OpenGL功能函数的JNI调用接口

Java代码:

frameworks/base/opengl/java/javax/microedition/khronos/egl

frameworks/base/opengl/java/javax/microedition/khronos/opengles

frameworks/base/opengl/java/com/google/android/gles_jni/

frameworks/base/opengl/java/android/opengl

EGL和OpenGL的Java层接口,提供给应用开发者,通过JNI方式调用底层函数。

首先从Native代码入手: frameworks/native/opengl/libs/EGL,该目录下文件如图所示:

frameworks/native/opengl/libs/EGL

依次解析该目录下各个文件的作用,由于文件缺少注释,只能从代码解读含义:

eglApi.cpp:提供暴露给上层的API。包含EGL对象的创建、配置、销毁等操作。

初始化EGL

OpenGL ES的初始化过程(EGL初始化)如下图所示意:

Display → Config → Surface

Context

Application → OpenGL Command

获取Display。

获得Display要调用EGLboolean eglGetDisplay(NativeDisplay dpy),参数一般为 EGL_DEFAULT_DISPLAY 。

初始化egl。

调用 EGLboolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor),该函数会进行一些内部初始化工作,并传回EGL版本号(major.minor)。

开机时打出的信息:

如下信息可以由const char * eglQueryString (EGLDisplay dpy, EGLint name);给出,name可以是EGL_VENDOR, EGL_VERSION, 或者EGL_EXTENSIONS 。该函数常用来查询当前版本EGL实现了哪些扩展,方便向下兼容。

SurfaceFlinger: EGL information:

SurfaceFlinger: vendor : Android

SurfaceFlinger: version : 1.4 Android META-EGL

SurfaceFlinger: extensions: EGL_KHR_get_all_proc_addresses EGL_ANDROID_presentation_time EGL_KHR_swap_buffers_with_damage EGL_ANDROID_get_native_client_buffer EGL_ANDROID_front_buffer_auto_refresh EGL_ANDROID_get_frame_timestamps EGL_KHR_image EGL_KHR_image_base EGL_KHR_gl_colorspace EGL_KHR_gl_texture_2D_image EGL_KHR_gl_texture_cubemap_image EGL_KHR_gl_renderbuffer_image EGL_KHR_fence_sync EGL_KHR_create_context EGL_KHR_config_attribs EGL_KHR_surfaceless_context EGL_EXT_create_context_robustness EGL_ANDROID_image_native_buffer EGL_KHR_wait_sync EGL_ANDROID_recordable EGL_KHR_partial_update EGL_KHR_mutable_render_buffer EGL_IMG_context_priority

SurfaceFlinger: Client API: OpenGL_ES

SurfaceFlinger: EGLSurface: 8-8-8-8, config=0x785f32d008

SurfaceFlinger: OpenGL ES informations:

SurfaceFlinger: vendor : ARM

SurfaceFlinger: renderer : Mali-T860

SurfaceFlinger: version : OpenGL ES 3.2 v1.r18p0-00cet0.e348142bb0bcdf18abb600a2670c56a1

SurfaceFlinger: extensions: GL_EXT_debug_marker GL_ARM_rgba8 GL_ARM_mali_shader_binary GL_OES_depth24 GL_OES_depth_texture GL_OES_depth_texture_cube_map GL_OES_packed_depth_stencil GL_OES_rgb8_rgba8 GL_EXT_read_format_bgra GL_OES_compressed_paletted_texture GL_OES_compressed_ETC1_RGB8_texture GL_OES_standard_derivatives GL_OES_EGL_image GL_OES_EGL_image_external GL_OES_EGL_image_external_essl3 GL_OES_EGL_sync GL_OES_texture_npot GL_OES_vertex_half_float GL_OES_required_internalformat GL_OES_vertex_array_object GL_OES_mapbuffer GL_EXT_texture_format_BGRA8888 GL_EXT_texture_rg GL_EXT_texture_type_2_10_10_10_REV GL_OES_fbo_render_mipmap GL_OES_element_index_uint GL_EXT_shadow_samplers GL_OES_texture_compression_astc GL_KHR_texture_compression_astc_ldr GL_KHR_texture_compression_astc_hdr GL_KHR_texture_compression_astc_sliced_3d GL_KHR_debug GL_EXT_occlusion_query_boolean GL_EXT_disjoint_timer_query GL_EXT_blend_minmax GL_EXT_discard_framebuffer GL_OES_get_prog...

SurfaceFlinger: GL_MAX_TEXTURE_SIZE = 8192

SurfaceFlinger: GL_MAX_VIEWPORT_DIMS = 8192

选择Config。

Config实际指的是FrameBuffer的参数,

一般用EGLboolean eglChooseConfig(EGLDisplay dpy, const EGLint * attr_list, EGLConfig * config, EGLint config_size, EGLint *num_config),其中attr_list是以EGL_NONE结束的参数数组,通常以id,value依次存放,对于个别标识性的属性可以只有 id,没有value。另一个办法是用EGLboolean eglGetConfigs(EGLDisplay dpy, EGLConfig * config, EGLint config_size, EGLint *num_config) 来获得所有config。

这两个函数都会返回不多于config_size个Config,结果保存在config[]中,系统的总Config个数保存 在num_config中。

可以利用eglGetConfig()中间两个参数为0来查询系统支持的Config总个数。Config有众多的Attribute,这些Attribute决定FrameBuffer的格式和能力,通过eglGetConfigAttrib ()来读取,但不能修改。

构造Surface

Surface实际上就是一个FrameBuffer,也就是渲染目的地,通过EGLSurface eglCreateWindowSurface(EGLDisplay dpy, EGLConfig confg, NativeWindow win, EGLint *cfg_attr)来创建一个可实际显示的Surface。

系统通常还支持另外两种Surface:PixmapSurface和PBufferSurface,这两种都不是可显示的Surface,PixmapSurface是保存在系统内存中的位图,PBuffer则是保存在显存中的帧。

对于这两种surface,Android系统中,支持PBufferSurface。Surface也有一些attribute,基本上都可以顾名思义,

EGL_HEIGHT EGL_WIDTH EGL_LARGEST_PBUFFER

EGL_TEXTURE_FORMAT EGL_TEXTURE_TARGET

EGL_MIPMAP_TEXTURE EGL_MIPMAP_LEVEL

通过eglSurfaceAttrib()设置、eglQuerySurface()读取。

创建Context

OpenGL ES的pipeline从程序的角度看就是一个状态机,有当前的颜色、纹理坐标、变换矩阵、绚染模式等一大堆状态,这些状态作用于OpenGL API程序提交的顶点坐标等图元从而形成帧缓冲内的像素。在OpenGL的编程接口中,Context就代表这个状态机,OpenGL API程序的主要工作就是向Context提供图元、设置状态,偶尔也从Context里获取一些信息。

可以用EGLContext eglCreateContext(EGLDisplay dpy, EGLSurface write, EGLSurface read, EGLContext * share_list)来创建一个Context。

EGL变量之间的绑定

boolean eglMakeCurrent(EGLDisplay display, EGLSurface draw, EGLSurface read, EGLContext context)

该接口将申请到的display,draw(surface)和 context进行了绑定。也就是说,在context下的OpenGLAPI指令将draw(surface)作为其渲染最终目的地。而display作为draw(surface)的前端显示。调用后,当前线程使用的EGLContex为context。

绘制。

应用程序通过OpenGL API进行绘制,一帧完成之后,调用eglSwapBuffers(EGLDisplay dpy, EGLContext ctx)来显示。

If surface is a window surface, eglSwapBuffers posts its color buffer to the associated native window.

The contents of ancillary buffers are always undefined after calling eglSwapBuffers. The contents of the color buffer are left unchanged if the value of the EGL_SWAP_BEHAVIOR attribute of surface is EGL_BUFFER_PRESERVED, and are undefined if the value is EGL_BUFFER_DESTROYED. The value of EGL_SWAP_BEHAVIOR can be set for some surfaces using eglSurfaceAttrib.

eglSwapBuffers performs an implicit flush operation on the context (glFlush for an OpenGL ES or OpenGL context, vgFlush for an OpenVG context) bound to surface before swapping. Subsequent client API commands may be issued on that context immediately after calling eglSwapBuffers, but are not executed until the buffer exchange is completed.

If surface is a pixel buffer or a pixmap, eglSwapBuffers has no effect, and no error is generated.

看看frameworks/native/opengl/libagl/egl.cpp对eglSwapBuffers的实现:

EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface draw)

{

egl_surface_t* d = static_cast(draw);

...

// post the surface

d->swapBuffers();

// if it's bound to a context, update the buffer

if (d->ctx != EGL_NO_CONTEXT) {

d->bindDrawSurface((ogles_context_t*)d->ctx);

// if this surface is also the read surface of the context

// it is bound to, make sure to update the read buffer as well.

// The EGL spec is a little unclear about this.

egl_context_t* c = egl_context_t::context(d->ctx);

if (c->read == draw) {

d->bindReadSurface((ogles_context_t*)d->ctx);

}

}

return EGL_TRUE;

}

eglSwapBuffers之后

应该是生成了layer供HWC合成,这部分仍在学习当中

android egl使用方法,Android EGL相关推荐

  1. android datepicker使用方法,android DatePicker

    Date Picker 提供了一个构件去选择一个时间,使用DatePicker构件,该构件允许用户去选择月,日,年在一个界面中. 实例介绍 首先我们应该先创建一个DatePickerDialog,该D ...

  2. android view使用方法,Android View构造方法第三参数使用方法详解

    我们都知道,在Android中要使用一个View,一般会有两种方式: 在XML文件中配置: 直接在代码中new一个View的对象. 我们今天讨论的内容就是围绕着View的构造方法的. 1.实例 首先我 ...

  3. android返回键方法,Android按返回键(后退键)Back键事件捕获的两种方法

    package zhangphil.back; import android.support.v7.app.ActionBarActivity; import android.util.Log; im ...

  4. android avd 使用方法,Android中Android Virtual Device(AVD)使用教程

    AVD的全称为:Android Virtual Device,就是Android运行的虚拟设备,他是Android的模拟器识别.建立的Android要运行,必须创建AVD,每个AVD上可以配置很多的运 ...

  5. android datepicker使用方法,android中DatePicker和TimePicker的使用方法详解

    本文以实例讲述了android中DatePicker和TimePicker的使用方法,具体步骤如下: 下面是实现具体功能的代码,其中main.xml代码为: android:layout_width= ...

  6. android view使用方法,android – 如何使用getView()方法,它在哪里被调用?

    我是Android开发的新手,并且一直遵循Android网站上提供的教程.我目前在视图教程部分,特别是Grid Views: Hello, Grid View Tutorial的教程. 我无法通过适配 ...

  7. Android代码混淆方法,Android 代码混淆零基础入门

    内容提要 本篇文章主要有三个部分,让读者读完后能自己写规则混淆项目 对Android代码怎么开启混淆做一个简单的介绍. 对混淆规则做一个简单介绍: 在混淆过后Crash日志反推代码工具retrace. ...

  8. android 接口实现方法,Android应用开发之Android 请求网络接口实现方法

    本文将带你了解Android应用开发之Android 请求网络接口实现方法,希望本文对大家学Android有所帮助. public   class Fragment01 extends Fragmen ...

  9. android模拟按键方法,Android随笔之——模拟按键操作的几种方式

    前几天转过一篇Android上模拟按键操作.触屏事件的博客,昨天又去找了百度.谷歌了一下,写了一点简单的测试代码,留待不时之需.有需要看之前转载的那篇博客的请看这里→_→转:Android随笔之--使 ...

  10. android 静态工厂方法,Android 源码中的静态工厂方法

    我们知道工厂模式有三兄弟,通常我们说的工厂模式指的是工厂方法模式,它的应用频率最高.本篇博客分享的简单工厂模式是工厂方法模式的"小弟",确切的来讲它不属于设计模式,而是一种方法.此 ...

最新文章

  1. 对函数指针与typedef的理解:typedef void (*sighandler_t)(int)
  2. 学习笔记Hadoop(一)—— Hadoop介绍(1)——认识大数据
  3. 数字识别java开源_Java基于opencv实现图像数字识别(三)—灰度化和二值化
  4. MQTT工作笔记0005---CONNECT控制报文2
  5. vue watch 监听不到变化_关于vue中watch检测到不到对象属性的变化的解决方法
  6. 品质标签分几种颜色_北京标签不干胶印刷厂
  7. Qt connect()的第五种重载[=](){}
  8. MSCHART控件中长字符的X轴坐标标注全部显示
  9. R语言决策树:NBA球员如何拿到大合同
  10. psp模拟器完美字库_安卓PSP模拟器评测:讨鬼传
  11. 如何使用qq截图工具,却能保证系统不会随意放大
  12. 2022年R2移动式压力容器充装上岗证题库及在线模拟考试
  13. 嘉立创 PCB 生产流程
  14. LS-DYNA材料模型
  15. excel英文自动翻译成中文教程
  16. 使用R语言进行单(双)因素方差分析
  17. 数据库查询三个以上名字重复的数据
  18. Oracle11g密码忘记
  19. 服务器上Kafka启动报错:error=‘Cannot allocate memory‘ (errno=12)
  20. 基于keras的seq2seq中英文翻译实现

热门文章

  1. 面相对象的总结项目(嗖嗖业务大厅)
  2. 十大简单排序:桶排序
  3. Parallel Scavenge垃圾回收器线上调优实战
  4. 传输表空间迁移数据步骤
  5. 工作之外的闲暇时光(玩魔方)
  6. 纯粹的Pure Storage,简单却又不简单
  7. vue手机端日期插件
  8. gromacs 安装_GROMACS安装
  9. 如何设置苹果手机铃声
  10. 学前端,学线下班还是丁鹿学堂或者慕课网?