jzy3d / jogl

Mirror of https://jogamp.org/cgit/jogl.git/
Other
6 stars 2 forks source link

Inconsistent GL Version : exception on GL4bcImpl.getGL2() - macOS #7

Open jzy3d opened 2 years ago

jzy3d commented 2 years ago

Discussed in a JOGL forum while trying to get the highest available OpenGL profile.

Problem

gl.getGL2() throws a "Not a GL2 implementation" when gl instance is GL4bcImpl. GL4bc being backward compatible, it is supposed to be able to return a GL2 instance.

Context

Reproduce

See below a test program to reproduce the issue which can be summarized as follow :

When using :

Then :

Investigation

gl.getGL2() relies on GLContext.isGL2()

public final boolean isGL2() { 
      return 0 != ( ctxOptions & CTX_PROFILE_COMPAT ) && ctxVersion.getMajor()>=1 ; 
} 

so I presume the problem comes from this ctxOptions value. I could not locate exactly where it is set, seamingly somewhere around GLContextImpl.createContextARB

The complete GLContext for macOS BigSur + Silicon is produced by the program given at the end of this ticket

PROFILE       : GLProfile[GL4/GL4.hw]
CAPS (query)  : GLCaps[rgba 8/8/8/0, opaque, accum-rgba 0/0/0/0, dp/st/ms 16/0/0, dbl, mono  , hw, GLProfile[GL4/GL4.hw], offscr[auto-cfg]]
CAPS (found)  : GLCaps[rgba 8/8/8/0, opaque, accum-rgba 0/0/0/0, dp/st/ms 16/0/0, dbl, mono  , hw, GLProfile[GL4/GL4.hw], offscr[fbo]]
--------------------------------------------------
GL_VENDOR     : Apple
GL_RENDERER   : Apple M1
GL_VERSION    : 4.1 Metal - 71.6.4
GL_EXTENSIONS : (43)
GL INSTANCE : jogamp.opengl.gl4.GL4bcImpl

--------------------------------------------------
MacOSXCGLContext [Version 4.1 (Core profile, arb, compat[ES2, ES3], FBO, hardware) - 4.1 Metal - 71.6.4 [GL 4.1.0, vendor 71.6.4 (Metal - 71.6.4)], options 0x4c05, this 0x68bbe345, handle 0x14f8f4500, isShared false, jogamp.opengl.gl4.GL4bcImpl@26aa12dd,
     quirks: [NoOffscreenBitmap, GL4NeedsGL3Request, NeedSharedObjectSync],
    Drawable: ResizeableImpl[Initialized true, realized true, texUnit 0, samples 0,
    Factory   jogamp.opengl.macosx.cgl.MacOSXCGLDrawableFactory@3fd7a715,
    Handle    0x0,
    Caps      GLCaps[rgba 8/8/8/0, opaque, accum-rgba 0/0/0/0, dp/st/ms 16/0/0, dbl, mono  , hw, GLProfile[GL4/GL4.hw], offscr[fbo]],
    fboI back 1, front 0, num 2,
    FBO front read 1, FBO[name r/w 1/1, init true, bound false, size 100x100, samples 0/4, modified false/false, depth RenderAttachment[type DEPTH, format 0x81a5, samples 0, 100x100, name 0x1, obj 0x51cdd8a], stencil null, colorbuffer attachments: 1/8, with 1 textures: [TextureAttachment[type COLOR_TEXTURE, target GL_TEXTURE_2D, level 0, format 0x8051, 100x100, border 0, dataFormat 0x1907, dataType 0x1401; min/mag 0x2600/0x2600, wrap S/T 0x812f/0x812f; name 0x1, obj 0x711f39f9], null, null, null, null, null, null, null], msaa[null, hasSink false, dirty true], state OK, obj 0xd44fc21],
    FBO back  write 2, FBO[name r/w 2/2, init true, bound true, size 100x100, samples 0/4, modified true/true, depth RenderAttachment[type DEPTH, format 0x81a5, samples 0, 100x100, name 0x2, obj 0x2d6eabae], stencil null, colorbuffer attachments: 1/8, with 1 textures: [TextureAttachment[type COLOR_TEXTURE, target GL_TEXTURE_2D, level 0, format 0x8051, 100x100, border 0, dataFormat 0x1907, dataType 0x1401; min/mag 0x2600/0x2600, wrap S/T 0x812f/0x812f; name 0x2, obj 0x23faf8f2], null, null, null, null, null, null, null], msaa[null, hasSink false, dirty true], state OK, obj 0x4e7dc304],
    Surface   WrappedSurface[ displayHandle 0x0
, surfaceHandle 0x0
, size 100x100
, UOB[ OWNS_SURFACE | OWNS_DEVICE | WINDOW_INVISIBLE | SURFACELESS ]
, MacOSXCGLGraphicsConfiguration[DefaultGraphicsScreen[MacOSXGraphicsDevice[type .macosx, connection decon, unitID 0, handle 0x0, owner false, NullToolkitLock[obj 0x64729b1e]], idx 0],
    chosen    GLCaps[rgba 8/8/8/0, opaque, accum-rgba 0/0/0/0, dp/st/ms 16/0/0, dbl, mono  , hw, GLProfile[GL4/GL4.hw], offscr[fbo]],
    requested GLCaps[rgba 8/8/8/0, opaque, accum-rgba 0/0/0/0, dp/st/ms 16/0/0, dbl, mono  , hw, GLProfile[GL4/GL4.hw], offscr[auto-cfg]]]
, surfaceLock <10bbd20a, 48503868>[count 1, qsz 0, owner <main>]
, GenericUpstreamSurfacelessHook[pixel 100x100]
, upstreamSurface false ]], mode NSOPENGL] 

Is compat profile : false
--------------------------------------------------
GL2    : true
GL2GL3 : true
GL3    : true
GL3bc  : false
GL4    : true
GL4ES3 : true
GL4bc  : false

The complete program to reproduce the issue

import org.junit.Test;
import org.jzy3d.chart.factories.NativePainterFactory;
import com.jogamp.opengl.GL;
import com.jogamp.opengl.GLAutoDrawable;
import com.jogamp.opengl.GLCapabilities;
import com.jogamp.opengl.GLDrawableFactory;
import com.jogamp.opengl.GLProfile;

/**
 * This shows how to switch OpenGL version with JOGL.
 * 
 * It requires to invoke the JVM with -Djogl.disable.openglcore=true to work.
 * 
 * @see https://forum.jogamp.org/Selecting-the-highest-possible-GL-profile-at-runtime-td4041302.html
 */
public class Test_OpenGLVersion {
  @Test
  public void openGLversion() throws Exception {
    System.out.println("=============================================================");
    System.out.println("");
    System.out.println("");
    System.out.println("                    OPENGL VERSION INFO                      ");
    System.out.println("");
    System.out.println("");
    System.out.println("=============================================================");

    // ------------------------------------------------------
    // Profile & capabilities

    //GLProfile glp = NativePainterFactory.detectGLProfile(); // use Jzy3D profile selection

    //GLProfile glp = GLProfile.get(GLProfile.GL4);
    GLProfile glp = GLProfile.getMaxProgrammable(true);

    GLCapabilities caps = new GLCapabilities(glp);
    caps.setOnscreen(false);

    // ------------------------------------------------------
    // Drawable to get a GL context

    GLDrawableFactory factory = GLDrawableFactory.getFactory(glp);
    GLAutoDrawable drawable =
        factory.createOffscreenAutoDrawable(factory.getDefaultDevice(), caps, null, 100, 100);
    drawable.display();
    drawable.getContext().makeCurrent();

    GL gl = drawable.getContext().getGL();

    // ------------------------------------------------------
    // Report

    System.out.println("PROFILE       : " + glp);
    System.out.println("CAPS (query)  : " + caps);
    System.out.println("CAPS (found)  : " + drawable.getChosenGLCapabilities());

    System.out.println("--------------------------------------------------");
    System.out.println(getDebugInfo(gl));

    System.out.println("--------------------------------------------------");
    System.out.println(drawable.getContext());
    System.out.println();
    System.out.println("Is compat profile : " + drawable.getContext().isGLCompatibilityProfile());

    System.out.println("--------------------------------------------------");
    System.out.println("GL2    : " + GLProfile.isAvailable(GLProfile.GL2));
    System.out.println("GL2GL3 : " + GLProfile.isAvailable(GLProfile.GL2GL3));
    System.out.println("GL3    : " + GLProfile.isAvailable(GLProfile.GL3));
    System.out.println("GL3bc  : " + GLProfile.isAvailable(GLProfile.GL3bc));
    System.out.println("GL4    : " + GLProfile.isAvailable(GLProfile.GL4));
    System.out.println("GL4ES3 : " + GLProfile.isAvailable(GLProfile.GL4ES3));
    System.out.println("GL4bc  : " + GLProfile.isAvailable(GLProfile.GL4bc));

    // ------------------------------------------------------
    // Try invoking something

    gl.getGL2().glClear(0);

    gl.getGL4bc().glClear(0);

    // ------------------------------------------------------
    // We are done, release context for further work

    drawable.getContext().release();
  }

  public static String getDebugInfo(GL gl) {
    StringBuffer sb = new StringBuffer();
    sb.append("GL_VENDOR     : " + gl.glGetString(GL.GL_VENDOR) + "\n");
    sb.append("GL_RENDERER   : " + gl.glGetString(GL.GL_RENDERER) + "\n");
    sb.append("GL_VERSION    : " + gl.glGetString(GL.GL_VERSION) + "\n");

    String ext = gl.glGetString(GL.GL_EXTENSIONS);

    if(ext!=null) {
      String[] exts = ext.split(" ");
      sb.append("GL_EXTENSIONS : (" + exts.length + ")\n");
      /*for(String e: exts) {
        sb.append("\t" + e + "\n");
      }*/
    }
    else {
      sb.append("GL_EXTENSIONS : null\n");      
    }

    sb.append("GL INSTANCE : " + gl.getClass().getName() + "\n");

    return sb.toString();
  }

}