/**
     * 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;
    }
    GL createEglSurface(Surface surface) throws Surface.OutOfResourcesException {
      // Check preconditions.
      if (sEgl == null) {
        throw new RuntimeException("egl not initialized");
      }
      if (sEglDisplay == null) {
        throw new RuntimeException("eglDisplay not initialized");
      }
      if (sEglConfig == null) {
        throw new RuntimeException("eglConfig not initialized");
      }
      if (Thread.currentThread() != mEglThread) {
        throw new IllegalStateException(
            "HardwareRenderer cannot be used " + "from multiple threads");
      }

      // In case we need to destroy an existing surface
      destroySurface();

      // Create an EGL surface we can render into.
      if (!createSurface(surface)) {
        return null;
      }

      initCaches();

      return mEglContext.getGL();
    }
    void initializeEgl() {
      synchronized (sEglLock) {
        if (sEgl == null && sEglConfig == null) {
          sEgl = (EGL10) EGLContext.getEGL();

          // Get to the default display.
          sEglDisplay = sEgl.eglGetDisplay(EGL_DEFAULT_DISPLAY);

          if (sEglDisplay == EGL_NO_DISPLAY) {
            throw new RuntimeException(
                "eglGetDisplay failed " + GLUtils.getEGLErrorString(sEgl.eglGetError()));
          }

          // We can now initialize EGL for that display
          int[] version = new int[2];
          if (!sEgl.eglInitialize(sEglDisplay, version)) {
            throw new RuntimeException(
                "eglInitialize failed " + GLUtils.getEGLErrorString(sEgl.eglGetError()));
          }

          checkEglErrorsForced();

          sEglConfig = chooseEglConfig();
          if (sEglConfig == null) {
            // We tried to use EGL_SWAP_BEHAVIOR_PRESERVED_BIT, try again without
            if (sDirtyRegions) {
              sDirtyRegions = false;
              sEglConfig = chooseEglConfig();
              if (sEglConfig == null) {
                throw new RuntimeException("eglConfig not initialized");
              }
            } else {
              throw new RuntimeException("eglConfig not initialized");
            }
          }
        }
      }

      ManagedEGLContext managedContext = sEglContextStorage.get();
      mEglContext = managedContext != null ? managedContext.getContext() : null;
      mEglThread = Thread.currentThread();

      if (mEglContext == null) {
        mEglContext = createContext(sEgl, sEglDisplay, sEglConfig);
        sEglContextStorage.set(createManagedContext(mEglContext));
      }
    }