Create a WebGL Program. Mobile vs Desktop

Update: After some reddit discussions with other mates, we reached to the conclusion that:

  • The error catch by gl.getError() is not produced by GL’s method createShader(). “GetError() just returns the last error, which doesn’t mean it was necessarily the error that occurred fromt he last GL call you made. The error could’ve been from a long time ago, with many GL calls having been made inbetween.” 
  • CreateShader() cannot generate an INVALID_VALUE error
  • “Mobile GPUs and their drivers are less lenient than their desktop counterparts”
  • “GetError() is really a poor way of debugging”. We really need KHR_debug in WebGL for error-checking
  • Always check in other browsers, to see if they catch this error.
  • Check for gl-shader-coreglslify and this post about gl debugging and profiling http://www.realtimerendering.com/blog/webgl-debugging-and-profiling-tools/
  • I didn’t have the time to check what GL line caused the problem, but I will check and write an update here as soon as I can.
  • Thanks to reddit users: jringstadspacejack2114 and mattdesl

I ran into a problem yesterday when I tried to create ,link and compile a WebGL program on a mobile device. On the PC, there were no problems, everything worked fine, my scene was drawn correctly. However on Mobile I saw just a black screen. I immediately knew that there was a WebGL problem there. On PC I have the latest version of Chrome, and the Mobile is a Samsung Galaxy Note 4 with its default browser. I connected the mobile to a PC through a USB cable, to be able to see Chrome Console and search for the bug. And the following red message appeared:

(1281) GL_INVALID_VALUE

This was just before gl.createShader. Was there a problem creating a WebGL shader on mobile? No, other websites with WebGL examples worked fine. I searched over the Internet for hours, and I couldn’t find anything, tried on other Android and iOS devices and nothing, more frustrating was that I couldn’t reproduce the same error on the PC. I thought that there might be some shaders problems on mobile and my GLSL code was not well written.  

My code was like this (just an excerpt, in TypeScript,  should not be a problem to read this if you are a JavaScript programmer):

private createShader(shaderText: string,
                     shaderType: number,
                     name: string): WebGLShader {

   var shader = this.gl.createShader(shaderType);
   this.getError('CreateShader: ' +name);

   // Set the shader source
   this.gl.shaderSource(shader, shaderText);
   this.getError('CreateShader ~ Shader Source ' + name);

   // Compile the shader
   this.gl.compileShader(shader);

    // Check the result of compilation
    var compiled = this.gl.getShaderParameter(shader, this.gl.COMPILE_STATUS);
    if (!compiled) {
      var error = this.gl.getShaderInfoLog(shader);
      this.gl.deleteShader(shader);
      throw 'Failed to compile shader: ' + error + iName;
    }

    return shader;
}

//Catch GL special error
private getError(test: string): boolean {

   var err = this.gl.getError();
   if (err != this.gl.NO_ERROR) {

    switch (err) {
      case this.gl.INVALID_ENUM:
          throw '"GL Error discovered from caller ' + test + '": Invalid enum.\n';
      case this.gl.INVALID_VALUE:
         throw 'GL Error discovered from caller ' + test + ': Invalid Value.\n';

      case this.gl.INVALID_OPERATION:
        throw 'GL Error discovered from caller ' + test + ': Invalid Operation.\n';

     case this.gl.INVALID_FRAMEBUFFER_OPERATION:
        throw 'GL Error discovered from caller ' + test + ': INVALID_FRAMEBUFFER_OPERATION.\n';

        }
   }
    return true;
 }

OK, what if I get rid of all paranoid/defensive programming?. I removed all this.getError() function calls and let just this.gl.getShaderParameter() to check if there are GLSL errors. And it worked on Mobile!!!. I don’t know what’s the reason behind it, why WebGL’s getError() catches this error when you try it on Mobile while it works perfectly on a Desktop. Maybe some WebGL gurus know about this and are able to give an answer.

And of course, after removing all this.getError() from my createShader method above I had to removed them from my other method where I create, attach shaders,link the program. Got the same error message from this.getError().

It’s true, I didn’t see anywhere else on the Internet, WebGL examples or tutorials where gl.getError() is called after every GL line in initialization code. I guess I’m too paranoid :)).


Tagged under:
blog comments powered by Disqus