/** Creates instances of CameraTextureRender and SurfaceTexture. */
  public SurfaceTextureManager() {

    textureRender = new CameraTextureRender();
    textureRender.surfaceCreated();

    logger.debug("textureID=" + textureRender.getTextureId());
    surfaceTexture = new SurfaceTexture(textureRender.getTextureId());

    surfaceTexture.setOnFrameAvailableListener(this);
  }
  /**
   * Latches the next buffer into the texture. Must be called from the thread that created the
   * OutputSurface object.
   */
  public void awaitNewImage() {
    final int TIMEOUT_MS = 2500;

    synchronized (frameSyncObject) {
      while (!frameAvailable) {
        try {
          // Wait for onFrameAvailable() to signal us. Use a timeout
          // to avoid stalling the test if it doesn't arrive.
          frameSyncObject.wait(TIMEOUT_MS);
          if (!frameAvailable) {
            // TODO: if "spurious wakeup", continue while loop
            throw new RuntimeException("Camera frame wait timed out");
          }
        } catch (InterruptedException ie) {
          // shouldn't happen
          throw new RuntimeException(ie);
        }
      }
      frameAvailable = false;
    }

    // Latch the data.
    textureRender.checkGlError("before updateTexImage");
    surfaceTexture.updateTexImage();
  }
 @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
 public void release() {
   if (textureRender != null) {
     textureRender.release();
     textureRender = null;
   }
   if (surfaceTexture != null) {
     surfaceTexture.release();
     surfaceTexture = null;
   }
 }
 /** Draws the data from SurfaceTexture onto the current EGL surface. */
 public void drawImage() {
   textureRender.drawFrame(surfaceTexture);
 }