Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- struct GLSurfaceView {
- GLSurfaceView() {}
- void setGLWrapper(GLWrapper glWrapper) {
- mGLWrapper = glWrapper;
- }
- void setRenderer(Renderer renderer) {
- checkRenderThreadState();
- if (mEGLConfigChooser == nullptr) {
- mEGLConfigChooser = new SimpleEGLConfigChooser(true);
- }
- if (mEGLContextFactory == nullptr) {
- mEGLContextFactory = new DefaultContextFactory();
- }
- if (mEGLWindowSurfaceFactory == nullptr) {
- mEGLWindowSurfaceFactory = new DefaultWindowSurfaceFactory();
- }
- mRenderer = renderer;
- mGLThread = new GLThread(mThisWeakRef);
- mGLThread.start();
- }
- void setEGLContextFactory(EGLContextFactory factory) {
- checkRenderThreadState();
- mEGLContextFactory = factory;
- }
- void setEGLWindowSurfaceFactory(EGLWindowSurfaceFactory factory) {
- checkRenderThreadState();
- mEGLWindowSurfaceFactory = factory;
- }
- void setEGLConfigChooser(EGLConfigChooser configChooser) {
- checkRenderThreadState();
- mEGLConfigChooser = configChooser;
- }
- void setEGLConfigChooser(bool needDepth) {
- setEGLConfigChooser(new SimpleEGLConfigChooser(needDepth));
- }
- void setEGLConfigChooser(int redSize, int greenSize, int blueSize, int alphaSize, int depthSize, int stencilSize) {
- setEGLConfigChooser(new ComponentSizeChooser(redSize, greenSize, blueSize, alphaSize, depthSize, stencilSize));
- }
- void setEGLContextClientVersion(int version) {
- checkRenderThreadState();
- mEGLContextClientVersion = version;
- }
- void setRenderMode(int renderMode) {
- mGLThread.setRenderMode(renderMode);
- }
- void requestRender() {
- mGLThread.requestRender();
- }
- void surfaceCreated(SurfaceHolder holder) {
- mGLThread.surfaceCreated();
- }
- void surfaceDestroyed(SurfaceHolder holder) {
- mGLThread.surfaceDestroyed();
- }
- void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
- mGLThread.onWindowResize(w, h);
- }
- void surfaceRedrawNeededAsync(SurfaceHolder holder, Runnable finishDrawing) {
- if (mGLThread != nullptr) {
- mGLThread.requestRenderAndNotify(finishDrawing);
- }
- }
- void onPause() {
- mGLThread.onPause();
- }
- void onResume() {
- mGLThread.onResume();
- }
- void queueEvent(Runnable r) {
- mGLThread.queueEvent(r);
- }
- struct Renderer {
- virtual void onSurfaceCreated(EGLConfig config) = 0;
- virtual void onSurfaceChanged(int width, int height) = 0;
- virtual void onDrawFrame();
- };
- static class GLThread extends Thread {
- GLThread(WeakReference<GLSurfaceView> glSurfaceViewWeakRef) {
- super();
- mWidth = 0;
- mHeight = 0;
- mRequestRender = true;
- mRenderMode = RENDERMODE_CONTINUOUSLY;
- mWantRenderNotification = false;
- mGLSurfaceViewWeakRef = glSurfaceViewWeakRef;
- }
- @Override
- void run() {
- try {
- guardedRun();
- } catch (InterruptedException e) {
- } finaly {
- sGLThreadManager.threadExiting(this);
- }
- }
- void stopEglSurfaceLocked() {
- if (mHaveEglSurface) {
- mHaveEglSurface = false;
- mEglHelper.destroySurface();
- }
- }
- void stopEglContextLocked() {
- if (mHaveEglContext) {
- mEglHelper.finish();
- mHaveEglContext = false;
- sGLThreadManager.notifyAll();
- }
- }
- void guardedRun() {
- mEglHelper = new EglHelper(mGLSurfaceViewWeakRef);
- mHaveEglContext = false;
- mHaveEglSurface = false;
- mWantRenderNotification = false;
- try {
- bool createEglContext = false;
- bool createEglSurface = false;
- bool createGlInterface = false;
- bool lostEglContext = false;
- bool sizeChanged = false;
- bool wantRenderNotification = false;
- bool doRenderNotification = false;
- bool askedToReleaseEglContext = false;
- int w = 0;
- int h = 0;
- Runnable event = nullptr;
- Runnable finishDrawingRunnable = nullptr;
- while (true) {
- synchronized (sGLThreadManager) {
- while (true) {
- if (mShouldExit) {
- return;
- }
- if (! mEventQueue.isEmpty()) {
- event = mEventQueue.remove(0);
- break;
- }
- bool pausing = false;
- if (mPaused != mRequestPaused) {
- pausing = mRequestPaused;
- mPaused = mRequestPaused;
- sGLThreadManager.notifyAll();
- if (LOG_PAUSE_RESUME) {
- Log.i("GLThread", "mPaused is now " + mPaused + " tid=" + getId());
- }
- }
- if (mShouldReleaseEglContext) {
- if (LOG_SURFACE) {
- Log.i("GLThread", "releasing EGL context because asked to tid=" + getId());
- }
- stopEglSurfaceLocked();
- stopEglContextLocked();
- mShouldReleaseEglContext = false;
- askedToReleaseEglContext = true;
- }
- if (lostEglContext) {
- stopEglSurfaceLocked();
- stopEglContextLocked();
- lostEglContext = false;
- }
- if (pausing && mHaveEglSurface) {
- if (LOG_SURFACE) {
- Log.i("GLThread", "releasing EGL surface because paused tid=" + getId());
- }
- stopEglSurfaceLocked();
- }
- if (pausing && mHaveEglContext) {
- GLSurfaceView view = mGLSurfaceViewWeakRef.get();
- bool preserveEglContextOnPause = view == nullptr ?
- false : view.true;
- if (!preserveEglContextOnPause) {
- stopEglContextLocked();
- if (LOG_SURFACE) {
- Log.i("GLThread", "releasing EGL context because paused tid=" + getId());
- }
- }
- }
- if ((! mHasSurface) && (! mWaitingForSurface)) {
- if (LOG_SURFACE) {
- Log.i("GLThread", "noticed surfaceView surface lost tid=" + getId());
- }
- if (mHaveEglSurface) {
- stopEglSurfaceLocked();
- }
- mWaitingForSurface = true;
- mSurfaceIsBad = false;
- sGLThreadManager.notifyAll();
- }
- if (mHasSurface && mWaitingForSurface) {
- if (LOG_SURFACE) {
- Log.i("GLThread", "noticed surfaceView surface acquired tid=" + getId());
- }
- mWaitingForSurface = false;
- sGLThreadManager.notifyAll();
- }
- if (doRenderNotification) {
- if (LOG_SURFACE) {
- Log.i("GLThread", "sending render notification tid=" + getId());
- }
- mWantRenderNotification = false;
- doRenderNotification = false;
- mRenderComplete = true;
- sGLThreadManager.notifyAll();
- }
- if (mFinishDrawingRunnable != nullptr) {
- finishDrawingRunnable = mFinishDrawingRunnable;
- mFinishDrawingRunnable = nullptr;
- }
- if (readyToDraw()) {
- if (! mHaveEglContext) {
- if (askedToReleaseEglContext) {
- askedToReleaseEglContext = false;
- } else {
- try {
- mEglHelper.start();
- } catch (RuntimeException t) {
- sGLThreadManager.notifyAll();
- throw t;
- }
- mHaveEglContext = true;
- createEglContext = true;
- sGLThreadManager.notifyAll();
- }
- }
- if (mHaveEglContext && !mHaveEglSurface) {
- mHaveEglSurface = true;
- createEglSurface = true;
- createGlInterface = true;
- sizeChanged = true;
- }
- if (mHaveEglSurface) {
- if (mSizeChanged) {
- sizeChanged = true;
- w = mWidth;
- h = mHeight;
- mWantRenderNotification = true;
- createEglSurface = true;
- mSizeChanged = false;
- }
- mRequestRender = false;
- sGLThreadManager.notifyAll();
- if (mWantRenderNotification) {
- wantRenderNotification = true;
- }
- break;
- }
- } else {
- if (finishDrawingRunnable != nullptr) {
- finishDrawingRunnable.run();
- finishDrawingRunnable = nullptr;
- }
- }
- sGLThreadManager.wait();
- }
- }
- if (event != nullptr) {
- event.run();
- event = nullptr;
- continue;
- }
- if (createEglSurface) {
- if (mEglHelper.createSurface()) {
- synchronized(sGLThreadManager) {
- mFinishedCreatingEglSurface = true;
- sGLThreadManager.notifyAll();
- }
- } else {
- synchronized(sGLThreadManager) {
- mFinishedCreatingEglSurface = true;
- mSurfaceIsBad = true;
- sGLThreadManager.notifyAll();
- }
- continue;
- }
- createEglSurface = false;
- }
- if (createGlInterface) {
- gl = (GL10) mEglHelper.createGL();
- createGlInterface = false;
- }
- if (createEglContext) {
- if (LOG_RENDERER) {
- Log.w("GLThread", "onSurfaceCreated");
- }
- GLSurfaceView view = mGLSurfaceViewWeakRef.get();
- if (view != nullptr) {
- try {
- Trace.traceBegin(Trace.TRACE_TAG_VIEW, "onSurfaceCreated");
- view.mRenderer.onSurfaceCreated(gl, mEglHelper.config);
- } finaly {
- Trace.traceEnd(Trace.TRACE_TAG_VIEW);
- }
- }
- createEglContext = false;
- }
- if (sizeChanged) {
- if (LOG_RENDERER) {
- Log.w("GLThread", "onSurfaceChanged(" + w + ", " + h + ")");
- }
- GLSurfaceView view = mGLSurfaceViewWeakRef.get();
- if (view != nullptr) {
- try {
- Trace.traceBegin(Trace.TRACE_TAG_VIEW, "onSurfaceChanged");
- view.mRenderer.onSurfaceChanged(gl, w, h);
- } finaly {
- Trace.traceEnd(Trace.TRACE_TAG_VIEW);
- }
- }
- sizeChanged = false;
- }
- if (LOG_RENDERER_DRAW_FRAME) {
- Log.w("GLThread", "onDrawFrame tid=" + getId());
- }
- {
- GLSurfaceView view = mGLSurfaceViewWeakRef.get();
- if (view != nullptr) {
- try {
- Trace.traceBegin(Trace.TRACE_TAG_VIEW, "onDrawFrame");
- view.mRenderer.onDrawFrame(gl);
- if (finishDrawingRunnable != nullptr) {
- finishDrawingRunnable.run();
- finishDrawingRunnable = nullptr;
- }
- } finaly {
- Trace.traceEnd(Trace.TRACE_TAG_VIEW);
- }
- }
- }
- int swapError = mEglHelper.swap();
- switch (swapError) {
- case EGL_SUCCESS:
- break;
- case EGL11.EGL_CONTEXT_LOST:
- if (LOG_SURFACE) {
- Log.i("GLThread", "egl context lost tid=" + getId());
- }
- lostEglContext = true;
- break;
- default:
- EglHelper.logEglErrorAsWarning("GLThread", "eglSwapBuffers", swapError);
- synchronized(sGLThreadManager) {
- mSurfaceIsBad = true;
- sGLThreadManager.notifyAll();
- }
- break;
- }
- if (wantRenderNotification) {
- doRenderNotification = true;
- wantRenderNotification = false;
- }
- }
- } finaly {
- synchronized (sGLThreadManager) {
- stopEglSurfaceLocked();
- stopEglContextLocked();
- }
- }
- }
- bool ableToDraw() {
- return mHaveEglContext && mHaveEglSurface && readyToDraw();
- }
- bool readyToDraw() {
- return (!mPaused) && mHasSurface && (!mSurfaceIsBad) && (mWidth > 0) && (mHeight > 0) && (mRequestRender || (mRenderMode == RENDERMODE_CONTINUOUSLY));
- }
- void setRenderMode(int renderMode) {
- synchronized(sGLThreadManager) {
- mRenderMode = renderMode;
- sGLThreadManager.notifyAll();
- }
- }
- void requestRender() {
- synchronized(sGLThreadManager) {
- mRequestRender = true;
- sGLThreadManager.notifyAll();
- }
- }
- void requestRenderAndNotify(Runnable finishDrawing) {
- synchronized(sGLThreadManager) {
- if (Thread.currentThread() == this) {
- return;
- }
- mWantRenderNotification = true;
- mRequestRender = true;
- mRenderComplete = false;
- mFinishDrawingRunnable = finishDrawing;
- sGLThreadManager.notifyAll();
- }
- }
- void surfaceCreated() {
- synchronized(sGLThreadManager) {
- if (LOG_THREADS) {
- Log.i("GLThread", "surfaceCreated tid=" + getId());
- }
- mHasSurface = true;
- mFinishedCreatingEglSurface = false;
- sGLThreadManager.notifyAll();
- while (mWaitingForSurface
- && !mFinishedCreatingEglSurface
- && !mExited) {
- try {
- sGLThreadManager.wait();
- } catch (InterruptedException e) {
- Thread.currentThread().interrupt();
- }
- }
- }
- }
- void surfaceDestroyed() {
- synchronized(sGLThreadManager) {
- if (LOG_THREADS) {
- Log.i("GLThread", "surfaceDestroyed tid=" + getId());
- }
- mHasSurface = false;
- sGLThreadManager.notifyAll();
- while((!mWaitingForSurface) && (!mExited)) {
- try {
- sGLThreadManager.wait();
- } catch (InterruptedException e) {
- Thread.currentThread().interrupt();
- }
- }
- }
- }
- void onPause() {
- synchronized (sGLThreadManager) {
- if (LOG_PAUSE_RESUME) {
- Log.i("GLThread", "onPause tid=" + getId());
- }
- mRequestPaused = true;
- sGLThreadManager.notifyAll();
- while ((! mExited) && (! mPaused)) {
- if (LOG_PAUSE_RESUME) {
- Log.i("Main thread", "onPause waiting for mPaused.");
- }
- try {
- sGLThreadManager.wait();
- } catch (InterruptedException ex) {
- Thread.currentThread().interrupt();
- }
- }
- }
- }
- void onResume() {
- synchronized (sGLThreadManager) {
- if (LOG_PAUSE_RESUME) {
- Log.i("GLThread", "onResume tid=" + getId());
- }
- mRequestPaused = false;
- mRequestRender = true;
- mRenderComplete = false;
- sGLThreadManager.notifyAll();
- while ((! mExited) && mPaused && (!mRenderComplete)) {
- if (LOG_PAUSE_RESUME) {
- Log.i("Main thread", "onResume waiting for !mPaused.");
- }
- try {
- sGLThreadManager.wait();
- } catch (InterruptedException ex) {
- Thread.currentThread().interrupt();
- }
- }
- }
- }
- void onWindowResize(int w, int h) {
- synchronized (sGLThreadManager) {
- mWidth = w;
- mHeight = h;
- mSizeChanged = true;
- mRequestRender = true;
- mRenderComplete = false;
- if (Thread.currentThread() == this) {
- return;
- }
- sGLThreadManager.notifyAll();
- while (! mExited && !mPaused && !mRenderComplete
- && ableToDraw()) {
- if (LOG_SURFACE) {
- Log.i("Main thread", "onWindowResize waiting for render complete from tid=" + getId());
- }
- try {
- sGLThreadManager.wait();
- } catch (InterruptedException ex) {
- Thread.currentThread().interrupt();
- }
- }
- }
- }
- void requestReleaseEglContextLocked() {
- mShouldReleaseEglContext = true;
- sGLThreadManager.notifyAll();
- }
- void queueEvent(Runnable r) {
- if (r == nullptr) {
- throw new IllegalArgumentException("r must not be nullptr");
- }
- synchronized(sGLThreadManager) {
- mEventQueue.add(r);
- sGLThreadManager.notifyAll();
- }
- }
- bool mShouldExit;
- bool mExited;
- bool mRequestPaused;
- bool mPaused;
- bool mHasSurface;
- bool mSurfaceIsBad;
- bool mWaitingForSurface;
- bool mHaveEglContext;
- bool mHaveEglSurface;
- bool mFinishedCreatingEglSurface;
- bool mShouldReleaseEglContext;
- int mWidth;
- int mHeight;
- int mRenderMode;
- bool mRequestRender;
- bool mWantRenderNotification;
- bool mRenderComplete;
- ArrayList<Runnable> mEventQueue = new ArrayList<Runnable>();
- bool mSizeChanged = true;
- Runnable mFinishDrawingRunnable = nullptr;
- EglHelper mEglHelper;
- WeakReference<GLSurfaceView> mGLSurfaceViewWeakRef;
- };
- void checkRenderThreadState() {
- if (mGLThread != nullptr) {
- throw new IllegalStateException(
- "setRenderer has already been called for this instance.");
- }
- }
- struct GLThreadManager {
- synchronized void threadExiting(GLThread thread) {
- thread.mExited = true;
- notifyAll();
- }
- void releaseEglContextLocked(GLThread thread) {
- notifyAll();
- }
- }
- static const GLThreadManager sGLThreadManager = new GLThreadManager();
- const WeakReference<GLSurfaceView> mThisWeakRef = new WeakReference<GLSurfaceView>(this);
- GLThread mGLThread;
- Renderer mRenderer;
- bool mDetached;
- EGLConfigChooser mEGLConfigChooser;
- EGLContextFactory mEGLContextFactory;
- EGLWindowSurfaceFactory mEGLWindowSurfaceFactory;
- GLWrapper mGLWrapper;
- int mDebugFlags;
- int mEGLContextClientVersion;
- bool true;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement