Difference between revisions of "Why Instance Design"

From JogampWiki
Jump to navigation Jump to search
Line 3: Line 3:
 
The content has been taken from [http://forum.jogamp.org/Why-does-JOGL-use-Instances-of-GLContext-GL-instead-of-exposing-a-Static-API-td4034144.html this thread] where Sven decided to elaborate and list the reasons behind that since many people wonder and ask why.
 
The content has been taken from [http://forum.jogamp.org/Why-does-JOGL-use-Instances-of-GLContext-GL-instead-of-exposing-a-Static-API-td4034144.html this thread] where Sven decided to elaborate and list the reasons behind that since many people wonder and ask why.
  
<h2>Then why does JOGL use Instances of GLContext / GL* instead of exposing a Static API?</h2>
+
== Then why does JOGL use Instances of GLContext / GL* instead of exposing a Static API? ==
 +
<br />
 +
Essentially because this is how it '''should''' be planned, doing differently is a '''wrong''' design. We are all about exposing a correct API, reflecting the real implementation model / design.<br />
 +
  Hint: OpenGL's implementation is not static!
 +
About having a static implementation, read the bottom remark!
 +
<br />
  
Essentially because this is how it '''should''' be planned, doing differently is a '''wrong''' design. We are all about exposing a correct API, reflecting the real implementation model / design.
+
==== "Isn't static invocation faster?" ====
  
Answer: "Isn't static invocation faster?"
+
OpenGL is a state machine. It associates locks and memory references and those OpenGL rendering states. In JOGL, we do track certain states, required for a functional binding.
  
Question:
+
- [{{SERVER}}/deployment/jogamp-next/javadoc/jogl/javadoc/com/jogamp/opengl/GLBufferStorage.html GLBufferStorage] and its private tracker is used to manage memory mapped and use-create storage.
 +
 
 +
- Seamless FBO handling requires us to track currently used [{{SERVER}}/deployment/jogamp-next/javadoc/jogl/javadoc/com/jogamp/opengl/GLBase.html#getDefaultDrawFramebuffer() FBO buffer]. This allows us to pipe even onscreen rendering using FBO as required for certain machines (OSX/CALayer with AWT). However, this can be utilized by user applications, since tracking of the FBO is for free.
 +
 
 +
- [{{SERVER}}/deployment/jogamp-next/javadoc/jogl/javadoc/com/jogamp/opengl/GLSharedContextSetter.html Sharing GLContext], to allow seamless and stable context sharing, we are required to track its actual state to know when we are able to create the shared 'slave' context.
 +
 
 +
- Last but not least, GLContext performs proper locking. User can query states and try locking, as well as associate data to TLS.
 +
 
 +
Tracking these states allows us not to query the native OpenGL context via glGet*. The latter most certainly cause a pipeline flush/sync and slow down rendering, see [{{SERVER}}/bugzilla/show_bug.cgi?id=1066 Bug 1066].
 +
 
 +
Tracking itself is cheap, occurring on the Java side simply setting a variable
 +
or using O(1) maps for more advanced stuff (memory objects).
  
- OpenGL is a state machine. It associates locks and memory references and those OpenGL rendering states.
+
==== "Isn't it more like OpenGL to have it static?" ====
  
In JOGL, we do track certain states, required for a functional binding.
+
OpenGL has many variations, read: Profiles. You can have different OpenGL context, e.g. GL 3.3, GL 4.5, ES 3.1 .. and so on.
 +
See [{{SERVER}}/jogl/doc/Overview-OpenGL-Evolution-And-JOGL.html OpenGL-Evolution-And-JOGL].<br />
 +
In JOGL you can actually use desktop GL [1.x - 4.5] besides GL-ES [1.0 - 3.1] in the same application!
  
- [{{SERVER}}/deployment/jogamp-next/javadoc/jogl/javadoc/com/jogamp/opengl/GLBufferStorage.html GLBufferStorage] and its private tracker is used to manage memory mapped and use-create storage.
+
==== "It's quite a burden to pass the GL object, isn't it?" ====
 +
 
 +
OpenGL may expose different function tables. OpenGL may even expose different function pointer, using different function tables depending on the OpenGL profile and what-not.
 +
OpenGL may be implemented by different native libraries (libGL, libGLES, ..).
 +
 
 +
Here it is required to bind the exposed OpenGL functions _dynamically_ to their respective function table used in JOGL.
 +
JOGL caches there function tables using certain compatibility criterias, e.g.
 +
* Display connection (X11 networking)!
 +
* OpenGL profile
 +
 
 +
See the previous answer as well.
 +
 
 +
----
 +
==== Bottom Remark ====
 +
 
 +
A static API can accommodate the above by using thread-local-storage (TLS).
 +
 
 +
However, this would require to map all the static API entries to proper state-full objects.
  
- Seamless FBO handling requires us to track currently used [[{{SERVER}}/deployment/jogamp-next/javadoc/jogl/javadoc/com/jogamp/opengl/GLBase.html#getDefaultDrawFramebuffer() FBO buffer]
+
* OpenGL actually maps static -> TLS objects
  
This allows us to pipe even onscreen rendering using FBO as required for certain machines (OSX/CALayer w/ AWT). However, this can be utilized by user applications, since tracking of the FBO is for free.
+
* JOGL however, exposes the plain state-full [{{SERVER}}/jogl/doc/uml/html/ API]
 +
 
 +
* Know that TLS access is not as fast as passing an object! (Even though TLS is not slow at all)  
  
- [{{SERVER}}/deployment/jogamp-next/javadoc/jogl/javadoc/com/jogamp/opengl/GLSharedContextSetter.html Sharing GLContext, to allow seamless and stable context sharing, we are required to track its actual state to know when we are able to create the shared 'slave' context.
+
To conclude, using TLS to simulate OO in an OO-language is just wrong.
  
- Last but not least, GLContext performs proper locking. User can query states and try locking, as well as associate data to TLS.
+
Since we like to expose and map reality, the JOGL API is as is!

Revision as of 14:02, 28 January 2016

The scope of this wiki page is essentially to explain why JOGL uses a instance-design instead of a static one, used by other libraries (such as Lwjgl).

The content has been taken from this thread where Sven decided to elaborate and list the reasons behind that since many people wonder and ask why.

Then why does JOGL use Instances of GLContext / GL* instead of exposing a Static API?


Essentially because this is how it should be planned, doing differently is a wrong design. We are all about exposing a correct API, reflecting the real implementation model / design.

  Hint: OpenGL's implementation is not static!

About having a static implementation, read the bottom remark!

"Isn't static invocation faster?"

OpenGL is a state machine. It associates locks and memory references and those OpenGL rendering states. In JOGL, we do track certain states, required for a functional binding.

- GLBufferStorage and its private tracker is used to manage memory mapped and use-create storage.

- Seamless FBO handling requires us to track currently used FBO buffer. This allows us to pipe even onscreen rendering using FBO as required for certain machines (OSX/CALayer with AWT). However, this can be utilized by user applications, since tracking of the FBO is for free.

- Sharing GLContext, to allow seamless and stable context sharing, we are required to track its actual state to know when we are able to create the shared 'slave' context.

- Last but not least, GLContext performs proper locking. User can query states and try locking, as well as associate data to TLS.

Tracking these states allows us not to query the native OpenGL context via glGet*. The latter most certainly cause a pipeline flush/sync and slow down rendering, see Bug 1066.

Tracking itself is cheap, occurring on the Java side simply setting a variable or using O(1) maps for more advanced stuff (memory objects).

"Isn't it more like OpenGL to have it static?"

OpenGL has many variations, read: Profiles. You can have different OpenGL context, e.g. GL 3.3, GL 4.5, ES 3.1 .. and so on. See OpenGL-Evolution-And-JOGL.
In JOGL you can actually use desktop GL [1.x - 4.5] besides GL-ES [1.0 - 3.1] in the same application!

"It's quite a burden to pass the GL object, isn't it?"

OpenGL may expose different function tables. OpenGL may even expose different function pointer, using different function tables depending on the OpenGL profile and what-not. OpenGL may be implemented by different native libraries (libGL, libGLES, ..).

Here it is required to bind the exposed OpenGL functions _dynamically_ to their respective function table used in JOGL. JOGL caches there function tables using certain compatibility criterias, e.g.

  • Display connection (X11 networking)!
  • OpenGL profile

See the previous answer as well.


Bottom Remark

A static API can accommodate the above by using thread-local-storage (TLS).

However, this would require to map all the static API entries to proper state-full objects.

  • OpenGL actually maps static -> TLS objects
  • JOGL however, exposes the plain state-full API
  • Know that TLS access is not as fast as passing an object! (Even though TLS is not slow at all)

To conclude, using TLS to simulate OO in an OO-language is just wrong.

Since we like to expose and map reality, the JOGL API is as is!