Loading opengl/java/android/opengl/GLSurfaceView.java +125 −134 Original line number Original line Diff line number Diff line Loading @@ -145,6 +145,10 @@ import android.view.SurfaceView; */ */ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback { public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback { private final static boolean LOG_THREADS = false; private final static boolean LOG_THREADS = false; private final static boolean LOG_SURFACE = false; private final static boolean LOG_RENDERER = false; // Work-around for bug 2263168 private final static boolean DRAW_TWICE_AFTER_SIZE_CHANGED = true; /** /** * The renderer only renders * The renderer only renders * when the surface is created, or when {@link #requestRender} is called. * when the surface is created, or when {@link #requestRender} is called. Loading Loading @@ -949,7 +953,6 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback class GLThread extends Thread { class GLThread extends Thread { GLThread(Renderer renderer) { GLThread(Renderer renderer) { super(); super(); mDone = false; mWidth = 0; mWidth = 0; mHeight = 0; mHeight = 0; mRequestRender = true; mRequestRender = true; Loading Loading @@ -982,7 +985,7 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback mHaveEgl = false; mHaveEgl = false; mEglHelper.destroySurface(); mEglHelper.destroySurface(); mEglHelper.finish(); mEglHelper.finish(); sGLThreadManager.releaseEglSurface(this); sGLThreadManager.releaseEglSurfaceLocked(this); } } } } Loading @@ -990,81 +993,89 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback mEglHelper = new EglHelper(); mEglHelper = new EglHelper(); try { try { GL10 gl = null; GL10 gl = null; boolean tellRendererSurfaceCreated = true; boolean createEglSurface = false; boolean tellRendererSurfaceChanged = true; boolean sizeChanged = false; /* * This is our main activity thread's loop, we go until * asked to quit. */ while (!isDone()) { /* * Update the asynchronous state (window size) */ int w = 0; int w = 0; int h = 0; int h = 0; boolean changed = false; Runnable event = null; boolean needStart = false; boolean eventsWaiting = false; while (true) { synchronized (sGLThreadManager) { synchronized (sGLThreadManager) { while (true) { while (true) { // Manage acquiring and releasing the SurfaceView if (mShouldExit) { // surface and the EGL surface. return; if (mPaused) { } if (! mEventQueue.isEmpty()) { event = mEventQueue.remove(0); break; } // Do we need to release the EGL surface? if (mHaveEgl && mPaused) { if (LOG_SURFACE) { Log.i("GLThread", "releasing EGL surface because paused tid=" + getId()); } stopEglLocked(); stopEglLocked(); } } if (!mHasSurface) { if (!mWaitingForSurface) { // Have we lost the surface view surface? if ((! mHasSurface) && (! mWaitingForSurface)) { if (LOG_SURFACE) { Log.i("GLThread", "noticed surfaceView surface lost tid=" + getId()); } if (mHaveEgl) { stopEglLocked(); stopEglLocked(); } mWaitingForSurface = true; mWaitingForSurface = true; sGLThreadManager.notifyAll(); sGLThreadManager.notifyAll(); } } } else { if (!mHaveEgl) { // Have we acquired the surface view surface? if (sGLThreadManager.tryAcquireEglSurface(this)) { if (mHasSurface && mWaitingForSurface) { mHaveEgl = true; if (LOG_SURFACE) { mEglHelper.start(); Log.i("GLThread", "noticed surfaceView surface acquired tid=" + getId()); mRequestRender = true; needStart = true; } } } mWaitingForSurface = false; sGLThreadManager.notifyAll(); } } // Check if we need to wait. If not, update any state // Ready to draw? // that needs to be updated, copy any state that if ((!mPaused) && mHasSurface // needs to be copied, and use "break" to exit the && (mWidth > 0) && (mHeight > 0) // wait loop. && (mRequestRender || (mRenderMode == RENDERMODE_CONTINUOUSLY))) { if (mDone) { return; } if (mEventsWaiting) { // If we don't have an egl surface, try to acquire one. eventsWaiting = true; if ((! mHaveEgl) && sGLThreadManager.tryAcquireEglSurfaceLocked(this)) { mEventsWaiting = false; mHaveEgl = true; break; mEglHelper.start(); createEglSurface = true; sizeChanged = true; sGLThreadManager.notifyAll(); } } if ( (! mPaused) && mHasSurface && mHaveEgl if (mHaveEgl) { && (mWidth > 0) && (mHeight > 0) if (mSizeChanged) { && (mRequestRender || (mRenderMode == RENDERMODE_CONTINUOUSLY)) sizeChanged = true; ) { changed = mSizeChanged; w = mWidth; w = mWidth; h = mHeight; h = mHeight; if (DRAW_TWICE_AFTER_SIZE_CHANGED) { // We keep mRequestRender true so that we draw twice after the size changes. // (Once because of mSizeChanged, the second time because of mRequestRender.) // This forces the updated graphics onto the screen. } else { mRequestRender = false; } mSizeChanged = false; mSizeChanged = false; } else { mRequestRender = false; mRequestRender = false; if (mHasSurface && mWaitingForSurface) { changed = true; mWaitingForSurface = false; sGLThreadManager.notifyAll(); } } sGLThreadManager.notifyAll(); break; break; } } } // By design, this is the only place where we wait(). // By design, this is the only place in a GLThread thread where we wait(). if (LOG_THREADS) { if (LOG_THREADS) { Log.i("GLThread", "waiting tid=" + getId()); Log.i("GLThread", "waiting tid=" + getId()); } } Loading @@ -1072,46 +1083,37 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback } } } // end of synchronized(sGLThreadManager) } // end of synchronized(sGLThreadManager) /* if (event != null) { * Handle queued events event.run(); */ event = null; if (eventsWaiting) { Runnable r; while ((r = getEvent()) != null) { r.run(); if (isDone()) { return; } } // Go back and see if we need to wait to render. continue; continue; } } if (needStart) { if (createEglSurface) { tellRendererSurfaceCreated = true; changed = true; } if (changed) { gl = (GL10) mEglHelper.createSurface(getHolder()); gl = (GL10) mEglHelper.createSurface(getHolder()); tellRendererSurfaceChanged = true; if (LOG_RENDERER) { Log.w("GLThread", "onSurfaceCreated"); } } if (tellRendererSurfaceCreated) { mRenderer.onSurfaceCreated(gl, mEglHelper.mEglConfig); mRenderer.onSurfaceCreated(gl, mEglHelper.mEglConfig); tellRendererSurfaceCreated = false; createEglSurface = false; } if (sizeChanged) { if (LOG_RENDERER) { Log.w("GLThread", "onSurfaceChanged(" + w + ", " + h + ")"); } } if (tellRendererSurfaceChanged) { mRenderer.onSurfaceChanged(gl, w, h); mRenderer.onSurfaceChanged(gl, w, h); tellRendererSurfaceChanged = false; sizeChanged = false; } } if ((w > 0) && (h > 0)) { /* draw a frame here */ mRenderer.onDrawFrame(gl); /* if (LOG_RENDERER) { * Once we're done with GL, we need to call swapBuffers() Log.w("GLThread", "onDrawFrame"); * to instruct the system to display the rendered frame } */ mRenderer.onDrawFrame(gl); mEglHelper.swap(); if(!mEglHelper.swap()) { if (LOG_SURFACE) { Log.i("GLThread", "egl surface lost tid=" + getId()); } } } } } } finally { } finally { Loading @@ -1124,23 +1126,15 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback } } } } private boolean isDone() { synchronized (sGLThreadManager) { return mDone; } } public void setRenderMode(int renderMode) { public void setRenderMode(int renderMode) { if ( !((RENDERMODE_WHEN_DIRTY <= renderMode) && (renderMode <= RENDERMODE_CONTINUOUSLY)) ) { if ( !((RENDERMODE_WHEN_DIRTY <= renderMode) && (renderMode <= RENDERMODE_CONTINUOUSLY)) ) { throw new IllegalArgumentException("renderMode"); throw new IllegalArgumentException("renderMode"); } } synchronized(sGLThreadManager) { synchronized(sGLThreadManager) { mRenderMode = renderMode; mRenderMode = renderMode; if (renderMode == RENDERMODE_CONTINUOUSLY) { sGLThreadManager.notifyAll(); sGLThreadManager.notifyAll(); } } } } } public int getRenderMode() { public int getRenderMode() { synchronized(sGLThreadManager) { synchronized(sGLThreadManager) { Loading Loading @@ -1172,7 +1166,7 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback } } mHasSurface = false; mHasSurface = false; sGLThreadManager.notifyAll(); sGLThreadManager.notifyAll(); while(!mWaitingForSurface && isAlive() && ! mDone) { while((!mWaitingForSurface) && (!mExited)) { try { try { sGLThreadManager.wait(); sGLThreadManager.wait(); } catch (InterruptedException e) { } catch (InterruptedException e) { Loading Loading @@ -1202,6 +1196,7 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback mWidth = w; mWidth = w; mHeight = h; mHeight = h; mSizeChanged = true; mSizeChanged = true; mRequestRender = true; sGLThreadManager.notifyAll(); sGLThreadManager.notifyAll(); } } } } Loading @@ -1210,43 +1205,36 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback // don't call this from GLThread thread or it is a guaranteed // don't call this from GLThread thread or it is a guaranteed // deadlock! // deadlock! synchronized(sGLThreadManager) { synchronized(sGLThreadManager) { mDone = true; mShouldExit = true; sGLThreadManager.notifyAll(); sGLThreadManager.notifyAll(); } while (! mExited) { try { try { join(); sGLThreadManager.wait(); } catch (InterruptedException ex) { } catch (InterruptedException ex) { Thread.currentThread().interrupt(); Thread.currentThread().interrupt(); } } } } } } /** /** * Queue an "event" to be run on the GL rendering thread. * Queue an "event" to be run on the GL rendering thread. * @param r the runnable to be run on the GL rendering thread. * @param r the runnable to be run on the GL rendering thread. */ */ public void queueEvent(Runnable r) { public void queueEvent(Runnable r) { synchronized(this) { if (r == null) { mEventQueue.add(r); throw new IllegalArgumentException("r must not be null"); } synchronized(sGLThreadManager) { synchronized(sGLThreadManager) { mEventsWaiting = true; mEventQueue.add(r); sGLThreadManager.notifyAll(); sGLThreadManager.notifyAll(); } } } } } private Runnable getEvent() { synchronized(this) { if (mEventQueue.size() > 0) { return mEventQueue.remove(0); } } return null; } // Once the thread is started, all accesses to the following member // Once the thread is started, all accesses to the following member // variables are protected by the sGLThreadManager monitor // variables are protected by the sGLThreadManager monitor private boolean mDone; private boolean mShouldExit; private boolean mExited; private boolean mPaused; private boolean mPaused; private boolean mHasSurface; private boolean mHasSurface; private boolean mWaitingForSurface; private boolean mWaitingForSurface; Loading @@ -1255,11 +1243,10 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback private int mHeight; private int mHeight; private int mRenderMode; private int mRenderMode; private boolean mRequestRender; private boolean mRequestRender; private boolean mEventsWaiting; private ArrayList<Runnable> mEventQueue = new ArrayList<Runnable>(); // End of member variables protected by the sGLThreadManager monitor. // End of member variables protected by the sGLThreadManager monitor. private Renderer mRenderer; private Renderer mRenderer; private ArrayList<Runnable> mEventQueue = new ArrayList<Runnable>(); private EglHelper mEglHelper; private EglHelper mEglHelper; } } Loading Loading @@ -1309,7 +1296,7 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback if (LOG_THREADS) { if (LOG_THREADS) { Log.i("GLThread", "exiting tid=" + thread.getId()); Log.i("GLThread", "exiting tid=" + thread.getId()); } } thread.mDone = true; thread.mExited = true; if (mEglOwner == thread) { if (mEglOwner == thread) { mEglOwner = null; mEglOwner = null; } } Loading @@ -1318,10 +1305,11 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback /* /* * Tries once to acquire the right to use an EGL * Tries once to acquire the right to use an EGL * surface. Does not block. * surface. Does not block. Requires that we are already * in the sGLThreadManager monitor when this is called. * @return true if the right to use an EGL surface was acquired. * @return true if the right to use an EGL surface was acquired. */ */ public synchronized boolean tryAcquireEglSurface(GLThread thread) { public boolean tryAcquireEglSurfaceLocked(GLThread thread) { if (mEglOwner == thread || mEglOwner == null) { if (mEglOwner == thread || mEglOwner == null) { mEglOwner = thread; mEglOwner = thread; notifyAll(); notifyAll(); Loading @@ -1329,8 +1317,11 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback } } return false; return false; } } /* public synchronized void releaseEglSurface(GLThread thread) { * Releases the EGL surface. Requires that we are already in the * sGLThreadManager monitor when this is called. */ public void releaseEglSurfaceLocked(GLThread thread) { if (mEglOwner == thread) { if (mEglOwner == thread) { mEglOwner = null; mEglOwner = null; } } Loading Loading
opengl/java/android/opengl/GLSurfaceView.java +125 −134 Original line number Original line Diff line number Diff line Loading @@ -145,6 +145,10 @@ import android.view.SurfaceView; */ */ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback { public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback { private final static boolean LOG_THREADS = false; private final static boolean LOG_THREADS = false; private final static boolean LOG_SURFACE = false; private final static boolean LOG_RENDERER = false; // Work-around for bug 2263168 private final static boolean DRAW_TWICE_AFTER_SIZE_CHANGED = true; /** /** * The renderer only renders * The renderer only renders * when the surface is created, or when {@link #requestRender} is called. * when the surface is created, or when {@link #requestRender} is called. Loading Loading @@ -949,7 +953,6 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback class GLThread extends Thread { class GLThread extends Thread { GLThread(Renderer renderer) { GLThread(Renderer renderer) { super(); super(); mDone = false; mWidth = 0; mWidth = 0; mHeight = 0; mHeight = 0; mRequestRender = true; mRequestRender = true; Loading Loading @@ -982,7 +985,7 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback mHaveEgl = false; mHaveEgl = false; mEglHelper.destroySurface(); mEglHelper.destroySurface(); mEglHelper.finish(); mEglHelper.finish(); sGLThreadManager.releaseEglSurface(this); sGLThreadManager.releaseEglSurfaceLocked(this); } } } } Loading @@ -990,81 +993,89 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback mEglHelper = new EglHelper(); mEglHelper = new EglHelper(); try { try { GL10 gl = null; GL10 gl = null; boolean tellRendererSurfaceCreated = true; boolean createEglSurface = false; boolean tellRendererSurfaceChanged = true; boolean sizeChanged = false; /* * This is our main activity thread's loop, we go until * asked to quit. */ while (!isDone()) { /* * Update the asynchronous state (window size) */ int w = 0; int w = 0; int h = 0; int h = 0; boolean changed = false; Runnable event = null; boolean needStart = false; boolean eventsWaiting = false; while (true) { synchronized (sGLThreadManager) { synchronized (sGLThreadManager) { while (true) { while (true) { // Manage acquiring and releasing the SurfaceView if (mShouldExit) { // surface and the EGL surface. return; if (mPaused) { } if (! mEventQueue.isEmpty()) { event = mEventQueue.remove(0); break; } // Do we need to release the EGL surface? if (mHaveEgl && mPaused) { if (LOG_SURFACE) { Log.i("GLThread", "releasing EGL surface because paused tid=" + getId()); } stopEglLocked(); stopEglLocked(); } } if (!mHasSurface) { if (!mWaitingForSurface) { // Have we lost the surface view surface? if ((! mHasSurface) && (! mWaitingForSurface)) { if (LOG_SURFACE) { Log.i("GLThread", "noticed surfaceView surface lost tid=" + getId()); } if (mHaveEgl) { stopEglLocked(); stopEglLocked(); } mWaitingForSurface = true; mWaitingForSurface = true; sGLThreadManager.notifyAll(); sGLThreadManager.notifyAll(); } } } else { if (!mHaveEgl) { // Have we acquired the surface view surface? if (sGLThreadManager.tryAcquireEglSurface(this)) { if (mHasSurface && mWaitingForSurface) { mHaveEgl = true; if (LOG_SURFACE) { mEglHelper.start(); Log.i("GLThread", "noticed surfaceView surface acquired tid=" + getId()); mRequestRender = true; needStart = true; } } } mWaitingForSurface = false; sGLThreadManager.notifyAll(); } } // Check if we need to wait. If not, update any state // Ready to draw? // that needs to be updated, copy any state that if ((!mPaused) && mHasSurface // needs to be copied, and use "break" to exit the && (mWidth > 0) && (mHeight > 0) // wait loop. && (mRequestRender || (mRenderMode == RENDERMODE_CONTINUOUSLY))) { if (mDone) { return; } if (mEventsWaiting) { // If we don't have an egl surface, try to acquire one. eventsWaiting = true; if ((! mHaveEgl) && sGLThreadManager.tryAcquireEglSurfaceLocked(this)) { mEventsWaiting = false; mHaveEgl = true; break; mEglHelper.start(); createEglSurface = true; sizeChanged = true; sGLThreadManager.notifyAll(); } } if ( (! mPaused) && mHasSurface && mHaveEgl if (mHaveEgl) { && (mWidth > 0) && (mHeight > 0) if (mSizeChanged) { && (mRequestRender || (mRenderMode == RENDERMODE_CONTINUOUSLY)) sizeChanged = true; ) { changed = mSizeChanged; w = mWidth; w = mWidth; h = mHeight; h = mHeight; if (DRAW_TWICE_AFTER_SIZE_CHANGED) { // We keep mRequestRender true so that we draw twice after the size changes. // (Once because of mSizeChanged, the second time because of mRequestRender.) // This forces the updated graphics onto the screen. } else { mRequestRender = false; } mSizeChanged = false; mSizeChanged = false; } else { mRequestRender = false; mRequestRender = false; if (mHasSurface && mWaitingForSurface) { changed = true; mWaitingForSurface = false; sGLThreadManager.notifyAll(); } } sGLThreadManager.notifyAll(); break; break; } } } // By design, this is the only place where we wait(). // By design, this is the only place in a GLThread thread where we wait(). if (LOG_THREADS) { if (LOG_THREADS) { Log.i("GLThread", "waiting tid=" + getId()); Log.i("GLThread", "waiting tid=" + getId()); } } Loading @@ -1072,46 +1083,37 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback } } } // end of synchronized(sGLThreadManager) } // end of synchronized(sGLThreadManager) /* if (event != null) { * Handle queued events event.run(); */ event = null; if (eventsWaiting) { Runnable r; while ((r = getEvent()) != null) { r.run(); if (isDone()) { return; } } // Go back and see if we need to wait to render. continue; continue; } } if (needStart) { if (createEglSurface) { tellRendererSurfaceCreated = true; changed = true; } if (changed) { gl = (GL10) mEglHelper.createSurface(getHolder()); gl = (GL10) mEglHelper.createSurface(getHolder()); tellRendererSurfaceChanged = true; if (LOG_RENDERER) { Log.w("GLThread", "onSurfaceCreated"); } } if (tellRendererSurfaceCreated) { mRenderer.onSurfaceCreated(gl, mEglHelper.mEglConfig); mRenderer.onSurfaceCreated(gl, mEglHelper.mEglConfig); tellRendererSurfaceCreated = false; createEglSurface = false; } if (sizeChanged) { if (LOG_RENDERER) { Log.w("GLThread", "onSurfaceChanged(" + w + ", " + h + ")"); } } if (tellRendererSurfaceChanged) { mRenderer.onSurfaceChanged(gl, w, h); mRenderer.onSurfaceChanged(gl, w, h); tellRendererSurfaceChanged = false; sizeChanged = false; } } if ((w > 0) && (h > 0)) { /* draw a frame here */ mRenderer.onDrawFrame(gl); /* if (LOG_RENDERER) { * Once we're done with GL, we need to call swapBuffers() Log.w("GLThread", "onDrawFrame"); * to instruct the system to display the rendered frame } */ mRenderer.onDrawFrame(gl); mEglHelper.swap(); if(!mEglHelper.swap()) { if (LOG_SURFACE) { Log.i("GLThread", "egl surface lost tid=" + getId()); } } } } } } finally { } finally { Loading @@ -1124,23 +1126,15 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback } } } } private boolean isDone() { synchronized (sGLThreadManager) { return mDone; } } public void setRenderMode(int renderMode) { public void setRenderMode(int renderMode) { if ( !((RENDERMODE_WHEN_DIRTY <= renderMode) && (renderMode <= RENDERMODE_CONTINUOUSLY)) ) { if ( !((RENDERMODE_WHEN_DIRTY <= renderMode) && (renderMode <= RENDERMODE_CONTINUOUSLY)) ) { throw new IllegalArgumentException("renderMode"); throw new IllegalArgumentException("renderMode"); } } synchronized(sGLThreadManager) { synchronized(sGLThreadManager) { mRenderMode = renderMode; mRenderMode = renderMode; if (renderMode == RENDERMODE_CONTINUOUSLY) { sGLThreadManager.notifyAll(); sGLThreadManager.notifyAll(); } } } } } public int getRenderMode() { public int getRenderMode() { synchronized(sGLThreadManager) { synchronized(sGLThreadManager) { Loading Loading @@ -1172,7 +1166,7 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback } } mHasSurface = false; mHasSurface = false; sGLThreadManager.notifyAll(); sGLThreadManager.notifyAll(); while(!mWaitingForSurface && isAlive() && ! mDone) { while((!mWaitingForSurface) && (!mExited)) { try { try { sGLThreadManager.wait(); sGLThreadManager.wait(); } catch (InterruptedException e) { } catch (InterruptedException e) { Loading Loading @@ -1202,6 +1196,7 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback mWidth = w; mWidth = w; mHeight = h; mHeight = h; mSizeChanged = true; mSizeChanged = true; mRequestRender = true; sGLThreadManager.notifyAll(); sGLThreadManager.notifyAll(); } } } } Loading @@ -1210,43 +1205,36 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback // don't call this from GLThread thread or it is a guaranteed // don't call this from GLThread thread or it is a guaranteed // deadlock! // deadlock! synchronized(sGLThreadManager) { synchronized(sGLThreadManager) { mDone = true; mShouldExit = true; sGLThreadManager.notifyAll(); sGLThreadManager.notifyAll(); } while (! mExited) { try { try { join(); sGLThreadManager.wait(); } catch (InterruptedException ex) { } catch (InterruptedException ex) { Thread.currentThread().interrupt(); Thread.currentThread().interrupt(); } } } } } } /** /** * Queue an "event" to be run on the GL rendering thread. * Queue an "event" to be run on the GL rendering thread. * @param r the runnable to be run on the GL rendering thread. * @param r the runnable to be run on the GL rendering thread. */ */ public void queueEvent(Runnable r) { public void queueEvent(Runnable r) { synchronized(this) { if (r == null) { mEventQueue.add(r); throw new IllegalArgumentException("r must not be null"); } synchronized(sGLThreadManager) { synchronized(sGLThreadManager) { mEventsWaiting = true; mEventQueue.add(r); sGLThreadManager.notifyAll(); sGLThreadManager.notifyAll(); } } } } } private Runnable getEvent() { synchronized(this) { if (mEventQueue.size() > 0) { return mEventQueue.remove(0); } } return null; } // Once the thread is started, all accesses to the following member // Once the thread is started, all accesses to the following member // variables are protected by the sGLThreadManager monitor // variables are protected by the sGLThreadManager monitor private boolean mDone; private boolean mShouldExit; private boolean mExited; private boolean mPaused; private boolean mPaused; private boolean mHasSurface; private boolean mHasSurface; private boolean mWaitingForSurface; private boolean mWaitingForSurface; Loading @@ -1255,11 +1243,10 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback private int mHeight; private int mHeight; private int mRenderMode; private int mRenderMode; private boolean mRequestRender; private boolean mRequestRender; private boolean mEventsWaiting; private ArrayList<Runnable> mEventQueue = new ArrayList<Runnable>(); // End of member variables protected by the sGLThreadManager monitor. // End of member variables protected by the sGLThreadManager monitor. private Renderer mRenderer; private Renderer mRenderer; private ArrayList<Runnable> mEventQueue = new ArrayList<Runnable>(); private EglHelper mEglHelper; private EglHelper mEglHelper; } } Loading Loading @@ -1309,7 +1296,7 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback if (LOG_THREADS) { if (LOG_THREADS) { Log.i("GLThread", "exiting tid=" + thread.getId()); Log.i("GLThread", "exiting tid=" + thread.getId()); } } thread.mDone = true; thread.mExited = true; if (mEglOwner == thread) { if (mEglOwner == thread) { mEglOwner = null; mEglOwner = null; } } Loading @@ -1318,10 +1305,11 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback /* /* * Tries once to acquire the right to use an EGL * Tries once to acquire the right to use an EGL * surface. Does not block. * surface. Does not block. Requires that we are already * in the sGLThreadManager monitor when this is called. * @return true if the right to use an EGL surface was acquired. * @return true if the right to use an EGL surface was acquired. */ */ public synchronized boolean tryAcquireEglSurface(GLThread thread) { public boolean tryAcquireEglSurfaceLocked(GLThread thread) { if (mEglOwner == thread || mEglOwner == null) { if (mEglOwner == thread || mEglOwner == null) { mEglOwner = thread; mEglOwner = thread; notifyAll(); notifyAll(); Loading @@ -1329,8 +1317,11 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback } } return false; return false; } } /* public synchronized void releaseEglSurface(GLThread thread) { * Releases the EGL surface. Requires that we are already in the * sGLThreadManager monitor when this is called. */ public void releaseEglSurfaceLocked(GLThread thread) { if (mEglOwner == thread) { if (mEglOwner == thread) { mEglOwner = null; mEglOwner = null; } } Loading