每个Activity都对应这个顶层的一个DecorView,DecorView是对WMS可见的,WMS就可以为这个View创建一个Surface,(Surface是原始图像缓冲区(raw buffer)的一个句柄,而原始图像缓冲区是由屏幕图像合成器(screen compositor)管理的。如在C语言编程一样,通过一个文件的句柄,就可以操作文件,获取文件的内容。 同样的,通过Surface就可以获取raw buffer其中的内容。原生缓冲区(raw buffer)存储着当前窗口的像素数据)。而SurfaceView就在自己内部简间接创建了一个Surface,这样DecorView和SurfaceView就可以在不同的线程中显示画面。
SurfaceView内部实现了SurfaceHolder接口可以操作Surface,我们直接使用的是Canvas类就可以绘制各种画面,能直观使用到的接口是lockCanvas(),unlockCanvasAndPost()来操作Canvas,但是Canvas的获取是通过Surface的 lockCanvas(Rect inOutDirty)接口,也就是说Canvas是Surface内部成员对象。
Surface是一个ANativeWindow,而ANatvieWidnow是一个EGL可以操作的窗口,所以除了在java层显式调用lockCanvas方法可以操作Surface外,openGL ES通过EGL也能操作Surface。
Android 使用openGL ES必须创建的几个关键类:
(1) EGLDisplay的创建:EGL14.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY)(EGL10也可以)。
(2) EGLConfig的创建:可以实现EGLConfigChooser接口,需要用到EGLDisplay参数
(3) EGLContext的创建:调用egl接口 eglCreateContext(),需要用到EGLDisplay和EGLConfig参数。
(4) EGLSurface的创建:调用EGL的接口eglCreateWindowSurface,需要用到EGLDisplay和EGLConfig参数。
为什么需要创建完成这几个关键类呢?
先来看一下android.opengl包里面的类EGL14的源码(包javax.microedition.khronos.egl里面EGL10类也可以):
首先需要创建display
public static native EGLDisplay eglGetDisplay(
int display_id
);
然后通过display和配置参数config创建context,该context是用于保存openGL ES绘制过程中的一些状态和其他很多重要参数的。
public static native EGLContext eglCreateContext(
EGLDisplay dpy,
EGLConfig config,
EGLContext share_context,
int[] attrib_list,
int offset
);
接着就是创建视频表面来显示画面,display和config也是需要用法,
public static EGLSurface eglCreateWindowSurface(EGLDisplay dpy,EGLConfig config, Object win, int[] attrib_list, int offset){
Surface sur = null;
if (win instanceof SurfaceView) {
SurfaceView surfaceView = (SurfaceView)win;
sur = surfaceView.getHolder().getSurface();
} else if (win instanceof SurfaceHolder) {
SurfaceHolder holder = (SurfaceHolder)win;
sur = holder.getSurface();
} else if (win instanceof Surface) {
sur = (Surface) win;
}
EGLSurface surface;
if (sur != null) {
surface = _eglCreateWindowSurface(dpy, config, sur, attrib_list, offset);
} else if (win instanceof SurfaceTexture) {
surface = _eglCreateWindowSurfaceTexture(dpy, config,
win, attrib_list, offset);
}
return surface;
}
从源码可以看出需要一个Surface才能创建EGLSurface,这个Surface从哪里来呢?就是从SurfaceView里面的SurfaceHolder的
getSurface()方法获取的,GLSurfaceView就是这样获取EGLSurface的。