Beispiel #1
0
  private static void initEGL() {
    if (sEGL != null) {
      return;
    }

    sEGL = (EGL10) EGLContext.getEGL();

    sEGLDisplay = sEGL.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
    if (sEGLDisplay == EGL10.EGL_NO_DISPLAY) {
      Log.w(LOGTAG, "can't get EGL display!");
      return;
    }

    // while calling eglInitialize here should not be necessary as it was already called
    // by the EGLPreloadingThread, it really doesn't cost much to call it again here,
    // and makes this code easier to think about: EGLPreloadingThread is only a
    // preloading optimization, not something we rely on for anything else.
    //
    // Also note that while calling eglInitialize isn't necessary on Android 4.x
    // (at least Android's HardwareRenderer does it for us already), it is necessary
    // on Android 2.x.
    int[] returnedVersion = new int[2];
    if (!sEGL.eglInitialize(sEGLDisplay, returnedVersion)) {
      Log.w(LOGTAG, "eglInitialize failed");
      return;
    }

    sEGLConfig = chooseConfig();
  }
    private static void printConfig(EGLConfig config) {
      int[] value = new int[1];

      Log.d(LOG_TAG, "EGL configuration " + config + ":");

      sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_RED_SIZE, value);
      Log.d(LOG_TAG, "  RED_SIZE = " + value[0]);

      sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_GREEN_SIZE, value);
      Log.d(LOG_TAG, "  GREEN_SIZE = " + value[0]);

      sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_BLUE_SIZE, value);
      Log.d(LOG_TAG, "  BLUE_SIZE = " + value[0]);

      sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_ALPHA_SIZE, value);
      Log.d(LOG_TAG, "  ALPHA_SIZE = " + value[0]);

      sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_DEPTH_SIZE, value);
      Log.d(LOG_TAG, "  DEPTH_SIZE = " + value[0]);

      sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_STENCIL_SIZE, value);
      Log.d(LOG_TAG, "  STENCIL_SIZE = " + value[0]);

      sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_SAMPLE_BUFFERS, value);
      Log.d(LOG_TAG, "  SAMPLE_BUFFERS = " + value[0]);

      sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_SAMPLES, value);
      Log.d(LOG_TAG, "  SAMPLES = " + value[0]);

      sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_SURFACE_TYPE, value);
      Log.d(LOG_TAG, "  SURFACE_TYPE = 0x" + Integer.toHexString(value[0]));

      sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_CONFIG_CAVEAT, value);
      Log.d(LOG_TAG, "  CONFIG_CAVEAT = 0x" + Integer.toHexString(value[0]));
    }
    @Override
    public void surfaceCreated(SurfaceHolder holder) {
      Log.d(TAG, "surfaceCreated");
      // Lots of stunningly tedious EGL setup. All we want is a 565 surface.
      egl = (EGL10) EGLContext.getEGL();
      display = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
      int[] version = new int[2];
      if (!egl.eglInitialize(display, version)) {
        throw new RuntimeException("eglInitialize failed");
      }
      /*
      int[] attrib_list = new int[] {
      		EGL10.EGL_RED_SIZE, 5,
      		EGL10.EGL_GREEN_SIZE, 6,
      		EGL10.EGL_BLUE_SIZE, 5,
      		EGL10.EGL_ALPHA_SIZE, 0,
      		EGL10.EGL_DEPTH_SIZE, 0,
      		EGL10.EGL_NONE
      };
      egl.eglGetConfigs(display, configs, config_size, num_config)
      EGLConfig[] configs = new EGLConfig[1];
      int[] numConfigs = new int[] {1};
      egl.eglChooseConfig(display, attrib_list, configs, configs.length, numConfigs);
      if (0 == numConfigs[0]) {
      	throw new RuntimeException("No matching EGL config");
      }
      config = configs[0];
       */

      config = getEglConfig565(egl, display);

      ctxt = egl.eglCreateContext(display, config, EGL10.EGL_NO_CONTEXT, null);
    }
  protected boolean checkGL20() {
    EGL10 egl = (EGL10) EGLContext.getEGL();
    EGLDisplay display = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);

    int[] version = new int[2];
    egl.eglInitialize(display, version);

    int EGL_OPENGL_ES2_BIT = 4;
    int[] configAttribs = {
      EGL10.EGL_RED_SIZE,
      4,
      EGL10.EGL_GREEN_SIZE,
      4,
      EGL10.EGL_BLUE_SIZE,
      4,
      EGL10.EGL_RENDERABLE_TYPE,
      EGL_OPENGL_ES2_BIT,
      EGL10.EGL_NONE
    };

    EGLConfig[] configs = new EGLConfig[10];
    int[] num_config = new int[1];
    egl.eglChooseConfig(display, configAttribs, configs, 10, num_config);
    egl.eglTerminate(display);
    return num_config[0] > 0;
  }
    private EGLConfig chooseEglConfig() {
      EGLConfig[] configs = new EGLConfig[1];
      int[] configsCount = new int[1];
      int[] configSpec = getConfig(sDirtyRegions);

      // Debug
      final String debug = SystemProperties.get(PRINT_CONFIG_PROPERTY, "");
      if ("all".equalsIgnoreCase(debug)) {
        sEgl.eglChooseConfig(sEglDisplay, configSpec, null, 0, configsCount);

        EGLConfig[] debugConfigs = new EGLConfig[configsCount[0]];
        sEgl.eglChooseConfig(sEglDisplay, configSpec, debugConfigs, configsCount[0], configsCount);

        for (EGLConfig config : debugConfigs) {
          printConfig(config);
        }
      }

      if (!sEgl.eglChooseConfig(sEglDisplay, configSpec, configs, 1, configsCount)) {
        throw new IllegalArgumentException(
            "eglChooseConfig failed " + GLUtils.getEGLErrorString(sEgl.eglGetError()));
      } else if (configsCount[0] > 0) {
        if ("choice".equalsIgnoreCase(debug)) {
          printConfig(configs[0]);
        }
        return configs[0];
      }

      return null;
    }
Beispiel #6
0
  // EGL functions
  public static boolean initEGL(int majorVersion, int minorVersion, int[] attribs) {
    try {
      if (SDLActivity.mEGLDisplay == null) {
        Log.v("SDL", "Starting up OpenGL ES " + majorVersion + "." + minorVersion);

        EGL10 egl = (EGL10) EGLContext.getEGL();

        EGLDisplay dpy = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);

        int[] version = new int[2];
        egl.eglInitialize(dpy, version);

        EGLConfig[] configs = new EGLConfig[1];
        int[] num_config = new int[1];
        if (!egl.eglChooseConfig(dpy, attribs, configs, 1, num_config) || num_config[0] == 0) {
          Log.e("SDL", "No EGL config available");
          return false;
        }
        EGLConfig config = configs[0];

        SDLActivity.mEGLDisplay = dpy;
        SDLActivity.mEGLConfig = config;
        SDLActivity.mGLMajor = majorVersion;
        SDLActivity.mGLMinor = minorVersion;
      }
      return SDLActivity.createEGLSurface();

    } catch (Exception e) {
      Log.v("SDL", e + "");
      for (StackTraceElement s : e.getStackTrace()) {
        Log.v("SDL", s.toString());
      }
      return false;
    }
  }
 void destroySurface() {
   if (mEglSurface != null && mEglSurface != EGL_NO_SURFACE) {
     sEgl.eglMakeCurrent(sEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
     sEgl.eglDestroySurface(sEglDisplay, mEglSurface);
     mEglSurface = null;
   }
 }
    /*--------- chooseConfig (2 param )-----------------------------------------------------*/
    public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {

      /* Get the number of minimally matching EGL configurations
       */
      Log.d(TAG + "class ConfigChooser", "chooseConfig 2 param");

      int[] num_config = new int[1];
      egl.eglChooseConfig(display, s_configAttribs2, null, 0, num_config);

      int numConfigs = num_config[0];

      if (numConfigs <= 0) {
        throw new IllegalArgumentException("No configs match configSpec");
      }

      /* Allocate then read the array of minimally matching EGL configs
       */
      EGLConfig[] configs = new EGLConfig[numConfigs];
      egl.eglChooseConfig(display, s_configAttribs2, configs, numConfigs, num_config);

      if (DEBUG) {
        printConfigs(egl, display, configs);
      }
      /* Now return the "best" one
       */
      return chooseConfig(egl, display, configs);
    }
Beispiel #9
0
  /**
   * After some initialization the method loops and renders the camera image whenever a new frame
   * arrived. The black and white byte array is binded to a texture by the bindCameraTexture method.
   * Afterwards an object can be rendered with this texture.
   */
  public void run() {
    init();

    running = true;

    while (running) {
      if (!running) return;

      // gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);

      newFrameLock.waitUntilTrue(1000000);
      newFrameLock.setValue(false);
      bindCameraTexture(gl);
      gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);

      // gl.glRotatef(1,0,0,1); //Rotate the camera image

      egl.eglSwapBuffers(dpy, surface);

      if (egl.eglGetError() == EGL11.EGL_CONTEXT_LOST) {
        Context c = getContext();
        if (c instanceof Activity) {
          ((Activity) c).finish();
        }
      }
    }
  }
Beispiel #10
0
  private boolean initGLES() {

    EGL10 egl = (EGL10) EGLContext.getEGL();

    mEglDisplay = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
    if (mEglDisplay == EGL10.EGL_NO_DISPLAY) {
      Log.e(TAG, "Fail to get Display");
      return false;
    }

    int[] version = new int[2];
    if (!egl.eglInitialize(mEglDisplay, version)) {
      Log.e(TAG, "Fail to eglInitialize");
      return false;
    }

    int[] configSpec = {EGL10.EGL_NONE};
    EGLConfig[] configs = new EGLConfig[1];

    int[] numConfigs = new int[1];
    if (!egl.eglChooseConfig(mEglDisplay, configSpec, configs, 1, numConfigs)) {
      Log.e(TAG, "Fail to Choose Config");
      return false;
    }
    mEglConfig = configs[0];

    mEglContext = egl.eglCreateContext(mEglDisplay, mEglConfig, EGL10.EGL_NO_CONTEXT, null);
    if (mEglContext == EGL10.EGL_NO_CONTEXT) {
      Log.e(TAG, "Fail to Create OpenGL Context");
      return false;
    }
    return true;
  }
    /**
     * Ensures the current EGL context is the one we expect.
     *
     * @return {@link #SURFACE_STATE_ERROR} if the correct EGL context cannot be made current,
     *     {@link #SURFACE_STATE_UPDATED} if the EGL context was changed or {@link
     *     #SURFACE_STATE_SUCCESS} if the EGL context was the correct one
     */
    int checkCurrent() {
      if (mEglThread != Thread.currentThread()) {
        throw new IllegalStateException(
            "Hardware acceleration can only be used with a "
                + "single UI thread.\nOriginal thread: "
                + mEglThread
                + "\n"
                + "Current thread: "
                + Thread.currentThread());
      }

      if (!mEglContext.equals(sEgl.eglGetCurrentContext())
          || !mEglSurface.equals(sEgl.eglGetCurrentSurface(EGL_DRAW))) {
        if (!sEgl.eglMakeCurrent(sEglDisplay, mEglSurface, mEglSurface, mEglContext)) {
          Log.e(LOG_TAG, "eglMakeCurrent failed " + GLUtils.getEGLErrorString(sEgl.eglGetError()));
          fallback(true);
          return SURFACE_STATE_ERROR;
        } else {
          if (mUpdateDirtyRegions) {
            enableDirtyRegions();
            mUpdateDirtyRegions = false;
          }
          return SURFACE_STATE_UPDATED;
        }
      }
      return SURFACE_STATE_SUCCESS;
    }
    public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {

      /* Get the number of minimally matching EGL configurations
       */
      int[] numConfig = new int[1];
      egl.eglChooseConfig(display, CONFIG_ATTRIBUTES, null, 0, numConfig);

      int numConfigs = numConfig[0];

      if (numConfigs <= 0) {
        throw new IllegalArgumentException("No configs match configSpec");
      }

      /* Allocate then read the array of minimally matching EGL configs
       */
      EGLConfig[] configs = new EGLConfig[numConfigs];
      egl.eglChooseConfig(display, CONFIG_ATTRIBUTES, configs, numConfigs, numConfig);

      if (DEBUG) {
        printConfigs(egl, display, configs);
      }
      /* Now return the "best" one
       */
      return chooseConfig(egl, display, configs);
    }
Beispiel #13
0
 private boolean createSurface() {
   EGL10 egl = (EGL10) EGLContext.getEGL();
   mEglSurface = egl.eglCreateWindowSurface(mEglDisplay, mEglConfig, getHolder(), null);
   if (mEglSurface == EGL10.EGL_NO_SURFACE) {
     return false;
   }
   return true;
 }
 private void cleanupgl() {
   // Unbind and destroy the old EGL surface, if there is one.
   if (surface != null) {
     egl.eglMakeCurrent(
         display, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT);
     egl.eglDestroySurface(display, surface);
     surface = null;
   }
 }
  /**
   * Display the current render surface.
   *
   * @return false if the context has been lost.
   */
  public boolean swap() {
    mEgl.eglSwapBuffers(mEglDisplay, mEglSurface);

    /*
     * Always check for EGL_CONTEXT_LOST, which means the context and all associated data were lost (For instance
     * because the device went to sleep). We need to sleep until we get a new surface.
     */
    return mEgl.eglGetError() != EGL11.EGL_CONTEXT_LOST;
  }
 private void destroySurfaceForTimeWarp() {
   if (null != mMainSurface) {
     Log.v(TAG, "destroying mMainSurface: 0x%x", mMainSurface.hashCode());
     final EGL10 egl = (EGL10) EGLContext.getEGL();
     final EGLDisplay display = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
     egl.eglDestroySurface(display, mMainSurface);
     mMainSurface = null;
   }
 }
Beispiel #17
0
  @Override
  public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

    EGL10 egl = (EGL10) EGLContext.getEGL();

    YabauseRunnable.lockGL();
    egl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext);
    YabauseRunnable.initViewport(width, height);
    YabauseRunnable.unlockGL();
  }
    public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
      int[] num_config = new int[1];

      egl.eglChooseConfig(display, s_configAttribs, null, 0, num_config);

      int numConfigs = num_config[0];

      EGLConfig[] configs = new EGLConfig[numConfigs];

      egl.eglChooseConfig(display, s_configAttribs, configs, numConfigs, num_config);

      return chooseConfig(egl, display, configs);
    }
Beispiel #19
0
 public static boolean createEGLContext() {
   EGL10 egl = (EGL10) EGLContext.getEGL();
   int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
   int contextAttrs[] =
       new int[] {EGL_CONTEXT_CLIENT_VERSION, SDLActivity.mGLMajor, EGL10.EGL_NONE};
   SDLActivity.mEGLContext =
       egl.eglCreateContext(
           SDLActivity.mEGLDisplay, SDLActivity.mEGLConfig, EGL10.EGL_NO_CONTEXT, contextAttrs);
   if (SDLActivity.mEGLContext == EGL10.EGL_NO_CONTEXT) {
     Log.e("SDL", "Couldn't create context");
     return false;
   }
   return true;
 }
        @Override
        public EGLContext createContext(
            final EGL10 egl, final EGLDisplay display, final EGLConfig eglConfig) {
          final int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
          final int[] contextAttribs = {EGL_CONTEXT_CLIENT_VERSION, 3, EGL10.EGL_NONE};

          final EGLContext context =
              egl.eglCreateContext(display, eglConfig, EGL10.EGL_NO_CONTEXT, contextAttribs);
          if (context == EGL10.EGL_NO_CONTEXT) {
            throw new IllegalStateException(
                "eglCreateContext failed; egl error 0x" + Integer.toHexString(egl.eglGetError()));
          }
          return context;
        }
    EGLContext createContext(EGL10 egl, EGLDisplay eglDisplay, EGLConfig eglConfig) {
      int[] attribs = {EGL14.EGL_CONTEXT_CLIENT_VERSION, mGlVersion, EGL_NONE};

      EGLContext context =
          egl.eglCreateContext(
              eglDisplay, eglConfig, EGL_NO_CONTEXT, mGlVersion != 0 ? attribs : null);
      if (context == null || context == EGL_NO_CONTEXT) {
        //noinspection ConstantConditions
        throw new IllegalStateException(
            "Could not create an EGL context. eglCreateContext failed with error: "
                + GLUtils.getEGLErrorString(sEgl.eglGetError()));
      }
      return context;
    }
  /** Initialize EGL for a given configuration spec. */
  @SuppressWarnings("StatementWithEmptyBody")
  public void start() {
    // Log.d("EglHelper" + instanceId, "start()");
    if (mEgl == null) {
      // Log.d("EglHelper" + instanceId, "getting new EGL");
      /*
       * Get an EGL instance
       */
      mEgl = (EGL10) EGLContext.getEGL();
    } else {
      // Log.d("EglHelper" + instanceId, "reusing EGL");
    }

    if (mEglDisplay == null) {
      // Log.d("EglHelper" + instanceId, "getting new display");
      /*
       * Get to the default display.
       */
      mEglDisplay = mEgl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
    } else {
      // Log.d("EglHelper" + instanceId, "reusing display");
    }

    if (mEglConfig == null) {
      // Log.d("EglHelper" + instanceId, "getting new config");
      /*
       * We can now initialize EGL for that display
       */
      int[] version = new int[2];
      mEgl.eglInitialize(mEglDisplay, version);
      mEglConfig = mEGLConfigChooser.chooseConfig(mEgl, mEglDisplay);
    } else {
      // Log.d("EglHelper" + instanceId, "reusing config");
    }

    if (mEglContext == null) {
      // Log.d("EglHelper" + instanceId, "creating new context");
      /*
       * Create an OpenGL ES context. This must be done only once, an OpenGL context is a somewhat heavy object.
       */
      mEglContext = mEGLContextFactory.createContext(mEgl, mEglDisplay, mEglConfig);
      if (mEglContext == null || mEglContext == EGL10.EGL_NO_CONTEXT) {
        throw new RuntimeException("createContext failed");
      }
    } else {
      // Log.d("EglHelper" + instanceId, "reusing context");
    }

    mEglSurface = null;
  }
    public void initgl() {
      cleanupgl();

      // Create new surface. Must succeed.
      surface = egl.eglCreateWindowSurface(display, config, getHolder(), null);
      if (null == surface) {
        throw new RuntimeException("eglCreateWindowSurface");
      }

      // Bind the rendering context to the surface.
      if (!egl.eglMakeCurrent(display, surface, surface, ctxt)) {
        throw new RuntimeException("eglMakeCurrent");
      }
      gl = (GL10) ctxt.getGL();
    }
Beispiel #24
0
  private void createSurface() {
    hasSurface = false;

    if (surface != null) {
      egl.eglMakeCurrent(display, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT);
      egl.eglDestroySurface(display, surface);
    }

    surface = egl.eglCreateWindowSurface(display, config, surfaceHolder, null);
    egl.eglMakeCurrent(display, surface, surface, eglContext);

    gl = eglContext.getGL();

    hasSurface = true;
  }
  @Override
  public EGLConfig chooseConfig(final EGL10 egl, final EGLDisplay display) {
    final int[] numConfig = new int[1];
    final int mConfigSpec[] = ApiHelper.USE_888_PIXEL_FORMAT ? mConfigSpec888 : mConfigSpec565;
    if (!egl.eglChooseConfig(display, mConfigSpec, null, 0, numConfig))
      throw new RuntimeException("eglChooseConfig failed");

    if (numConfig[0] <= 0) throw new RuntimeException("No configs match configSpec");

    final EGLConfig[] configs = new EGLConfig[numConfig[0]];
    if (!egl.eglChooseConfig(display, mConfigSpec, configs, configs.length, numConfig))
      throw new RuntimeException();

    return chooseConfig(egl, display, configs);
  }
Beispiel #26
0
  public static boolean createEGLSurface() {
    if (SDLActivity.mEGLDisplay != null && SDLActivity.mEGLConfig != null) {
      EGL10 egl = (EGL10) EGLContext.getEGL();
      if (SDLActivity.mEGLContext == EGL10.EGL_NO_CONTEXT) createEGLContext();

      if (SDLActivity.mEGLSurface == EGL10.EGL_NO_SURFACE) {
        Log.v("SDL", "Creating new EGL Surface");
        SDLActivity.mEGLSurface =
            egl.eglCreateWindowSurface(
                SDLActivity.mEGLDisplay, SDLActivity.mEGLConfig, SDLActivity.mSurface, null);
        if (SDLActivity.mEGLSurface == EGL10.EGL_NO_SURFACE) {
          Log.e("SDL", "Couldn't create surface");
          return false;
        }
      } else Log.v("SDL", "EGL Surface remains valid");

      if (egl.eglGetCurrentContext() != SDLActivity.mEGLContext) {
        if (!egl.eglMakeCurrent(
            SDLActivity.mEGLDisplay,
            SDLActivity.mEGLSurface,
            SDLActivity.mEGLSurface,
            SDLActivity.mEGLContext)) {
          Log.e("SDL", "Old EGL Context doesnt work, trying with a new one");
          // TODO: Notify the user via a message that the old context could not be restored, and
          // that textures need to be manually restored.
          createEGLContext();
          if (!egl.eglMakeCurrent(
              SDLActivity.mEGLDisplay,
              SDLActivity.mEGLSurface,
              SDLActivity.mEGLSurface,
              SDLActivity.mEGLContext)) {
            Log.e("SDL", "Failed making EGL Context current");
            return false;
          }
        } else Log.v("SDL", "EGL Context made current");
      } else Log.v("SDL", "EGL Context remains current");

      return true;
    } else {
      Log.e(
          "SDL",
          "Surface creation failed, display = "
              + SDLActivity.mEGLDisplay
              + ", config = "
              + SDLActivity.mEGLConfig);
      return false;
    }
  }
    @Override
    boolean initialize(Surface surface) throws Surface.OutOfResourcesException {
      if (isRequested() && !isEnabled()) {
        initializeEgl();
        mGl = createEglSurface(surface);
        mDestroyed = false;

        if (mGl != null) {
          int err = sEgl.eglGetError();
          if (err != EGL_SUCCESS) {
            destroy(true);
            setRequested(false);
          } else {
            if (mCanvas == null) {
              mCanvas = createCanvas();
            }
            if (mCanvas != null) {
              setEnabled(true);
            } else {
              Log.w(LOG_TAG, "Hardware accelerated Canvas could not be created");
            }
          }

          return mCanvas != null;
        }
      }
      return false;
    }
Beispiel #28
0
  public void surfaceDestroyed(SurfaceHolder arg0) {
    if (running) {
      running = false;
      this.newFrameLock.setValue(true);
      try {
        mainLoop.join();
      } catch (Exception ex) {
      }
      mainLoop = null;

      egl.eglMakeCurrent(dpy, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT);
      egl.eglDestroySurface(dpy, surface);
      egl.eglDestroyContext(dpy, eglContext);
      egl.eglTerminate(dpy);
    }
  }
    private int findConfigAttrib(
        EGL10 egl, EGLDisplay display, EGLConfig config, int attribute, int defaultValue) {
      int[] mValue = new int[1];

      if (egl.eglGetConfigAttrib(display, config, attribute, mValue)) return mValue[0];
      return defaultValue;
    }
    public EGLContext createContext(EGL10 egl, EGLDisplay display, EGLConfig eglConfig) {
      int[] attrib_list = {0x3098, 2, EGL10.EGL_NONE};

      EGLContext context =
          egl.eglCreateContext(display, eglConfig, EGL10.EGL_NO_CONTEXT, attrib_list);
      return context;
    }