GLSurfaceView简介
GLSurfaceView继承于SurfaceView,主要用于配合OpenGL ES的接口执行渲染窗口的任务。
一、创建及使用
1、在layout文件中使用android.opengl.GLSurfaceView,代码如下:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.opengl.GLSurfaceView
android:id="@+id/surfaceview"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
2、自定义Renderer
public class TestRenderer implements GLSurfaceView.Renderer{
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
//设置窗口大小
GLES20.glViewport(0, 0, width, height);
}
@Override
public void onDrawFrame(GL10 gl) {
//执行清屏
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
GLES20.glClearColor(0.0f, 0.1f, 0.0f, 1.0f);
}
}
3、给GLSurfaceView设置Renderer
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
glSurfaceView = (GLSurfaceView)findViewById(R.id.surfaceview);
TestRenderer renderer = new TestRenderer();
glSurfaceView.setRenderer(renderer);
}
4、执行效果
二、GLSurfaceView原理
上面我们执行GLSurfaceView的setRenderer方法,界面就执行绘制,那么我们从这个方法源码入手:
public void setRenderer(Renderer renderer) {
//第一步,检查GLThread线程是否已经存在,存在则抛出IllegalStateException异常
checkRenderThreadState();
//判断EGL设置是否已经设置过了,没有的话,就会选择最接近安装设备的参数进行设置
if (mEGLConfigChooser == null) {
mEGLConfigChooser = new SimpleEGLConfigChooser(true);
}
//EGLContext上下文创建
if (mEGLContextFactory == null) {
mEGLContextFactory = new DefaultContextFactory();
}
//EGLWindowSurfaceFactory创建
if (mEGLWindowSurfaceFactory == null) {
mEGLWindowSurfaceFactory = new DefaultWindowSurfaceFactory();
}
mRenderer = renderer;
//开启一个线程,执行相关操作,这里才是重头戏
mGLThread = new GLThread(mThisWeakRef);
mGLThread.start();
}
从源码上看,setRenderer这个方法前面都是一些初始化环境的判断及创建,后面开启一个GLThread线程,这个线程才是重头戏,我们来看下这个线程的run方法:
@Override
public void run() {
setName("GLThread " + getId());
if (LOG_THREADS) {
Log.i("GLThread", "starting tid=" + getId());
}
try {
//只调用了这个方法
guardedRun();
} catch (InterruptedException e) {
} finally {
sGLThreadManager.threadExiting(this);
}
}
我们来看看这个guardedRun方法源码干了什么事:
private void guardedRun() throws InterruptedException {
mEglHelper = new EglHelper(mGLSurfaceViewWeakRef);
mHaveEglContext = false;
mHaveEglSurface = false;
mWantRenderNotification = false;
try {
GL10 gl = null;
boolean createEglContext = false;
boolean createEglSurface = false;
boolean createGlInterface = false;
boolean lostEglContext = false;
boolean sizeChanged = false;
boolean wantRenderNotification = false;
boolean doRenderNotification = false;
boolean askedToReleaseEglContext = false;
int w =