/*
  * This private method should only be called inside a synchronized(sGLThreadManager) block.
  */
 private void stopEglLocked() {
   if (mHaveEgl) {
     mHaveEgl = false;
     mEglHelper.destroySurface();
     sGLThreadManager.releaseEglSurface(this);
   }
 }
  private void guardedRun() throws InterruptedException {
    mEglHelper =
        new EglHelper(mEGLConfigChooser, mEGLContextFactory, mEGLWindowSurfaceFactory, mGLWrapper);
    try {
      GL10 gl = null;
      boolean tellRendererSurfaceCreated = true;
      boolean tellRendererSurfaceChanged = true;

      /*
       * 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 h = 0;
        boolean changed = false;
        boolean needStart = false;
        boolean eventsWaiting = false;

        synchronized (sGLThreadManager) {
          while (true) {
            // Manage acquiring and releasing the SurfaceView
            // surface and the EGL surface.
            if (mPaused) {
              stopEglLocked();
            }
            if (!mHasSurface) {
              if (!mWaitingForSurface) {
                stopEglLocked();
                mWaitingForSurface = true;
                sGLThreadManager.notifyAll();
              }
            } else {
              if (!mHaveEgl) {
                if (sGLThreadManager.tryAcquireEglSurface(this)) {
                  mHaveEgl = true;
                  mEglHelper.start();
                  mRequestRender = true;
                  needStart = true;
                }
              }
            }

            // Check if we need to wait. If not, update any state
            // that needs to be updated, copy any state that
            // needs to be copied, and use "break" to exit the
            // wait loop.

            if (mDone) {
              return;
            }

            if (mEventsWaiting) {
              eventsWaiting = true;
              mEventsWaiting = false;
              break;
            }

            if ((!mPaused)
                && mHasSurface
                && mHaveEgl
                && (mWidth > 0)
                && (mHeight > 0)
                && (mRequestRender
                    || (mRenderMode == GLWallpaperService.GLEngine.RENDERMODE_CONTINUOUSLY))) {
              changed = mSizeChanged;
              w = mWidth;
              h = mHeight;
              mSizeChanged = false;
              mRequestRender = false;
              if (mHasSurface && mWaitingForSurface) {
                changed = true;
                mWaitingForSurface = false;
                sGLThreadManager.notifyAll();
              }
              break;
            }

            // By design, this is the only place where we wait().

            if (LOG_THREADS) {
              Log.i("GLThread", "waiting tid=" + getId());
            }
            sGLThreadManager.wait();
          }
        } // end of synchronized(sGLThreadManager)

        /*
         * Handle queued events
         */
        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;
        }

        if (needStart) {
          tellRendererSurfaceCreated = true;
          changed = true;
        }
        if (changed) {
          gl = (GL10) mEglHelper.createSurface(mHolder);
          tellRendererSurfaceChanged = true;
        }
        if (tellRendererSurfaceCreated) {
          mRenderer.onSurfaceCreated(gl, mEglHelper.mEglConfig);
          tellRendererSurfaceCreated = false;
        }
        if (tellRendererSurfaceChanged) {
          mRenderer.onSurfaceChanged(gl, w, h);
          tellRendererSurfaceChanged = false;
        }
        if ((w > 0) && (h > 0)) {
          /* draw a frame here */
          mRenderer.onDrawFrame(gl);

          /*
           * Once we're done with GL, we need to call swapBuffers() to instruct the system to display the
           * rendered frame
           */
          mEglHelper.swap();
          Thread.sleep(10);
        }
      }
    } finally {
      /*
       * clean-up everything...
       */
      synchronized (sGLThreadManager) {
        stopEglLocked();
        mEglHelper.finish();
      }
    }
  }