From 72a84b422327c6abb688339419d3552ec0e5c70c Mon Sep 17 00:00:00 2001
From: Sven Gothel
LPVOID glMapBuffer(GLenum target, GLenum access);
*/
-public java.nio.ByteBuffer glMapBuffer(int target, int access) {
+public final java.nio.ByteBuffer glMapBuffer(int target, int access) {
final long __addr_ = ((GL4bcProcAddressTable)_context.getGLProcAddressTable())._addressof_glMapBuffer;
if (__addr_ == 0) {
throw new GLException("Method \"glMapBuffer\" not available");
@@ -230,7 +232,7 @@ public java.nio.ByteBuffer glMapBuffer(int target, int access) {
native private long dispatch_glMapBuffer(int target, int access, long glProcAddress);
/** Entry point to C language function: GLvoid * {@native glMapNamedBufferEXT}(GLuint buffer, GLenum access);
Part of GL_EXT_direct_state_access
*/
-public java.nio.ByteBuffer glMapNamedBufferEXT(int bufferName, int access) {
+public final java.nio.ByteBuffer glMapNamedBufferEXT(int bufferName, int access) {
final long __addr_ = ((GL4bcProcAddressTable)_context.getGLProcAddressTable())._addressof_glMapNamedBufferEXT;
if (__addr_ == 0) {
throw new GLException("Method \"glMapNamedBufferEXT\" not available");
@@ -269,7 +271,8 @@ private native long dispatch_glMapNamedBufferEXT(int buffer, int access, long pr
native private ByteBuffer newDirectByteBuffer(long addr, long capacity);
- public void glVertexPointer(GLArrayData array) {
+ @Override
+ public final void glVertexPointer(GLArrayData array) {
if(array.getComponentCount()==0) return;
if(array.isVBO()) {
glVertexPointer(array.getComponentCount(), array.getComponentType(), array.getStride(), array.getVBOOffset());
@@ -277,7 +280,8 @@ native private ByteBuffer newDirectByteBuffer(long addr, long capacity);
glVertexPointer(array.getComponentCount(), array.getComponentType(), array.getStride(), array.getBuffer());
}
}
- public void glColorPointer(GLArrayData array) {
+ @Override
+ public final void glColorPointer(GLArrayData array) {
if(array.getComponentCount()==0) return;
if(array.isVBO()) {
glColorPointer(array.getComponentCount(), array.getComponentType(), array.getStride(), array.getVBOOffset());
@@ -286,7 +290,8 @@ native private ByteBuffer newDirectByteBuffer(long addr, long capacity);
}
}
- public void glNormalPointer(GLArrayData array) {
+ @Override
+ public final void glNormalPointer(GLArrayData array) {
if(array.getComponentCount()==0) return;
if(array.getComponentCount()!=3) {
throw new GLException("Only 3 components per normal allowed");
@@ -297,7 +302,8 @@ native private ByteBuffer newDirectByteBuffer(long addr, long capacity);
glNormalPointer(array.getComponentType(), array.getStride(), array.getBuffer());
}
}
- public void glTexCoordPointer(GLArrayData array) {
+ @Override
+ public final void glTexCoordPointer(GLArrayData array) {
if(array.getComponentCount()==0) return;
if(array.isVBO()) {
glTexCoordPointer(array.getComponentCount(), array.getComponentType(), array.getStride(), array.getVBOOffset());
diff --git a/make/config/jogl/gl-impl-CustomJavaCode-gles1.java b/make/config/jogl/gl-impl-CustomJavaCode-gles1.java
index dff33cf81..68eadc683 100644
--- a/make/config/jogl/gl-impl-CustomJavaCode-gles1.java
+++ b/make/config/jogl/gl-impl-CustomJavaCode-gles1.java
@@ -12,98 +12,122 @@ public GLES1Impl(GLProfile glp, GLContextImpl context) {
this.glProfile = glp;
}
+@Override
public final boolean isGL4bc() {
return false;
}
+@Override
public final boolean isGL4() {
return false;
}
+@Override
public final boolean isGL3bc() {
return false;
}
+@Override
public final boolean isGL3() {
return false;
}
+@Override
public final boolean isGL2() {
return false;
}
+@Override
public final boolean isGLES1() {
return true;
}
+@Override
public final boolean isGLES2() {
return false;
}
+@Override
public final boolean isGLES() {
return true;
}
+@Override
public final boolean isGL2ES1() {
return true;
}
+@Override
public final boolean isGL2ES2() {
return false;
}
+@Override
public final boolean isGLES2Compatible() {
return false;
}
+@Override
public final boolean isGL2GL3() {
return false;
}
+@Override
public final boolean hasGLSL() {
return false;
}
+@Override
public boolean isNPOTTextureAvailable() {
return false;
}
+@Override
public final GL4bc getGL4bc() throws GLException {
throw new GLException("Not a GL4bc implementation");
}
+@Override
public final GL4 getGL4() throws GLException {
throw new GLException("Not a GL4 implementation");
}
+@Override
public final GL3bc getGL3bc() throws GLException {
throw new GLException("Not a GL3bc implementation");
}
+@Override
public final GL3 getGL3() throws GLException {
throw new GLException("Not a GL3 implementation");
}
+@Override
public final GL2 getGL2() throws GLException {
throw new GLException("Not a GL2 implementation");
}
+@Override
public final GLES1 getGLES1() throws GLException {
return this;
}
+@Override
public final GLES2 getGLES2() throws GLException {
throw new GLException("Not a GLES2 implementation");
}
+@Override
public final GL2ES1 getGL2ES1() throws GLException {
return this;
}
+@Override
public final GL2ES2 getGL2ES2() throws GLException {
throw new GLException("Not a GL2ES2 implementation");
}
+@Override
public final GL2GL3 getGL2GL3() throws GLException {
throw new GLException("Not a GL2GL3 implementation");
}
@@ -119,17 +143,17 @@ private final GLStateTracker glStateTracker;
private boolean bufferObjectExtensionsInitialized = false;
private boolean haveOESFramebufferObject;
-private void initBufferObjectExtensionChecks() {
+private final void initBufferObjectExtensionChecks() {
if (bufferObjectExtensionsInitialized)
return;
bufferObjectExtensionsInitialized = true;
haveOESFramebufferObject = isExtensionAvailable("GL_OES_framebuffer_object");
}
-private boolean checkBufferObject(boolean avail,
- boolean enabled,
- int state,
- String kind, boolean throwException) {
+private final boolean checkBufferObject(boolean avail,
+ boolean enabled,
+ int state,
+ String kind, boolean throwException) {
if (!avail) {
if (!enabled)
return true;
@@ -157,7 +181,7 @@ private boolean checkBufferObject(boolean avail,
return true;
}
-private boolean checkArrayVBODisabled(boolean throwException) {
+private final boolean checkArrayVBODisabled(boolean throwException) {
initBufferObjectExtensionChecks();
return checkBufferObject(true,
false,
@@ -165,7 +189,7 @@ private boolean checkArrayVBODisabled(boolean throwException) {
"array vertex_buffer_object", throwException);
}
-private boolean checkArrayVBOEnabled(boolean throwException) {
+private final boolean checkArrayVBOEnabled(boolean throwException) {
initBufferObjectExtensionChecks();
return checkBufferObject(true,
true,
@@ -173,7 +197,7 @@ private boolean checkArrayVBOEnabled(boolean throwException) {
"array vertex_buffer_object", throwException);
}
-private boolean checkElementVBODisabled(boolean throwException) {
+private final boolean checkElementVBODisabled(boolean throwException) {
initBufferObjectExtensionChecks();
return checkBufferObject(true,
false,
@@ -181,7 +205,7 @@ private boolean checkElementVBODisabled(boolean throwException) {
"element vertex_buffer_object", throwException);
}
-private boolean checkElementVBOEnabled(boolean throwException) {
+private final boolean checkElementVBOEnabled(boolean throwException) {
initBufferObjectExtensionChecks();
return checkBufferObject(true,
true,
@@ -189,30 +213,30 @@ private boolean checkElementVBOEnabled(boolean throwException) {
"element vertex_buffer_object", throwException);
}
-private boolean checkUnpackPBODisabled(boolean throwException) {
+private final boolean checkUnpackPBODisabled(boolean throwException) {
// PBO n/a for ES 1.1 or ES 2.0
return true;
}
-private boolean checkUnpackPBOEnabled(boolean throwException) {
+private final boolean checkUnpackPBOEnabled(boolean throwException) {
// PBO n/a for ES 1.1 or ES 2.0
return false;
}
-private boolean checkPackPBODisabled(boolean throwException) {
+private final boolean checkPackPBODisabled(boolean throwException) {
// PBO n/a for ES 1.1 or ES 2.0
return true;
}
-private boolean checkPackPBOEnabled(boolean throwException) {
+private final boolean checkPackPBOEnabled(boolean throwException) {
// PBO n/a for ES 1.1 or ES 2.0
return false;
}
-private HashMap
LPVOID glMapBuffer(GLenum target, GLenum access);
*/
-public java.nio.ByteBuffer glMapBuffer(int target, int access) {
+public final java.nio.ByteBuffer glMapBuffer(int target, int access) {
final long __addr_ = ((GLES1ProcAddressTable)_context.getGLProcAddressTable())._addressof_glMapBuffer;
if (__addr_ == 0) {
throw new GLException("Method \"glMapBuffer\" not available");
@@ -252,7 +276,8 @@ native private long dispatch_glMapBuffer(int target, int access, long glProcAddr
native private ByteBuffer newDirectByteBuffer(long addr, long capacity);
-public void glVertexPointer(GLArrayData array) {
+@Override
+public final void glVertexPointer(GLArrayData array) {
if(array.getComponentCount()==0) return;
if(array.isVBO()) {
glVertexPointer(array.getComponentCount(), array.getComponentType(), array.getStride(), array.getVBOOffset());
@@ -260,7 +285,8 @@ public void glVertexPointer(GLArrayData array) {
glVertexPointer(array.getComponentCount(), array.getComponentType(), array.getStride(), array.getBuffer());
}
}
-public void glColorPointer(GLArrayData array) {
+@Override
+public final void glColorPointer(GLArrayData array) {
if(array.getComponentCount()==0) return;
if(array.isVBO()) {
glColorPointer(array.getComponentCount(), array.getComponentType(), array.getStride(), array.getVBOOffset());
@@ -269,7 +295,8 @@ public void glColorPointer(GLArrayData array) {
}
}
-public void glNormalPointer(GLArrayData array) {
+@Override
+public final void glNormalPointer(GLArrayData array) {
if(array.getComponentCount()==0) return;
if(array.getComponentCount()!=3) {
throw new GLException("Only 3 components per normal allowed");
@@ -280,7 +307,8 @@ public void glNormalPointer(GLArrayData array) {
glNormalPointer(array.getComponentType(), array.getStride(), array.getBuffer());
}
}
-public void glTexCoordPointer(GLArrayData array) {
+@Override
+public final void glTexCoordPointer(GLArrayData array) {
if(array.getComponentCount()==0) return;
if(array.isVBO()) {
glTexCoordPointer(array.getComponentCount(), array.getComponentType(), array.getStride(), array.getVBOOffset());
diff --git a/make/config/jogl/gl-impl-CustomJavaCode-gles2.java b/make/config/jogl/gl-impl-CustomJavaCode-gles2.java
index a4976f5ea..760287364 100644
--- a/make/config/jogl/gl-impl-CustomJavaCode-gles2.java
+++ b/make/config/jogl/gl-impl-CustomJavaCode-gles2.java
@@ -1,6 +1,3 @@
-// Tracks glBegin/glEnd calls to determine whether it is legal to
-// query Vertex Buffer Object state
-private boolean inBeginEndPair;
public GLES2Impl(GLProfile glp, GLContextImpl context) {
this._context = context;
@@ -16,18 +13,22 @@ public GLES2Impl(GLProfile glp, GLContextImpl context) {
this.glProfile = glp;
}
+@Override
public final boolean isGL4bc() {
return false;
}
+@Override
public final boolean isGL4() {
return false;
}
+@Override
public final boolean isGL3bc() {
return false;
}
+@Override
public final boolean isGL3() {
return false;
}
@@ -36,78 +37,97 @@ public final boolean isGL2() {
return false;
}
+@Override
public final boolean isGLES1() {
return false;
}
+@Override
public final boolean isGLES2() {
return true;
}
+@Override
public final boolean isGLES() {
return true;
}
+@Override
public final boolean isGL2ES1() {
return false;
}
+@Override
public final boolean isGL2ES2() {
return true;
}
+@Override
public final boolean isGLES2Compatible() {
return true;
}
+@Override
public final boolean isGL2GL3() {
return false;
}
+@Override
public final boolean hasGLSL() {
return true;
}
+@Override
public boolean isNPOTTextureAvailable() {
return true;
}
+@Override
public final GL4bc getGL4bc() throws GLException {
throw new GLException("Not a GL4bc implementation");
}
+@Override
public final GL4 getGL4() throws GLException {
throw new GLException("Not a GL4 implementation");
}
+@Override
public final GL3bc getGL3bc() throws GLException {
throw new GLException("Not a GL3bc implementation");
}
+@Override
public final GL3 getGL3() throws GLException {
throw new GLException("Not a GL3 implementation");
}
+@Override
public final GL2 getGL2() throws GLException {
throw new GLException("Not a GL2 implementation");
}
+@Override
public final GLES1 getGLES1() throws GLException {
throw new GLException("Not a GLES1 implementation");
}
+@Override
public final GLES2 getGLES2() throws GLException {
return this;
}
+@Override
public final GL2ES1 getGL2ES1() throws GLException {
throw new GLException("Not a GL2ES1 implementation");
}
+@Override
public final GL2ES2 getGL2ES2() throws GLException {
return this;
}
+@Override
public final GL2GL3 getGL2GL3() throws GLException {
throw new GLException("Not a GL2GL3 implementation");
}
@@ -123,17 +143,17 @@ private final GLStateTracker glStateTracker;
private boolean bufferObjectExtensionsInitialized = false;
private boolean haveOESFramebufferObject;
-private void initBufferObjectExtensionChecks() {
+private final void initBufferObjectExtensionChecks() {
if (bufferObjectExtensionsInitialized)
return;
bufferObjectExtensionsInitialized = true;
haveOESFramebufferObject = isExtensionAvailable("GL_OES_framebuffer_object");
}
-private boolean checkBufferObject(boolean avail,
- boolean enabled,
- int state,
- String kind, boolean throwException) {
+private final boolean checkBufferObject(boolean avail,
+ boolean enabled,
+ int state,
+ String kind, boolean throwException) {
if (!avail) {
if (!enabled)
return true;
@@ -161,7 +181,7 @@ private boolean checkBufferObject(boolean avail,
return true;
}
-private boolean checkArrayVBODisabled(boolean throwException) {
+private final boolean checkArrayVBODisabled(boolean throwException) {
initBufferObjectExtensionChecks();
return checkBufferObject(true,
false,
@@ -169,7 +189,7 @@ private boolean checkArrayVBODisabled(boolean throwException) {
"array vertex_buffer_object", throwException);
}
-private boolean checkArrayVBOEnabled(boolean throwException) {
+private final boolean checkArrayVBOEnabled(boolean throwException) {
initBufferObjectExtensionChecks();
return checkBufferObject(true,
true,
@@ -177,7 +197,7 @@ private boolean checkArrayVBOEnabled(boolean throwException) {
"array vertex_buffer_object", throwException);
}
-private boolean checkElementVBODisabled(boolean throwException) {
+private final boolean checkElementVBODisabled(boolean throwException) {
initBufferObjectExtensionChecks();
return checkBufferObject(true,
false,
@@ -185,7 +205,7 @@ private boolean checkElementVBODisabled(boolean throwException) {
"element vertex_buffer_object", throwException);
}
-private boolean checkElementVBOEnabled(boolean throwException) {
+private final boolean checkElementVBOEnabled(boolean throwException) {
initBufferObjectExtensionChecks();
return checkBufferObject(true,
true,
@@ -193,30 +213,31 @@ private boolean checkElementVBOEnabled(boolean throwException) {
"element vertex_buffer_object", throwException);
}
-private boolean checkUnpackPBODisabled(boolean throwException) {
+private final boolean checkUnpackPBODisabled(boolean throwException) {
// PBO n/a for ES 1.1 or ES 2.0
return true;
}
-private boolean checkUnpackPBOEnabled(boolean throwException) {
+private final boolean checkUnpackPBOEnabled(boolean throwException) {
// PBO n/a for ES 1.1 or ES 2.0
return false;
}
-private boolean checkPackPBODisabled(boolean throwException) {
+private final boolean checkPackPBODisabled(boolean throwException) {
// PBO n/a for ES 1.1 or ES 2.0
return true;
}
-private boolean checkPackPBOEnabled(boolean throwException) {
+private final boolean checkPackPBOEnabled(boolean throwException) {
// PBO n/a for ES 1.1 or ES 2.0
return false;
}
-private HashMap
LPVOID glMapBuffer(GLenum target, GLenum access);
*/
-public java.nio.ByteBuffer glMapBuffer(int target, int access) {
+@Override
+public final java.nio.ByteBuffer glMapBuffer(int target, int access) {
final long __addr_ = ((GLES2ProcAddressTable)_context.getGLProcAddressTable())._addressof_glMapBuffer;
if (__addr_ == 0) {
throw new GLException("Method \"glMapBuffer\" not available");
@@ -256,11 +277,13 @@ native private long dispatch_glMapBuffer(int target, int access, long glProcAddr
native private ByteBuffer newDirectByteBuffer(long addr, long capacity);
-public void glClearDepth(double depth) {
+@Override
+public final void glClearDepth(double depth) {
glClearDepthf((float)depth);
}
-public void glDepthRange(double zNear, double zFar) {
+@Override
+public final void glDepthRange(double zNear, double zFar) {
glDepthRangef((float)zNear, (float)zFar);
}
diff --git a/make/scripts/java-win32-dbg.bat b/make/scripts/java-win32-dbg.bat
index d1797bdbb..6f8206721 100755
--- a/make/scripts/java-win32-dbg.bat
+++ b/make/scripts/java-win32-dbg.bat
@@ -9,9 +9,9 @@ set BLD_DIR=..\%BLD_SUB%
set FFMPEG_LIB=%PROJECT_ROOT%\make\lib\ffmpeg\x32
-set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;%FFMPEG_LIB%;%PATH%
-REM set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;%PROJECT_ROOT%\make\lib\angle\win32;%PATH%
-REM set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;%PROJECT_ROOT%\make\lib\PVRVFrame\OGLES-2.0\Windows_x86_32;%PATH%
+REM set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;%FFMPEG_LIB%;%PATH%
+REM set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;%PROJECT_ROOT%\make\lib\external\angle\win32;%PATH%
+set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;%PROJECT_ROOT%\make\lib\external\PVRVFrame\OGLES-2.0\Windows_x86_32;%PATH%
REM set LIB_DIR=%BLD_DIR%\lib;..\..\gluegen\%BLD_SUB%\obj
set LIB_DIR=%FFMPEG_LIB%
@@ -20,11 +20,14 @@ set CP_ALL=.;%BLD_DIR%\jar\jogl-all.jar;%BLD_DIR%\jar\jogl-test.jar;..\..\gluege
echo CP_ALL %CP_ALL%
-set D_ARGS="-Djogamp.debug.IOUtil" "-Djogl.debug.GLSLCode" "-Djogl.debug.GLMediaPlayer"
+set D_ARGS="-Djogl.debug.GLContext" "-Djogl.debug.FBObject"
+REM set D_ARGS="-Djogl.debug.GLDrawable" "-Djogl.debug.EGLDrawableFactory.DontQuery"
+REM set D_ARGS="-Djogl.debug.GLDrawable" "-Djogl.debug.EGLDrawableFactory.QueryNativeTK"
+REM set D_ARGS="-Djogl.debug=all" "-Dnewt.debug=all" "-Dnativewindow.debug=all"
+REM set D_ARGS="-Djogamp.debug.IOUtil" "-Djogl.debug.GLSLCode" "-Djogl.debug.GLMediaPlayer"
REM set D_ARGS="-Djogl.debug.ExtensionAvailabilityCache" "-Djogl.debug=all" "-Dnewt.debug=all" "-Dnativewindow.debug=all" "-Djogamp.debug.ProcAddressHelper=true" "-Djogamp.debug.NativeLibrary=true" "-Djogamp.debug.NativeLibrary.Lookup=true"
REM set D_ARGS="-Djogl.debug=all" "-Dnewt.debug=all" "-Dnativewindow.debug=all" "-Djogamp.debug.NativeLibrary=true"
REM set D_ARGS="-Djogamp.debug.JNILibLoader=true" "-Djogamp.debug.NativeLibrary=true" "-Djogamp.debug.NativeLibrary.Lookup=true" "-Djogl.debug.GLProfile=true"
-REM set D_ARGS="-Djogl.debug=all" "-Dnewt.debug=all" "-Dnativewindow.debug=all"
REM set D_ARGS="-Dnewt.debug.Window" "-Dnativewindow.debug.TraceLock"
REM set D_ARGS="-Dnativewindow.debug.TraceLock"
REM set D_ARGS="-Dnewt.debug.Window" "-Dnewt.debug.Display"
diff --git a/make/scripts/java-win32.bat b/make/scripts/java-win32.bat
index 9d59c045e..1d8430280 100755
--- a/make/scripts/java-win32.bat
+++ b/make/scripts/java-win32.bat
@@ -8,8 +8,8 @@ set PROJECT_ROOT=D:\projects\jogamp\jogl
set BLD_DIR=..\%BLD_SUB%
REM set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;c:\mingw\bin;%PATH%
-set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;%PROJECT_ROOT%\make\lib\angle\win32;%PATH%
-REM set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;%PROJECT_ROOT%\make\lib\PVRVFrame\OGLES-2.0\Windows_x86_32;%PATH%
+REM set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;%PROJECT_ROOT%\make\lib\angle\win32;%PATH%
+set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;%PROJECT_ROOT%\make\lib\PVRVFrame\OGLES-2.0\Windows_x86_32;%PATH%
set BLD_DIR=..\%BLD_SUB%
REM set LIB_DIR=..\..\gluegen\%BLD_SUB%\obj;%BLD_DIR%\lib
diff --git a/make/scripts/java-win64-dbg.bat b/make/scripts/java-win64-dbg.bat
index d6b0435ea..109755d2e 100755
--- a/make/scripts/java-win64-dbg.bat
+++ b/make/scripts/java-win64-dbg.bat
@@ -9,7 +9,8 @@ set BLD_DIR=..\%BLD_SUB%
set FFMPEG_LIB=%PROJECT_ROOT%\make\lib\ffmpeg\x64
-set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;%FFMPEG_LIB%;%PATH%
+set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;c:\mingw\bin;%PATH%
+REM set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;%PROJECT_ROOT%\make\lib\external\PVRVFrame\OGLES-2.0\Windows_x86_64;%PATH%
REM set LIB_DIR=%BLD_DIR%\lib;..\..\gluegen\%BLD_SUB%\obj
set LIB_DIR=%FFMPEG_LIB%
@@ -17,7 +18,13 @@ set CP_ALL=.;%BLD_DIR%\jar\jogl-all.jar;%BLD_DIR%\jar\jogl-test.jar;..\..\gluege
echo CP_ALL %CP_ALL%
-set D_ARGS="-Djogamp.debug.IOUtil" "-Djogl.debug.GLSLCode" "-Djogl.debug.GLMediaPlayer"
+set D_ARGS="-Djogl.debug.GLContext" "-Djogl.debug.FBObject"
+REM set D_ARGS="-Djogl.debug.GLDrawable" "-Djogl.debug.EGLDrawableFactory.DontQuery"
+REM set D_ARGS="-Djogl.debug.GLDrawable" "-Djogl.debug.EGLDrawableFactory.QueryNativeTK"
+REM set D_ARGS="-Djogl.debug=all" "-Dnewt.debug=all" "-Dnativewindow.debug=all"
+REM set D_ARGS="-Djogl.debug=all" "-Dnewt.debug=all" "-Dnativewindow.debug=all" "-Djogamp.debug=all" "-Djogl.debug.EGLDrawableFactory.DontQuery"
+REM set D_ARGS="-Dnativewindow.debug.GraphicsConfiguration -Djogl.debug.CapabilitiesChooser -Djogl.debug.GLProfile"
+REM set D_ARGS="-Djogamp.debug.IOUtil" "-Djogl.debug.GLSLCode" "-Djogl.debug.GLMediaPlayer"
REM set D_ARGS="-Djogamp.debug.NativeLibrary=true" "-Djogamp.debug.NativeLibrary.Lookup=true" "-Djogl.debug.GLSLCode"
REM set D_ARGS="-Djogl.debug.ExtensionAvailabilityCache" "-Djogl.debug=all" "-Dnewt.debug=all" "-Dnativewindow.debug=all" "-Djogamp.debug.ProcAddressHelper=true" "-Djogamp.debug.NativeLibrary=true" "-Djogamp.debug.NativeLibrary.Lookup=true"
REM set D_ARGS="-Djogl.debug=all" "-Dnewt.debug=all" "-Dnativewindow.debug=all" "-Djogamp.debug.NativeLibrary=true"
@@ -33,7 +40,6 @@ REM set D_ARGS="-Djogl.debug.GLCanvas" "-Djogl.debug.Animator" "-Djogl.debug.GLC
REM set D_ARGS="-Dnewt.debug.Window"
REM set D_ARGS="-Djogl.debug.GLDebugMessageHandler" "-Djogl.debug.DebugGL" "-Djogl.debug.TraceGL"
REM set D_ARGS="-Djogl.debug.DebugGL" "-Djogl.debug.GLDebugMessageHandler" "-Djogl.debug.GLSLCode"
-REM set D_ARGS="-Djogl.debug.GraphicsConfiguration" "-Djogl.debug.CapabilitiesChooser"
REM set D_ARGS="-Djogl.debug.GLContext" "-Dnewt.debug=all"
REM set D_ARGS="-Dnewt.debug.Window" "-Dnativewindow.debug.TraceLock"
REM set D_ARGS="-Dnativewindow.debug.TraceLock"
diff --git a/make/scripts/java-win64.bat b/make/scripts/java-win64.bat
index b8f438aab..2c09feedc 100755
--- a/make/scripts/java-win64.bat
+++ b/make/scripts/java-win64.bat
@@ -4,7 +4,8 @@ set J2RE_HOME=c:\jre1.6.0_30_x64
set JAVA_HOME=c:\jdk1.6.0_30_x64
set ANT_PATH=C:\apache-ant-1.8.2
-set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;c:\mingw\bin;%PATH%
+REM set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;c:\mingw\bin;%PATH%
+set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;%PROJECT_ROOT%\make\lib\external\PVRVFrame\OGLES-2.0\Windows_x86_64;%PATH%
set BLD_DIR=..\%BLD_SUB%
REM set LIB_DIR=%BLD_DIR%\lib;..\..\gluegen\%BLD_SUB%\obj
diff --git a/make/scripts/tests-x32.bat b/make/scripts/tests-x32.bat
index c29dcef39..7947759a4 100755
--- a/make/scripts/tests-x32.bat
+++ b/make/scripts/tests-x32.bat
@@ -51,7 +51,7 @@ REM scripts\java-win32-dbg.bat com.jogamp.opengl.test.junit.newt.TestScreenMode0
REM scripts\java-win32.bat com.jogamp.opengl.test.junit.newt.ManualScreenMode03NEWT
REM scripts\java-win32-dbg.bat com.jogamp.opengl.test.junit.jogl.demos.es2.av.MovieSimple %*
-scripts\java-win32-dbg.bat com.jogamp.opengl.test.junit.jogl.demos.es2.av.MovieCube %*
+REM scripts\java-win32-dbg.bat com.jogamp.opengl.test.junit.jogl.demos.es2.av.MovieCube %*
REM scripts\java-win32-dbg.bat com.jogamp.opengl.test.junit.jogl.demos.es2.TexCubeES2 %*
REM scripts\java-win32-dbg.bat com.jogamp.opengl.test.junit.newt.TestDisplayLifecycle01NEWT
@@ -94,6 +94,7 @@ REM scripts\java-win32-dbg.bat com.jogamp.opengl.test.junit.jogl.acore.TestGPUMe
REM scripts\java-win32.bat com.jogamp.opengl.test.junit.jogl.acore.TestMapBuffer01NEWT
REM scripts\java-win32.bat com.jogamp.opengl.test.junit.jogl.glsl.TestRulerNEWT01
+scripts\java-win32-dbg.bat com.jogamp.opengl.test.junit.jogl.acore.TestFBODrawableNEWT %*
REM scripts\java-win32.bat com.jogamp.opengl.test.junit.jogl.glsl.TestFBOMRTNEWT01
REM scripts\java-win32-dbg.bat com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestElektronenMultipliziererNEWT %*
diff --git a/make/scripts/tests-x64.bat b/make/scripts/tests-x64.bat
index 32729d235..0b3711784 100755
--- a/make/scripts/tests-x64.bat
+++ b/make/scripts/tests-x64.bat
@@ -72,7 +72,7 @@ REM scripts\java-win64.bat com.jogamp.opengl.test.junit.newt.TestWindowClosingPr
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.swt.TestSWT01GLn %*
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.swt.TestSWT02GLn %*
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.swt.TestSWTAWT01GLn %*
-scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.swt.TestSWTJOGLGLCanvas01GLn %*
+REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.swt.TestSWTJOGLGLCanvas01GLn %*
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.offscreen.TestOffscreen02BitmapNEWT -time 5000
@@ -96,7 +96,8 @@ REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.acore.TestGPUMe
REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.acore.TestMapBuffer01NEWT
REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.glsl.TestRulerNEWT01
-REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.glsl.TestFBOMRTNEWT01
+scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.acore.TestFBODrawableNEWT %*
+REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.glsl.TestFBOMRTNEWT01 %*
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestElektronenMultipliziererNEWT %*
diff --git a/make/scripts/tests.sh b/make/scripts/tests.sh
index 0258187fd..591f5f9d2 100755
--- a/make/scripts/tests.sh
+++ b/make/scripts/tests.sh
@@ -53,10 +53,17 @@ function jrun() {
swton=$1
shift
+ #D_ARGS="-Djogl.debug.FBObject -Djogl.debug.DebugGL"
+ #D_ARGS="-Djogl.debug.FBObject"
+ #D_ARGS="-Dnativewindow.debug.GraphicsConfiguration -Djogl.debug.GLDrawable -Djogl.debug.GLContext -Djogl.debug.FBObject"
#D_ARGS="-Djogl.debug.GLContext.NoProfileAliasing"
#D_ARGS="-Djogamp.debug=all -Dnativewindow.debug=all -Djogl.debug=all -Dnewt.debug=all"
#D_ARGS="-Djogl.debug=all -Dnativewindow.debug=all -Dnewt.debug=all"
+ #D_ARGS="-Djogl.debug=all -Dnativewindow.debug=all -Dnewt.debug=all -Djogamp.debug.Lock"
#D_ARGS="-Djogl.debug=all -Dnativewindow.debug=all"
+ #D_ARGS="-Djogl.debug.EGLDrawableFactory.DontQuery -Djogl.debug.GLDrawable"
+ #D_ARGS="-Djogl.debug.EGLDrawableFactory.QueryNativeTK -Djogl.debug.GLDrawable"
+ #D_ARGS="-Djogl.debug.GLDrawable"
#D_ARGS="-Djogl.debug=all -Dnewt.debug=all"
#D_ARGS="-Djogl.debug.DebugGL -Djogl.debug.TraceGL"
#D_ARGS="-Djogl.debug.GLDebugMessageHandler"
@@ -71,6 +78,7 @@ function jrun() {
#D_ARGS="-Djogamp.debug.IOUtil -Djogl.debug.GLSLCode -Djogl.debug.GLMediaPlayer"
#D_ARGS="-Djogl.debug.GLArrayData"
#D_ARGS="-Djogl.debug.EGL -Dnativewindow.debug.GraphicsConfiguration -Djogl.debug.GLDrawable"
+ #D_ARGS="-Djogl.debug.GLDrawable"
#D_ARGS="-Dnewt.test.Screen.disableScreenMode -Dnewt.debug.Screen"
#D_ARGS="-Djogl.debug.ExtensionAvailabilityCache -Djogl.debug=all -Dnativewindow.debug=all -Djogamp.debug.ProcAddressHelper=true -Djogamp.debug.NativeLibrary=true -Djogamp.debug.NativeLibrary.Lookup=true"
#D_ARGS="-Dnewt.debug.MainThread"
@@ -85,7 +93,7 @@ function jrun() {
#D_ARGS="-Dnativewindow.debug.NativeWindow"
#D_ARGS="-Dnewt.debug.Window -Dnewt.debug.Display -Dnewt.debug.EDT"
#D_ARGS="-Dnewt.debug.EDT -Dnewt.debug.Window -Djogl.debug.GLContext"
- #D_ARGS="-Dnativewindow.debug.ToolkitLock.TraceLock -Dnativewindow.debug.X11Util.XErrorStackDump -Dnativewindow.debug.X11Util.TraceDisplayLifecycle -Dnativewindow.debug.X11Util"
+ #D_ARGS="-Dnativewindow.debug.X11Util.XErrorStackDump -Dnativewindow.debug.X11Util.TraceDisplayLifecycle -Dnativewindow.debug.X11Util"
#D_ARGS="-Dnativewindow.debug.X11Util -Djogl.debug.GLContext -Djogl.debug.GLDrawable -Dnewt.debug=all"
#D_ARGS="-Dnativewindow.debug.X11Util -Dnativewindow.debug.X11Util.XSync"
#D_ARGS="-Dnativewindow.debug.X11Util.XSync -Dnewt.debug.Window"
@@ -100,9 +108,9 @@ function jrun() {
#D_ARGS="-Djogl.debug.Animator -Dnewt.debug=all"
#D_ARGS="-Dnewt.debug.EDT -Dnewt.debug.Display -Dnativewindow.debug.X11Util -Djogl.debug.GLDrawable -Djogl.debug.GLCanvas"
#D_ARGS="-Djogl.debug.GLContext"
- #D_ARGS="-Djogl.debug.GraphicsConfiguration -Djogl.debug.CapabilitiesChooser"
+ #D_ARGS="-Dnativewindow.debug.GraphicsConfiguration -Djogl.debug.CapabilitiesChooser"
#D_ARGS="-Dnewt.debug.Screen -Dnewt.debug.EDT -Djogamp.debug.Lock"
- #D_ARGS="-Djogl.debug.GLContext -Djogl.debug.GraphicsConfiguration"
+ #D_ARGS="-Djogl.debug.GLContext -Dnativewindow.debug.GraphicsConfiguration"
#D_ARGS="-Dnewt.debug.EDT"
#D_ARGS="-Dnewt.debug.Window -Dnewt.debug.Display -Dnewt.debug.EDT -Djogl.debug.GLContext"
#D_ARGS="-Dnewt.debug.Window -Djogl.debug.Animator -Dnewt.debug.Screen"
@@ -115,8 +123,6 @@ function jrun() {
#D_ARGS="-Xprof"
#D_ARGS="-Djogl.debug.Animator"
#D_ARGS="-Dnativewindow.debug=all"
- #D_ARGS="-Djogl.debug.GraphicsConfiguration"
- #D_ARGS="-Djogl.debug.GLCanvas -Djogl.debug.GraphicsConfiguration"
#D_ARGS="-Djogl.debug.GLCanvas"
#D_ARGS="-Dnativewindow.debug.ToolkitLock.TraceLock"
#D_ARGS="-Djogl.debug.graph.curve -Djogl.debug.GLSLCode -Djogl.debug.TraceGL"
@@ -162,20 +168,20 @@ function jrun() {
C_ARG="com.jogamp.newt.util.MainThread"
fi
fi
+ #export LD_LIBRARY_PATH=$spath/../lib/external/PVRVFrame/OGLES-2.0/Linux_x86_64:$LD_LIBRARY_PATH
+ #export LD_LIBRARY_PATH=$spath/../lib/external/PVRVFrame/OGLES-2.0/Linux_x86_32:$LD_LIBRARY_PATH
+ #export LD_LIBRARY_PATH=/usr/local/projects/Xorg.modular/build-x86_64/lib:$LD_LIBRARY_PATH
+ #export LD_LIBRARY_PATH=/opt-linux-x86_64/x11lib-1.3:$LD_LIBRARY_PATH
+ #export LD_LIBRARY_PATH=/opt-linux-x86_64/mesa-7.8.1/lib64:$LD_LIBRARY_PATH
+ #export LD_LIBRARY_PATH=/usr/lib/mesa:/usr/lib32/mesa:$LD_LIBRARY_PATH
+ #export LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu/mesa:/usr/lib/i386-linux-gnu/mesa:$LD_LIBRARY_PATH
echo
echo "Test Start: $*"
echo
echo LD_LIBRARY_PATH $LD_LIBRARY_PATH
echo
echo $javaexe $javaxargs $X_ARGS $D_ARGS $C_ARG $*
- #LD_LIBRARY_PATH=/usr/local/projects/Xorg.modular/build-x86_64/lib:$LD_LIBRARY_PATH \
- #LD_LIBRARY_PATH=/opt-linux-x86_64/x11lib-1.3:$LD_LIBRARY_PATH \
- #LD_LIBRARY_PATH=/opt-linux-x86_64/mesa-7.8.1/lib64:$LD_LIBRARY_PATH \
#LIBGL_DRIVERS_PATH=/usr/lib/mesa:/usr/lib32/mesa \
- #LD_LIBRARY_PATH=/usr/lib/mesa:/usr/lib32/mesa:$LD_LIBRARY_PATH \
- #LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu/mesa:/usr/lib/i386-linux-gnu/mesa:$LD_LIBRARY_PATH \
- #LD_LIBRARY_PATH=$spath/../lib/PVRVFrame/OGLES-2.0/Linux_x86_64:$LD_LIBRARY_PATH \
- #LD_LIBRARY_PATH=$spath/../lib/PVRVFrame/OGLES-2.0/Linux_x86_32:$LD_LIBRARY_PATH \
#gdb --args $javaexe $javaxargs $X_ARGS $D_ARGS $C_ARG $*
$javaexe $javaxargs $X_ARGS $D_ARGS $C_ARG $*
echo
@@ -228,6 +234,7 @@ function testawtswt() {
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextVBOES2NEWT2 $*
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLAutoDrawableDelegateNEWT $*
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLContextDrawableSwitchNEWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestFBODrawableNEWT $*
#testnoawt com.jogamp.opengl.test.junit.newt.parenting.TestParenting01NEWT $*
#testnoawt com.jogamp.opengl.test.junit.newt.parenting.TestParenting02NEWT $*
@@ -292,7 +299,7 @@ function testawtswt() {
# swt (testswt)
#
#testswt com.jogamp.opengl.test.junit.jogl.swt.TestSWTEclipseGLCanvas01GLn $*
-testswt com.jogamp.opengl.test.junit.jogl.swt.TestSWTJOGLGLCanvas01GLn $*
+#testswt com.jogamp.opengl.test.junit.jogl.swt.TestSWTJOGLGLCanvas01GLn $*
#testawtswt com.jogamp.opengl.test.junit.jogl.swt.TestSWTJOGLGLCanvas01GLn $*
#testswt com.jogamp.opengl.test.junit.jogl.swt.TestSWTAccessor02GLn $*
@@ -322,7 +329,8 @@ testswt com.jogamp.opengl.test.junit.jogl.swt.TestSWTJOGLGLCanvas01GLn $*
#testawt com.jogamp.opengl.test.junit.newt.parenting.TestTranslucentParentingAWT $*
#testawt com.jogamp.opengl.test.junit.newt.TestCloseNewtAWT
#testawt com.jogamp.opengl.test.junit.jogl.caps.TestMultisampleES1AWT $*
-#testawt com.jogamp.opengl.test.junit.jogl.caps.TestMultisampleES1NEWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.caps.TestMultisampleES1NEWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.caps.TestMultisampleES2NEWT $*
#testawt com.jogamp.opengl.test.junit.jogl.caps.TestTranslucencyAWT $*
#testawt com.jogamp.opengl.test.junit.jogl.caps.TestTranslucencyNEWT $*
#testawt com.jogamp.opengl.test.junit.jogl.glsl.TestShaderCompilationBug459AWT
@@ -358,7 +366,9 @@ testswt com.jogamp.opengl.test.junit.jogl.swt.TestSWTJOGLGLCanvas01GLn $*
#testnoawt com.jogamp.opengl.test.junit.jogl.glsl.TestGLSLShaderState01NEWT $*
#testnoawt com.jogamp.opengl.test.junit.jogl.glsl.TestGLSLShaderState02NEWT $*
#testnoawt com.jogamp.opengl.test.junit.jogl.glsl.TestRulerNEWT01 $*
-#testnoawt com.jogamp.opengl.test.junit.jogl.glsl.TestFBOMRTNEWT01 $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestFBOMRTNEWT01 $*
+testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestFBOMix2DemosES2NEWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestFBODrawableNEWT $*
#
# Graph
@@ -394,6 +404,7 @@ testswt com.jogamp.opengl.test.junit.jogl.swt.TestSWTJOGLGLCanvas01GLn $*
#testawt com.jogamp.opengl.test.junit.newt.TestFocus02SwingAWTRobot $*
#linux:
+#testnoawt com.jogamp.opengl.test.junit.jogl.caps.TestMultisampleES2NEWT $* # linux NV: cannot make ctx current ..
# osx:
#testawt com.jogamp.opengl.test.junit.newt.parenting.TestParentingFocusTraversal01AWT $*
diff --git a/make/stub_includes/opengl/macosx-window-system.h b/make/stub_includes/opengl/macosx-window-system.h
index e7fe13553..47b51a509 100644
--- a/make/stub_includes/opengl/macosx-window-system.h
+++ b/make/stub_includes/opengl/macosx-window-system.h
@@ -31,7 +31,7 @@ NSView* getNSView(NSOpenGLContext* ctx);
NSOpenGLContext* createContext(NSOpenGLContext* shareContext,
NSView* nsView,
- Bool isBackingLayerView,
+ Bool allowIncompleteView,
NSOpenGLPixelFormat* pixelFormat,
Bool opaque,
int* viewNotReady);
diff --git a/src/jogl/classes/com/jogamp/gluegen/opengl/BuildStaticGLInfo.java b/src/jogl/classes/com/jogamp/gluegen/opengl/BuildStaticGLInfo.java
index 87a734e1f..482d35cae 100644
--- a/src/jogl/classes/com/jogamp/gluegen/opengl/BuildStaticGLInfo.java
+++ b/src/jogl/classes/com/jogamp/gluegen/opengl/BuildStaticGLInfo.java
@@ -293,9 +293,9 @@ public class BuildStaticGLInfo {
output.println(" public static String getFunctionAssociation(String glFunctionName)");
output.println(" {");
output.println(" String mappedName = null;");
- output.println(" int funcNamePermNum = com.jogamp.gluegen.runtime.opengl.GLExtensionNames.getFuncNamePermutationNumber(glFunctionName);");
+ output.println(" int funcNamePermNum = com.jogamp.gluegen.runtime.opengl.GLNameResolver.getFuncNamePermutationNumber(glFunctionName);");
output.println(" for(int i = 0; null==mappedName && i < funcNamePermNum; i++) {");
- output.println(" String tmp = com.jogamp.gluegen.runtime.opengl.GLExtensionNames.getFuncNamePermutation(glFunctionName, i);");
+ output.println(" String tmp = com.jogamp.gluegen.runtime.opengl.GLNameResolver.getFuncNamePermutation(glFunctionName, i);");
output.println(" try {");
output.println(" mappedName = (String)funcToAssocMap.get(tmp);");
output.println(" } catch (Exception e) { }");
diff --git a/src/jogl/classes/com/jogamp/gluegen/opengl/GLConfiguration.java b/src/jogl/classes/com/jogamp/gluegen/opengl/GLConfiguration.java
index c1a4facd2..ba025e18c 100755
--- a/src/jogl/classes/com/jogamp/gluegen/opengl/GLConfiguration.java
+++ b/src/jogl/classes/com/jogamp/gluegen/opengl/GLConfiguration.java
@@ -43,7 +43,7 @@ import com.jogamp.gluegen.GlueEmitterControls;
import com.jogamp.gluegen.GlueGen;
import com.jogamp.gluegen.MethodBinding;
import com.jogamp.gluegen.procaddress.ProcAddressConfiguration;
-import com.jogamp.gluegen.runtime.opengl.GLExtensionNames;
+import com.jogamp.gluegen.runtime.opengl.GLNameResolver;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
@@ -224,11 +224,11 @@ public class GLConfiguration extends ProcAddressConfiguration {
}
}
}
- boolean isGLEnum = GLExtensionNames.isGLEnumeration(symbol);
- boolean isGLFunc = GLExtensionNames.isGLFunction(symbol);
+ boolean isGLEnum = GLNameResolver.isGLEnumeration(symbol);
+ boolean isGLFunc = GLNameResolver.isGLFunction(symbol);
if (isGLFunc || isGLEnum) {
- if (GLExtensionNames.isExtensionVEN(symbol, isGLFunc)) {
- String extSuffix = GLExtensionNames.getExtensionSuffix(symbol, isGLFunc);
+ if (GLNameResolver.isExtensionVEN(symbol, isGLFunc)) {
+ String extSuffix = GLNameResolver.getExtensionSuffix(symbol, isGLFunc);
if (getDropUniqVendorExtensions(extSuffix)) {
if (DEBUG_IGNORES) {
System.err.println("Ignore UniqVendorEXT: " + symbol + ", vendor " + extSuffix);
diff --git a/src/jogl/classes/com/jogamp/gluegen/opengl/GLEmitter.java b/src/jogl/classes/com/jogamp/gluegen/opengl/GLEmitter.java
index f4658ad7b..809c6783d 100644
--- a/src/jogl/classes/com/jogamp/gluegen/opengl/GLEmitter.java
+++ b/src/jogl/classes/com/jogamp/gluegen/opengl/GLEmitter.java
@@ -51,7 +51,7 @@ import com.jogamp.gluegen.SymbolFilter;
import com.jogamp.gluegen.cgram.types.FunctionSymbol;
import com.jogamp.gluegen.procaddress.ProcAddressEmitter;
import com.jogamp.gluegen.procaddress.ProcAddressJavaMethodBindingEmitter;
-import com.jogamp.gluegen.runtime.opengl.GLExtensionNames;
+import com.jogamp.gluegen.runtime.opengl.GLNameResolver;
import java.io.IOException;
import java.io.PrintWriter;
@@ -110,13 +110,13 @@ public class GLEmitter extends ProcAddressEmitter {
if (declarations != null) {
for (Iterator
+ * Integrates default read/write framebuffers via {@link GLContext#getDefaultReadFramebuffer()} and {@link GLContext#getDefaultReadFramebuffer()},
+ * which is being hooked at {@link GL#glBindFramebuffer(int, int)} when the default (zero
) framebuffer is selected.
+ *
FIXME: Implement support for {@link Type#DEPTH_TEXTURE}, {@link Type#STENCIL_TEXTURE} .
+ */ +public class FBObject { + protected static final boolean DEBUG = Debug.debug("FBObject"); + + /** + * Returnstrue
if basic FBO support is available, otherwise false
.
+ *
+ * Basic FBO is supported if the context is either GL-ES >= 2.0, GL >= core 3.0 or implements the extensions
+ * ARB_ES2_compatibility
, ARB_framebuffer_object
, EXT_framebuffer_object
or OES_framebuffer_object
.
+ *
+ * Basic FBO support may only include one color attachment and no multisampling, + * as well as limited internal formats for renderbuffer. + *
+ * @see GLContext#hasFBO() + */ + public static final boolean supportsBasicFBO(GL gl) { + return gl.getContext().hasFBO(); + } + + /** + * Returnstrue
if full FBO support is available, otherwise false
.
+ *
+ * Full FBO is supported if the context is either GL >= core 3.0 or implements the extensions
+ * ARB_framebuffer_object
, or all of
+ * EXT_framebuffer_object
, EXT_framebuffer_multisample
,
+ * EXT_framebuffer_blit
, GL_EXT_packed_depth_stencil
.
+ *
+ * Full FBO support includes multiple color attachments and multisampling. + *
+ */ + public static final boolean supportsFullFBO(GL gl) { + return gl.isGL3() || // GL >= 3.0 + + gl.isExtensionAvailable(GLExtensions.ARB_framebuffer_object) || // ARB_framebuffer_object + + ( gl.isExtensionAvailable(GLExtensions.EXT_framebuffer_object) && // All EXT_framebuffer_object* + gl.isExtensionAvailable(GLExtensions.EXT_framebuffer_multisample) && + gl.isExtensionAvailable(GLExtensions.EXT_framebuffer_blit) && + gl.isExtensionAvailable(GLExtensions.EXT_packed_depth_stencil) ) ; + } + + public static final int getMaxSamples(GL gl) { + if( supportsFullFBO(gl) ) { + int[] val = new int[] { 0 } ; + gl.glGetIntegerv(GL2GL3.GL_MAX_SAMPLES, val, 0); + return val[0]; + } else { + return 0; + } + } + + /** Common super class of all attachments */ + public static abstract class Attachment { + public enum Type { + NONE, DEPTH, STENCIL, DEPTH_STENCIL, COLOR, COLOR_TEXTURE, DEPTH_TEXTURE, STENCIL_TEXTURE; + + /** + * Returns {@link #COLOR}, {@link #DEPTH}, {@link #STENCIL} or {@link #DEPTH_STENCIL} + * @throws IllegalArgumentException ifformat
cannot be handled.
+ */
+ public static Type determine(int format) throws IllegalArgumentException {
+ switch(format) {
+ case GL.GL_RGBA4:
+ case GL.GL_RGB5_A1:
+ case GL.GL_RGB565:
+ case GL.GL_RGB8:
+ case GL.GL_RGBA8:
+ return Type.COLOR;
+ case GL.GL_DEPTH_COMPONENT16:
+ case GL.GL_DEPTH_COMPONENT24:
+ case GL.GL_DEPTH_COMPONENT32:
+ return Type.DEPTH;
+ case GL.GL_STENCIL_INDEX1:
+ case GL.GL_STENCIL_INDEX4:
+ case GL.GL_STENCIL_INDEX8:
+ return Type.STENCIL;
+ case GL.GL_DEPTH24_STENCIL8:
+ return Type.DEPTH_STENCIL;
+ default:
+ throw new IllegalArgumentException("format invalid: 0x"+Integer.toHexString(format));
+ }
+ }
+ };
+
+ /** immutable type [{@link #COLOR}, {@link #DEPTH}, {@link #STENCIL}, {@link #COLOR_TEXTURE}, {@link #DEPTH_TEXTURE}, {@link #STENCIL_TEXTURE} ] */
+ public final Type type;
+
+ /** immutable the internal format */
+ public final int format;
+
+ private int width, height;
+
+ private int name;
+
+ /** true
if resource is initialized by {@link #initialize(GL)}, hence {@link #free(GL)} is allowed to free the GL resources. */
+ protected boolean resourceOwner;
+
+ private int initCounter;
+
+ protected Attachment(Type type, int iFormat, int width, int height, int name) {
+ this.type = type;
+ this.format = iFormat;
+ this.width = width;
+ this.height = height;
+ this.name = name;
+ this.resourceOwner = false;
+ this.initCounter = 0;
+ }
+
+ /** width of attachment */
+ public final int getWidth() { return width; }
+ /** height of attachment */
+ public final int getHeight() { return height; }
+ /* pp */ final void setSize(int w, int h) { width = w; height = h; }
+
+ /** buffer name [1..max], maybe a texture or renderbuffer name, depending on type. */
+ public final int getName() { return name; }
+ /* pp */ final void setName(int n) { name = n; }
+
+ public final int getInitCounter() { return initCounter; }
+
+ /**
+ * Initializes the attachment buffer and set it's parameter, if uninitialized, i.e. name is zero
.
+ * Implementation employs an initialization counter, hence it can be paired recursively with {@link #free(GL)}.
+ * @throws GLException if buffer generation or setup fails. The just created buffer name will be deleted in this case. + */ + public void initialize(GL gl) throws GLException { + initCounter++; + /* + super.initialize(gl); + if(1 == getInitCounter() && 0 == getName() ) { + do init .. + freeResources = true; // if all OK + } + */ + } + + /** + * Releases the attachment buffer if initialized, i.e. name iszero
.
+ * Implementation employs an initialization counter, hence it can be paired recursively with {@link #initialize(GL)}.
+ * @throws GLException if buffer release fails. + */ + public void free(GL gl) throws GLException { + /* + if(1 == getInitCounter() && freeResources && .. ) { + do free .. + } + super.free(gl); + */ + initCounter--; + if(0 == initCounter) { + resourceOwner = false; + name = 0; + } + if(DEBUG) { + System.err.println("Attachment.free: "+this); + } + } + + /** + *+ * Comparison by {@link #type}, {@link #format}, {@link #width}, {@link #height} and {@link #name}. + *
+ * {@inheritDoc} + */ + @Override + public boolean equals(Object o) { + if( this == o ) return true; + if( ! ( o instanceof Attachment ) ) return false; + final Attachment a = (Attachment)o; + return type == a.type && + format == a.format || + width == a.width || + height== a.height || + name == a.name ; + } + + /** + *+ * Hashed by {@link #type}, {@link #format}, {@link #width}, {@link #height} and {@link #name}. + *
+ * {@inheritDoc} + */ + @Override + public int hashCode() { + // 31 * x == (x << 5) - x + int hash = 31 + type.ordinal(); + hash = ((hash << 5) - hash) + format; + hash = ((hash << 5) - hash) + width; + hash = ((hash << 5) - hash) + height; + hash = ((hash << 5) - hash) + name; + return hash; + } + + int objectHashCode() { return super.hashCode(); } + + public String toString() { + return getClass().getSimpleName()+"[type "+type+", format 0x"+Integer.toHexString(format)+", "+width+"x"+height+ + ", name 0x"+Integer.toHexString(name)+", obj 0x"+Integer.toHexString(objectHashCode())+ + ", resOwner "+resourceOwner+", initCount "+initCounter+"]"; + } + + public static Type getType(int attachmentPoint, int maxColorAttachments) { + if( GL.GL_COLOR_ATTACHMENT0 <= attachmentPoint && attachmentPoint < GL.GL_COLOR_ATTACHMENT0+maxColorAttachments ) { + return Type.COLOR; + } + switch(attachmentPoint) { + case GL.GL_DEPTH_ATTACHMENT: + return Type.DEPTH; + case GL.GL_STENCIL_ATTACHMENT: + return Type.STENCIL; + default: + throw new IllegalArgumentException("Invalid attachment point 0x"+Integer.toHexString(attachmentPoint)); + } + } + } + + /** Other renderbuffer attachment which maybe a colorbuffer, depth or stencil. */ + public static class RenderAttachment extends Attachment { + private int samples; + + /** + * @param type allowed types are {@link Type#DEPTH}, {@link Type#STENCIL} or {@link Type#COLOR} + * @param iFormat + * @param samples + * @param width + * @param height + * @param name + */ + public RenderAttachment(Type type, int iFormat, int samples, int width, int height, int name) { + super(validateType(type), iFormat, width, height, name); + this.samples = samples; + } + + /** number of samples, or zero for no multisampling */ + public final int getSamples() { return samples; } + /* pp */ final void setSamples(int s) { samples = s; } + + private static Type validateType(Type type) { + switch(type) { + case DEPTH: + case STENCIL: + case COLOR: + return type; + default: + throw new IllegalArgumentException("Invalid type: "+type); + } + } + + /** + *+ * Comparison by {@link #type}, {@link #format}, {@link #samples}, {@link #width}, {@link #height} and {@link #name}. + *
+ * {@inheritDoc} + */ + @Override + public boolean equals(Object o) { + if( this == o ) return true; + if( ! ( o instanceof RenderAttachment ) ) return false; + return super.equals(o) && + samples == ((RenderAttachment)o).samples; + } + + /** + *+ * Hashed by {@link #type}, {@link #format}, {@link #samples}, {@link #width}, {@link #height} and {@link #name}. + *
+ * {@inheritDoc} + */ + @Override + public int hashCode() { + // 31 * x == (x << 5) - x + int hash = super.hashCode(); + hash = ((hash << 5) - hash) + samples; + return hash; + } + + @Override + public void initialize(GL gl) throws GLException { + super.initialize(gl); + if( 1 == getInitCounter() && 0 == getName() ) { + final int[] name = new int[] { -1 }; + gl.glGenRenderbuffers(1, name, 0); + if( 0 == name[0] ) { + throw new GLException("null renderbuffer, "+this); + } + setName(name[0]); + + gl.glBindRenderbuffer(GL.GL_RENDERBUFFER, getName()); + if( samples > 0 ) { + ((GL2GL3)gl).glRenderbufferStorageMultisample(GL.GL_RENDERBUFFER, samples, format, getWidth(), getHeight()); + } else { + gl.glRenderbufferStorage(GL.GL_RENDERBUFFER, format, getWidth(), getHeight()); + } + int glerr = gl.glGetError(); + if(GL.GL_NO_ERROR != glerr) { + gl.glDeleteRenderbuffers(1, name, 0); + setName(0); + throw new GLException("GL Error 0x"+Integer.toHexString(glerr)+" while creating "+this); + } + resourceOwner = true; + if(DEBUG) { + System.err.println("Attachment.init: "+this); + } + } + } + + @Override + public void free(GL gl) { + if(1 == getInitCounter() && resourceOwner && 0 != getName() ) { + final int[] name = new int[] { getName() }; + gl.glDeleteRenderbuffers(1, name, 0); + } + super.free(gl); + } + + public String toString() { + return getClass().getSimpleName()+"[type "+type+", format 0x"+Integer.toHexString(format)+", samples "+samples+", "+getWidth()+"x"+getHeight()+ + ", name 0x"+Integer.toHexString(getName())+", obj 0x"+Integer.toHexString(objectHashCode())+ + ", resOwner "+resourceOwner+", initCount "+getInitCounter()+"]"; + } + } + + /** + * Marker interface, denotes a color buffer attachment. + *Always an instance of {@link Attachment}.
+ *Either an instance of {@link ColorAttachment} or {@link TextureAttachment}.
+ */
+ public static interface Colorbuffer {
+ }
+
+ /** Color render buffer attachment */
+ public static class ColorAttachment extends RenderAttachment implements Colorbuffer {
+ public ColorAttachment(int iFormat, int samples, int width, int height, int name) {
+ super(Type.COLOR, iFormat, samples, width, height, name);
+ }
+ }
+
+ /** Texture attachment */
+ public static class TextureAttachment extends Attachment implements Colorbuffer {
+ /** details of the texture setup */
+ public final int dataFormat, dataType, magFilter, minFilter, wrapS, wrapT;
+
+ /**
+ * @param type allowed types are [ {@link Type#COLOR_TEXTURE}, {@link Type#DEPTH_TEXTURE}, {@link Type#STENCIL_TEXTURE} ]
+ * @param iFormat
+ * @param width
+ * @param height
+ * @param dataFormat
+ * @param dataType
+ * @param magFilter
+ * @param minFilter
+ * @param wrapS
+ * @param wrapT
+ * @param name
+ */
+ public TextureAttachment(Type type, int iFormat, int width, int height, int dataFormat, int dataType,
+ int magFilter, int minFilter, int wrapS, int wrapT, int name) {
+ super(validateType(type), iFormat, width, height, name);
+ this.dataFormat = dataFormat;
+ this.dataType = dataType;
+ this.magFilter = magFilter;
+ this.minFilter = minFilter;
+ this.wrapS = wrapS;
+ this.wrapT = wrapT;
+ }
+
+ private static Type validateType(Type type) {
+ switch(type) {
+ case COLOR_TEXTURE:
+ case DEPTH_TEXTURE:
+ case STENCIL_TEXTURE:
+ return type;
+ default:
+ throw new IllegalArgumentException("Invalid type: "+type);
+ }
+ }
+
+ /**
+ * Initializes the texture and set it's parameter, if uninitialized, i.e. name is zero
.
+ * @throws GLException if texture generation and setup fails. The just created texture name will be deleted in this case.
+ */
+ @Override
+ public void initialize(GL gl) throws GLException {
+ super.initialize(gl);
+ if( 1 == getInitCounter() && 0 == getName() ) {
+ final int[] name = new int[] { -1 };
+ gl.glGenTextures(1, name, 0);
+ if(0 == name[0]) {
+ throw new GLException("null texture, "+this);
+ }
+ setName(name[0]);
+
+ gl.glBindTexture(GL.GL_TEXTURE_2D, name[0]);
+ gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, format, getWidth(), getHeight(), 0, dataFormat, dataType, null);
+ if( 0 < magFilter ) {
+ gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, magFilter);
+ }
+ if( 0 < minFilter ) {
+ gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, minFilter);
+ }
+ if( 0 < wrapS ) {
+ gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, wrapS);
+ }
+ if( 0 < wrapT ) {
+ gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, wrapT);
+ }
+ int glerr = gl.glGetError();
+ if(GL.GL_NO_ERROR != glerr) {
+ gl.glDeleteTextures(1, name, 0);
+ setName(0);
+ throw new GLException("GL Error 0x"+Integer.toHexString(glerr)+" while creating "+this);
+ }
+ resourceOwner = true;
+ }
+ if(DEBUG) {
+ System.err.println("Attachment.init: "+this);
+ }
+ }
+
+ @Override
+ public void free(GL gl) {
+ if(1 == getInitCounter() && resourceOwner && 0 != getName() ) {
+ final int[] name = new int[] { getName() };
+ gl.glDeleteTextures(1, name, 0);
+ }
+ super.free(gl);
+ }
+ }
+
+ private boolean initialized;
+ private boolean basicFBOSupport;
+ private boolean fullFBOSupport;
+ private boolean rgba8Avail;
+ private boolean depth24Avail;
+ private boolean depth32Avail;
+ private boolean stencil01Avail;
+ private boolean stencil04Avail;
+ private boolean stencil08Avail;
+ private boolean stencil16Avail;
+ private boolean packedDepthStencilAvail;
+ private int maxColorAttachments, maxSamples, maxTextureSize, maxRenderbufferSize;
+
+ private int width, height, samples;
+ private int vStatus;
+ private int fbName;
+ private boolean bound;
+
+ private int colorAttachmentCount;
+ private Colorbuffer[] colorAttachmentPoints; // colorbuffer attachment points
+ private RenderAttachment depth, stencil; // depth and stencil maybe equal in case of packed-depth-stencil
+
+ private final FBObject samplesSink; // MSAA sink
+ private TextureAttachment samplesSinkTexture;
+ private boolean samplesSinkDirty;
+
+ //
+ // ColorAttachment helper ..
+ //
+
+ private final void validateColorAttachmentPointRange(int point) {
+ if(maxColorAttachments != colorAttachmentPoints.length) {
+ throw new InternalError("maxColorAttachments "+maxColorAttachments+", array.lenght "+colorAttachmentPoints);
+ }
+ if(0 > point || point >= maxColorAttachments) {
+ throw new IllegalArgumentException("attachment point out of range: "+point+", should be within [0.."+(maxColorAttachments-1)+"]");
+ }
+ }
+
+ private final void validateAddColorAttachment(int point, Colorbuffer ca) {
+ validateColorAttachmentPointRange(point);
+ if( null != colorAttachmentPoints[point] ) {
+ throw new IllegalArgumentException("Cannot attach "+ca+", attachment point already in use by "+colorAttachmentPoints[point]);
+ }
+ }
+
+ private final void addColorAttachment(int point, Colorbuffer ca) {
+ validateColorAttachmentPointRange(point);
+ final Colorbuffer c = colorAttachmentPoints[point];
+ if( null != c && c != ca ) {
+ throw new IllegalArgumentException("Add failed: requested to add "+ca+" at "+point+", but slot is holding "+c+"; "+this);
+ }
+ colorAttachmentPoints[point] = ca;
+ colorAttachmentCount++;
+ }
+
+ private final void removeColorAttachment(int point, Colorbuffer ca) {
+ validateColorAttachmentPointRange(point);
+ final Colorbuffer c = colorAttachmentPoints[point];
+ if( null != c && c != ca ) {
+ throw new IllegalArgumentException("Remove failed: requested to removed "+ca+" at "+point+", but slot is holding "+c+"; "+this);
+ }
+ colorAttachmentPoints[point] = null;
+ colorAttachmentCount--;
+ }
+
+ /**
+ * Return the {@link Colorbuffer} attachment at attachmentPoint
if it is attached to this FBO, otherwise null.
+ *
+ * @see #attachColorbuffer(GL, boolean)
+ * @see #attachColorbuffer(GL, boolean)
+ * @see #attachTexture2D(GL, int, boolean, int, int, int, int)
+ * @see #attachTexture2D(GL, int, int, int, int, int, int, int, int)
+ */
+ public final Colorbuffer getColorbuffer(int attachmentPoint) {
+ validateColorAttachmentPointRange(attachmentPoint);
+ return colorAttachmentPoints[attachmentPoint];
+ }
+
+ /**
+ * Finds the passed {@link Colorbuffer} within the valid range of attachment points
+ * using reference comparison only.
+ *
+ * Note: Slow. Implementation uses a logN array search to save resources, i.e. not using a HashMap. + *
+ * @param ca the {@link Colorbuffer} to look for. + * @return -1 if the {@link Colorbuffer} could not be found, otherwise [0..{@link #getMaxColorAttachments()}-1] + */ + public final int getColorbufferAttachmentPoint(Colorbuffer ca) { + for(int i=0; i+ * Note: Slow. Uses {@link #getColorbufferAttachmentPoint(Colorbuffer)} to determine it's attachment point + * to be used for {@link #getColorbuffer(int)} + *
+ * + * @see #attachColorbuffer(GL, boolean) + * @see #attachColorbuffer(GL, boolean) + * @see #attachTexture2D(GL, int, boolean, int, int, int, int) + * @see #attachTexture2D(GL, int, int, int, int, int, int, int, int) + */ + public final Colorbuffer getColorbuffer(Colorbuffer ca) { + final int p = getColorbufferAttachmentPoint(ca); + return p>=0 ? getColorbuffer(p) : null; + } + + /** + * Creates an uninitialized FBObject instance. + *+ * Call {@link #init(GL, int, int, int)} .. etc to use it. + *
+ */ + public FBObject() { + this(false); + } + /* pp */ FBObject(boolean isSampleSink) { + this.initialized = false; + + // TBD @ init + this.basicFBOSupport = false; + this.fullFBOSupport = false; + this.rgba8Avail = false; + this.depth24Avail = false; + this.depth32Avail = false; + this.stencil01Avail = false; + this.stencil04Avail = false; + this.stencil08Avail = false; + this.stencil16Avail = false; + this.packedDepthStencilAvail = false; + this.maxColorAttachments=-1; + this.maxSamples=-1; + this.maxTextureSize = 0; + this.maxRenderbufferSize = 0; + + this.width = 0; + this.height = 0; + this.samples = 0; + this.vStatus = -1; + this.fbName = 0; + this.bound = false; + + this.colorAttachmentPoints = null; // at init .. + this.colorAttachmentCount = 0; + this.depth = null; + this.stencil = null; + + this.samplesSink = isSampleSink ? null : new FBObject(true); + this.samplesSinkTexture = null; + this.samplesSinkDirty = true; + } + + private void init(GL gl, int width, int height, int samples) throws GLException { + if(initialized) { + throw new GLException("FBO already initialized"); + } + fullFBOSupport = supportsFullFBO(gl); + + if( !fullFBOSupport && !supportsBasicFBO(gl) ) { + throw new GLException("FBO not supported w/ context: "+gl.getContext()+", "+this); + } + + basicFBOSupport = true; + + rgba8Avail = gl.isGL2GL3() || gl.isExtensionAvailable(GLExtensions.OES_rgb8_rgba8); + depth24Avail = fullFBOSupport || gl.isExtensionAvailable(GLExtensions.OES_depth24); + depth32Avail = fullFBOSupport || gl.isExtensionAvailable(GLExtensions.OES_depth32); + stencil01Avail = fullFBOSupport || gl.isExtensionAvailable(GLExtensions.OES_stencil1); + stencil04Avail = fullFBOSupport || gl.isExtensionAvailable(GLExtensions.OES_stencil4); + stencil08Avail = fullFBOSupport || gl.isExtensionAvailable(GLExtensions.OES_stencil8); + stencil16Avail = fullFBOSupport; + + packedDepthStencilAvail = fullFBOSupport || gl.isExtensionAvailable(GLExtensions.OES_packed_depth_stencil); + + final boolean NV_fbo_color_attachments = gl.isExtensionAvailable(GLExtensions.NV_fbo_color_attachments); + + int val[] = new int[1]; + + int glerr = gl.glGetError(); + if(DEBUG && GL.GL_NO_ERROR != glerr) { + System.err.println("FBObject.init-preexisting.0 GL Error 0x"+Integer.toHexString(glerr)); + } + + int realMaxColorAttachments = 1; + maxColorAttachments = 1; + if( null != samplesSink && fullFBOSupport || NV_fbo_color_attachments ) { + try { + gl.glGetIntegerv(GL2GL3.GL_MAX_COLOR_ATTACHMENTS, val, 0); + glerr = gl.glGetError(); + if(GL.GL_NO_ERROR == glerr) { + realMaxColorAttachments = 1 <= val[0] ? val[0] : 1; // cap minimum to 1 + } else if(DEBUG) { + System.err.println("FBObject.init-GL_MAX_COLOR_ATTACHMENTS query GL Error 0x"+Integer.toHexString(glerr)); + } + } catch (GLException gle) {} + } + maxColorAttachments = realMaxColorAttachments <= 8 ? realMaxColorAttachments : 8; // cap to limit array size + + colorAttachmentPoints = new Colorbuffer[maxColorAttachments]; + colorAttachmentCount = 0; + + maxSamples = 0; + if(fullFBOSupport) { + gl.glGetIntegerv(GL2GL3.GL_MAX_SAMPLES, val, 0); + glerr = gl.glGetError(); + if(GL.GL_NO_ERROR == glerr) { + maxSamples = val[0]; + } else if(DEBUG) { + System.err.println("FBObject.init-GL_MAX_SAMPLES query GL Error 0x"+Integer.toHexString(glerr)); + } + } + gl.glGetIntegerv(GL.GL_MAX_TEXTURE_SIZE, val, 0); + maxTextureSize = val[0]; + gl.glGetIntegerv(GL.GL_MAX_RENDERBUFFER_SIZE, val, 0); + this.maxRenderbufferSize = val[0]; + + glerr = gl.glGetError(); + if(DEBUG && GL.GL_NO_ERROR != glerr) { + System.err.println("FBObject.init-preexisting.1 GL Error 0x"+Integer.toHexString(glerr)); + } + + this.width = width; + this.height = height; + this.samples = samples <= maxSamples ? samples : maxSamples; + + if(DEBUG) { + System.err.println("FBObject "+width+"x"+height+", "+samples+" -> "+samples+" samples"); + System.err.println("basicFBOSupport: "+basicFBOSupport); + System.err.println("fullFBOSupport: "+fullFBOSupport); + System.err.println("maxColorAttachments: "+maxColorAttachments+"/"+realMaxColorAttachments); + System.err.println("maxSamples: "+maxSamples); + System.err.println("maxTextureSize: "+maxTextureSize); + System.err.println("maxRenderbufferSize: "+maxRenderbufferSize); + System.err.println("rgba8: "+rgba8Avail); + System.err.println("depth24: "+depth24Avail); + System.err.println("depth32: "+depth32Avail); + System.err.println("stencil01: "+stencil01Avail); + System.err.println("stencil04: "+stencil04Avail); + System.err.println("stencil08: "+stencil08Avail); + System.err.println("stencil16: "+stencil16Avail); + System.err.println("packedDepthStencil: "+packedDepthStencilAvail); + System.err.println("NV_fbo_color_attachments: "+NV_fbo_color_attachments); + System.err.println(gl.getContext().getGLVersion()); + System.err.println(JoglVersion.getGLStrings(gl, null).toString()); + System.err.println(gl.getContext()); + } + + checkNoError(null, gl.glGetError(), "FBObject Init.pre"); // throws GLException if error + + if(width > 2 + maxTextureSize || height> 2 + maxTextureSize || + width > maxRenderbufferSize || height> maxRenderbufferSize ) { + throw new GLException("size "+width+"x"+height+" exceeds on of the maxima [texture "+maxTextureSize+", renderbuffer "+maxRenderbufferSize+"]"); + } + + if(null != samplesSink) { + // init sampling sink + samplesSink.reset(gl, width, height); + resetMSAATexture2DSink(gl); + } + + // generate fbo .. + gl.glGenFramebuffers(1, val, 0); + fbName = val[0]; + if(0 == fbName) { + throw new GLException("null framebuffer"); + } + + // bind fbo .. + gl.glBindFramebuffer(GL.GL_FRAMEBUFFER, fbName); + checkNoError(gl, gl.glGetError(), "FBObject Init.bindFB"); // throws GLException if error + if(!gl.glIsFramebuffer(fbName)) { + checkNoError(gl, GL.GL_INVALID_VALUE, "FBObject Init.isFB"); // throws GLException + } + bound = true; + initialized = true; + + updateStatus(gl); + if(DEBUG) { + System.err.println("FBObject.init(): "+this); + } + } + + /** + * Initializes or resets this FBO's instance. + *+ * In case the new parameters are compatible with the current ones + * no action will be performed. Otherwise all attachments will be recreated + * to match the new given parameters. + *
+ *+ * Currently incompatibility and hence recreation is given if + * the size or sample count doesn't match for subsequent calls. + *
+ * + *Leaves the FBO bound state untouched
+ * + * @param gl the current GL context + * @param newWidth + * @param newHeight + * @throws GLException in case of an error + */ + public final void reset(GL gl, int newWidth, int newHeight) { + reset(gl, newWidth, newHeight, 0); + } + + /** + * Initializes or resets this FBO's instance. + *+ * In case the new parameters are compatible with the current ones + * no action will be performed. Otherwise all attachments will be recreated + * to match the new given parameters. + *
+ *+ * Currently incompatibility and hence recreation is given if + * the size or sample count doesn't match for subsequent calls. + *
+ * + *Leaves the FBO bound state untouched
+ * + * @param gl the current GL context + * @param newWidth + * @param newHeight + * @param newSamples if > 0, MSAA will be used, otherwise no multisampling. Will be capped to {@link #getMaxSamples()}. + * @throws GLException in case of an error + */ + public final void reset(GL gl, int newWidth, int newHeight, int newSamples) { + if(!initialized) { + init(gl, newWidth, newHeight, newSamples); + return; + } + newSamples = newSamples <= maxSamples ? newSamples : maxSamples; // clamp + + if( newWidth != width || newHeight != height || newSamples != samples ) { + if(DEBUG) { + System.err.println("FBObject.reset - START - "+this); + } + + final boolean wasBound = isBound(); + + width = newWidth; + height = newHeight; + samples = newSamples; + detachAllImpl(gl, true , true); + resetMSAATexture2DSink(gl); + + if(wasBound) { + bind(gl); + } else { + unbind(gl); + } + + if(DEBUG) { + System.err.println("FBObject.reset - END - "+this); + } + } + } + + /** + * Note that the status may reflect an incomplete state during transition of attachments. + * @return The FB status. {@link GL.GL_FRAMEBUFFER_COMPLETE} if ok, otherwise return GL FBO error state or -1 + * @see #validateStatus() + */ + public final int getStatus() { + return vStatus; + } + + /** return the {@link #getStatus()} as a string. */ + public final String getStatusString() { + return getStatusString(vStatus); + } + + public static final String getStatusString(int fbStatus) { + switch(fbStatus) { + case -1: + return "NOT A FBO"; + + case GL.GL_FRAMEBUFFER_COMPLETE: + return "OK"; + + case GL.GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: + return("GL FBO: incomplete, incomplete attachment\n"); + case GL.GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: + return("GL FBO: incomplete, missing attachment"); + case GL.GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS: + return("GL FBO: incomplete, attached images must have same dimensions"); + case GL.GL_FRAMEBUFFER_INCOMPLETE_FORMATS: + return("GL FBO: incomplete, attached images must have same format"); + case GL2GL3.GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER: + return("GL FBO: incomplete, missing draw buffer"); + case GL2GL3.GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER: + return("GL FBO: incomplete, missing read buffer"); + case GL2GL3.GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE: + return("GL FBO: incomplete, missing multisample buffer"); + case GL3.GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS: + return("GL FBO: incomplete, layer targets"); + + case GL.GL_FRAMEBUFFER_UNSUPPORTED: + return("GL FBO: Unsupported framebuffer format"); + case GL2GL3.GL_FRAMEBUFFER_UNDEFINED: + return("GL FBO: framebuffer undefined"); + + case 0: + return("GL FBO: incomplete, implementation fault"); + default: + return("GL FBO: incomplete, implementation ERROR 0x"+Integer.toHexString(fbStatus)); + } + } + + /** + * The status may even be valid if incomplete during transition of attachments. + * @see #getStatus() + */ + public final boolean isStatusValid() { + switch(vStatus) { + case GL.GL_FRAMEBUFFER_COMPLETE: + return true; + + case GL.GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: + case GL.GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: + case GL.GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS: + case GL.GL_FRAMEBUFFER_INCOMPLETE_FORMATS: + case GL2GL3.GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER: + case GL2GL3.GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER: + case GL2GL3.GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE: + case GL3.GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS: + if(0 == colorAttachmentCount || null == depth) { + // we are in transition + return true; + } + + case GL.GL_FRAMEBUFFER_UNSUPPORTED: + case GL2GL3.GL_FRAMEBUFFER_UNDEFINED: + + case 0: + default: + System.out.println("Framebuffer " + fbName + " is incomplete: status = 0x" + Integer.toHexString(vStatus) + + " : " + getStatusString(vStatus)); + return false; + } + } + + private final boolean checkNoError(GL gl, int err, String exceptionMessage) throws GLException { + if(GL.GL_NO_ERROR != err) { + if(null != gl) { + destroy(gl); + } + if(null != exceptionMessage) { + throw new GLException(exceptionMessage+" GL Error 0x"+Integer.toHexString(err)); + } + return false; + } + return true; + } + + private final void checkInitialized() throws GLException { + if(!initialized) { + throw new GLException("FBO not initialized, call init(GL) first."); + } + } + + /** + * Attaches a Texture2D Color Buffer to this FBO's instance at the given attachment point, + * selecting the texture data type and format automatically. + * + *Using default min/mag filter {@link GL#GL_NEAREST} and default wrapS/wrapT {@link GL#GL_CLAMP_TO_EDGE}.
+ * + *Leaves the FBO bound.
+ * + * @param gl the current GL context + * @param attachmentPoint the color attachment point ranging from [0..{@link #getMaxColorAttachments()}-1] + * @param alpha set totrue
if you request alpha channel, otherwise false
;
+ * @return TextureAttachment instance describing the new attached texture colorbuffer if bound and configured successfully, otherwise GLException is thrown
+ * @throws GLException in case the texture colorbuffer couldn't be allocated or MSAA has been chosen
+ */
+ public final TextureAttachment attachTexture2D(GL gl, int attachmentPoint, boolean alpha) throws GLException {
+ return attachTexture2D(gl, attachmentPoint, alpha, GL.GL_NEAREST, GL.GL_NEAREST, GL.GL_CLAMP_TO_EDGE, GL.GL_CLAMP_TO_EDGE);
+ }
+
+ /**
+ * Attaches a Texture2D Color Buffer to this FBO's instance at the given attachment point,
+ * selecting the texture data type and format automatically.
+ *
+ * Leaves the FBO bound.
+ * + * @param gl the current GL context + * @param attachmentPoint the color attachment point ranging from [0..{@link #getMaxColorAttachments()}-1] + * @param alpha set totrue
if you request alpha channel, otherwise false
;
+ * @param magFilter if > 0 value for {@link GL#GL_TEXTURE_MAG_FILTER}
+ * @param minFilter if > 0 value for {@link GL#GL_TEXTURE_MIN_FILTER}
+ * @param wrapS if > 0 value for {@link GL#GL_TEXTURE_WRAP_S}
+ * @param wrapT if > 0 value for {@link GL#GL_TEXTURE_WRAP_T}
+ * @return TextureAttachment instance describing the new attached texture colorbuffer if bound and configured successfully, otherwise GLException is thrown
+ * @throws GLException in case the texture colorbuffer couldn't be allocated or MSAA has been chosen
+ */
+ public final TextureAttachment attachTexture2D(GL gl, int attachmentPoint, boolean alpha, int magFilter, int minFilter, int wrapS, int wrapT) throws GLException {
+ final int textureInternalFormat, textureDataFormat, textureDataType;
+ if(gl.isGLES()) {
+ textureInternalFormat = alpha ? GL.GL_RGBA : GL.GL_RGB;
+ textureDataFormat = alpha ? GL.GL_RGBA : GL.GL_RGB;
+ textureDataType = GL.GL_UNSIGNED_BYTE;
+ } else {
+ textureInternalFormat = alpha ? GL.GL_RGBA8 : GL.GL_RGB8;
+ textureDataFormat = alpha ? GL.GL_BGRA : GL.GL_RGB;
+ textureDataType = alpha ? GL2GL3.GL_UNSIGNED_INT_8_8_8_8_REV : GL.GL_UNSIGNED_BYTE;
+ }
+ return attachTexture2D(gl, attachmentPoint, textureInternalFormat, textureDataFormat, textureDataType, magFilter, minFilter, wrapS, wrapT);
+ }
+
+ /**
+ * Attaches a Texture2D Color Buffer to this FBO's instance at the given attachment point.
+ *
+ * Leaves the FBO bound.
+ * + * @param gl the current GL context + * @param attachmentPoint the color attachment point ranging from [0..{@link #getMaxColorAttachments()}-1] + * @param internalFormat internalFormat parameter to {@link GL#glTexImage2D(int, int, int, int, int, int, int, int, long)} + * @param dataFormat format parameter to {@link GL#glTexImage2D(int, int, int, int, int, int, int, int, long)} + * @param dataType type parameter to {@link GL#glTexImage2D(int, int, int, int, int, int, int, int, long)} + * @param magFilter if > 0 value for {@link GL#GL_TEXTURE_MAG_FILTER} + * @param minFilter if > 0 value for {@link GL#GL_TEXTURE_MIN_FILTER} + * @param wrapS if > 0 value for {@link GL#GL_TEXTURE_WRAP_S} + * @param wrapT if > 0 value for {@link GL#GL_TEXTURE_WRAP_T} + * @return TextureAttachment instance describing the new attached texture colorbuffer if bound and configured successfully, otherwise GLException is thrown + * @throws GLException in case the texture colorbuffer couldn't be allocated or MSAA has been chosen + */ + public final TextureAttachment attachTexture2D(GL gl, int attachmentPoint, + int internalFormat, int dataFormat, int dataType, + int magFilter, int minFilter, int wrapS, int wrapT) throws GLException { + return attachTexture2D(gl, attachmentPoint, + new TextureAttachment(Type.COLOR_TEXTURE, internalFormat, width, height, dataFormat, dataType, + magFilter, minFilter, wrapS, wrapT, 0 /* name */)); + } + + /** + * Attaches a Texture2D Color Buffer to this FBO's instance at the given attachment point. + * + *
+ * In case the passed TextureAttachment texA
is uninitialized, i.e. it's texture name is zero
,
+ * a new texture name is generated and setup w/ the texture parameter.
+ * Otherwise, i.e. texture name is not zero
, the passed TextureAttachment texA
is
+ * considered complete and assumed matching this FBO requirement. A GL error may occur is the latter is untrue.
+ *
Leaves the FBO bound.
+ * + * @param gl the current GL context + * @param attachmentPoint the color attachment point ranging from [0..{@link #getMaxColorAttachments()}-1] + * @param texA the to be attached {@link TextureAttachment}. Maybe complete or uninitialized, see above. + * @return the passed TextureAttachmenttexA
instance describing the new attached texture colorbuffer if bound and configured successfully, otherwise GLException is thrown
+ * @throws GLException in case the texture colorbuffer couldn't be allocated or MSAA has been chosen
+ */
+ public final TextureAttachment attachTexture2D(GL gl, int attachmentPoint, TextureAttachment texA) throws GLException {
+ validateAddColorAttachment(attachmentPoint, texA);
+
+ if(samples>0) {
+ removeColorAttachment(attachmentPoint, texA);
+ throw new GLException("Texture2D not supported w/ MSAA. If you have enabled MSAA with exisiting texture attachments, you may want to detach them via detachAllTexturebuffer(gl).");
+ }
+
+ texA.initialize(gl);
+ addColorAttachment(attachmentPoint, texA);
+
+ bind(gl);
+
+ // Set up the color buffer for use as a renderable texture:
+ gl.glFramebufferTexture2D(GL.GL_FRAMEBUFFER,
+ GL.GL_COLOR_ATTACHMENT0 + attachmentPoint,
+ GL.GL_TEXTURE_2D, texA.getName(), 0);
+ updateStatus(gl);
+
+ if(!isStatusValid()) {
+ detachColorbuffer(gl, attachmentPoint);
+ throw new GLException("attachTexture2D "+texA+" at "+attachmentPoint+" failed "+getStatusString()+", "+this);
+ }
+ if(DEBUG) {
+ System.err.println("FBObject.attachTexture2D: "+this);
+ }
+ return texA;
+ }
+
+ /**
+ * Attaches a Color Buffer to this FBO's instance at the given attachment point,
+ * selecting the format automatically.
+ *
+ * Leaves the FBO bound.
+ * + * @param gl the current GL context + * @param attachmentPoint the color attachment point ranging from [0..{@link #getMaxColorAttachments()}-1] + * @param alpha set totrue
if you request alpha channel, otherwise false
;
+ * @return ColorAttachment instance describing the new attached colorbuffer if bound and configured successfully, otherwise GLException is thrown
+ * @throws GLException in case the colorbuffer couldn't be allocated
+ */
+ public final ColorAttachment attachColorbuffer(GL gl, int attachmentPoint, boolean alpha) throws GLException {
+ final int internalFormat;
+ if( rgba8Avail ) {
+ internalFormat = alpha ? GL.GL_RGBA8 : GL.GL_RGB8 ;
+ } else {
+ internalFormat = alpha ? GL.GL_RGBA4 : GL.GL_RGB565;
+ }
+ return attachColorbuffer(gl, attachmentPoint, internalFormat);
+ }
+
+ /**
+ * Attaches a Color Buffer to this FBO's instance at the given attachment point.
+ *
+ * Leaves the FBO bound.
+ * + * @param gl the current GL context + * @param attachmentPoint the color attachment point ranging from [0..{@link #getMaxColorAttachments()}-1] + * @param internalFormat usually {@link GL#GL_RGBA4}, {@link GL#GL_RGB5_A1}, {@link GL#GL_RGB565}, {@link GL#GL_RGB8} or {@link GL#GL_RGBA8} + * @return ColorAttachment instance describing the new attached colorbuffer if bound and configured successfully, otherwise GLException is thrown + * @throws GLException in case the colorbuffer couldn't be allocated + * @throws IllegalArgumentException ifinternalFormat
doesn't reflect a colorbuffer
+ */
+ public final ColorAttachment attachColorbuffer(GL gl, int attachmentPoint, int internalFormat) throws GLException, IllegalArgumentException {
+ final Attachment.Type atype = Attachment.Type.determine(internalFormat);
+ if( Attachment.Type.COLOR != atype ) {
+ throw new IllegalArgumentException("colorformat invalid: 0x"+Integer.toHexString(internalFormat)+", "+this);
+ }
+
+ return attachColorbuffer(gl, attachmentPoint, new ColorAttachment(internalFormat, samples, width, height, 0));
+ }
+
+ /**
+ * Attaches a Color Buffer to this FBO's instance at the given attachment point.
+ *
+ * Leaves the FBO bound.
+ * + * @param gl + * @param attachmentPoint the color attachment point ranging from [0..{@link #getMaxColorAttachments()}-1] + * @param colA the template for the new {@link ColorAttachment} + * @return ColorAttachment instance describing the new attached colorbuffer if bound and configured successfully, otherwise GLException is thrown + * @throws GLException in case the colorbuffer couldn't be allocated + */ + public final ColorAttachment attachColorbuffer(GL gl, int attachmentPoint, ColorAttachment colA) throws GLException { + validateAddColorAttachment(attachmentPoint, colA); + + colA.initialize(gl); + addColorAttachment(attachmentPoint, colA); + + bind(gl); + + // Attach the color buffer + gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, + GL.GL_COLOR_ATTACHMENT0 + attachmentPoint, + GL.GL_RENDERBUFFER, colA.getName()); + + updateStatus(gl); + if(!isStatusValid()) { + detachColorbuffer(gl, attachmentPoint); + throw new GLException("attachColorbuffer "+colA+" at "+attachmentPoint+" failed "+getStatusString()+", "+this); + } + if(DEBUG) { + System.err.println("FBObject.attachColorbuffer: "+this); + } + return colA; + } + + + /** + * Attaches one depth, stencil or packed-depth-stencil buffer to this FBO's instance, + * selecting the internalFormat automatically. + *+ * Stencil and depth buffer can be attached only once. + *
+ *+ * In case the desired type or bit-number is not supported, the next available one is chosen. + *
+ *+ * Use {@link #getDepthAttachment()} and/or {@link #getStencilAttachment()} to retrieve details + * about the attached buffer. The details cannot be returned, since it's possible 2 buffers + * are being created, depth and stencil. + *
+ * + *Leaves the FBO bound.
+ * + * @param gl + * @param atype either {@link Type#DEPTH}, {@link Type#STENCIL} or {@link Type#DEPTH_STENCIL} + * @param reqBits desired bits for depth or -1 for default (24 bits) + * @throws GLException in case the renderbuffer couldn't be allocated or one is already attached. + * @throws IllegalArgumentException + * @see #getDepthAttachment() + * @see #getStencilAttachment() + */ + public final void attachRenderbuffer(GL gl, Attachment.Type atype, int reqBits) throws GLException, IllegalArgumentException { + if( 0 > reqBits ) { + reqBits = 24; + } + final int internalFormat; + int internalStencilFormat = -1; + + switch ( atype ) { + case DEPTH: + if( 32 <= reqBits && depth32Avail ) { + internalFormat = GL.GL_DEPTH_COMPONENT32; + } else if( 24 <= reqBits && depth24Avail ) { + internalFormat = GL.GL_DEPTH_COMPONENT24; + } else { + internalFormat = GL.GL_DEPTH_COMPONENT16; + } + break; + + case STENCIL: + if( 16 <= reqBits && stencil16Avail ) { + internalFormat = GL2GL3.GL_STENCIL_INDEX16; + } else if( 8 <= reqBits && stencil08Avail ) { + internalFormat = GL.GL_STENCIL_INDEX8; + } else if( 4 <= reqBits && stencil04Avail ) { + internalFormat = GL.GL_STENCIL_INDEX4; + } else if( 1 <= reqBits && stencil01Avail ) { + internalFormat = GL.GL_STENCIL_INDEX1; + } else { + throw new GLException("stencil buffer n/a"); + } + break; + + case DEPTH_STENCIL: + if( packedDepthStencilAvail ) { + internalFormat = GL.GL_DEPTH24_STENCIL8; + } else { + if( 24 <= reqBits && depth24Avail ) { + internalFormat = GL.GL_DEPTH_COMPONENT24; + } else { + internalFormat = GL.GL_DEPTH_COMPONENT16; + } + if( stencil08Avail ) { + internalStencilFormat = GL.GL_STENCIL_INDEX8; + } else if( stencil04Avail ) { + internalStencilFormat = GL.GL_STENCIL_INDEX4; + } else if( stencil01Avail ) { + internalStencilFormat = GL.GL_STENCIL_INDEX1; + } else { + throw new GLException("stencil buffer n/a"); + } + } + break; + default: + throw new IllegalArgumentException("only depth/stencil types allowed, was "+atype+", "+this); + } + + attachRenderbufferImpl(gl, atype, internalFormat); + + if(0<=internalStencilFormat) { + attachRenderbufferImpl(gl, Attachment.Type.STENCIL, internalStencilFormat); + } + } + + /** + * Attaches one depth, stencil or packed-depth-stencil buffer to this FBO's instance, + * depending on theinternalFormat
.
+ * + * Stencil and depth buffer can be attached only once. + *
+ *+ * Use {@link #getDepthAttachment()} and/or {@link #getStencilAttachment()} to retrieve details + * about the attached buffer. The details cannot be returned, since it's possible 2 buffers + * are being created, depth and stencil. + *
+ * + *Leaves the FBO bound.
+ * + * @param gl the current GL context + * @param internalFormat {@link GL#GL_DEPTH_COMPONENT16}, {@link GL#GL_DEPTH_COMPONENT24}, {@link GL#GL_DEPTH_COMPONENT32}, + * {@link GL#GL_STENCIL_INDEX1}, {@link GL#GL_STENCIL_INDEX4}, {@link GL#GL_STENCIL_INDEX8} + * or {@link GL#GL_DEPTH24_STENCIL8} + * @throws GLException in case the renderbuffer couldn't be allocated or one is already attached. + * @throws IllegalArgumentException + * @see #getDepthAttachment() + * @see #getStencilAttachment() + */ + public final void attachRenderbuffer(GL gl, int internalFormat) throws GLException, IllegalArgumentException { + final Attachment.Type atype = Attachment.Type.determine(internalFormat); + if( Attachment.Type.DEPTH != atype && Attachment.Type.STENCIL != atype && Attachment.Type.DEPTH_STENCIL != atype ) { + throw new IllegalArgumentException("renderformat invalid: 0x"+Integer.toHexString(internalFormat)+", "+this); + } + attachRenderbufferImpl(gl, atype, internalFormat); + } + + protected final void attachRenderbufferImpl(GL gl, Attachment.Type atype, int internalFormat) throws GLException { + if( null != depth && ( Attachment.Type.DEPTH == atype || Attachment.Type.DEPTH_STENCIL == atype ) ) { + throw new GLException("FBO depth buffer already attached (rb "+depth+"), type is "+atype+", 0x"+Integer.toHexString(internalFormat)+", "+this); + } + if( null != stencil && ( Attachment.Type.STENCIL== atype || Attachment.Type.DEPTH_STENCIL == atype ) ) { + throw new GLException("FBO stencil buffer already attached (rb "+stencil+"), type is "+atype+", 0x"+Integer.toHexString(internalFormat)+", "+this); + } + attachRenderbufferImpl2(gl, atype, internalFormat); + } + + private final void attachRenderbufferImpl2(GL gl, Attachment.Type atype, int internalFormat) throws GLException { + if( Attachment.Type.DEPTH == atype ) { + if(null == depth) { + depth = new RenderAttachment(Type.DEPTH, internalFormat, samples, width, height, 0); + } else { + depth.setSize(width, height); + depth.setSamples(samples); + } + depth.initialize(gl); + } else if( Attachment.Type.STENCIL == atype ) { + if(null == stencil) { + stencil = new RenderAttachment(Type.STENCIL, internalFormat, samples, width, height, 0); + } else { + stencil.setSize(width, height); + stencil.setSamples(samples); + } + stencil.initialize(gl); + } else if( Attachment.Type.DEPTH_STENCIL == atype ) { + if(null == depth) { + depth = new RenderAttachment(Type.DEPTH, internalFormat, samples, width, height, 0); + } else { + depth.setSize(width, height); + depth.setSamples(samples); + } + depth.initialize(gl); + if(null == stencil) { + stencil = new RenderAttachment(Type.STENCIL, internalFormat, samples, width, height, depth.getName()); + } else { + stencil.setName(depth.getName()); + stencil.setSize(width, height); + stencil.setSamples(samples); + } + stencil.initialize(gl); + } + + bind(gl); + + // Attach the buffer + if( Attachment.Type.DEPTH == atype ) { + gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_DEPTH_ATTACHMENT, GL.GL_RENDERBUFFER, depth.getName()); + } else if( Attachment.Type.STENCIL == atype ) { + gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_STENCIL_ATTACHMENT, GL.GL_RENDERBUFFER, stencil.getName()); + } else if( Attachment.Type.DEPTH_STENCIL == atype ) { + gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_DEPTH_ATTACHMENT, GL.GL_RENDERBUFFER, depth.getName()); + gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_STENCIL_ATTACHMENT, GL.GL_RENDERBUFFER, stencil.getName()); + } + + updateStatus(gl); + if( !isStatusValid() ) { + detachRenderbuffer(gl, atype); + throw new GLException("renderbuffer attachment failed: "+this.getStatusString()); + } + + if(DEBUG) { + System.err.println("FBObject.attachRenderbuffer: "+this); + } + } + + /** + *Leaves the FBO bound!
+ * @param gl + * @param ca + * @throws IllegalArgumentException + */ + public final void detachColorbuffer(GL gl, int attachmentPoint) throws IllegalArgumentException { + if(null == detachColorbufferImpl(gl, attachmentPoint, false)) { + throw new IllegalArgumentException("ColorAttachment at "+attachmentPoint+", not attached, "+this); + } + if(DEBUG) { + System.err.println("FBObject.detachAll: "+this); + } + } + + private final Colorbuffer detachColorbufferImpl(GL gl, int attachmentPoint, boolean recreate) { + final Colorbuffer colbuf = colorAttachmentPoints[attachmentPoint]; // shortcut, don't validate here + + if(null == colbuf) { + return null; + } + + bind(gl); + + if(colbuf instanceof TextureAttachment) { + final TextureAttachment texA = (TextureAttachment) colbuf; + if( 0 != texA.getName() ) { + gl.glFramebufferTexture2D(GL.GL_FRAMEBUFFER, + GL.GL_COLOR_ATTACHMENT0 + attachmentPoint, + GL.GL_TEXTURE_2D, 0, 0); + gl.glBindTexture(GL.GL_TEXTURE_2D, 0); + } + texA.free(gl); + removeColorAttachment(attachmentPoint, texA); + if(recreate) { + texA.setSize(width, height); + attachTexture2D(gl, attachmentPoint, texA); + } + } else if(colbuf instanceof ColorAttachment) { + final ColorAttachment colA = (ColorAttachment) colbuf; + if( 0 != colA.getName() ) { + gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, + GL.GL_COLOR_ATTACHMENT0+attachmentPoint, + GL.GL_RENDERBUFFER, 0); + } + colA.free(gl); + removeColorAttachment(attachmentPoint, colbuf); + if(recreate) { + colA.setSize(width, height); + colA.setSamples(samples); + attachColorbuffer(gl, attachmentPoint, colA); + } + } + return colbuf; + } + + /** + * + * @param gl + * @param reqAType {@link Type#DEPTH}, {@link Type#DEPTH} or {@link Type#DEPTH_STENCIL} + */ + public final void detachRenderbuffer(GL gl, Attachment.Type atype) throws IllegalArgumentException { + detachRenderbufferImpl(gl, atype, false); + } + + public final boolean isDepthStencilPackedFormat() { + final boolean res = null != depth && null != stencil && + depth.format == stencil.format ; + if(res && depth.getName() != stencil.getName() ) { + throw new InternalError("depth/stencil packed format not sharing: depth "+depth+", stencil "+stencil); + } + return res; + } + + private final void detachRenderbufferImpl(GL gl, Attachment.Type atype, boolean recreate) throws IllegalArgumentException { + switch ( atype ) { + case DEPTH: + case STENCIL: + case DEPTH_STENCIL: + break; + default: + throw new IllegalArgumentException("only depth/stencil types allowed, was "+atype+", "+this); + } + if( null == depth && null == stencil ) { + return ; // nop + } + // reduction of possible combinations, create unique atype command(s) + final ArrayListLeaves the FBO bound!
+ *+ * An attached sampling sink texture will be detached as well, see {@link #getSamplingSink()}. + *
+ * @param gl the current GL context + */ + public final void detachAll(GL gl) { + if(null != samplesSink) { + samplesSink.detachAll(gl); + } + detachAllImpl(gl, true/* detachNonColorbuffer */, false /* recreate */); + } + + /** + * Detaches all {@link ColorAttachment}s and {@link TextureAttachment}s. + *Leaves the FBO bound!
+ *+ * An attached sampling sink texture will be detached as well, see {@link #getSamplingSink()}. + *
+ * @param gl the current GL context + */ + public final void detachAllColorbuffer(GL gl) { + if(null != samplesSink) { + samplesSink.detachAllColorbuffer(gl); + } + detachAllImpl(gl, false/* detachNonColorbuffer */, false /* recreate */); + } + + /** + * Detaches all {@link TextureAttachment}s + *Leaves the FBO bound!
+ *+ * An attached sampling sink texture will be detached as well, see {@link #getSamplingSink()}. + *
+ * @param gl the current GL context + */ + public final void detachAllTexturebuffer(GL gl) { + if(null != samplesSink) { + samplesSink.detachAllTexturebuffer(gl); + } + for(int i=0; iIf multisampling is used, it sets the read framebuffer to the sampling sink {@link #getWriteFramebuffer()}, + * if full FBO is supported.
+ * + *+ * In case you have attached more than one color buffer, + * you may want to setup {@link GL2GL3#glDrawBuffers(int, int[], int)}. + *
+ * @param gl the current GL context + * @throws GLException + */ + public final void bind(GL gl) throws GLException { + if(!bound || fbName != gl.getBoundFramebuffer(GL.GL_FRAMEBUFFER)) { + checkInitialized(); + if(samples > 0 && fullFBOSupport) { + // draw to multisampling - read from samplesSink + gl.glBindFramebuffer(GL2GL3.GL_DRAW_FRAMEBUFFER, getWriteFramebuffer()); + gl.glBindFramebuffer(GL2GL3.GL_READ_FRAMEBUFFER, getReadFramebuffer()); + } else { + // one for all + gl.glBindFramebuffer(GL.GL_FRAMEBUFFER, getWriteFramebuffer()); + } + + checkNoError(null, gl.glGetError(), "FBObject post-bind"); // throws GLException if error + bound = true; + samplesSinkDirty = true; + } + } + + /** + * Unbind this FBO, i.e. bind read and write framebuffer to default, see {@link GLBase#getDefaultDrawFramebuffer()}. + * + *If full FBO is supported, sets the read and write framebuffer individually to default, hence not disturbing + * an optional operating MSAA FBO, see {@link GLBase#getDefaultReadFramebuffer()} and {@link GLBase#getDefaultDrawFramebuffer()}
+ * + * @param gl the current GL context + * @throws GLException + */ + public final void unbind(GL gl) throws GLException { + if(bound) { + if(fullFBOSupport) { + // default read/draw buffers, may utilize GLContext/GLDrawable override of + // GLContext.getDefaultDrawFramebuffer() and GLContext.getDefaultReadFramebuffer() + gl.glBindFramebuffer(GL2GL3.GL_DRAW_FRAMEBUFFER, 0); + gl.glBindFramebuffer(GL2GL3.GL_READ_FRAMEBUFFER, 0); + } else { + gl.glBindFramebuffer(GL.GL_FRAMEBUFFER, 0); // default draw buffer + } + checkNoError(null, gl.glGetError(), "FBObject post-unbind"); // throws GLException if error + bound = false; + } + } + + /** + * Returnstrue
if framebuffer object is bound via {@link #bind(GL)}, otherwise false
.
+ * + * Method verifies the bound state via {@link GL#getBoundFramebuffer(int)}. + *
+ * @param gl the current GL context + */ + public final boolean isBound(GL gl) { + bound = bound && fbName != gl.getBoundFramebuffer(GL.GL_FRAMEBUFFER) ; + return bound; + } + + /** Returnstrue
if framebuffer object is bound via {@link #bind(GL)}, otherwise false
. */
+ public final boolean isBound() { return bound; }
+
+ /**
+ * Samples the multisampling colorbuffer (msaa-buffer) to it's sink {@link #getSamplingSink()}.
+ *
+ * The operation is skipped, if no multisampling is used or + * the msaa-buffer has not been flagged dirty by a previous call of {@link #bind(GL)}, + * see {@link #isSamplingBufferDirty()}
+ * + *If full FBO is supported, sets the read and write framebuffer individually to default after sampling, hence not disturbing + * an optional operating MSAA FBO, see {@link GLBase#getDefaultReadFramebuffer()} and {@link GLBase#getDefaultDrawFramebuffer()}
+ * + *In case you intend to employ {@link GL#glReadPixels(int, int, int, int, int, int, java.nio.Buffer) glReadPixels(..)} + * you may want to call {@link GL#glBindFramebuffer(int, int) glBindFramebuffer}({@link GL2GL3#GL_READ_FRAMEBUFFER}, {@link #getReadFramebuffer()}); + *
+ * + *Leaves the FBO unbound.
+ * + * @param gl the current GL context + * @param ta {@link TextureAttachment} to use, prev. attached w/ {@link #attachTexture2D(GL, int, boolean, int, int, int, int) attachTexture2D(..)} + * @throws IllegalArgumentException + */ + public final void syncSamplingBuffer(GL gl) { + unbind(gl); + if(samples>0 && samplesSinkDirty) { + samplesSinkDirty = false; + resetMSAATexture2DSink(gl); + gl.glBindFramebuffer(GL2GL3.GL_READ_FRAMEBUFFER, fbName); + gl.glBindFramebuffer(GL2GL3.GL_DRAW_FRAMEBUFFER, samplesSink.getWriteFramebuffer()); + ((GL2GL3)gl).glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, // since MSAA is supported, ugly cast is OK + GL.GL_COLOR_BUFFER_BIT, GL.GL_NEAREST); + if(fullFBOSupport) { + // default read/draw buffers, may utilize GLContext/GLDrawable override of + // GLContext.getDefaultDrawFramebuffer() and GLContext.getDefaultReadFramebuffer() + gl.glBindFramebuffer(GL2GL3.GL_DRAW_FRAMEBUFFER, 0); + gl.glBindFramebuffer(GL2GL3.GL_READ_FRAMEBUFFER, 0); + } else { + gl.glBindFramebuffer(GL.GL_FRAMEBUFFER, 0); // default draw buffer + } + } + } + + /** + * Bind the given texture colorbuffer. + * + *If multisampling is being used, {@link #syncSamplingBuffer(GL)} is being called.
+ * + *Leaves the FBO unbound!
+ * + * @param gl the current GL context + * @param ta {@link TextureAttachment} to use, prev. attached w/ {@link #attachTexture2D(GL, int, boolean, int, int, int, int) attachTexture2D(..)} + * @throws IllegalArgumentException + */ + public final void use(GL gl, TextureAttachment ta) throws IllegalArgumentException { + if(null == ta) { throw new IllegalArgumentException("null TextureAttachment"); } + if(samples > 0 && samplesSinkTexture == ta) { + syncSamplingBuffer(gl); + } else { + unbind(gl); + } + gl.glBindTexture(GL.GL_TEXTURE_2D, ta.getName()); // use it .. + } + + /** + * Unbind texture, ie bind 'non' texture 0 + * + *Leaves the FBO unbound.
+ */ + public final void unuse(GL gl) { + unbind(gl); + gl.glBindTexture(GL.GL_TEXTURE_2D, 0); // don't use it + } + + /** + * Returnstrue
if basic or full FBO is supported, otherwise false
.
+ * @param full true
for full FBO supported query, otherwise false
for basic FBO support query.
+ * @see #supportsFullFBO(GL)
+ * @see #supportsBasicFBO(GL)
+ * @throws GLException if {@link #init(GL)} hasn't been called.
+ */
+ public final boolean supportsFBO(boolean full) throws GLException { checkInitialized(); return full ? fullFBOSupport : basicFBOSupport; }
+
+ /**
+ * Returns true
if renderbuffer accepts internal format {@link GL#GL_RGB8} and {@link GL#GL_RGBA8}, otherwise false
.
+ * @throws GLException if {@link #init(GL)} hasn't been called.
+ */
+ public final boolean supportsRGBA8() throws GLException { checkInitialized(); return rgba8Avail; }
+
+ /**
+ * Returns true
if {@link GL#GL_DEPTH_COMPONENT16}, {@link GL#GL_DEPTH_COMPONENT24} or {@link GL#GL_DEPTH_COMPONENT32} is supported, otherwise false
.
+ * @param bits 16, 24 or 32 bits
+ * @throws GLException if {@link #init(GL)} hasn't been called.
+ */
+ public final boolean supportsDepth(int bits) throws GLException {
+ checkInitialized();
+ switch(bits) {
+ case 16: return basicFBOSupport;
+ case 24: return depth24Avail;
+ case 32: return depth32Avail;
+ default: return false;
+ }
+ }
+
+ /**
+ * Returns true
if {@link GL#GL_STENCIL_INDEX1}, {@link GL#GL_STENCIL_INDEX4}, {@link GL#GL_STENCIL_INDEX8} or {@link GL2GL3#GL_STENCIL_INDEX16} is supported, otherwise false
.
+ * @param bits 1, 4, 8 or 16 bits
+ * @throws GLException if {@link #init(GL)} hasn't been called.
+ */
+ public final boolean supportsStencil(int bits) throws GLException {
+ checkInitialized();
+ switch(bits) {
+ case 1: return stencil01Avail;
+ case 4: return stencil04Avail;
+ case 8: return stencil08Avail;
+ case 16: return stencil16Avail;
+ default: return false;
+ }
+ }
+
+ /**
+ * Returns true
if {@link GL#GL_DEPTH24_STENCIL8} is supported, otherwise false
.
+ * @throws GLException if {@link #init(GL)} hasn't been called.
+ */
+ public final boolean supportsPackedDepthStencil() throws GLException { checkInitialized(); return packedDepthStencilAvail; }
+
+ /**
+ * Returns the maximum number of colorbuffer attachments.
+ * @throws GLException if {@link #init(GL)} hasn't been called.
+ */
+ public final int getMaxColorAttachments() throws GLException { checkInitialized(); return maxColorAttachments; }
+
+ /**
+ * Returns the maximum number of samples for multisampling. Maybe zero if multisampling is not supported.
+ * @throws GLException if {@link #init(GL)} hasn't been called.
+ */
+ public final int getMaxSamples() throws GLException { checkInitialized(); return maxSamples; }
+
+ /**
+ * Returns true
if this instance has been initialized with {@link #reset(GL, int, int)}
+ * or {@link #reset(GL, int, int, int)}, otherwise false
+ */
+ public final boolean isInitialized() { return initialized; }
+ /** Returns the width */
+ public final int getWidth() { return width; }
+ /** Returns the height */
+ public final int getHeight() { return height; }
+ /** Returns the number of samples for multisampling (MSAA). zero if no multisampling is used. */
+ public final int getNumSamples() { return samples; }
+ /** Returns the framebuffer name to render to. */
+ public final int getWriteFramebuffer() { return fbName; }
+ /** Returns the framebuffer name to read from. Depending on multisampling, this may be a different framebuffer. */
+ public final int getReadFramebuffer() { return ( samples > 0 ) ? samplesSink.getReadFramebuffer() : fbName; }
+ /** Return the number of color/texture attachments */
+ public final int getColorAttachmentCount() { return colorAttachmentCount; }
+ /** Return the stencil {@link RenderAttachment} attachment, if exist. Maybe share the same {@link Attachment#getName()} as {@link #getDepthAttachment()}, if packed depth-stencil is being used. */
+ public final RenderAttachment getStencilAttachment() { return stencil; }
+ /** Return the depth {@link RenderAttachment} attachment. Maybe share the same {@link Attachment#getName()} as {@link #getStencilAttachment()}, if packed depth-stencil is being used. */
+ public final RenderAttachment getDepthAttachment() { return depth; }
+
+ /** Return the complete multisampling {@link FBObject} sink, if using multisampling. */
+ public final FBObject getSamplingSinkFBO() { return samplesSink; }
+
+ /** Return the multisampling {@link TextureAttachment} sink, if using multisampling. */
+ public final TextureAttachment getSamplingSink() { return samplesSinkTexture; }
+ /**
+ * Returns true
if the multisampling colorbuffer (msaa-buffer)
+ * has been flagged dirty by a previous call of {@link #bind(GL)},
+ * otherwise false
.
+ */
+ public final boolean isSamplingBufferDirty() { return samplesSinkDirty; }
+
+ int objectHashCode() { return super.hashCode(); }
+
+ public final String toString() {
+ final String caps = null != colorAttachmentPoints ? Arrays.asList(colorAttachmentPoints).toString() : null ;
+ return "FBO[name r/w "+fbName+"/"+getReadFramebuffer()+", init "+initialized+", bound "+bound+", size "+width+"x"+height+", samples "+samples+"/"+maxSamples+
+ ", depth "+depth+", stencil "+stencil+", color attachments: "+colorAttachmentCount+"/"+maxColorAttachments+
+ ": "+caps+", msaa-sink "+samplesSinkTexture+", isSamplesSink "+(null == samplesSink)+
+ ", obj 0x"+Integer.toHexString(objectHashCode())+"]";
+ }
+
+ private final void updateStatus(GL gl) {
+ if( 0 == fbName ) {
+ vStatus = -1;
+ } else {
+ vStatus = gl.glCheckFramebufferStatus(GL.GL_FRAMEBUFFER);
+ }
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/GLExtensions.java b/src/jogl/classes/com/jogamp/opengl/GLExtensions.java
new file mode 100644
index 000000000..f7e25fa01
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/GLExtensions.java
@@ -0,0 +1,81 @@
+/**
+ * Copyright 2012 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+package com.jogamp.opengl;
+
+/**
+ * Class holding OpenGL extension strings, commonly used by JOGL's implementation.
+ */
+public class GLExtensions {
+ public static final String VERSION_1_2 = "GL_VERSION_1_2";
+ public static final String VERSION_1_4 = "GL_VERSION_1_4";
+ public static final String VERSION_1_5 = "GL_VERSION_1_5";
+ public static final String VERSION_2_0 = "GL_VERSION_2_0";
+
+ public static final String ARB_debug_output = "GL_ARB_debug_output";
+ public static final String AMD_debug_output = "GL_AMD_debug_output";
+
+ public static final String ARB_framebuffer_object = "GL_ARB_framebuffer_object";
+ public static final String OES_framebuffer_object = "GL_OES_framebuffer_object";
+ public static final String EXT_framebuffer_object = "GL_EXT_framebuffer_object";
+ public static final String EXT_framebuffer_blit = "GL_EXT_framebuffer_blit";
+ public static final String EXT_framebuffer_multisample = "GL_EXT_framebuffer_multisample";
+ public static final String EXT_packed_depth_stencil = "GL_EXT_packed_depth_stencil";
+ public static final String OES_depth24 = "GL_OES_depth24";
+ public static final String OES_depth32 = "GL_OES_depth32";
+ public static final String OES_packed_depth_stencil = "GL_OES_packed_depth_stencil";
+ public static final String NV_fbo_color_attachments = "GL_NV_fbo_color_attachments";
+
+ public static final String ARB_ES2_compatibility = "GL_ARB_ES2_compatibility";
+
+ public static final String EXT_abgr = "GL_EXT_abgr";
+ public static final String OES_rgb8_rgba8 = "GL_OES_rgb8_rgba8";
+ public static final String OES_stencil1 = "GL_OES_stencil1";
+ public static final String OES_stencil4 = "GL_OES_stencil4";
+ public static final String OES_stencil8 = "GL_OES_stencil8";
+ public static final String APPLE_float_pixels = "GL_APPLE_float_pixels";
+
+ public static final String ARB_texture_non_power_of_two = "GL_ARB_texture_non_power_of_two";
+ public static final String ARB_texture_rectangle = "GL_ARB_texture_rectangle";
+ public static final String EXT_texture_rectangle = "GL_EXT_texture_rectangle";
+ public static final String NV_texture_rectangle = "GL_NV_texture_rectangle";
+ public static final String EXT_texture_format_BGRA8888 = "GL_EXT_texture_format_BGRA8888";
+ public static final String IMG_texture_format_BGRA8888 = "GL_IMG_texture_format_BGRA8888";
+ public static final String EXT_texture_compression_s3tc = "GL_EXT_texture_compression_s3tc";
+ public static final String NV_texture_compression_vtc = "GL_NV_texture_compression_vtc";
+ public static final String SGIS_generate_mipmap = "GL_SGIS_generate_mipmap";
+ public static final String OES_read_format = "GL_OES_read_format";
+
+ public static final String OES_EGL_image_external = "GL_OES_EGL_image_external";
+
+ //
+ // Aliased GLX/WGL/.. extensions
+ //
+
+ public static final String ARB_pixel_format = "GL_ARB_pixel_format";
+ public static final String ARB_pbuffer = "GL_ARB_pbuffer";
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/JoglVersion.java b/src/jogl/classes/com/jogamp/opengl/JoglVersion.java
index 75785fd86..cdb4b82bb 100644
--- a/src/jogl/classes/com/jogamp/opengl/JoglVersion.java
+++ b/src/jogl/classes/com/jogamp/opengl/JoglVersion.java
@@ -93,11 +93,13 @@ public class JoglVersion extends JogampVersion {
return sb;
}
- public static StringBuilder getDefaultOpenGLInfo(StringBuilder sb, boolean withCapabilitiesInfo) {
+ public static StringBuilder getDefaultOpenGLInfo(AbstractGraphicsDevice device, StringBuilder sb, boolean withCapabilitiesInfo) {
if(null==sb) {
sb = new StringBuilder();
}
- final AbstractGraphicsDevice device = GLProfile.getDefaultDevice();
+ if(null == device) {
+ device = GLProfile.getDefaultDevice();
+ }
sb.append("Default Profiles on device ").append(device).append(Platform.getNewline());
if(null!=device) {
GLProfile.glAvailabilityToString(device, sb, "\t", 1);
@@ -120,13 +122,21 @@ public class JoglVersion extends JogampVersion {
if(null==sb) {
sb = new StringBuilder();
}
- GLContext ctx = gl.getContext();
-
+
sb.append(VersionUtil.SEPERATOR).append(Platform.getNewline());
sb.append(device.getClass().getSimpleName()).append("[type ")
.append(device.getType()).append(", connection ").append(device.getConnection()).append("]: ").append(Platform.getNewline());
GLProfile.glAvailabilityToString(device, sb, "\t", 1);
sb.append(Platform.getNewline());
+
+ return getGLStrings(gl, sb);
+ }
+
+ public static StringBuilder getGLStrings(GL gl, StringBuilder sb) {
+ if(null==sb) {
+ sb = new StringBuilder();
+ }
+ final GLContext ctx = gl.getContext();
sb.append("Swap Interval ").append(gl.getSwapInterval());
sb.append(Platform.getNewline());
sb.append("GL Profile ").append(gl.getGLProfile());
diff --git a/src/jogl/classes/com/jogamp/opengl/OffscreenAutoDrawable.java b/src/jogl/classes/com/jogamp/opengl/OffscreenAutoDrawable.java
new file mode 100644
index 000000000..1ea8595c6
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/OffscreenAutoDrawable.java
@@ -0,0 +1,89 @@
+/**
+ * Copyright 2012 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package com.jogamp.opengl;
+
+import javax.media.opengl.GLAutoDrawableDelegate;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLDrawable;
+import javax.media.opengl.GLException;
+
+import jogamp.opengl.GLFBODrawableImpl;
+
+/**
+ * Platform-independent class exposing FBO offscreen functionality to
+ * applications.
+ * + * This class distinguishes itself from {@link GLAutoDrawableDelegate} + * with it's {@link #setSize(int, int)} functionality. + *
+ */ +public class OffscreenAutoDrawable extends GLAutoDrawableDelegate { + + public OffscreenAutoDrawable(GLDrawable drawable, GLContext context, Object upstreamWidget) { + super(drawable, context, upstreamWidget); + } + + /** + * Attempts to resize this offscreen auto drawable, if supported + * by the underlying {@link GLDrawable). + * @param newWidth + * @param newHeight + * @returntrue
if resize was executed, otherwise false
.
+ * @throws GLException in case of an error during the resize operation
+ */
+ public boolean setSize(int newWidth, int newHeight) throws GLException {
+ boolean done = false;
+ if(drawable instanceof GLFBODrawableImpl) {
+ context.makeCurrent();
+ try {
+ ((GLFBODrawableImpl)drawable).setSize(context.getGL(), newWidth, newHeight);
+ done = true;
+ } finally {
+ context.release();
+ }
+ }
+ if(done) {
+ this.defaultWindowResizedOp();
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * If the underlying {@link GLDrawable} is an FBO implementation
+ * and contains an {#link FBObject}, the same is returned.
+ * Otherwise returns null
.
+ */
+ public FBObject getFBObject() {
+ if(drawable instanceof GLFBODrawableImpl) {
+ return ((GLFBODrawableImpl)drawable).getFBObject();
+ }
+ return null;
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java b/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java
index 5ee58b78d..0d9d3ddf5 100644
--- a/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java
+++ b/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java
@@ -231,6 +231,8 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
/* Get the nativewindow-Graphics Device associated with this control (which is determined by the parent Composite) */
device = SWTAccessor.getDevice(this);
+ /* Since we have no means of querying the screen index yet, assume 0. Good choice due to Xinerama alike settings anyways. */
+ final int screenIdx = 0;
/* Native handle for the control, used to associate with GLContext */
nativeWindowHandle = SWTAccessor.getWindowHandle(this);
@@ -243,7 +245,7 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
final GLDrawableFactory glFactory = GLDrawableFactory.getFactory(caps.getGLProfile());
/* Create a NativeWindow proxy for the SWT canvas */
- proxySurface = glFactory.createProxySurface(device, nativeWindowHandle, caps, chooser);
+ proxySurface = glFactory.createProxySurface(device, screenIdx, nativeWindowHandle, caps, chooser, swtCanvasUpStreamHook);
/* Associate a GL surface with the proxy */
drawable = glFactory.createGLDrawable(proxySurface);
@@ -265,12 +267,58 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
addControlListener(new ControlAdapter() {
@Override
public void controlResized(final ControlEvent arg0) {
- clientArea = GLCanvas.this.getClientArea();
- /* Mark for OpenGL reshape next time the control is painted */
- sendReshape = true;
+ updateSizeCheck();
}
});
}
+ private final ProxySurface.UpstreamSurfaceHook swtCanvasUpStreamHook = new ProxySurface.UpstreamSurfaceHook() {
+ @Override
+ public final void create(ProxySurface s) { /* nop */ }
+
+ @Override
+ public final void destroy(ProxySurface s) { /* nop */ }
+
+ @Override
+ public final int getWidth(ProxySurface s) {
+ return clientArea.width;
+ }
+
+ @Override
+ public final int getHeight(ProxySurface s) {
+ return clientArea.height;
+ }
+
+ @Override
+ public String toString() {
+ return "SETUpstreamSurfaceHook[upstream: "+GLCanvas.this.toString()+"]";
+ }
+
+ };
+
+ protected final void updateSizeCheck() {
+ clientArea = GLCanvas.this.getClientArea();
+ if (clientArea != null &&
+ proxySurface.getWidth() != clientArea.width &&
+ proxySurface.getHeight() != clientArea.height) {
+ sendReshape = true; // Mark for OpenGL reshape next time the control is painted
+ }
+ sendReshape = false;
+ }
+
+ @Override
+ public final Object getUpstreamWidget() {
+ return this;
+ }
+
+ @Override
+ public int getWidth() {
+ return clientArea.width;
+ }
+
+ @Override
+ public int getHeight() {
+ return clientArea.height;
+ }
@Override
public void addGLEventListener(final GLEventListener arg0) {
@@ -417,25 +465,11 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
return (drawable != null) ? drawable.getHandle() : 0;
}
- @Override
- public int getHeight() {
- final Rectangle clientArea = this.clientArea;
- if (clientArea == null) return 0;
- return clientArea.height;
- }
-
@Override
public NativeSurface getNativeSurface() {
return (drawable != null) ? drawable.getNativeSurface() : null;
}
- @Override
- public int getWidth() {
- final Rectangle clientArea = this.clientArea;
- if (clientArea == null) return 0;
- return clientArea.width;
- }
-
@Override
public boolean isRealized() {
return (drawable != null) ? drawable.isRealized() : false;
@@ -515,7 +549,7 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
// System.err.println(NativeWindowVersion.getInstance());
System.err.println(JoglVersion.getInstance());
- System.err.println(JoglVersion.getDefaultOpenGLInfo(null, true).toString());
+ System.err.println(JoglVersion.getDefaultOpenGLInfo(null, null, true).toString());
final GLCapabilitiesImmutable caps = new GLCapabilities( GLProfile.getDefault(GLProfile.getDefaultDevice()) );
final Display display = new Display();
diff --git a/src/jogl/classes/com/jogamp/opengl/util/FBObject.java b/src/jogl/classes/com/jogamp/opengl/util/FBObject.java
deleted file mode 100644
index 3e049a334..000000000
--- a/src/jogl/classes/com/jogamp/opengl/util/FBObject.java
+++ /dev/null
@@ -1,483 +0,0 @@
-/*
- * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
- * Copyright (c) 2011 JogAmp Community. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * - Redistribution of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistribution in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * Neither the name of Sun Microsystems, Inc. or the names of
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * This software is provided "AS IS," without a warranty of any kind. ALL
- * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
- * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
- * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
- * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
- * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
- * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
- * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
- * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
- * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
- * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
- * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
- *
- */
-
-package com.jogamp.opengl.util;
-
-import javax.media.opengl.*;
-
-public class FBObject {
- static final int MAX_FBO_TEXTURES = 32; // just for our impl .. not the real 'max' FBO color attachments
- private int[] fbo_tex_names;
- private int[] fbo_tex_units;
- private int fbo_tex_num;
- private int colorattachment_num;
-
- private boolean initialized;
- private int width, height;
- private int fb, depth_rb, stencil_rb, vStatus;
- private boolean bound;
-
- public FBObject(int width, int height) {
- this.fbo_tex_names = new int[MAX_FBO_TEXTURES];
- this.fbo_tex_units = new int[MAX_FBO_TEXTURES];
- this.fbo_tex_num = 0;
- this.colorattachment_num = 0;
- this.initialized = false;
- this.width = width;
- this.height = height;
- this.fb = 0;
- this.depth_rb = 0;
- this.stencil_rb = 0;
- this.bound = false;
- }
-
- /**
- * @return true if the FB status is valid, otherwise false
- * @see #getStatus()
- */
- public boolean isStatusValid() {
- switch(vStatus) {
- case GL.GL_FRAMEBUFFER_COMPLETE:
- return true;
- case GL.GL_FRAMEBUFFER_UNSUPPORTED:
- case GL.GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
- case GL.GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
- case GL.GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
- case GL.GL_FRAMEBUFFER_INCOMPLETE_FORMATS:
- //case GL2.GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
- //case GL2.GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
- //case GL2.GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT:
- case 0:
- default:
- System.out.println("Framebuffer " + fb + " is incomplete: status = 0x" + Integer.toHexString(vStatus) +
- " : " + getStatusString(vStatus));
- return false;
- }
- }
-
- /**
- * @return The FB status. {@link GL.GL_FRAMEBUFFER_COMPLETE} if ok, otherwise return GL FBO error state or -1
- * @see #validateStatus()
- */
- public int getStatus() {
- return vStatus;
- }
-
- public String getStatusString() {
- return getStatusString(vStatus);
- }
-
- public static final String getStatusString(int fbStatus) {
- switch(fbStatus) {
- case -1:
- return "NOT A FBO";
- case GL.GL_FRAMEBUFFER_COMPLETE:
- return "OK";
- case GL.GL_FRAMEBUFFER_UNSUPPORTED:
- return("GL FBO: Unsupported framebuffer format");
- case GL.GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
- return("GL FBO: incomplete, incomplete attachment\n");
- case GL.GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
- return("GL FBO: incomplete, missing attachment");
- case GL.GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
- return("GL FBO: incomplete, attached images must have same dimensions");
- case GL.GL_FRAMEBUFFER_INCOMPLETE_FORMATS:
- return("GL FBO: incomplete, attached images must have same format");
- case GL2.GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
- return("GL FBO: incomplete, missing draw buffer");
- case GL2.GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
- return("GL FBO: incomplete, missing read buffer");
- case GL2.GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
- return("GL FBO: incomplete, missing multisample buffer");
- case 0:
- return("GL FBO: incomplete, implementation fault");
- default:
- return("GL FBO: incomplete, implementation ERROR");
- }
- }
-
- private boolean checkNoError(GL gl, int err, String exceptionMessage) {
- if(GL.GL_NO_ERROR != err) {
- if(null != gl) {
- destroy(gl);
- }
- if(null != exceptionMessage) {
- throw new GLException(exceptionMessage+" GL Error 0x"+Integer.toHexString(err));
- }
- return false;
- }
- return true;
- }
-
- private final void checkInitialized() {
- if(!initialized) {
- throw new GLException("FBO not initialized, call init(GL) first.");
- }
- }
-
- private final void checkBound(GL gl, boolean shallBeBound) {
- checkInitialized();
- if(bound != shallBeBound) {
- final String s0 = shallBeBound ? "not" : "already" ;
- throw new GLException("FBO "+s0+" bound "+toString());
- }
- checkNoError(null, gl.glGetError(), "FBObject pre"); // throws GLException if error
- }
-
- /**
- * Initializes this FBO's instance with it's texture.
- *
- * Leaves the FBO bound!
- * - * @param gl the current GL context - * @throws GLException in case of an error - */ - public void init(GL gl) throws GLException { - if(initialized) { - throw new GLException("FBO already initialized"); - } - checkNoError(null, gl.glGetError(), "FBObject Init.pre"); // throws GLException if error - - // generate fbo .. - int name[] = new int[1]; - - gl.glGenFramebuffers(1, name, 0); - fb = name[0]; - if(fb==0) { - throw new GLException("null generated framebuffer"); - } - - // bind fbo .. - gl.glBindFramebuffer(GL.GL_FRAMEBUFFER, fb); - checkNoError(gl, gl.glGetError(), "FBObject Init.bindFB"); // throws GLException if error - if(!gl.glIsFramebuffer(fb)) { - checkNoError(gl, GL.GL_INVALID_VALUE, "FBObject Init.isFB"); // throws GLException - } - bound = true; - initialized = true; - - updateStatus(gl); - } - - /** - * Attaches a[nother] Texture2D Color Buffer to this FBO's instance, - * selecting the texture data type and format automatically. - *This may be done as many times as many color attachments are supported, - * see {@link GL2GL3#GL_MAX_COLOR_ATTACHMENTS}.
- * - *Assumes a bound FBO
- *Leaves the FBO bound!
- * - * @param gl the current GL context - * @param texUnit the desired texture unit ranging from [0..{@link GL2#GL_MAX_TEXTURE_UNITS}-1], or -1 if no unit shall be activate at {@link #use(GL, int)} - * @param magFilter if > 0 value for {@link GL#GL_TEXTURE_MAG_FILTER} - * @param minFilter if > 0 value for {@link GL#GL_TEXTURE_MIN_FILTER} - * @param wrapS if > 0 value for {@link GL#GL_TEXTURE_WRAP_S} - * @param wrapT if > 0 value for {@link GL#GL_TEXTURE_WRAP_T} - * @return idx of the new attached texture, otherwise -1 - * @throws GLException in case of an error - */ - public int attachTexture2D(GL gl, int texUnit, int magFilter, int minFilter, int wrapS, int wrapT) throws GLException { - final int textureInternalFormat, textureDataFormat, textureDataType; - if(gl.isGLES()) { - textureInternalFormat=GL.GL_RGBA; - textureDataFormat=GL.GL_RGBA; - textureDataType=GL.GL_UNSIGNED_BYTE; - } else { - textureInternalFormat=GL.GL_RGBA8; - textureDataFormat=GL.GL_BGRA; - textureDataType=GL2GL3.GL_UNSIGNED_INT_8_8_8_8_REV; - } - return attachTexture2D(gl, texUnit, textureInternalFormat, textureDataFormat, textureDataType, magFilter, minFilter, wrapS, wrapT); - } - - /** - * Attaches a[nother] Texture2D Color Buffer to this FBO's instance, - * selecting the texture data type and format automatically. - *This may be done as many times as many color attachments are supported, - * see {@link GL2GL3#GL_MAX_COLOR_ATTACHMENTS}.
- * - *Assumes a bound FBO
- *Leaves the FBO bound!
- * - * @param gl the current GL context - * @param texUnit the desired texture unit ranging from [0..{@link GL2#GL_MAX_TEXTURE_UNITS}-1], or -1 if no unit shall be activate at {@link #use(GL, int)} - * @param textureInternalFormat internalFormat parameter to {@link GL#glTexImage2D(int, int, int, int, int, int, int, int, long)} - * @param textureDataFormat format parameter to {@link GL#glTexImage2D(int, int, int, int, int, int, int, int, long)} - * @param textureDataType type parameter to {@link GL#glTexImage2D(int, int, int, int, int, int, int, int, long)} - * @param magFilter if > 0 value for {@link GL#GL_TEXTURE_MAG_FILTER} - * @param minFilter if > 0 value for {@link GL#GL_TEXTURE_MIN_FILTER} - * @param wrapS if > 0 value for {@link GL#GL_TEXTURE_WRAP_S} - * @param wrapT if > 0 value for {@link GL#GL_TEXTURE_WRAP_T} - * @return index of the texture colorbuffer if bound and configured successfully, otherwise -1 - * @throws GLException in case the texture colorbuffer couldn't be allocated - */ - public int attachTexture2D(GL gl, int texUnit, - int textureInternalFormat, int textureDataFormat, int textureDataType, - int magFilter, int minFilter, int wrapS, int wrapT) throws GLException { - checkBound(gl, true); - final int fbo_tex_idx = fbo_tex_num; - gl.glGenTextures(1, fbo_tex_names, fbo_tex_num); - if(fbo_tex_names[fbo_tex_idx]==0) { - throw new GLException("null generated texture"); - } - fbo_tex_units[fbo_tex_idx] = texUnit; - fbo_tex_num++; - if(0<=texUnit) { - gl.glActiveTexture(GL.GL_TEXTURE0 + texUnit); - } - gl.glBindTexture(GL.GL_TEXTURE_2D, fbo_tex_names[fbo_tex_idx]); - checkNoError(gl, gl.glGetError(), "FBObject Init.bindTex"); // throws GLException if error - gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, textureInternalFormat, width, height, 0, - textureDataFormat, textureDataType, null); - int glerr = gl.glGetError(); - if(GL.GL_NO_ERROR != glerr) { - int[] sz = new int[1]; - gl.glGetIntegerv(GL.GL_MAX_TEXTURE_SIZE, sz, 0); - // throws GLException if error - checkNoError(gl, glerr, "FBObject Init.texImage2D: "+ - " int-fmt 0x"+Integer.toHexString(textureInternalFormat)+ - ", "+width+"x"+height+ - ", data-fmt 0x"+Integer.toHexString(textureDataFormat)+ - ", data-type 0x"+Integer.toHexString(textureDataType)+ - ", max tex-sz "+sz[0]); - } - if( 0 < magFilter ) { - gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, magFilter); - } - if( 0 < minFilter ) { - gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, minFilter); - } - if( 0 < wrapS ) { - gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, wrapS); - } - if( 0 < wrapT ) { - gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, wrapT); - } - - // Set up the color buffer for use as a renderable texture: - gl.glFramebufferTexture2D(GL.GL_FRAMEBUFFER, - GL.GL_COLOR_ATTACHMENT0 + colorattachment_num++, - GL.GL_TEXTURE_2D, fbo_tex_names[fbo_tex_idx], 0); - - updateStatus(gl); - return isStatusValid() ? fbo_tex_idx : -1; - } - - /** - * Attaches one Depth Buffer to this FBO's instance. - *This may be done only one time.
- * - *Assumes a bound FBO
- *Leaves the FBO bound!
- * @param gl the current GL context - * @param depthComponentType {@link GL#GL_DEPTH_COMPONENT16}, {@link GL#GL_DEPTH_COMPONENT24} or {@link GL#GL_DEPTH_COMPONENT32} - * @return true if the depth renderbuffer could be bound and configured, otherwise false - * @throws GLException in case the depth renderbuffer couldn't be allocated or one is already attached. - */ - public boolean attachDepthBuffer(GL gl, int depthComponentType) throws GLException { - checkBound(gl, true); - if(depth_rb != 0) { - throw new GLException("FBO depth buffer already attached (rb "+depth_rb+")"); - } - int name[] = new int[1]; - gl.glGenRenderbuffers(1, name, 0); - depth_rb = name[0]; - if(depth_rb==0) { - throw new GLException("null generated renderbuffer"); - } - // Initialize the depth buffer: - gl.glBindRenderbuffer(GL.GL_RENDERBUFFER, depth_rb); - if(!gl.glIsRenderbuffer(depth_rb)) { - System.err.println("not a depthbuffer: "+ depth_rb); - name[0] = depth_rb; - gl.glDeleteRenderbuffers(1, name, 0); - depth_rb=0; - return false; - } - - gl.glRenderbufferStorage(GL.GL_RENDERBUFFER, depthComponentType, width, height); - // Set up the depth buffer attachment: - gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, - GL.GL_DEPTH_ATTACHMENT, - GL.GL_RENDERBUFFER, depth_rb); - updateStatus(gl); - return isStatusValid(); - } - - /** - * Attaches one Stencil Buffer to this FBO's instance. - *This may be done only one time.
- * - *Assumes a bound FBO
- *Leaves the FBO bound!
- * @param gl the current GL context - * @param stencilComponentType {@link GL#GL_STENCIL_INDEX1}, {@link GL#GL_STENCIL_INDEX4} or {@link GL#GL_STENCIL_INDEX8} - * @return true if the stencil renderbuffer could be bound and configured, otherwise false - * @throws GLException in case the stencil renderbuffer couldn't be allocated or one is already attached. - */ - public boolean attachStencilBuffer(GL gl, int stencilComponentType) throws GLException { - checkBound(gl, true); - if(stencil_rb != 0) { - throw new GLException("FBO stencil buffer already attached (rb "+stencil_rb+")"); - } - int name[] = new int[1]; - gl.glGenRenderbuffers(1, name, 0); - stencil_rb = name[0]; - if(stencil_rb==0) { - throw new GLException("null generated stencilbuffer"); - } - // Initialize the stencil buffer: - gl.glBindRenderbuffer(GL.GL_RENDERBUFFER, stencil_rb); - if(!gl.glIsRenderbuffer(stencil_rb)) { - System.err.println("not a stencilbuffer: "+ stencil_rb); - name[0] = stencil_rb; - gl.glDeleteRenderbuffers(1, name, 0); - stencil_rb=0; - return false; - } - gl.glRenderbufferStorage(GL.GL_RENDERBUFFER, stencilComponentType, width, height); - gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, - GL.GL_STENCIL_ATTACHMENT, - GL.GL_RENDERBUFFER, stencil_rb); - updateStatus(gl); - return isStatusValid(); - } - - /** - * @param gl the current GL context - */ - public void destroy(GL gl) { - if(bound) { - unbind(gl); - } - - int name[] = new int[1]; - - if(0!=stencil_rb) { - name[0] = stencil_rb; - gl.glDeleteRenderbuffers(1, name, 0); - stencil_rb = 0; - } - if(0!=depth_rb) { - name[0] = depth_rb; - gl.glDeleteRenderbuffers(1, name, 0); - depth_rb=0; - } - if(null!=fbo_tex_names && fbo_tex_num>0) { - gl.glDeleteTextures(1, fbo_tex_names, fbo_tex_num); - fbo_tex_names = new int[MAX_FBO_TEXTURES]; - fbo_tex_units = new int[MAX_FBO_TEXTURES]; - fbo_tex_num = 0; - } - colorattachment_num = 0; - if(0!=fb) { - name[0] = fb; - gl.glDeleteFramebuffers(1, name, 0); - fb = 0; - } - initialized = false; - } - - /** - * Bind this FBO - *In case you have attached more than one color buffer, - * you may want to setup {@link GL2GL3#glDrawBuffers(int, int[], int)}.
- * @param gl the current GL context - */ - public void bind(GL gl) { - checkBound(gl, false); - gl.glBindFramebuffer(GL.GL_FRAMEBUFFER, fb); - bound = true; - } - - /** - * Unbind FBO, ie bind 'non' FBO 0 - * @param gl the current GL context - */ - public void unbind(GL gl) { - checkBound(gl, true); - gl.glBindFramebuffer(GL.GL_FRAMEBUFFER, 0); - bound = false; - } - - /** - * Bind the texture with given index. - * - *If a valid texture unit was named via {@link #attachTexture2D(GL, int, int, int, int, int) attachTexture2D(..)}, - * the unit is activated via {@link GL#glActiveTexture(int) glActiveTexture(GL.GL_TEXTURE0 + unit)}.
- * @param gl the current GL context - * @param texIdx index of the texture to use, prev. attached w/ {@link #attachTexture2D(GL, int, int, int, int, int) attachTexture2D(..)} - */ - public void use(GL gl, int texIdx) { - checkBound(gl, false); - if(texIdx >= fbo_tex_num) { - throw new GLException("Invalid texId, only "+fbo_tex_num+" textures are attached"); - } - if(0<=fbo_tex_units[texIdx]) { - gl.glActiveTexture(GL.GL_TEXTURE0 + fbo_tex_units[texIdx]); - } - gl.glBindTexture(GL.GL_TEXTURE_2D, fbo_tex_names[texIdx]); // use it .. - } - - /** Unbind texture, ie bind 'non' texture 0 */ - public void unuse(GL gl) { - checkBound(gl, false); - gl.glBindTexture(GL.GL_TEXTURE_2D, 0); // don't use it - } - - public final boolean isBound() { return bound; } - public final int getWidth() { return width; } - public final int getHeight() { return height; } - public final int getFBName() { return fb; } - public final int getTextureNumber() { return fbo_tex_num; } - public final int getTextureName(int idx) { return fbo_tex_names[idx]; } - - /** @return the named texture unit ranging from [0..{@link GL2#GL_MAX_TEXTURE_UNITS}-1], or -1 if no unit was desired. */ - public final int getTextureUnit(int idx) { return fbo_tex_units[idx]; } - public final int getColorAttachmentNumber() { return colorattachment_num; } - public final int getStencilBuffer() { return stencil_rb; } - public final int getDepthBuffer() { return depth_rb; } - public final String toString() { - return "FBO[name "+fb+", size "+width+"x"+height+", color num "+colorattachment_num+", tex num "+fbo_tex_num+", depth "+depth_rb+", stencil "+stencil_rb+"]"; - } - - private void updateStatus(GL gl) { - if(!gl.glIsFramebuffer(fb)) { - vStatus = -1; - } else { - vStatus = gl.glCheckFramebufferStatus(GL.GL_FRAMEBUFFER); - } - } -} diff --git a/src/jogl/classes/com/jogamp/opengl/util/GLBuffers.java b/src/jogl/classes/com/jogamp/opengl/util/GLBuffers.java index 8401b9cd2..331d6fa4e 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/GLBuffers.java +++ b/src/jogl/classes/com/jogamp/opengl/util/GLBuffers.java @@ -39,6 +39,7 @@ package com.jogamp.opengl.util; import com.jogamp.common.nio.Buffers; + import javax.media.opengl.GL; import javax.media.opengl.GL2; import javax.media.opengl.GL2ES2; @@ -56,22 +57,32 @@ import java.nio.*; public class GLBuffers extends Buffers { /** - * @param glType shall be one of - * GL_UNSIGNED_BYTE, GL_BYTE, GL_UNSIGNED_SHORT, GL_SHORT, - * GL_UNSIGNED_INT, GL_INT, GL_HALF_FLOAT, GL_FLOAT, GL_DOUBLE, - * GL_UNSIGNED_BYTE_3_3_2, GL_UNSIGNED_BYTE_2_3_3_REV, - * GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_SHORT_5_6_5_REV, - * GL_UNSIGNED_SHORT_4_4_4_4, GL_UNSIGNED_SHORT_4_4_4_4_REV, - * GL_UNSIGNED_SHORT_5_5_5_1, GL_UNSIGNED_SHORT_1_5_5_5_REV, - * GL_UNSIGNED_INT_8_8_8_8, GL_UNSIGNED_INT_8_8_8_8_REV, - * GL_UNSIGNED_INT_10_10_10_2, GL_UNSIGNED_INT_2_10_10_10_REV - * GL_UNSIGNED_INT_24_8, GL_UNSIGNED_INT_10F_11F_11F_REV, - * GL_UNSIGNED_INT_5_9_9_9_REV, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, - * GL_HILO16_NV, GL_SIGNED_HILO16_NV (27) + * @param glType shall be one of (29)- + based rendering mechanism as well by end users directly. +
The implementation shall initialize itself as soon as possible, ie if the attached {@link javax.media.nativewindow.NativeSurface NativeSurface} becomes visible/realized. The following protocol shall be satisfied: @@ -64,18 +64,18 @@ import jogamp.opengl.Debug; registered {@link GLEventListener}s. This can be done immediatly, or with the followup {@link #display display(..)} call.
- +
+
Another implementation detail is the drawable reconfiguration. One use case is where a window is being
dragged to another screen with a different pixel configuration, ie {@link GLCapabilities}. The implementation
- shall be able to detect such cases in conjunction with the associated {@link javax.media.nativewindow.NativeSurface NativeSurface}.
+ shall be able to detect such cases in conjunction with the associated {@link javax.media.nativewindow.NativeSurface NativeSurface}.
For example, AWT's {@link java.awt.Canvas} 's {@link java.awt.Canvas#getGraphicsConfiguration getGraphicsConfiguration()}
is capable to determine a display device change. This is demonstrated within {@link javax.media.opengl.awt.GLCanvas}'s
and NEWT's AWTCanvas
{@link javax.media.opengl.awt.GLCanvas#getGraphicsConfiguration getGraphicsConfiguration()}
specialization. Another demonstration is NEWT's {@link javax.media.nativewindow.NativeWindow NativeWindow}
- implementation on the Windows platform, which utilizes the native platform's MonitorFromWindow(HWND) function.
+ implementation on the Windows platform, which utilizes the native platform's MonitorFromWindow(HWND) function.
All OpenGL resources shall be regenerated, while the drawable's {@link GLCapabilities} has
- to be choosen again. The following protocol shall be satisfied.
+ to be chosen again. The following protocol shall be satisfied.
- - However, to not introduce to much breakage with older applications and because of the situation + and make your application comply with the above protocol. +
+ Avoiding breakage with older applications and because of the situation
mentioned above, the boolean
system property jogl.screenchange.action
will control the
- screen change action as follows:
-
+ screen change action as follows:
-Djogl.screenchange.action=false Disable the drawable reconfiguration (the default) -Djogl.screenchange.action=true Enable the drawable reconfiguration+ */ public interface GLAutoDrawable extends GLDrawable { /** Flag reflecting wheather the drawable reconfiguration will be issued in @@ -362,5 +362,29 @@ public interface GLAutoDrawable extends GLDrawable { demos for examples. @return the set GL pipeline or null if not successful */ public GL setGL(GL gl); + + /** + * Method may return the upstream UI toolkit object + * holding this {@link GLAutoDrawable} instance, if exist. + *
+ * Currently known Java UI toolkits and it's known return types are: + * + *
Toolkit | GLAutoDrawable Implementation | ~ | Return Type of getUpstreamWidget() | + *
NEWT | {@link com.jogamp.newt.opengl.GLWindow} | has a | {@link com.jogamp.newt.Window} | + *
SWT | {@link com.jogamp.opengl.swt.GLCanvas} | is a | {@link org.eclipse.swt.widgets.Canvas} | + *
AWT | {@link javax.media.opengl.awt.GLCanvas} | is a | {@link java.awt.Canvas} | + *
AWT | {@link javax.media.opengl.awt.GLJPanel} | is a | {@link javax.swing.JPanel} | + *
+ * This method may also return null
if no UI toolkit is being used,
+ * as common for offscreen rendering.
+ *
diff --git a/src/jogl/classes/javax/media/opengl/GLBase.java b/src/jogl/classes/javax/media/opengl/GLBase.java
index bd24b15bc..f5831a72d 100644
--- a/src/jogl/classes/javax/media/opengl/GLBase.java
+++ b/src/jogl/classes/javax/media/opengl/GLBase.java
@@ -340,5 +340,60 @@ public interface GLBase {
* completeness.
*/
public Object getExtension(String extensionName);
+
+ /** Aliased entrypoint of void {@native glClearDepth}(GLclampd depth);
and void {@native glClearDepthf}(GLclampf depth);
. */
+ public void glClearDepth( double depth );
+
+ /** Aliased entrypoint of void {@native glDepthRange}(GLclampd depth);
and void {@native glDepthRangef}(GLclampf depth);
. */
+ public void glDepthRange(double zNear, double zFar);
+
+ /**
+ * @param target a GL buffer (VBO) target as used in {@link GL#glBindBuffer(int, int)}, ie {@link GL#GL_ELEMENT_ARRAY_BUFFER}, {@link GL#GL_ARRAY_BUFFER}, ..
+ * @return the GL buffer (VBO) name bound to a target via {@link GL#glBindBuffer(int, int)} or 0 if unbound.
+ */
+ public int glGetBoundBuffer(int target);
+
+ /**
+ * @param buffer a GL buffer name, generated with {@link GL#glGenBuffers(int, int[], int)} and used in {@link GL#glBindBuffer(int, int)}, {@link GL#glBufferData(int, long, java.nio.Buffer, int)} or {@link GL2#glNamedBufferDataEXT(int, long, java.nio.Buffer, int)} for example.
+ * @return the size of the given GL buffer
+ */
+ public long glGetBufferSize(int buffer);
+
+ /**
+ * @return true if a VBO is bound to {@link GL.GL_ARRAY_BUFFER} via {@link GL#glBindBuffer(int, int)}, otherwise false
+ */
+ public boolean glIsVBOArrayEnabled();
+
+ /**
+ * @return true if a VBO is bound to {@link GL.GL_ELEMENT_ARRAY_BUFFER} via {@link GL#glBindBuffer(int, int)}, otherwise false
+ */
+ public boolean glIsVBOElementArrayEnabled();
+
+ /**
+ * Return the framebuffer name bound to this context,
+ * see {@link GL#glBindFramebuffer(int, int)}.
+ */
+ public int getBoundFramebuffer(int target);
+
+ /**
+ * Return the default draw framebuffer name.
+ *
+ * May differ from it's default zero
+ * in case an framebuffer object ({@link FBObject}) based drawable
+ * is being used.
+ *
+ * May differ from it's default zero
+ * in case an framebuffer object ({@link FBObject}) based drawable
+ * is being used.
+ *
- * If enabled this method also invokes {@link #setOnscreen(int) setOnscreen(false)}
- * and {@link #setFBO(int) setFBO(false)}
+ * If enabled this method also invokes {@link #setOnscreen(int) setOnscreen(false)}.
*
- * If enabled this method also invokes {@link #setOnscreen(int) setOnscreen(false)}
- * and {@link #setPBuffer(int) setPBuffer(false)}
+ * If enabled this method also invokes {@link #setOnscreen(int) setOnscreen(false)}.
*
true
(default), bootstrapping the available GL profiles
* will use the highest compatible GL context for each profile,
@@ -120,13 +122,13 @@ public abstract class GLContext {
protected static final int CTX_PROFILE_ES = 1 << 3;
/** ARB_create_context
related: flag forward compatible. Cache key value. See {@link #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)}. */
protected static final int CTX_OPTION_FORWARD = 1 << 4;
- /** ARB_create_context
related: flag debug. Not a cache key. See {@link #setContextCreationFlags(int)}, {@link GLAutoDrawable#setContextCreationFlags(int)}, {@link #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)}. */
+ /** ARB_create_context
related: flag debug. Cache key value. See {@link #setContextCreationFlags(int)}, {@link GLAutoDrawable#setContextCreationFlags(int)}, {@link #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)}. */
public static final int CTX_OPTION_DEBUG = 1 << 5;
/** GL_ARB_ES2_compatibility
implementation related: Context is compatible w/ ES2. Not a cache key. See {@link #isGLES2Compatible()}, {@link #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)}. */
protected static final int CTX_IMPL_ES2_COMPAT = 1 << 8;
- /** Context supports FBO, details see {@link #hasFBO()}.
+ /** Context supports basic FBO, details see {@link #hasFBO()}.
* Not a cache key.
* @see #hasFBO()
* @see #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)
@@ -136,16 +138,6 @@ public abstract class GLContext {
/** Context uses software rasterizer, otherwise hardware rasterizer. Cache key value. See {@link #isHardwareRasterizer()}, {@link #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)}. */
protected static final int CTX_IMPL_ACCEL_SOFT = 1 << 15;
- protected static final String GL_ARB_ES2_compatibility = "GL_ARB_ES2_compatibility";
- protected static final String GL_ARB_framebuffer_object = "GL_ARB_framebuffer_object";
- protected static final String GL_EXT_framebuffer_object = "GL_EXT_framebuffer_object";
- protected static final String GL_EXT_framebuffer_blit = "GL_EXT_framebuffer_blit";
- protected static final String GL_EXT_framebuffer_multisample = "GL_EXT_framebuffer_multisample";
- protected static final String GL_EXT_packed_depth_stencil = "GL_EXT_packed_depth_stencil";
- protected static final String GL_ARB_texture_non_power_of_two = "GL_ARB_texture_non_power_of_two";
- protected static final String GL_EXT_texture_format_BGRA8888 = "GL_EXT_texture_format_BGRA8888";
- protected static final String GL_IMG_texture_format_BGRA8888 = "GL_IMG_texture_format_BGRA8888";
-
private static final ThreadLocalGL_ARB_ES2_compatibility
, ARB_framebuffer_object
or all of
- * EXT_framebuffer_object
, EXT_framebuffer_multisample
,
- * EXT_framebuffer_blit
, GL_EXT_packed_depth_stencil
.
+ /**
+ * Returns true
if basic FBO support is available, otherwise false
.
+ *
+ * Basic FBO is supported if the context is either GL-ES >= 2.0, GL >= core 3.0 or implements the extensions
+ * GL_ARB_ES2_compatibility
, GL_ARB_framebuffer_object
, GL_EXT_framebuffer_object
or GL_OES_framebuffer_object
.
+ *
+ * Basic FBO support may only include one color attachment and no multisampling, + * as well as limited internal formats for renderbuffer. + *
* @see #CTX_IMPL_FBO + * @see com.jogamp.opengl.FBObject#supportsBasicFBO(GL) + * @see com.jogamp.opengl.FBObject#supportsFullFBO(GL) */ public final boolean hasFBO() { return 0 != ( ctxOptions & CTX_IMPL_FBO ) ; @@ -659,13 +659,13 @@ public abstract class GLContext { /** Note: The GL impl. may return a const value, ie {@link GLES2#isNPOTTextureAvailable()} always returnstrue
. */
public boolean isNPOTTextureAvailable() {
- return isGL3() || isGLES2Compatible() || isExtensionAvailable(GL_ARB_texture_non_power_of_two);
+ return isGL3() || isGLES2Compatible() || isExtensionAvailable(GLExtensions.ARB_texture_non_power_of_two);
}
public boolean isTextureFormatBGRA8888Available() {
return isGL2GL3() ||
- isExtensionAvailable(GL_EXT_texture_format_BGRA8888) ||
- isExtensionAvailable(GL_IMG_texture_format_BGRA8888) ;
+ isExtensionAvailable(GLExtensions.EXT_texture_format_BGRA8888) ||
+ isExtensionAvailable(GLExtensions.IMG_texture_format_BGRA8888) ;
}
/** @see GLProfile#isGL4bc() */
@@ -798,7 +798,32 @@ public abstract class GLContext {
}
protected boolean bindSwapBarrierImpl(int group, int barrier) { /** nop per default .. **/ return false; }
-
+ /**
+ * Return the framebuffer name bound to this context,
+ * see {@link GL#glBindFramebuffer(int, int)}.
+ */
+ public abstract int getBoundFramebuffer(int target);
+
+ /**
+ * Return the default draw framebuffer name.
+ *
+ * May differ from it's default zero
+ * in case an framebuffer object ({@link FBObject}) based drawable
+ * is being used.
+ *
+ * May differ from it's default zero
+ * in case an framebuffer object ({@link FBObject}) based drawable
+ * is being used.
+ *
+ * FBO feature is implemented in OpenGL, hence it is {@link GLProfile} dependent. + *
+ *+ * FBO support is queried as described in {@link #hasFBO()}. + *
+ * + * @param device the device to request whether FBO is available for + * @param glp {@link GLProfile} to check for FBO capabilities + * @see GLContext#hasFBO() + */ + public static final boolean isFBOAvailable(AbstractGraphicsDevice device, GLProfile glp) { + return 0 != ( CTX_IMPL_FBO & getAvailableContextProperties(device, glp) ); + } + /** * @param device the device to request whether the profile is available for * @param reqMajor Key Value either 1, 2, 3 or 4 diff --git a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java index d6480e7aa..612a02f14 100644 --- a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java +++ b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java @@ -50,9 +50,11 @@ import com.jogamp.common.JogampRuntimeException; import com.jogamp.common.util.ReflectionUtil; import javax.media.nativewindow.AbstractGraphicsDevice; +import javax.media.nativewindow.AbstractGraphicsScreen; import javax.media.nativewindow.NativeSurface; import javax.media.nativewindow.NativeWindowFactory; import javax.media.nativewindow.ProxySurface; +import javax.media.nativewindow.ProxySurface.UpstreamSurfaceHook; import javax.media.opengl.GLProfile.ShutdownType; import jogamp.opengl.Debug; @@ -398,9 +400,18 @@ public abstract class GLDrawableFactory { /** * Creates a Offscreen GLDrawable incl it's offscreen {@link javax.media.nativewindow.NativeSurface} with the given capabilites and dimensions. *
- * A Pbuffer drawable/surface is created if both {@link javax.media.opengl.GLCapabilities#isPBuffer() caps.isPBuffer()}
- * and {@link #canCreateGLPbuffer(javax.media.nativewindow.AbstractGraphicsDevice) canCreateGLPbuffer(device)} is true.
- * Otherwise a simple pixmap/bitmap drawable/surface is created, which is unlikely to be hardware accelerated.
+ * It's {@link AbstractGraphicsConfiguration} is properly set according to the given {@link GLCapabilitiesImmutable}, see below.
+ *
+ * A FBO drawable is created if both {@link javax.media.opengl.GLCapabilities#isFBO() caps.isFBO()} + * and {@link GLContext#isFBOAvailable(AbstractGraphicsDevice, GLProfile) canCreateFBO(device, caps.getGLProfile())} is true. + *
+ *+ * A Pbuffer drawable is created if both {@link javax.media.opengl.GLCapabilities#isPBuffer() caps.isPBuffer()} + * and {@link #canCreateGLPbuffer(javax.media.nativewindow.AbstractGraphicsDevice) canCreateGLPbuffer(device)} is true. + *
+ *+ * If neither FBO nor Pbuffer is available, a simple pixmap/bitmap drawable/surface is created, which is unlikely to be hardware accelerated. *
* * @param device which {@link javax.media.nativewindow.AbstractGraphicsDevice#getConnection() connection} denotes the shared device to be used, may benull
for the platform's default device.
@@ -421,42 +432,31 @@ public abstract class GLDrawableFactory {
throws GLException;
/**
- * Creates an offscreen NativeSurface.null
for the platform's default device.
- * @param caps the requested GLCapabilties
- * @param chooser the custom chooser, may be null for default
- * @param width the requested offscreen width
- * @param height the requested offscreen height
- * @return the created offscreen native surface
- *
- * @throws GLException if any window system-specific errors caused
- * the creation of the GLDrawable to fail.
- */
- public abstract NativeSurface createOffscreenSurface(AbstractGraphicsDevice device,
- GLCapabilitiesImmutable caps,
- GLCapabilitiesChooser chooser,
- int width, int height);
-
- /**
- * Highly experimental API entry, allowing developer of new windowing system bindings
- * to leverage the native window handle to produce a NativeSurface implementation (ProxySurface), having the required GLCapabilities.+ * It's {@link AbstractGraphicsConfiguration} is properly set according to the given {@link GLCapabilitiesImmutable}. + *
+ *+ * Lifecycle (destruction) of the given surface handle shall be handled by the caller. + *
+ *+ * Such surface can be used to instantiate a GLDrawable. With the help of {@link GLAutoDrawableDelegate} + * you will be able to implement a new native windowing system binding almost on-the-fly, see {@link com.jogamp.opengl.swt.GLCanvas}. + *
* - * @param device the platform's target device, shall not benull
+ * @param device which {@link javax.media.nativewindow.AbstractGraphicsDevice#getConnection() connection} denotes the shared the target device, may be null
for the platform's default device.
+ * Caller has to ensure it is compatible w/ the given windowHandle
+ * @param screenIdx matching screen index of given windowHandle
* @param windowHandle the native window handle
* @param caps the requested GLCapabilties
* @param chooser the custom chooser, may be null for default
- * @return The proxy surface wrapping the windowHandle on the device
+ * @param upstream optional {@link ProxySurface.UpstreamSurfaceHook} allowing control of the {@link ProxySurface}'s lifecycle and data it presents.
+ * @return the created {@link ProxySurface} instance w/ defined surface handle.
*/
- public abstract ProxySurface createProxySurface(AbstractGraphicsDevice device,
+ public abstract ProxySurface createProxySurface(AbstractGraphicsDevice device,
+ int screenIdx,
long windowHandle,
- GLCapabilitiesImmutable caps,
- GLCapabilitiesChooser chooser);
+ GLCapabilitiesImmutable caps, GLCapabilitiesChooser chooser, UpstreamSurfaceHook upstream);
/**
* Returns true if it is possible to create a GLPbuffer. Some older
@@ -492,23 +492,7 @@ public abstract class GLDrawableFactory {
GLContext shareWith)
throws GLException;
- /**
- * Returns true if it is possible to create an framebuffer object (FBO).
- * - * FBO feature is implemented in OpenGL, hence it is {@link GLProfile} dependent. - *
- *- * FBO support is queried as described in {@link GLContext#hasFBO()}. - *
- * - * @param device which {@link javax.media.nativewindow.AbstractGraphicsDevice#getConnection() connection} denotes the shared the target device, may benull
for the platform's default device.
- * @param glp {@link GLProfile} to check for FBO capabilities
- * @see GLContext#hasFBO()
- */
- public final boolean canCreateFBO(AbstractGraphicsDevice device, GLProfile glp) {
- return 0 != ( GLContext.CTX_IMPL_FBO & GLContext.getAvailableContextProperties(device, glp) );
- }
-
+
//----------------------------------------------------------------------
// Methods for interacting with third-party OpenGL libraries
diff --git a/src/jogl/classes/javax/media/opengl/GLProfile.java b/src/jogl/classes/javax/media/opengl/GLProfile.java
index a7200b560..73d13a387 100644
--- a/src/jogl/classes/javax/media/opengl/GLProfile.java
+++ b/src/jogl/classes/javax/media/opengl/GLProfile.java
@@ -117,10 +117,12 @@ public class GLProfile {
* @deprecated Use {@link #initSingleton()}. This method is subject to be removed in future versions of JOGL.
*/
public static void initSingleton(final boolean firstUIActionOnProcess) {
+ final boolean justInitialized;
initLock.lock();
try {
if(!initialized) { // volatile: ok
initialized = true;
+ justInitialized = true;
if(DEBUG) {
System.err.println("GLProfile.initSingleton(firstUIActionOnProcess: "+firstUIActionOnProcess+") - thread "+Thread.currentThread().getName());
Thread.dumpStack();
@@ -166,10 +168,17 @@ public class GLProfile {
return null;
}
});
+ } else {
+ justInitialized = false;
}
} finally {
initLock.unlock();
}
+ if(DEBUG) {
+ if( justInitialized && ( hasGL234Impl || hasGLES1Impl || hasGLES2Impl ) ) {
+ System.err.println(JoglVersion.getDefaultOpenGLInfo(defaultDevice, null, true));
+ }
+ }
}
/**
@@ -1532,18 +1541,17 @@ public class GLProfile {
if(DEBUG) {
// System.err.println("GLProfile.init addedAnyProfile "+addedAnyProfile+" (desktop: "+addedDesktopProfile+", egl "+addedEGLProfile+")");
- System.err.println("GLProfile.init addedAnyProfile "+addedAnyProfile);
- System.err.println("GLProfile.init isAWTAvailable "+isAWTAvailable);
- System.err.println("GLProfile.init hasDesktopGLFactory "+hasDesktopGLFactory);
- System.err.println("GLProfile.init hasGL234Impl "+hasGL234Impl);
- System.err.println("GLProfile.init hasEGLFactory "+hasEGLFactory);
- System.err.println("GLProfile.init hasGLES1Impl "+hasGLES1Impl);
- System.err.println("GLProfile.init hasGLES2Impl "+hasGLES2Impl);
- System.err.println("GLProfile.init defaultDevice "+defaultDevice);
- System.err.println("GLProfile.init profile order "+array2String(GL_PROFILE_LIST_ALL));
- if(hasGL234Impl || hasGLES1Impl || hasGLES2Impl) { // avoid deadlock
- System.err.println(JoglVersion.getDefaultOpenGLInfo(null, true));
- }
+ System.err.println("GLProfile.init addedAnyProfile "+addedAnyProfile);
+ System.err.println("GLProfile.init isAWTAvailable "+isAWTAvailable);
+ System.err.println("GLProfile.init hasDesktopGLFactory "+hasDesktopGLFactory);
+ System.err.println("GLProfile.init hasGL234Impl "+hasGL234Impl);
+ System.err.println("GLProfile.init hasEGLFactory "+hasEGLFactory);
+ System.err.println("GLProfile.init hasGLES1Impl "+hasGLES1Impl);
+ System.err.println("GLProfile.init hasGLES2Impl "+hasGLES2Impl);
+ System.err.println("GLProfile.init defaultDevice "+defaultDevice);
+ System.err.println("GLProfile.init defaultDevice Desktop "+defaultDesktopDevice);
+ System.err.println("GLProfile.init defaultDevice EGL "+defaultEGLDevice);
+ System.err.println("GLProfile.init profile order "+array2String(GL_PROFILE_LIST_ALL));
}
}
@@ -1642,24 +1650,6 @@ public class GLProfile {
if (DEBUG) {
System.err.println("GLProfile.initProfilesForDevice: "+device+": egl Shared Ctx "+eglSharedCtxAvail);
}
- if( hasGLES2Impl ) {
- // The native ES2 impl. overwrites a previous mapping using 'ES2 compatibility' by a desktop profile
- GLContext.mapAvailableGLVersion(device,
- 2, GLContext.CTX_PROFILE_ES,
- 2, 0, GLContext.CTX_PROFILE_ES|GLContext.CTX_IMPL_ES2_COMPAT);
- if (DEBUG) {
- System.err.println(GLContext.getThreadName() + ": initProfilesForDeviceCritical-MapVersionsAvailable HAVE: ES2 -> ES 2.0");
- }
- }
- if( hasGLES1Impl ) {
- // Always favor the native ES1 impl.
- GLContext.mapAvailableGLVersion(device,
- 1, GLContext.CTX_PROFILE_ES,
- 1, 0, GLContext.CTX_PROFILE_ES);
- if (DEBUG) {
- System.err.println(GLContext.getThreadName() + ": initProfilesForDeviceCritical-MapVersionsAvailable HAVE: ES1 -> ES 1.0");
- }
- }
addedEGLProfile = computeProfileMap(device, false /* desktopCtxUndef*/, false /* esCtxUndef */);
}
@@ -1767,7 +1757,7 @@ public class GLProfile {
}
_mappedProfiles.put(profile, glProfile);
if (DEBUG) {
- System.err.println("GLProfile.init map "+glProfile+" on devide "+device.getConnection());
+ System.err.println("GLProfile.init map "+glProfile+" on device "+device.getConnection());
}
if(null==defaultGLProfileHW && isHardwareRasterizer[0]) {
defaultGLProfileHW=glProfile;
diff --git a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
index 48f7ea24a..c2e36ef9b 100644
--- a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
+++ b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
@@ -261,6 +261,11 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
this.device = device;
}
+ @Override
+ public final Object getUpstreamWidget() {
+ return this;
+ }
+
@Override
public void setShallUseOffscreenLayer(boolean v) {
shallUseOffscreenLayer = v;
@@ -1070,7 +1075,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
// System.err.println(NativeWindowVersion.getInstance());
System.err.println(JoglVersion.getInstance());
- System.err.println(JoglVersion.getDefaultOpenGLInfo(null, true).toString());
+ System.err.println(JoglVersion.getDefaultOpenGLInfo(null, null, true).toString());
final GLCapabilitiesImmutable caps = new GLCapabilities( GLProfile.getDefault(GLProfile.getDefaultDevice()) );
final Frame frame = new Frame("JOGL AWT Test");
diff --git a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
index cd18c5098..acb8f2183 100644
--- a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
+++ b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
@@ -87,7 +87,7 @@ import jogamp.opengl.awt.Java2D;
import jogamp.opengl.awt.Java2DGLContext;
import com.jogamp.nativewindow.awt.AWTWindowClosingProtocol;
-import com.jogamp.opengl.util.FBObject;
+import com.jogamp.opengl.FBObject;
import com.jogamp.opengl.util.GLBuffers;
// FIXME: Subclasses need to call resetGLFunctionAvailability() on their
@@ -250,6 +250,11 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
this.shareWith = shareWith;
}
+ @Override
+ public final Object getUpstreamWidget() {
+ return this;
+ }
+
@Override
public void display() {
if (EventQueue.isDispatchThread()) {
diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PES2.java b/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PES2.java
index 804e9ee14..aabef29b0 100644
--- a/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PES2.java
+++ b/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PES2.java
@@ -32,7 +32,6 @@ import java.nio.FloatBuffer;
import javax.media.opengl.GL2ES2;
// FIXME: Subsume GL2GL3.GL_DRAW_FRAMEBUFFER -> GL2ES2.GL_DRAW_FRAMEBUFFER !
import javax.media.opengl.GL;
-import javax.media.opengl.GLException;
import javax.media.opengl.GLUniformData;
import javax.media.opengl.fixedfunc.GLMatrixFunc;
@@ -45,7 +44,9 @@ import com.jogamp.graph.geom.Vertex;
import com.jogamp.graph.curve.opengl.GLRegion;
import com.jogamp.graph.curve.opengl.RenderState;
-import com.jogamp.opengl.util.FBObject;
+import com.jogamp.opengl.FBObject;
+import com.jogamp.opengl.FBObject.Attachment;
+import com.jogamp.opengl.FBObject.TextureAttachment;
import com.jogamp.opengl.util.GLArrayDataServer;
import com.jogamp.opengl.util.PMVMatrix;
import com.jogamp.opengl.util.glsl.ShaderState;
@@ -60,6 +61,7 @@ public class VBORegion2PES2 extends GLRegion {
private FBObject fbo;
+ private TextureAttachment texA;
private PMVMatrix fboPMVMatrix;
GLUniformData mgl_fboPMVMatrix;
@@ -72,7 +74,7 @@ public class VBORegion2PES2 extends GLRegion {
super(renderModes);
fboPMVMatrix = new PMVMatrix();
mgl_fboPMVMatrix = new GLUniformData(UniformNames.gcu_PMVMatrix, 4, 4, fboPMVMatrix.glGetPMvMatrixf());
- mgl_ActiveTexture = new GLUniformData(UniformNames.gcu_TextureUnit, textureEngine);
+ mgl_ActiveTexture = new GLUniformData(UniformNames.gcu_TextureUnit, textureEngine);
}
public void update(GL2ES2 gl, RenderState rs) {
@@ -214,8 +216,9 @@ public class VBORegion2PES2 extends GLRegion {
final ShaderState st = rs.getShaderState();
gl.glViewport(0, 0, width, hight);
- st.uniform(gl, mgl_ActiveTexture);
- fbo.use(gl, 0);
+ st.uniform(gl, mgl_ActiveTexture);
+ gl.glActiveTexture(GL.GL_TEXTURE0 + mgl_ActiveTexture.intValue());
+ fbo.use(gl, texA);
verticeFboAttr.enableBuffer(gl, true);
texCoordFboAttr.enableBuffer(gl, true);
indicesFbo.enableBuffer(gl, true);
@@ -244,20 +247,16 @@ public class VBORegion2PES2 extends GLRegion {
// System.out.println("FBO Scale: " + m.glGetMatrixf().get(0) +" " + m.glGetMatrixf().get(5));
if(null != fbo && fbo.getWidth() != tex_width_c && fbo.getHeight() != tex_height_c ) {
- fbo.destroy(gl);
- fbo = null;
+ fbo.reset(gl, tex_width_c, tex_height_c);
}
- if(null == fbo) {
- fbo = new FBObject(tex_width_c, tex_height_c);
- fbo.init(gl);
+ if(null == fbo) {
+ fbo = new FBObject();
+ fbo.reset(gl, tex_width_c, tex_height_c);
// FIXME: shall not use bilinear, due to own AA ? However, w/o bilinear result is not smooth
- fbo.attachTexture2D(gl, mgl_ActiveTexture.intValue(), GL2ES2.GL_LINEAR, GL2ES2.GL_LINEAR, GL2ES2.GL_CLAMP_TO_EDGE, GL2ES2.GL_CLAMP_TO_EDGE);
- // fbo.attachTexture2D(gl, mgl_ActiveTexture.intValue(), GL2ES2.GL_NEAREST, GL2ES2.GL_NEAREST, GL2ES2.GL_CLAMP_TO_EDGE, GL2ES2.GL_CLAMP_TO_EDGE);
- fbo.attachDepthBuffer(gl, GL.GL_DEPTH_COMPONENT16); // FIXME: or shall we use 24 or 32 bit depth ?
- if(!fbo.isStatusValid()) {
- throw new GLException("FBO invalid: "+fbo);
- }
+ texA = fbo.attachTexture2D(gl, 0, true, GL2ES2.GL_LINEAR, GL2ES2.GL_LINEAR, GL2ES2.GL_CLAMP_TO_EDGE, GL2ES2.GL_CLAMP_TO_EDGE);
+ // texA = fbo.attachTexture2D(gl, 0, GL2ES2.GL_NEAREST, GL2ES2.GL_NEAREST, GL2ES2.GL_CLAMP_TO_EDGE, GL2ES2.GL_CLAMP_TO_EDGE);
+ fbo.attachRenderbuffer(gl, Attachment.Type.DEPTH, 24);
} else {
fbo.bind(gl);
}
@@ -305,6 +304,7 @@ public class VBORegion2PES2 extends GLRegion {
if(null != fbo) {
fbo.destroy(gl);
fbo = null;
+ texA = null;
}
if(null != verticeTxtAttr) {
st.ownAttribute(verticeTxtAttr, false);
diff --git a/src/jogl/classes/jogamp/opengl/GLContextImpl.java b/src/jogl/classes/jogamp/opengl/GLContextImpl.java
index 4dd8806fa..e730bc62e 100644
--- a/src/jogl/classes/jogamp/opengl/GLContextImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLContextImpl.java
@@ -49,8 +49,9 @@ import com.jogamp.common.os.DynamicLookupHelper;
import com.jogamp.common.util.ReflectionUtil;
import com.jogamp.gluegen.runtime.FunctionAddressResolver;
import com.jogamp.gluegen.runtime.ProcAddressTable;
-import com.jogamp.gluegen.runtime.opengl.GLExtensionNames;
+import com.jogamp.gluegen.runtime.opengl.GLNameResolver;
import com.jogamp.gluegen.runtime.opengl.GLProcAddressResolver;
+import com.jogamp.opengl.GLExtensions;
import javax.media.nativewindow.AbstractGraphicsConfiguration;
import javax.media.nativewindow.AbstractGraphicsDevice;
@@ -88,13 +89,14 @@ public abstract class GLContextImpl extends GLContext {
// Tracks creation and initialization of buffer objects to avoid
// repeated glGet calls upon glMapBuffer operations
private GLBufferSizeTracker bufferSizeTracker; // Singleton - Set by GLContextShareSet
- private GLBufferStateTracker bufferStateTracker = new GLBufferStateTracker();
- private GLStateTracker glStateTracker = new GLStateTracker();
+ private final GLBufferStateTracker bufferStateTracker = new GLBufferStateTracker();
+ private final GLStateTracker glStateTracker = new GLStateTracker();
private GLDebugMessageHandler glDebugHandler = null;
+ private final int[] boundFBOTarget = new int[] { 0, 0 }; // { draw, read }
protected GLDrawableImpl drawable;
protected GLDrawableImpl drawableRead;
-
+
protected GL gl;
protected static final Object mappedContextTypeObjectLock;
@@ -140,11 +142,11 @@ public abstract class GLContextImpl extends GLContext {
bufferSizeTracker.clearCachedBufferSizes();
}
- if (bufferStateTracker != null) {
+ if (bufferStateTracker != null) { // Invoked by {@link GL#glBindFramebuffer(int, int)}.
+ * + *Assumes valid framebufferName
range of [0..{@link Integer#MAX_VALUE}]
Does not throw an exception if target
is unknown or framebufferName
invalid.
device
{@link AbstractGraphicsDevice#getConnection()},
* either a preexisting or newly created, or null
if creation failed or not supported.1
refers to ES1 and 2
to ES2,
* otherwise the profile is ignored.
@@ -125,6 +126,7 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
//---------------------------------------------------------------------------
// Dispatching GLDrawable construction in respect to the NativeSurface Capabilities
//
+ @Override
public GLDrawable createGLDrawable(NativeSurface target) {
if (target == null) {
throw new IllegalArgumentException("Null target");
@@ -132,23 +134,37 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
final MutableGraphicsConfiguration config = (MutableGraphicsConfiguration) target.getGraphicsConfiguration();
final GLCapabilitiesImmutable chosenCaps = (GLCapabilitiesImmutable) config.getChosenCapabilities();
final AbstractGraphicsDevice adevice = config.getScreen().getDevice();
+ final boolean isFBOAvailable = GLContext.isFBOAvailable(adevice, chosenCaps.getGLProfile());
GLDrawable result = null;
adevice.lock();
try {
final OffscreenLayerSurface ols = NativeWindowFactory.getOffscreenLayerSurface(target, true);
if(null != ols) {
- // layered surface -> Offscreen/PBuffer
+ // layered surface -> Offscreen/[FBO|PBuffer]
final GLCapabilities chosenCapsMod = (GLCapabilities) chosenCaps.cloneMutable();
chosenCapsMod.setOnscreen(false);
- chosenCapsMod.setPBuffer(canCreateGLPbuffer(adevice));
+ if( isFBOAvailable ) {
+ chosenCapsMod.setFBO(true);
+ } else if(canCreateGLPbuffer(adevice)) {
+ chosenCapsMod.setPBuffer(true);
+ } else {
+ chosenCapsMod.setFBO(false);
+ chosenCapsMod.setPBuffer(false);
+ }
config.setChosenCapabilities(chosenCapsMod);
if(DEBUG) {
System.err.println("GLDrawableFactoryImpl.createGLDrawable -> OnscreenDrawable -> Offscreen-Layer: "+target);
}
- if( ! ( target instanceof SurfaceChangeable ) ) {
+ if( ! ( target instanceof MutableSurface ) ) {
throw new IllegalArgumentException("Passed NativeSurface must implement SurfaceChangeable for offscreen layered surface: "+target);
+ }
+ if( ((GLCapabilitiesImmutable)config.getRequestedCapabilities()).isFBO() && isFBOAvailable ) {
+ // FIXME JAU: Need to revise passed MutableSurface to work w/ FBO ..
+ final GLDrawableImpl dummyDrawable = createOnscreenDrawableImpl(target);
+ result = new GLFBODrawableImpl(this, dummyDrawable, target, target.getWidth(), target.getHeight(), 0 /* textureUnit */);
+ } else {
+ result = createOffscreenDrawableImpl(target);
}
- result = createOffscreenDrawableImpl(target);
} else if(chosenCaps.isOnscreen()) {
// onscreen
if(DEBUG) {
@@ -158,12 +174,18 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
} else {
// offscreen
if(DEBUG) {
- System.err.println("GLDrawableFactoryImpl.createGLDrawable -> OffScreenDrawable (PBuffer: "+chosenCaps.isPBuffer()+"): "+target);
+ System.err.println("GLDrawableFactoryImpl.createGLDrawable -> OffScreenDrawable, FBO-chosen(-avail)/PBuffer: "+chosenCaps.isFBO()+"("+isFBOAvailable+")/"+chosenCaps.isPBuffer()+": "+target);
}
- if( ! ( target instanceof SurfaceChangeable ) ) {
+ if( ! ( target instanceof MutableSurface ) ) {
throw new IllegalArgumentException("Passed NativeSurface must implement SurfaceChangeable for offscreen: "+target);
}
- result = createOffscreenDrawableImpl(target);
+ if( ((GLCapabilitiesImmutable)config.getRequestedCapabilities()).isFBO() && isFBOAvailable ) {
+ // FIXME JAU: Need to revise passed MutableSurface to work w/ FBO ..
+ final GLDrawableImpl dummyDrawable = createOnscreenDrawableImpl(target);
+ result = new GLFBODrawableImpl(this, dummyDrawable, target, target.getWidth(), target.getHeight(), 0 /* textureUnit */);
+ } else {
+ result = createOffscreenDrawableImpl(target);
+ }
}
} finally {
adevice.unlock();
@@ -176,43 +198,42 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
//---------------------------------------------------------------------------
//
- // Onscreen GLDrawable construction
+ // Onscreen GLDrawable construction
//
protected abstract GLDrawableImpl createOnscreenDrawableImpl(NativeSurface target);
//---------------------------------------------------------------------------
//
- // PBuffer Offscreen GLDrawable construction
+ // PBuffer Offscreen GLDrawable construction
//
-
+
+ @Override
public abstract boolean canCreateGLPbuffer(AbstractGraphicsDevice device);
+ @Override
public GLPbuffer createGLPbuffer(AbstractGraphicsDevice deviceReq,
GLCapabilitiesImmutable capsRequested,
GLCapabilitiesChooser chooser,
int width,
int height,
GLContext shareWith) {
- if(height<=0 || height<=0) {
- throw new GLException("Width and height of pbuffer must be positive (were (" +
- width + ", " + height + "))");
+ if(width<=0 || height<=0) {
+ throw new GLException("initial size must be positive (were (" + width + " x " + height + "))");
}
-
AbstractGraphicsDevice device = getOrCreateSharedDevice(deviceReq);
if(null == device) {
throw new GLException("No shared device for requested: "+deviceReq);
}
-
- if (!canCreateGLPbuffer(device)) {
- throw new GLException("Pbuffer support not available with device: "+device);
+ if ( !canCreateGLPbuffer(device) ) {
+ throw new GLException("Pbuffer not available with device: "+device);
}
-
- GLCapabilitiesImmutable capsChosen = GLGraphicsConfigurationUtil.fixGLPBufferGLCapabilities(capsRequested);
+
+ final GLCapabilitiesImmutable capsChosen = GLGraphicsConfigurationUtil.fixGLPBufferGLCapabilities(capsRequested);
GLDrawableImpl drawable = null;
device.lock();
try {
- drawable = (GLDrawableImpl) createGLDrawable( createOffscreenSurfaceImpl(device, capsChosen, capsRequested, chooser, width, height) );
+ drawable = (GLDrawableImpl) createGLDrawable( createMutableSurfaceImpl(device, true, capsChosen, capsRequested, chooser, width, height, null) );
if(null != drawable) {
drawable.setRealized(true);
}
@@ -228,75 +249,155 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
//---------------------------------------------------------------------------
//
- // Offscreen GLDrawable construction
+ // Offscreen GLDrawable construction
//
- protected abstract GLDrawableImpl createOffscreenDrawableImpl(NativeSurface target) ;
-
+ @Override
public GLDrawable createOffscreenDrawable(AbstractGraphicsDevice deviceReq,
GLCapabilitiesImmutable capsRequested,
GLCapabilitiesChooser chooser,
- int width,
- int height) {
+ int width, int height) {
if(width<=0 || height<=0) {
- throw new GLException("Width and height of pbuffer must be positive (were (" +
- width + ", " + height + "))");
+ throw new GLException("initial size must be positive (were (" + width + " x " + height + "))");
}
- AbstractGraphicsDevice device = getOrCreateSharedDevice(deviceReq);
+ final AbstractGraphicsDevice device = getOrCreateSharedDevice(deviceReq);
if(null == device) {
throw new GLException("No shared device for requested: "+deviceReq);
}
- GLCapabilitiesImmutable capsChosen = GLGraphicsConfigurationUtil.fixOffScreenGLCapabilities(capsRequested, canCreateGLPbuffer(deviceReq));
-
+
+ if( capsRequested.isFBO() && GLContext.isFBOAvailable(device, capsRequested.getGLProfile()) ) {
+ device.lock();
+ try {
+ return createFBODrawableImpl(device, capsRequested, chooser, width, height);
+ } finally {
+ device.unlock();
+ }
+ }
+
+ final GLCapabilitiesImmutable capsChosen = GLGraphicsConfigurationUtil.fixOffscreenGLCapabilities(capsRequested, false, canCreateGLPbuffer(device));
device.lock();
try {
- return createGLDrawable( createOffscreenSurfaceImpl(device, capsChosen, capsRequested, chooser, width, height) );
+ return createOffscreenDrawableImpl( createMutableSurfaceImpl(device, true, capsChosen, capsRequested, chooser, width, height, null) );
} finally {
device.unlock();
}
}
- public NativeSurface createOffscreenSurface(AbstractGraphicsDevice deviceReq,
- GLCapabilitiesImmutable capsRequested,
- GLCapabilitiesChooser chooser,
- int width, int height) {
- AbstractGraphicsDevice device = getOrCreateSharedDevice(deviceReq);
+ /** Creates a platform independent offscreen FBO GLDrawable implementation */
+ protected GLDrawable createFBODrawableImpl(AbstractGraphicsDevice device, GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser,
+ int initialWidth, int initialHeight) {
+ final GLCapabilitiesImmutable dummyCaps = GLGraphicsConfigurationUtil.fixOnscreenGLCapabilities(requestedCaps);
+ final NativeSurface dummySurface = createDummySurfaceImpl(device, true, dummyCaps, null, 64, 64);
+ final GLDrawableImpl dummyDrawable = createOnscreenDrawableImpl(dummySurface);
+
+ return new GLFBODrawableImpl(this, dummyDrawable, dummySurface, initialWidth, initialHeight, 0 /* textureUnit */);
+ }
+
+ /** Creates a platform dependent offscreen pbuffer/pixmap GLDrawable implementation */
+ protected abstract GLDrawableImpl createOffscreenDrawableImpl(NativeSurface target) ;
+
+ /**
+ * Creates a mutable {@link ProxySurface} w/o defined surface handle.
+ * + * It's {@link AbstractGraphicsConfiguration} is properly set according to the given {@link GLCapabilitiesImmutable}. + *
+ *+ * Lifecycle (destruction) of the TBD surface handle shall be handled by the caller. + *
+ * @param device a valid platform dependent target device. + * @param createNewDevice iftrue
a new device instance is created using device
details,
+ * otherwise device
instance is used as-is.
+ * @param capsChosen
+ * @param capsRequested
+ * @param chooser the custom chooser, may be null for default
+ * @param width the initial width
+ * @param height the initial height
+ * @param lifecycleHook optional control of the surface's lifecycle
+ * @return the created {@link MutableSurface} instance w/o defined surface handle
+ */
+ protected abstract ProxySurface createMutableSurfaceImpl(AbstractGraphicsDevice device, boolean createNewDevice,
+ GLCapabilitiesImmutable capsChosen,
+ GLCapabilitiesImmutable capsRequested,
+ GLCapabilitiesChooser chooser, int width, int height, UpstreamSurfaceHook lifecycleHook);
+
+ /**
+ * A dummy surface is not visible on screen and will not be used to render directly to,
+ * it maybe on- or offscreen.
+ * + * It is used to allow the creation of a {@link GLDrawable} and {@link GLContext} to query information. + * It also allows creation of framebuffer objects which are used for rendering. + *
+ * @param deviceReq which {@link javax.media.nativewindow.AbstractGraphicsDevice#getConnection() connection} denotes the shared device to be used, may benull
for the platform's default device.
+ * @param requestedCaps
+ * @param chooser the custom chooser, may be null for default
+ * @param width the initial width
+ * @param height the initial height
+ *
+ * @return the created {@link MutableSurface} instance w/o defined surface handle
+ */
+ public NativeSurface createDummySurface(AbstractGraphicsDevice deviceReq, GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser,
+ int width, int height) {
+ final AbstractGraphicsDevice device = getOrCreateSharedDevice(deviceReq);
if(null == device) {
throw new GLException("No shared device for requested: "+deviceReq);
}
- GLCapabilitiesImmutable capsChosen = GLGraphicsConfigurationUtil.fixOffScreenGLCapabilities(capsRequested, canCreateGLPbuffer(deviceReq));
-
device.lock();
try {
- return createOffscreenSurfaceImpl(device, capsChosen, capsRequested, chooser, width, height);
+ return createDummySurfaceImpl(device, true, requestedCaps, chooser, width, height);
} finally {
device.unlock();
}
}
-
+
/**
- * creates an offscreen NativeSurface, which must implement SurfaceChangeable as well,
- * so the windowing system related implementation is able to set the surface handle.
+ * A dummy surface is not visible on screen and will not be used to render directly to,
+ * it maybe on- or offscreen.
+ * + * It is used to allow the creation of a {@link GLDrawable} and {@link GLContext} to query information. + * It also allows creation of framebuffer objects which are used for rendering. + *
+ * @param device a valid platform dependent target device. + * @param createNewDevice iftrue
a new device instance is created using device
details,
+ * otherwise device
instance is used as-is.
+ * @param requestedCaps
+ * @param chooser the custom chooser, may be null for default
+ * @param width the initial width
+ * @param height the initial height
+ * @return the created {@link MutableSurface} instance w/o defined surface handle
*/
- protected abstract NativeSurface createOffscreenSurfaceImpl(AbstractGraphicsDevice device,
- GLCapabilitiesImmutable capabilities, GLCapabilitiesImmutable capsRequested,
- GLCapabilitiesChooser chooser,
- int width, int height);
+ public abstract ProxySurface createDummySurfaceImpl(AbstractGraphicsDevice device, boolean createNewDevice,
+ GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser, int width, int height);
- public ProxySurface createProxySurface(AbstractGraphicsDevice device, long windowHandle, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser) {
+ //---------------------------------------------------------------------------
+ //
+ // ProxySurface (Wrapped pre-existing native surface) construction
+ //
+
+ @Override
+ public ProxySurface createProxySurface(AbstractGraphicsDevice deviceReq, int screenIdx, long windowHandle,
+ GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser, UpstreamSurfaceHook upstream) {
+ final AbstractGraphicsDevice device = getOrCreateSharedDevice(deviceReq);
if(null == device) {
- throw new GLException("No shared device for requested: "+device);
+ throw new GLException("No shared device for requested: "+deviceReq);
}
device.lock();
try {
- return createProxySurfaceImpl(device, windowHandle, capsRequested, chooser);
+ return createProxySurfaceImpl(device, screenIdx, windowHandle, capsRequested, chooser, upstream);
} finally {
device.unlock();
}
- }
-
- protected abstract ProxySurface createProxySurfaceImpl(AbstractGraphicsDevice device, long windowHandle, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser);
+ }
+
+ /**
+ * Creates a {@link ProxySurface} with a set surface handle.
+ * + * Implementation is also required to allocate it's own {@link AbstractGraphicsDevice} instance. + *
+ * @param upstream TODO + */ + protected abstract ProxySurface createProxySurfaceImpl(AbstractGraphicsDevice deviceReq, int screenIdx, long windowHandle, + GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser, UpstreamSurfaceHook upstream); //--------------------------------------------------------------------------- // @@ -304,7 +405,8 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory { // protected abstract GLContext createExternalGLContextImpl(); - + + @Override public GLContext createExternalGLContext() { NativeWindowFactory.getDefaultToolkitLock().lock(); try { @@ -316,6 +418,7 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory { protected abstract GLDrawable createExternalGLDrawableImpl(); + @Override public GLDrawable createExternalGLDrawable() { NativeWindowFactory.getDefaultToolkitLock().lock(); try { @@ -398,7 +501,7 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory { * normal ahead of time, use resetDisplayGamma(). Throws * IllegalArgumentException if any of the parameters were * out-of-bounds. - * + * * @param gamma The gamma value, typically > 1.0 (default value is * 1.0) * @param brightness The brightness value between -1.0 and 1.0, @@ -484,7 +587,8 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory { return; if (gammaShutdownHook == null) { gammaShutdownHook = new Thread(new Runnable() { - public void run() { + @Override + public void run() { synchronized (GLDrawableFactoryImpl.this) { resetGammaRamp(originalGammaRamp); } diff --git a/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java b/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java index 58a4ac6b4..abf2bf557 100644 --- a/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java +++ b/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java @@ -42,6 +42,7 @@ package jogamp.opengl; import javax.media.nativewindow.AbstractGraphicsDevice; import javax.media.nativewindow.NativeSurface; +import javax.media.nativewindow.ProxySurface; import javax.media.opengl.GLCapabilitiesImmutable; import javax.media.opengl.GLContext; import javax.media.opengl.GLDrawable; @@ -75,7 +76,7 @@ public abstract class GLDrawableImpl implements GLDrawable { if( !realized ) { return; // destroyed already } - GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable)surface.getGraphicsConfiguration().getChosenCapabilities(); + final GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable)surface.getGraphicsConfiguration().getChosenCapabilities(); if ( caps.getDoubleBuffered() ) { if(!surface.surfaceSwap()) { int lockRes = lockSurface(); // it's recursive, so it's ok within [makeCurrent .. release] @@ -149,6 +150,9 @@ public abstract class GLDrawableImpl implements GLDrawable { realized = realizedArg; AbstractGraphicsDevice aDevice = surface.getGraphicsConfiguration().getScreen().getDevice(); if(realizedArg) { + if(surface instanceof ProxySurface) { + ((ProxySurface)surface).createNotify(); + } if(NativeSurface.LOCK_SURFACE_NOT_READY >= lockSurface()) { throw new GLException("GLDrawableImpl.setRealized(true): Surface not ready (lockSurface)"); } @@ -156,17 +160,21 @@ public abstract class GLDrawableImpl implements GLDrawable { aDevice.lock(); } try { - setRealizedImpl(); if(realizedArg) { + setRealizedImpl(); updateHandle(); } else { destroyHandle(); + setRealizedImpl(); } } finally { if(realizedArg) { unlockSurface(); } else { aDevice.unlock(); + if(surface instanceof ProxySurface) { + ((ProxySurface)surface).destroyNotify(); + } } } } else if(DEBUG) { @@ -175,6 +183,39 @@ public abstract class GLDrawableImpl implements GLDrawable { } protected abstract void setRealizedImpl(); + /** + * Callback for special implementations, allowing GLContext to trigger GL related lifecycle:construct
, destroy
.
+ *
+ * If realized
is true
, the context has just been created and made current.
+ *
+ * If realized
is false
, the context is still current and will be release and destroyed after this method returns.
+ *
+ * @see #contextMadeCurrent(GLContext, boolean)
+ */
+ protected void contextRealized(GLContext glc, boolean realized) {}
+
+ /**
+ * Callback for special implementations, allowing GLContext to trigger GL related lifecycle: makeCurrent
, release
.
+ *
+ * Will not be called if {@link #contextRealized(GLContext, boolean)} has been triggered. + *
+ *
+ * If current
is true
, the context has just been made current.
+ *
+ * If current
is false
, the context is still current and will be release after this method returns.
+ *
+ * We intentionally override a non native EGL device ES profile mapping, + * i.e. this will override/modify an already 'set' X11/WGL/.. mapping. + *
+ * + * @param device + */ + protected void mapCurrentAvailableGLVersion(AbstractGraphicsDevice device) { + mapCurrentAvailableGLVersionImpl(device, ctxMajorVersion, ctxMinorVersion, ctxOptions); + } + + protected static void mapStaticGLESVersion(AbstractGraphicsDevice device, int major) { + int ctp = ( 2 == major ) ? ( GLContext.CTX_PROFILE_ES | GLContext.CTX_IMPL_ES2_COMPAT | GLContext.CTX_IMPL_FBO ) : ( GLContext.CTX_PROFILE_ES ); + mapCurrentAvailableGLVersionImpl(device, major, 0, ctp); + } + private static void mapCurrentAvailableGLVersionImpl(AbstractGraphicsDevice device, int major, int minor, int ctp) { + if( 0 != ( ctp & GLContext.CTX_PROFILE_ES) ) { + // ES1 or ES2 + final int reqMajor = major; + final int reqProfile = GLContext.CTX_PROFILE_ES; + GLContext.mapAvailableGLVersion(device, reqMajor, reqProfile, + major, minor, ctp); + } + } + + protected static boolean getAvailableGLVersionsSet(AbstractGraphicsDevice device) { + return GLContext.getAvailableGLVersionsSet(device); + } + protected static void setAvailableGLVersionsSet(AbstractGraphicsDevice device) { + GLContext.setAvailableGLVersionsSet(device); + } + protected static String toHexString(int hex) { return GLContext.toHexString(hex); } diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java b/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java index 7f10d3bd9..432010f49 100644 --- a/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java +++ b/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java @@ -136,7 +136,17 @@ public class EGLDisplayUtil { return res; } - public static final EGLGraphicsDevice.EGLTerminateCallback eglTerminateCallback = new EGLGraphicsDevice.EGLTerminateCallback() { + public static final EGLGraphicsDevice.EGLDisplayLifecycleCallback eglLifecycleCallback = new EGLGraphicsDevice.EGLDisplayLifecycleCallback() { + public long eglGetAndInitDisplay(long nativeDisplayID) { + long eglDisplay = EGLDisplayUtil.eglGetDisplay(nativeDisplayID); + if (eglDisplay == EGL.EGL_NO_DISPLAY) { + throw new GLException("Failed to created EGL display: 0x"+Long.toHexString(nativeDisplayID)+", error 0x"+Integer.toHexString(EGL.eglGetError())); + } + if (!EGLDisplayUtil.eglInitialize(eglDisplay, null, null)) { + throw new GLException("eglInitialize failed"+", error 0x"+Integer.toHexString(EGL.eglGetError())); + } + return eglDisplay; + } public void eglTerminate(long eglDisplayHandle) { EGLDisplayUtil.eglTerminate(eglDisplayHandle); } @@ -148,17 +158,12 @@ public class EGLDisplayUtil { * @param unitID * @return an initialized EGLGraphicsDevice * @throws GLException if {@link EGL#eglGetDisplay(long)} or {@link EGL#eglInitialize(long, int[], int, int[], int)} fails - * @see EGLGraphicsDevice#EGLGraphicsDevice(long, long, String, int, com.jogamp.nativewindow.egl.EGLGraphicsDevice.EGLTerminateCallback) + * @see EGLGraphicsDevice#EGLGraphicsDevice(long, long, String, int, com.jogamp.nativewindow.egl.EGLGraphicsDevice.EGLDisplayLifecycleCallback) */ public static EGLGraphicsDevice eglCreateEGLGraphicsDevice(long nativeDisplayID, String connection, int unitID) { - long eglDisplay = EGLDisplayUtil.eglGetDisplay(nativeDisplayID); - if (eglDisplay == EGL.EGL_NO_DISPLAY) { - throw new GLException("Failed to created EGL display: 0x"+Long.toHexString(nativeDisplayID)+", error 0x"+Integer.toHexString(EGL.eglGetError())); - } - if (!EGLDisplayUtil.eglInitialize(eglDisplay, null, null)) { - throw new GLException("eglInitialize failed"+", error 0x"+Integer.toHexString(EGL.eglGetError())); - } - return new EGLGraphicsDevice(nativeDisplayID, eglDisplay, connection, unitID, eglTerminateCallback); + final EGLGraphicsDevice eglDisplay = new EGLGraphicsDevice(nativeDisplayID, 0, connection, unitID, eglLifecycleCallback); + eglDisplay.open(); + return eglDisplay; } /** @@ -189,6 +194,6 @@ public class EGLDisplayUtil { throw new GLException("eglInitialize failed"+", error 0x"+Integer.toHexString(EGL.eglGetError())); } final AbstractGraphicsDevice adevice = surface.getGraphicsConfiguration().getScreen().getDevice(); - return new EGLGraphicsDevice(nativeDisplayID, eglDisplay, adevice.getConnection(), adevice.getUnitID(), eglTerminateCallback); + return new EGLGraphicsDevice(nativeDisplayID, eglDisplay, adevice.getConnection(), adevice.getUnitID(), eglLifecycleCallback); } } diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java b/src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java index d777c4f04..383b61f88 100644 --- a/src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java +++ b/src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java @@ -36,82 +36,65 @@ package jogamp.opengl.egl; -import jogamp.opengl.GLDynamicLookupHelper; -import jogamp.opengl.GLDrawableImpl; +import javax.media.nativewindow.MutableSurface; +import javax.media.nativewindow.NativeSurface; +import javax.media.nativewindow.NativeWindow; +import javax.media.nativewindow.ProxySurface; +import javax.media.opengl.GLContext; +import javax.media.opengl.GLException; -import javax.media.nativewindow.*; -import javax.media.nativewindow.VisualIDHolder.VIDType; -import javax.media.opengl.*; +import jogamp.opengl.GLDrawableImpl; +import jogamp.opengl.GLDynamicLookupHelper; -import com.jogamp.nativewindow.egl.*; +import com.jogamp.nativewindow.egl.EGLGraphicsDevice; public abstract class EGLDrawable extends GLDrawableImpl { - private boolean ownEGLDisplay = false; // for destruction private boolean ownEGLSurface = false; // for destruction - private EGLGraphicsConfiguration eglConfig; - private EGLGraphicsDevice eglDevice; - private long eglSurface; - protected EGLDrawable(EGLDrawableFactory factory, - NativeSurface component) throws GLException { + protected EGLDrawable(EGLDrawableFactory factory, NativeSurface component) throws GLException { super(factory, component, false); - eglSurface=EGL.EGL_NO_SURFACE; - eglDevice=null; - } - - public final long getDisplay() { - return null != eglDevice ? eglDevice.getHandle() : 0; - } - - @Override - public final long getHandle() { - return eglSurface; - } - - public final EGLGraphicsConfiguration getGraphicsConfiguration() { - return eglConfig; - } - - @Override - public final GLCapabilitiesImmutable getChosenGLCapabilities() { - return (null==eglConfig)?super.getChosenGLCapabilities():(GLCapabilitiesImmutable)eglConfig.getChosenCapabilities(); } @Override public abstract GLContext createContext(GLContext shareWith); - protected abstract long createSurface(long eglDpy, long eglNativeCfg, long surfaceHandle); + protected abstract long createSurface(EGLGraphicsConfiguration config, long nativeSurfaceHandle); private final void recreateSurface() { - // create a new EGLSurface .. - if(EGL.EGL_NO_SURFACE!=eglSurface) { - EGL.eglDestroySurface(eglDevice.getHandle(), eglSurface); - } - + final EGLGraphicsConfiguration eglConfig = (EGLGraphicsConfiguration) surface.getGraphicsConfiguration(); + final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) eglConfig.getScreen().getDevice(); if(DEBUG) { - System.err.println(getThreadName() + ": createSurface using "+eglDevice+", "+eglConfig); + System.err.println(getThreadName() + ": createSurface using "+eglConfig); + } + if( EGL.EGL_NO_SURFACE != surface.getSurfaceHandle() ) { + EGL.eglDestroySurface(eglDevice.getHandle(), surface.getSurfaceHandle()); } - - eglSurface = createSurface(eglDevice.getHandle(), eglConfig.getNativeConfig(), surface.getSurfaceHandle()); - int eglError0 = EGL.EGL_SUCCESS; + + final EGLUpstreamSurfaceHook upstreamHook = (EGLUpstreamSurfaceHook) ((ProxySurface)surface).getUpstreamSurfaceHook(); + final NativeSurface upstreamSurface = upstreamHook.getUpstreamSurface(); + long eglSurface = createSurface(eglConfig, upstreamSurface.getSurfaceHandle()); + + int eglError0; if (EGL.EGL_NO_SURFACE == eglSurface) { eglError0 = EGL.eglGetError(); if(EGL.EGL_BAD_NATIVE_WINDOW == eglError0) { // Try window handle if available and differs (Windows HDC / HWND). // ANGLE impl. required HWND on Windows. - if(surface instanceof NativeWindow) { - final NativeWindow nw = (NativeWindow) surface; + if(upstreamSurface instanceof NativeWindow) { + final NativeWindow nw = (NativeWindow) upstreamSurface; if(nw.getWindowHandle() != nw.getSurfaceHandle()) { if(DEBUG) { System.err.println(getThreadName() + ": Info: Creation of window surface w/ surface handle failed: "+eglConfig+", error "+toHexString(eglError0)+", retry w/ windowHandle"); } - eglSurface = createSurface(eglDevice.getHandle(), eglConfig.getNativeConfig(), nw.getWindowHandle()); + eglSurface = createSurface(eglConfig, nw.getWindowHandle()); if (EGL.EGL_NO_SURFACE == eglSurface) { eglError0 = EGL.eglGetError(); } } } } + } else { + eglError0 = EGL.EGL_SUCCESS; } if (EGL.EGL_NO_SURFACE == eglSurface) { throw new GLException("Creation of window surface failed: "+eglConfig+", "+surface+", error "+toHexString(eglError0)); @@ -120,6 +103,8 @@ public abstract class EGLDrawable extends GLDrawableImpl { if(DEBUG) { System.err.println(getThreadName() + ": setSurface using component: handle "+toHexString(surface.getSurfaceHandle())+" -> "+toHexString(eglSurface)); } + + ((MutableSurface)surface).setSurfaceHandle(eglSurface); } @Override @@ -131,123 +116,71 @@ public abstract class EGLDrawable extends GLDrawableImpl { @Override protected final void setRealizedImpl() { + final EGLGraphicsConfiguration eglConfig = (EGLGraphicsConfiguration) surface.getGraphicsConfiguration(); + final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) eglConfig.getScreen().getDevice(); if (realized) { - AbstractGraphicsConfiguration aConfig = surface.getGraphicsConfiguration(); - AbstractGraphicsDevice aDevice = aConfig.getScreen().getDevice(); - if(aDevice instanceof EGLGraphicsDevice) { + final long eglDisplayHandle = eglDevice.getHandle(); + if (EGL.EGL_NO_DISPLAY == eglDisplayHandle) { + throw new GLException("Invalid EGL display in EGLGraphicsDevice "+eglDevice); + } + int[] tmp = new int[1]; + boolean eglSurfaceValid = 0 != surface.getSurfaceHandle(); + if(eglSurfaceValid) { + eglSurfaceValid = EGL.eglQuerySurface(eglDisplayHandle, surface.getSurfaceHandle(), EGL.EGL_CONFIG_ID, tmp, 0); + if(!eglSurfaceValid) { + if(DEBUG) { + System.err.println(getThreadName() + ": EGLDrawable.setRealizedImpl eglQuerySuface failed: "+toHexString(EGL.eglGetError())+", "+surface); + } + } + } + if(eglSurfaceValid) { + // surface holds valid EGLSurface if(DEBUG) { - System.err.println(getThreadName() + ": EGLDrawable.setRealized(true): using existing EGL config - START"); + System.err.println(getThreadName() + ": EGLDrawable.setRealizedImpl re-using component's EGLSurface: handle "+toHexString(surface.getSurfaceHandle())); + } + ownEGLSurface=false; + } else { + // EGLSurface is ours - subsequent updateHandle() will issue recreateSurface(); + // However .. let's validate the surface object first + if( ! (surface instanceof ProxySurface) ) { + throw new InternalError("surface not ProxySurface: "+surface.getClass().getName()+", "+surface); } - // just fetch the data .. trust but verify .. - ownEGLDisplay = false; - eglDevice = (EGLGraphicsDevice) aDevice; - if (eglDevice.getHandle() == EGL.EGL_NO_DISPLAY) { - throw new GLException("Invalid EGL display in EGLGraphicsDevice "+eglDevice); + final ProxySurface.UpstreamSurfaceHook upstreamHook = ((ProxySurface)surface).getUpstreamSurfaceHook(); + if( null == upstreamHook ) { + throw new InternalError("null upstreamHook of: "+surface); } - if(aConfig instanceof EGLGraphicsConfiguration) { - eglConfig = (EGLGraphicsConfiguration) aConfig; // done .. - if (null == eglConfig) { - throw new GLException("Null EGLGraphicsConfiguration from "+aConfig); - } - - int[] tmp = new int[1]; - if ( 0 != surface.getSurfaceHandle() && - EGL.eglQuerySurface(eglDevice.getHandle(), surface.getSurfaceHandle(), EGL.EGL_CONFIG_ID, tmp, 0) ) { - // surface holds static EGLSurface - eglSurface = surface.getSurfaceHandle(); - if(DEBUG) { - System.err.println(getThreadName() + ": setSurface re-using component's EGLSurface: handle "+toHexString(eglSurface)); - } - ownEGLSurface=false; - } else { - // EGLSurface is ours - subsequent updateHandle() will issue recreateSurface(); - ownEGLSurface=true; - } - } else { - throw new GLException("EGLGraphicsDevice hold by non EGLGraphicsConfiguration: "+aConfig); + if( ! (upstreamHook instanceof EGLUpstreamSurfaceHook) ) { + throw new InternalError("upstreamHook not EGLUpstreamSurfaceHook: Surface: "+surface.getClass().getName()+", "+surface+"; UpstreamHook: "+upstreamHook.getClass().getName()+", "+upstreamHook); } - } else { - if(DEBUG) { - System.err.println(getThreadName() + ": EGLDrawable.setRealized(true): creating new EGL config - START"); + if( null == ((EGLUpstreamSurfaceHook)upstreamHook).getUpstreamSurface() ) { + throw new InternalError("null upstream surface"); } - // create a new EGL config .. - ownEGLDisplay=true; - // EGLSurface is ours .. ownEGLSurface=true; - - eglDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(surface, true); - AbstractGraphicsScreen eglScreen = new DefaultGraphicsScreen(eglDevice, aConfig.getScreen().getIndex()); - final GLCapabilitiesImmutable capsRequested = (GLCapabilitiesImmutable) aConfig.getRequestedCapabilities(); - if(aConfig instanceof EGLGraphicsConfiguration) { - final EGLGLCapabilities capsChosen = (EGLGLCapabilities) aConfig.getChosenCapabilities(); - if(0 == capsChosen.getEGLConfig()) { - // 'refresh' the native EGLConfig handle - capsChosen.setEGLConfig(EGLGraphicsConfiguration.EGLConfigId2EGLConfig(eglDevice.getHandle(), capsChosen.getEGLConfigID())); - if(0 == capsChosen.getEGLConfig()) { - throw new GLException("Refreshing native EGLConfig handle failed: "+capsChosen+" of "+aConfig); - } - } - eglConfig = new EGLGraphicsConfiguration(eglScreen, capsChosen, capsRequested, null); - if(DEBUG) { - System.err.println(getThreadName() + ": Reusing chosenCaps: "+eglConfig); - } - } else { - eglConfig = EGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic( - capsRequested, capsRequested, null, eglScreen, aConfig.getVisualID(VIDType.NATIVE), false); - - if (null == eglConfig) { - throw new GLException("Couldn't create EGLGraphicsConfiguration from "+eglScreen); - } else if(DEBUG) { - System.err.println(getThreadName() + ": Chosen eglConfig: "+eglConfig); - } + if(DEBUG) { + System.err.println(getThreadName() + ": EGLDrawable.setRealizedImpl owning EGLSurface"); } - // subsequent updateHandle() will issue recreateSurface(); - } - if(DEBUG) { - System.err.println(getThreadName() + ": EGLDrawable.setRealized(true): END: ownDisplay "+ownEGLDisplay+", ownSurface "+ownEGLSurface); } - } else if (ownEGLSurface && eglSurface != EGL.EGL_NO_SURFACE) { + } else if (ownEGLSurface && surface.getSurfaceHandle() != EGL.EGL_NO_SURFACE) { if(DEBUG) { - System.err.println(getThreadName() + ": EGLDrawable.setRealized(false): ownDisplay "+ownEGLDisplay+", ownSurface "+ownEGLSurface+", "+eglDevice+", eglSurface: "+toHexString(eglSurface)); + System.err.println(getThreadName() + ": EGLDrawable.setRealized(false): ownSurface "+ownEGLSurface+", "+eglDevice+", eglSurface: "+toHexString(surface.getSurfaceHandle())); } // Destroy the window surface - if (!EGL.eglDestroySurface(eglDevice.getHandle(), eglSurface)) { + if (!EGL.eglDestroySurface(eglDevice.getHandle(), surface.getSurfaceHandle())) { throw new GLException("Error destroying window surface (eglDestroySurface)"); } - eglSurface = EGL.EGL_NO_SURFACE; - eglConfig=null; - eglDevice.close(); - eglDevice=null; + ((MutableSurface)surface).setSurfaceHandle(EGL.EGL_NO_SURFACE); } } @Override protected final void swapBuffersImpl() { + final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) surface.getGraphicsConfiguration().getScreen().getDevice(); // single-buffer is already filtered out @ GLDrawableImpl#swapBuffers() - if(!EGL.eglSwapBuffers(eglDevice.getHandle(), eglSurface)) { + if(!EGL.eglSwapBuffers(eglDevice.getHandle(), surface.getSurfaceHandle())) { throw new GLException("Error swapping buffers, eglError "+toHexString(EGL.eglGetError())+", "+this); } } - /** - * Surface not realizes yet (onscreen) .. Quering EGL surface size only makes sense for external drawable. - * Leave it here for later impl. of an EGLExternalDrawable. - public int getWidth() { - int[] tmp = new int[1]; - if (!EGL.eglQuerySurface(eglDisplay, eglSurface, EGL.EGL_WIDTH, tmp, 0)) { - throw new GLException("Error querying surface width, eglError "+toHexString(EGL.eglGetError())); - } - return tmp[0]; - } - - public int getHeight() { - int[] tmp = new int[1]; - if (!EGL.eglQuerySurface(eglDisplay, eglSurface, EGL.EGL_HEIGHT, tmp, 0)) { - throw new GLException("Error querying surface height, eglError "+toHexString(EGL.eglGetError())); - } - return tmp[0]; - } */ - @Override public GLDynamicLookupHelper getGLDynamicLookupHelper() { if (getGLProfile().usesNativeGLES2()) { @@ -263,10 +196,9 @@ public abstract class EGLDrawable extends GLDrawableImpl { public String toString() { return getClass().getName()+"[realized "+isRealized()+ ",\n\tfactory "+getFactory()+ - ",\n\tdevice "+eglDevice+ ",\n\tsurface "+getNativeSurface()+ - ",\n\teglSurface "+toHexString(eglSurface)+ - ",\n\teglConfig "+eglConfig+ + ",\n\teglSurface "+toHexString(surface.getSurfaceHandle())+ + ",\n\teglConfig "+surface.getGraphicsConfiguration()+ ",\n\trequested "+getRequestedGLCapabilities()+ ",\n\tchosen "+getChosenGLCapabilities()+"]"; } diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java index f4fa1f13f..c848e3e5c 100644 --- a/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java +++ b/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java @@ -46,21 +46,29 @@ import javax.media.nativewindow.AbstractGraphicsConfiguration; import javax.media.nativewindow.AbstractGraphicsDevice; import javax.media.nativewindow.AbstractGraphicsScreen; import javax.media.nativewindow.DefaultGraphicsScreen; +import javax.media.nativewindow.MutableSurface; import javax.media.nativewindow.NativeSurface; import javax.media.nativewindow.NativeWindowFactory; import javax.media.nativewindow.ProxySurface; +import javax.media.nativewindow.ProxySurface.UpstreamSurfaceHook; +import javax.media.nativewindow.VisualIDHolder.VIDType; import javax.media.nativewindow.VisualIDHolder; +import javax.media.opengl.GL; +import javax.media.opengl.GLCapabilities; import javax.media.opengl.GLCapabilitiesChooser; import javax.media.opengl.GLCapabilitiesImmutable; import javax.media.opengl.GLContext; import javax.media.opengl.GLDrawable; +import javax.media.opengl.GLDrawableFactory; import javax.media.opengl.GLException; import javax.media.opengl.GLProfile; import javax.media.opengl.GLProfile.ShutdownType; +import jogamp.opengl.Debug; import jogamp.opengl.GLDrawableFactoryImpl; import jogamp.opengl.GLDrawableImpl; import jogamp.opengl.GLDynamicLookupHelper; +import jogamp.opengl.GLGraphicsConfigurationUtil; import com.jogamp.common.JogampRuntimeException; import com.jogamp.common.os.Platform; @@ -69,6 +77,9 @@ import com.jogamp.nativewindow.WrappedSurface; import com.jogamp.nativewindow.egl.EGLGraphicsDevice; public class EGLDrawableFactory extends GLDrawableFactoryImpl { + /* package */ static final boolean QUERY_EGL_ES = !Debug.isPropertyDefined("jogl.debug.EGLDrawableFactory.DontQuery", true); + /* package */ static final boolean QUERY_EGL_ES_NATIVE_TK = Debug.isPropertyDefined("jogl.debug.EGLDrawableFactory.QueryNativeTK", true); + private static GLDynamicLookupHelper eglES1DynamicLookupHelper = null; private static GLDynamicLookupHelper eglES2DynamicLookupHelper = null; private static boolean isANGLE = false; @@ -231,7 +242,7 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl { // final EGLContext getContextES1() { return contextES1; } // final EGLContext getContextES2() { return contextES2; } final boolean wasES1ContextAvailable() { return wasES1ContextCreated; } - final boolean wasES2ContextAvailable() { return wasES2ContextCreated; } + final boolean wasES2ContextAvailable() { return wasES2ContextCreated; } } @Override @@ -245,35 +256,98 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl { return null!=eglES2DynamicLookupHelper || null!=eglES1DynamicLookupHelper; } - /** - private boolean isEGLContextAvailable(EGLGraphicsDevice sharedDevice, String profile) { - boolean madeCurrent = false; - final GLCapabilities caps = new GLCapabilities(GLProfile.get(profile)); - caps.setRedBits(5); caps.setGreenBits(5); caps.setBlueBits(5); caps.setAlphaBits(0); - caps.setDoubleBuffered(false); - caps.setOnscreen(false); - caps.setPBuffer(true); - final EGLDrawable drawable = (EGLDrawable) createGLDrawable( createOffscreenSurfaceImpl(sharedDevice, caps, caps, null, 64, 64) ); - if(null!=drawable) { + private boolean isEGLContextAvailable(AbstractGraphicsDevice adevice, EGLGraphicsDevice sharedEGLDevice, String profileString) { + if( !GLProfile.isAvailable(adevice, profileString) ) { + return false; + } + final GLProfile glp = GLProfile.get(adevice, profileString) ; + final GLDrawableFactoryImpl desktopFactory = (GLDrawableFactoryImpl) GLDrawableFactory.getDesktopFactory(); + EGLGraphicsDevice eglDevice = null; + NativeSurface surface = null; + ProxySurface upstreamSurface = null; // X11, GLX, .. + boolean success = false; + boolean deviceFromUpstreamSurface = false; + try { + final GLCapabilities caps = new GLCapabilities(glp); + caps.setRedBits(5); caps.setGreenBits(5); caps.setBlueBits(5); caps.setAlphaBits(0); + if(adevice instanceof EGLGraphicsDevice || null == desktopFactory || !QUERY_EGL_ES_NATIVE_TK) { + eglDevice = sharedEGLDevice; // reuse + surface = createDummySurfaceImpl(eglDevice, false, caps, null, 64, 64); // egl pbuffer offscreen + upstreamSurface = (ProxySurface)surface; + upstreamSurface.createNotify(); + deviceFromUpstreamSurface = false; + } else { + surface = desktopFactory.createDummySurface(adevice, caps, null, 64, 64); // X11, WGL, .. dummy window + upstreamSurface = ( surface instanceof ProxySurface ) ? (ProxySurface)surface : null ; + if(null != upstreamSurface) { + upstreamSurface.createNotify(); + } + eglDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(surface, true); + deviceFromUpstreamSurface = true; + } + + final EGLDrawable drawable = (EGLDrawable) createOnscreenDrawableImpl ( surface ); + drawable.setRealized(true); final EGLContext context = (EGLContext) drawable.createContext(null); if (null != context) { - context.setSynchronized(true); try { context.makeCurrent(); // could cause exception - madeCurrent = context.isCurrent(); + success = context.isCurrent(); + if(success) { + final String glVersion = context.getGL().glGetString(GL.GL_VERSION); + if(null == glVersion) { + // Oops .. something is wrong + if(DEBUG) { + System.err.println("EGLDrawableFactory.isEGLContextAvailable: "+eglDevice+", "+context.getGLVersion()+" - VERSION is null, dropping availability!"); + } + success = false; + } + } + if(success) { + context.mapCurrentAvailableGLVersion(eglDevice); + if(eglDevice != adevice) { + context.mapCurrentAvailableGLVersion(adevice); + } + } } catch (GLException gle) { if (DEBUG) { - System.err.println("EGLDrawableFactory.createShared: INFO: makeCurrent failed"); + System.err.println("EGLDrawableFactory.createShared: INFO: context create/makeCurrent failed"); gle.printStackTrace(); } } finally { context.destroy(); } } - drawable.destroy(); + drawable.setRealized(false); + } catch (Throwable t) { + if(DEBUG) { + System.err.println("Catched Exception:"); + t.printStackTrace(); + } + success = false; + } finally { + if(eglDevice == sharedEGLDevice) { + if(null != upstreamSurface) { + upstreamSurface.destroyNotify(); + } + } else if( deviceFromUpstreamSurface ) { + if(null != eglDevice) { + eglDevice.close(); + } + if(null != upstreamSurface) { + upstreamSurface.destroyNotify(); + } + } else { + if(null != upstreamSurface) { + upstreamSurface.destroyNotify(); + } + if(null != eglDevice) { + eglDevice.close(); + } + } } - return madeCurrent; - } */ + return success; + } /* package */ SharedResource getOrCreateEGLSharedResource(AbstractGraphicsDevice adevice) { if(null == eglES1DynamicLookupHelper && null == eglES2DynamicLookupHelper) { @@ -285,18 +359,41 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl { sr = sharedMap.get(connection); } if(null==sr) { - final EGLGraphicsDevice sharedDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(EGL.EGL_DEFAULT_DISPLAY, connection, adevice.getUnitID()); + final boolean madeCurrentES1; + final boolean madeCurrentES2; + final EGLGraphicsDevice sharedDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(EGL.EGL_DEFAULT_DISPLAY, AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT); - // final boolean madeCurrentES1 = isEGLContextAvailable(sharedDevice, GLProfile.GLES1); - // final boolean madeCurrentES2 = isEGLContextAvailable(sharedDevice, GLProfile.GLES2); - final boolean madeCurrentES1 = true; // FIXME - final boolean madeCurrentES2 = true; // FIXME + if(QUERY_EGL_ES) { + madeCurrentES1 = isEGLContextAvailable(adevice, sharedDevice, GLProfile.GLES1); + madeCurrentES2 = isEGLContextAvailable(adevice, sharedDevice, GLProfile.GLES2); + } else { + madeCurrentES1 = true; + madeCurrentES2 = true; + EGLContext.mapStaticGLESVersion(sharedDevice, 1); + if(sharedDevice != adevice) { + EGLContext.mapStaticGLESVersion(adevice, 1); + } + EGLContext.mapStaticGLESVersion(sharedDevice, 2); + if(sharedDevice != adevice) { + EGLContext.mapStaticGLESVersion(adevice, 2); + } + } + + if( !EGLContext.getAvailableGLVersionsSet(adevice) ) { + // Even though we override the non EGL native mapping intentionally, + // avoid exception due to double 'set' - carefull exception of the rule. + EGLContext.setAvailableGLVersionsSet(adevice); + } sr = new SharedResource(sharedDevice, madeCurrentES1, madeCurrentES2); + synchronized(sharedMap) { sharedMap.put(connection, sr); + if(adevice != sharedDevice) { + sharedMap.put(sharedDevice.getConnection(), sr); + } } if (DEBUG) { - System.err.println("EGLDrawableFactory.createShared: device: " + sharedDevice); + System.err.println("EGLDrawableFactory.createShared: devices: queried " + QUERY_EGL_ES + "[nativeTK "+QUERY_EGL_ES_NATIVE_TK+"], " + adevice + ", " + sharedDevice); System.err.println("EGLDrawableFactory.createShared: context ES1: " + madeCurrentES1); System.err.println("EGLDrawableFactory.createShared: context ES2: " + madeCurrentES2); } @@ -367,8 +464,51 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl { if (target == null) { throw new IllegalArgumentException("Null target"); } - return new EGLOnscreenDrawable(this, target); + return new EGLOnscreenDrawable(this, getEGLSurface(target)); + } + + protected static NativeSurface getEGLSurface(NativeSurface surface) { + AbstractGraphicsConfiguration aConfig = surface.getGraphicsConfiguration(); + AbstractGraphicsDevice aDevice = aConfig.getScreen().getDevice(); + if( aDevice instanceof EGLGraphicsDevice && aConfig instanceof EGLGraphicsConfiguration ) { + // already in native EGL format + if(DEBUG) { + System.err.println(getThreadName() + ": getEGLSurface - already in EGL format - use as-is: "+aConfig); + } + return surface; + } + // create EGL instance out of platform native types + final EGLGraphicsDevice eglDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(surface, true); + final AbstractGraphicsScreen eglScreen = new DefaultGraphicsScreen(eglDevice, aConfig.getScreen().getIndex()); + final GLCapabilitiesImmutable capsRequested = (GLCapabilitiesImmutable) aConfig.getRequestedCapabilities(); + final EGLGraphicsConfiguration eglConfig; + if( aConfig instanceof EGLGraphicsConfiguration ) { + // Config is already in EGL type - reuse .. + final EGLGLCapabilities capsChosen = (EGLGLCapabilities) aConfig.getChosenCapabilities(); + if( 0 == capsChosen.getEGLConfig() ) { + // 'refresh' the native EGLConfig handle + capsChosen.setEGLConfig(EGLGraphicsConfiguration.EGLConfigId2EGLConfig(eglDevice.getHandle(), capsChosen.getEGLConfigID())); + if( 0 == capsChosen.getEGLConfig() ) { + throw new GLException("Refreshing native EGLConfig handle failed: "+capsChosen+" of "+aConfig); + } + } + eglConfig = new EGLGraphicsConfiguration(eglScreen, capsChosen, capsRequested, null); + if(DEBUG) { + System.err.println(getThreadName() + ": getEGLSurface - Reusing chosenCaps: "+eglConfig); + } + } else { + eglConfig = EGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic( + capsRequested, capsRequested, null, eglScreen, aConfig.getVisualID(VIDType.NATIVE), false); + + if (null == eglConfig) { + throw new GLException("Couldn't create EGLGraphicsConfiguration from "+eglScreen); + } else if(DEBUG) { + System.err.println(getThreadName() + ": getEGLSurface - Chosen eglConfig: "+eglConfig); + } + } + return new WrappedSurface(eglConfig, EGL.EGL_NO_SURFACE, surface.getWidth(), surface.getHeight(), new EGLUpstreamSurfaceHook(surface)); } + static String getThreadName() { return Thread.currentThread().getName(); } @Override protected GLDrawableImpl createOffscreenDrawableImpl(NativeSurface target) { @@ -390,22 +530,115 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl { } @Override - protected NativeSurface createOffscreenSurfaceImpl(AbstractGraphicsDevice deviceReq, GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser, int width, int height) { - final EGLGraphicsDevice eglDeviceReq = (EGLGraphicsDevice) deviceReq; - final EGLGraphicsDevice device = EGLDisplayUtil.eglCreateEGLGraphicsDevice(eglDeviceReq.getNativeDisplayID(), deviceReq.getConnection(), deviceReq.getUnitID()); - WrappedSurface ns = new WrappedSurface(EGLGraphicsConfigurationFactory.createOffscreenGraphicsConfiguration(device, capsChosen, capsRequested, chooser)); - ns.surfaceSizeChanged(width, height); - return ns; + protected ProxySurface createMutableSurfaceImpl(AbstractGraphicsDevice deviceReq, boolean createNewDevice, + GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested, + GLCapabilitiesChooser chooser, int width, int height, UpstreamSurfaceHook lifecycleHook) { + final EGLGraphicsDevice device; + if(createNewDevice) { + final EGLGraphicsDevice eglDeviceReq = (EGLGraphicsDevice) deviceReq; + device = EGLDisplayUtil.eglCreateEGLGraphicsDevice(eglDeviceReq.getNativeDisplayID(), deviceReq.getConnection(), deviceReq.getUnitID()); + } else { + device = (EGLGraphicsDevice) deviceReq; + } + final DefaultGraphicsScreen screen = new DefaultGraphicsScreen(device, 0); + final EGLGraphicsConfiguration config = EGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capsChosen, capsRequested, chooser, screen, VisualIDHolder.VID_UNDEFINED, false); + if(null == config) { + throw new GLException("Choosing GraphicsConfiguration failed w/ "+capsChosen+" on "+screen); + } + return new WrappedSurface(config, 0, width, height, lifecycleHook); + } + + @Override + public final ProxySurface createDummySurfaceImpl(AbstractGraphicsDevice deviceReq, boolean createNewDevice, + GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser, int width, int height) { + final GLCapabilitiesImmutable chosenCaps = GLGraphicsConfigurationUtil.fixOffscreenGLCapabilities(requestedCaps, false, canCreateGLPbuffer(deviceReq)); + return createMutableSurfaceImpl(deviceReq, createNewDevice, chosenCaps, requestedCaps, chooser, width, height, dummySurfaceLifecycleHook); + } + private static final ProxySurface.UpstreamSurfaceHook dummySurfaceLifecycleHook = new ProxySurface.UpstreamSurfaceHook() { + @Override + public final void create(ProxySurface s) { + if( EGL.EGL_NO_SURFACE == s.getSurfaceHandle() ) { + final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) s.getGraphicsConfiguration().getScreen().getDevice(); + if(0 == eglDevice.getHandle()) { + eglDevice.open(); + s.setImplBitfield(ProxySurface.OWN_DEVICE); + } + createPBufferSurfaceImpl(s, false); + if(DEBUG) { + System.err.println("EGLDrawableFactory.dummySurfaceLifecycleHook.create: "+s); + } + } + } + @Override + public final void destroy(ProxySurface s) { + if( EGL.EGL_NO_SURFACE != s.getSurfaceHandle() ) { + final EGLGraphicsConfiguration config = (EGLGraphicsConfiguration) s.getGraphicsConfiguration(); + final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) config.getScreen().getDevice(); + EGL.eglDestroySurface(eglDevice.getHandle(), s.getSurfaceHandle()); + s.setSurfaceHandle(EGL.EGL_NO_SURFACE); + if( 0 != ( ProxySurface.OWN_DEVICE & s.getImplBitfield() ) ) { + eglDevice.close(); + } + if(DEBUG) { + System.err.println("EGLDrawableFactory.dummySurfaceLifecycleHook.create: "+s); + } + } + } + @Override + public final int getWidth(ProxySurface s) { + return s.initialWidth; + } + @Override + public final int getHeight(ProxySurface s) { + return s.initialHeight; + } + @Override + public String toString() { + return "EGLSurfaceLifecycleHook[]"; + } + + }; + + /** + * @param ms {@link MutableSurface} which dimensions and config are being used to create the pbuffer surface. + * It will also hold the resulting pbuffer surface handle. + * @param useTexture + * @return the passed {@link MutableSurface} which now has the EGL pbuffer surface set as it's handle + */ + protected static MutableSurface createPBufferSurfaceImpl(MutableSurface ms, boolean useTexture) { + final EGLGraphicsConfiguration config = (EGLGraphicsConfiguration) ms.getGraphicsConfiguration(); + final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) config.getScreen().getDevice(); + final GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable) config.getChosenCapabilities(); + final int texFormat; + + if(useTexture) { + texFormat = caps.getAlphaBits() > 0 ? EGL.EGL_TEXTURE_RGBA : EGL.EGL_TEXTURE_RGB ; + } else { + texFormat = EGL.EGL_NO_TEXTURE; + } + + if (DEBUG) { + System.out.println("Pbuffer config: " + config); + } + + final int[] attrs = EGLGraphicsConfiguration.CreatePBufferSurfaceAttribList(ms.getWidth(), ms.getHeight(), texFormat); + final long surf = EGL.eglCreatePbufferSurface(eglDevice.getHandle(), config.getNativeConfig(), attrs, 0); + if (EGL.EGL_NO_SURFACE==surf) { + throw new GLException("Creation of window surface (eglCreatePbufferSurface) failed, dim "+ms.getWidth()+"x"+ms.getHeight()+", error 0x"+Integer.toHexString(EGL.eglGetError())); + } else if(DEBUG) { + System.err.println("PBuffer setSurface result: eglSurface 0x"+Long.toHexString(surf)); + } + ms.setSurfaceHandle(surf); + return ms; } @Override - protected ProxySurface createProxySurfaceImpl(AbstractGraphicsDevice adevice, long windowHandle, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser) { - // FIXME device/windowHandle -> screen ?! - EGLGraphicsDevice device = (EGLGraphicsDevice) adevice; - DefaultGraphicsScreen screen = new DefaultGraphicsScreen(device, 0); - EGLGraphicsConfiguration cfg = EGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capsRequested, capsRequested, chooser, screen, VisualIDHolder.VID_UNDEFINED, false); - WrappedSurface ns = new WrappedSurface(cfg, windowHandle); - return ns; + protected ProxySurface createProxySurfaceImpl(AbstractGraphicsDevice deviceReq, int screenIdx, long windowHandle, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser, UpstreamSurfaceHook upstream) { + final EGLGraphicsDevice eglDeviceReq = (EGLGraphicsDevice) deviceReq; + final EGLGraphicsDevice device = EGLDisplayUtil.eglCreateEGLGraphicsDevice(eglDeviceReq.getNativeDisplayID(), deviceReq.getConnection(), deviceReq.getUnitID()); + final DefaultGraphicsScreen screen = new DefaultGraphicsScreen(device, screenIdx); + final EGLGraphicsConfiguration cfg = EGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capsRequested, capsRequested, chooser, screen, VisualIDHolder.VID_UNDEFINED, false); + return new WrappedSurface(cfg, windowHandle, 0, 0, upstream); } @Override diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java index 56e7a4d22..214b36493 100644 --- a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java +++ b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java @@ -151,7 +151,7 @@ public class EGLGraphicsConfiguration extends MutableGraphicsConfiguration imple public static EGLGLCapabilities EGLConfig2Capabilities(GLProfile glp, long display, long config, boolean relaxed, boolean onscreen, boolean usePBuffer, boolean forceTransparentFlag) { ListEGL.eglGetDisplay(nativeDisplayID)
+ * inclusive EGL.eglInitialize(eglDisplayHandle, ..)
call.
+ * @param eglDisplayHandle
+ */
+ public long eglGetAndInitDisplay(long nativeDisplayID);
+
/**
* Implementation should issue an EGL.eglTerminate(eglDisplayHandle)
call.
* @param eglDisplayHandle
@@ -61,28 +68,45 @@ public class EGLGraphicsDevice extends DefaultGraphicsDevice implements Cloneabl
*/
public EGLGraphicsDevice(String connection, int unitID) {
super(NativeWindowFactory.TYPE_EGL, connection, unitID);
- this.nativeDisplayID = 0;
- this.eglTerminateCallback = null;
+ this.nativeDisplayID = 0 ; // EGL.EGL_DEFAULT_DISPLAY
+ this.eglLifecycleCallback = null;
}
- public EGLGraphicsDevice(long nativeDisplayID, long eglDisplay, String connection, int unitID, EGLTerminateCallback eglTerminateCallback) {
+ public EGLGraphicsDevice(long nativeDisplayID, long eglDisplay, String connection, int unitID, EGLDisplayLifecycleCallback eglLifecycleCallback) {
super(NativeWindowFactory.TYPE_EGL, connection, unitID, eglDisplay);
this.nativeDisplayID = nativeDisplayID;
- this.eglTerminateCallback = eglTerminateCallback;
+ this.eglLifecycleCallback = eglLifecycleCallback;
}
public long getNativeDisplayID() { return nativeDisplayID; }
+ @Override
public Object clone() {
return super.clone();
}
+
+ @Override
+ public boolean open() {
+ if(null != eglLifecycleCallback && 0 == handle) {
+ if(DEBUG) {
+ System.err.println(Thread.currentThread().getName() + " - EGLGraphicsDevice.open(): "+this);
+ }
+ handle = eglLifecycleCallback.eglGetAndInitDisplay(nativeDisplayID);
+ if(0 == handle) {
+ throw new NativeWindowException("EGLGraphicsDevice.open() failed: "+this);
+ }
+ return true;
+ }
+ return false;
+ }
+ @Override
public boolean close() {
- if(null != eglTerminateCallback) {
+ if(null != eglLifecycleCallback && 0 != handle) {
if(DEBUG) {
- System.err.println(Thread.currentThread().getName() + " - eglTerminate: "+this);
+ System.err.println(Thread.currentThread().getName() + " - EGLGraphicsDevice.close(): "+this);
}
- eglTerminateCallback.eglTerminate(handle);
+ eglLifecycleCallback.eglTerminate(handle);
}
return super.close();
}
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java b/src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java
index 735d85fb1..0494bb408 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java
@@ -43,7 +43,6 @@ import com.jogamp.nativewindow.macosx.MacOSXGraphicsDevice;
import com.jogamp.nativewindow.windows.WindowsGraphicsDevice;
import com.jogamp.nativewindow.x11.X11GraphicsDevice;
-import jogamp.common.awt.AWTEDTExecutor;
import jogamp.nativewindow.macosx.OSXUtil;
public class SWTAccessor {
@@ -204,8 +203,6 @@ public class SWTAccessor {
if( null != OS_gtk_class ) {
long widgedHandle = callStaticMethodL2L(OS_GTK_WIDGET_WINDOW, handle);
long displayHandle = callStaticMethodL2L(OS_gdk_x11_drawable_get_xdisplay, widgedHandle);
- // FIXME: May think about creating a private non-shared X11 Display handle, like we use to for AWT
- // to avoid locking problems !
return new X11GraphicsDevice(displayHandle, AbstractGraphicsDevice.DEFAULT_UNIT, false);
}
if( NativeWindowFactory.TYPE_WINDOWS == NativeWindowFactory.getNativeWindowType(false) ) {
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsDevice.java b/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsDevice.java
index a02332413..7a98e3c25 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsDevice.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsDevice.java
@@ -33,7 +33,6 @@
package com.jogamp.nativewindow.x11;
-import jogamp.nativewindow.Debug;
import jogamp.nativewindow.x11.X11Lib;
import jogamp.nativewindow.x11.X11Util;
@@ -46,7 +45,7 @@ import javax.media.nativewindow.ToolkitLock;
*/
public class X11GraphicsDevice extends DefaultGraphicsDevice implements Cloneable {
- final boolean closeDisplay;
+ final boolean handleOwner;
/** Constructs a new X11GraphicsDevice corresponding to the given connection and default
* {@link javax.media.nativewindow.ToolkitLock} via {@link NativeWindowFactory#getDefaultToolkitLock(String)}.null
.
+ *
+ * The default implementation is a NOP
.
+ *
+ * Example implementations like {@link com.jogamp.nativewindow.x11.X11GraphicsDevice}
+ * or {@link com.jogamp.nativewindow.egl.EGLGraphicsDevice}
+ * issue the native open operation in case handle is null
.
+ *
null
and opening was successful, otherwise false.
+ */
+ public boolean open();
+
/**
- * Optionally closing the device.
+ * Optionally closing the device if handle is not null
.
*
* The default implementation is a NOP
, just setting the handle to null
.
*
+ * Example implementations like {@link com.jogamp.nativewindow.x11.X11GraphicsDevice} + * or {@link com.jogamp.nativewindow.egl.EGLGraphicsDevice} + * issue the native close operation or skip it depending on the handles's ownership. + *
* - * @return true if the handle was notnull
, otherwise false.
+ * @return true if the handle was not null
and closing was successful, otherwise false.
*/
public boolean close();
}
diff --git a/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java b/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java
index 187959a67..583fde07f 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java
@@ -97,22 +97,27 @@ public class DefaultGraphicsDevice implements Cloneable, AbstractGraphicsDevice
}
}
+ @Override
public final String getType() {
return type;
}
+ @Override
public final String getConnection() {
return connection;
}
+ @Override
public final int getUnitID() {
return unitID;
}
+ @Override
public final String getUniqueID() {
return uniqueID;
}
+ @Override
public final long getHandle() {
return handle;
}
@@ -124,6 +129,7 @@ public class DefaultGraphicsDevice implements Cloneable, AbstractGraphicsDevice
* @see DefaultGraphicsDevice#DefaultGraphicsDevice(java.lang.String, long)
* @see DefaultGraphicsDevice#DefaultGraphicsDevice(java.lang.String, long, javax.media.nativewindow.ToolkitLock)
*/
+ @Override
public final void lock() {
toolkitLock.lock();
}
@@ -135,10 +141,17 @@ public class DefaultGraphicsDevice implements Cloneable, AbstractGraphicsDevice
* @see DefaultGraphicsDevice#DefaultGraphicsDevice(java.lang.String, long)
* @see DefaultGraphicsDevice#DefaultGraphicsDevice(java.lang.String, long, javax.media.nativewindow.ToolkitLock)
*/
+ @Override
public final void unlock() {
toolkitLock.unlock();
}
+
+ @Override
+ public boolean open() {
+ return false;
+ }
+ @Override
public boolean close() {
if(0 != handle) {
handle = 0;
diff --git a/src/nativewindow/classes/javax/media/nativewindow/MutableSurface.java b/src/nativewindow/classes/javax/media/nativewindow/MutableSurface.java
new file mode 100644
index 000000000..ff53c8109
--- /dev/null
+++ b/src/nativewindow/classes/javax/media/nativewindow/MutableSurface.java
@@ -0,0 +1,44 @@
+/**
+ * Copyright 2012 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package javax.media.nativewindow;
+
+/**
+ * Provides a {@link NativeSurface} with a mutable surfaceHandle
+ * via {@link #setSurfaceHandle(long)}.
+ *
+ * @see NativeSurface
+ */
+public interface MutableSurface extends NativeSurface {
+
+ /**
+ * Sets the surface handle which is created outside of this implementation.
+ */
+ public void setSurfaceHandle(long surfaceHandle);
+}
+
diff --git a/src/nativewindow/classes/javax/media/nativewindow/ProxySurface.java b/src/nativewindow/classes/javax/media/nativewindow/ProxySurface.java
index 1dabc3dcd..7fc9789c2 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/ProxySurface.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/ProxySurface.java
@@ -28,38 +28,108 @@
package javax.media.nativewindow;
-
import jogamp.nativewindow.Debug;
import jogamp.nativewindow.SurfaceUpdatedHelper;
import com.jogamp.common.util.locks.LockFactory;
import com.jogamp.common.util.locks.RecursiveLock;
-public abstract class ProxySurface implements NativeSurface {
+public abstract class ProxySurface implements NativeSurface, MutableSurface {
public static final boolean DEBUG = Debug.debug("ProxySurface");
+
+ /**
+ * Implementation specific bitvalue stating the upstream's {@link AbstractGraphicsDevice} is owned by this {@link ProxySurface}.
+ * @see #setImplBitfield(int)
+ * @see #getImplBitfield()
+ */
+ public static final int OWN_DEVICE = 1 << 7;
+
+ /**
+ * Implementation specific bitvalue stating the upstream's {@link NativeSurface} is an invisible window, i.e. maybe incomplete.
+ * @see #setImplBitfield(int)
+ * @see #getImplBitfield()
+ */
+ public static final int INVISIBLE_WINDOW = 1 << 8;
- private SurfaceUpdatedHelper surfaceUpdatedHelper = new SurfaceUpdatedHelper();
- private AbstractGraphicsConfiguration config; // control access due to delegation
- protected RecursiveLock surfaceLock = LockFactory.createRecursiveLock();
+ /** Interface allowing upstream caller to pass lifecycle actions and size info to a {@link ProxySurface} instance. */
+ public interface UpstreamSurfaceHook {
+ /** called within {@link ProxySurface#createNotify()} within lock, before using surface. */
+ public void create(ProxySurface s);
+ /** called within {@link ProxySurface#destroyNotify()} within lock, before clearing fields. */
+ public void destroy(ProxySurface s);
+
+ /** Returns the width of the upstream surface */
+ public int getWidth(ProxySurface s);
+ /** Returns the height of the upstream surface */
+ public int getHeight(ProxySurface s);
+ }
+
+ private final SurfaceUpdatedHelper surfaceUpdatedHelper = new SurfaceUpdatedHelper();
+ private final AbstractGraphicsConfiguration config; // control access due to delegation
+ private final UpstreamSurfaceHook upstream;
+ public final int initialWidth;
+ public final int initialHeight;
private long surfaceHandle_old;
+ protected RecursiveLock surfaceLock = LockFactory.createRecursiveLock();
protected long displayHandle;
- protected int height;
protected int scrnIndex;
- protected int width;
+ protected int implBitfield;
- public ProxySurface(AbstractGraphicsConfiguration cfg) {
- invalidate();
- config = cfg;
- displayHandle=cfg.getNativeGraphicsConfiguration().getScreen().getDevice().getHandle();
- surfaceHandle_old = 0;
+ /**
+ * @param cfg the {@link AbstractGraphicsConfiguration} to be used
+ * @param initialWidth the initial width
+ * @param initialHeight the initial height
+ */
+ protected ProxySurface(AbstractGraphicsConfiguration cfg, int initialWidth, int initialHeight, UpstreamSurfaceHook upstream) {
+ if(null == cfg) {
+ throw new IllegalArgumentException("null config");
+ }
+ this.config = cfg;
+ this.upstream = upstream;
+ this.initialWidth = initialWidth;
+ this.initialHeight = initialHeight;
+ this.displayHandle=config.getNativeGraphicsConfiguration().getScreen().getDevice().getHandle();
+ this.surfaceHandle_old = 0;
+ this.implBitfield = 0;
}
- void invalidate() {
- displayHandle = 0;
- invalidateImpl();
+ public final UpstreamSurfaceHook getUpstreamSurfaceHook() { return upstream; }
+
+ /**
+ * If a valid {@link UpstreamSurfaceHook} instance is passed in the
+ * {@link ProxySurface#ProxySurface(AbstractGraphicsConfiguration, int, int, UpstreamSurfaceHook) constructor},
+ * {@link UpstreamSurfaceHook#create(ProxySurface)} is being issued and the proxy surface/window handles shall be set.
+ */
+ public void createNotify() {
+ if(null != upstream) {
+ upstream.create(this);
+ }
+ this.displayHandle=config.getNativeGraphicsConfiguration().getScreen().getDevice().getHandle();
+ this.surfaceHandle_old = 0;
}
- protected abstract void invalidateImpl();
-
+
+ /**
+ * If a valid {@link UpstreamSurfaceHook} instance is passed in the
+ * {@link ProxySurface#ProxySurface(AbstractGraphicsConfiguration, int, int, UpstreamSurfaceHook) constructor},
+ * {@link UpstreamSurfaceHook#destroy(ProxySurface)} is being issued and all fields are cleared.
+ */
+ public void destroyNotify() {
+ if(null != upstream) {
+ upstream.destroy(this);
+ invalidateImpl();
+ }
+ this.displayHandle = 0;
+ this.surfaceHandle_old = 0;
+ }
+
+ /**
+ * Must be overridden by implementations allowing having a {@link UpstreamSurfaceHook} being passed.
+ * @see #destroyNotify()
+ */
+ protected void invalidateImpl() {
+ throw new InternalError("UpstreamSurfaceHook given, but required method not implemented.");
+ }
+
@Override
public final long getDisplayHandle() {
return displayHandle;
@@ -82,19 +152,23 @@ public abstract class ProxySurface implements NativeSurface {
@Override
public abstract long getSurfaceHandle();
+ @Override
+ public abstract void setSurfaceHandle(long surfaceHandle);
+
@Override
public final int getWidth() {
- return width;
+ if(null != upstream) {
+ return upstream.getWidth(this);
+ }
+ return initialWidth;
}
@Override
public final int getHeight() {
- return height;
- }
-
- public void surfaceSizeChanged(int width, int height) {
- this.width = width;
- this.height = height;
+ if(null != upstream) {
+ return upstream.getHeight(this);
+ }
+ return initialHeight;
}
@Override
@@ -187,7 +261,10 @@ public abstract class ProxySurface implements NativeSurface {
public final Thread getSurfaceLockOwner() {
return surfaceLock.getOwner();
}
-
+
@Override
public abstract String toString();
+
+ public int getImplBitfield() { return implBitfield; }
+ public void setImplBitfield(int v) { implBitfield=v; }
}
diff --git a/src/nativewindow/classes/javax/media/nativewindow/SurfaceChangeable.java b/src/nativewindow/classes/javax/media/nativewindow/SurfaceChangeable.java
deleted file mode 100644
index 956e68e61..000000000
--- a/src/nativewindow/classes/javax/media/nativewindow/SurfaceChangeable.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * - Redistribution of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistribution in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * Neither the name of Sun Microsystems, Inc. or the names of
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * This software is provided "AS IS," without a warranty of any kind. ALL
- * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
- * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
- * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
- * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
- * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
- * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
- * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
- * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
- * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
- * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
- * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
- *
- * You acknowledge that this software is not designed or intended for use
- * in the design, construction, operation or maintenance of any nuclear
- * facility.
- *
- * Sun gratefully acknowledges that this software was originally authored
- * and developed by Kenneth Bradley Russell and Christopher John Kline.
- */
-
-package javax.media.nativewindow;
-
-public interface SurfaceChangeable {
-
- /** Sets the surface handle which is created outside of this implementation */
- public void setSurfaceHandle(long surfaceHandle);
-
- /**
- * The surface's size has been determined or changed.
- * Implementation shall update the stored surface size with the given ones.
- */
- public void surfaceSizeChanged(int width, int height);
-
-}
-
diff --git a/src/nativewindow/classes/jogamp/nativewindow/SurfaceUpdatedHelper.java b/src/nativewindow/classes/jogamp/nativewindow/SurfaceUpdatedHelper.java
index 4877d5c4f..4f68c6945 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/SurfaceUpdatedHelper.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/SurfaceUpdatedHelper.java
@@ -34,8 +34,8 @@ import javax.media.nativewindow.NativeSurface;
import javax.media.nativewindow.SurfaceUpdatedListener;
public class SurfaceUpdatedHelper implements SurfaceUpdatedListener {
- private Object surfaceUpdatedListenersLock = new Object();
- private ArrayList+ * Actually the window handle (HWND), since the surfaceHandle (HDC) is derived + * from it at {@link #lockSurface()}. + *
+ */ + @Override + public final void setSurfaceHandle(long surfaceHandle) { + this.windowHandle = surfaceHandle; + } + + /** + * Sets the window handle (HWND). + */ + public final void setWindowHandle(long windowHandle) { + this.windowHandle = windowHandle; + } + + public final long getWindowHandle() { + return windowHandle; } @Override final protected int lockSurfaceImpl() { + if (0 == windowHandle) { + throw new NativeWindowException("null window handle: "+this); + } if (0 != surfaceHandle) { throw new InternalError("surface not released"); } @@ -89,12 +117,15 @@ public class GDISurface extends ProxySurface { @Override final public String toString() { - return "GDISurface[config "+getPrivateGraphicsConfiguration()+ + final UpstreamSurfaceHook ush = getUpstreamSurfaceHook(); + final String ush_s = null != ush ? ( ush.getClass().getName() + ": " + ush ) : "nil"; + return getClass().getSimpleName()+"[config "+getPrivateGraphicsConfiguration()+ ", displayHandle 0x"+Long.toHexString(getDisplayHandle())+ ", windowHandle 0x"+Long.toHexString(windowHandle)+ ", surfaceHandle 0x"+Long.toHexString(getSurfaceHandle())+ ", size "+getWidth()+"x"+getHeight()+ - ", surfaceLock "+surfaceLock+"]"; + ", surfaceLock "+surfaceLock+ + ", upstreamSurfaceHook "+ush_s+"]"; } } diff --git a/src/nativewindow/native/macosx/OSXmisc.m b/src/nativewindow/native/macosx/OSXmisc.m index e010fc440..ebfefe345 100644 --- a/src/nativewindow/native/macosx/OSXmisc.m +++ b/src/nativewindow/native/macosx/OSXmisc.m @@ -148,37 +148,6 @@ JNIEXPORT jobject JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_GetLocationOnS return res; } -/* - * Class: Java_jogamp_nativewindow_macosx_OSXUtil - * Method: CreateNSView0 - * Signature: (IIIIZ)J - */ -JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_CreateNSView0 - (JNIEnv *env, jclass unused, jint x, jint y, jint width, jint height) -{ - NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - NSRect rect = NSMakeRect(x, y, width, height); - NSView * view = [[NSView alloc] initWithFrame: rect] ; - [view setCanDrawConcurrently: YES]; - [pool release]; - - return (jlong) (intptr_t) view; -} - -/* - * Class: Java_jogamp_nativewindow_macosx_OSXUtil - * Method: DestroyNSView0 - * Signature: (J)V - */ -JNIEXPORT void JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_DestroyNSView0 - (JNIEnv *env, jclass unused, jlong nsView) -{ - NSView* view = (NSView*) (intptr_t) nsView; - NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - [view release]; - [pool release]; -} - /* * Class: Java_jogamp_nativewindow_macosx_OSXUtil * Method: CreateNSWindow0 @@ -222,6 +191,27 @@ JNIEXPORT void JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_DestroyNSWindow0 [pool release]; } +/* + * Class: Java_jogamp_nativewindow_macosx_OSXUtil + * Method: GetNSView0 + * Signature: (J)J + */ +JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_GetNSView0 + (JNIEnv *env, jclass unused, jlong window) +{ + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + NSWindow* win = (NSWindow*) ((intptr_t) window); + + DBG_PRINT( "contentView0 - window: %p (START)\n", win); + + jlong res = (jlong) ((intptr_t) [win contentView]); + + DBG_PRINT( "contentView0 - window: %p (END)\n", win); + + [pool release]; + return res; +} + /* * Class: Java_jogamp_nativewindow_macosx_OSXUtil * Method: CreateCALayer0 diff --git a/src/newt/classes/com/jogamp/newt/Window.java b/src/newt/classes/com/jogamp/newt/Window.java index 71e86d520..e8537fec5 100644 --- a/src/newt/classes/com/jogamp/newt/Window.java +++ b/src/newt/classes/com/jogamp/newt/Window.java @@ -40,8 +40,20 @@ import javax.media.nativewindow.NativeWindow; import javax.media.nativewindow.WindowClosingProtocol; /** - * Specifying the public Window functionality for the - * using a Window and for shadowing one like {@link com.jogamp.newt.opengl.GLWindow}. + * Specifying NEWT's Window functionality: + *+ * One use case is {@link com.jogamp.newt.opengl.GLWindow}, which delegates + * window operation to an instance of this interface while providing OpenGL + * functionality. + *
*/ public interface Window extends NativeWindow, WindowClosingProtocol { public static final boolean DEBUG_MOUSE_EVENT = Debug.debug("Window.MouseEvent"); diff --git a/src/newt/classes/com/jogamp/newt/event/KeyEvent.java b/src/newt/classes/com/jogamp/newt/event/KeyEvent.java index 44fcea49c..4db661eeb 100644 --- a/src/newt/classes/com/jogamp/newt/event/KeyEvent.java +++ b/src/newt/classes/com/jogamp/newt/event/KeyEvent.java @@ -43,7 +43,7 @@ public class KeyEvent extends InputEvent this.keyChar=keyChar; } - /** Only valid if delivered via {@link KeyListener#keyPressed(KeyEvent)} */ + /** Only valid on all platforms at {@link KeyListener#keyTyped(KeyEvent)} */ public char getKeyChar() { return keyChar; } diff --git a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java index f08fbc8fa..c50ab77c4 100644 --- a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java +++ b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java @@ -124,6 +124,11 @@ public class GLWindow extends GLAutoDrawableBase implements GLAutoDrawable, Wind this.window.setLifecycleHook(new GLLifecycleHook()); } + @Override + public final Object getUpstreamWidget() { + return window; + } + /** * Creates a new GLWindow attaching a new Window referencing a * new default Screen and default Display with the given GLCapabilities. @@ -762,7 +767,7 @@ public class GLWindow extends GLAutoDrawableBase implements GLAutoDrawable, Wind System.err.println(GlueGenVersion.getInstance()); System.err.println(JoglVersion.getInstance()); - System.err.println(JoglVersion.getDefaultOpenGLInfo(null, true).toString()); + System.err.println(JoglVersion.getDefaultOpenGLInfo(null, null, true).toString()); final GLProfile glp = GLProfile.getDefault(); final GLCapabilitiesImmutable caps = new GLCapabilities( glp ); diff --git a/src/newt/classes/jogamp/newt/OffscreenWindow.java b/src/newt/classes/jogamp/newt/OffscreenWindow.java index 050e24b6c..be543aba9 100644 --- a/src/newt/classes/jogamp/newt/OffscreenWindow.java +++ b/src/newt/classes/jogamp/newt/OffscreenWindow.java @@ -34,15 +34,24 @@ package jogamp.newt; -import javax.media.nativewindow.*; +import javax.media.nativewindow.AbstractGraphicsConfiguration; +import javax.media.nativewindow.AbstractGraphicsScreen; +import javax.media.nativewindow.GraphicsConfigurationFactory; +import javax.media.nativewindow.MutableSurface; +import javax.media.nativewindow.NativeWindowException; +import javax.media.nativewindow.ProxySurface; import javax.media.nativewindow.util.Insets; import javax.media.nativewindow.util.Point; -public class OffscreenWindow extends WindowImpl implements SurfaceChangeable { +public class OffscreenWindow extends WindowImpl implements MutableSurface { long surfaceHandle = 0; - + ProxySurface.UpstreamSurfaceHook upstreamHook; + ProxySurface dummySurface; + public OffscreenWindow() { + upstreamHook = null; + dummySurface = null; } static long nextWindowHandle = 0x100; // start here - a marker @@ -52,6 +61,17 @@ public class OffscreenWindow extends WindowImpl implements SurfaceChangeable { throw new NativeWindowException("Capabilities is onscreen"); } final AbstractGraphicsScreen aScreen = getScreen().getGraphicsScreen(); + /** Cannot use OpenGL here .. + if(capsRequested instanceof GLCapabilitiesImmutable) { + final GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable) capsRequested; + if(caps.isFBO() && GLContext.isFBOAvailable(aScreen.getDevice(), caps.getGLProfile()) ) { + final GLDrawableFactoryImpl factory = (GLDrawableFactoryImpl) GLDrawableFactory.getFactory(caps.getGLProfile()); + final GLCapabilitiesImmutable dummyCaps = GLGraphicsConfigurationUtil.fixOnscreenGLCapabilities(caps); + final ProxySurface dummySurface = factory.createDummySurfaceImpl(aScreen.getDevice(), false, dummyCaps, null, 64, 64); + upstreamHook = dummySurface.getUpstreamSurfaceHook(); + dummySurface.createNotify(); + } + } */ final AbstractGraphicsConfiguration cfg = GraphicsConfigurationFactory.getFactory(aScreen.getDevice()).chooseGraphicsConfiguration( capsRequested, capsRequested, capabilitiesChooser, aScreen); if (null == cfg) { @@ -68,13 +88,14 @@ public class OffscreenWindow extends WindowImpl implements SurfaceChangeable { // nop } - public void surfaceSizeChanged(int width, int height) { - sizeChanged(false, width, height, false); - } - @Override public synchronized void destroy() { super.destroy(); + if(null != dummySurface) { + dummySurface.destroyNotify(); + dummySurface = null; + upstreamHook = null; + } surfaceHandle = 0; } @@ -84,8 +105,12 @@ public class OffscreenWindow extends WindowImpl implements SurfaceChangeable { @Override public long getSurfaceHandle() { + if(null != dummySurface) { + return dummySurface.getSurfaceHandle(); + // return upstreamHook.getWidth(); + } return surfaceHandle; - } + } protected void requestFocusImpl(boolean reparented) { } diff --git a/src/newt/classes/jogamp/newt/driver/android/MD.java b/src/newt/classes/jogamp/newt/driver/android/MD.java index 403eae383..f2f30937b 100644 --- a/src/newt/classes/jogamp/newt/driver/android/MD.java +++ b/src/newt/classes/jogamp/newt/driver/android/MD.java @@ -43,7 +43,7 @@ public class MD { .append(JoglVersion.getInstance()).append(Platform.NEWLINE) .append(Platform.NEWLINE); - JoglVersion.getDefaultOpenGLInfo(sb, true); + JoglVersion.getDefaultOpenGLInfo(null, sb, true); return sb.toString(); } diff --git a/src/newt/classes/jogamp/newt/driver/macosx/MacWindow.java b/src/newt/classes/jogamp/newt/driver/macosx/MacWindow.java index 942994c13..fcca5c843 100644 --- a/src/newt/classes/jogamp/newt/driver/macosx/MacWindow.java +++ b/src/newt/classes/jogamp/newt/driver/macosx/MacWindow.java @@ -38,7 +38,7 @@ import javax.media.nativewindow.AbstractGraphicsConfiguration; import javax.media.nativewindow.GraphicsConfigurationFactory; import javax.media.nativewindow.NativeWindow; import javax.media.nativewindow.NativeWindowException; -import javax.media.nativewindow.SurfaceChangeable; +import javax.media.nativewindow.MutableSurface; import javax.media.nativewindow.util.Insets; import javax.media.nativewindow.util.InsetsImmutable; import javax.media.nativewindow.util.Point; @@ -50,7 +50,7 @@ import jogamp.newt.driver.DriverUpdatePosition; import com.jogamp.newt.event.KeyEvent; -public class MacWindow extends WindowImpl implements SurfaceChangeable, DriverClearFocus, DriverUpdatePosition { +public class MacWindow extends WindowImpl implements MutableSurface, DriverClearFocus, DriverUpdatePosition { static { MacDisplay.initSingleton(); @@ -131,10 +131,6 @@ public class MacWindow extends WindowImpl implements SurfaceChangeable, DriverCl } } - public void surfaceSizeChanged(int width, int height) { - sizeChanged(false, width, height, false); - } - @Override protected void setTitleImpl(final String title) { setTitle0(getWindowHandle(), title); diff --git a/src/newt/native/NewtMacWindow.m b/src/newt/native/NewtMacWindow.m index f914467af..b58b99e38 100644 --- a/src/newt/native/NewtMacWindow.m +++ b/src/newt/native/NewtMacWindow.m @@ -972,7 +972,7 @@ static jint mods2JavaMods(NSUInteger mods) NSView* nsview = [self contentView]; if( ! [nsview isMemberOfClass:[NewtView class]] ) { - return; + return NO; } NewtView* view = (NewtView *) nsview; @@ -981,14 +981,14 @@ static jint mods2JavaMods(NSUInteger mods) DBG_PRINT( "*************** windowWillClose.0: %p\n", (void *)(intptr_t)javaWindowObject); if (javaWindowObject == NULL) { DBG_PRINT("windowWillClose: null javaWindowObject\n"); - return; + return NO; } int shallBeDetached = 0; JavaVM *jvmHandle = [view getJVMHandle]; JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], &shallBeDetached); if(NULL==env) { DBG_PRINT("windowWillClose: null JNIEnv\n"); - return; + return NO; } [view setDestroyNotifySent: true]; // earmark assumption of being closed diff --git a/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT00.java b/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT00.java index a09cc76ac..b22be0a93 100644 --- a/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT00.java +++ b/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT00.java @@ -194,7 +194,7 @@ public class TestTextRendererNEWT00 extends UITestCase { pw.printf("%s-%03dx%03d-T%04d", objName, drawable.getWidth(), drawable.getHeight(), texSize[0]); final String filename = dir + sw +".png"; - if(screenshot.readPixels(drawable.getGL(), drawable, false)) { + if(screenshot.readPixels(drawable.getGL(), false)) { screenshot.write(new File(filename)); } } diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPURendererListenerBase01.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPURendererListenerBase01.java index a3182a30f..6378c1ee3 100644 --- a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPURendererListenerBase01.java +++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPURendererListenerBase01.java @@ -194,7 +194,7 @@ public abstract class GPURendererListenerBase01 implements GLEventListener { pw.printf("-%03dx%03d-Z%04d-T%04d-%s", drawable.getWidth(), drawable.getHeight(), (int)Math.abs(zoom), texSize[0], objName); final String filename = dir + tech + sw +".png"; - if(screenshot.readPixels(drawable.getGL(), drawable, false)) { + if(screenshot.readPixels(drawable.getGL(), false)) { screenshot.write(new File(filename)); } } diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/UIListenerBase01.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/UIListenerBase01.java index d0093ad0c..15daf70cd 100644 --- a/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/UIListenerBase01.java +++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/UIListenerBase01.java @@ -180,7 +180,7 @@ public abstract class UIListenerBase01 implements GLEventListener { pw.printf("-%03dx%03d-Z%04d-T%04d-%s", drawable.getWidth(), drawable.getHeight(), (int)Math.abs(zoom), 0, objName); final String filename = dir + tech + sw +".png"; - if(screenshot.readPixels(drawable.getGL(), drawable, false)) { + if(screenshot.readPixels(drawable.getGL(), false)) { screenshot.write(new File(filename)); } } diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBODrawableNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBODrawableNEWT.java new file mode 100644 index 000000000..1a33845b3 --- /dev/null +++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBODrawableNEWT.java @@ -0,0 +1,272 @@ +/** + * Copyright 2012 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package com.jogamp.opengl.test.junit.jogl.acore; + +import java.io.IOException; + +import javax.media.opengl.GL; +import javax.media.opengl.GLAutoDrawable; +import javax.media.opengl.GLCapabilities; +import javax.media.opengl.GLContext; +import javax.media.opengl.GLDrawable; +import javax.media.opengl.GLDrawableFactory; +import javax.media.opengl.GLEventListener; +import javax.media.opengl.GLProfile; + +import jogamp.opengl.GLFBODrawableImpl; + +import org.junit.Assert; +import org.junit.Test; + +import com.jogamp.opengl.FBObject; +import com.jogamp.opengl.OffscreenAutoDrawable; +import com.jogamp.opengl.test.junit.jogl.demos.es2.FBOMix2DemosES2; +import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2; +import com.jogamp.opengl.test.junit.jogl.demos.es2.MultisampleDemoES2; +import com.jogamp.opengl.test.junit.util.UITestCase; +import com.jogamp.opengl.util.GLReadBufferUtil; +import com.jogamp.opengl.util.texture.TextureIO; + +public class TestFBODrawableNEWT extends UITestCase { + + static final int widthStep = 800/4; + static final int heightStep = 600/4; + volatile int szStep = 2; + + @Test + public void testGL2ES2_Demo1Normal() throws InterruptedException { + final GLProfile glp = GLProfile.getGL2ES2(); + final GLCapabilities caps = new GLCapabilities(glp); + testGLFBODrawableImpl(caps, new GearsES2(0)); + } + + @Test + public void testGL2ES2_Demo1MSAA4() throws InterruptedException { + final GLProfile glp = GLProfile.getGL2ES2(); + final GLCapabilities caps = new GLCapabilities(glp); + caps.setSampleBuffers(true); + caps.setNumSamples(4); + testGLFBODrawableImpl(caps, new GearsES2(0)); + } + + @Test + public void testGL2ES2_Demo2Normal() throws InterruptedException { + final GLProfile glp = GLProfile.getGL2ES2(); + final GLCapabilities caps = new GLCapabilities(glp); + testGLFBODrawableImpl(caps, new MultisampleDemoES2(false)); + } + + @Test + public void testGL2ES2_Demo2MSAA4() throws InterruptedException { + final GLProfile glp = GLProfile.getGL2ES2(); + final GLCapabilities caps = new GLCapabilities(glp); + caps.setSampleBuffers(true); + caps.setNumSamples(4); + testGLFBODrawableImpl(caps, new MultisampleDemoES2(true)); + } + + @Test + public void testGL2ES2_FBODemoNormal() throws InterruptedException { + final GLProfile glp = GLProfile.getGL2ES2(); + final FBOMix2DemosES2 demo = new FBOMix2DemosES2(0); + demo.setDoRotation(false); + final GLCapabilities caps = new GLCapabilities(glp); + testGLFBODrawableImpl(caps, demo); + } + + @Test + public void testGL2ES2_FBODemoMSAA4() throws InterruptedException { + final GLProfile glp = GLProfile.getGL2ES2(); + final FBOMix2DemosES2 demo = new FBOMix2DemosES2(0); + demo.setDoRotation(false); + final GLCapabilities caps = new GLCapabilities(glp); + caps.setSampleBuffers(true); + caps.setNumSamples(4); + testGLFBODrawableImpl(caps, demo); + } + + @Test + public void testEGLES2_Demo0Normal() throws InterruptedException { + if( GLProfile.isAvailable(GLProfile.GLES2) ) { + final GLProfile glp = GLProfile.get(GLProfile.GLES2); + final GLCapabilities caps = new GLCapabilities(glp); + testGLFBODrawableImpl(caps, new GearsES2(0)); + } else { + System.err.println("EGL ES2 n/a"); + } + } + + @Test + public void testEGLES2_Demo0MSAA4() throws InterruptedException { + if( GLProfile.isAvailable(GLProfile.GLES2) ) { + final GLProfile glp = GLProfile.get(GLProfile.GLES2); + final GLCapabilities caps = new GLCapabilities(glp); + caps.setSampleBuffers(true); + caps.setNumSamples(4); + testGLFBODrawableImpl(caps, new GearsES2(0)); + } else { + System.err.println("EGL ES2 n/a"); + } + } + + boolean skipShot = false; + + void testGLFBODrawableImpl(GLCapabilities caps, GLEventListener demo) throws InterruptedException { + final GLReadBufferUtil screenshot = new GLReadBufferUtil(false, false); + caps.setFBO(true); + final GLDrawableFactory factory = GLDrawableFactory.getFactory(caps.getGLProfile()); + final GLDrawable fboDrawable = factory.createOffscreenDrawable(null, caps, null, widthStep*szStep, heightStep*szStep); + Assert.assertNotNull(fboDrawable); + Assert.assertTrue("Not an FBO Drawable", fboDrawable instanceof GLFBODrawableImpl); + + fboDrawable.setRealized(true); + Assert.assertTrue(fboDrawable.isRealized()); + + final FBObject fbo = ((GLFBODrawableImpl)fboDrawable).getFBObject(); + + System.out.println("Realized: "+fboDrawable); + System.out.println("Realized: "+fboDrawable.getChosenGLCapabilities()); + System.out.println("Realized: "+fbo); + + final GLContext context = fboDrawable.createContext(null); + Assert.assertNotNull(context); + + int res = context.makeCurrent(); + Assert.assertTrue(GLContext.CONTEXT_CURRENT_NEW==res || GLContext.CONTEXT_CURRENT==res); + context.release(); + + System.out.println("Post Create-Ctx: "+fbo); + final FBObject.Colorbuffer colorA = fbo.getColorbuffer(0); + Assert.assertNotNull(colorA); + final FBObject.RenderAttachment depthA = fbo.getDepthAttachment(); + Assert.assertNotNull(depthA); + + final OffscreenAutoDrawable glad = new OffscreenAutoDrawable(fboDrawable, context, null); + + glad.addGLEventListener(demo); + glad.addGLEventListener(new GLEventListener() { + volatile int displayCount=0; + volatile int reshapeCount=0; + public void init(GLAutoDrawable drawable) {} + public void dispose(GLAutoDrawable drawable) {} + public void display(GLAutoDrawable drawable) { + final GL gl = drawable.getGL(); + // System.err.println(Thread.currentThread().getName()+": ** display: "+displayCount+": step "+szStep+" "+drawable.getWidth()+"x"+drawable.getHeight()); + // System.err.println(Thread.currentThread().getName()+": ** FBO-THIS: "+fbo); + // System.err.println(Thread.currentThread().getName()+": ** FBO-SINK: "+fbo.getSamplingSinkFBO()); + // System.err.println(Thread.currentThread().getName()+": ** drawable-read: "+gl.getDefaultReadFramebuffer()); + if(skipShot) { + skipShot=false; + } else { + snapshot(getSimpleTestName("."), displayCount, "msaa"+fbo.getNumSamples(), gl, screenshot, TextureIO.PNG, null); + } + Assert.assertEquals(drawable.getWidth(), widthStep*szStep); + Assert.assertEquals(drawable.getHeight(), heightStep*szStep); + displayCount++; + } + public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { + System.err.println(Thread.currentThread().getName()+": ** reshape: "+reshapeCount+": step "+szStep+" "+width+"x"+height+" - "+drawable.getWidth()+"x"+drawable.getHeight()); + Assert.assertEquals(drawable.getWidth(), widthStep*szStep); + Assert.assertEquals(drawable.getHeight(), heightStep*szStep); + reshapeCount++; + } + }); + + // 0 - szStep = 2 + glad.display(); + + // 1, 2 (resize + display) + szStep = 1; + skipShot=true; + glad.setSize(widthStep*szStep, heightStep*szStep); + glad.display(); + Assert.assertEquals(glad.getWidth(), widthStep*szStep); + Assert.assertEquals(glad.getHeight(), heightStep*szStep); + { + // Check whether the attachment reference are still valid! + FBObject.Colorbuffer _colorA = fbo.getColorbuffer(0); + Assert.assertNotNull(_colorA); + Assert.assertTrue(colorA == _colorA); + Assert.assertTrue(colorA.equals(_colorA)); + FBObject.RenderAttachment _depthA = fbo.getDepthAttachment(); + Assert.assertNotNull(_depthA); + Assert.assertTrue(depthA == _depthA); + Assert.assertTrue(depthA.equals(_depthA)); + + _colorA = fbo.getColorbuffer(colorA); + Assert.assertNotNull(_colorA); + Assert.assertTrue(colorA == _colorA); + Assert.assertTrue(colorA.equals(_colorA)); + } + + // 3, 4 (resize + display) + szStep = 4; + skipShot=true; + glad.setSize(widthStep*szStep, heightStep*szStep); + glad.display(); + Assert.assertEquals(glad.getWidth(), widthStep*szStep); + Assert.assertEquals(glad.getHeight(), heightStep*szStep); + { + // Check whether the attachment reference are still valid! + FBObject.Colorbuffer _colorA = fbo.getColorbuffer(0); + Assert.assertNotNull(_colorA); + Assert.assertTrue(colorA == _colorA); + final FBObject.RenderAttachment _depthA = fbo.getDepthAttachment(); + Assert.assertNotNull(_depthA); + Assert.assertTrue(depthA == _depthA); + + _colorA = fbo.getColorbuffer(colorA); + Assert.assertNotNull(_colorA); + Assert.assertTrue(colorA == _colorA); + } + + // 5 + glad.display(); + Assert.assertEquals(glad.getWidth(), widthStep*szStep); + Assert.assertEquals(glad.getHeight(), heightStep*szStep); + + // 6, 7 (resize + display) + szStep = 3; + skipShot=true; + glad.setSize(widthStep*szStep, heightStep*szStep); + glad.display(); + Assert.assertEquals(glad.getWidth(), widthStep*szStep); + Assert.assertEquals(glad.getHeight(), heightStep*szStep); + + glad.destroy(); + System.out.println("Fin: "+fboDrawable); + + // final GLAutoDrawableDelegate glad = new GLAutoDrawableDelegate(fboDrawable, context); + } + + public static void main(String args[]) throws IOException { + org.junit.runner.JUnitCore.main(TestFBODrawableNEWT.class.getName()); + } + +} diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOMRTNEWT01.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOMRTNEWT01.java new file mode 100644 index 000000000..f7c83a03b --- /dev/null +++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOMRTNEWT01.java @@ -0,0 +1,266 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ +package com.jogamp.opengl.test.junit.jogl.acore; + +import com.jogamp.opengl.FBObject; +import com.jogamp.opengl.FBObject.TextureAttachment; +import com.jogamp.opengl.util.GLArrayDataServer; +import com.jogamp.opengl.util.GLReadBufferUtil; +import com.jogamp.opengl.util.PMVMatrix; +import com.jogamp.opengl.util.glsl.ShaderCode; +import com.jogamp.opengl.util.glsl.ShaderProgram; +import com.jogamp.opengl.util.glsl.ShaderState; +import com.jogamp.opengl.util.texture.TextureIO; +import com.jogamp.opengl.FBObject.Attachment.Type; +import com.jogamp.opengl.test.junit.jogl.demos.es2.RedSquareES2; +import com.jogamp.opengl.test.junit.util.MiscUtils; +import com.jogamp.opengl.test.junit.util.NEWTGLContext; +import com.jogamp.opengl.test.junit.util.UITestCase; + +import java.io.IOException; + +import javax.media.nativewindow.NativeSurface; +import javax.media.opengl.GL; +import javax.media.opengl.GL2ES2; +import javax.media.opengl.GL2GL3; +import javax.media.opengl.GLCapabilities; +import javax.media.opengl.GLDrawable; +import javax.media.opengl.GLPipelineFactory; +import javax.media.opengl.GLProfile; +import javax.media.opengl.GLUniformData; + +import org.junit.Assert; +import org.junit.Test; + +public class TestFBOMRTNEWT01 extends UITestCase { + static long durationPerTest = 10*40*2; // ms + + @Test + public void test01() throws InterruptedException { + final int step = 4; + final int width = 800; + final int height = 600; + // preset .. + if(!GLProfile.isAvailable(GLProfile.GL2GL3)) { + System.err.println("Test requires GL2/GL3 profile."); + return; + } + final NEWTGLContext.WindowContext winctx = NEWTGLContext.createOnscreenWindow( + new GLCapabilities(GLProfile.getGL2GL3()), width/step, height/step, true); + final GLDrawable drawable = winctx.context.getGLDrawable(); + GL2GL3 gl = winctx.context.getGL().getGL2GL3(); + gl = gl.getContext().setGL( GLPipelineFactory.create("javax.media.opengl.Debug", null, gl, null) ).getGL2GL3(); + System.err.println(winctx.context); + + Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError()); + // test code .. + final ShaderState st = new ShaderState(); + // st.setVerbose(true); + + final ShaderCode vp0 = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, RedSquareES2.class, "shader", + "shader/bin", "fbo-mrt-1", false); + final ShaderCode fp0 = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, RedSquareES2.class, "shader", + "shader/bin", "fbo-mrt-1", false); + final ShaderProgram sp0 = new ShaderProgram(); + sp0.add(gl, vp0, System.err); + sp0.add(gl, fp0, System.err); + Assert.assertTrue(0<=sp0.program()); + Assert.assertTrue(!sp0.inUse()); + Assert.assertTrue(!sp0.linked()); + Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError()); + st.attachShaderProgram(gl, sp0, false); + + final ShaderCode vp1 = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, RedSquareES2.class, "shader", + "shader/bin", "fbo-mrt-2", false); + final ShaderCode fp1 = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, RedSquareES2.class, "shader", + "shader/bin", "fbo-mrt-2", false); + final ShaderProgram sp1 = new ShaderProgram(); + sp1.add(gl, vp1, System.err); + sp1.add(gl, fp1, System.err); + Assert.assertTrue(0<=sp1.program()); + Assert.assertTrue(!sp1.inUse()); + Assert.assertTrue(!sp1.linked()); + Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError()); + st.attachShaderProgram(gl, sp1, true); + + final PMVMatrix pmvMatrix = new PMVMatrix(); + final GLUniformData pmvMatrixUniform = new GLUniformData("gcu_PMVMatrix", 4, 4, pmvMatrix.glGetPMvMatrixf()); + Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError()); + st.ownUniform(pmvMatrixUniform); + st.uniform(gl, pmvMatrixUniform); + Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError()); + + final GLArrayDataServer vertices0 = GLArrayDataServer.createGLSL("gca_Vertices", 3, GL.GL_FLOAT, false, 4, GL.GL_STATIC_DRAW); + // st.bindAttribLocation(gl, 0, vertices0); + vertices0.putf(0); vertices0.putf(1); vertices0.putf(0); + vertices0.putf(1); vertices0.putf(1); vertices0.putf(0); + vertices0.putf(0); vertices0.putf(0); vertices0.putf(0); + vertices0.putf(1); vertices0.putf(0); vertices0.putf(0); + vertices0.seal(gl, true); + st.ownAttribute(vertices0, true); + vertices0.enableBuffer(gl, false); + Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError()); + + final GLArrayDataServer colors0 = GLArrayDataServer.createGLSL("gca_Colors", 4, GL.GL_FLOAT, false, 4, GL.GL_STATIC_DRAW); + // st.bindAttribLocation(gl, 1, colors0); + colors0.putf(1); colors0.putf(0); colors0.putf(1); colors0.putf(1); + colors0.putf(0); colors0.putf(0); colors0.putf(1); colors0.putf(1); + colors0.putf(0); colors0.putf(0); colors0.putf(0); colors0.putf(1); + colors0.putf(0); colors0.putf(1); colors0.putf(1); colors0.putf(1); + colors0.seal(gl, true); + st.ownAttribute(colors0, true); + colors0.enableBuffer(gl, false); + Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError()); + + final GLUniformData texUnit0 = new GLUniformData("gcs_TexUnit0", 0); + st.ownUniform(texUnit0); + st.uniform(gl, texUnit0); + final GLUniformData texUnit1 = new GLUniformData("gcs_TexUnit1", 1); + st.ownUniform(texUnit1); + st.uniform(gl, texUnit1); + + final GLArrayDataServer texCoords0 = GLArrayDataServer.createGLSL("gca_TexCoords", 2, GL.GL_FLOAT, false, 4, GL.GL_STATIC_DRAW); + // st.bindAttribLocation(gl, 2, texCoords0); + texCoords0.putf(0f); texCoords0.putf(1f); + texCoords0.putf(1f); texCoords0.putf(1f); + texCoords0.putf(0f); texCoords0.putf(0f); + texCoords0.putf(1f); texCoords0.putf(0f); + texCoords0.seal(gl, true); + st.ownAttribute(texCoords0, true); + texCoords0.enableBuffer(gl, false); + Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError()); + + final int texA0Point = 0; // attachment point for texA0 + final int texA1Point = 1; // attachment point for texA1 + + // FBO w/ 2 texture2D color buffers + final FBObject fbo_mrt = new FBObject(); + fbo_mrt.reset(gl, drawable.getWidth(), drawable.getHeight()); + final TextureAttachment texA0 = fbo_mrt.attachTexture2D(gl, texA0Point, true, GL.GL_NEAREST, GL.GL_NEAREST, GL.GL_CLAMP_TO_EDGE, GL.GL_CLAMP_TO_EDGE); + final TextureAttachment texA1 = fbo_mrt.attachTexture2D(gl, texA1Point, true, GL.GL_NEAREST, GL.GL_NEAREST, GL.GL_CLAMP_TO_EDGE, GL.GL_CLAMP_TO_EDGE); + fbo_mrt.attachRenderbuffer(gl, Type.DEPTH, 24); + Assert.assertTrue( fbo_mrt.isStatusValid() ) ; + fbo_mrt.unbind(gl); + + // misc GL setup + gl.glClearColor(1, 1, 1, 1); + gl.glEnable(GL2ES2.GL_DEPTH_TEST); + Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError()); + + // reshape + pmvMatrix.glMatrixMode(PMVMatrix.GL_PROJECTION); + pmvMatrix.glLoadIdentity(); + pmvMatrix.glOrthof(0f, 1f, 0f, 1f, -10f, 10f); + pmvMatrix.glMatrixMode(PMVMatrix.GL_MODELVIEW); + pmvMatrix.glLoadIdentity(); + st.uniform(gl, pmvMatrixUniform); + Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError()); + + final int[] two_buffers = new int[] { GL.GL_COLOR_ATTACHMENT0+texA0Point, GL.GL_COLOR_ATTACHMENT0+texA1Point }; + final int[] bck_buffers = new int[] { GL2GL3.GL_BACK_LEFT }; + + final GLReadBufferUtil screenshot = new GLReadBufferUtil(true, false); + int step_i = 0; + int[] last_snap_size = new int[] { 0, 0 }; + + for(int i=0; i+ * TestFBODrawableNEWT.test01-F_rgba-I_rgba-S0_default-GL2-n0004-0800x0600.png + * TestFBODrawableNEWT.test01-F_rgba-I_rgba-S0_default-GL2-n0005-0800x0600.png + *+ * + * @param simpleTestName will be used as the filename prefix + * @param sn sequential number + * @param postSNDetail optional detail to be added to the filename after
sn
+ * @param gl the current GL context object. It's read drawable is being used as the pixel source and to gather some details which will end up in the filename.
+ * @param readBufferUtil the {@link GLReadBufferUtil} to be used to read the pixels for the screenshot.
+ * @param fileSuffix Optional file suffix without a dot defining the file type, i.e. "png"
.
+ * If null
the "png"
as defined in {@link TextureIO#PNG} is being used.
+ * @param destPath Optional platform dependent file path. It shall use {@link File#separatorChar} as is directory separator.
+ * It shall not end with a directory separator, {@link File#separatorChar}.
+ * If null
the current working directory is being used.
+ */
+ public static void snapshot(String simpleTestName, int sn, String postSNDetail, GL gl, GLReadBufferUtil readBufferUtil, String fileSuffix, String destPath) {
+ if(null == fileSuffix) {
+ fileSuffix = TextureIO.PNG;
+ }
+ final StringWriter filenameSW = new StringWriter();
+ {
+ final GLDrawable drawable = gl.getContext().getGLReadDrawable();
+ final GLCapabilitiesImmutable caps = drawable.getChosenGLCapabilities();
+ final String F_pfmt = readBufferUtil.hasAlpha() ? "rgba" : "rgb_";
+ final String pfmt = caps.getAlphaBits() > 0 ? "rgba" : "rgb_";
+ final String aaext = caps.getSampleExtension();
+ final int samples = caps.getNumSamples() ;
+ postSNDetail = null != postSNDetail ? "-"+postSNDetail : "";
+ final PrintWriter pw = new PrintWriter(filenameSW);
+ pw.printf("%s-n%04d%s-F_%s-I_%s-S%d_%s-%s-%04dx%04d.%s",
+ simpleTestName, sn, postSNDetail, F_pfmt, pfmt, samples, aaext, drawable.getGLProfile().getName(),
+ drawable.getWidth(), drawable.getHeight(), fileSuffix);
+ }
+ final String filename = null != destPath ? destPath + File.separator + filenameSW.toString() : filenameSW.toString();
+ System.err.println(Thread.currentThread().getName()+": ** screenshot: "+filename);
+ gl.glFinish(); // just make sure rendering finished ..
+ if(readBufferUtil.readPixels(gl, false)) {
+ readBufferUtil.write(new File(filename));
+ }
+ }
}
--
cgit v1.2.3
From 43a473b2005d7f59a7f4f5b8bc7ca9ae88b4e894 Mon Sep 17 00:00:00 2001
From: Sven Gothel EGL.eglGetDisplay(nativeDisplayID)
* inclusive EGL.eglInitialize(eglDisplayHandle, ..)
call.
- * @param eglDisplayHandle
+ * @param nativeDisplayID in/out array of size 1, passing the requested nativeVisualID, may return a different revised nativeVisualID handle
+ * @return the initialized EGL display ID, or 0
if not successful
*/
- public long eglGetAndInitDisplay(long nativeDisplayID);
+ public long eglGetAndInitDisplay(long[] nativeDisplayID);
/**
* Implementation should issue an EGL.eglTerminate(eglDisplayHandle)
call.
@@ -68,17 +69,17 @@ public class EGLGraphicsDevice extends DefaultGraphicsDevice implements Cloneabl
*/
public EGLGraphicsDevice(String connection, int unitID) {
super(NativeWindowFactory.TYPE_EGL, connection, unitID);
- this.nativeDisplayID = 0 ; // EGL.EGL_DEFAULT_DISPLAY
+ this.nativeDisplayID[0] = 0 ; // EGL.EGL_DEFAULT_DISPLAY
this.eglLifecycleCallback = null;
}
public EGLGraphicsDevice(long nativeDisplayID, long eglDisplay, String connection, int unitID, EGLDisplayLifecycleCallback eglLifecycleCallback) {
super(NativeWindowFactory.TYPE_EGL, connection, unitID, eglDisplay);
- this.nativeDisplayID = nativeDisplayID;
+ this.nativeDisplayID[0] = nativeDisplayID;
this.eglLifecycleCallback = eglLifecycleCallback;
}
- public long getNativeDisplayID() { return nativeDisplayID; }
+ public long getNativeDisplayID() { return nativeDisplayID[0]; }
@Override
public Object clone() {
@@ -113,7 +114,7 @@ public class EGLGraphicsDevice extends DefaultGraphicsDevice implements Cloneabl
@Override
public String toString() {
- return "EGLGraphicsDevice[type EGL, connection "+getConnection()+", unitID "+getUnitID()+", handle 0x"+Long.toHexString(getHandle())+", nativeDisplayID 0x"+Long.toHexString(nativeDisplayID)+"]";
+ return "EGLGraphicsDevice[type EGL, connection "+getConnection()+", unitID "+getUnitID()+", handle 0x"+Long.toHexString(getHandle())+", nativeDisplayID 0x"+Long.toHexString(nativeDisplayID[0])+", eglLifecycleCallback "+(null != eglLifecycleCallback)+"]";
}
}
--
cgit v1.2.3
From c5835a2e19a84cb08957d6c742e4334d578c3c66 Mon Sep 17 00:00:00 2001
From: Sven Gothel ==
produce the same result.
*/
public static String getNativeWindowType(boolean useCustom) {
return useCustom?nativeWindowingTypeCustom:nativeWindowingTypePure;
@@ -301,13 +303,13 @@ public abstract class NativeWindowFactory {
/** Don't know if we shall add this factory here ..
public static AbstractGraphicsDevice createGraphicsDevice(String type, String connection, int unitID, long handle, ToolkitLock locker) {
- if(type.equals(TYPE_EGL)) {
+ if(TYPE_EGL == type) {
return new
- } else if(type.equals(TYPE_X11)) {
- } else if(type.equals(TYPE_WINDOWS)) {
- } else if(type.equals(TYPE_MACOSX)) {
- } else if(type.equals(TYPE_AWT)) {
- } else if(type.equals(TYPE_DEFAULT)) {
+ } else if(TYPE_X11 == type) {
+ } else if(TYPE_WINDOWS == type) {
+ } else if(TYPE_MACOSX == type)) {
+ } else if(TYPE_AWT == type) {
+ } else if(TYPE_DEFAULT == type) {
}
} */
diff --git a/src/nativewindow/classes/jogamp/nativewindow/NativeWindowFactoryImpl.java b/src/nativewindow/classes/jogamp/nativewindow/NativeWindowFactoryImpl.java
index 2c2a627a4..29564da3b 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/NativeWindowFactoryImpl.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/NativeWindowFactoryImpl.java
@@ -39,7 +39,6 @@ import javax.media.nativewindow.NativeWindow;
import javax.media.nativewindow.NativeWindowFactory;
import javax.media.nativewindow.ToolkitLock;
-import com.jogamp.common.os.Platform;
import com.jogamp.common.util.ReflectionUtil;
import com.jogamp.common.util.ReflectionUtil.AWTNames;
@@ -76,17 +75,17 @@ public class NativeWindowFactoryImpl extends NativeWindowFactory {
private NativeWindow getAWTNativeWindow(Object winObj, AbstractGraphicsConfiguration config) {
if (nativeWindowConstructor == null) {
try {
- String windowingType = getNativeWindowType(true);
- String windowClassName = null;
+ final String windowingType = getNativeWindowType(true);
+ final String windowClassName;
// We break compile-time dependencies on the AWT here to
// make it easier to run this code on mobile devices
- if (windowingType.equals(TYPE_WINDOWS)) {
+ if (TYPE_WINDOWS == windowingType) {
windowClassName = "jogamp.nativewindow.jawt.windows.WindowsJAWTWindow";
- } else if (windowingType.equals(TYPE_MACOSX)) {
+ } else if (TYPE_MACOSX == windowingType) {
windowClassName = "jogamp.nativewindow.jawt.macosx.MacOSXJAWTWindow";
- } else if (windowingType.equals(TYPE_X11)) {
+ } else if (TYPE_X11 == windowingType) {
// Assume Linux, Solaris, etc. Should probably test for these explicitly.
windowClassName = "jogamp.nativewindow.jawt.x11.X11JAWTWindow";
} else {
diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTJNILibLoader.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTJNILibLoader.java
index 2377c2be6..f579da217 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTJNILibLoader.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTJNILibLoader.java
@@ -60,7 +60,7 @@ public class JAWTJNILibLoader extends NWJNILibLoader {
// ensure references from jogl_awt shared object
// will succeed since JAWT shared object isn't in
// default library path
- if ( ! NativeWindowFactory.TYPE_MACOSX.equals( NativeWindowFactory.getNativeWindowType(false) ) ) {
+ if ( NativeWindowFactory.TYPE_MACOSX != NativeWindowFactory.getNativeWindowType(false) ) {
try {
loadLibrary("jawt", null, true, JAWTJNILibLoader.class.getClassLoader());
} catch (Throwable t) {
--
cgit v1.2.3
From f2cfb6119a3663715ed2d572643949b3bef58662 Mon Sep 17 00:00:00 2001
From: Sven Gothel