google/ExoPlayer · error · GlException

glError: {gluErrorString(error)}

Error message

glError: {gluErrorString(error)}

What it means

GlUtil.checkGlError() drains ALL pending GLES errors with glGetError() and throws a GlException listing each as 'glError: <string>' (via gluErrorString). GL errors are sticky and set by any preceding GLES call, so this exception rarely points at the line that caused it — it points at the first place that checked. Each message line corresponds to one deferred error code such as GL_INVALID_ENUM, GL_INVALID_VALUE, GL_INVALID_OPERATION, or GL_OUT_OF_MEMORY.

Source

Thrown at library/common/src/main/java/com/google/android/exoplayer2/util/GlUtil.java:418

  }

  /**
   * Collects all OpenGL errors that occurred since this method was last called and throws a {@link
   * GlException} with the combined error message.
   */
  public static void checkGlError() throws GlException {
    StringBuilder errorMessageBuilder = new StringBuilder();
    boolean foundError = false;
    int error;
    while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) {
      if (foundError) {
        errorMessageBuilder.append('\n');
      }
      errorMessageBuilder.append("glError: ").append(gluErrorString(error));
      foundError = true;
    }
    if (foundError) {
      throw new GlException(errorMessageBuilder.toString());
    }
  }

  /**
   * Asserts the texture size is valid.
   *
   * @param width The width for a texture.
   * @param height The height for a texture.
   * @throws GlException If the texture width or height is invalid.
   */
  private static void assertValidTextureSize(int width, int height) throws GlException {
    // TODO(b/201293185): Consider handling adjustments for sizes > GL_MAX_TEXTURE_SIZE
    //  (ex. downscaling appropriately) in a shader program instead of asserting incorrect
    //  values.
    // For valid GL sizes, see:
    // https://www.khronos.org/registry/OpenGL-Refpages/es2.0/xhtml/glTexImage2D.xml
    int[] maxTextureSizeBuffer = new int[1];
    GLES20.glGetIntegerv(GLES20.GL_MAX_TEXTURE_SIZE, maxTextureSizeBuffer, 0);

View on GitHub (pinned to dd430f7053)

Solutions

  1. Reproduce with a GL call tracer (Android GPU Inspector or 'adb shell dumpsys gfxinfo ... framestats'/GPU profiling) to find the actual failing GLES call before the checkGlError() site
  2. Validate every texture size against GlUtil.maxTextureSize()/assertValidTextureSize expectations and use power-of-2-friendly/row-aligned sizes for uncompressed uploads
  3. Ensure an EGL context is current and all GL work runs on the single GL thread that owns the context; never share GL objects across contexts without EGL share-groups
  4. If GL_OUT_OF_MEMORY: reduce output resolution/bitrate in the Transformer/effects configuration (e.g. 1080p instead of 4K) for that device
  5. Update media3/GLES drivers: several INVALID_VALUE bugs on specific OEM drivers are worked around in newer releases

Example fix

// before
int texId = GlUtil.createTexture(GLES20.GL_TEXTURE_2D, 5000, 3000, false); // > max on device -> later glError
// after
int max = GlUtil.maxTextureSize();
int w = Math.min(width, max), h = Math.min(height, max);
int texId = GlUtil.createTexture(GLES20.GL_TEXTURE_2D, w, h, false);
Defensive patterns

Strategy: try-catch

Validate before calling

int err = GLES20.glGetError();
if (err != GLES20.GL_NO_ERROR) {
  // clear or abort before invoking GlUtil helpers
}

Try / catch

try { glOperation(); } catch (GlException e) { /* messages are prefixed 'glError:'; log per-line, release GL objects, abort the frame */ }

Prevention

When it happens

Trigger: Any preceding GLES20/GLES11Ext call on the same thread/context passed invalid arguments: binding a deleted texture id (GL_INVALID_OPERATION), glTexImage2D with non-multiple-of-4 width on uncompressed formats (GL_INVALID_VALUE), using a uniform location from a different program, enabling a capability in the wrong state, or GL_OUT_OF_MEMORY when allocating large textures — then any later GlUtil call that invokes checkGlError() (createTexture, focusFramebuffer, GlProgram.draw, etc.) surfaces them.

Common situations: Device-specific driver quirks (especially on cheap SoCs/emulators), shader compile/link issues surfacing as draw-time INVALID_OPERATION, textures exceeding device max size, calling GL methods without a current EGL context, and interleaving third-party GL code that leaves errors pending before ExoPlayer's GL utility runs.

Related errors


AI-assisted analysis of google/ExoPlayer@dd430f7053 (2026-08-14). Data as JSON: /api/errors/d494d4ddff5527eb. Report an issue: GitHub.