    public void onSurfaceCreated(final SurfaceHolder holder) {
      if (_debug) Log.d(TAG, "start onSurfaceCreated() [" + this + "]");
      super.onSurfaceCreated(holder);
      Runnable surfaceCreatedCommand = new Runnable() {
        @Override
        public void run() {
          doSurfaceCreated();
        }
        protected void doSurfaceCreated() {
          if (mInitialized) {
            if (_debug) Log.d(TAG, "already Initialized(surfaceCreatedCommand)");
            return;
          }
          boolean ret;
          int counter = 0;
          int specCounter = 0;
          while(true) {
            if (_debug) Log.d(TAG, "start EGLContext.getEGL()");
            exitEgl();
            egl10 = (EGL10) EGLContext.getEGL();
            if (_debug) Log.d(TAG, "end EGLContext.getEGL()");
            if (_debug) Log.d(TAG, "start eglGetDisplay");
            eglDisplay = egl10.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
            if (_debug) Log.d(TAG, "end eglGetDisplay");
            if (eglDisplay == null || EGL10.EGL_NO_DISPLAY.equals(eglDisplay)) {
              String errStr = AtlantisService.getErrorString(egl10.eglGetError());
              if (_debug) Log.d(TAG, "eglGetDisplayがEGL_NO_DISPLAY [" + errStr + "]");
              exitEgl();
              if (++counter >= AtlantisService.RETRY_COUNT) {
                Log.e(TAG, "egl10.eglCreateContextがEGL_NO_DISPLAY");
                throw new RuntimeException("OpenGL Error(EGL_NO_DISPLAY) "
                  + errStr + ": "
                );
              }     
              if (_debug) Log.d(TAG, "RETRY");
              System.gc();
              waitNano();
              continue;
            }
            {
              egl10.eglMakeCurrent(eglDisplay, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT);
            }
            int[] version = new int[2];
            if (! egl10.eglInitialize(eglDisplay, version)) {
              String errStr = AtlantisService.getErrorString(egl10.eglGetError());
              if (_debug) Log.d(TAG, "egl10.eglInitializeがfalse [" + errStr + "]");
              exitEgl();
              if (++counter >= AtlantisService.RETRY_COUNT) {
                Log.e(TAG,"egl10.eglInitializeがfalse");
                throw new RuntimeException("OpenGL Error(eglInitialize) "
                  + errStr + ": "
                );
              }
              if (_debug) Log.d(TAG,"RETRY");
              System.gc();
              waitNano();
              continue;
            }
            EGLConfig[] configs = new EGLConfig[1];
            int[] numConfig = new int[1];
            egl10.eglChooseConfig(eglDisplay, configSpec[specCounter++], configs, 1, numConfig);
            if (numConfig[0] == 0) {
              if (_debug) Log.d(TAG, "numConfig[0]=" + numConfig[0] + "");
              String errStr = AtlantisService.getErrorString(egl10.eglGetError());
              errStr += " eglChooseConfig numConfig == 0 ";
              errStr += " numConfig:[" + numConfig[0] + "]";
              errStr += " specCounter:[" + (specCounter - 1) + "]";
              exitEgl();
              Log.e(TAG,"eglChooseConfig失敗:"
                 + "numConfig:[" + numConfig[0] + "]"
                 + errStr);
              if (++counter >= AtlantisService.RETRY_COUNT) {
                throw new RuntimeException("OpenGL Error "
                  + errStr + " :"
                );
              }
            }
            EGLConfig config = configs[0];
            eglContext = egl10.eglCreateContext(eglDisplay, config, EGL10.EGL_NO_CONTEXT, null); 
            if (eglContext == null || EGL10.EGL_NO_CONTEXT.equals(eglContext)) {
              String errStr = AtlantisService.getErrorString(egl10.eglGetError());
              errStr += "egl10.eglCreateContext == EGL_NO_CONTEXT ";
              errStr += "specCounter:[" + (specCounter - 1) + "]";
              if (_debug) Log.d(TAG, "egl10.eglCreateContext == EGL_NO_CONTEXT [" + errStr + "]");
              exitEgl();
              if (++counter >= AtlantisService.RETRY_COUNT) {
                Log.e(TAG, "egl10.eglCreateContextがEGL_NO_CONTEXT");
                throw new RuntimeException("OpenGL Error(EGL_NO_CONTEXT) "
                  + errStr + " :"
                );
              }
              if (_debug) Log.d(TAG, "RETRY");
              System.gc();
              waitNano();
              continue;
            }
            if (_debug) Log.d(TAG, "eglCreateContext done.");
            eglSurface = egl10.eglCreateWindowSurface(eglDisplay, config, holder, null);
            if (eglSurface == null || EGL10.EGL_NO_SURFACE.equals(eglSurface)) {
              String errStr = AtlantisService.getErrorString(egl10.eglGetError());
              errStr += "egl10.eglCreateWindowSurface == EGL_NO_SURFACE ";
              errStr += "specCounter:[" + (specCounter - 1) + "]";
              if (_debug) Log.d(TAG, "egl10.eglCreateWindowSurface == EGL_NO_SURFACE [" + errStr + "]");
              exitEgl();
              if (++counter >= AtlantisService.RETRY_COUNT) {
                Log.e(TAG, "egl10.eglCreateWindowSurfaceがEGL_NO_SURFACE");
                throw new RuntimeException("OpenGL Error(EGL_NO_SURFACE) "
                  + errStr + " :"
                );
              }
              if (_debug) Log.e(TAG, "RETRY");
              System.gc();
              waitNano();
              continue;
            }
            if (_debug) Log.d(TAG, "eglCreateWindowSurface done.");
            if (! egl10.eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext)) {
              String errStr = AtlantisService.getErrorString(egl10.eglGetError());
              errStr += "egl10.eglMakeCurrent == false ";
              errStr += "specCounter:[" + (specCounter - 1) + "]";
              if (_debug) Log.d(TAG, "egl10.eglMakeCurrent == false [" + errStr + "]");
              exitEgl();
              if (++counter >= AtlantisService.RETRY_COUNT) {
                Log.e(TAG,"egl10.eglMakeCurrentがfalse");
                throw new RuntimeException("OpenGL Error(eglMakeCurrent) "
                  + errStr + " :"
                );
              }
              if (_debug) Log.d(TAG,"RETRY");
              System.gc();
              waitNano();
              continue;
            }
            if (_debug) Log.d(TAG, "eglMakeCurrent done.");
            if (_debug) Log.d(TAG, "now create gl10 object");
            gl10 = new MatrixTrackingGL((GL10) (eglContext.getGL()));
            glRenderer = GLRenderer.getInstance(getApplicationContext());
            synchronized (glRenderer) {
              glRenderer.onSurfaceCreated(gl10, config, getApplicationContext());
            }
            if (_debug) Log.d(TAG, "EGL initalize done.");
            mInitialized = true;
            if (drawCommand == null) {
              drawCommand = new Runnable() {
                public void run() {
                  doDrawCommand();
                }
                protected void doDrawCommand() {
                  if (mInitialized && glRenderer != null && gl10 != null) {
                    synchronized (glRenderer) {
                      long nowTime = System.nanoTime();
                      if (nowTime - glRenderer.prevTick < BASE_TICK) {
                        try {
                          TimeUnit.NANOSECONDS.sleep(BASE_TICK - (nowTime - glRenderer.prevTick));
                        } catch (InterruptedException e) {
                        }
                      }
                      glRenderer.onDrawFrame(gl10);
                      glRenderer.prevTick = nowTime;
                    }
                    egl10.eglSwapBuffers(eglDisplay, eglSurface);
                    if (!getExecutor().isShutdown() && isVisible() && egl10.eglGetError() != EGL11.EGL_CONTEXT_LOST) {
                      doExecute(drawCommand);
                    }
                  }
                }
              };
              doExecute(drawCommand);
            }
            break;
          }
        }
      };
      doExecute(surfaceCreatedCommand);
      if (_debug) Log.d(TAG, "end onSurfaceCreated() [" + this + "]");
    }

    public void onSurfaceCreated(final SurfaceHolder holder) {
      if (_debug) Log.d(TAG, "start onSurfaceCreated() [" + this + "]");
      super.onSurfaceCreated(holder);
      Runnable surfaceCreatedCommand = new Runnable() {
        @Override
        public void run() {
          doSurfaceCreated();
        }
        protected void doSurfaceCreated() {
          if (mInitialized) {
            if (_debug) Log.d(TAG, "already Initialized(surfaceCreatedCommand)");
            return;
          }
          boolean ret;
          int counter = 0;
          int specCounter = 0;
          while(true) {
            if (_debug) Log.d(TAG, "start EGLContext.getEGL()");
            exitEgl();
            egl10 = (EGL10) EGLContext.getEGL();
            if (_debug) Log.d(TAG, "end EGLContext.getEGL()");
            if (_debug) Log.d(TAG, "start eglGetDisplay");
            eglDisplay = egl10.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
            if (_debug) Log.d(TAG, "end eglGetDisplay");
            if (eglDisplay == null || EGL10.EGL_NO_DISPLAY.equals(eglDisplay)) {
              String errStr = AtlantisService.getErrorString(egl10.eglGetError());
              if (_debug) Log.d(TAG, "eglGetDisplayがEGL_NO_DISPLAY [" + errStr + "]");
              exitEgl();
              if (++counter >= AtlantisService.RETRY_COUNT) {
                Log.e(TAG, "egl10.eglCreateContextがEGL_NO_DISPLAY");
                throw new RuntimeException("OpenGL Error(EGL_NO_DISPLAY) "
                  + errStr + ": "
                );
              }     
              if (_debug) Log.d(TAG, "RETRY");
              System.gc();
              waitNano();
              continue;
            }
            {
              egl10.eglMakeCurrent(eglDisplay, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT);
            }
            int[] version = new int[2];
            if (! egl10.eglInitialize(eglDisplay, version)) {
              String errStr = AtlantisService.getErrorString(egl10.eglGetError());
              if (_debug) Log.d(TAG, "egl10.eglInitializeがfalse [" + errStr + "]");
              exitEgl();
              if (++counter >= AtlantisService.RETRY_COUNT) {
                Log.e(TAG,"egl10.eglInitializeがfalse");
                throw new RuntimeException("OpenGL Error(eglInitialize) "
                  + errStr + ": "
                );
              }
              if (_debug) Log.d(TAG,"RETRY");
              System.gc();
              waitNano();
              continue;
            }
            EGLConfig[] configs = new EGLConfig[1];
            int[] numConfig = new int[1];
            egl10.eglChooseConfig(eglDisplay, configSpec[specCounter++], configs, 1, numConfig);
            if (numConfig[0] == 0) {
              if (_debug) Log.d(TAG, "numConfig[0]=" + numConfig[0] + "");
              String errStr = AtlantisService.getErrorString(egl10.eglGetError());
              errStr += " eglChooseConfig numConfig == 0 ";
              errStr += " numConfig:[" + numConfig[0] + "]";
              errStr += " specCounter:[" + (specCounter - 1) + "]";
              exitEgl();
              Log.e(TAG,"eglChooseConfig失敗:"
                 + "numConfig:[" + numConfig[0] + "]"
                 + errStr);
              if (++counter >= AtlantisService.RETRY_COUNT) {
                throw new RuntimeException("OpenGL Error "
                  + errStr + " :"
                );
              }
              if (_debug) Log.d(TAG, "RETRY");
              System.gc();
              waitNano();
              continue;
            }
            EGLConfig config = configs[0];
            eglContext = egl10.eglCreateContext(eglDisplay, config, EGL10.EGL_NO_CONTEXT, null); 
            if (eglContext == null || EGL10.EGL_NO_CONTEXT.equals(eglContext)) {
              String errStr = AtlantisService.getErrorString(egl10.eglGetError());
              errStr += "egl10.eglCreateContext == EGL_NO_CONTEXT ";
              errStr += "specCounter:[" + (specCounter - 1) + "]";
              if (_debug) Log.d(TAG, "egl10.eglCreateContext == EGL_NO_CONTEXT [" + errStr + "]");
              exitEgl();
              if (++counter >= AtlantisService.RETRY_COUNT) {
                Log.e(TAG, "egl10.eglCreateContextがEGL_NO_CONTEXT");
                throw new RuntimeException("OpenGL Error(EGL_NO_CONTEXT) "
                  + errStr + " :"
                );
              }
              if (_debug) Log.d(TAG, "RETRY");
              System.gc();
              waitNano();
              continue;
            }
            if (_debug) Log.d(TAG, "eglCreateContext done.");
            eglSurface = egl10.eglCreateWindowSurface(eglDisplay, config, holder, null);
            if (eglSurface == null || EGL10.EGL_NO_SURFACE.equals(eglSurface)) {
              String errStr = AtlantisService.getErrorString(egl10.eglGetError());
              errStr += "egl10.eglCreateWindowSurface == EGL_NO_SURFACE ";
              errStr += "specCounter:[" + (specCounter - 1) + "]";
              if (_debug) Log.d(TAG, "egl10.eglCreateWindowSurface == EGL_NO_SURFACE [" + errStr + "]");
              exitEgl();
              if (++counter >= AtlantisService.RETRY_COUNT) {
                Log.e(TAG, "egl10.eglCreateWindowSurfaceがEGL_NO_SURFACE");
                throw new RuntimeException("OpenGL Error(EGL_NO_SURFACE) "
                  + errStr + " :"
                );
              }
              if (_debug) Log.e(TAG, "RETRY");
              System.gc();
              waitNano();
              continue;
            }
            if (_debug) Log.d(TAG, "eglCreateWindowSurface done.");
            if (! egl10.eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext)) {
              String errStr = AtlantisService.getErrorString(egl10.eglGetError());
              errStr += "egl10.eglMakeCurrent == false ";
              errStr += "specCounter:[" + (specCounter - 1) + "]";
              if (_debug) Log.d(TAG, "egl10.eglMakeCurrent == false [" + errStr + "]");
              exitEgl();
              if (++counter >= AtlantisService.RETRY_COUNT) {
                Log.e(TAG,"egl10.eglMakeCurrentがfalse");
                throw new RuntimeException("OpenGL Error(eglMakeCurrent) "
                  + errStr + " :"
                );
              }
              if (_debug) Log.d(TAG,"RETRY");
              System.gc();
              waitNano();
              continue;
            }
            if (_debug) Log.d(TAG, "eglMakeCurrent done.");
            if (_debug) Log.d(TAG, "now create gl10 object");
            gl10 = new MatrixTrackingGL((GL10) (eglContext.getGL()));
            glRenderer = GLRenderer.getInstance(getApplicationContext());
            synchronized (glRenderer) {
              glRenderer.onSurfaceCreated(gl10, config, getApplicationContext());
            }
            if (_debug) Log.d(TAG, "EGL initalize done.");
            mInitialized = true;
            if (drawCommand == null) {
              drawCommand = new Runnable() {
                public void run() {
                  doDrawCommand();
                }
                protected void doDrawCommand() {
                  if (mInitialized && glRenderer != null && gl10 != null) {
                    synchronized (glRenderer) {
                      long nowTime = System.nanoTime();
                      if (nowTime - glRenderer.prevTick < BASE_TICK) {
                        try {
                          TimeUnit.NANOSECONDS.sleep(BASE_TICK - (nowTime - glRenderer.prevTick));
                        } catch (InterruptedException e) {
                        }
                      }
                      glRenderer.onDrawFrame(gl10);
                      glRenderer.prevTick = nowTime;
                    }
                    egl10.eglSwapBuffers(eglDisplay, eglSurface);
                    if (!getExecutor().isShutdown() && isVisible() && egl10.eglGetError() != EGL11.EGL_CONTEXT_LOST) {
                      doExecute(drawCommand);
                    }
                  }
                }
              };
              doExecute(drawCommand);
            }
            break;
          }
        }
      };
      doExecute(surfaceCreatedCommand);
      if (_debug) Log.d(TAG, "end onSurfaceCreated() [" + this + "]");
    }
