Bug 1068

Summary: Allow GLContext creation and makeCurrent without default framebuffer for OpenGL >= 3.0 (for offscreen / GLFBODrawable usage)
Product: [JogAmp] Jogl Reporter: Sven Gothel <sgothel>
Component: coreAssignee: Sven Gothel <sgothel>
Status: RESOLVED FIXED    
Severity: enhancement CC: sgothel
Priority: ---    
Version: 2.3.0   
Hardware: All   
OS: all   
Type: --- SCM Refs:
35622a7cef4a28ce7e32bf008ef331d9a0d9e3e2 fe4670c4d0efa8e9457e2d89ce77dda774a1dbbb 2120be14c7525ef051d105f9bb02294f78d17d28 3317e7a427fbb81dd3d7daa8116c7d33166ed003
Workaround: ---
Bug Depends on: 1096    
Bug Blocks:    

Description Sven Gothel 2014-09-18 05:37:28 CEST
Drop default framebuffer requirement/usage (windowing system) if GL >= 3.0.

Current impl. creates a dummy native window to provide a default framebuffer.
This apparently is no more required since OpenGL >= 3.0.

See OpenGL spec 3.0, chapter 2.1 OpenGL Fundamentals, page 7:
    "It is possible to use a GL context without a default framebuffer, in which case
    a framebuffer object must be used to perform all rendering. This is useful for 
    applications neeting to perform offscreen rendering."

See OpenGL spec 4.3 core, 2.1. Execution Model, page 10: 
    "It is possible to use a GL context without a default framebuffer, in which case
    a framebuffer object must be used to perform all rendering. This is useful for 
    applications needing to perform offscreen rendering."

GLX/WGL:
    It also allows making an OpenGL 3.0 or later context current
    without providing a default framebuffer.

Operation:
    MakeContextCurrent(dpy, None, None, ctx30); // make current w/o def. framebuffer
    MakeContextCurrent(dpy, None, None, NULL); // release ctx 

See https://www.opengl.org/registry/specs/ARB/glx_create_context.txt
    "If either <draw> or <read> are not a valid GLX drawable, a
     GLXBadDrawable error is generated, unless <draw> and <read> are both
     None and the OpenGL version supported by <ctx> is 3.0 or greater. In
     this case the context is made current without a default framebuffer,
     as defined in chapter 4 of the OpenGL 3.0 Specification."

See https://www.opengl.org/registry/specs/ARB/wgl_create_context.txt
    "If the OpenGL context version of <hglrc> is 3.0 or above, and if
    either the <hdc> parameter of wglMakeCurrent is NULL, or both of the 
    <hDrawDC> and <hReadDC> parameters of wglMakeContextCurrentARB are 
    NULL, then the context is made current, but with no default
    framebuffer defined. The effects of having no default framebuffer on
    the GL are defined in Chapter 4 of the OpenGL 3.0 Specification."

+++

This might not be possible w/ all companion APIs, especially WGL!

See https://www.opengl.org/registry/specs/ARB/wgl_create_context.txt
Issues 4)  
    NOTE: Apparently on Windows, opengl32.dll makes use of the drawable
    argument to identify the namespace of the driver, so we may not be
    able to work around it. 

+++

JOGL shall query whether MakeCurrent operates properly
w/o def. framebuffer within the initial shared resource configuration!
Comment 1 Sven Gothel 2014-10-11 01:46:01 CEST
Mesa 10.2.6 supports GL >= 3.0 context w/o default drawable!

- Debian 8, Jessie

+++

Proprietary Nvidia GNU/Linux driver 340.24 does not .. 

- glXMakeCurrent fails w/ BadMatch
  - Info: Nativewindow X11 Error: 8 - BadMatch (invalid parameter attributes), 
    dpy 0x7fec144a54d0, id 17, # 20: 155:26 Unknown

- Debian 8, Jessie

+++
Comment 2 Sven Gothel 2014-10-11 06:04:11 CEST
OpenGL ES >= 3.0 also [may] support context w/o default framebuffer:

OpenGL ES spec 3.0.2, chapter 2.1 OpenGL Fundamentals, page 6:

"It is possible to use a GL context without a default framebuffer, in which case
a framebuffer object must be used to perform all rendering. This is useful for
applications needing to perform offscreen rendering."

EGL spec 1.5, chapter 3.7.3 Binding Contexts and Drawables, page 60:

"If ctx is not EGL_NO_CONTEXT, then both draw and read must not be EGL_-
NO_SURFACE unless ctx is a context which supports being bound without read and
draw surfaces. In this case the context is made current without a default frame-
buffer. The meaning of this is defined by the client API of the supporting context
(see chapter 4 of the OpenGL 3.0 Specification, and the GL_OES_surfaceless_-
context OpenGL ES extension.)."

<https://www.khronos.org/registry/egl/extensions/KHR/EGL_KHR_create_context.txt>

  "If both <draw> and <read> are EGL_NO_SURFACE, and <ctx> is an OpenGL
   context supporting version 3.0 or later of the OpenGL API, then no
   error is generated and the context is made current without a
   <default framebuffer>. The meaning of this is defined in chapter 4
   of the OpenGL 3.0 Specification."

eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, ctx) // make current w/o def.
eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, NULL) // release

[similar to GLX/WGL ..]
Comment 3 Sven Gothel 2014-10-11 06:18:25 CEST
Implementation strategy:

- Add <TOOL>UpstreamSurfacelessHook to support
  a null surface (i.e. no surface) and hence a null drawable

- Let the initialization stage probe (SharedResource)
  whether platform allow binding a context to null read- and write surface.
  This shall happen for any context >= 3.0 (ES, desktop, ..)

- If platform should support a current surfaceless context (GL >= 3.0)
  but fails to do so, the new GLRendererQuirk.NoSurfacelessCtx shall be set
  for ES and desktop context.

Surfaceless context shall be utilized for offscreen FBO drawables
allowing us to drop the dummy surface.
Comment 4 Sven Gothel 2014-12-07 04:05:26 CET
35622a7cef4a28ce7e32bf008ef331d9a0d9e3e2

    Implement surfaceless context on EGL and GLX/X11
    utilizing *UpstreamSurfacelessHook as introduced in
    commit 9ea218a5990b908e04235c407c0951c60df6ffba.
    
    Surfaceless context is probed during GL profile probing by default.
    If available, it will be used for offscreen FBO drawables.
    If probing fails, or is disabled,
    the new GLRendererQuirks.NoSurfacelessCtx is set.
    
    - GLProfile.disableSurfacelessContext disables
      surfaceless context probing, set property 'jogl.disable.surfacelesscontext'
    
    Tested:
      - Mesa/EGL works,
      - Mesa + NVidia w/ GLX fail on GNU/Linux): Fails NoSurfacelessCtx
    
    - TODO: Windows impl. and more tests
Comment 5 Sven Gothel 2015-01-23 01:01:05 CET
fe4670c4d0efa8e9457e2d89ce77dda774a1dbbb
  Use GenericUpstreamSurfacelessHook for all createSurfacelessImpl(..)
  implementations
Comment 6 Sven Gothel 2015-01-23 22:06:40 CET
2120be14c7525ef051d105f9bb02294f78d17d28

    Unify Surfaceless probing; Fix Surfaceless for OSX and Windows (probing, etc)
    
    - Unify surfaceless probing
      GLDrawableFactoryImpl.probeSurfacelessCtx(..) implements surfaceless probing for all platforms
    
    - Fix Surfaceless for OSX (probing, etc)
      - Handle 'surfaceless' mode in MacOSXCGLContext impl
      - MacOSXCGLDrawableFactory.getOrCreateSharedResourceImpl adds surfaceless probing
    
    - Fix Surfaceless for Windows (probing, etc)
      - WindowsWGLContext.wglMakeContextCurrent(..)
        - Split release code into WindowsWGLContext.wglReleaseContext(..)
          allowing to handle zero HDC.
      - WindowsWGLGraphicsConfigurationFactory.updateGraphicsConfiguration(..)
        - Skip HDC -> PFD handling for
      - WindowsWGLDrawableFactory.createSharedResource adds surfaceless probing

Support for surfaceless context is hereby given.

Subsequent issues shall be filed under a new bug report.
Comment 7 Sven Gothel 2015-02-03 21:20:23 CET
3317e7a427fbb81dd3d7daa8116c7d33166ed003:

Commit 2120be14c7525ef051d105f9bb02294f78d17d28
caused GLDrawableFactoryImpl.probeSurfacelessCtx(..)
to be only called if appropriate, hence GLRendererQuirks.NoSurfacelessCtx
was not set otherwise.
    
This patch adds the required 'else' branch for the case
GLDrawableFactoryImpl.probeSurfacelessCtx(..) is not called
and issues GLDrawableFactoryImpl.setNoSurfacelessCtxQuirk(..).