/*
*
* GLThread.java
*
* Created by Wuwang on 2017/3/2
* Copyright © 2016年 深圳哎吖科技. All rights reserved.
*/
package com.aiyaapp.camera.sdk.util;
import java.lang.ref.WeakReference;
import android.opengl.GLSurfaceView;
import com.aiyaapp.camera.sdk.base.Log;
/**
* Description:
*/
public class GLThread extends Thread{
private EGLHelper mEGLHelper;
private WeakReference<RendererBackstage> mWeak;
private boolean mSizeChanged=false;
private int mWidth,mHeight;
private static final GLThreadManager sGlThreadManager=new GLThreadManager();
private int renderMode= GLSurfaceView.RENDERMODE_CONTINUOUSLY;
private boolean mShouldExit=false;
private boolean mRequestPause=false;
private boolean mRequestRender=false;
private boolean mRenderComplete=false;
private boolean mExited=false;
private boolean mPaused=false;
private boolean mHaveEglSurface=false;
private boolean mHaveEglContext=false;
private final String TAG="GLThread";
public GLThread(WeakReference<RendererBackstage> weak){
super();
this.mWeak=weak;
mEGLHelper=new EGLHelper();
}
public void setWindowSize(int width,int height){
this.mWidth=width;
this.mHeight=height;
mSizeChanged=true;
}
public void setRenderMode(int mode){
synchronized (sGlThreadManager){
this.renderMode=mode;
sGlThreadManager.notifyAll();
}
}
public void requestRender(){
synchronized (sGlThreadManager){
mRequestRender=true;
sGlThreadManager.notifyAll();
Log.e(TAG,"notifyAll");
}
}
public void requestExit(){
synchronized (sGlThreadManager){
mShouldExit = true;
sGlThreadManager.notifyAll();
while (! mExited) {
try {
sGlThreadManager.wait();
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
}
}
private void stopEglSurfaceLocked() {
if (mHaveEglSurface) {
mHaveEglSurface = false;
mEGLHelper.destroySurface();
}
}
private void stopEglContextLocked() {
if (mHaveEglContext) {
mEGLHelper.finish();
mHaveEglContext = false;
sGlThreadManager.notifyAll();
}
}
public void onPause(){
synchronized (sGlThreadManager){
mRequestPause=true;
sGlThreadManager.notifyAll();
//保证pause命令能被正常执行完
while ((! mExited) && (! mPaused)) {
Log.e(TAG, "onPause waiting for mPaused.");
try {
sGlThreadManager.wait();
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
}
}
public void onResume(){
synchronized (sGlThreadManager){
mRequestPause=false;
mRequestRender=true;
mRenderComplete=false;
sGlThreadManager.notifyAll();
while ((! mExited) && mPaused && (!mRenderComplete)){
Log.e(TAG,"onResume waiting for !mPaused.");
try {
sGlThreadManager.wait();
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
}
}
@Override
public void run() {
setName("GLThread -"+System.currentTimeMillis());
try {
guardedRun();
// RendererBackstage rend = mWeak.get();
// if (rend != null&&rend.mRenderer!=null) {
// rend.mRenderer.onDestroySurface(mEGLHelper.getGL());
// }
synchronized (sGlThreadManager){
if(mShouldExit){
mExited=true;
Log.e(TAG,"should exit");
RendererBackstage rend=mWeak.get();
if(rend!=null&&rend.mRenderer!=null){
rend.mRenderer.onDestroy();
}
stopEglContextLocked();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void guardedRun() throws InterruptedException {
// boolean surfaceCreated=false;
boolean surfaceChanged=false;
boolean createEglContext=false;
boolean createEglSurface=false;
Log.e(TAG,"start---");
while (true){
synchronized (sGlThreadManager){
while (true){
if(mShouldExit){
return;
}
//处理Pause
boolean pausing=false;
if (mPaused!=mRequestPause){
Log.e(TAG,"mRequestPause:"+mRequestPause);
mPaused = mRequestPause;
pausing = mRequestPause;
sGlThreadManager.notifyAll();
}
//如果确定要暂停且EglSurface存在,释放掉EglSurface
if(pausing&&mHaveEglSurface){
Log.e(TAG,"destroy egl surface");
stopEglSurfaceLocked();
}
//如果确定要暂停且EglContext存在,RendererBackstage为空,或者在暂停时不用保存
//Context,则释放掉EglContext
if(pausing&&mHaveEglContext){
RendererBackstage rbk=mWeak.get();
if(rbk==null||!rbk.mPreserveEglContextOnPause){
Log.e(TAG,"destroy egl context");
stopEglContextLocked();
}
}
//如果绘制对象不存在,则释放掉EGL资源
RendererBackstage rend=mWeak.get();
if(rend==null){
mEGLHelper.finish();
}else if(rend.output==null&&mHaveEglSurface){
stopEglSurfaceLocked();
}
if(readyToDraw()){
Log.e(TAG,"ready to draw");
//不存在EglContext,就创建一个Context
if(!mHaveEglContext){
mEGLHelper.eglStart();
mHaveEglContext=true;
createEglContext=true;
sGlThreadManager.notifyAll();
}
//判断是否需要创建一个EglSurface
if(mHaveEglContext&&!mHaveEglSurface){
mHaveEglSurface=true;
createEglSurface=true;
surfaceChanged=true;
}
if(mHaveEglSurface){
mRequestRender=false;
sGlThreadManager.notifyAll();
Log.e(TAG,"break wait");
break;
}
}
Log.e(TAG,"wait --------------");
sGlThreadManager.wait();
}
}
if(createEglSurface){
Log.e(TAG,"eglCreateSurface");
RendererBackstage rend=mWeak.get();
if(rend!=null&&rend.output!=null){
mEGLHelper.eglCreateSurface(rend.output);
}
createEglSurface=false;
}
if(createEglContext){
Log.e(TAG,"surface created");
RendererBackstage rend=mWeak.get();
if(rend!=null&&rend.mRenderer!=null){
rend.mRenderer.onSurfaceCreated(mEGLHelper.getGL(),mEGLHelper.getEglConfig());
}
createEglContext=false;
}
if(surfaceChanged){
Log.e(TAG,"surface changed");
RendererBackstage rend=mWeak.get();
if(rend!=null&&rend.mRenderer!=null){
rend.mRenderer.onSurfaceChanged(mEGLHelper.getGL(),mWidth,mHeight);
}
surfaceChanged=false;
}
{
RendererBackstage rend = mWeak.get();
if (rend != null&&rend.mRenderer!=null) {
rend.mRenderer.onDrawFrame(mEGLHelper.getGL());
mEGLHelper.swap();
}
}
Log.e(TAG,"draw finish");
}
}
private boolean hasSurface(){
return mWeak.get()!=null&&mWeak.get().output!=null;
}
private boolean readyToDraw(){
return (!mPaused)&&mWidth>0&&mHeight>0&&hasSurface()
&&(mRequestRender||renderMode==GLSurfaceView.RENDERMODE_CONTINUOUSLY);
}
private static class GLThreadManager{
}
}