Android SurfaceView中的Surface,openGL es中 EGLDisplay,EGLConfig,EGLContext,EGLSurface

每个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的。
 
  

你可能感兴趣的:(android)