From 54d0ff131097a2cd9a91a0c1dd84deb8b1f7d0ac Mon Sep 17 00:00:00 2001
From: Sven Gothel
+ jar/jogl-all.jar,
+ jar/jogl-test.jar">
@@ -43,8 +43,8 @@ JOGL NEWT JNLP Applet Runner Special Keys:
pluginspage="http://java.sun.com/javase/downloads/ea.jsp"
archive="jar/applet-launcher.jar,
jar/gluegen-rt.jar,
- jar/jogl.all.jar,
- jar/jogl.test.jar"
+ jar/jogl-all.jar,
+ jar/jogl-test.jar"
codebase_lookup" value="false"
subapplet.classname="com.jogamp.newt.awt.applet.JOGLNewtApplet1Run"
subapplet.displayname="JOGL GearsES2 Applet"
@@ -75,8 +75,8 @@ The applet above is instantiated with the following code:
<param name="code" value="org.jdesktop.applet.util.JNLPAppletLauncher">
<param name="archive" value="jar/applet-launcher.jar,
jar/gluegen-rt.jar,
- jar/jogl.all.jar,
- jar/jogl.test.jar">
+ jar/jogl-all.jar,
+ jar/jogl-test.jar">
<param name="codebase_lookup" value="false">
<param name="subapplet.classname" value="com.jogamp.newt.awt.applet.JOGLNewtApplet1Run">
<param name="subapplet.displayname" value="JOGL GearsES2 Applet">
@@ -97,8 +97,8 @@ The applet above is instantiated with the following code:
pluginspage="http://java.sun.com/javase/downloads/ea.jsp"
archive="jar/applet-launcher.jar,
jar/gluegen-rt.jar,
- jar/jogl.all.jar,
- jar/jogl.test.jar"
+ jar/jogl-all.jar,
+ jar/jogl-test.jar"
codebase_lookup" value="false"
subapplet.classname="com.jogamp.newt.awt.applet.JOGLNewtApplet1Run"
subapplet.displayname="JOGL GearsES2 Applet"
diff --git a/jnlp-files/jogl-applet-runner-newt-gears-normal-napplet.html b/jnlp-files/jogl-applet-runner-newt-gears-normal-napplet.html
index 9db6d8cc2..37473befe 100644
--- a/jnlp-files/jogl-applet-runner-newt-gears-normal-napplet.html
+++ b/jnlp-files/jogl-applet-runner-newt-gears-normal-napplet.html
@@ -20,8 +20,8 @@ JOGL NEWT Applet Runner Special Keys:
width="200" height="200">
+ jar/jogl-all.jar,
+ jar/jogl-test.jar">
@@ -34,8 +34,8 @@ JOGL NEWT Applet Runner Special Keys:
type="application/x-java-applet;version=1.6"
pluginspage="http://java.sun.com/javase/downloads/ea.jsp"
archive="jar/gluegen-rt.jar,
- jar/jogl.all.jar,
- jar/jogl.test.jar"
+ jar/jogl-all.jar,
+ jar/jogl-test.jar"
java_arguments="-Dsun.java2d.noddraw=true"
gl_event_listener_class="com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2"
gl_profile="GL2ES2"
@@ -58,8 +58,8 @@ The applet above is instantiated with the following code:
width="200" height="200">
<param name="code" value="com.jogamp.newt.awt.applet.JOGLNewtApplet1Run">
<param name="archive" value="jar/gluegen-rt.jar,
- jar/jogl.all.jar,
- jar/jogl.test.jar">
+ jar/jogl-all.jar,
+ jar/jogl-test.jar">
<param name="java_arguments" value="-Dsun.java2d.noddraw=true">
<param name="gl_event_listener_class" value="com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2">
<param name="gl_profile" value="GL2ES2">
@@ -72,8 +72,8 @@ The applet above is instantiated with the following code:
type="application/x-java-applet;version=1.6"
pluginspage="http://java.sun.com/javase/downloads/ea.jsp"
archive="jar/gluegen-rt.jar,
- jar/jogl.all.jar,
- jar/jogl.test.jar"
+ jar/jogl-all.jar,
+ jar/jogl-test.jar"
java_arguments="-Dsun.java2d.noddraw=true"
gl_event_listener_class="com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2"
gl_profile="GL2ES2"
@@ -90,7 +90,7 @@ The applet above is instantiated with the following code:
-Note that the jogl.test.jar, which contains the test applet class, +Note that the jogl-test.jar, which contains the test applet class, does not need to be signed! JogAmp Community signs jogl.jar and gluegen-rt.jar, which contain JOGL's supporting classes; this is the only diff --git a/jnlp-files/jogl-applet-runner-newt-gears-normal-napplet2.html b/jnlp-files/jogl-applet-runner-newt-gears-normal-napplet2.html index ba2f69ef4..63df4ed60 100644 --- a/jnlp-files/jogl-applet-runner-newt-gears-normal-napplet2.html +++ b/jnlp-files/jogl-applet-runner-newt-gears-normal-napplet2.html @@ -21,8 +21,8 @@ If Applet is out of browser window, it is closeable. width="200" height="200"> + jar/jogl-all.jar, + jar/jogl-test.jar"> @@ -36,8 +36,8 @@ If Applet is out of browser window, it is closeable. type="application/x-java-applet;version=1.6" pluginspage="http://java.sun.com/javase/downloads/ea.jsp" archive="jar/gluegen-rt.jar, - jar/jogl.all.jar, - jar/jogl.test.jar" + jar/jogl-all.jar, + jar/jogl-test.jar" java_arguments="-Dsun.java2d.noddraw=true" gl_event_listener_class="com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2" gl_profile="GL2ES2" @@ -61,8 +61,8 @@ The applet above is instantiated with the following code: width="200" height="200"> <param name="code" value="com.jogamp.newt.awt.applet.JOGLNewtApplet1Run"> <param name="archive" value="jar/gluegen-rt.jar, - jar/jogl.all.jar, - jar/jogl.test.jar"> + jar/jogl-all.jar, + jar/jogl-test.jar"> <param name="java_arguments" value="-Dsun.java2d.noddraw=true"> <param name="gl_event_listener_class" value="com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2"> <param name="gl_profile" value="GL2ES2"> @@ -76,8 +76,8 @@ The applet above is instantiated with the following code: type="application/x-java-applet;version=1.6" pluginspage="http://java.sun.com/javase/downloads/ea.jsp" archive="jar/gluegen-rt.jar, - jar/jogl.all.jar, - jar/jogl.test.jar" + jar/jogl-all.jar, + jar/jogl-test.jar" java_arguments="-Dsun.java2d.noddraw=true" gl_event_listener_class="com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2" gl_profile="GL2ES2" @@ -95,7 +95,7 @@ The applet above is instantiated with the following code:
-Note that the jogl.test.jar, which contains the test applet class,
+Note that the jogl-test.jar, which contains the test applet class,
does not need to be signed! JogAmp Community signs
jogl.jar and gluegen-rt.jar, which contain
JOGL's supporting classes; this is the only
diff --git a/jnlp-files/jogl-applet-runner-newt-gears-normal.html b/jnlp-files/jogl-applet-runner-newt-gears-normal.html
index c8d654dbc..a6dd16a0c 100644
--- a/jnlp-files/jogl-applet-runner-newt-gears-normal.html
+++ b/jnlp-files/jogl-applet-runner-newt-gears-normal.html
@@ -35,8 +35,8 @@ JOGL NEWT JNLP Applet Runner Special Keys:
+ jar/jogl-all.jar,
+ jar/jogl-test.jar">
@@ -58,8 +58,8 @@ JOGL NEWT JNLP Applet Runner Special Keys:
pluginspage="http://java.sun.com/javase/downloads/ea.jsp"
archive="jar/applet-launcher.jar,
jar/gluegen-rt.jar,
- jar/jogl.all.jar,
- jar/jogl.test.jar"
+ jar/jogl-all.jar,
+ jar/jogl-test.jar"
codebase_lookup" value="false"
subapplet.classname="com.jogamp.newt.awt.applet.JOGLNewtApplet1Run"
subapplet.displayname="JOGL GearsES2 Applet"
@@ -91,8 +91,8 @@ The applet above is instantiated with the following code:
<param name="code" value="org.jdesktop.applet.util.JNLPAppletLauncher">
<param name="archive" value="jar/applet-launcher.jar,
jar/gluegen-rt.jar,
- jar/jogl.all.jar,
- jar/jogl.test.jar">
+ jar/jogl-all.jar,
+ jar/jogl-test.jar">
<param name="codebase_lookup" value="false">
<param name="subapplet.classname" value="com.jogamp.newt.awt.applet.JOGLNewtApplet1Run">
<param name="subapplet.displayname" value="JOGL GearsES2 Applet">
@@ -114,8 +114,8 @@ The applet above is instantiated with the following code:
pluginspage="http://java.sun.com/javase/downloads/ea.jsp"
archive="jar/applet-launcher.jar,
jar/gluegen-rt.jar,
- jar/jogl.all.jar,
- jar/jogl.test.jar"
+ jar/jogl-all.jar,
+ jar/jogl-test.jar"
codebase_lookup" value="false"
subapplet.classname="com.jogamp.newt.awt.applet.JOGLNewtApplet1Run"
subapplet.displayname="JOGL GearsES2 Applet"
@@ -154,7 +154,7 @@ Where the referenced JNLP file jogl-applet-runner-newt.jnlp looks as fo
<resources>
<j2se href="http://java.sun.com/products/autodl/j2se" version="1.4+"/>
<property name="sun.java2d.noddraw" value="true"/>
- <jar href="jar/jogl.test.jar" main="true"/>
+ <jar href="jar/jogl-test.jar" main="true"/>
<extension name="jogl-all-awt" href="http://jogamp.org/deployment/jogamp-current/jogl-all-awt.jnlp" />
</resources>
@@ -170,7 +170,7 @@ Where the referenced JNLP file jogl-applet-runner-newt.jnlp looks as fo
-Note that the jogl.test.jar, which contains the test applet class,
+Note that the jogl-test.jar, which contains the test applet class,
does not need to be signed! JogAmp Community signs
applet-launcher.jar, jogl.jar and gluegen-rt.jar, which contain the
JNLPAppletLauncher and JOGL's supporting classes; this is the only
diff --git a/jnlp-files/jogl-applet-runner-newt-gears-special-napplet.html b/jnlp-files/jogl-applet-runner-newt-gears-special-napplet.html
index 3c1895b45..7df167844 100644
--- a/jnlp-files/jogl-applet-runner-newt-gears-special-napplet.html
+++ b/jnlp-files/jogl-applet-runner-newt-gears-special-napplet.html
@@ -11,8 +11,8 @@ JOGL NEWT JNLP Applet Runner Special Keys:
width="1" height="1">
+ jar/jogl-all.jar,
+ jar/jogl-test.jar">
@@ -32,8 +32,8 @@ JOGL NEWT JNLP Applet Runner Special Keys:
type="application/x-java-applet;version=1.6"
pluginspage="http://java.sun.com/javase/downloads/ea.jsp"
archive="jar/gluegen-rt.jar,
- jar/jogl.all.jar,
- jar/jogl.test.jar"
+ jar/jogl-all.jar,
+ jar/jogl-test.jar"
java_arguments="-Dsun.java2d.noddraw=true"
gl_event_listener_class="com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2"
gl_profile="GL2ES2"
diff --git a/jnlp-files/jogl-applet-runner-newt-gears-special.html b/jnlp-files/jogl-applet-runner-newt-gears-special.html
index dcbe898e2..0f5911414 100644
--- a/jnlp-files/jogl-applet-runner-newt-gears-special.html
+++ b/jnlp-files/jogl-applet-runner-newt-gears-special.html
@@ -12,8 +12,8 @@ JOGL NEWT JNLP Applet Runner Special Keys:
+ jar/jogl-all.jar,
+ jar/jogl-test.jar">
@@ -42,8 +42,8 @@ JOGL NEWT JNLP Applet Runner Special Keys:
pluginspage="http://java.sun.com/javase/downloads/ea.jsp"
archive="jar/applet-launcher.jar,
jar/gluegen-rt.jar,
- jar/jogl.all.jar,
- jar/jogl.test.jar"
+ jar/jogl-all.jar,
+ jar/jogl-test.jar"
codebase_lookup" value="false"
subapplet.classname="com.jogamp.newt.awt.applet.JOGLNewtApplet1Run"
subapplet.displayname="JOGL GearsES2 Applet Transparent"
diff --git a/jnlp-files/jogl-applet-runner-newt.jnlp b/jnlp-files/jogl-applet-runner-newt.jnlp
index 259e39f18..c33e1b761 100644
--- a/jnlp-files/jogl-applet-runner-newt.jnlp
+++ b/jnlp-files/jogl-applet-runner-newt.jnlp
@@ -12,7 +12,7 @@
- * Basic FBO is supported if the context is either GL-ES >= 2.0, GL >= core 3.0 or implements the extensions
- *
- * Basic FBO support may only include one color attachment and no multisampling,
- * as well as limited internal formats for renderbuffer.
- *
- * Full FBO is supported if the context is either GL >= core 3.0 or implements the extensions
- *
- * Full FBO support includes multiple color attachments and multisampling.
- * Always an instance of {@link Attachment}. Either an instance of {@link ColorAttachment} or {@link TextureAttachment}.
*/
- public static final boolean supportsFullFBO(GL gl) {
- return !forceMinimumFBOSupport &&
- ( 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;
- }
+ public static interface Colorbuffer {
+ /**
+ * Initializes the color buffer and set it's parameter, if uninitialized, i.e. name is Implementation employs an initialization counter, hence it can be paired recursively with {@link #free(GL)}. Implementation employs an initialization counter, hence it can be paired recursively with {@link #initialize(GL)}.
@@ -232,9 +265,9 @@ public class FBObject {
if( ! ( o instanceof Attachment ) ) return false;
final Attachment a = (Attachment)o;
return type == a.type &&
- format == a.format ||
- width == a.width ||
- height== a.height ||
+ format == a.format &&
+ width == a.width &&
+ height== a.height &&
name == a.name ;
}
@@ -259,8 +292,7 @@ public class FBObject {
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+"]";
+ ", name 0x"+Integer.toHexString(name)+", obj 0x"+Integer.toHexString(objectHashCode())+"]";
}
public static Type getType(int attachmentPoint, int maxColorAttachments) {
@@ -277,7 +309,7 @@ public class FBObject {
}
}
}
-
+
/** Other renderbuffer attachment which maybe a colorbuffer, depth or stencil. */
public static class RenderAttachment extends Attachment {
private int samples;
@@ -339,14 +371,13 @@ public class FBObject {
}
@Override
- public void initialize(GL gl) throws GLException {
- super.initialize(gl);
- if( 1 == getInitCounter() && 0 == getName() ) {
+ public boolean initialize(GL gl) throws GLException {
+ final boolean init = 0 == getName();
+ if( init ) {
+ int glerr = checkPreGLError(gl);
+
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());
@@ -355,43 +386,37 @@ public class FBObject {
} else {
gl.glRenderbufferStorage(GL.GL_RENDERBUFFER, format, getWidth(), getHeight());
}
- int glerr = gl.glGetError();
+ 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);
}
}
+ return init;
}
@Override
public void free(GL gl) {
- if(1 == getInitCounter() && resourceOwner && 0 != getName() ) {
- final int[] name = new int[] { getName() };
+ final int[] name = new int[] { getName() };
+ if( 0 != name[0] ) {
gl.glDeleteRenderbuffers(1, name, 0);
+ setName(0);
+ if(DEBUG) {
+ System.err.println("Attachment.free: "+this);
+ }
}
- 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()+"]";
+ ", name 0x"+Integer.toHexString(getName())+", obj 0x"+Integer.toHexString(objectHashCode())+"]";
}
}
- /**
- * 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) {
@@ -444,9 +469,11 @@ public class FBObject {
* @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() ) {
+ public boolean initialize(GL gl) throws GLException {
+ final boolean init = 0 == getName();
+ if( init ) {
+ int glerr = checkPreGLError(gl);
+
final int[] name = new int[] { -1 };
gl.glGenTextures(1, name, 0);
if(0 == name[0]) {
@@ -468,31 +495,111 @@ public class FBObject {
if( 0 < wrapT ) {
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, wrapT);
}
- int glerr = gl.glGetError();
+ 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);
+ if(DEBUG) {
+ System.err.println("Attachment.init: "+this);
+ }
}
+ return init;
}
@Override
public void free(GL gl) {
- if(1 == getInitCounter() && resourceOwner && 0 != getName() ) {
- final int[] name = new int[] { getName() };
+ final int[] name = new int[] { getName() };
+ if( 0 != name[0] ) {
gl.glDeleteTextures(1, name, 0);
+ setName(0);
+ if(DEBUG) {
+ System.err.println("Attachment.free: "+this);
+ }
}
- super.free(gl);
+ }
+ }
+
+ /**
+ * Creates a color {@link TextureAttachment}, i.e. type {@link Type#COLOR_TEXTURE},
+ * 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}.true
if basic FBO support is available, otherwise false
.
- * ARB_ES2_compatibility
, ARB_framebuffer_object
, EXT_framebuffer_object
or OES_framebuffer_object
.
- * true
if full FBO support is available, otherwise false
.
- * ARB_framebuffer_object
, or all of
- * EXT_framebuffer_object
, EXT_framebuffer_multisample
,
- * EXT_framebuffer_blit
, GL_EXT_packed_depth_stencil
.
- * zero
.
+ * @return true
if newly initialized, otherwise false
.
+ * @throws GLException if buffer generation or setup fails. The just created buffer name will be deleted in this case.
+ */
+ public boolean initialize(GL gl) throws GLException;
+
+ /**
+ * Releases the color buffer if initialized, i.e. name is not zero
.
+ * @throws GLException if buffer release fails.
+ */
+ public void free(GL gl) throws GLException;
+
+ /**
+ * Writes the internal format to the given GLCapabilities object.
+ * @param caps the destination for format bits
+ * @param rgba8Avail whether rgba8 is available
+ */
+ public void formatToGLCapabilities(GLCapabilities caps, boolean rgba8Avail);
}
/** Common super class of all attachments */
@@ -155,21 +134,89 @@ public class FBObject {
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;
}
+ /**
+ * Writes the internal format to the given GLCapabilities object.
+ * @param caps the destination for format bits
+ * @param rgba8Avail whether rgba8 is available
+ */
+ public final void formatToGLCapabilities(GLCapabilities caps, boolean rgba8Avail) {
+ final int _format;
+ switch(format) {
+ case GL.GL_RGBA:
+ _format = rgba8Avail ? GL.GL_RGBA8 : GL.GL_RGBA4;
+ break;
+ case GL.GL_RGB:
+ _format = rgba8Avail ? GL.GL_RGB8 : GL.GL_RGB565;
+ break;
+ default:
+ _format = format;
+ }
+ switch(_format) {
+ case GL.GL_RGBA4:
+ caps.setRedBits(4);
+ caps.setGreenBits(4);
+ caps.setBlueBits(4);
+ caps.setAlphaBits(4);
+ break;
+ case GL.GL_RGB5_A1:
+ caps.setRedBits(5);
+ caps.setGreenBits(5);
+ caps.setBlueBits(5);
+ caps.setAlphaBits(1);
+ break;
+ case GL.GL_RGB565:
+ caps.setRedBits(5);
+ caps.setGreenBits(6);
+ caps.setBlueBits(5);
+ caps.setAlphaBits(0);
+ break;
+ case GL.GL_RGB8:
+ caps.setRedBits(8);
+ caps.setGreenBits(8);
+ caps.setBlueBits(8);
+ caps.setAlphaBits(0);
+ break;
+ case GL.GL_RGBA8:
+ caps.setRedBits(8);
+ caps.setGreenBits(8);
+ caps.setBlueBits(8);
+ caps.setAlphaBits(8);
+ break;
+ case GL.GL_DEPTH_COMPONENT16:
+ caps.setDepthBits(16);
+ break;
+ case GL.GL_DEPTH_COMPONENT24:
+ caps.setDepthBits(24);
+ break;
+ case GL.GL_DEPTH_COMPONENT32:
+ caps.setDepthBits(32);
+ break;
+ case GL.GL_STENCIL_INDEX1:
+ caps.setStencilBits(1);
+ break;
+ case GL.GL_STENCIL_INDEX4:
+ caps.setStencilBits(4);
+ break;
+ case GL.GL_STENCIL_INDEX8:
+ caps.setStencilBits(8);
+ break;
+ case GL.GL_DEPTH24_STENCIL8:
+ caps.setDepthBits(24);
+ caps.setStencilBits(8);
+ break;
+ default:
+ throw new IllegalArgumentException("format invalid: 0x"+Integer.toHexString(format));
+ }
+ }
+
/** width of attachment */
public final int getWidth() { return width; }
/** height of attachment */
@@ -180,45 +227,31 @@ public class FBObject {
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
.
- * zero
.
+ *
+ final boolean init = 0 == name;
+ if( init ) {
do init ..
- freeResources = true; // if all OK
}
- */
- }
+ return init;
+ *
+ * @return true
if newly initialized, otherwise false
.
+ * @throws GLException if buffer generation or setup fails. The just created buffer name will be deleted in this case.
+ */
+ public abstract boolean initialize(GL gl) throws GLException;
/**
- * Releases the attachment buffer if initialized, i.e. name is zero
.
- * zero
.
+ *
+ if(0 != name) {
do free ..
- }
- super.free(gl);
- */
- initCounter--;
- if(0 == initCounter) {
- resourceOwner = false;
name = 0;
}
- if(DEBUG) {
- System.err.println("Attachment.free: "+this);
- }
- }
+ *
+ * @throws GLException if buffer release fails.
+ */
+ public abstract void free(GL gl) throws GLException;
/**
* true
if you request alpha channel, otherwise false
;
+ * @param width texture width
+ * @param height texture height
+ * @return the created and uninitialized color {@link TextureAttachment}
+ */
+ public static final TextureAttachment createColorTextureAttachment(GLProfile glp, boolean alpha, int width, int height) {
+ return createColorTextureAttachment(glp, alpha, width, height, GL.GL_NEAREST, GL.GL_NEAREST, GL.GL_CLAMP_TO_EDGE, GL.GL_CLAMP_TO_EDGE);
+ }
+
+ /**
+ * Creates a color {@link TextureAttachment}, i.e. type {@link Type#COLOR_TEXTURE},
+ * selecting the texture data type and format automatically.
+ *
+ * @param glp the chosen {@link GLProfile}
+ * @param alpha set to true
if you request alpha channel, otherwise false
;
+ * @param width texture width
+ * @param height texture height
+ * @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 the created and uninitialized color {@link TextureAttachment}
+ */
+ public static final TextureAttachment createColorTextureAttachment(GLProfile glp, boolean alpha, int width, int height,
+ int magFilter, int minFilter, int wrapS, int wrapT) {
+ final int textureInternalFormat, textureDataFormat, textureDataType;
+ if(glp.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 createColorTextureAttachment(textureInternalFormat, width, height, textureDataFormat, textureDataType, magFilter, minFilter, wrapS, wrapT);
+ }
+
+ /**
+ * Creates a color {@link TextureAttachment}, i.e. type {@link Type#COLOR_TEXTURE}.
+ *
+ * @param internalFormat internalFormat parameter to {@link GL#glTexImage2D(int, int, int, int, int, int, int, int, long)}
+ * @param width texture width
+ * @param height texture height
+ * @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 the created and uninitialized color {@link TextureAttachment}
+ */
+ public static final TextureAttachment createColorTextureAttachment(int internalFormat, int width, int height, int dataFormat, int dataType,
+ int magFilter, int minFilter, int wrapS, int wrapT) {
+ return new TextureAttachment(Type.COLOR_TEXTURE, internalFormat, width, height, dataFormat, dataType,
+ magFilter, minFilter, wrapS, wrapT, 0 /* name */);
+ }
+
+ private static boolean hasAlpha(int format) {
+ switch(format) {
+ case GL.GL_RGBA8:
+ case GL.GL_RGBA4:
+ case GL.GL_RGBA:
+ case GL.GL_BGRA:
+ case 4:
+ return true;
+ default:
+ return false;
}
}
private boolean initialized;
- private boolean basicFBOSupport;
private boolean fullFBOSupport;
private boolean rgba8Avail;
private boolean depth24Avail;
@@ -523,6 +630,9 @@ public class FBObject {
//
private final void validateColorAttachmentPointRange(int point) {
+ if(!initialized) {
+ throw new GLException("FBO not initialized");
+ }
if(maxColorAttachments != colorAttachmentPoints.length) {
throw new InternalError("maxColorAttachments "+maxColorAttachments+", array.lenght "+colorAttachmentPoints);
}
@@ -621,7 +731,6 @@ public class FBObject {
this.initialized = false;
// TBD @ init
- this.basicFBOSupport = false;
this.fullFBOSupport = false;
this.rgba8Avail = false;
this.depth24Avail = false;
@@ -657,14 +766,11 @@ public class FBObject {
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) ) {
+ }
+ if( !gl.hasBasicFBOSupport() ) {
throw new GLException("FBO not supported w/ context: "+gl.getContext()+", "+this);
}
-
- basicFBOSupport = true;
+ fullFBOSupport = gl.hasFullFBOSupport();
rgba8Avail = gl.isGL2GL3() || gl.isExtensionAvailable(GLExtensions.OES_rgb8_rgba8);
depth24Avail = fullFBOSupport || gl.isExtensionAvailable(GLExtensions.OES_depth24);
@@ -680,10 +786,7 @@ public class FBObject {
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 glerr = checkPreGLError(gl);
int realMaxColorAttachments = 1;
maxColorAttachments = 1;
@@ -703,16 +806,7 @@ public class FBObject {
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));
- }
- }
+ maxSamples = gl.getMaxRenderbufferSamples();
if(!forceMinimumFBOSupport) {
gl.glGetIntegerv(GL.GL_MAX_TEXTURE_SIZE, val, 0);
maxTextureSize = val[0];
@@ -733,10 +827,9 @@ public class FBObject {
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("FBObject "+width+"x"+height+", "+samples+" -> "+this.samples+" samples");
System.err.println("fullFBOSupport: "+fullFBOSupport);
- System.err.println("maxColorAttachments: "+maxColorAttachments+"/"+realMaxColorAttachments);
+ System.err.println("maxColorAttachments: "+maxColorAttachments+"/"+realMaxColorAttachments+" [capped/real]");
System.err.println("maxSamples: "+maxSamples);
System.err.println("maxTextureSize: "+maxTextureSize);
System.err.println("maxRenderbufferSize: "+maxRenderbufferSize);
@@ -761,12 +854,8 @@ public class FBObject {
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);
- }
-
+ resetMSAATexture2DSink(gl);
+
// generate fbo ..
gl.glGenFramebuffers(1, val, 0);
fbName = val[0];
@@ -780,7 +869,8 @@ public class FBObject {
if(!gl.glIsFramebuffer(fbName)) {
checkNoError(gl, GL.GL_INVALID_VALUE, "FBObject Init.isFB"); // throws GLException
}
- bound = true;
+ bound = true;
+ samplesSinkDirty = true;
initialized = true;
updateStatus(gl);
@@ -797,7 +887,7 @@ public class FBObject {
* to match the new given parameters.
*
- * Currently incompatibility and hence recreation is given if + * Incompatibility and hence recreation is forced if * the size or sample count doesn't match for subsequent calls. *
* @@ -820,17 +910,17 @@ public class FBObject { * 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. + * Currently incompatibility and hence recreation of the attachments will be performed + * 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 newWidth the new width, it's minimum is capped to 1 + * @param newHeight the new height, it's minimum is capped to 1 * @param newSamples if > 0, MSAA will be used, otherwise no multisampling. Will be capped to {@link #getMaxSamples()}. - * @throws GLException in case of an error + * @throws GLException in case of an error, i.e. size too big, etc .. */ public final void reset(GL gl, int newWidth, int newHeight, int newSamples) { if(!initialized) { @@ -841,13 +931,15 @@ public class FBObject { newSamples = newSamples <= maxSamples ? newSamples : maxSamples; // clamp if( newWidth != width || newHeight != height || newSamples != samples ) { + if(0>=newWidth) { newWidth = 1; } + if(0>=newHeight) { newHeight = 1; } if(newWidth > 2 + maxTextureSize || newHeight> 2 + maxTextureSize || newWidth > maxRenderbufferSize || newHeight> maxRenderbufferSize ) { throw new GLException("size "+width+"x"+height+" exceeds on of the maxima [texture "+maxTextureSize+", renderbuffer "+maxRenderbufferSize+"]"); } if(DEBUG) { - System.err.println("FBObject.reset - START - "+this); + System.err.println("FBObject.reset - START - "+width+"x"+height+", "+samples+" -> "+newWidth+"x"+newHeight+", "+newSamples+"; "+this); } final boolean wasBound = isBound(); @@ -856,11 +948,18 @@ public class FBObject { height = newHeight; samples = newSamples; detachAllImpl(gl, true , true); - resetMSAATexture2DSink(gl); - if(wasBound) { - bind(gl); - } else { + /** + * Postpone reset of samplesSink until syncFramebuffer, + * issued at use(..) method (swapBuffer usually initiates it). + * This allows another thread to still use the 'samplesSinkTexture' + * until swapBuffer happens and does not invalidate the GL_FRONT + * FBO (framebuffer & texture). + resetMSAATexture2DSink(gl); + */ + samplesSinkDirty = true; + + if(!wasBound) { unbind(gl); } @@ -870,6 +969,28 @@ public class FBObject { } } + /** + * Writes the internal format of the attachments to the given GLCapabilities object. + * @param caps the destination for format bits + */ + public final void formatToGLCapabilities(GLCapabilities caps) { + caps.setSampleBuffers(samples > 0); + caps.setNumSamples(samples); + caps.setDepthBits(0); + caps.setStencilBits(0); + + final Colorbuffer cb = samples > 0 ? getSamplingSink() : getColorbuffer(0); + if(null != cb) { + cb.formatToGLCapabilities(caps, rgba8Avail); + } + if(null != depth) { + depth.formatToGLCapabilities(caps, rgba8Avail); + } + if(null != stencil && stencil != depth) { + stencil.formatToGLCapabilities(caps, rgba8Avail); + } + } + /** * 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 @@ -954,6 +1075,15 @@ public class FBObject { } } + private static int checkPreGLError(GL gl) { + int glerr = gl.glGetError(); + if(DEBUG && GL.GL_NO_ERROR != glerr) { + System.err.println("Pre-existing GL error: 0x"+Integer.toHexString(glerr)); + Thread.dumpStack(); + } + return glerr; + } + private final boolean checkNoError(GL gl, int err, String exceptionMessage) throws GLException { if(GL.GL_NO_ERROR != err) { if(null != gl) { @@ -974,7 +1104,7 @@ public class FBObject { } /** - * Attaches a Texture2D Color Buffer to this FBO's instance at the given attachment point, + * Attaches a {@link Colorbuffer}, i.e. {@link TextureAttachment}, 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}.
@@ -986,13 +1116,15 @@ public class FBObject { * @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
+ * @see #createColorTextureAttachment(GLProfile, boolean, int, int)
*/
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);
+ return (TextureAttachment)attachColorbuffer(gl, attachmentPoint,
+ createColorTextureAttachment(gl.getGLProfile(), alpha, width, height));
}
/**
- * Attaches a Texture2D Color Buffer to this FBO's instance at the given attachment point,
+ * Attaches a {@link Colorbuffer}, i.e. {@link TextureAttachment}, to this FBO's instance at the given attachment point,
* selecting the texture data type and format automatically.
*
* Leaves the FBO bound.
@@ -1006,23 +1138,15 @@ public class FBObject { * @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 + * @see #createColorTextureAttachment(GLProfile, boolean, int, int, int, int, int, int) */ 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); + return (TextureAttachment)attachColorbuffer(gl, attachmentPoint, + createColorTextureAttachment(gl.getGLProfile(), alpha, width, height, magFilter, minFilter, wrapS, wrapT)); } /** - * Attaches a Texture2D Color Buffer to this FBO's instance at the given attachment point. + * Attaches a {@link Colorbuffer}, i.e. {@link TextureAttachment}, to this FBO's instance at the given attachment point. * *Leaves the FBO bound.
* @@ -1037,66 +1161,33 @@ public class FBObject { * @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 + * @see #createColorTextureAttachment(int, int, int, int, int, int, int, int, int) */ 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 */)); + return (TextureAttachment)attachColorbuffer(gl, attachmentPoint, + createColorTextureAttachment(internalFormat, width, height, dataFormat, dataType, magFilter, minFilter, wrapS, wrapT)); } /** - * Attaches a Texture2D Color Buffer to this FBO's instance at the given attachment point. + * Creates a {@link ColorAttachment}, selecting the format automatically. * - *
- * 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
+ * @param alpha set to true
if you request alpha channel, otherwise false
;
+ * @return uninitialized ColorAttachment instance describing the new attached colorbuffer
*/
- 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);
-
- if(!ignoreStatus) {
- 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);
+ public final ColorAttachment createColorAttachment(boolean alpha) {
+ final int internalFormat;
+ if( rgba8Avail ) {
+ internalFormat = alpha ? GL.GL_RGBA8 : GL.GL_RGB8 ;
+ } else {
+ internalFormat = alpha ? GL.GL_RGBA4 : GL.GL_RGB565;
}
- return texA;
+ return new ColorAttachment(internalFormat, samples, width, height, 0);
}
-
+
/**
- * Attaches a Color Buffer to this FBO's instance at the given attachment point,
+ * Attaches a {@link Colorbuffer}, i.e. {@link ColorAttachment}, to this FBO's instance at the given attachment point,
* selecting the format automatically.
*
* Leaves the FBO bound.
@@ -1106,19 +1197,14 @@ public class FBObject { * @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
+ * @see #createColorAttachment(boolean)
*/
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);
+ return (ColorAttachment) attachColorbuffer(gl, attachmentPoint, createColorAttachment(alpha));
}
/**
- * Attaches a Color Buffer to this FBO's instance at the given attachment point.
+ * Attaches a {@link Colorbuffer}, i.e. {@link ColorAttachment}, to this FBO's instance at the given attachment point.
*
* Leaves the FBO bound.
* @@ -1135,46 +1221,80 @@ public class FBObject { throw new IllegalArgumentException("colorformat invalid: 0x"+Integer.toHexString(internalFormat)+", "+this); } - return attachColorbuffer(gl, attachmentPoint, new ColorAttachment(internalFormat, samples, width, height, 0)); + return (ColorAttachment) attachColorbuffer(gl, attachmentPoint, new ColorAttachment(internalFormat, samples, width, height, 0)); } /** - * Attaches a Color Buffer to this FBO's instance at the given attachment point. + * Attaches a {@link Colorbuffer}, i.e. {@link ColorAttachment} or {@link TextureAttachment}, + * to this FBO's instance at the given attachment point. * + *
+ * If {@link Colorbuffer} is a {@link TextureAttachment} and 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 * @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 + * @param colbuf the to be attached {@link Colorbuffer} + * @return newly attached {@link Colorbuffer} instance if bound and configured successfully, otherwise GLException is thrown + * @throws GLException in case the colorbuffer couldn't be allocated or MSAA has been chosen in case of a {@link TextureAttachment} */ - public final ColorAttachment attachColorbuffer(GL gl, int attachmentPoint, ColorAttachment colA) throws GLException { - validateAddColorAttachment(attachmentPoint, colA); - - colA.initialize(gl); - addColorAttachment(attachmentPoint, colA); + public final Colorbuffer attachColorbuffer(GL gl, int attachmentPoint, Colorbuffer colbuf) throws GLException { + validateAddColorAttachment(attachmentPoint, colbuf); - bind(gl); + final boolean initializedColorbuf = colbuf.initialize(gl); + addColorAttachment(attachmentPoint, colbuf); - // Attach the color buffer - gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, - GL.GL_COLOR_ATTACHMENT0 + attachmentPoint, - GL.GL_RENDERBUFFER, colA.getName()); + bind(gl); - if(!ignoreStatus) { - updateStatus(gl); - if(!isStatusValid()) { - detachColorbuffer(gl, attachmentPoint); - throw new GLException("attachColorbuffer "+colA+" at "+attachmentPoint+" failed "+getStatusString()+", "+this); + if(colbuf instanceof TextureAttachment) { + final TextureAttachment texA = (TextureAttachment) colbuf; + + if(samples>0) { + removeColorAttachment(attachmentPoint, texA); + if(initializedColorbuf) { + texA.free(gl); + } + 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)."); + } + + // 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); + + if(!ignoreStatus) { + updateStatus(gl); + if(!isStatusValid()) { + detachColorbuffer(gl, attachmentPoint, true); + throw new GLException("attachTexture2D "+texA+" at "+attachmentPoint+" failed "+getStatusString()+", "+this); + } + } + } else if(colbuf instanceof ColorAttachment) { + final ColorAttachment colA = (ColorAttachment) colbuf; + + // Attach the color buffer + gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, + GL.GL_COLOR_ATTACHMENT0 + attachmentPoint, + GL.GL_RENDERBUFFER, colA.getName()); + + if(!ignoreStatus) { + updateStatus(gl); + if(!isStatusValid()) { + detachColorbuffer(gl, attachmentPoint, true); + throw new GLException("attachColorbuffer "+colA+" at "+attachmentPoint+" failed "+getStatusString()+", "+this); + } } } if(DEBUG) { - System.err.println("FBObject.attachColorbuffer: "+this); + System.err.println("FBObject.attachColorbuffer: [attachmentPoint "+attachmentPoint+", colbuf "+colbuf+"]: "+this); } - return colA; + return colbuf; } - /** * Attaches one depth, stencil or packed-depth-stencil buffer to this FBO's instance, @@ -1355,33 +1475,39 @@ public class FBObject { if(!ignoreStatus) { updateStatus(gl); if( !isStatusValid() ) { - detachRenderbuffer(gl, atype); + detachRenderbuffer(gl, atype, true); throw new GLException("renderbuffer attachment failed: "+this.getStatusString()); } } if(DEBUG) { - System.err.println("FBObject.attachRenderbuffer: "+this); - } + System.err.println("FBObject.attachRenderbuffer: [attachmentType "+atype+"]: "+this); + } } /** + * Detaches a {@link Colorbuffer}, i.e. {@link ColorAttachment} or {@link TextureAttachment}. *Leaves the FBO bound!
+ * * @param gl - * @param ca + * @param attachmentPoint + * @param dispose true if the Colorbuffer shall be disposed + * @return the detached Colorbuffer * @throws IllegalArgumentException */ - public final void detachColorbuffer(GL gl, int attachmentPoint) throws IllegalArgumentException { - if(null == detachColorbufferImpl(gl, attachmentPoint, false)) { + public final Colorbuffer detachColorbuffer(GL gl, int attachmentPoint, boolean dispose) throws IllegalArgumentException { + final Colorbuffer res = detachColorbufferImpl(gl, attachmentPoint, dispose ? DetachAction.DISPOSE : DetachAction.NONE); + if(null == res) { throw new IllegalArgumentException("ColorAttachment at "+attachmentPoint+", not attached, "+this); } if(DEBUG) { - System.err.println("FBObject.detachColorbuffer: [attachmentPoint "+attachmentPoint+"]: "+this); + System.err.println("FBObject.detachColorbuffer: [attachmentPoint "+attachmentPoint+", dispose "+dispose+"]: "+res+", "+this); } + return res; } - private final Colorbuffer detachColorbufferImpl(GL gl, int attachmentPoint, boolean recreate) { - final Colorbuffer colbuf = colorAttachmentPoints[attachmentPoint]; // shortcut, don't validate here + private final Colorbuffer detachColorbufferImpl(GL gl, int attachmentPoint, DetachAction detachAction) { + Colorbuffer colbuf = colorAttachmentPoints[attachmentPoint]; // shortcut, don't validate here if(null == colbuf) { return null; @@ -1389,6 +1515,8 @@ public class FBObject { bind(gl); + removeColorAttachment(attachmentPoint, colbuf); + if(colbuf instanceof TextureAttachment) { final TextureAttachment texA = (TextureAttachment) colbuf; if( 0 != texA.getName() ) { @@ -1397,11 +1525,22 @@ public class FBObject { 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); + switch(detachAction) { + case DISPOSE: + texA.free(gl); + break; + case RECREATE: + texA.free(gl); + if(samples == 0) { + // stay non MSAA + texA.setSize(width, height); + } else { + // switch to MSAA + colbuf = createColorAttachment(hasAlpha(texA.format)); + } + attachColorbuffer(gl, attachmentPoint, colbuf); + break; + default: } } else if(colbuf instanceof ColorAttachment) { final ColorAttachment colA = (ColorAttachment) colbuf; @@ -1410,12 +1549,30 @@ public class FBObject { 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); + switch(detachAction) { + case DISPOSE: + colA.free(gl); + break; + case RECREATE: + colA.free(gl); + if(samples > 0) { + // stay MSAA + colA.setSize(width, height); + colA.setSamples(samples); + } else { + // switch to non MSAA + if(null != samplesSinkTexture) { + colbuf = createColorTextureAttachment(samplesSinkTexture.format, width, height, + samplesSinkTexture.dataFormat, samplesSinkTexture.dataType, + samplesSinkTexture.magFilter, samplesSinkTexture.minFilter, + samplesSinkTexture.wrapS, samplesSinkTexture.wrapT); + } else { + colbuf = createColorTextureAttachment(gl.getGLProfile(), true, width, height); + } + } + attachColorbuffer(gl, attachmentPoint, colbuf); + break; + default: } } return colbuf; @@ -1424,10 +1581,14 @@ public class FBObject { /** * * @param gl + * @param dispose true if the Colorbuffer shall be disposed * @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 void detachRenderbuffer(GL gl, Attachment.Type atype, boolean dispose) throws IllegalArgumentException { + detachRenderbufferImpl(gl, atype, dispose ? DetachAction.DISPOSE : DetachAction.NONE); + if(DEBUG) { + System.err.println("FBObject.detachRenderbuffer: [attachmentType "+atype+", dispose "+dispose+"]: "+this); + } } public final boolean isDepthStencilPackedFormat() { @@ -1439,7 +1600,7 @@ public class FBObject { return res; } - private final void detachRenderbufferImpl(GL gl, Attachment.Type atype, boolean recreate) throws IllegalArgumentException { + private final void detachRenderbufferImpl(GL gl, Attachment.Type atype, DetachAction detachAction) throws IllegalArgumentException { switch ( atype ) { case DEPTH: case STENCIL: @@ -1485,8 +1646,14 @@ public class FBObject { if( 0 != depth.getName() ) { gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_DEPTH_ATTACHMENT, GL.GL_RENDERBUFFER, 0); } - depth.free(gl); - if(!recreate) { + switch(detachAction) { + case DISPOSE: + case RECREATE: + depth.free(gl); + break; + default: + } + if(DetachAction.RECREATE != detachAction) { depth = null; } break; @@ -1495,8 +1662,14 @@ public class FBObject { if(0 != stencil.getName()) { gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_STENCIL_ATTACHMENT, GL.GL_RENDERBUFFER, 0); } - stencil.free(gl); - if(!recreate) { + switch(detachAction) { + case DISPOSE: + case RECREATE: + stencil.free(gl); + break; + default: + } + if(DetachAction.RECREATE != detachAction) { stencil = null; } break; @@ -1506,9 +1679,15 @@ public class FBObject { gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_DEPTH_ATTACHMENT, GL.GL_RENDERBUFFER, 0); gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_STENCIL_ATTACHMENT, GL.GL_RENDERBUFFER, 0); } - depth.free(gl); - stencil.free(gl); - if(!recreate) { + switch(detachAction) { + case DISPOSE: + case RECREATE: + depth.free(gl); + stencil.free(gl); + break; + default: + } + if(DetachAction.RECREATE != detachAction) { depth = null; stencil = null; } @@ -1516,14 +1695,15 @@ public class FBObject { default: throw new InternalError("XXX"); } - if(recreate) { + if(DetachAction.RECREATE == detachAction) { attachRenderbufferImpl2(gl, action, format); } } } /** - * Detaches all {@link ColorAttachment}s, {@link TextureAttachment}s and {@link RenderAttachment}s. + * Detaches all {@link ColorAttachment}s, {@link TextureAttachment}s and {@link RenderAttachment}s + * and disposes them. *Leaves the FBO bound!
** An attached sampling sink texture will be detached as well, see {@link #getSamplingSink()}. @@ -1538,7 +1718,8 @@ public class FBObject { } /** - * Detaches all {@link ColorAttachment}s and {@link TextureAttachment}s. + * Detaches all {@link ColorAttachment}s and {@link TextureAttachment}s + * and disposes them. *
Leaves the FBO bound!
** An attached sampling sink texture will be detached as well, see {@link #getSamplingSink()}. @@ -1553,7 +1734,7 @@ public class FBObject { } /** - * Detaches all {@link TextureAttachment}s + * Detaches all {@link TextureAttachment}s and disposes them. *
Leaves the FBO bound!
*
* An attached sampling sink texture will be detached as well, see {@link #getSamplingSink()}.
@@ -1566,30 +1747,33 @@ public class FBObject {
}
for(int i=0; i
+ * Only use this method if a subsequent {@link #unbind(GL)}, {@link #use(GL, TextureAttachment)} or {@link #bind(GL)}
+ * follows on any FBO.
+ * 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(..)}
+ * If multisampling is being used and flagged dirty by a previous call of {@link #bind(GL)} or after initialization,
+ * the msaa-buffers are sampled to it's sink {@link #getSamplingSink()}.
+ *
+ * Method also updates the sampling sink configuration (if used). Hence it is recommended to call this
+ * method after your have initialized the FBO and attached renderbuffer etc for the 1st time.
+ * Method is called automatically by {@link #use(GL, TextureAttachment)}.
+ *
+ * Methos always resets the framebuffer binding to default in the end.
+ * 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 use this FBO w/o the {@link GLFBODrawable} and 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. If multisampling is being used, {@link #syncSamplingBuffer(GL)} is being called. If using multiple texture units, ensure you call {@link GL#glActiveTexture(int)} first! {@link #syncFramebuffer(GL)} is being called Leaves the FBO unbound!
+ * Since no native windowing system events are being processed, it is recommended
+ * to handle at least:
+ * true
if framebuffer object is bound via {@link #bind(GL)}, otherwise false
.
@@ -1785,49 +1988,54 @@ public class FBObject {
public final boolean isBound() { return bound; }
/**
- * Samples the multisampling colorbuffer (msaa-buffer) to it's sink {@link #getSamplingSink()}.
- *
- * true
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; }
+ /** @see GL#hasFullFBOSupport() */
+ public final boolean hasFullFBOSupport() throws GLException { checkInitialized(); return this.fullFBOSupport; }
/**
* Returns true
if renderbuffer accepts internal format {@link GL#GL_RGB8} and {@link GL#GL_RGBA8}, otherwise false
.
@@ -1878,7 +2076,7 @@ public class FBObject {
public final boolean supportsDepth(int bits) throws GLException {
checkInitialized();
switch(bits) {
- case 16: return basicFBOSupport;
+ case 16: return true;
case 24: return depth24Avail;
case 32: return depth32Avail;
default: return false;
@@ -1913,11 +2111,11 @@ public class FBObject {
*/
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; }
+ public final int getMaxTextureSize() throws GLException { checkInitialized(); return this.maxTextureSize; }
+ public final int getMaxRenderbufferSize() throws GLException { checkInitialized(); return this.maxRenderbufferSize; }
+
+ /** @see GL#getMaxRenderbufferSamples() */
+ public final int getMaxSamples() throws GLException { checkInitialized(); return this.maxSamples; }
/**
* Returns true
if this instance has been initialized with {@link #reset(GL, int, int)}
diff --git a/src/jogl/classes/com/jogamp/opengl/GLAutoDrawableDelegate.java b/src/jogl/classes/com/jogamp/opengl/GLAutoDrawableDelegate.java
new file mode 100644
index 000000000..38a8deef8
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/GLAutoDrawableDelegate.java
@@ -0,0 +1,189 @@
+/**
+ * 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.nativewindow.AbstractGraphicsDevice;
+import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.WindowClosingProtocol;
+import javax.media.nativewindow.WindowClosingProtocol.WindowClosingMode;
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLDrawable;
+import javax.media.opengl.GLDrawableFactory;
+import javax.media.opengl.GLException;
+
+import com.jogamp.common.util.locks.LockFactory;
+import com.jogamp.common.util.locks.RecursiveLock;
+
+import jogamp.opengl.GLAutoDrawableBase;
+import jogamp.opengl.GLContextImpl;
+import jogamp.opengl.GLDrawableImpl;
+
+
+/**
+ * Fully functional {@link GLAutoDrawable} implementation
+ * utilizing already created created {@link GLDrawable} and {@link GLContext} instances.
+ *
+ *
+ *
+ * See example {@link com.jogamp.opengl.test.junit.jogl.acore.TestGLAutoDrawableDelegateNEWT TestGLAutoDrawableDelegateNEWT}. + *
+ */ +public class GLAutoDrawableDelegate extends GLAutoDrawableBase implements GLAutoDrawable { + /** + * @param drawable a valid and already realized {@link GLDrawable} + * @param context a valid {@link GLContext}, may not be made current (created) yet. + * @param upstreamWidget optional UI element holding this instance, see {@link #getUpstreamWidget()}. + * @param ownDevice passtrue
if {@link AbstractGraphicsDevice#close()} shall be issued,
+ * otherwise pass false
. Closing the device is required in case
+ * the drawable is created w/ it's own new instance, e.g. offscreen drawables,
+ * and no further lifecycle handling is applied.
+ * @param lock optional custom {@link RecursiveLock}.
+ */
+ public GLAutoDrawableDelegate(GLDrawable drawable, GLContext context, Object upstreamWidget, boolean ownDevice, RecursiveLock lock) {
+ super((GLDrawableImpl)drawable, (GLContextImpl)context, ownDevice);
+ if(null == drawable) {
+ throw new IllegalArgumentException("null drawable");
+ }
+ if(null == context) {
+ throw new IllegalArgumentException("null context");
+ }
+ if(!drawable.isRealized()) {
+ throw new IllegalArgumentException("drawable not realized");
+ }
+ this.upstreamWidget = upstreamWidget;
+ this.lock = ( null != lock ) ? lock : LockFactory.createRecursiveLock() ;
+ }
+
+ //
+ // expose default methods
+ //
+
+ /** Default implementation to handle repaint events from the windowing system */
+ public final void windowRepaintOp() {
+ super.defaultWindowRepaintOp();
+ }
+
+ /** Implementation to handle resize events from the windowing system. All required locks are being claimed. */
+ public final void windowResizedOp(int newWidth, int newHeight) {
+ super.defaultWindowResizedOp(newWidth, newHeight);
+ }
+
+ /**
+ * Implementation to handle destroy notifications from the windowing system.
+ *
+ * + * If the {@link NativeSurface} does not implement {@link WindowClosingProtocol} + * or {@link WindowClosingMode#DISPOSE_ON_CLOSE} is enabled (default), + * a thread safe destruction is being induced. + *
+ */ + public final void windowDestroyNotifyOp() { + super.defaultWindowDestroyNotifyOp(); + } + + // + // Complete GLAutoDrawable + // + + private Object upstreamWidget; + private final RecursiveLock lock; + + @Override + protected final RecursiveLock getLock() { return lock; } + + @Override + public final Object getUpstreamWidget() { + return upstreamWidget; + } + + /** + * Set the upstream UI toolkit object. + * @see #getUpstreamWidget() + */ + public final void setUpstreamWidget(Object newUpstreamWidget) { + upstreamWidget = newUpstreamWidget; + } + + /** + * {@inheritDoc} + *+ * This implementation calls {@link #defaultDestroy()}. + *
+ *+ * User still needs to destroy the upstream window, which details are hidden from this aspect. + * This can be performed by overriding {@link #destroyImplInLock()}. + *
+ */ + @Override + public final void destroy() { + defaultDestroy(); + } + + @Override + protected void destroyImplInLock() { + super.destroyImplInLock(); + } + + @Override + public void display() { + defaultDisplay(); + } + + // + // GLDrawable delegation + // + + @Override + public final GLDrawableFactory getFactory() { + return drawable.getFactory(); + } + + @Override + public final void setRealized(boolean realized) { + } + + @Override + public final void swapBuffers() throws GLException { + defaultSwapBuffers(); + } + + @Override + public String toString() { + return getClass().getSimpleName()+"[ \n\tHelper: " + helper + ", \n\tDrawable: " + drawable + + ", \n\tContext: " + context + ", \n\tUpstreamWidget: "+upstreamWidget+ /** ", \n\tFactory: "+factory+ */ "]"; + } +} diff --git a/src/jogl/classes/com/jogamp/opengl/GLExtensions.java b/src/jogl/classes/com/jogamp/opengl/GLExtensions.java index f7e25fa01..cf81b85ee 100644 --- a/src/jogl/classes/com/jogamp/opengl/GLExtensions.java +++ b/src/jogl/classes/com/jogamp/opengl/GLExtensions.java @@ -72,6 +72,9 @@ public class GLExtensions { public static final String OES_EGL_image_external = "GL_OES_EGL_image_external"; + public static final String ARB_gpu_shader_fp64 = "GL_ARB_gpu_shader_fp64"; + public static final String ARB_shader_objects = "GL_ARB_shader_objects"; + // // Aliased GLX/WGL/.. extensions // diff --git a/src/jogl/classes/com/jogamp/opengl/OffscreenAutoDrawable.java b/src/jogl/classes/com/jogamp/opengl/OffscreenAutoDrawable.java deleted file mode 100644 index 4caea03b2..000000000 --- a/src/jogl/classes/com/jogamp/opengl/OffscreenAutoDrawable.java +++ /dev/null @@ -1,112 +0,0 @@ -/** - * 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.nativewindow.AbstractGraphicsDevice; -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 { - - /** - * @param drawable a valid {@link GLDrawable}, may not be realized yet. - * @param context a valid {@link GLContext}, may not be made current (created) yet. - * @param ownDevice passtrue
if {@link AbstractGraphicsDevice#close()} shall be issued,
- * otherwise pass false
. Closing the device is required in case
- * the drawable is created w/ it's own new instance, e.g. offscreen drawables,
- * and no further lifecycle handling is applied.
- */
- public OffscreenAutoDrawable(GLDrawable drawable, GLContext context, boolean ownDevice) {
- super(drawable, context, null, ownDevice);
- }
-
- /**
- * Attempts to resize this offscreen auto drawable, if supported
- * by the underlying {@link GLDrawable).
- * @param newWidth
- * @param newHeight
- * @return true
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) {
- Throwable tFBO = null;
- Throwable tGL = null;
- context.makeCurrent();
- try {
- ((GLFBODrawableImpl)drawable).setSize(context.getGL(), newWidth, newHeight);
- done = true;
- } catch (Throwable t) {
- tFBO = t;
- } finally {
- try {
- context.release();
- } catch (Throwable t) {
- tGL = t;
- }
- }
- if(null != tFBO) {
- throw new GLException("OffscreenAutoDrawable.setSize(..) GLFBODrawableImpl.setSize(..) exception", tFBO);
- }
- if(null != tGL) {
- throw new GLException("OffscreenAutoDrawable.setSize(..) GLContext.release() exception", tGL);
- }
- }
- 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 8d237162c..02f62daec 100644
--- a/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java
+++ b/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java
@@ -30,6 +30,7 @@ package com.jogamp.opengl.swt;
import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.NativeSurface;
import javax.media.nativewindow.ProxySurface;
+import javax.media.nativewindow.UpstreamSurfaceHook;
import javax.media.opengl.GL;
import javax.media.opengl.GLAnimatorControl;
import javax.media.opengl.GLAutoDrawable;
@@ -48,6 +49,7 @@ import javax.media.opengl.Threading;
import jogamp.opengl.Debug;
import jogamp.opengl.GLContextImpl;
import jogamp.opengl.GLDrawableHelper;
+import jogamp.opengl.GLDrawableImpl;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ControlAdapter;
@@ -97,8 +99,8 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
private final GLCapabilitiesImmutable capsRequested;
private final GLCapabilitiesChooser capsChooser;
- private volatile GLDrawable drawable; // volatile: avoid locking for read-only access
- private GLContext context;
+ private volatile GLDrawableImpl drawable; // volatile: avoid locking for read-only access
+ private GLContextImpl context;
/* Native window surface */
private AbstractGraphicsDevice device;
@@ -319,7 +321,7 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
}
});
}
- private final ProxySurface.UpstreamSurfaceHook swtCanvasUpStreamHook = new ProxySurface.UpstreamSurfaceHook() {
+ private final UpstreamSurfaceHook swtCanvasUpStreamHook = new UpstreamSurfaceHook() {
@Override
public final void create(ProxySurface s) { /* nop */ }
@@ -349,7 +351,27 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
( nClientArea.width != oClientArea.width || nClientArea.height != oClientArea.height )
) {
clientArea = nClientArea; // write back new value
- sendReshape = true; // Mark for OpenGL reshape next time the control is painted
+
+ GLDrawableImpl _drawable = drawable;
+ if( null != _drawable ) {
+ if(DEBUG) {
+ System.err.println("GLCanvas.sizeChanged: ("+Thread.currentThread().getName()+"): "+nClientArea.width+"x"+nClientArea.height+" - surfaceHandle 0x"+Long.toHexString(getNativeSurface().getSurfaceHandle()));
+ }
+ if( ! _drawable.getChosenGLCapabilities().isOnscreen() ) {
+ final RecursiveLock _lock = lock;
+ _lock.lock();
+ try {
+ final GLDrawableImpl _drawableNew = GLDrawableHelper.resizeOffscreenDrawable(_drawable, context, nClientArea.width, nClientArea.height);
+ if(_drawable != _drawableNew) {
+ // write back
+ drawable = _drawableNew;
+ }
+ } finally {
+ _lock.unlock();
+ }
+ sendReshape = true; // async if display() doesn't get called below, but avoiding deadlock
+ }
+ }
}
}
@@ -391,10 +413,10 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
if(null != proxySurface) {
/* Associate a GL surface with the proxy */
- drawable = glFactory.createGLDrawable(proxySurface);
+ drawable = (GLDrawableImpl) glFactory.createGLDrawable(proxySurface);
drawable.setRealized(true);
- context = drawable.createContext(shareWith);
+ context = (GLContextImpl) drawable.createContext(shareWith);
}
} finally {
_lock.unlock();
@@ -455,6 +477,11 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
return helper.getAutoSwapBufferMode();
}
+ @Override
+ public final GLDrawable getDelegatedDrawable() {
+ return drawable;
+ }
+
@Override
public GLContext getContext() {
return null != drawable ? context : null;
@@ -502,7 +529,7 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
_lock.lock();
try {
final GLContext oldCtx = context;
- final boolean newCtxCurrent = helper.switchContext(drawable, oldCtx, newCtx, additionalCtxCreationFlags);
+ final boolean newCtxCurrent = GLDrawableHelper.switchContext(drawable, oldCtx, newCtx, additionalCtxCreationFlags);
context=(GLContextImpl)newCtx;
if(newCtxCurrent) {
context.makeCurrent();
diff --git a/src/jogl/classes/javax/media/opengl/GLAutoDrawable.java b/src/jogl/classes/javax/media/opengl/GLAutoDrawable.java
index 0b2c664fe..38f1746f9 100644
--- a/src/jogl/classes/javax/media/opengl/GLAutoDrawable.java
+++ b/src/jogl/classes/javax/media/opengl/GLAutoDrawable.java
@@ -114,6 +114,12 @@ public interface GLAutoDrawable extends GLDrawable {
* where you drag the window to another monitor. */
public static final boolean SCREEN_CHANGE_ACTION_ENABLED = Debug.getBooleanProperty("jogl.screenchange.action", true);
+ /**
+ * If the implementation uses delegation, return the delegated {@link GLDrawable} instance,
+ * otherwise return this
instance.
+ */
+ public GLDrawable getDelegatedDrawable();
+
/**
* Returns the context associated with this drawable. The returned
* context will be synchronized.
@@ -124,23 +130,31 @@ public interface GLAutoDrawable extends GLDrawable {
/**
* Associate a new context to this drawable and also propagates the context/drawable switch by
* calling {@link GLContext#setGLDrawable(GLDrawable, boolean) newCtx.setGLDrawable(drawable, true);}.
- * drawable
might be an inner GLDrawable instance if using such a delegation pattern,
- * or this GLAutoDrawable itself.
- * - * If the old context's drawable was an {@link GLAutoDrawable}, it's reference to the given drawable - * is being cleared by calling - * {@link GLAutoDrawable#setContext(GLContext) ((GLAutoDrawable)oldCtx.getGLDrawable()).setContext(null)}. - *
+ *drawable
might be an inner GLDrawable instance if using a delegation pattern,
+ * or this GLAutoDrawable instance.
* * If the old or new context was current on this thread, it is being released before switching the drawable. * The new context will be made current afterwards, if it was current before. - * However the user shall take extra care that not other thread - * attempts to make this context current. Otherwise a race condition may happen. + * However the user shall take extra care that no other thread + * attempts to make this context current. + *
+ *+ * Be aware that the old context is still bound to the drawable, + * and that one context can only be bound to one drawable at one time! *
*- * Disclaimer: Even though the API may allows this functionality in theory, your mileage may vary - * switching the drawable of an already established GLContext, i.e. which is already made current once. - * FIXME: Validate functionality! + * In case you do not intend to use the old context anymore, i.e. + * not assigning it to another drawable, it shall be + * destroyed before setting the new context, i.e.: + *
+ GLContext oldCtx = glad.getContext(); + if(null != oldCtx) { + oldCtx.destroy(); + } + glad.setContext(newCtx); + *+ * This is required, since a context must have a valid drawable at all times + * and this API shall not restrict the user in any way. * * * @param newCtx the new context diff --git a/src/jogl/classes/javax/media/opengl/GLAutoDrawableDelegate.java b/src/jogl/classes/javax/media/opengl/GLAutoDrawableDelegate.java deleted file mode 100644 index 67e81270d..000000000 --- a/src/jogl/classes/javax/media/opengl/GLAutoDrawableDelegate.java +++ /dev/null @@ -1,144 +0,0 @@ -/** - * 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.opengl; - -import javax.media.nativewindow.AbstractGraphicsDevice; - -import com.jogamp.common.util.locks.LockFactory; -import com.jogamp.common.util.locks.RecursiveLock; - -import jogamp.opengl.Debug; -import jogamp.opengl.GLAutoDrawableBase; -import jogamp.opengl.GLContextImpl; -import jogamp.opengl.GLDrawableImpl; - - -/** - * Fully functional {@link GLAutoDrawable} implementation - * utilizing already created created {@link GLDrawable} and {@link GLContext} instances. - *
- * Since no native windowing system events are being processed, it is recommended - * to handle at least: - *
- * See example {@link com.jogamp.opengl.test.junit.jogl.acore.TestGLAutoDrawableDelegateNEWT TestGLAutoDrawableDelegateNEWT}. - *
- */ -public class GLAutoDrawableDelegate extends GLAutoDrawableBase { - public static final boolean DEBUG = Debug.debug("GLAutoDrawableDelegate"); - - /** - * @param drawable a valid {@link GLDrawable}, may not be realized yet. - * @param context a valid {@link GLContext}, may not be made current (created) yet. - * @param upstreamWidget optional UI element holding this instance, see {@link #getUpstreamWidget()}. - * @param ownDevice passtrue
if {@link AbstractGraphicsDevice#close()} shall be issued,
- * otherwise pass false
. Closing the device is required in case
- * the drawable is created w/ it's own new instance, e.g. offscreen drawables,
- * and no further lifecycle handling is applied.
- */
- public GLAutoDrawableDelegate(GLDrawable drawable, GLContext context, Object upstreamWidget, boolean ownDevice) {
- super((GLDrawableImpl)drawable, (GLContextImpl)context, ownDevice);
- this.upstreamWidget = null;
- }
-
- //
- // expose default methods
- //
-
- public final void windowRepaintOp() {
- super.defaultWindowRepaintOp();
- }
-
- public final void windowResizedOp() {
- super.defaultWindowResizedOp();
- }
-
- public final void windowDestroyNotifyOp() {
- super.defaultWindowDestroyNotifyOp();
- }
-
- //
- // Complete GLAutoDrawable
- //
-
- private final RecursiveLock lock = LockFactory.createRecursiveLock(); // instance wide lock
- private final Object upstreamWidget;
-
- @Override
- protected final RecursiveLock getLock() { return lock; }
-
- @Override
- public final Object getUpstreamWidget() {
- return upstreamWidget;
- }
-
- /**
- * {@inheritDoc}
- * - * This implementation calls {@link #defaultDestroy()}. - *
- *- * User still needs to destroy the upstream window, which details are hidden from this aspect. - * This can be performed by overriding {@link #destroyImplInLock()}. - *
- */ - @Override - public final void destroy() { - defaultDestroy(); - } - - @Override - public void display() { - defaultDisplay(); - } - - // - // GLDrawable delegation - // - - @Override - public final GLDrawableFactory getFactory() { - return drawable.getFactory(); - } - - @Override - public final void setRealized(boolean realized) { - } - - @Override - public final void swapBuffers() throws GLException { - defaultSwapBuffers(); - } - -} diff --git a/src/jogl/classes/javax/media/opengl/GLBase.java b/src/jogl/classes/javax/media/opengl/GLBase.java index f5831a72d..9bcee819a 100644 --- a/src/jogl/classes/javax/media/opengl/GLBase.java +++ b/src/jogl/classes/javax/media/opengl/GLBase.java @@ -273,6 +273,42 @@ public interface GLBase { */ public boolean isExtensionAvailable(String glExtensionName); + /** + * 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
+ * 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 GLContext#hasBasicFBOSupport() + */ + public boolean hasBasicFBOSupport(); + + /** + * 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. + *
+ * @see GLContext#hasFullFBOSupport() + */ + public boolean hasFullFBOSupport(); + + /** + * Returns the maximum number of FBO RENDERBUFFER samples + * if {@link #hasFullFBOSupport() full FBO is supported}, otherwise false. + * @see GLContext#getMaxRenderbufferSamples() + */ + public int getMaxRenderbufferSamples(); + /** * Returns true if the GL context supports non power of two (NPOT) textures, * otherwise false. @@ -284,6 +320,8 @@ public interface GLBase { */ public boolean isNPOTTextureAvailable(); + public boolean isTextureFormatBGRA8888Available(); + /** Provides a platform-independent way to specify the minimum swap interval for buffer swaps. An argument of 0 disables sync-to-vertical-refresh completely, while an argument of 1 diff --git a/src/jogl/classes/javax/media/opengl/GLContext.java b/src/jogl/classes/javax/media/opengl/GLContext.java index c2f94b9af..a5e639c74 100644 --- a/src/jogl/classes/javax/media/opengl/GLContext.java +++ b/src/jogl/classes/javax/media/opengl/GLContext.java @@ -96,6 +96,9 @@ public abstract class GLContext { */ public static final boolean PROFILE_ALIASING = !Debug.isPropertyDefined("jogl.debug.GLContext.NoProfileAliasing", true); + protected static final boolean FORCE_NO_FBO_SUPPORT = Debug.isPropertyDefined("jogl.fbo.force.none", true); + protected static final boolean FORCE_MIN_FBO_SUPPORT = Debug.isPropertyDefined("jogl.fbo.force.min", true); + public static final boolean DEBUG = Debug.debug("GLContext"); public static final boolean TRACE_SWITCH = Debug.isPropertyDefined("jogl.debug.GLContext.TraceSwitch", true); @@ -127,9 +130,9 @@ public abstract class GLContext { /**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 basic FBO, details see {@link #hasFBO()}.
+ /** Context supports basic FBO, details see {@link #hasBasicFBOSupport()}.
* Not a cache key.
- * @see #hasFBO()
+ * @see #hasBasicFBOSupport()
* @see #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)
*/
protected static final int CTX_IMPL_FBO = 1 << 9;
@@ -178,11 +181,6 @@ public abstract class GLContext {
* and made current afterwards. However the user shall take extra care that not other thread
* attempts to make this context current. Otherwise a race condition may happen.
*
- * - * Disclaimer: Even though the API may allows this functionality in theory, your mileage may vary - * switching the drawable of an already established GLContext, i.e. which is already made current once. - * FIXME: Validate functionality! - *
* @param readWrite the read/write drawable for framebuffer operations. * @param setWriteOnly iftrue
and if the current read-drawable differs
* from the write-drawable ({@link #setGLReadDrawable(GLDrawable)}),
@@ -603,12 +601,23 @@ public abstract class GLContext {
/**
* @return true if impl. is a hardware rasterizer, otherwise false.
+ * @see #isHardwareRasterizer(AbstractGraphicsDevice, GLProfile)
* @see GLProfile#isHardwareRasterizer()
*/
public final boolean isHardwareRasterizer() {
return 0 == ( ctxOptions & CTX_IMPL_ACCEL_SOFT ) ;
}
+ /**
+ * @return true if context supports GLSL, i.e. is either {@link #isGLES2()}, {@link #isGL3()} or {@link #isGL2()} and major-version > 1.
+ * @see GLProfile#hasGLSL()
+ */
+ public final boolean hasGLSL() {
+ return isGLES2() ||
+ isGL3() ||
+ isGL2() && ctxMajorVersion>1 ;
+ }
+
/**
* Returns true
if basic FBO support is available, otherwise false
.
* @@ -620,21 +629,54 @@ public abstract class GLContext { * 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() { + public final boolean hasBasicFBOSupport() { return 0 != ( ctxOptions & CTX_IMPL_FBO ) ; } + /** + * 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 final boolean hasFullFBOSupport() { + return !FORCE_MIN_FBO_SUPPORT && hasBasicFBOSupport() && + ( isGL3() || // GL >= 3.0 + isExtensionAvailable(GLExtensions.ARB_framebuffer_object) || // ARB_framebuffer_object + ( isExtensionAvailable(GLExtensions.EXT_framebuffer_object) && // All EXT_framebuffer_object* + isExtensionAvailable(GLExtensions.EXT_framebuffer_multisample) && + isExtensionAvailable(GLExtensions.EXT_framebuffer_blit) && + isExtensionAvailable(GLExtensions.EXT_packed_depth_stencil) + ) + ) ; + } + /** - * @return true if context supports GLSL - * @see GLProfile#hasGLSL() + * Returns the maximum number of FBO RENDERBUFFER samples + * if {@link #hasFullFBOSupport() full FBO is supported}, otherwise false. */ - public final boolean hasGLSL() { - return isGL2ES2() ; + public final int getMaxRenderbufferSamples() { + if( hasFullFBOSupport() ) { + final GL gl = getGL(); + final int[] val = new int[] { 0 } ; + gl.glGetIntegerv(GL2GL3.GL_MAX_SAMPLES, val, 0); + final int glerr = gl.glGetError(); + if(GL.GL_NO_ERROR == glerr) { + return val[0]; + } else if(DEBUG) { + System.err.println("GLContext.getMaxRenderbufferSamples: GL_MAX_SAMPLES query GL Error 0x"+Integer.toHexString(glerr)); + } + } + return 0; } - + /** Note: The GL impl. may return a const value, ie {@link GLES2#isNPOTTextureAvailable()} always returnstrue
. */
public boolean isNPOTTextureAvailable() {
return isGL3() || isGLES2Compatible() || isExtensionAvailable(GLExtensions.ARB_texture_non_power_of_two);
@@ -1014,6 +1056,9 @@ public abstract class GLContext {
validateProfileBits(profile, "profile");
validateProfileBits(resCtp, "resCtp");
+ if(FORCE_NO_FBO_SUPPORT) {
+ resCtp &= ~CTX_IMPL_FBO ;
+ }
if(DEBUG) {
System.err.println("GLContext.mapAvailableGLVersion: "+device+": "+getGLVersion(reqMajor, 0, profile, null)+" -> "+getGLVersion(resMajor, resMinor, resCtp, null));
// Thread.dumpStack();
@@ -1197,17 +1242,35 @@ public abstract class GLContext {
* FBO feature is implemented in OpenGL, hence it is {@link GLProfile} dependent.
*
* - * FBO support is queried as described in {@link #hasFBO()}. + * FBO support is queried as described in {@link #hasBasicFBOSupport()}. *
* * @param device the device to request whether FBO is available for * @param glp {@link GLProfile} to check for FBO capabilities - * @see GLContext#hasFBO() + * @see GLContext#hasBasicFBOSupport() */ public static final boolean isFBOAvailable(AbstractGraphicsDevice device, GLProfile glp) { return 0 != ( CTX_IMPL_FBO & getAvailableContextProperties(device, glp) ); } + /** + * @return1
if using a hardware rasterizer, 0
if using a software rasterizer and -1
if not determined yet.
+ * @see GLContext#isHardwareRasterizer()
+ * @see GLProfile#isHardwareRasterizer()
+ */
+ public static final int isHardwareRasterizer(AbstractGraphicsDevice device, GLProfile glp) {
+ final int r;
+ final int ctp = getAvailableContextProperties(device, glp);
+ if(0 == ctp) {
+ r = -1;
+ } else if( 0 == ( CTX_IMPL_ACCEL_SOFT & ctp ) ) {
+ r = 1;
+ } else {
+ r = 0;
+ }
+ return r;
+ }
+
/**
* @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 9fd895c1f..b6e7b0576 100644
--- a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java
+++ b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java
@@ -48,13 +48,16 @@ import java.util.List;
import com.jogamp.common.JogampRuntimeException;
import com.jogamp.common.util.ReflectionUtil;
+import com.jogamp.opengl.GLAutoDrawableDelegate;
import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.AbstractGraphicsScreen;
+import javax.media.nativewindow.AbstractGraphicsConfiguration;
+import javax.media.nativewindow.CapabilitiesImmutable;
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.UpstreamSurfaceHook;
import jogamp.opengl.Debug;
@@ -373,44 +376,63 @@ public abstract class GLDrawableFactory {
// Methods to create high-level objects
/**
- * Returns a GLDrawable according to it's chosen Capabilities,- * The native platform's chosen Capabilties are referenced within the target - * NativeSurface's AbstractGraphicsConfiguration.
- *
- * In case target's {@link javax.media.nativewindow.Capabilities#isOnscreen()} is true,
- * an onscreen GLDrawable will be realized.
+ * The chosen {@link GLCapabilitiesImmutable} are referenced within the target
+ * {@link NativeSurface}'s {@link AbstractGraphicsConfiguration}.
+ *
*
- * In case target's {@link javax.media.nativewindow.Capabilities#isOnscreen()} is false,
- * either a Pbuffer drawable is created if target's {@link javax.media.opengl.GLCapabilities#isPBuffer()} is true,
- * or a simple pixmap/bitmap drawable is created. The latter is unlikely to be hardware accelerated.
+ * An onscreen GLDrawable is created if {@link CapabilitiesImmutable#isOnscreen() caps.isOnscreen()} is true.
+ *
- * + * A FBO drawable is created if both {@link GLCapabilitiesImmutable#isFBO() caps.isFBO()} + * and {@link GLContext#isFBOAvailable(AbstractGraphicsDevice, GLProfile) canCreateFBO(device, caps.getGLProfile())} is true. + *
+ *+ * A Pbuffer drawable is created if both {@link GLCapabilitiesImmutable#isPBuffer() caps.isPBuffer()} + * and {@link #canCreateGLPbuffer(AbstractGraphicsDevice) canCreateGLPbuffer(device)} is true. + *
+ *+ * If not onscreen and neither FBO nor Pbuffer is available, + * a simple pixmap/bitmap drawable/surface is created, which is unlikely to be hardware accelerated. + *
+ * * @throws IllegalArgumentException if the passed target is null * @throws GLException if any window system-specific errors caused * the creation of the GLDrawable to fail. * + * @see #canCreateGLPbuffer(AbstractGraphicsDevice) + * @see GLContext#isFBOAvailable(AbstractGraphicsDevice, GLProfile) + * @see javax.media.opengl.GLCapabilities#isOnscreen() + * @see javax.media.opengl.GLCapabilities#isFBO() + * @see javax.media.opengl.GLCapabilities#isPBuffer() * @see javax.media.nativewindow.GraphicsConfigurationFactory#chooseGraphicsConfiguration(Capabilities, CapabilitiesChooser, AbstractGraphicsScreen) */ public abstract GLDrawable createGLDrawable(NativeSurface target) throws IllegalArgumentException, GLException; - + /** - * Creates a Offscreen GLDrawable incl it's offscreen {@link javax.media.nativewindow.NativeSurface} with the given capabilites and dimensions. + * Creates an {@link GLOffscreenAutoDrawable} incl it's offscreen {@link javax.media.nativewindow.NativeSurface} with the given capabilites and dimensions. *- * It's {@link AbstractGraphicsConfiguration} is properly set according to the given {@link GLCapabilitiesImmutable}, see below. + * The {@link GLOffscreenAutoDrawable}'s {@link GLDrawable} is realized and it's {@link GLContext} assigned but not yet made current. *
*
- * A FBO drawable is created if both {@link javax.media.opengl.GLCapabilities#isFBO() caps.isFBO()}
+ * In case the passed {@link GLCapabilitiesImmutable} contains default values, i.e.
+ * {@link GLCapabilitiesImmutable#isOnscreen() caps.isOnscreen()} == true
,
+ * it is auto-configured. The latter will set offscreen and also FBO or Pbuffer, whichever is available in that order.
+ *
+ * A FBO based auto drawable, {@link GLOffscreenAutoDrawable.FBO}, is created if both {@link GLCapabilitiesImmutable#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. + * A Pbuffer based auto drawable is created if both {@link GLCapabilitiesImmutable#isPBuffer() caps.isPBuffer()} + * and {@link #canCreateGLPbuffer(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. + * If neither FBO nor Pbuffer is available, + * a simple pixmap/bitmap auto drawable 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.
@@ -418,17 +440,55 @@ public abstract class GLDrawableFactory {
* @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 and initialized offscreen {@link GLOffscreenAutoDrawable} instance
*
- * @return the created offscreen GLDrawable
+ * @throws GLException if any window system-specific errors caused
+ * the creation of the Offscreen to fail.
+ *
+ * @see #createOffscreenDrawable(AbstractGraphicsDevice, GLCapabilitiesImmutable, GLCapabilitiesChooser, int, int)
+ */
+ public abstract GLOffscreenAutoDrawable createOffscreenAutoDrawable(AbstractGraphicsDevice device,
+ GLCapabilitiesImmutable caps,
+ GLCapabilitiesChooser chooser,
+ int width, int height,
+ GLContext shareWith) throws GLException;
+ /**
+ * Creates a offscreen {@link GLDrawable} incl it's offscreen {@link javax.media.nativewindow.NativeSurface} with the given capabilites and dimensions.
+ *
+ * In case the passed {@link GLCapabilitiesImmutable} contains default values, i.e.
+ * {@link GLCapabilitiesImmutable#isOnscreen() caps.isOnscreen()} == true
,
+ * it is auto-configured. The latter will set offscreen and also FBO or Pbuffer, whichever is available in that order.
+ *
+ * A resizeable FBO drawable, {@link GLFBODrawable.Resizeable}, is created if both {@link GLCapabilitiesImmutable#isFBO() caps.isFBO()} + * and {@link GLContext#isFBOAvailable(AbstractGraphicsDevice, GLProfile) canCreateFBO(device, caps.getGLProfile())} is true. + *
+ *+ * A Pbuffer drawable is created if both {@link GLCapabilitiesImmutable#isPBuffer() caps.isPBuffer()} + * and {@link #canCreateGLPbuffer(AbstractGraphicsDevice) canCreateGLPbuffer(device)} is true. + *
+ *+ * If neither FBO nor Pbuffer is available, + * a simple pixmap/bitmap drawable 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.
+ * @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 {@link GLDrawable}
*
* @throws GLException if any window system-specific errors caused
* the creation of the Offscreen to fail.
+ *
+ * @see #createOffscreenAutoDrawable(AbstractGraphicsDevice, GLCapabilitiesImmutable, GLCapabilitiesChooser, int, int, GLContext)
*/
public abstract GLDrawable createOffscreenDrawable(AbstractGraphicsDevice device,
- GLCapabilitiesImmutable capabilities,
+ GLCapabilitiesImmutable caps,
GLCapabilitiesChooser chooser,
- int width, int height)
- throws GLException;
+ int width, int height) throws GLException;
/**
* Creates a proxy {@link NativeSurface} w/ defined surface handle, i.e. a {@link WrappedSurface} or {@link GDISurface} instance.
@@ -458,6 +518,21 @@ public abstract class GLDrawableFactory {
long windowHandle,
GLCapabilitiesImmutable caps, GLCapabilitiesChooser chooser, UpstreamSurfaceHook upstream);
+ /**
+ * 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#hasBasicFBOSupport()}. + *
+ * + * @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#hasBasicFBOSupport()
+ */
+ public abstract boolean canCreateFBO(AbstractGraphicsDevice device, GLProfile glp);
+
/**
* Returns true if it is possible to create a GLPbuffer. Some older
* graphics cards do not have this capability.
@@ -467,7 +542,10 @@ public abstract class GLDrawableFactory {
public abstract boolean canCreateGLPbuffer(AbstractGraphicsDevice device);
/**
- * Creates a GLPbuffer with the given capabilites and dimensions. + * Creates a GLPbuffer {@link GLAutoDrawable} with the given capabilites and dimensions. + *
+ * The GLPbuffer drawable is realized and initialized eagerly. + *
* * See the note in the overview documentation on * context sharing. @@ -479,10 +557,12 @@ public abstract class GLDrawableFactory { * @param initialHeight initial height of pbuffer * @param shareWith a shared GLContext this GLPbuffer shall use * - * @return the new {@link GLPbuffer} specific {@link GLAutoDrawable} + * @return the created and initialized {@link GLPbuffer} instance * * @throws GLException if any window system-specific errors caused * the creation of the GLPbuffer to fail. + * + * @deprecated {@link GLPbuffer} is deprecated, use {@link #createOffscreenAutoDrawable(AbstractGraphicsDevice, GLCapabilitiesImmutable, GLCapabilitiesChooser, int, int, GLContext)} */ public abstract GLPbuffer createGLPbuffer(AbstractGraphicsDevice device, GLCapabilitiesImmutable capabilities, diff --git a/src/jogl/classes/javax/media/opengl/GLFBODrawable.java b/src/jogl/classes/javax/media/opengl/GLFBODrawable.java new file mode 100644 index 000000000..45fd3b686 --- /dev/null +++ b/src/jogl/classes/javax/media/opengl/GLFBODrawable.java @@ -0,0 +1,173 @@ +/** + * 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.opengl; + +import javax.media.nativewindow.NativeWindowException; + +import com.jogamp.opengl.FBObject; +import com.jogamp.opengl.FBObject.TextureAttachment; + +/** + * Platform-independent {@link GLDrawable} specialization, + * exposing {@link FBObject} functionality. + * + *+ * A {@link GLFBODrawable} is uninitialized until a {@link GLContext} is bound + * and made current the first time. + *
+ * + *+ * MSAA is used if {@link GLCapabilitiesImmutable#getNumSamples() requested}. + *
+ *+ * Double buffering is used if {@link GLCapabilitiesImmutable#getDoubleBuffered() requested}. + *
+ *+ * In MSAA mode, it always uses the implicit 2nd {@link FBObject framebuffer} {@link FBObject#getSamplingSinkFBO() sink}. + * Hence double buffering is always the case w/ MSAA. + *
+ *+ * In non MSAA a second explicit {@link FBObject framebuffer} is being used. + * This method allows compliance w/ the spec, i.e. read and draw framebuffer selection + * and double buffer usage for e.g. {@link GL#glReadPixels(int, int, int, int, int, int, java.nio.Buffer) glReadPixels(..)}. + * This method also allows usage of both textures seperately. + *
+ *+ * It would be possible to implement double buffering simply using + * {@link FBObject.TextureAttachment texture attachment}s with one {@link FBObject framebuffer}. + * This would require mode selection and hence complicate the API. Besides, it would + * not support differentiation of read and write framebuffer and hence not be spec compliant. + *
+ *
+ * Actual swapping of the {@link FBObject.TextureAttachment texture}s or {@link FBObject framebuffer}
+ * is performed either in the {@link #contextMadeCurrent(boolean) context current hook}
+ * or when {@link #swapBuffersImpl(boolean) swapping buffers}, whatever comes first.
+ *
true
if initialized, i.e. a {@link GLContext} is bound and made current once, otherwise false
.
+ */
+ public boolean isInitialized();
+
+ /**
+ * Notify this instance about upstream size change
+ * to reconfigure the {@link FBObject}.
+ * @param gl GL context object bound to this drawable, will be made current during operation.
+ * A prev. current context will be make current after operation.
+ * @throws GLException if resize operation failed
+ */
+ void resetSize(GL gl) throws GLException;
+
+ /**
+ * @return the used texture unit
+ */
+ int getTextureUnit();
+
+ /**
+ *
+ * @param unit the texture unit to be used
+ */
+ void setTextureUnit(int unit);
+
+ /**
+ * Set a new sample size
+ * @param gl GL context object bound to this drawable, will be made current during operation.
+ * A prev. current context will be make current after operation.
+ * @param newSamples new sample size
+ * @throws GLException if resetting the FBO failed
+ */
+ void setNumSamples(GL gl, int newSamples) throws GLException;
+
+ /**
+ * @return the number of sample buffers if using MSAA, otherwise 0
+ */
+ int getNumSamples();
+
+ /**
+ * @return the used {@link DoubleBufferMode}
+ */
+ // DoubleBufferMode getDoubleBufferMode(); // TODO: Add or remove TEXTURE (only) DoubleBufferMode support
+
+ /**
+ * Sets the {@link DoubleBufferMode}. Must be called before {@link #isInitialized() initialization},
+ * otherwise an exception is thrown.
+ * + * This call has no effect is MSAA is selected, since MSAA always forces the mode to {@link DoubleBufferMode#FBO FBO}. + * Also setting the mode to {@link DoubleBufferMode#NONE NONE} where double buffering is {@link GLCapabilitiesImmutable#getDoubleBuffered() requested} + * or setting a double buffering mode w/o {@link GLCapabilitiesImmutable#getDoubleBuffered() request} will be ignored. + *
+ *+ * Since {@link DoubleBufferMode#TEXTURE TEXTURE} mode is currently not implemented, this method has no effect. + *
+ * @throws GLException if already initialized, see {@link #isInitialized()}. + */ + // void setDoubleBufferMode(DoubleBufferMode mode) throws GLException; // TODO: Add or remove TEXTURE (only) DoubleBufferMode support + + /** + * If MSAA is being used and {@link GL#GL_FRONT} is requested, + * the internal {@link FBObject} {@link FBObject#getSamplingSinkFBO() sample sink} is being returned. + * + * @param bufferName {@link GL#GL_FRONT} and {@link GL#GL_BACK} are valid buffer names + * @return the named {@link FBObject} + * @throws IllegalArgumentException if an illegal buffer name is being used + */ + FBObject getFBObject(int bufferName) throws IllegalArgumentException; + + /** + * Returns the named texture buffer. + *+ * If MSAA is being used, only the {@link GL#GL_FRONT} buffer is accessible + * and an exception is being thrown if {@link GL#GL_BACK} is being requested. + *
+ * @param bufferName {@link GL#GL_FRONT} and {@link GL#GL_BACK} are valid buffer names + * @return the named {@link TextureAttachment} + * @throws IllegalArgumentException if using MSAA and {@link GL#GL_BACK} is requested or an illegal buffer name is being used + */ + FBObject.TextureAttachment getTextureBuffer(int bufferName) throws IllegalArgumentException; + + /** Resizeable {@link GLFBODrawable} specialization */ + public interface Resizeable extends GLFBODrawable { + /** + * Resize this drawable. + *+ * This drawable is being locked during operation. + *
+ * @param context the {@link GLContext} bound to this drawable, will be made current during operation + * A prev. current context will be make current after operation. + * @param newWidth + * @param newHeight + * @throws NativeWindowException in case the surface could no be locked + * @throws GLException in case an error during the resize operation occurred + */ + void setSize(GLContext context, int newWidth, int newHeight) throws NativeWindowException, GLException; + } +} diff --git a/src/jogl/classes/javax/media/opengl/GLOffscreenAutoDrawable.java b/src/jogl/classes/javax/media/opengl/GLOffscreenAutoDrawable.java new file mode 100644 index 000000000..6fe76a3f4 --- /dev/null +++ b/src/jogl/classes/javax/media/opengl/GLOffscreenAutoDrawable.java @@ -0,0 +1,63 @@ +/** + * 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.opengl; + +import javax.media.nativewindow.NativeWindowException; + +import com.jogamp.opengl.FBObject; + +/** + * Platform-independent {@link GLAutoDrawable} specialization, + * exposing offscreen functionality. + *+ * This class distinguishes itself from {@link GLAutoDrawable} + * with it's {@link #setSize(int, int)} functionality. + *
+ */ +public interface GLOffscreenAutoDrawable extends GLAutoDrawable { + + /** + * Resize this auto drawable. + * @param newWidth + * @param newHeight + * @throws NativeWindowException in case the surface could no be locked + * @throws GLException in case of an error during the resize operation + */ + void setSize(int newWidth, int newHeight) throws NativeWindowException, GLException; + + /** + * Set the upstream UI toolkit object. + * @see #getUpstreamWidget() + */ + void setUpstreamWidget(Object newUpstreamWidget); + + /** {@link FBObject} based {@link GLOffscreenAutoDrawable} specialization */ + public interface FBO extends GLOffscreenAutoDrawable, GLFBODrawable { + } +} diff --git a/src/jogl/classes/javax/media/opengl/GLPbuffer.java b/src/jogl/classes/javax/media/opengl/GLPbuffer.java index 273a992cf..de7731a3b 100644 --- a/src/jogl/classes/javax/media/opengl/GLPbuffer.java +++ b/src/jogl/classes/javax/media/opengl/GLPbuffer.java @@ -45,7 +45,11 @@ package javax.media.opengl; contains experimental methods for accessing the pbuffer's contents as a texture map and enabling rendering to floating-point frame buffers. These methods are not guaranteed to be supported on all - platforms and may be deprecated in a future release. */ + platforms and may be deprecated in a future release. + + @deprecated Use {@link GLOffscreenAutoDrawable} w/ {@link GLCapabilities#setFBO(boolean)} + via {@link GLDrawableFactory#createOffscreenAutoDrawable(javax.media.nativewindow.AbstractGraphicsDevice, GLCapabilitiesImmutable, GLCapabilitiesChooser, int, int, GLContext) GLDrawableFactory.createOffscreenAutoDrawable(..)}. + */ public interface GLPbuffer extends GLAutoDrawable { /** Indicates the GL_APPLE_float_pixels extension is being used for this pbuffer. */ diff --git a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java index 033591fe3..329cf9e3f 100644 --- a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java +++ b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java @@ -98,6 +98,7 @@ import jogamp.common.awt.AWTEDTExecutor; import jogamp.opengl.Debug; import jogamp.opengl.GLContextImpl; import jogamp.opengl.GLDrawableHelper; +import jogamp.opengl.GLDrawableImpl; // FIXME: Subclasses need to call resetGLFunctionAvailability() on their // context whenever the displayChanged() function is called on our @@ -109,6 +110,16 @@ import jogamp.opengl.GLDrawableHelper; interfaces when adding a heavyweight doesn't work either because of Z-ordering or LayoutManager problems. * + *
+ * {@link OffscreenLayerOption#setShallUseOffscreenLayer(boolean) setShallUseOffscreenLayer(true)}
+ * is being called if {@link GLCapabilitiesImmutable#isOnscreen()} is false
.
+ *
- - Overrides: -
paint
in class java.awt.Component
Overridden to track when this component is removed from a @@ -620,22 +637,37 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing @SuppressWarnings("deprecation") @Override public void reshape(int x, int y, int width, int height) { - super.reshape(x, y, width, height); - final GLDrawable _drawable = drawable; - if(null != _drawable && _drawable.isRealized() && !_drawable.getChosenGLCapabilities().isOnscreen()) { - dispose(true); - } else { - sendReshape = true; + synchronized (getTreeLock()) { // super.reshape(..) claims tree lock, so we do extend it's lock over reshape + super.reshape(x, y, width, height); + + GLDrawableImpl _drawable = drawable; + if( null != _drawable ) { + if(DEBUG) { + System.err.println("GLCanvas.sizeChanged: ("+Thread.currentThread().getName()+"): "+width+"x"+height+" - surfaceHandle 0x"+Long.toHexString(getNativeSurface().getSurfaceHandle())); + } + if( ! _drawable.getChosenGLCapabilities().isOnscreen() ) { + final RecursiveLock _lock = lock; + _lock.lock(); + try { + final GLDrawableImpl _drawableNew = GLDrawableHelper.resizeOffscreenDrawable(_drawable, context, width, height); + if(_drawable != _drawableNew) { + // write back + drawable = _drawableNew; + } + } finally { + _lock.unlock(); + } + } + sendReshape = true; // async if display() doesn't get called below, but avoiding deadlock + } } } - /** Overrides: -
update
in class java.awt.Component
reshape
in class java.awt.Component
true
if {@link AbstractGraphicsDevice#close()} shall be issued,
- * otherwise pass false
. Closing the device is required in case
- * the drawable is created w/ it's own new instance, e.g. offscreen drawables,
- * and no further lifecycle handling is applied.
+ * @param drawable upstream {@link GLDrawableImpl} instance, may be null for lazy initialization
+ * @param context upstream {@link GLContextImpl} instance, may be null for lazy initialization
+ * @param ownsDevice pass true
if {@link AbstractGraphicsDevice#close()} shall be issued,
+ * otherwise pass false
. Closing the device is required in case
+ * the drawable is created w/ it's own new instance, e.g. offscreen drawables,
+ * and no further lifecycle handling is applied.
*/
- public GLAutoDrawableBase(GLDrawableImpl drawable, GLContextImpl context, boolean ownDevice) {
+ public GLAutoDrawableBase(GLDrawableImpl drawable, GLContextImpl context, boolean ownsDevice) {
this.drawable = drawable;
this.context = context;
- this.ownDevice = ownDevice;
+ this.ownsDevice = ownsDevice;
resetFPSCounter();
}
+ /** Returns the recursive lock object of the upstream implementation, which synchronizes multithreaded access. */
protected abstract RecursiveLock getLock();
- /** Returns the delegated GLDrawable */
- public final GLDrawable getDelegatedDrawable() { return drawable; }
-
/** Default implementation to handle repaint events from the windowing system */
protected final void defaultWindowRepaintOp() {
final GLDrawable _drawable = drawable;
@@ -103,29 +101,43 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, FPSCounter {
}
}
- /** Default implementation to handle resize events from the windowing system */
- protected final void defaultWindowResizedOp() {
- final GLDrawable _drawable = drawable;
+ /** Default implementation to handle resize events from the windowing system. All required locks are being claimed. */
+ protected final void defaultWindowResizedOp(int newWidth, int newHeight) throws NativeWindowException, GLException {
+ GLDrawableImpl _drawable = drawable;
if( null!=_drawable ) {
if(DEBUG) {
- System.err.println("GLAutoDrawableBase.sizeChanged: ("+Thread.currentThread().getName()+"): "+getWidth()+"x"+getHeight()+" - surfaceHandle 0x"+Long.toHexString(getNativeSurface().getSurfaceHandle()));
+ System.err.println("GLAutoDrawableBase.sizeChanged: ("+Thread.currentThread().getName()+"): "+newWidth+"x"+newHeight+" - surfaceHandle 0x"+Long.toHexString(getNativeSurface().getSurfaceHandle()));
+ }
+ if( ! _drawable.getChosenGLCapabilities().isOnscreen() ) {
+ final RecursiveLock _lock = getLock();
+ _lock.lock();
+ try {
+ final GLDrawableImpl _drawableNew = GLDrawableHelper.resizeOffscreenDrawable(_drawable, context, newWidth, newHeight);
+ if(_drawable != _drawableNew) {
+ // write back
+ _drawable = _drawableNew;
+ drawable = _drawableNew;
+ }
+ } finally {
+ _lock.unlock();
+ }
}
sendReshape = true; // async if display() doesn't get called below, but avoiding deadlock
if( _drawable.isRealized() ) {
if( !_drawable.getNativeSurface().isSurfaceLockedByOtherThread() && !helper.isAnimatorAnimating() ) {
display();
}
- }
+ }
}
}
-
+
/**
* Default implementation to handle destroy notifications from the windowing system.
*
* * If the {@link NativeSurface} does not implement {@link WindowClosingProtocol} * or {@link WindowClosingMode#DISPOSE_ON_CLOSE} is enabled (default), - * {@link #defaultDestroy()} is being called. + * a thread safe destruction is being induced. *
*/ protected final void defaultWindowDestroyNotifyOp() { @@ -174,7 +186,7 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, FPSCounter { ctrl.resume(); } } else if (null != ns && ns.isSurfaceLockedByOtherThread()) { - // surface is locked by another thread + // Surface is locked by another thread. // Flag that destroy should be performed on the next // attempt to display. sendDestroy = true; // async, but avoiding deadlock @@ -225,7 +237,7 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, FPSCounter { } _drawable.setRealized(false); } - if( ownDevice ) { + if( ownsDevice ) { _drawable.getNativeSurface().getGraphicsConfiguration().getScreen().getDevice().close(); } } @@ -238,7 +250,6 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, FPSCounter { _lock.lock(); try { if(drawable!=null && context != null) { - drawable.swapBuffers(); helper.invokeGL(drawable, context, defaultSwapAction, defaultInitAction); } } finally { @@ -276,7 +287,7 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, FPSCounter { destroy(); return; } - final RecursiveLock _lock = getLock(); + final RecursiveLock _lock = getLock(); _lock.lock(); try { if( null != context ) { @@ -294,6 +305,11 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, FPSCounter { drawable.swapBuffers(); } } ; + @Override + public final GLDrawable getDelegatedDrawable() { + return drawable; + } + @Override public final GLContext getContext() { return context; @@ -305,7 +321,7 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, FPSCounter { lock.lock(); try { final GLContext oldCtx = context; - final boolean newCtxCurrent = helper.switchContext(drawable, oldCtx, newCtx, additionalCtxCreationFlags); + final boolean newCtxCurrent = GLDrawableHelper.switchContext(drawable, oldCtx, newCtx, additionalCtxCreationFlags); context=(GLContextImpl)newCtx; if(newCtxCurrent) { context.makeCurrent(); @@ -529,4 +545,10 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, FPSCounter { final GLDrawable _drawable = drawable; return null != _drawable ? _drawable.getHandle() : 0; } + + @Override + public String toString() { + return getClass().getSimpleName()+"[ \n\tHelper: " + helper + ", \n\tDrawable: " + drawable + + ", \n\tContext: " + context + /** ", \n\tWindow: "+window+ ", \n\tFactory: "+factory+ */ "]"; + } } diff --git a/src/jogl/classes/jogamp/opengl/GLContextImpl.java b/src/jogl/classes/jogamp/opengl/GLContextImpl.java index e82756022..050c619fd 100644 --- a/src/jogl/classes/jogamp/opengl/GLContextImpl.java +++ b/src/jogl/classes/jogamp/opengl/GLContextImpl.java @@ -47,6 +47,7 @@ import java.util.Map; import com.jogamp.common.os.DynamicLookupHelper; import com.jogamp.common.util.ReflectionUtil; +import com.jogamp.common.util.VersionNumber; import com.jogamp.gluegen.runtime.FunctionAddressResolver; import com.jogamp.gluegen.runtime.ProcAddressTable; import com.jogamp.gluegen.runtime.opengl.GLNameResolver; @@ -85,6 +86,7 @@ public abstract class GLContextImpl extends GLContext { private String glRenderer; private String glRendererLowerCase; + private String glVersion; // Tracks creation and initialization of buffer objects to avoid // repeated glGet calls upon glMapBuffer operations @@ -126,6 +128,9 @@ public abstract class GLContextImpl extends GLContext { GLContextShareSet.synchronizeBufferObjectSharing(shareWith, this); this.drawable = drawable; + if(null != drawable) { + drawable.associateContext(this, true); + } this.drawableRead = drawable; this.glDebugHandler = new GLDebugMessageHandler(this); @@ -205,8 +210,10 @@ public abstract class GLContextImpl extends GLContext { if(!setWriteOnly || drawableRead==drawable) { // if !setWriteOnly || !explicitReadDrawable drawableRead = (GLDrawableImpl) readWrite; } - final GLDrawable old = drawable; + final GLDrawableImpl old = drawable; + old.associateContext(this, false); drawable = (GLDrawableImpl) readWrite ; + drawable.associateContext(this, true); if(lockHeld) { makeCurrent(); } @@ -272,7 +279,7 @@ public abstract class GLContextImpl extends GLContext { if( actualRelease ) { if( !inDestruction ) { try { - drawable.contextMadeCurrent(this, false); + contextMadeCurrent(false); } catch (Throwable t) { drawableContextMadeCurrentException = t; } @@ -331,7 +338,8 @@ public abstract class GLContextImpl extends GLContext { makeCurrent(); } try { - drawable.contextRealized(this, false); + contextRealized(false); + drawable.associateContext(this, false); } catch (Throwable t) { drawableContextRealizedException = t; } @@ -514,19 +522,17 @@ public abstract class GLContextImpl extends GLContext { gl = gl.getContext().setGL( GLPipelineFactory.create("javax.media.opengl.Trace", null, gl, new Object[] { System.err } ) ); } - drawable.contextRealized(this, true); + contextRealized(true); if(DEBUG || TRACE_SWITCH) { System.err.println(getThreadName() +": GLContext.ContextSwitch: obj " + toHexString(hashCode()) + ", ctx "+toHexString(contextHandle)+" - switch - CONTEXT_CURRENT_NEW - "+lock); } - } else { - drawable.contextMadeCurrent(this, true); - - if(TRACE_SWITCH) { - System.err.println(getThreadName() +": GLContext.ContextSwitch: obj " + toHexString(hashCode()) + ", ctx "+toHexString(contextHandle)+" - switch - CONTEXT_CURRENT - "+lock); - } + } else if(TRACE_SWITCH) { + System.err.println(getThreadName() +": GLContext.ContextSwitch: obj " + toHexString(hashCode()) + ", ctx "+toHexString(contextHandle)+" - switch - CONTEXT_CURRENT - "+lock); } + contextMadeCurrent(true); + /* FIXME: refactor dependence on Java 2D / JOGL bridge // Try cleaning up any stale server-side OpenGL objects @@ -608,6 +614,20 @@ public abstract class GLContextImpl extends GLContext { } protected abstract void makeCurrentImpl() throws GLException; + /** + * @see GLDrawableImpl#contextRealized(GLContext, boolean) + */ + protected void contextRealized(boolean realized) { + drawable.contextRealized(this, realized); + } + + /** + * @see GLDrawableImpl#contextMadeCurrent(GLContext, boolean) + */ + protected void contextMadeCurrent(boolean current) { + drawable.contextMadeCurrent(this, current); + } + /** * Platform dependent entry point for context creation.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
+ * @param width the initial width as returned by {@link NativeSurface#getWidth()}, not the actual dummy surface width.
+ * The latter is platform specific and small
+ * @param height the initial height as returned by {@link NativeSurface#getHeight()}, not the actual dummy surface height,
+ * The latter is platform specific and small
+ * @return the created {@link ProxySurface} instance w/o defined surface handle but platform specific {@link UpstreamSurfaceHook}.
*/
public abstract ProxySurface createDummySurfaceImpl(AbstractGraphicsDevice device, boolean createNewDevice,
GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser, int width, int height);
diff --git a/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java b/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java
index 090c5fe69..bdf0b6d74 100644
--- a/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java
+++ b/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java
@@ -43,12 +43,19 @@ package jogamp.opengl;
import java.util.ArrayList;
import java.util.HashSet;
+import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.ProxySurface;
+import javax.media.nativewindow.UpstreamSurfaceHook;
import javax.media.opengl.GLAnimatorControl;
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.GLException;
+import javax.media.opengl.GLFBODrawable;
import javax.media.opengl.GLRunnable;
import com.jogamp.opengl.util.Animator;
@@ -108,24 +115,27 @@ public class GLDrawableHelper {
/**
* Associate a new context to the drawable and also propagates the context/drawable switch by
* calling {@link GLContext#setGLDrawable(GLDrawable, boolean) newCtx.setGLDrawable(drawable, true);}.
- * - * If the old context's drawable was an {@link GLAutoDrawable}, it's reference to the given drawable - * is being cleared by calling - * {@link GLAutoDrawable#setContext(GLContext) ((GLAutoDrawable)oldCtx.getGLDrawable()).setContext(null)}. - *
** If the old or new context was current on this thread, it is being released before switching the drawable. *
+ *+ * Be aware that the old context is still bound to the drawable, + * and that one context can only bound to one drawable at one time! + *
+ *+ * No locking is being performed on the drawable, caller is required to take care of it. + *
* * @param drawable the drawable which context is changed - * @param newCtx the new context * @param oldCtx the old context - * @return true if the newt context was current, otherwise false + * @param newCtx the new context + * @param newCtxCreationFlags additional creation flags if newCtx is not null and not been created yet, see {@link GLContext#setContextCreationFlags(int)} + * @return true if the new context was current, otherwise false * * @see GLAutoDrawable#setContext(GLContext) */ - public final boolean switchContext(GLDrawable drawable, GLContext oldCtx, GLContext newCtx, int additionalCtxCreationFlags) { - if(null != oldCtx && oldCtx.isCurrent()) { + public static final boolean switchContext(GLDrawable drawable, GLContext oldCtx, GLContext newCtx, int newCtxCreationFlags) { + if( null != oldCtx && oldCtx.isCurrent() ) { oldCtx.release(); } final boolean newCtxCurrent; @@ -134,17 +144,135 @@ public class GLDrawableHelper { if(newCtxCurrent) { newCtx.release(); } - newCtx.setContextCreationFlags(additionalCtxCreationFlags); + newCtx.setContextCreationFlags(newCtxCreationFlags); newCtx.setGLDrawable(drawable, true); // propagate context/drawable switch } else { newCtxCurrent = false; } - if(null!=oldCtx && oldCtx.getGLDrawable() instanceof GLAutoDrawable) { - ((GLAutoDrawable)oldCtx.getGLDrawable()).setContext(null); - } return newCtxCurrent; } + /** + * If the drawable is not realized, OP is a NOP. + *+ * No locking is being performed, caller is required to take care of it. + *
+ * + * @param drawable + * @param context maybe null + * @return the new drawable + */ + public static final GLDrawableImpl recreateGLDrawable(GLDrawableImpl drawable, GLContext context) { + if( ! drawable.isRealized() ) { + return drawable; + } + final boolean contextCurrent = null != context && context.isCurrent(); + final GLDrawableFactory factory = drawable.getFactory(); + final NativeSurface surface = drawable.getNativeSurface(); + final ProxySurface proxySurface = (surface instanceof ProxySurface) ? (ProxySurface)surface : null; + + if(contextCurrent) { + context.release(); + } + + if(null != proxySurface) { + proxySurface.enableUpstreamSurfaceHookLifecycle(false); + } + try { + drawable.setRealized(false); + drawable = (GLDrawableImpl) factory.createGLDrawable(surface); // [2] + drawable.setRealized(true); + } finally { + if(null != proxySurface) { + proxySurface.enableUpstreamSurfaceHookLifecycle(true); + } + } + + if(null != context) { + context.setGLDrawable(drawable, true); // re-association + } + + if(contextCurrent) { + context.makeCurrent(); + } + return drawable; + } + + /** + * Performs resize operation on the given drawable, assuming it is offscreen. + *+ * The {@link GLDrawableImpl}'s {@link NativeSurface} is being locked during operation. + * In case the holder is an auto drawable or similar, it's lock shall be claimed by the caller. + *
+ *+ * May recreate the drawable via {@link #recreateGLDrawable(GLDrawableImpl, GLContext)} + * in case of a a pbuffer- or pixmap-drawable. + *
+ *+ * FBO drawables are resized w/o drawable destruction. + *
+ *+ * Offscreen resize operation is validated w/ drawable size in the end. + * An exception is thrown if not successful. + *
+ * + * @param drawable + * @param context + * @param newWidth the new width, it's minimum is capped to 1 + * @param newHeight the new height, it's minimum is capped to 1 + * @return the new drawable in case of an pbuffer/pixmap drawable, otherwise the passed drawable is being returned. + * @throws NativeWindowException is drawable is not offscreen or it's surface lock couldn't be claimed + * @throws GLException may be thrown a resize operation + */ + public static final GLDrawableImpl resizeOffscreenDrawable(GLDrawableImpl drawable, GLContext context, int newWidth, int newHeight) + throws NativeWindowException, GLException + { + if(drawable.getChosenGLCapabilities().isOnscreen()) { + throw new NativeWindowException("Drawable is not offscreen: "+drawable); + } + final NativeSurface ns = drawable.getNativeSurface(); + final int lockRes = ns.lockSurface(); + if (NativeSurface.LOCK_SURFACE_NOT_READY >= lockRes) { + throw new NativeWindowException("Could not lock surface of drawable: "+drawable); + } + try { + if(0>=newWidth) { newWidth = 1; } + if(0>=newHeight) { newHeight = 1; } + // propagate new size + if(ns instanceof ProxySurface) { + final ProxySurface ps = (ProxySurface) ns; + final UpstreamSurfaceHook ush = ps.getUpstreamSurfaceHook(); + if(ush instanceof UpstreamSurfaceHook.MutableSize) { + ((UpstreamSurfaceHook.MutableSize)ush).setSize(newWidth, newHeight); + } else if(DEBUG) { // we have to assume UpstreamSurfaceHook contains the new size already, hence size check @ bottom + System.err.println("GLDrawableHelper.resizeOffscreenDrawable: Drawable's offscreen ProxySurface n.a. UpstreamSurfaceHook.MutableSize, but "+ush.getClass().getName()+": "+ush); + } + } else if(DEBUG) { // we have to assume surface contains the new size already, hence size check @ bottom + System.err.println("GLDrawableHelper.resizeOffscreenDrawable: Drawable's offscreen surface n.a. ProxySurface, but "+ns.getClass().getName()+": "+ns); + } + if(drawable instanceof GLFBODrawable) { + if( null != context && context.isCreated() ) { + ((GLFBODrawable) drawable).resetSize(context.getGL()); + } + } else { + drawable = GLDrawableHelper.recreateGLDrawable(drawable, context); + } + } finally { + ns.unlockSurface(); + } + if(drawable.getWidth() != newWidth || drawable.getHeight() != newHeight) { + throw new InternalError("Incomplete resize operation: expected "+newWidth+"x"+newHeight+", has: "+drawable); + } + return drawable; + } + public final void addGLEventListener(GLEventListener listener) { addGLEventListener(-1, listener); } @@ -196,15 +324,11 @@ public class GLDrawableHelper { } } - private final boolean init(GLEventListener l, GLAutoDrawable drawable, boolean sendReshape) { - if(listenersToBeInit.remove(l)) { - l.init(drawable); - if(sendReshape) { - reshape(l, drawable, 0, 0, drawable.getWidth(), drawable.getHeight(), true /* setViewport */, false /* checkInit */); - } - return true; + private final void init(GLEventListener l, GLAutoDrawable drawable, boolean sendReshape) { + l.init(drawable); + if(sendReshape) { + reshape(l, drawable, 0, 0, drawable.getWidth(), drawable.getHeight(), true /* setViewport */, false /* checkInit */); } - return false; } /** The default init action to be called once after ctx is being created @ 1st makeCurrent(). */ @@ -214,14 +338,11 @@ public class GLDrawableHelper { for (int i=0; i < _listeners.size(); i++) { final GLEventListener listener = _listeners.get(i) ; - // If make current ctx, invoked by invokGL(..), results in a new ctx, init gets called. + // If make ctx current, invoked by invokGL(..), results in a new ctx, init gets called. // This may happen not just for initial setup, but for ctx recreation due to resource change (drawable/window), - // hence the must always be initialized unconditional. - listenersToBeInit.add(listener); - - if ( ! init( listener, drawable, true /* sendReshape */) ) { - throw new GLException("GLEventListener "+listener+" already initialized: "+drawable); - } + // hence it must be called unconditional, always. + listenersToBeInit.remove(listener); // remove if exist, avoiding dbl init + init( listener, drawable, true /* sendReshape */); } } } @@ -239,7 +360,9 @@ public class GLDrawableHelper { final GLEventListener listener = _listeners.get(i) ; // GLEventListener may need to be init, // in case this one is added after the realization of the GLAutoDrawable - init( listener, drawable, true /* sendReshape */) ; + if( listenersToBeInit.remove(listener) ) { + init( listener, drawable, true /* sendReshape */) ; + } listener.display(drawable); } } @@ -251,7 +374,9 @@ public class GLDrawableHelper { // GLEventListener may need to be init, // in case this one is added after the realization of the GLAutoDrawable synchronized(listenersLock) { - init( listener, drawable, false /* sendReshape */) ; + if( listenersToBeInit.remove(listener) ) { + init( listener, drawable, false /* sendReshape */) ; + } } } if(setViewport) { diff --git a/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java b/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java index abf2bf557..311690f1d 100644 --- a/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java +++ b/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java @@ -43,6 +43,7 @@ package jogamp.opengl; import javax.media.nativewindow.AbstractGraphicsDevice; import javax.media.nativewindow.NativeSurface; import javax.media.nativewindow.ProxySurface; +import javax.media.opengl.GL; import javax.media.opengl.GLCapabilitiesImmutable; import javax.media.opengl.GLContext; import javax.media.opengl.GLDrawable; @@ -76,31 +77,46 @@ public abstract class GLDrawableImpl implements GLDrawable { if( !realized ) { return; // destroyed already } - 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] - if (NativeSurface.LOCK_SURFACE_NOT_READY == lockRes) { - return; + int lockRes = lockSurface(); // it's recursive, so it's ok within [makeCurrent .. release] + if (NativeSurface.LOCK_SURFACE_NOT_READY == lockRes) { + return; + } + try { + if (NativeSurface.LOCK_SURFACE_CHANGED == lockRes) { + updateHandle(); + } + final GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable)surface.getGraphicsConfiguration().getChosenCapabilities(); + if ( caps.getDoubleBuffered() ) { + if(!surface.surfaceSwap()) { + swapBuffersImpl(true); } - try { - if (NativeSurface.LOCK_SURFACE_CHANGED == lockRes) { - updateHandle(); - } - swapBuffersImpl(); - } finally { - unlockSurface(); + } else { + final GLContext ctx = GLContext.getCurrent(); + if(null!=ctx && ctx.getGLDrawable()==this) { + ctx.getGL().glFlush(); } + swapBuffersImpl(false); } - } else { - GLContext ctx = GLContext.getCurrent(); - if(null!=ctx && ctx.getGLDrawable()==this) { - ctx.getGL().glFinish(); - } - } + } finally { + unlockSurface(); + } surface.surfaceUpdated(this, surface, System.currentTimeMillis()); } - protected abstract void swapBuffersImpl(); + + /** + * Platform and implementation depending surface swap. + *The surface is locked.
+ *
+ * If doubleBuffered
is true
,
+ * an actual platform dependent surface swap shall be executed.
+ *
+ * If doubleBuffered
is false
,
+ * {@link GL#glFlush()} has been called already and
+ * the implementation may execute implementation specific code.
+ *
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.
+ * If realized
is false
, the context is still current and will be released and destroyed after this method returns.
*
* @see #contextMadeCurrent(GLContext, boolean)
@@ -199,18 +218,27 @@ public abstract class GLDrawableImpl implements GLDrawable {
/**
* 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.
*
+ * Note: Will also be called after {@link #contextRealized(GLContext, boolean) contextRealized(ctx, true)} + * but not at context destruction, i.e. {@link #contextRealized(GLContext, boolean) contextRealized(ctx, false)}. + *
* @see #contextRealized(GLContext, boolean) */ protected void contextMadeCurrent(GLContext glc, boolean current) { } + /** + * Callback for special implementations, allowing to associate bound context to this drawable (bound == true) + * or to remove such association (bound == false). + * @param ctx the just bounded or unbounded context + * @param bound iftrue
create an association, otherwise remove it
+ */
+ protected void associateContext(GLContext ctx, boolean bound) { }
+
/** Callback for special implementations, allowing GLContext to fetch a custom default render framebuffer. Defaults to zero.*/
protected int getDefaultDrawFramebuffer() { return 0; }
/** Callback for special implementations, allowing GLContext to fetch a custom default read framebuffer. Defaults to zero. */
@@ -245,8 +273,8 @@ public abstract class GLDrawableImpl implements GLDrawable {
public String toString() {
return getClass().getSimpleName()+"[Realized "+isRealized()+
",\n\tFactory "+getFactory()+
- ",\n\thandle "+toHexString(getHandle())+
- ",\n\tWindow "+getNativeSurface()+"]";
+ ",\n\tHandle "+toHexString(getHandle())+
+ ",\n\tSurface "+getNativeSurface()+"]";
}
protected static String getThreadName() {
diff --git a/src/jogl/classes/jogamp/opengl/GLFBODrawableImpl.java b/src/jogl/classes/jogamp/opengl/GLFBODrawableImpl.java
index 03bc26cbc..de45466f3 100644
--- a/src/jogl/classes/jogamp/opengl/GLFBODrawableImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLFBODrawableImpl.java
@@ -1,142 +1,476 @@
package jogamp.opengl;
import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.ProxySurface;
+import javax.media.nativewindow.UpstreamSurfaceHook;
import javax.media.opengl.GL;
-import javax.media.opengl.GL2GL3;
+import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLCapabilitiesImmutable;
import javax.media.opengl.GLContext;
import javax.media.opengl.GLException;
+import javax.media.opengl.GLFBODrawable;
import com.jogamp.nativewindow.MutableGraphicsConfiguration;
import com.jogamp.opengl.FBObject;
import com.jogamp.opengl.FBObject.Attachment;
+import com.jogamp.opengl.FBObject.Colorbuffer;
import com.jogamp.opengl.FBObject.TextureAttachment;
/**
- * Offscreen GLDrawable implementation using framebuffer object (FBO)
- * as it's offscreen rendering mechanism.
+ * {@link FBObject} offscreen GLDrawable implementation, i.e. {@link GLFBODrawable}.
+ * + * It utilizes the context lifecycle hook {@link #contextRealized(GLContext, boolean)} + * to initialize the {@link FBObject} instance. + *
+ *+ * It utilizes the context current hook {@link #contextMadeCurrent(GLContext, boolean) contextMadeCurrent(context, true)} + * to {@link FBObject#bind(GL) bind} the FBO. + *
+ * See {@link GLFBODrawable} for double buffering details. * * @see GLDrawableImpl#contextRealized(GLContext, boolean) * @see GLDrawableImpl#contextMadeCurrent(GLContext, boolean) * @see GLDrawableImpl#getDefaultDrawFramebuffer() * @see GLDrawableImpl#getDefaultReadFramebuffer() */ -public class GLFBODrawableImpl extends GLDrawableImpl { - final GLDrawableImpl parent; - final FBObject fbo; - int texUnit; - int samplesTexUnit = 0; - int width=0, height=0, samples=0; - - protected GLFBODrawableImpl(GLDrawableFactoryImpl factory, GLDrawableImpl parent, - NativeSurface surface, int initialWidth, int initialHeight, int textureUnit) { +public class GLFBODrawableImpl extends GLDrawableImpl implements GLFBODrawable { + protected static final boolean DEBUG = GLDrawableImpl.DEBUG || Debug.debug("FBObject"); + + private final GLDrawableImpl parent; + + private boolean initialized; + private int texUnit; + private int samples; + + private FBObject[] fbos; + private int fboIBack; // points to GL_BACK buffer + private int fboIFront; // points to GL_FRONT buffer + private FBObject pendingFBOReset = null; + private boolean fboBound; + private static final int bufferCount = 2; // number of FBOs for double buffering. TODO: Possible to configure! + + // private DoubleBufferMode doubleBufferMode; // TODO: Add or remove TEXTURE (only) DoubleBufferMode support + + private SwapBufferContext swapBufferContext; + + public static interface SwapBufferContext { + public void swapBuffers(boolean doubleBuffered); + } + + protected GLFBODrawableImpl(GLDrawableFactoryImpl factory, GLDrawableImpl parent, NativeSurface surface, + GLCapabilitiesImmutable fboCaps, int textureUnit) { super(factory, surface, false); + this.initialized = false; + + // Replace the chosen caps of dummy-surface w/ it's clone and copied values of orig FBO caps request. + // The dummy-surface has already been configured, hence value replace is OK + // and due to cloning, the native GLCapability portion is being preserved. + final MutableGraphicsConfiguration msConfig = (MutableGraphicsConfiguration) surface.getGraphicsConfiguration(); + final GLCapabilities fboCapsNative = (GLCapabilities) msConfig.getChosenCapabilities().cloneMutable(); + fboCapsNative.copyFrom(fboCaps); + msConfig.setChosenCapabilities(fboCapsNative); + this.parent = parent; this.texUnit = textureUnit; - final GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable) surface.getGraphicsConfiguration().getChosenCapabilities(); - this.width = initialWidth; - this.height = initialHeight; - this.samples = caps.getNumSamples(); - this.fbo = new FBObject(); + this.samples = fboCaps.getNumSamples(); + + // default .. // TODO: Add or remove TEXTURE (only) DoubleBufferMode support + // this.doubleBufferMode = ( samples > 0 || fboCaps.getDoubleBuffered() ) ? DoubleBufferMode.FBO : DoubleBufferMode.NONE ; + + this.swapBufferContext = null; } - @Override - protected void contextRealized(GLContext glc, boolean realized) { - final GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable) surface.getGraphicsConfiguration().getChosenCapabilities(); - final GL gl = glc.getGL(); - if(realized) { - fbo.reset(gl, width, height, samples); - samples = fbo.getNumSamples(); // update, maybe capped + private final void initialize(boolean realize, GL gl) { + if(realize) { + final int maxSamples = gl.getMaxRenderbufferSamples(); + samples = samples <= maxSamples ? samples : maxSamples; + + final GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable) surface.getGraphicsConfiguration().getChosenCapabilities(); + final int fbosN; if(samples > 0) { - fbo.attachColorbuffer(gl, 0, caps.getAlphaBits()>0); + fbosN = 1; + } else if( caps.getDoubleBuffered() ) { + fbosN = bufferCount; } else { - fbo.attachTexture2D(gl, 0, caps.getAlphaBits()>0); + fbosN = 1; } - if( caps.getStencilBits() > 0 ) { - fbo.attachRenderbuffer(gl, Attachment.Type.DEPTH_STENCIL, 24); - } else { - fbo.attachRenderbuffer(gl, Attachment.Type.DEPTH, 24); + + fbos = new FBObject[fbosN]; + fboIBack = 0; // head + fboIFront = fbos.length - 1; // tail + + for(int i=0; i+ * The implementation may itself apply the swapping, * in which case true shall be returned. + *
* * @return true if this method completed swapping the surface, * otherwise false, in which case eg the GLDrawable diff --git a/src/nativewindow/classes/javax/media/nativewindow/OffscreenLayerSurface.java b/src/nativewindow/classes/javax/media/nativewindow/OffscreenLayerSurface.java index f7dbc6c27..f9800109c 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/OffscreenLayerSurface.java +++ b/src/nativewindow/classes/javax/media/nativewindow/OffscreenLayerSurface.java @@ -50,4 +50,7 @@ public interface OffscreenLayerSurface { /** Returns true if a surface layer is attached, otherwise false. */ public boolean isSurfaceLayerAttached(); + /** Sets the capabilities of this instance, allowing upstream API's to refine it, i.e. OpenGL related settings. */ + public void setChosenCapabilities(CapabilitiesImmutable caps); + } diff --git a/src/nativewindow/classes/javax/media/nativewindow/ProxySurface.java b/src/nativewindow/classes/javax/media/nativewindow/ProxySurface.java index 7fc9789c2..395fdc818 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/ProxySurface.java +++ b/src/nativewindow/classes/javax/media/nativewindow/ProxySurface.java @@ -1,5 +1,5 @@ /** - * Copyright 2010 JogAmp Community. All rights reserved. + * 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: @@ -29,242 +29,82 @@ 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, MutableSurface { +/** + * Provides a mutable {@link NativeSurface}, i.e. {@link MutableSurface}, while allowing an + * {@link UpstreamSurfaceHook} to influence the lifecycle and information. + * + * @see UpstreamSurfaceHook + * @see MutableSurface + * @see NativeSurface + */ +public interface ProxySurface extends 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() + * Implementation specific bit-value stating this {@link ProxySurface} owns the upstream's surface handle + * @see #addUpstreamOptionBits(int) + * @see #getUpstreamOptionBits() */ - public static final int OWN_DEVICE = 1 << 7; + public static final int OPT_PROXY_OWNS_UPSTREAM_SURFACE = 1 << 6; + + /** + * Implementation specific bit-value stating this {@link ProxySurface} owns the upstream's {@link AbstractGraphicsDevice}. + * @see #addUpstreamOptionBits(int) + * @see #getUpstreamOptionBits() + */ + public static final int OPT_PROXY_OWNS_UPSTREAM_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() + * @see #addUpstreamOptionBits(int) + * @see #getUpstreamOptionBits() */ - public static final int INVISIBLE_WINDOW = 1 << 8; + public static final int OPT_UPSTREAM_WINDOW_INVISIBLE = 1 << 8; - /** 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); + /** Allow redefining the AbstractGraphicsConfiguration */ + public void setGraphicsConfiguration(AbstractGraphicsConfiguration cfg); - /** Returns the width of the upstream surface */ - public int getWidth(ProxySurface s); - /** Returns the height of the upstream surface */ - public int getHeight(ProxySurface s); - } + /** Returns the set {@link UpstreamSurfaceHook}, or null if not set. */ + public UpstreamSurfaceHook getUpstreamSurfaceHook(); - 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 scrnIndex; - protected int implBitfield; - /** - * @param cfg the {@link AbstractGraphicsConfiguration} to be used - * @param initialWidth the initial width - * @param initialHeight the initial height + * Sets the {@link UpstreamSurfaceHook} and returns the previous value. */ - 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; - } - - public final UpstreamSurfaceHook getUpstreamSurfaceHook() { return upstream; } + public void setUpstreamSurfaceHook(UpstreamSurfaceHook hook); + + /** + * Enables or disables the {@link UpstreamSurfaceHook} lifecycle functions + * {@link UpstreamSurfaceHook#create(ProxySurface)} and {@link UpstreamSurfaceHook#destroy(ProxySurface)}. + *+ * Use this for small code blocks where the native resources shall not change, + * i.e. resizing a derived (OpenGL) drawable. + *
+ */ + public void enableUpstreamSurfaceHookLifecycle(boolean enable); /** - * 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; - } + public void createNotify(); /** - * 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. + * {@link UpstreamSurfaceHook#destroy(ProxySurface)} is being issued and all proxy surface/window handles shall be cleared. */ - public void destroyNotify() { - if(null != upstream) { - upstream.destroy(this); - invalidateImpl(); - } - this.displayHandle = 0; - this.surfaceHandle_old = 0; - } + public void destroyNotify(); - /** - * 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."); - } + public StringBuilder getUpstreamOptionBits(StringBuilder sink); + public int getUpstreamOptionBits(); - @Override - public final long getDisplayHandle() { - return displayHandle; - } - - protected final AbstractGraphicsConfiguration getPrivateGraphicsConfiguration() { - return config; - } - - @Override - public final AbstractGraphicsConfiguration getGraphicsConfiguration() { - return config.getNativeGraphicsConfiguration(); - } - - @Override - public final int getScreenIndex() { - return getGraphicsConfiguration().getScreen().getIndex(); - } - - @Override - public abstract long getSurfaceHandle(); - - @Override - public abstract void setSurfaceHandle(long surfaceHandle); + /** Returnstrue
if the give bit-mask v
is set in this instance upstream-option-bits, otherwise false
.*/
+ public boolean containsUpstreamOptionBits(int v);
- @Override
- public final int getWidth() {
- if(null != upstream) {
- return upstream.getWidth(this);
- }
- return initialWidth;
- }
-
- @Override
- public final int getHeight() {
- if(null != upstream) {
- return upstream.getHeight(this);
- }
- return initialHeight;
- }
-
- @Override
- public boolean surfaceSwap() {
- return false;
- }
-
- @Override
- public void addSurfaceUpdatedListener(SurfaceUpdatedListener l) {
- surfaceUpdatedHelper.addSurfaceUpdatedListener(l);
- }
-
- @Override
- public void addSurfaceUpdatedListener(int index, SurfaceUpdatedListener l) throws IndexOutOfBoundsException {
- surfaceUpdatedHelper.addSurfaceUpdatedListener(index, l);
- }
-
- @Override
- public void removeSurfaceUpdatedListener(SurfaceUpdatedListener l) {
- surfaceUpdatedHelper.removeSurfaceUpdatedListener(l);
- }
-
- @Override
- public void surfaceUpdated(Object updater, NativeSurface ns, long when) {
- surfaceUpdatedHelper.surfaceUpdated(updater, ns, when);
- }
-
- @Override
- public int lockSurface() throws NativeWindowException, RuntimeException {
- surfaceLock.lock();
- int res = surfaceLock.getHoldCount() == 1 ? LOCK_SURFACE_NOT_READY : LOCK_SUCCESS; // new lock ?
-
- if ( LOCK_SURFACE_NOT_READY == res ) {
- try {
- final AbstractGraphicsDevice adevice = getGraphicsConfiguration().getScreen().getDevice();
- adevice.lock();
- try {
- res = lockSurfaceImpl();
- if(LOCK_SUCCESS == res && surfaceHandle_old != getSurfaceHandle()) {
- res = LOCK_SURFACE_CHANGED;
- if(DEBUG) {
- System.err.println("ProxySurface: surface change 0x"+Long.toHexString(surfaceHandle_old)+" -> 0x"+Long.toHexString(getSurfaceHandle()));
- // Thread.dumpStack();
- }
- }
- } finally {
- if (LOCK_SURFACE_NOT_READY >= res) {
- adevice.unlock();
- }
- }
- } finally {
- if (LOCK_SURFACE_NOT_READY >= res) {
- surfaceLock.unlock();
- }
- }
- }
- return res;
- }
-
- @Override
- public final void unlockSurface() {
- surfaceLock.validateLocked();
- surfaceHandle_old = getSurfaceHandle();
-
- if (surfaceLock.getHoldCount() == 1) {
- final AbstractGraphicsDevice adevice = getGraphicsConfiguration().getScreen().getDevice();
- try {
- unlockSurfaceImpl();
- } finally {
- adevice.unlock();
- }
- }
- surfaceLock.unlock();
- }
-
- protected abstract int lockSurfaceImpl();
-
- protected abstract void unlockSurfaceImpl() ;
-
- public final void validateSurfaceLocked() {
- surfaceLock.validateLocked();
- }
-
- @Override
- public final boolean isSurfaceLockedByOtherThread() {
- return surfaceLock.isLockedByOtherThread();
- }
-
- @Override
- public final Thread getSurfaceLockOwner() {
- return surfaceLock.getOwner();
- }
+ /** Add the given bit-mask to this instance upstream-option-bits using bit-or w/ v
.*/
+ public void addUpstreamOptionBits(int v);
- @Override
- public abstract String toString();
+ /** Clear the given bit-mask from this instance upstream-option-bits using bit-and w/ ~v
*/
+ public void clearUpstreamOptionBits(int v);
- public int getImplBitfield() { return implBitfield; }
- public void setImplBitfield(int v) { implBitfield=v; }
+ public StringBuilder toString(StringBuilder sink);
+ public String toString();
}
diff --git a/src/nativewindow/classes/javax/media/nativewindow/UpstreamSurfaceHook.java b/src/nativewindow/classes/javax/media/nativewindow/UpstreamSurfaceHook.java
new file mode 100644
index 000000000..6fe2e5364
--- /dev/null
+++ b/src/nativewindow/classes/javax/media/nativewindow/UpstreamSurfaceHook.java
@@ -0,0 +1,52 @@
+/**
+ * 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;
+
+/**
+ * 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, used if {@link ProxySurface#UPSTREAM_PROVIDES_SIZE} is set. */
+ public int getWidth(ProxySurface s);
+ /** Returns the height of the upstream surface, used if {@link ProxySurface#UPSTREAM_PROVIDES_SIZE} is set. */
+ public int getHeight(ProxySurface s);
+
+ /**
+ * {@link UpstreamSurfaceHook} w/ mutable size, allowing it's {@link ProxySurface} user to resize.
+ */
+ public interface MutableSize extends UpstreamSurfaceHook {
+ public void setSize(int width, int height);
+ }
+}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/ProxySurfaceImpl.java b/src/nativewindow/classes/jogamp/nativewindow/ProxySurfaceImpl.java
new file mode 100644
index 000000000..63f56cbae
--- /dev/null
+++ b/src/nativewindow/classes/jogamp/nativewindow/ProxySurfaceImpl.java
@@ -0,0 +1,326 @@
+/**
+ * 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 jogamp.nativewindow;
+
+import javax.media.nativewindow.AbstractGraphicsConfiguration;
+import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.ProxySurface;
+import javax.media.nativewindow.SurfaceUpdatedListener;
+import javax.media.nativewindow.UpstreamSurfaceHook;
+
+
+import com.jogamp.common.util.locks.LockFactory;
+import com.jogamp.common.util.locks.RecursiveLock;
+
+public abstract class ProxySurfaceImpl implements ProxySurface {
+ private final SurfaceUpdatedHelper surfaceUpdatedHelper = new SurfaceUpdatedHelper();
+ protected long displayHandle; // convenient ref of config.screen.device.handle
+ private AbstractGraphicsConfiguration config; // control access due to delegation
+ private UpstreamSurfaceHook upstream;
+ private long surfaceHandle_old;
+ private RecursiveLock surfaceLock = LockFactory.createRecursiveLock();
+ private int implBitfield;
+ private boolean upstreamSurfaceHookLifecycleEnabled;
+
+ /**
+ * @param cfg the {@link AbstractGraphicsConfiguration} to be used
+ * @param upstream the {@link UpstreamSurfaceHook} to be used
+ * @param ownsDevice true
if this {@link ProxySurface} instance
+ * owns the {@link AbstractGraphicsConfiguration}'s {@link AbstractGraphicsDevice},
+ * otherwise false
. Owning the device implies closing it at {@link #destroyNotify()}.
+ */
+ protected ProxySurfaceImpl(AbstractGraphicsConfiguration cfg, UpstreamSurfaceHook upstream, boolean ownsDevice) {
+ if(null == cfg) {
+ throw new IllegalArgumentException("null AbstractGraphicsConfiguration");
+ }
+ if(null == upstream) {
+ throw new IllegalArgumentException("null UpstreamSurfaceHook");
+ }
+ this.config = cfg;
+ this.displayHandle=config.getNativeGraphicsConfiguration().getScreen().getDevice().getHandle();
+ this.upstream = upstream;
+ this.surfaceHandle_old = 0;
+ this.implBitfield = 0;
+ this.upstreamSurfaceHookLifecycleEnabled = true;
+ if(ownsDevice) {
+ addUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_DEVICE );
+ }
+ }
+
+ @Override
+ public final UpstreamSurfaceHook getUpstreamSurfaceHook() { return upstream; }
+
+ @Override
+ public void setUpstreamSurfaceHook(UpstreamSurfaceHook hook) {
+ if(null == hook) {
+ throw new IllegalArgumentException("null UpstreamSurfaceHook");
+ }
+ upstream = hook;
+ }
+
+ @Override
+ public final void enableUpstreamSurfaceHookLifecycle(boolean enable) {
+ upstreamSurfaceHookLifecycleEnabled = enable;
+ }
+
+ @Override
+ public void createNotify() {
+ if(upstreamSurfaceHookLifecycleEnabled) {
+ upstream.create(this);
+ }
+ this.displayHandle=config.getNativeGraphicsConfiguration().getScreen().getDevice().getHandle();
+ this.surfaceHandle_old = 0;
+ }
+
+ @Override
+ public void destroyNotify() {
+ if(upstreamSurfaceHookLifecycleEnabled) {
+ upstream.destroy(this);
+ if( containsUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_DEVICE ) ) {
+ final AbstractGraphicsDevice aDevice = getGraphicsConfiguration().getScreen().getDevice();
+ aDevice.close();
+ clearUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_DEVICE );
+ }
+ 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;
+ }
+
+ protected final AbstractGraphicsConfiguration getPrivateGraphicsConfiguration() {
+ return config;
+ }
+
+ @Override
+ public final AbstractGraphicsConfiguration getGraphicsConfiguration() {
+ return config.getNativeGraphicsConfiguration();
+ }
+
+ @Override
+ public final void setGraphicsConfiguration(AbstractGraphicsConfiguration cfg) {
+ config = cfg;
+ }
+
+ @Override
+ public final int getScreenIndex() {
+ return getGraphicsConfiguration().getScreen().getIndex();
+ }
+
+ @Override
+ public abstract long getSurfaceHandle();
+
+ @Override
+ public abstract void setSurfaceHandle(long surfaceHandle);
+
+ @Override
+ public final int getWidth() {
+ return upstream.getWidth(this);
+ }
+
+ @Override
+ public final int getHeight() {
+ return upstream.getHeight(this);
+ }
+
+ @Override
+ public boolean surfaceSwap() {
+ return false;
+ }
+
+ @Override
+ public void addSurfaceUpdatedListener(SurfaceUpdatedListener l) {
+ surfaceUpdatedHelper.addSurfaceUpdatedListener(l);
+ }
+
+ @Override
+ public void addSurfaceUpdatedListener(int index, SurfaceUpdatedListener l) throws IndexOutOfBoundsException {
+ surfaceUpdatedHelper.addSurfaceUpdatedListener(index, l);
+ }
+
+ @Override
+ public void removeSurfaceUpdatedListener(SurfaceUpdatedListener l) {
+ surfaceUpdatedHelper.removeSurfaceUpdatedListener(l);
+ }
+
+ @Override
+ public void surfaceUpdated(Object updater, NativeSurface ns, long when) {
+ surfaceUpdatedHelper.surfaceUpdated(updater, ns, when);
+ }
+
+ @Override
+ public int lockSurface() throws NativeWindowException, RuntimeException {
+ surfaceLock.lock();
+ int res = surfaceLock.getHoldCount() == 1 ? LOCK_SURFACE_NOT_READY : LOCK_SUCCESS; // new lock ?
+
+ if ( LOCK_SURFACE_NOT_READY == res ) {
+ try {
+ final AbstractGraphicsDevice adevice = getGraphicsConfiguration().getScreen().getDevice();
+ adevice.lock();
+ try {
+ res = lockSurfaceImpl();
+ if(LOCK_SUCCESS == res && surfaceHandle_old != getSurfaceHandle()) {
+ res = LOCK_SURFACE_CHANGED;
+ if(DEBUG) {
+ System.err.println("ProxySurfaceImpl: surface change 0x"+Long.toHexString(surfaceHandle_old)+" -> 0x"+Long.toHexString(getSurfaceHandle()));
+ // Thread.dumpStack();
+ }
+ }
+ } finally {
+ if (LOCK_SURFACE_NOT_READY >= res) {
+ adevice.unlock();
+ }
+ }
+ } finally {
+ if (LOCK_SURFACE_NOT_READY >= res) {
+ surfaceLock.unlock();
+ }
+ }
+ }
+ return res;
+ }
+
+ @Override
+ public final void unlockSurface() {
+ surfaceLock.validateLocked();
+ surfaceHandle_old = getSurfaceHandle();
+
+ if (surfaceLock.getHoldCount() == 1) {
+ final AbstractGraphicsDevice adevice = getGraphicsConfiguration().getScreen().getDevice();
+ try {
+ unlockSurfaceImpl();
+ } finally {
+ adevice.unlock();
+ }
+ }
+ surfaceLock.unlock();
+ }
+
+ protected abstract int lockSurfaceImpl();
+
+ protected abstract void unlockSurfaceImpl() ;
+
+ public final void validateSurfaceLocked() {
+ surfaceLock.validateLocked();
+ }
+
+ @Override
+ public final boolean isSurfaceLockedByOtherThread() {
+ return surfaceLock.isLockedByOtherThread();
+ }
+
+ @Override
+ public final Thread getSurfaceLockOwner() {
+ return surfaceLock.getOwner();
+ }
+
+ public final StringBuilder getUpstreamOptionBits(StringBuilder sink) {
+ if(null == sink) {
+ sink = new StringBuilder();
+ }
+ sink.append("UOB[ ");
+ if(0 == implBitfield) {
+ sink.append("]");
+ return sink;
+ }
+ boolean needsOr = false;
+ if( 0 != ( implBitfield & OPT_PROXY_OWNS_UPSTREAM_SURFACE ) ) {
+ sink.append("OWNS_SURFACE");
+ needsOr = true;
+ }
+ if( 0 != ( implBitfield & OPT_PROXY_OWNS_UPSTREAM_DEVICE ) ) {
+ if(needsOr) {
+ sink.append(" | ");
+ }
+ sink.append("OWNS_DEVICE");
+ needsOr = true;
+ }
+ if( 0 != ( implBitfield & OPT_UPSTREAM_WINDOW_INVISIBLE ) ) {
+ if(needsOr) {
+ sink.append(" | ");
+ }
+ sink.append("WINDOW_INVISIBLE");
+ needsOr = true;
+ }
+ sink.append(" ]");
+ return sink;
+ }
+
+ @Override
+ public final int getUpstreamOptionBits() { return implBitfield; }
+
+ @Override
+ public final boolean containsUpstreamOptionBits(int v) {
+ return v == ( implBitfield & v ) ;
+ }
+
+ @Override
+ public final void addUpstreamOptionBits(int v) { implBitfield |= v; }
+
+ @Override
+ public final void clearUpstreamOptionBits(int v) { implBitfield &= ~v; }
+
+ @Override
+ public StringBuilder toString(StringBuilder sink) {
+ if(null == sink) {
+ sink = new StringBuilder();
+ }
+ sink.append(getUpstreamSurfaceHook()).
+ append(", displayHandle 0x" + Long.toHexString(getDisplayHandle())).
+ append(", surfaceHandle 0x" + Long.toHexString(getSurfaceHandle())).
+ append(", size " + getWidth() + "x" + getHeight()).append(", ");
+ getUpstreamOptionBits(sink);
+ sink.append(", surfaceLock "+surfaceLock);
+ return sink;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder msg = new StringBuilder();
+ msg.append(getClass().getSimpleName()).append("[ ");
+ toString(msg);
+ msg.append(" ]");
+ return msg.toString();
+ }
+
+}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/WrappedSurface.java b/src/nativewindow/classes/jogamp/nativewindow/WrappedSurface.java
new file mode 100644
index 000000000..e544bc61a
--- /dev/null
+++ b/src/nativewindow/classes/jogamp/nativewindow/WrappedSurface.java
@@ -0,0 +1,95 @@
+/**
+ * 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 jogamp.nativewindow;
+
+import javax.media.nativewindow.AbstractGraphicsConfiguration;
+import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.nativewindow.ProxySurface;
+import javax.media.nativewindow.UpstreamSurfaceHook;
+
+import com.jogamp.nativewindow.UpstreamSurfaceHookMutableSize;
+
+public class WrappedSurface extends ProxySurfaceImpl {
+ protected long surfaceHandle;
+
+ /**
+ * Utilizes a {@link UpstreamSurfaceHook.MutableSize} to hold the size information,
+ * which is being passed to the {@link ProxySurface} instance.
+ *
+ * @param cfg the {@link AbstractGraphicsConfiguration} to be used
+ * @param handle the wrapped pre-existing native surface handle, maybe 0 if not yet determined
+ * @param initialWidth
+ * @param initialHeight
+ * @param ownsDevice true
if this {@link ProxySurface} instance
+ * owns the {@link AbstractGraphicsConfiguration}'s {@link AbstractGraphicsDevice},
+ * otherwise false
. Owning the device implies closing it at {@link #destroyNotify()}.
+ */
+ public WrappedSurface(AbstractGraphicsConfiguration cfg, long handle, int initialWidth, int initialHeight, boolean ownsDevice) {
+ super(cfg, new UpstreamSurfaceHookMutableSize(initialWidth, initialHeight), ownsDevice);
+ surfaceHandle=handle;
+ }
+
+ /**
+ * @param cfg the {@link AbstractGraphicsConfiguration} to be used
+ * @param handle the wrapped pre-existing native surface handle, maybe 0 if not yet determined
+ * @param upstream the {@link UpstreamSurfaceHook} to be used
+ * @param ownsDevice true
if this {@link ProxySurface} instance
+ * owns the {@link AbstractGraphicsConfiguration}'s {@link AbstractGraphicsDevice},
+ * otherwise false
.
+ */
+ public WrappedSurface(AbstractGraphicsConfiguration cfg, long handle, UpstreamSurfaceHook upstream, boolean ownsDevice) {
+ super(cfg, upstream, ownsDevice);
+ surfaceHandle=handle;
+ }
+
+ @Override
+ protected void invalidateImpl() {
+ surfaceHandle = 0;
+ }
+
+ @Override
+ public final long getSurfaceHandle() {
+ return surfaceHandle;
+ }
+
+ @Override
+ public final void setSurfaceHandle(long surfaceHandle) {
+ this.surfaceHandle=surfaceHandle;
+ }
+
+ @Override
+ protected final int lockSurfaceImpl() {
+ return LOCK_SUCCESS;
+ }
+
+ @Override
+ protected final void unlockSurfaceImpl() {
+ }
+
+}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java
index e81d61e0f..5fd242247 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java
@@ -51,7 +51,6 @@ import javax.media.nativewindow.NativeWindowException;
import javax.media.nativewindow.MutableSurface;
import javax.media.nativewindow.util.Point;
-import com.jogamp.nativewindow.MutableGraphicsConfiguration;
import com.jogamp.nativewindow.awt.JAWTWindow;
import jogamp.nativewindow.jawt.JAWT;
@@ -71,17 +70,18 @@ public class MacOSXJAWTWindow extends JAWTWindow implements MutableSurface {
}
protected void invalidateNative() {
- surfaceHandle=0;
+ offscreenSurfaceHandle=0;
+ offscreenSurfaceHandleSet=false;
if(isOffscreenLayerSurfaceEnabled()) {
if(0 != rootSurfaceLayerHandle) {
OSXUtil.DestroyCALayer(rootSurfaceLayerHandle);
rootSurfaceLayerHandle = 0;
}
- if(0 != drawable) {
- OSXUtil.DestroyNSWindow(drawable);
- drawable = 0;
+ if(0 != windowHandle) {
+ OSXUtil.DestroyNSWindow(windowHandle);
}
}
+ windowHandle=0;
}
protected void attachSurfaceLayerImpl(final long layerHandle) {
@@ -92,8 +92,14 @@ public class MacOSXJAWTWindow extends JAWTWindow implements MutableSurface {
OSXUtil.RemoveCASublayer(rootSurfaceLayerHandle, layerHandle);
}
- public long getSurfaceHandle() {
- return isOffscreenLayerSurfaceEnabled() ? surfaceHandle : super.getSurfaceHandle() ;
+ @Override
+ public final long getWindowHandle() {
+ return windowHandle;
+ }
+
+ @Override
+ public final long getSurfaceHandle() {
+ return offscreenSurfaceHandleSet ? offscreenSurfaceHandle : drawable /* super.getSurfaceHandle() */ ;
}
public void setSurfaceHandle(long surfaceHandle) {
@@ -103,7 +109,8 @@ public class MacOSXJAWTWindow extends JAWTWindow implements MutableSurface {
if(DEBUG) {
System.err.println("MacOSXJAWTWindow.setSurfaceHandle(): 0x"+Long.toHexString(surfaceHandle));
}
- this.surfaceHandle = surfaceHandle;
+ this.offscreenSurfaceHandle = surfaceHandle;
+ this.offscreenSurfaceHandleSet = true;
}
protected JAWT fetchJAWTImpl() throws NativeWindowException {
@@ -167,6 +174,7 @@ public class MacOSXJAWTWindow extends JAWTWindow implements MutableSurface {
unlockSurfaceImpl();
return NativeWindow.LOCK_SURFACE_NOT_READY;
} else {
+ windowHandle = OSXUtil.GetNSWindow(drawable);
ret = NativeWindow.LOCK_SUCCESS;
}
} else {
@@ -177,36 +185,46 @@ public class MacOSXJAWTWindow extends JAWTWindow implements MutableSurface {
* The actual surface/ca-layer shall be created/attached
* by the upper framework (JOGL) since they require more information.
*/
+ String errMsg = null;
if(0 == drawable) {
- drawable = OSXUtil.CreateNSWindow(0, 0, getBounds().getWidth(), getBounds().getHeight());
- if(0 == drawable) {
- unlockSurfaceImpl();
- throw new NativeWindowException("Unable to created dummy NSWindow (layered case)");
+ windowHandle = OSXUtil.CreateNSWindow(0, 0, 64, 64);
+ if(0 == windowHandle) {
+ errMsg = "Unable to create dummy NSWindow (layered case)";
+ } else {
+ drawable = OSXUtil.GetNSView(windowHandle);
+ if(0 == drawable) {
+ errMsg = "Null NSView of NSWindow 0x"+Long.toHexString(windowHandle);
+ }
+ }
+ if(null == errMsg) {
+ // fix caps reflecting offscreen! (no GL available here ..)
+ Capabilities caps = (Capabilities) getGraphicsConfiguration().getChosenCapabilities().cloneMutable();
+ caps.setOnscreen(false);
+ setChosenCapabilities(caps);
}
- // fix caps reflecting offscreen!
- Capabilities caps = (Capabilities) getPrivateGraphicsConfiguration().getChosenCapabilities().cloneMutable();
- caps.setOnscreen(false);
- getPrivateGraphicsConfiguration().setChosenCapabilities(caps);
- caps = (Capabilities) getGraphicsConfiguration().getChosenCapabilities().cloneMutable();
- caps.setOnscreen(false);
- ((MutableGraphicsConfiguration)getGraphicsConfiguration()).setChosenCapabilities(caps);
}
- if(0 == rootSurfaceLayerHandle) {
- rootSurfaceLayerHandle = OSXUtil.CreateCALayer(bounds.getX(), bounds.getY(), bounds.getWidth(), bounds.getHeight());
- if(0 == rootSurfaceLayerHandle) {
- OSXUtil.DestroyNSWindow(drawable);
- drawable = 0;
- unlockSurfaceImpl();
- throw new NativeWindowException("Could not create root CALayer: "+this);
+ if(null == errMsg) {
+ if(0 == rootSurfaceLayerHandle) {
+ rootSurfaceLayerHandle = OSXUtil.CreateCALayer(bounds.getX(), bounds.getY(), bounds.getWidth(), bounds.getHeight());
+ if(0 == rootSurfaceLayerHandle) {
+ errMsg = "Could not create root CALayer";
+ } else if(!SetJAWTRootSurfaceLayer0(dsi.getBuffer(), rootSurfaceLayerHandle)) {
+ errMsg = "Could not set JAWT rootSurfaceLayerHandle 0x"+Long.toHexString(rootSurfaceLayerHandle);
+ }
}
- if(!SetJAWTRootSurfaceLayer0(dsi.getBuffer(), rootSurfaceLayerHandle)) {
+ }
+ if(null != errMsg) {
+ if(0 != rootSurfaceLayerHandle) {
OSXUtil.DestroyCALayer(rootSurfaceLayerHandle);
rootSurfaceLayerHandle = 0;
- OSXUtil.DestroyNSWindow(drawable);
- drawable = 0;
- unlockSurfaceImpl();
- throw new NativeWindowException("Could not set JAWT rootSurfaceLayerHandle: "+this);
}
+ if(0 != windowHandle) {
+ OSXUtil.DestroyNSWindow(windowHandle);
+ windowHandle = 0;
+ }
+ drawable = 0;
+ unlockSurfaceImpl();
+ throw new NativeWindowException(errMsg+": "+this);
}
ret = NativeWindow.LOCK_SUCCESS;
}
@@ -264,7 +282,9 @@ public class MacOSXJAWTWindow extends JAWTWindow implements MutableSurface {
private long rootSurfaceLayerHandle = 0; // attached to the JAWT_SurfaceLayer
- private long surfaceHandle = 0;
+ private long windowHandle = 0;
+ private long offscreenSurfaceHandle = 0;
+ private boolean offscreenSurfaceHandleSet = false;
// Workaround for instance of 4796548
private boolean firstLock = true;
diff --git a/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXDummyUpstreamSurfaceHook.java b/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXDummyUpstreamSurfaceHook.java
new file mode 100644
index 000000000..de3206c0c
--- /dev/null
+++ b/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXDummyUpstreamSurfaceHook.java
@@ -0,0 +1,56 @@
+package jogamp.nativewindow.macosx;
+
+import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.ProxySurface;
+import javax.media.nativewindow.UpstreamSurfaceHook;
+
+import com.jogamp.nativewindow.UpstreamSurfaceHookMutableSize;
+
+public class OSXDummyUpstreamSurfaceHook extends UpstreamSurfaceHookMutableSize {
+ long nsWindow;
+
+ /**
+ * @param width the initial width as returned by {@link NativeSurface#getWidth()} via {@link UpstreamSurfaceHook#getWidth(ProxySurface)},
+ * not the actual dummy surface width.
+ * The latter is platform specific and small
+ * @param height the initial height as returned by {@link NativeSurface#getHeight()} via {@link UpstreamSurfaceHook#getHeight(ProxySurface)},
+ * not the actual dummy surface height,
+ * The latter is platform specific and small
+ */
+ public OSXDummyUpstreamSurfaceHook(int width, int height) {
+ super(width, height);
+ nsWindow = 0;
+ }
+
+ @Override
+ public final void create(ProxySurface s) {
+ if(0 == nsWindow && 0 == s.getSurfaceHandle()) {
+ nsWindow = OSXUtil.CreateNSWindow(0, 0, 64, 64);
+ if(0 == nsWindow) {
+ throw new NativeWindowException("Error NS window 0");
+ }
+ long nsView = OSXUtil.GetNSView(nsWindow);
+ if(0 == nsView) {
+ throw new NativeWindowException("Error NS view 0");
+ }
+ s.setSurfaceHandle(nsView);
+ s.addUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE );
+ }
+ s.addUpstreamOptionBits(ProxySurface.OPT_UPSTREAM_WINDOW_INVISIBLE);
+ }
+
+ @Override
+ public final void destroy(ProxySurface s) {
+ if( s.containsUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE ) ) {
+ if( 0 == nsWindow || 0 == s.getSurfaceHandle() ) {
+ throw new InternalError("Owns upstream surface, but no OSX view/window: "+s+", nsWindow 0x"+Long.toHexString(nsWindow));
+ }
+ OSXUtil.DestroyNSWindow(nsWindow);
+ nsWindow = 0;
+ s.setSurfaceHandle(0);
+ s.clearUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE );
+ }
+ }
+
+}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java b/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java
index 149ebdf4a..b7a83e133 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java
@@ -72,6 +72,10 @@ public class OSXUtil {
return isNSView0(object);
}
+ public static boolean isNSWindow(long object) {
+ return isNSWindow0(object);
+ }
+
/**
* In case the windowOrView
is top-level,
* you shall set topLevel
to true where
@@ -114,6 +118,9 @@ public class OSXUtil {
public static long GetNSView(long nsWindow) {
return GetNSView0(nsWindow);
}
+ public static long GetNSWindow(long nsView) {
+ return GetNSWindow0(nsView);
+ }
public static long CreateCALayer(int x, int y, int width, int height) {
return CreateCALayer0(x, y, width, height);
@@ -149,6 +156,11 @@ public class OSXUtil {
return IsMainThread0();
}
+ /** Returns the screen refresh rate in Hz. If unavailable, returns 60Hz. */
+ public static int GetScreenRefreshRate(int scrn_idx) {
+ return GetScreenRefreshRate0(scrn_idx);
+ }
+
/***
private static boolean isAWTEDTMainThreadInit = false;
private static boolean isAWTEDTMainThread;
@@ -172,15 +184,18 @@ public class OSXUtil {
private static native boolean initIDs0();
private static native boolean isNSView0(long object);
+ private static native boolean isNSWindow0(long object);
private static native Object GetLocationOnScreen0(long windowOrView, int src_x, int src_y);
private static native Object GetInsets0(long windowOrView);
private static native long CreateNSWindow0(int x, int y, int width, int height);
private static native void DestroyNSWindow0(long nsWindow);
private static native long GetNSView0(long nsWindow);
+ private static native long GetNSWindow0(long nsView);
private static native long CreateCALayer0(int x, int y, int width, int height);
private static native void AddCASublayer0(long rootCALayer, long subCALayer);
private static native void RemoveCASublayer0(long rootCALayer, long subCALayer);
private static native void DestroyCALayer0(long caLayer);
private static native void RunOnMainThread0(boolean waitUntilDone, Runnable runnable);
private static native boolean IsMainThread0();
+ private static native int GetScreenRefreshRate0(int scrn_idx);
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/windows/GDIDummyUpstreamSurfaceHook.java b/src/nativewindow/classes/jogamp/nativewindow/windows/GDIDummyUpstreamSurfaceHook.java
new file mode 100644
index 000000000..aa5f3dac5
--- /dev/null
+++ b/src/nativewindow/classes/jogamp/nativewindow/windows/GDIDummyUpstreamSurfaceHook.java
@@ -0,0 +1,50 @@
+package jogamp.nativewindow.windows;
+
+import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.ProxySurface;
+import javax.media.nativewindow.UpstreamSurfaceHook;
+
+import com.jogamp.nativewindow.UpstreamSurfaceHookMutableSize;
+
+public class GDIDummyUpstreamSurfaceHook extends UpstreamSurfaceHookMutableSize {
+ /**
+ * @param width the initial width as returned by {@link NativeSurface#getWidth()} via {@link UpstreamSurfaceHook#getWidth(ProxySurface)},
+ * not the actual dummy surface width.
+ * The latter is platform specific and small
+ * @param height the initial height as returned by {@link NativeSurface#getHeight()} via {@link UpstreamSurfaceHook#getHeight(ProxySurface)},
+ * not the actual dummy surface height,
+ * The latter is platform specific and small
+ */
+ public GDIDummyUpstreamSurfaceHook(int width, int height) {
+ super(width, height);
+ }
+
+ @Override
+ public final void create(ProxySurface s) {
+ final GDISurface ms = (GDISurface)s;
+ if(0 == ms.getWindowHandle()) {
+ final long windowHandle = GDIUtil.CreateDummyWindow(0, 0, 64, 64);
+ if(0 == windowHandle) {
+ throw new NativeWindowException("Error windowHandle 0, werr: "+GDI.GetLastError());
+ }
+ ms.setWindowHandle(windowHandle);
+ ms.addUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE );
+ }
+ s.addUpstreamOptionBits(ProxySurface.OPT_UPSTREAM_WINDOW_INVISIBLE);
+ }
+
+ @Override
+ public final void destroy(ProxySurface s) {
+ final GDISurface ms = (GDISurface)s;
+ if( ms.containsUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE ) ) {
+ if( 0 == ms.getWindowHandle() ) {
+ throw new InternalError("Owns upstream surface, but no GDI window: "+ms);
+ }
+ GDI.ShowWindow(ms.getWindowHandle(), GDI.SW_HIDE);
+ GDIUtil.DestroyDummyWindow(ms.getWindowHandle());
+ ms.setWindowHandle(0);
+ ms.clearUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE );
+ }
+ }
+}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/windows/GDISurface.java b/src/nativewindow/classes/jogamp/nativewindow/windows/GDISurface.java
index e368aa6a1..3db2b5fc9 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/windows/GDISurface.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/windows/GDISurface.java
@@ -29,9 +29,13 @@
package jogamp.nativewindow.windows;
import javax.media.nativewindow.AbstractGraphicsConfiguration;
+import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.NativeWindowException;
import javax.media.nativewindow.ProxySurface;
-import javax.media.nativewindow.ProxySurface.UpstreamSurfaceHook;
+import javax.media.nativewindow.UpstreamSurfaceHook;
+
+import jogamp.nativewindow.ProxySurfaceImpl;
+import jogamp.nativewindow.windows.GDI;
/**
@@ -40,12 +44,20 @@ import javax.media.nativewindow.ProxySurface.UpstreamSurfaceHook;
* The latter will get and release the HDC.
* The size via getWidth()/getHeight() is invalid.
*/
-public class GDISurface extends ProxySurface {
+public class GDISurface extends ProxySurfaceImpl {
protected long windowHandle;
protected long surfaceHandle;
- public GDISurface(AbstractGraphicsConfiguration cfg, long windowHandle, int initialWidth, int initialHeight, UpstreamSurfaceHook upstream) {
- super(cfg, initialWidth, initialHeight, upstream);
+ /**
+ * @param cfg the {@link AbstractGraphicsConfiguration} to be used
+ * @param windowHandle the wrapped pre-existing native window handle, maybe 0 if not yet determined
+ * @param upstream the {@link UpstreamSurfaceHook} to be used
+ * @param ownsDevice true
if this {@link ProxySurface} instance
+ * owns the {@link AbstractGraphicsConfiguration}'s {@link AbstractGraphicsDevice},
+ * otherwise false
. Owning the device implies closing it at {@link #destroyNotify()}.
+ */
+ public GDISurface(AbstractGraphicsConfiguration cfg, long windowHandle, UpstreamSurfaceHook upstream, boolean ownsDevice) {
+ super(cfg, upstream, ownsDevice);
this.windowHandle=windowHandle;
this.surfaceHandle=0;
}
@@ -114,18 +126,4 @@ public class GDISurface extends ProxySurface {
final public long getSurfaceHandle() {
return surfaceHandle;
}
-
- @Override
- final public String toString() {
- 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+
- ", upstreamSurfaceHook "+ush_s+"]";
- }
-
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/x11/X11DummyUpstreamSurfaceHook.java b/src/nativewindow/classes/jogamp/nativewindow/x11/X11DummyUpstreamSurfaceHook.java
new file mode 100644
index 000000000..55a29dd5e
--- /dev/null
+++ b/src/nativewindow/classes/jogamp/nativewindow/x11/X11DummyUpstreamSurfaceHook.java
@@ -0,0 +1,60 @@
+package jogamp.nativewindow.x11;
+
+import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.ProxySurface;
+import javax.media.nativewindow.UpstreamSurfaceHook;
+
+import jogamp.nativewindow.x11.X11Lib;
+
+import com.jogamp.nativewindow.UpstreamSurfaceHookMutableSize;
+import com.jogamp.nativewindow.x11.X11GraphicsConfiguration;
+import com.jogamp.nativewindow.x11.X11GraphicsDevice;
+import com.jogamp.nativewindow.x11.X11GraphicsScreen;
+
+public class X11DummyUpstreamSurfaceHook extends UpstreamSurfaceHookMutableSize {
+ /**
+ * @param width the initial width as returned by {@link NativeSurface#getWidth()} via {@link UpstreamSurfaceHook#getWidth(ProxySurface)},
+ * not the actual dummy surface width.
+ * The latter is platform specific and small
+ * @param height the initial height as returned by {@link NativeSurface#getHeight()} via {@link UpstreamSurfaceHook#getHeight(ProxySurface)},
+ * not the actual dummy surface height,
+ * The latter is platform specific and small
+ */
+ public X11DummyUpstreamSurfaceHook(int width, int height) {
+ super(width, height);
+ }
+
+ @Override
+ public final void create(ProxySurface s) {
+ final X11GraphicsConfiguration cfg = (X11GraphicsConfiguration) s.getGraphicsConfiguration();
+ final X11GraphicsScreen screen = (X11GraphicsScreen) cfg.getScreen();
+ final X11GraphicsDevice device = (X11GraphicsDevice) screen.getDevice();
+ if(0 == device.getHandle()) {
+ device.open();
+ s.addUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_DEVICE );
+ }
+ if( 0 == s.getSurfaceHandle() ) {
+ final long windowHandle = X11Lib.CreateDummyWindow(device.getHandle(), screen.getIndex(), cfg.getXVisualID(), 64, 64);
+ if(0 == windowHandle) {
+ throw new NativeWindowException("Creating dummy window failed w/ "+cfg);
+ }
+ s.setSurfaceHandle(windowHandle);
+ s.addUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE );
+ }
+ s.addUpstreamOptionBits(ProxySurface.OPT_UPSTREAM_WINDOW_INVISIBLE);
+ }
+
+ @Override
+ public final void destroy(ProxySurface s) {
+ if( s.containsUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE ) ) {
+ final X11GraphicsDevice device = (X11GraphicsDevice) s.getGraphicsConfiguration().getScreen().getDevice();
+ if( 0 == s.getSurfaceHandle() ) {
+ throw new InternalError("Owns upstream surface, but no X11 window: "+s);
+ }
+ X11Lib.DestroyDummyWindow(device.getHandle(), s.getSurfaceHandle());
+ s.setSurfaceHandle(0);
+ s.clearUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE );
+ }
+ }
+}
diff --git a/src/nativewindow/native/macosx/OSXmisc.m b/src/nativewindow/native/macosx/OSXmisc.m
index 2c853a43d..d6ae7ed31 100644
--- a/src/nativewindow/native/macosx/OSXmisc.m
+++ b/src/nativewindow/native/macosx/OSXmisc.m
@@ -119,6 +119,12 @@ Java_jogamp_nativewindow_macosx_OSXUtil_isNSView0(JNIEnv *env, jclass _unused, j
return [nsObj isMemberOfClass:[NSView class]];
}
+JNIEXPORT jboolean JNICALL
+Java_jogamp_nativewindow_macosx_OSXUtil_isNSWindow0(JNIEnv *env, jclass _unused, jlong object) {
+ NSObject *nsObj = (NSObject*) (intptr_t) object;
+ return [nsObj isMemberOfClass:[NSWindow class]];
+}
+
/*
* Class: Java_jogamp_nativewindow_macosx_OSXUtil
* Method: getLocationOnScreen0
@@ -238,8 +244,10 @@ JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_CreateNSWindow0
[myWindow setPreservesContentDuringLiveResize: YES];
// Remove animations
NS_DURING
+ if ( [myWindow respondsToSelector:@selector(setAnimationBehavior:)] ) {
// Available >= 10.7 - Removes default animations
[myWindow setAnimationBehavior: NSWindowAnimationBehaviorNone];
+ }
NS_HANDLER
NS_ENDHANDLER
@@ -278,11 +286,28 @@ JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_GetNSView0
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);
+ DBG_PRINT( "GetNSView(window: %p): %p\n", win, (void*) (intptr_t) res);
+
+ [pool release];
+ return res;
+}
+
+/*
+ * Class: Java_jogamp_nativewindow_macosx_OSXUtil
+ * Method: GetNSWindow0
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_GetNSWindow0
+ (JNIEnv *env, jclass unused, jlong view)
+{
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ NSView* v = (NSView*) ((intptr_t) view);
+
+ jlong res = (jlong) ((intptr_t) [v window]);
+
+ DBG_PRINT( "GetNSWindow(view: %p): %p\n", v, (void*) (intptr_t) res);
[pool release];
return res;
@@ -314,6 +339,8 @@ JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_CreateCALayer0
// no animations for add/remove/swap sublayers etc
// doesn't work: [layer removeAnimationForKey: kCAOnOrderIn, kCAOnOrderOut, kCATransition]
[layer removeAllAnimations];
+ [layer setAutoresizingMask: (kCALayerWidthSizable|kCALayerHeightSizable)];
+ [layer setNeedsDisplayOnBoundsChange: YES];
DBG_PRINT("CALayer::CreateCALayer.1: %p %lf/%lf %lfx%lf\n", layer, lRect.origin.x, lRect.origin.y, lRect.size.width, lRect.size.height);
DBG_PRINT("CALayer::CreateCALayer.X: %p (refcnt %d)\n", layer, (int)[layer retainCount]);
@@ -357,7 +384,11 @@ JNIEXPORT void JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_AddCASublayer0
// no animations for add/remove/swap sublayers etc
// doesn't work: [layer removeAnimationForKey: kCAOnOrderIn, kCAOnOrderOut, kCATransition]
[rootLayer removeAllAnimations];
+ [rootLayer setAutoresizingMask: (kCALayerWidthSizable|kCALayerHeightSizable)];
+ [rootLayer setNeedsDisplayOnBoundsChange: YES];
[subLayer removeAllAnimations];
+ [subLayer setAutoresizingMask: (kCALayerWidthSizable|kCALayerHeightSizable)];
+ [subLayer setNeedsDisplayOnBoundsChange: YES];
}];
DBG_PRINT("CALayer::AddCASublayer0.X: %p . %p (refcnt %d)\n", rootLayer, subLayer, (int)[subLayer retainCount]);
JNF_COCOA_EXIT(env);
@@ -404,6 +435,63 @@ JNIEXPORT void JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_DestroyCALayer0
JNF_COCOA_EXIT(env);
}
+/*
+ * Class: Java_jogamp_nativewindow_jawt_macosx_MacOSXJAWTWindow
+ * Method: SetJAWTRootSurfaceLayer0
+ * Signature: (JJ)Z
+ */
+JNIEXPORT jboolean JNICALL Java_jogamp_nativewindow_jawt_macosx_MacOSXJAWTWindow_SetJAWTRootSurfaceLayer0
+ (JNIEnv *env, jclass unused, jobject jawtDrawingSurfaceInfoBuffer, jlong caLayer)
+{
+ JNF_COCOA_ENTER(env);
+ JAWT_DrawingSurfaceInfo* dsi = (JAWT_DrawingSurfaceInfo*) (*env)->GetDirectBufferAddress(env, jawtDrawingSurfaceInfoBuffer);
+ if (NULL == dsi) {
+ NativewindowCommon_throwNewRuntimeException(env, "Argument \"jawtDrawingSurfaceInfoBuffer\" was not a direct buffer");
+ return JNI_FALSE;
+ }
+ CALayer* layer = (CALayer*) (intptr_t) caLayer;
+ [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
+ id + * The created {@link GLOffscreenAutoDrawable.FBO} is being used to run the {@link GLEventListener}. + *
+ *+ * Extensive FBO reconfiguration (size and sample buffer count) and validation are performed. + *
+ */ +public class TestFBOAutoDrawableFactoryNEWT extends UITestCase { + + static final int widthStep = 800/4; + static final int heightStep = 600/4; + volatile int szStep = 2; + + interface MyGLEventListener extends GLEventListener { + void setMakeSnapshot(); + } + + @Test + public void testGL2ES2_Demo1_SingleBuffer_Normal() throws InterruptedException { + final GLProfile glp = GLProfile.getGL2ES2(); + final GLCapabilities caps = new GLCapabilities(glp); + caps.setDoubleBuffered(false); + testGLFBODrawableImpl(caps, new GearsES2(0)); + } + + @Test + public void testGL2ES2_Demo1_DoubleBuffer_Normal() throws InterruptedException { + final GLProfile glp = GLProfile.getGL2ES2(); + final GLCapabilities caps = new GLCapabilities(glp); + caps.setDoubleBuffered(true); // default + testGLFBODrawableImpl(caps, new GearsES2(0)); + } + + @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_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"); + } + } + + void testGLFBODrawableImpl(GLCapabilities caps, GLEventListener demo) throws InterruptedException { + caps.setFBO(true); + final GLDrawableFactory factory = GLDrawableFactory.getFactory(caps.getGLProfile()); + final GLOffscreenAutoDrawable.FBO glad = (GLOffscreenAutoDrawable.FBO) + factory.createOffscreenAutoDrawable(null, caps, null, widthStep*szStep, heightStep*szStep, null); + Assert.assertNotNull(glad); + + System.out.println("Realized GLAD: "+glad); + System.out.println("Realized GLAD: "+glad.getChosenGLCapabilities()); + Assert.assertTrue("FBO drawable is initialized before ctx creation", !glad.isInitialized()); + + glad.display(); // initial display incl. init! + { + final GLContext context = glad.getContext(); + Assert.assertNotNull(context); + Assert.assertTrue(context.isCreated()); + } + Assert.assertTrue("FBO drawable is not initialized after ctx creation", glad.isInitialized()); + + // + // FBO incl. MSAA is fully initialized now + // + + final GLCapabilitiesImmutable chosenCaps = glad.getChosenGLCapabilities(); + System.out.println("Init GLAD: "+glad); + System.out.println("Init GLAD: "+chosenCaps); + + final FBObject fboFront = glad.getFBObject(GL.GL_FRONT); + final FBObject fboBack = glad.getFBObject(GL.GL_BACK); + + System.out.println("Init front FBO: "+fboFront); + System.out.println("Init back FBO: "+fboBack); + + Assert.assertTrue("FBO drawable is not initialized before ctx creation", glad.isInitialized()); + Assert.assertTrue("FBO Front is not initialized before ctx creation", fboFront.isInitialized()); + Assert.assertTrue("FBO Back is not initialized before ctx creation", fboBack.isInitialized()); + + if( chosenCaps.getDoubleBuffered() ) { + Assert.assertTrue("FBO are equal: "+fboFront+" == "+fboBack, !fboFront.equals(fboBack)); + Assert.assertNotSame(fboFront, fboBack); + } else { + Assert.assertTrue("FBO are not equal: "+fboFront+" != "+fboBack, fboFront.equals(fboBack)); + Assert.assertSame(fboFront, fboBack); + } + + final FBObject.TextureAttachment texAttachA, texAttachB; + + texAttachA = glad.getTextureBuffer(GL.GL_FRONT); + if(0==glad.getNumSamples()) { + texAttachB = glad.getTextureBuffer(GL.GL_BACK); + } else { + texAttachB = null; + } + + final FBObject.Colorbuffer colorA, colorB; + final FBObject.RenderAttachment depthA, depthB; + + colorA = fboFront.getColorbuffer(0); + Assert.assertNotNull(colorA); + colorB = fboBack.getColorbuffer(0); + Assert.assertNotNull(colorB); + + depthA = fboFront.getDepthAttachment(); + Assert.assertNotNull(depthA); + depthB = fboBack.getDepthAttachment(); + Assert.assertNotNull(depthB); + + glad.display(); // SWAP_ODD + + if( chosenCaps.getDoubleBuffered() ) { + // double buffer or MSAA + Assert.assertTrue("Color attachments are equal: "+colorB+" == "+colorA, !colorB.equals(colorA)); + Assert.assertNotSame(colorB, colorA); + Assert.assertTrue("Depth attachments are equal: "+depthB+" == "+depthA, !depthB.equals(depthA)); + Assert.assertNotSame(depthB, depthA); + } else { + // single buffer + Assert.assertEquals(colorA, colorB); + Assert.assertSame(colorA, colorB); + Assert.assertEquals(depthA, depthB); + Assert.assertSame(depthA, depthB); + } + + Assert.assertEquals(texAttachA, colorA); + Assert.assertSame(texAttachA, colorA); + if(0==glad.getNumSamples()) { + Assert.assertEquals(texAttachB, colorB); + Assert.assertSame(texAttachB, colorB); + } + + if( chosenCaps.getNumSamples() > 0 ) { + // MSAA + FBObject _fboFront = glad.getFBObject(GL.GL_FRONT); + FBObject _fboBack = glad.getFBObject(GL.GL_BACK); + Assert.assertTrue("FBO are not equal: "+fboFront+" != "+_fboFront, fboFront.equals(_fboFront)); + Assert.assertSame(fboFront, _fboFront); + Assert.assertTrue("FBO are not equal: "+fboBack+" != "+_fboBack, fboBack.equals(_fboBack)); + Assert.assertSame(fboBack, _fboBack); + } else if( chosenCaps.getDoubleBuffered() ) { + // real double buffer + FBObject _fboFront = glad.getFBObject(GL.GL_FRONT); + FBObject _fboBack = glad.getFBObject(GL.GL_BACK); + Assert.assertTrue("FBO are not equal: "+fboBack+" != "+_fboFront, fboBack.equals(_fboFront)); + Assert.assertSame(fboBack, _fboFront); + Assert.assertTrue("FBO are not equal: "+fboFront+" != "+_fboBack, fboFront.equals(_fboBack)); + Assert.assertSame(fboFront, _fboBack); + } else { + // single buffer + FBObject _fboFront = glad.getFBObject(GL.GL_FRONT); + FBObject _fboBack = glad.getFBObject(GL.GL_BACK); + Assert.assertTrue("FBO are not equal: "+fboFront+" != "+_fboFront, fboFront.equals(_fboFront)); + Assert.assertSame(fboFront, _fboFront); + Assert.assertTrue("FBO are not equal: "+fboBack+" != "+_fboFront, fboBack.equals(_fboFront)); + Assert.assertSame(fboBack, _fboFront); + Assert.assertTrue("FBO are not equal: "+fboBack+" != "+_fboBack, fboBack.equals(_fboBack)); + Assert.assertSame(fboBack, _fboBack); + Assert.assertTrue("FBO are not equal: "+fboFront+" != "+_fboBack, fboFront.equals(_fboBack)); + Assert.assertSame(fboFront, _fboBack); + } + + glad.addGLEventListener(demo); + + final SnapshotGLEventListener snapshotGLEventListener = new SnapshotGLEventListener(); + glad.addGLEventListener(snapshotGLEventListener); + + glad.display(); // - SWAP_EVEN + + // 1 - szStep = 2 + snapshotGLEventListener.setMakeSnapshot(); + glad.display(); // - SWAP_ODD + + // 2, 3 (resize + display) + szStep = 1; + glad.setSize(widthStep*szStep, heightStep*szStep); // SWAP_EVEN + Assert.assertTrue("Size not reached: Expected "+(widthStep*szStep)+"x"+(heightStep*szStep)+", Is "+glad.getWidth()+"x"+glad.getHeight(), + AWTRobotUtil.waitForSize(glad, widthStep*szStep, heightStep*szStep)); + snapshotGLEventListener.setMakeSnapshot(); + glad.display(); // - SWAP_ODD + glad.display(); // - SWAP_EVEN + { + // Check whether the attachment reference are still valid! + final FBObject _fboFront = glad.getFBObject(GL.GL_FRONT); + final FBObject _fboBack = glad.getFBObject(GL.GL_BACK); + System.out.println("Resize1.oldFront: "+fboFront); + System.out.println("Resize1.nowFront: "+_fboFront); + System.out.println("Resize1.oldBack : "+fboBack); + System.out.println("Resize1.nowBack : "+_fboBack); + Assert.assertEquals(fboFront, _fboFront); + Assert.assertSame(fboFront, _fboFront); + Assert.assertEquals(fboBack, _fboBack); + Assert.assertSame(fboBack, _fboBack); + + FBObject.Colorbuffer _color = _fboFront.getColorbuffer(0); + Assert.assertNotNull(_color); + Assert.assertEquals(colorA, _color); + Assert.assertSame(colorA, _color); + + FBObject.RenderAttachment _depth = _fboFront.getDepthAttachment(); + System.err.println("Resize1.oldDepth "+depthA); + System.err.println("Resize1.newDepth "+_depth); + Assert.assertNotNull(_depth); + + Assert.assertEquals(depthA, _depth); + Assert.assertSame(depthA, _depth); + _depth = _fboBack.getDepthAttachment(); + Assert.assertNotNull(_depth); + Assert.assertEquals(depthB, _depth); + Assert.assertSame(depthB, _depth); + + _color = _fboFront.getColorbuffer(colorA); + Assert.assertNotNull(_color); + Assert.assertEquals(colorA, _color); + Assert.assertSame(colorA, _color); + } + + // 4, 5 (resize + display) + szStep = 4; + glad.setSize(widthStep*szStep, heightStep*szStep); // SWAP_ODD + Assert.assertTrue("Size not reached: Expected "+(widthStep*szStep)+"x"+(heightStep*szStep)+", Is "+glad.getWidth()+"x"+glad.getHeight(), + AWTRobotUtil.waitForSize(glad, widthStep*szStep, heightStep*szStep)); + snapshotGLEventListener.setMakeSnapshot(); + glad.display(); // - SWAP_EVEN + glad.display(); // - SWAP_ODD + { + // Check whether the attachment reference are still valid! + final FBObject _fboFront = glad.getFBObject(GL.GL_FRONT); + final FBObject _fboBack = glad.getFBObject(GL.GL_BACK); + System.out.println("Resize2.oldFront: "+fboFront); + System.out.println("Resize2.nowFront: "+_fboFront); + System.out.println("Resize2.oldBack : "+fboBack); + System.out.println("Resize2.nowBack : "+_fboBack); + if(chosenCaps.getDoubleBuffered() && 0==chosenCaps.getNumSamples()) { + // real double buffer + Assert.assertEquals(fboBack, _fboFront); + Assert.assertEquals(fboFront, _fboBack); + } else { + // single or MSAA + Assert.assertEquals(fboFront, _fboFront); + Assert.assertEquals(fboBack, _fboBack); + } + + FBObject.Colorbuffer _color = fboBack.getColorbuffer(0); + Assert.assertNotNull(_color); + Assert.assertEquals(colorB, _color); + Assert.assertSame(colorB, _color); + + FBObject.RenderAttachment _depth = fboBack.getDepthAttachment(); + Assert.assertNotNull(_depth); // MSAA back w/ depth + Assert.assertEquals(depthB, _depth); + Assert.assertSame(depthB, _depth); + + _depth = fboFront.getDepthAttachment(); + Assert.assertNotNull(_depth); + Assert.assertEquals(depthA, _depth); + Assert.assertSame(depthA, _depth); + + _color = fboBack.getColorbuffer(colorB); + Assert.assertNotNull(_color); + Assert.assertEquals(colorB, _color); + Assert.assertSame(colorB, _color); + } + + // 6 + 7 (samples + display) + glad.setNumSamples(glad.getGL(), chosenCaps.getNumSamples() > 0 ? 0 : 4); // triggers repaint + snapshotGLEventListener.setMakeSnapshot(); + glad.display(); // actual screenshot + + // 8, 9 (resize + samples + display) + szStep = 3; + glad.setSize(widthStep*szStep, heightStep*szStep); + Assert.assertTrue("Size not reached: Expected "+(widthStep*szStep)+"x"+(heightStep*szStep)+", Is "+glad.getWidth()+"x"+glad.getHeight(), + AWTRobotUtil.waitForSize(glad, widthStep*szStep, heightStep*szStep)); + snapshotGLEventListener.setMakeSnapshot(); + glad.display(); + + glad.destroy(); + System.out.println("Fin: "+glad); + } + + public static void main(String args[]) throws IOException { + org.junit.runner.JUnitCore.main(TestFBOAutoDrawableFactoryNEWT.class.getName()); + } + +} 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 deleted file mode 100644 index 7977347a7..000000000 --- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBODrawableNEWT.java +++ /dev/null @@ -1,272 +0,0 @@ -/** - * 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, true); - - 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 index f7c83a03b..077baad43 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOMRTNEWT01.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOMRTNEWT01.java @@ -229,7 +229,7 @@ public class TestFBOMRTNEWT01 extends UITestCase { final NativeSurface ns = gl.getContext().getGLReadDrawable().getNativeSurface(); if(last_snap_size[0] != ns.getWidth() && last_snap_size[1] != ns.getHeight()) { gl.glFinish(); // sync .. no swap buffers yet! - snapshot(getSimpleTestName("."), step_i, null, gl, screenshot, TextureIO.PNG, null); // overwrite ok + snapshot(step_i, null, gl, screenshot, TextureIO.PNG, null); // overwrite ok last_snap_size[0] = ns.getWidth(); last_snap_size[1] = ns.getHeight(); } diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOMix2DemosES2NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOMix2DemosES2NEWT.java index b384c9327..b3c542c63 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOMix2DemosES2NEWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOMix2DemosES2NEWT.java @@ -106,7 +106,7 @@ public class TestFBOMix2DemosES2NEWT extends UITestCase { if(dw<800) { System.err.println("XXX: "+dw+"x"+dh+", c "+c); if(0 == c%3) { - snapshot(getSimpleTestName("."), i++, "msaa"+demo.getMSAA(), drawable.getGL(), screenshot, TextureIO.PNG, null); + snapshot(i++, "msaa"+demo.getMSAA(), drawable.getGL(), screenshot, TextureIO.PNG, null); } if( 3 == c ) { new Thread() { diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOOffThreadSharedContextMix2DemosES2NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOOffThreadSharedContextMix2DemosES2NEWT.java new file mode 100644 index 000000000..3ecf89bfc --- /dev/null +++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOOffThreadSharedContextMix2DemosES2NEWT.java @@ -0,0 +1,298 @@ +/** + * 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.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; + +import com.jogamp.newt.event.WindowEvent; +import com.jogamp.newt.event.WindowAdapter; +import com.jogamp.newt.opengl.GLWindow; +import com.jogamp.opengl.test.junit.util.AWTRobotUtil; +import com.jogamp.opengl.test.junit.util.MiscUtils; +import com.jogamp.opengl.test.junit.util.UITestCase; +import com.jogamp.opengl.test.junit.util.QuitAdapter; + +import com.jogamp.opengl.util.Animator; +import com.jogamp.opengl.util.FPSAnimator; +import com.jogamp.opengl.util.GLReadBufferUtil; +import com.jogamp.opengl.util.texture.TextureIO; +import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2; +import com.jogamp.opengl.test.junit.jogl.demos.es2.Mix2TexturesES2; +import com.jogamp.opengl.test.junit.jogl.demos.es2.RedSquareES2; + +import javax.media.nativewindow.NativeSurface; +import javax.media.nativewindow.SurfaceUpdatedListener; +import javax.media.opengl.GL; +import javax.media.opengl.GLAutoDrawable; +import javax.media.opengl.GLCapabilities; +import javax.media.opengl.GLCapabilitiesImmutable; +import javax.media.opengl.GLContext; +import javax.media.opengl.GLDrawableFactory; +import javax.media.opengl.GLEventListener; +import javax.media.opengl.GLOffscreenAutoDrawable; +import javax.media.opengl.GLProfile; + +import org.junit.Assert; +import org.junit.AfterClass; +import org.junit.Test; + +/** + * Toolkit agnostic {@link GLOffscreenAutoDrawable.FBO} tests using the + * {@link GLDrawableFactory#createOffscreenAutoDrawable(javax.media.nativewindow.AbstractGraphicsDevice, GLCapabilitiesImmutable, javax.media.opengl.GLCapabilitiesChooser, int, int, GLContext) factory model}. + *+ * The created {@link GLOffscreenAutoDrawable.FBO} is being used to run the {@link GLEventListener}. + *
+ *+ * This test simulates shared off-thread GL context / texture usage, + * where the producer use FBOs and delivers shared textures. + * The receiver blends the shared textures onscreen. + * In detail the test consist of: + *
+ * This test simulates shared on-thread GL context / texture usage, + * where the producer uses an FBO and delivers a shared texture. + * The receiver draws the shared texture onscreen. + * In detail the test consist of: + *
+ * Finally a {@link GLAutoDrawableDelegate} is created with the just created {@link GLDrawable} and {@link GLContext}. + * It is being used to run the {@link GLEventListener}. + *
+ */ +public class TestGLAutoDrawableDelegateOnOffscrnCapsNEWT extends UITestCase { + static final int widthStep = 800/4; + static final int heightStep = 600/4; + volatile int szStep = 2; + + static GLCapabilities getCaps(String profile) { + if( !GLProfile.isAvailable(profile) ) { + System.err.println("Profile "+profile+" n/a"); + return null; + } + return new GLCapabilities(GLProfile.get(profile)); + } + + void doTest(GLCapabilitiesImmutable reqGLCaps, GLEventListener demo) throws InterruptedException { + System.out.println("Requested GL Caps: "+reqGLCaps); + final GLDrawableFactory factory = GLDrawableFactory.getFactory(reqGLCaps.getGLProfile()); + + final boolean fboAvailable = factory.canCreateFBO(null, reqGLCaps.getGLProfile()); + final boolean pbufferAvailable = factory.canCreateGLPbuffer(null); + final GLCapabilitiesImmutable expGLCaps = GLGraphicsConfigurationUtil.fixGLCapabilities(reqGLCaps, fboAvailable, pbufferAvailable); + System.out.println("Expected GL Caps: "+expGLCaps); + // + // Create native windowing resources .. X11/Win/OSX + // + final Window window = NewtFactory.createWindow(reqGLCaps); + Assert.assertNotNull(window); + window.setSize(widthStep*szStep, heightStep*szStep); + window.setVisible(true); + Assert.assertTrue(AWTRobotUtil.waitForVisible(window, true)); + Assert.assertTrue(AWTRobotUtil.waitForRealized(window, true)); + System.out.println("Window: "+window.getClass().getName()); + + // Check caps of NativeWindow config w/o GL + final CapabilitiesImmutable chosenCaps = window.getGraphicsConfiguration().getChosenCapabilities(); + System.out.println("Window Caps Pre_GL: "+chosenCaps); + Assert.assertNotNull(chosenCaps); + Assert.assertTrue(chosenCaps.getGreenBits()>5); + Assert.assertTrue(chosenCaps.getBlueBits()>5); + Assert.assertTrue(chosenCaps.getRedBits()>5); + + // + // Create native OpenGL resources .. XGL/WGL/CGL .. + // equivalent to GLAutoDrawable methods: setVisible(true) + // + final GLDrawable drawable = factory.createGLDrawable(window); + Assert.assertNotNull(drawable); + System.out.println("Drawable Pre-GL(0): "+drawable.getClass().getName()+", "+drawable.getNativeSurface().getClass().getName()); + + // + drawable.setRealized(true); + Assert.assertTrue(drawable.isRealized()); + + System.out.println("Window Caps PostGL : "+window.getGraphicsConfiguration().getChosenCapabilities()); + System.out.println("Drawable Post-GL(1): "+drawable.getClass().getName()+", "+drawable.getNativeSurface().getClass().getName()); + + // Check caps of GLDrawable after realization + final GLCapabilitiesImmutable chosenGLCaps = drawable.getChosenGLCapabilities(); + System.out.println("Chosen GL Caps(1): "+chosenGLCaps); + Assert.assertNotNull(chosenGLCaps); + Assert.assertTrue(chosenGLCaps.getGreenBits()>5); + Assert.assertTrue(chosenGLCaps.getBlueBits()>5); + Assert.assertTrue(chosenGLCaps.getRedBits()>5); + Assert.assertTrue(chosenGLCaps.getDepthBits()>4); + Assert.assertEquals(expGLCaps.isOnscreen(), chosenGLCaps.isOnscreen()); + Assert.assertEquals(expGLCaps.isFBO(), chosenGLCaps.isFBO()); + Assert.assertEquals(expGLCaps.isPBuffer(), chosenGLCaps.isPBuffer()); + Assert.assertEquals(expGLCaps.isBitmap(), chosenGLCaps.isBitmap()); + /** Single/Double buffer cannot be checked since result may vary .. + if(chosenGLCaps.isOnscreen() || chosenGLCaps.isFBO()) { + // dbl buffer may be disabled w/ offscreen pbuffer and bitmap + Assert.assertEquals(expGLCaps.getDoubleBuffered(), chosenGLCaps.getDoubleBuffered()); + } */ + + GLContext context = drawable.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("Chosen GL Caps(2): "+drawable.getChosenGLCapabilities()); + System.out.println("Chosen GL CTX (2): "+context.getGLVersion()); + System.out.println("Drawable Post-GL(2): "+drawable.getClass().getName()+", "+drawable.getNativeSurface().getClass().getName()); + + final GLAutoDrawableDelegate glad = new GLAutoDrawableDelegate(drawable, context, window, false, null) { + @Override + protected void destroyImplInLock() { + super.destroyImplInLock(); // destroys drawable/context + window.destroy(); // destroys the actual window, incl. the device + } + }; + + window.addWindowListener(new WindowAdapter() { + @Override + public void windowRepaint(WindowUpdateEvent e) { + glad.windowRepaintOp(); + } + + @Override + public void windowResized(WindowEvent e) { + glad.windowResizedOp(window.getWidth(), window.getHeight()); + } + + @Override + public void windowDestroyNotify(WindowEvent e) { + glad.windowDestroyNotifyOp(); + } + }); + + glad.addGLEventListener(demo); + + final SnapshotGLEventListener snapshotGLEventListener = new SnapshotGLEventListener(); + glad.addGLEventListener(snapshotGLEventListener); + + glad.display(); // initial resize/display + + // 1 - szStep = 2 + Assert.assertTrue("Size not reached: Expected "+(widthStep*szStep)+"x"+(heightStep*szStep)+", Is "+glad.getWidth()+"x"+glad.getHeight(), + AWTRobotUtil.waitForSize(glad, widthStep*szStep, heightStep*szStep)); + snapshotGLEventListener.setMakeSnapshot(); + glad.display(); + + // 2, 3 (resize + display) + szStep = 1; + window.setSize(widthStep*szStep, heightStep*szStep); + Assert.assertTrue("Size not reached: Expected "+(widthStep*szStep)+"x"+(heightStep*szStep)+", Is "+glad.getWidth()+"x"+glad.getHeight(), + AWTRobotUtil.waitForSize(glad, widthStep*szStep, heightStep*szStep)); + snapshotGLEventListener.setMakeSnapshot(); + glad.display(); + + // 4, 5 (resize + display) + szStep = 4; + window.setSize(widthStep*szStep, heightStep*szStep); + Assert.assertTrue("Size not reached: Expected "+(widthStep*szStep)+"x"+(heightStep*szStep)+", Is "+glad.getWidth()+"x"+glad.getHeight(), + AWTRobotUtil.waitForSize(glad, widthStep*szStep, heightStep*szStep)); + snapshotGLEventListener.setMakeSnapshot(); + glad.display(); + + Thread.sleep(50); + + glad.destroy(); + System.out.println("Fin Drawable: "+drawable); + System.out.println("Fin Window: "+window); + } + + @Test + public void testAvailableInfo() { + GLDrawableFactory f = GLDrawableFactory.getDesktopFactory(); + if(null != f) { + System.err.println(JoglVersion.getDefaultOpenGLInfo(f.getDefaultDevice(), null, true).toString()); + } + f = GLDrawableFactory.getEGLFactory(); + if(null != f) { + System.err.println(JoglVersion.getDefaultOpenGLInfo(f.getDefaultDevice(), null, true).toString()); + } + } + + @Test + public void testGL2OnScreenDblBuf() throws InterruptedException { + final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2); + if(null == reqGLCaps) return; + doTest(reqGLCaps, new GearsES2(1)); + } + + @Test + public void testGL2OnScreenSglBuf() throws InterruptedException { + final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2); + if(null == reqGLCaps) return; + reqGLCaps.setDoubleBuffered(false); + doTest(reqGLCaps, new GearsES2(1)); + } + + @Test + public void testGL2OffScreenAutoDblBuf() throws InterruptedException { + final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2); + if(null == reqGLCaps) return; + reqGLCaps.setOnscreen(false); + doTest(reqGLCaps, new GearsES2(1)); + } + + @Test + public void testGL2OffScreenFBODblBuf() throws InterruptedException { + final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2); + if(null == reqGLCaps) return; + reqGLCaps.setOnscreen(false); + reqGLCaps.setFBO(true); + doTest(reqGLCaps, new GearsES2(1)); + } + + @Test + public void testGL2OffScreenFBOSglBuf() throws InterruptedException { + final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2); + if(null == reqGLCaps) return; + reqGLCaps.setOnscreen(false); + reqGLCaps.setFBO(true); + reqGLCaps.setDoubleBuffered(false); + doTest(reqGLCaps, new GearsES2(1)); + } + + @Test + public void testGL2OffScreenPbufferDblBuf() throws InterruptedException { + final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2); + if(null == reqGLCaps) return; + reqGLCaps.setOnscreen(false); + reqGLCaps.setPBuffer(true); + doTest(reqGLCaps, new GearsES2(1)); + } + + @Test + public void testGL2OffScreenPbufferSglBuf() throws InterruptedException { + final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2); + if(null == reqGLCaps) return; + reqGLCaps.setOnscreen(false); + reqGLCaps.setPBuffer(true); + reqGLCaps.setDoubleBuffered(false); + doTest(reqGLCaps, new GearsES2(1)); + } + + @Test + public void testGL2OffScreenBitmapDblBuf() throws InterruptedException { + final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2); + if(null == reqGLCaps) return; + reqGLCaps.setOnscreen(false); + reqGLCaps.setBitmap(true); + doTest(reqGLCaps, new Gears(1)); + } + + @Test + public void testGL2OffScreenBitmapSglBuf() throws InterruptedException { + final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2); + if(null == reqGLCaps) return; + reqGLCaps.setOnscreen(false); + reqGLCaps.setBitmap(true); + reqGLCaps.setDoubleBuffered(false); + doTest(reqGLCaps, new Gears(1)); + } + + @Test + public void testES2OnScreenDblBuf() throws InterruptedException { + final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2); + if(null == reqGLCaps) return; + doTest(reqGLCaps, new GearsES2(1)); + } + + @Test + public void testES2OnScreenSglBuf() throws InterruptedException { + final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2); + if(null == reqGLCaps) return; + reqGLCaps.setDoubleBuffered(false); + doTest(reqGLCaps, new GearsES2(1)); + } + + @Test + public void testES2OffScreenAutoDblBuf() throws InterruptedException { + final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2); + if(null == reqGLCaps) return; + reqGLCaps.setOnscreen(false); + doTest(reqGLCaps, new GearsES2(1)); + } + + @Test + public void testES2OffScreenFBODblBuf() throws InterruptedException { + final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2); + if(null == reqGLCaps) return; + reqGLCaps.setOnscreen(false); + reqGLCaps.setFBO(true); + doTest(reqGLCaps, new GearsES2(1)); + } + + @Test + public void testES2OffScreenFBOSglBuf() throws InterruptedException { + final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2); + if(null == reqGLCaps) return; + reqGLCaps.setOnscreen(false); + reqGLCaps.setFBO(true); + reqGLCaps.setDoubleBuffered(false); + doTest(reqGLCaps, new GearsES2(1)); + } + + @Test + public void testES2OffScreenPbufferDblBuf() throws InterruptedException { + final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2); + if(null == reqGLCaps) return; + reqGLCaps.setOnscreen(false); + reqGLCaps.setPBuffer(true); + doTest(reqGLCaps, new GearsES2(1)); + } + + @Test + public void testES2OffScreenPbufferSglBuf() throws InterruptedException { + final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2); + if(null == reqGLCaps) return; + reqGLCaps.setOnscreen(false); + reqGLCaps.setPBuffer(true); + reqGLCaps.setDoubleBuffered(false); + doTest(reqGLCaps, new GearsES2(1)); + } + + /** Not implemented ! + @Test + public void testES2OffScreenBitmapDblBuf() throws InterruptedException { + if(!checkProfile(GLProfile.GLES2)) { + return; + } + final GLCapabilities reqGLCaps = new GLCapabilities(GLProfile.get(GLProfile.GLES2)); + reqGLCaps.setOnscreen(false); + reqGLCaps.setBitmap(true); + doTest(reqGLCaps, new GearsES2(1)); + } */ + + public static void main(String args[]) throws IOException { + org.junit.runner.JUnitCore.main(TestGLAutoDrawableDelegateOnOffscrnCapsNEWT.class.getName()); + } + +} diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableFactoryOffscrnCapsNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableFactoryOffscrnCapsNEWT.java new file mode 100644 index 000000000..544d74aa5 --- /dev/null +++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableFactoryOffscrnCapsNEWT.java @@ -0,0 +1,317 @@ +/** + * 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 java.io.IOException; + +import javax.media.nativewindow.CapabilitiesImmutable; +import javax.media.opengl.GLCapabilities; +import javax.media.opengl.GLCapabilitiesImmutable; +import javax.media.opengl.GLContext; +import javax.media.opengl.GLDrawableFactory; +import javax.media.opengl.GLEventListener; +import javax.media.opengl.GLOffscreenAutoDrawable; +import javax.media.opengl.GLProfile; + +import jogamp.opengl.GLGraphicsConfigurationUtil; + +import org.junit.Assert; +import org.junit.Test; + +import com.jogamp.opengl.JoglVersion; +import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2; +import com.jogamp.opengl.test.junit.jogl.demos.gl2.Gears; +import com.jogamp.opengl.test.junit.util.AWTRobotUtil; +import com.jogamp.opengl.test.junit.util.UITestCase; + +/** + * Toolkit agnostic {@link GLOffscreenAutoDrawable} tests using the + * {@link GLDrawableFactory#createOffscreenAutoDrawable(javax.media.nativewindow.AbstractGraphicsDevice, GLCapabilitiesImmutable, javax.media.opengl.GLCapabilitiesChooser, int, int, GLContext) factory model}. + *+ * The created {@link GLOffscreenAutoDrawable} is being used to run the {@link GLEventListener}. + *
+ */ +public class TestGLAutoDrawableFactoryOffscrnCapsNEWT extends UITestCase { + static final int widthStep = 800/4; + static final int heightStep = 600/4; + volatile int szStep = 2; + + static GLCapabilities getCaps(String profile) { + if( !GLProfile.isAvailable(profile) ) { + System.err.println("Profile "+profile+" n/a"); + return null; + } + return new GLCapabilities(GLProfile.get(profile)); + } + + void doTest(GLCapabilitiesImmutable reqGLCaps, GLEventListener demo) throws InterruptedException { + System.out.println("Requested GL Caps: "+reqGLCaps); + final GLDrawableFactory factory = GLDrawableFactory.getFactory(reqGLCaps.getGLProfile()); + + final boolean fboAvailable = factory.canCreateFBO(null, reqGLCaps.getGLProfile()); + final boolean pbufferAvailable = factory.canCreateGLPbuffer(null); + final GLCapabilitiesImmutable expGLCaps = GLGraphicsConfigurationUtil.fixGLCapabilities(reqGLCaps, fboAvailable, pbufferAvailable); + System.out.println("Expected GL Caps: "+expGLCaps); + + // + // Create native OpenGL resources .. XGL/WGL/CGL .. + // equivalent to GLAutoDrawable methods: setVisible(true) + // + final GLOffscreenAutoDrawable glad = factory.createOffscreenAutoDrawable(null, reqGLCaps, null, widthStep*szStep, heightStep*szStep, null); + + Assert.assertNotNull(glad); + System.out.println("Drawable Pre-GL(0): "+glad.getClass().getName()+", "+glad.getNativeSurface().getClass().getName()); + Assert.assertTrue(glad.isRealized()); + + // Check caps of NativeWindow config w/o GL + final CapabilitiesImmutable chosenCaps = glad.getChosenGLCapabilities(); + System.out.println("Drawable Caps Pre_GL : "+chosenCaps); + Assert.assertNotNull(chosenCaps); + Assert.assertTrue(chosenCaps.getGreenBits()>5); + Assert.assertTrue(chosenCaps.getBlueBits()>5); + Assert.assertTrue(chosenCaps.getRedBits()>5); + + glad.display(); // force native context creation + + // Check caps of GLDrawable after realization + final GLCapabilitiesImmutable chosenGLCaps = glad.getChosenGLCapabilities(); + System.out.println("Chosen GL Caps(1): "+chosenGLCaps); + System.out.println("Chosen GL CTX (1): "+glad.getContext().getGLVersion()); + + Assert.assertNotNull(chosenGLCaps); + Assert.assertTrue(chosenGLCaps.getGreenBits()>5); + Assert.assertTrue(chosenGLCaps.getBlueBits()>5); + Assert.assertTrue(chosenGLCaps.getRedBits()>5); + Assert.assertTrue(chosenGLCaps.getDepthBits()>4); + Assert.assertEquals(expGLCaps.isOnscreen(), chosenGLCaps.isOnscreen()); + Assert.assertEquals(expGLCaps.isFBO(), chosenGLCaps.isFBO()); + Assert.assertEquals(expGLCaps.isPBuffer(), chosenGLCaps.isPBuffer()); + Assert.assertEquals(expGLCaps.isBitmap(), chosenGLCaps.isBitmap()); + /** Single/Double buffer cannot be checked since result may vary .. + if(chosenGLCaps.isOnscreen() || chosenGLCaps.isFBO()) { + // dbl buffer may be disabled w/ offscreen pbuffer and bitmap + Assert.assertEquals(expGLCaps.getDoubleBuffered(), chosenGLCaps.getDoubleBuffered()); + } */ + + glad.addGLEventListener(demo); + + final SnapshotGLEventListener snapshotGLEventListener = new SnapshotGLEventListener(); + glad.addGLEventListener(snapshotGLEventListener); + + glad.display(); // initial resize/display + + // 1 - szStep = 2 + Assert.assertTrue("Size not reached: Expected "+(widthStep*szStep)+"x"+(heightStep*szStep)+", Is "+glad.getWidth()+"x"+glad.getHeight(), + AWTRobotUtil.waitForSize(glad, widthStep*szStep, heightStep*szStep)); + snapshotGLEventListener.setMakeSnapshot(); + glad.display(); + + // 2, 3 (resize + display) + szStep = 1; + glad.setSize(widthStep*szStep, heightStep*szStep); + Assert.assertTrue("Size not reached: Expected "+(widthStep*szStep)+"x"+(heightStep*szStep)+", Is "+glad.getWidth()+"x"+glad.getHeight(), + AWTRobotUtil.waitForSize(glad, widthStep*szStep, heightStep*szStep)); + snapshotGLEventListener.setMakeSnapshot(); + glad.display(); + + // 4, 5 (resize + display) + szStep = 4; + glad.setSize(widthStep*szStep, heightStep*szStep); + Assert.assertTrue("Size not reached: Expected "+(widthStep*szStep)+"x"+(heightStep*szStep)+", Is "+glad.getWidth()+"x"+glad.getHeight(), + AWTRobotUtil.waitForSize(glad, widthStep*szStep, heightStep*szStep)); + snapshotGLEventListener.setMakeSnapshot(); + glad.display(); + + Thread.sleep(50); + + glad.destroy(); + System.out.println("Fin Drawable: "+glad); + } + + @Test + public void testAvailableInfo() { + GLDrawableFactory f = GLDrawableFactory.getDesktopFactory(); + if(null != f) { + System.err.println(JoglVersion.getDefaultOpenGLInfo(f.getDefaultDevice(), null, true).toString()); + } + f = GLDrawableFactory.getEGLFactory(); + if(null != f) { + System.err.println(JoglVersion.getDefaultOpenGLInfo(f.getDefaultDevice(), null, true).toString()); + } + } + + @Test + public void testGL2OffScreenAutoDblBuf() throws InterruptedException { + final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2); + if(null == reqGLCaps) return; + reqGLCaps.setOnscreen(false); + doTest(reqGLCaps, new GearsES2(1)); + } + + @Test + public void testGL2OffScreenFBODblBuf() throws InterruptedException { + final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2); + if(null == reqGLCaps) return; + reqGLCaps.setOnscreen(false); + reqGLCaps.setFBO(true); + doTest(reqGLCaps, new GearsES2(1)); + } + + @Test + public void testGL2OffScreenFBOSglBuf() throws InterruptedException { + final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2); + if(null == reqGLCaps) return; + reqGLCaps.setOnscreen(false); + reqGLCaps.setFBO(true); + reqGLCaps.setDoubleBuffered(false); + doTest(reqGLCaps, new GearsES2(1)); + } + + @Test + public void testGL2OffScreenFBOStencil() throws InterruptedException { + final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2); + if(null == reqGLCaps) return; + reqGLCaps.setOnscreen(false); + reqGLCaps.setFBO(true); + reqGLCaps.setStencilBits(1); + doTest(reqGLCaps, new GearsES2(1)); + } + + @Test + public void testGL2OffScreenFBOStencilMSAA() throws InterruptedException { + final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2); + if(null == reqGLCaps) return; + reqGLCaps.setOnscreen(false); + reqGLCaps.setFBO(true); + reqGLCaps.setStencilBits(1); + reqGLCaps.setSampleBuffers(true); + doTest(reqGLCaps, new GearsES2(1)); + } + + @Test + public void testGL2OffScreenPbufferDblBuf() throws InterruptedException { + final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2); + if(null == reqGLCaps) return; + reqGLCaps.setOnscreen(false); + reqGLCaps.setPBuffer(true); + doTest(reqGLCaps, new GearsES2(1)); + } + + @Test + public void testGL2OffScreenPbufferSglBuf() throws InterruptedException { + final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2); + if(null == reqGLCaps) return; + reqGLCaps.setOnscreen(false); + reqGLCaps.setPBuffer(true); + reqGLCaps.setDoubleBuffered(false); + doTest(reqGLCaps, new GearsES2(1)); + } + + @Test + public void testGL2OffScreenBitmapDblBuf() throws InterruptedException { + final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2); + if(null == reqGLCaps) return; + reqGLCaps.setOnscreen(false); + reqGLCaps.setBitmap(true); + doTest(reqGLCaps, new Gears(1)); + } + + @Test + public void testGL2OffScreenBitmapSglBuf() throws InterruptedException { + final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2); + if(null == reqGLCaps) return; + reqGLCaps.setOnscreen(false); + reqGLCaps.setBitmap(true); + reqGLCaps.setDoubleBuffered(false); + doTest(reqGLCaps, new Gears(1)); + } + + @Test + public void testES2OffScreenAutoDblBuf() throws InterruptedException { + final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2); + if(null == reqGLCaps) return; + reqGLCaps.setOnscreen(false); + doTest(reqGLCaps, new GearsES2(1)); + } + + @Test + public void testES2OffScreenFBODblBuf() throws InterruptedException { + final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2); + if(null == reqGLCaps) return; + reqGLCaps.setOnscreen(false); + reqGLCaps.setFBO(true); + doTest(reqGLCaps, new GearsES2(1)); + } + + @Test + public void testES2OffScreenFBOSglBuf() throws InterruptedException { + final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2); + if(null == reqGLCaps) return; + reqGLCaps.setOnscreen(false); + reqGLCaps.setFBO(true); + reqGLCaps.setDoubleBuffered(false); + doTest(reqGLCaps, new GearsES2(1)); + } + + @Test + public void testES2OffScreenPbufferDblBuf() throws InterruptedException { + final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2); + if(null == reqGLCaps) return; + reqGLCaps.setOnscreen(false); + reqGLCaps.setPBuffer(true); + doTest(reqGLCaps, new GearsES2(1)); + } + + @Test + public void testES2OffScreenPbufferSglBuf() throws InterruptedException { + final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2); + if(null == reqGLCaps) return; + reqGLCaps.setOnscreen(false); + reqGLCaps.setPBuffer(true); + reqGLCaps.setDoubleBuffered(false); + doTest(reqGLCaps, new GearsES2(1)); + } + + /** Not implemented ! + @Test + public void testES2OffScreenBitmapDblBuf() throws InterruptedException { + if(!checkProfile(GLProfile.GLES2)) { + return; + } + final GLCapabilities reqGLCaps = new GLCapabilities(GLProfile.get(GLProfile.GLES2)); + reqGLCaps.setOnscreen(false); + reqGLCaps.setBitmap(true); + doTest(reqGLCaps, new GearsES2(1)); + } */ + + public static void main(String args[]) throws IOException { + org.junit.runner.JUnitCore.main(TestGLAutoDrawableFactoryOffscrnCapsNEWT.class.getName()); + } + +} diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableGLCanvasOnOffscrnCapsAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableGLCanvasOnOffscrnCapsAWT.java new file mode 100644 index 000000000..64a75716b --- /dev/null +++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableGLCanvasOnOffscrnCapsAWT.java @@ -0,0 +1,328 @@ +/** + * 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 java.awt.Dimension; +import java.awt.Frame; +import java.io.IOException; + +import javax.media.nativewindow.CapabilitiesImmutable; +import javax.media.opengl.GLAutoDrawable; +import javax.media.opengl.GLCapabilities; +import javax.media.opengl.GLCapabilitiesImmutable; +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 javax.media.opengl.awt.GLCanvas; + +import jogamp.nativewindow.jawt.JAWTUtil; +import jogamp.opengl.GLGraphicsConfigurationUtil; + +import org.junit.Assert; +import org.junit.Assume; +import org.junit.Test; + +import com.jogamp.newt.opengl.GLWindow; +import com.jogamp.opengl.JoglVersion; +import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2; +import com.jogamp.opengl.test.junit.util.AWTRobotUtil; +import com.jogamp.opengl.test.junit.util.UITestCase; + +/** + * Tests using a NEWT {@link GLWindow} {@link GLAutoDrawable auto drawable} for on- and offscreen cases. + *+ * The NEWT {@link GLAutoDrawable} is being used to run the {@link GLEventListener}. + *
+ */ +public class TestGLAutoDrawableGLCanvasOnOffscrnCapsAWT extends UITestCase { + static final int widthStep = 800/4; + static final int heightStep = 600/4; + volatile int szStep = 2; + + static GLCapabilities getCaps(String profile) { + if( !GLProfile.isAvailable(profile) ) { + System.err.println("Profile "+profile+" n/a"); + return null; + } + return new GLCapabilities(GLProfile.get(profile)); + } + + static void setGLCanvasSize(final Frame frame, final GLCanvas glc, final int width, final int height) { + try { + javax.swing.SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + final Dimension new_sz = new Dimension(width, height); + glc.setMinimumSize(new_sz); + glc.setPreferredSize(new_sz); + glc.setSize(new_sz); + frame.pack(); + frame.validate(); + } } ); + } catch( Throwable throwable ) { + throwable.printStackTrace(); + Assume.assumeNoException( throwable ); + } + } + + static interface MyGLEventListener extends GLEventListener { + void setMakeSnapshot(); + } + + void doTest(GLCapabilitiesImmutable reqGLCaps, GLEventListener demo) throws InterruptedException { + if(reqGLCaps.isOnscreen() && JAWTUtil.isOffscreenLayerRequired()) { + System.err.println("onscreen layer n/a"); + return; + } + if(!reqGLCaps.isOnscreen() && !JAWTUtil.isOffscreenLayerSupported()) { + System.err.println("offscreen layer n/a"); + return; + } + System.out.println("Requested GL Caps: "+reqGLCaps); + final GLDrawableFactory factory = GLDrawableFactory.getFactory(reqGLCaps.getGLProfile()); + + final boolean fboAvailable = factory.canCreateFBO(null, reqGLCaps.getGLProfile()); + final boolean pbufferAvailable = factory.canCreateGLPbuffer(null); + final GLCapabilitiesImmutable expGLCaps = GLGraphicsConfigurationUtil.fixGLCapabilities(reqGLCaps, fboAvailable, pbufferAvailable); + System.out.println("Expected GL Caps: "+expGLCaps); + // + // Create native windowing resources .. X11/Win/OSX + // + final GLCanvas glad = new GLCanvas(reqGLCaps); // will implicit trigger offscreen layer - if !onscreen && supported + Assert.assertNotNull(glad); + Dimension glc_sz = new Dimension(widthStep*szStep, heightStep*szStep); + glad.setMinimumSize(glc_sz); + glad.setPreferredSize(glc_sz); + glad.setSize(glc_sz); + final Frame frame = new Frame(getSimpleTestName(".")); + Assert.assertNotNull(frame); + frame.add(glad); + + try { + javax.swing.SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + frame.pack(); + frame.setVisible(true); + }}); + } catch( Throwable throwable ) { + throwable.printStackTrace(); + Assume.assumeNoException( throwable ); + } + + Assert.assertTrue(AWTRobotUtil.waitForVisible(glad, true)); + Assert.assertTrue(AWTRobotUtil.waitForRealized(glad, true)); + System.out.println("Window: "+glad.getClass().getName()); + + // Check caps of NativeWindow config w/o GL + final CapabilitiesImmutable chosenCaps = glad.getChosenGLCapabilities(); + System.out.println("Window Caps Pre_GL: "+chosenCaps); + Assert.assertNotNull(chosenCaps); + Assert.assertTrue(chosenCaps.getGreenBits()>5); + Assert.assertTrue(chosenCaps.getBlueBits()>5); + Assert.assertTrue(chosenCaps.getRedBits()>5); + + glad.display(); // force native context creation + + // + // Create native OpenGL resources .. XGL/WGL/CGL .. + // equivalent to GLAutoDrawable methods: setVisible(true) + // + { + final GLDrawable actualDrawable = glad.getDelegatedDrawable(); + Assert.assertNotNull(actualDrawable); + System.out.println("Drawable Pre-GL(0): "+actualDrawable.getClass().getName()+", "+actualDrawable.getNativeSurface().getClass().getName()); + } + + System.out.println("Window Caps PostGL : "+glad.getChosenGLCapabilities()); + System.out.println("Drawable Post-GL(1): "+glad.getClass().getName()+", "+glad.getNativeSurface().getClass().getName()); + + // Check caps of GLDrawable after realization + final GLCapabilitiesImmutable chosenGLCaps = glad.getChosenGLCapabilities(); + System.out.println("Chosen GL Caps(1): "+chosenGLCaps); + Assert.assertNotNull(chosenGLCaps); + Assert.assertTrue(chosenGLCaps.getGreenBits()>5); + Assert.assertTrue(chosenGLCaps.getBlueBits()>5); + Assert.assertTrue(chosenGLCaps.getRedBits()>5); + Assert.assertTrue(chosenGLCaps.getDepthBits()>4); + Assert.assertEquals(expGLCaps.isOnscreen(), chosenGLCaps.isOnscreen()); + Assert.assertEquals(expGLCaps.isFBO(), chosenGLCaps.isFBO()); + Assert.assertEquals(expGLCaps.isPBuffer(), chosenGLCaps.isPBuffer()); + Assert.assertEquals(expGLCaps.isBitmap(), chosenGLCaps.isBitmap()); + /** Single/Double buffer cannot be checked since result may vary .. + if(chosenGLCaps.isOnscreen() || chosenGLCaps.isFBO()) { + // dbl buffer may be disabled w/ offscreen pbuffer and bitmap + Assert.assertEquals(expGLCaps.getDoubleBuffered(), chosenGLCaps.getDoubleBuffered()); + } */ + + { + GLContext context = glad.getContext(); + System.out.println("Chosen GL CTX (2): "+context.getGLVersion()); + Assert.assertNotNull(context); + Assert.assertTrue(context.isCreated()); + } + + System.out.println("Chosen GL Caps(2): "+glad.getChosenGLCapabilities()); + System.out.println("Drawable Post-GL(2): "+glad.getClass().getName()+", "+glad.getNativeSurface().getClass().getName()); + + glad.addGLEventListener(demo); + + final SnapshotGLEventListener snapshotGLEventListener = new SnapshotGLEventListener(); + glad.addGLEventListener(snapshotGLEventListener); + + glad.display(); // initial resize/display + + // 1 - szStep = 2 + Assert.assertTrue("Size not reached: Expected "+(widthStep*szStep)+"x"+(heightStep*szStep)+", Is "+glad.getWidth()+"x"+glad.getHeight(), + AWTRobotUtil.waitForSize(glad, widthStep*szStep, heightStep*szStep)); + snapshotGLEventListener.setMakeSnapshot(); + glad.display(); + + // 2, 3 (resize + display) + szStep = 1; + setGLCanvasSize(frame, glad, widthStep*szStep, heightStep*szStep); + Assert.assertTrue("Size not reached: Expected "+(widthStep*szStep)+"x"+(heightStep*szStep)+", Is "+glad.getWidth()+"x"+glad.getHeight(), + AWTRobotUtil.waitForSize(glad, widthStep*szStep, heightStep*szStep)); + glad.display(); + snapshotGLEventListener.setMakeSnapshot(); + glad.display(); + + // 4, 5 (resize + display) + szStep = 4; + setGLCanvasSize(frame, glad, widthStep*szStep, heightStep*szStep); + Assert.assertTrue("Size not reached: Expected "+(widthStep*szStep)+"x"+(heightStep*szStep)+", Is "+glad.getWidth()+"x"+glad.getHeight(), + AWTRobotUtil.waitForSize(glad, widthStep*szStep, heightStep*szStep)); + glad.display(); + snapshotGLEventListener.setMakeSnapshot(); + glad.display(); + + Thread.sleep(50); + + try { + javax.swing.SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + frame.setVisible(false); + frame.remove(glad); + frame.dispose(); + }}); + } catch( Throwable throwable ) { + throwable.printStackTrace(); + Assume.assumeNoException( throwable ); + } + System.out.println("Fin: "+glad); + } + + @Test + public void testAvailableInfo() { + GLDrawableFactory f = GLDrawableFactory.getDesktopFactory(); + if(null != f) { + System.err.println(JoglVersion.getDefaultOpenGLInfo(f.getDefaultDevice(), null, true).toString()); + } + f = GLDrawableFactory.getEGLFactory(); + if(null != f) { + System.err.println(JoglVersion.getDefaultOpenGLInfo(f.getDefaultDevice(), null, true).toString()); + } + } + + @Test + public void testGL2OnScreen() throws InterruptedException { + final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2); + if(null == reqGLCaps) return; + doTest(reqGLCaps, new GearsES2(1)); + } + + @Test + public void testGL2OffScreenAuto() throws InterruptedException { + final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2); + if(null == reqGLCaps) return; + reqGLCaps.setOnscreen(false); + doTest(reqGLCaps, new GearsES2(1)); + } + + @Test + public void testGL2OffScreenFBOMSAA() throws InterruptedException { + final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2); + if(null == reqGLCaps) return; + reqGLCaps.setOnscreen(false); + reqGLCaps.setFBO(true); + reqGLCaps.setSampleBuffers(true); + reqGLCaps.setNumSamples(4); + doTest(reqGLCaps, new GearsES2(1)); + } + + @Test + public void testGL2OffScreenPbuffer() throws InterruptedException { + final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2); + if(null == reqGLCaps) return; + reqGLCaps.setOnscreen(false); + reqGLCaps.setPBuffer(true); + doTest(reqGLCaps, new GearsES2(1)); + } + + @Test + public void testES2OnScreen() throws InterruptedException { + final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2); + if(null == reqGLCaps) return; + doTest(reqGLCaps, new GearsES2(1)); + } + + @Test + public void testES2OffScreenAuto() throws InterruptedException { + final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2); + if(null == reqGLCaps) return; + reqGLCaps.setOnscreen(false); + doTest(reqGLCaps, new GearsES2(1)); + } + + @Test + public void testES2OffScreenFBOMSAA() throws InterruptedException { + final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2); + if(null == reqGLCaps) return; + reqGLCaps.setOnscreen(false); + reqGLCaps.setFBO(true); + reqGLCaps.setSampleBuffers(true); + reqGLCaps.setNumSamples(4); + doTest(reqGLCaps, new GearsES2(1)); + } + + @Test + public void testES2OffScreenPbuffer() throws InterruptedException { + final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2); + if(null == reqGLCaps) return; + reqGLCaps.setOnscreen(false); + reqGLCaps.setPBuffer(true); + doTest(reqGLCaps, new GearsES2(1)); + } + + + public static void main(String args[]) throws IOException { + org.junit.runner.JUnitCore.main(TestGLAutoDrawableGLCanvasOnOffscrnCapsAWT.class.getName()); + } + +} diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableGLWindowOnOffscrnCapsNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableGLWindowOnOffscrnCapsNEWT.java new file mode 100644 index 000000000..37ec44566 --- /dev/null +++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableGLWindowOnOffscrnCapsNEWT.java @@ -0,0 +1,351 @@ +/** + * 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 java.io.IOException; + +import javax.media.nativewindow.CapabilitiesImmutable; +import javax.media.opengl.GLAutoDrawable; +import javax.media.opengl.GLCapabilities; +import javax.media.opengl.GLCapabilitiesImmutable; +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.GLGraphicsConfigurationUtil; + +import org.junit.Assert; +import org.junit.Test; + +import com.jogamp.newt.opengl.GLWindow; +import com.jogamp.opengl.JoglVersion; +import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2; +import com.jogamp.opengl.test.junit.jogl.demos.gl2.Gears; +import com.jogamp.opengl.test.junit.util.AWTRobotUtil; +import com.jogamp.opengl.test.junit.util.UITestCase; + +/** + * Tests using a NEWT {@link GLWindow} {@link GLAutoDrawable auto drawable} for on- and offscreen cases. + *+ * The NEWT {@link GLAutoDrawable} is being used to run the {@link GLEventListener}. + *
+ */ +public class TestGLAutoDrawableGLWindowOnOffscrnCapsNEWT extends UITestCase { + static final int widthStep = 800/4; + static final int heightStep = 600/4; + volatile int szStep = 2; + + static interface MyGLEventListener extends GLEventListener { + void setMakeSnapshot(); + } + + static GLCapabilities getCaps(String profile) { + if( !GLProfile.isAvailable(profile) ) { + System.err.println("Profile "+profile+" n/a"); + return null; + } + return new GLCapabilities(GLProfile.get(profile)); + } + + void doTest(GLCapabilitiesImmutable reqGLCaps, GLEventListener demo) throws InterruptedException { + System.out.println("Requested GL Caps: "+reqGLCaps); + final GLDrawableFactory factory = GLDrawableFactory.getFactory(reqGLCaps.getGLProfile()); + + final boolean fboAvailable = factory.canCreateFBO(null, reqGLCaps.getGLProfile()); + final boolean pbufferAvailable = factory.canCreateGLPbuffer(null); + final GLCapabilitiesImmutable expGLCaps = GLGraphicsConfigurationUtil.fixGLCapabilities(reqGLCaps, fboAvailable, pbufferAvailable); + System.out.println("Expected GL Caps: "+expGLCaps); + // + // Create native windowing resources .. X11/Win/OSX + // + final GLWindow glad = GLWindow.create(reqGLCaps); + Assert.assertNotNull(glad); + glad.setSize(widthStep*szStep, heightStep*szStep); + glad.setVisible(true); + Assert.assertTrue(AWTRobotUtil.waitForVisible(glad, true)); + Assert.assertTrue(AWTRobotUtil.waitForRealized(glad, true)); + System.out.println("Window: "+glad.getClass().getName()); + + // Check caps of NativeWindow config w/o GL + final CapabilitiesImmutable chosenCaps = glad.getGraphicsConfiguration().getChosenCapabilities(); + System.out.println("Window Caps Pre_GL: "+chosenCaps); + Assert.assertNotNull(chosenCaps); + Assert.assertTrue(chosenCaps.getGreenBits()>5); + Assert.assertTrue(chosenCaps.getBlueBits()>5); + Assert.assertTrue(chosenCaps.getRedBits()>5); + + // + // Create native OpenGL resources .. XGL/WGL/CGL .. + // equivalent to GLAutoDrawable methods: setVisible(true) + // + { + final GLDrawable actualDrawable = glad.getDelegatedDrawable(); + Assert.assertNotNull(actualDrawable); + System.out.println("Drawable Pre-GL(0): "+actualDrawable.getClass().getName()+", "+actualDrawable.getNativeSurface().getClass().getName()); + } + + System.out.println("Window Caps PostGL : "+glad.getGraphicsConfiguration().getChosenCapabilities()); + System.out.println("Drawable Post-GL(1): "+glad.getClass().getName()+", "+glad.getNativeSurface().getClass().getName()); + + // Check caps of GLDrawable after realization + final GLCapabilitiesImmutable chosenGLCaps = glad.getChosenGLCapabilities(); + System.out.println("Chosen GL Caps(1): "+chosenGLCaps); + Assert.assertNotNull(chosenGLCaps); + Assert.assertTrue(chosenGLCaps.getGreenBits()>5); + Assert.assertTrue(chosenGLCaps.getBlueBits()>5); + Assert.assertTrue(chosenGLCaps.getRedBits()>5); + Assert.assertTrue(chosenGLCaps.getDepthBits()>4); + Assert.assertEquals(expGLCaps.isOnscreen(), chosenGLCaps.isOnscreen()); + Assert.assertEquals(expGLCaps.isFBO(), chosenGLCaps.isFBO()); + Assert.assertEquals(expGLCaps.isPBuffer(), chosenGLCaps.isPBuffer()); + Assert.assertEquals(expGLCaps.isBitmap(), chosenGLCaps.isBitmap()); + /** Single/Double buffer cannot be checked since result may vary .. + if(chosenGLCaps.isOnscreen() || chosenGLCaps.isFBO()) { + // dbl buffer may be disabled w/ offscreen pbuffer and bitmap + Assert.assertEquals(expGLCaps.getDoubleBuffered(), chosenGLCaps.getDoubleBuffered()); + } */ + + glad.display(); + { + GLContext context = glad.getContext(); + System.out.println("Chosen GL CTX (2): "+context.getGLVersion()); + Assert.assertNotNull(context); + Assert.assertTrue(context.isCreated()); + } + + System.out.println("Chosen GL Caps(2): "+glad.getChosenGLCapabilities()); + System.out.println("Drawable Post-GL(2): "+glad.getClass().getName()+", "+glad.getNativeSurface().getClass().getName()); + + glad.addGLEventListener(demo); + + final SnapshotGLEventListener snapshotGLEventListener = new SnapshotGLEventListener(); + glad.addGLEventListener(snapshotGLEventListener); + + glad.display(); // initial resize/display + + // 1 - szStep = 2 + Assert.assertTrue("Size not reached: Expected "+(widthStep*szStep)+"x"+(heightStep*szStep)+", Is "+glad.getWidth()+"x"+glad.getHeight(), + AWTRobotUtil.waitForSize(glad, widthStep*szStep, heightStep*szStep)); + snapshotGLEventListener.setMakeSnapshot(); + glad.display(); + + // 2, 3 (resize + display) + szStep = 1; + glad.setSize(widthStep*szStep, heightStep*szStep); + Assert.assertTrue("Size not reached: Expected "+(widthStep*szStep)+"x"+(heightStep*szStep)+", Is "+glad.getWidth()+"x"+glad.getHeight(), + AWTRobotUtil.waitForSize(glad, widthStep*szStep, heightStep*szStep)); + snapshotGLEventListener.setMakeSnapshot(); + glad.display(); + + // 4, 5 (resize + display) + szStep = 4; + glad.setSize(widthStep*szStep, heightStep*szStep); + Assert.assertTrue("Size not reached: Expected "+(widthStep*szStep)+"x"+(heightStep*szStep)+", Is "+glad.getWidth()+"x"+glad.getHeight(), + AWTRobotUtil.waitForSize(glad, widthStep*szStep, heightStep*szStep)); + snapshotGLEventListener.setMakeSnapshot(); + glad.display(); + + Thread.sleep(50); + + glad.destroy(); + System.out.println("Fin: "+glad); + } + + @Test + public void testAvailableInfo() { + GLDrawableFactory f = GLDrawableFactory.getDesktopFactory(); + if(null != f) { + System.err.println(JoglVersion.getDefaultOpenGLInfo(f.getDefaultDevice(), null, true).toString()); + } + f = GLDrawableFactory.getEGLFactory(); + if(null != f) { + System.err.println(JoglVersion.getDefaultOpenGLInfo(f.getDefaultDevice(), null, true).toString()); + } + } + + @Test + public void testGL2OnScreenDblBuf() throws InterruptedException { + final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2); + if(null == reqGLCaps) return; + doTest(reqGLCaps, new GearsES2(1)); + } + + @Test + public void testGL2OnScreenSglBuf() throws InterruptedException { + final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2); + if(null == reqGLCaps) return; + reqGLCaps.setDoubleBuffered(false); + doTest(reqGLCaps, new GearsES2(1)); + } + + @Test + public void testGL2OffScreenAutoDblBuf() throws InterruptedException { + final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2); + if(null == reqGLCaps) return; + reqGLCaps.setOnscreen(false); + doTest(reqGLCaps, new GearsES2(1)); + } + + @Test + public void testGL2OffScreenFBODblBuf() throws InterruptedException { + final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2); + if(null == reqGLCaps) return; + reqGLCaps.setOnscreen(false); + reqGLCaps.setFBO(true); + doTest(reqGLCaps, new GearsES2(1)); + } + + @Test + public void testGL2OffScreenFBOSglBuf() throws InterruptedException { + final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2); + if(null == reqGLCaps) return; + reqGLCaps.setOnscreen(false); + reqGLCaps.setFBO(true); + reqGLCaps.setDoubleBuffered(false); + doTest(reqGLCaps, new GearsES2(1)); + } + + @Test + public void testGL2OffScreenPbufferDblBuf() throws InterruptedException { + final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2); + if(null == reqGLCaps) return; + reqGLCaps.setOnscreen(false); + reqGLCaps.setPBuffer(true); + doTest(reqGLCaps, new GearsES2(1)); + } + + @Test + public void testGL2OffScreenPbufferSglBuf() throws InterruptedException { + final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2); + if(null == reqGLCaps) return; + reqGLCaps.setOnscreen(false); + reqGLCaps.setPBuffer(true); + reqGLCaps.setDoubleBuffered(false); + doTest(reqGLCaps, new GearsES2(1)); + } + + @Test + public void testGL2OffScreenBitmapDblBuf() throws InterruptedException { + final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2); + if(null == reqGLCaps) return; + reqGLCaps.setOnscreen(false); + reqGLCaps.setBitmap(true); + doTest(reqGLCaps, new Gears(1)); + } + + @Test + public void testGL2OffScreenBitmapSglBuf() throws InterruptedException { + final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2); + if(null == reqGLCaps) return; + reqGLCaps.setOnscreen(false); + reqGLCaps.setBitmap(true); + reqGLCaps.setDoubleBuffered(false); + doTest(reqGLCaps, new Gears(1)); + } + + @Test + public void testES2OnScreenDblBuf() throws InterruptedException { + final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2); + if(null == reqGLCaps) return; + doTest(reqGLCaps, new GearsES2(1)); + } + + @Test + public void testES2OnScreenSglBuf() throws InterruptedException { + final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2); + if(null == reqGLCaps) return; + reqGLCaps.setDoubleBuffered(false); + doTest(reqGLCaps, new GearsES2(1)); + } + + @Test + public void testES2OffScreenAutoDblBuf() throws InterruptedException { + final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2); + if(null == reqGLCaps) return; + reqGLCaps.setOnscreen(false); + doTest(reqGLCaps, new GearsES2(1)); + } + + @Test + public void testES2OffScreenFBODblBuf() throws InterruptedException { + final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2); + if(null == reqGLCaps) return; + reqGLCaps.setOnscreen(false); + reqGLCaps.setFBO(true); + doTest(reqGLCaps, new GearsES2(1)); + } + + @Test + public void testES2OffScreenFBOSglBuf() throws InterruptedException { + final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2); + if(null == reqGLCaps) return; + reqGLCaps.setOnscreen(false); + reqGLCaps.setFBO(true); + reqGLCaps.setDoubleBuffered(false); + doTest(reqGLCaps, new GearsES2(1)); + } + + @Test + public void testES2OffScreenPbufferDblBuf() throws InterruptedException { + final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2); + if(null == reqGLCaps) return; + reqGLCaps.setOnscreen(false); + reqGLCaps.setPBuffer(true); + doTest(reqGLCaps, new GearsES2(1)); + } + + @Test + public void testES2OffScreenPbufferSglBuf() throws InterruptedException { + final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2); + if(null == reqGLCaps) return; + reqGLCaps.setOnscreen(false); + reqGLCaps.setPBuffer(true); + reqGLCaps.setDoubleBuffered(false); + doTest(reqGLCaps, new GearsES2(1)); + } + + /** Not implemented ! + @Test + public void testES2OffScreenBitmapDblBuf() throws InterruptedException { + if(!checkProfile(GLProfile.GLES2)) { + return; + } + final GLCapabilities reqGLCaps = new GLCapabilities(GLProfile.get(GLProfile.GLES2)); + reqGLCaps.setOnscreen(false); + reqGLCaps.setBitmap(true); + doTest(reqGLCaps, new GearsES2(1)); + } */ + + public static void main(String args[]) throws IOException { + org.junit.runner.JUnitCore.main(TestGLAutoDrawableGLWindowOnOffscrnCapsNEWT.class.getName()); + } + +} diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableNewtCanvasAWTOnOffscrnCapsAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableNewtCanvasAWTOnOffscrnCapsAWT.java new file mode 100644 index 000000000..47fc99844 --- /dev/null +++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableNewtCanvasAWTOnOffscrnCapsAWT.java @@ -0,0 +1,300 @@ +/** + * 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 java.awt.Component; +import java.awt.Dimension; +import java.awt.Frame; +import java.io.IOException; + +import javax.media.nativewindow.CapabilitiesImmutable; +import javax.media.opengl.GLAutoDrawable; +import javax.media.opengl.GLCapabilities; +import javax.media.opengl.GLCapabilitiesImmutable; +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.nativewindow.jawt.JAWTUtil; +import jogamp.opengl.GLGraphicsConfigurationUtil; + +import org.junit.Assert; +import org.junit.Assume; +import org.junit.Test; + +import com.jogamp.newt.awt.NewtCanvasAWT; +import com.jogamp.newt.opengl.GLWindow; +import com.jogamp.opengl.JoglVersion; +import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2; +import com.jogamp.opengl.test.junit.util.AWTRobotUtil; +import com.jogamp.opengl.test.junit.util.UITestCase; + +/** + * Tests using a NEWT {@link GLWindow} {@link GLAutoDrawable auto drawable} for on- and offscreen cases. + *+ * The NEWT {@link GLAutoDrawable} is being used to run the {@link GLEventListener}. + *
+ */ +public class TestGLAutoDrawableNewtCanvasAWTOnOffscrnCapsAWT extends UITestCase { + static final int widthStep = 800/4; + static final int heightStep = 600/4; + volatile int szStep = 2; + + static GLCapabilities getCaps(String profile) { + if( !GLProfile.isAvailable(profile) ) { + System.err.println("Profile "+profile+" n/a"); + return null; + } + return new GLCapabilities(GLProfile.get(profile)); + } + + static void setComponentSize(final Frame frame, final Component comp, final int width, final int height) { + try { + javax.swing.SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + final Dimension new_sz = new Dimension(width, height); + comp.setMinimumSize(new_sz); + comp.setPreferredSize(new_sz); + comp.setSize(new_sz); + frame.pack(); + frame.validate(); + } } ); + } catch( Throwable throwable ) { + throwable.printStackTrace(); + Assume.assumeNoException( throwable ); + } + } + + static interface MyGLEventListener extends GLEventListener { + void setMakeSnapshot(); + } + + void doTest(boolean offscreenLayer, GLCapabilitiesImmutable reqGLCaps, GLEventListener demo) throws InterruptedException { + if(!offscreenLayer && JAWTUtil.isOffscreenLayerRequired()) { + System.err.println("onscreen layer n/a"); + return; + } + if(offscreenLayer && !JAWTUtil.isOffscreenLayerSupported()) { + System.err.println("offscreen layer n/a"); + return; + } + System.out.println("Requested GL Caps: "+reqGLCaps); + final GLDrawableFactory factory = GLDrawableFactory.getFactory(reqGLCaps.getGLProfile()); + + final boolean fboAvailable = factory.canCreateFBO(null, reqGLCaps.getGLProfile()); + final boolean pbufferAvailable = factory.canCreateGLPbuffer(null); + final GLCapabilitiesImmutable expGLCaps = offscreenLayer ? + GLGraphicsConfigurationUtil.fixOffscreenGLCapabilities(reqGLCaps, fboAvailable, pbufferAvailable) : + GLGraphicsConfigurationUtil.fixGLCapabilities(reqGLCaps, fboAvailable, pbufferAvailable); + System.out.println("Expected GL Caps: "+expGLCaps); + + final GLWindow glad = GLWindow.create(reqGLCaps); + Assert.assertNotNull(glad); + + + final NewtCanvasAWT nca = new NewtCanvasAWT(glad); + Assert.assertNotNull(nca); + Dimension size0 = new Dimension(widthStep*szStep, heightStep*szStep); + nca.setShallUseOffscreenLayer(offscreenLayer); // trigger offscreen layer - if supported + nca.setPreferredSize(size0); + nca.setMinimumSize(size0); + nca.setSize(size0); + + final Frame frame = new Frame(getSimpleTestName(".")); + Assert.assertNotNull(frame); + frame.add(nca); + + try { + javax.swing.SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + frame.pack(); + frame.setVisible(true); + }}); + } catch( Throwable throwable ) { + throwable.printStackTrace(); + Assume.assumeNoException( throwable ); + } + + Assert.assertTrue(AWTRobotUtil.waitForVisible(glad, true)); + Assert.assertTrue(AWTRobotUtil.waitForRealized(glad, true)); + System.out.println("Window: "+glad.getClass().getName()); + + // Check caps of NativeWindow config w/o GL + final CapabilitiesImmutable chosenCaps = glad.getChosenGLCapabilities(); + System.out.println("Window Caps Pre_GL: "+chosenCaps); + Assert.assertNotNull(chosenCaps); + Assert.assertTrue(chosenCaps.getGreenBits()>5); + Assert.assertTrue(chosenCaps.getBlueBits()>5); + Assert.assertTrue(chosenCaps.getRedBits()>5); + + glad.display(); // force native context creation + + // + // Create native OpenGL resources .. XGL/WGL/CGL .. + // equivalent to GLAutoDrawable methods: setVisible(true) + // + { + final GLDrawable actualDrawable = glad.getDelegatedDrawable(); + Assert.assertNotNull(actualDrawable); + System.out.println("Drawable Pre-GL(0): "+actualDrawable.getClass().getName()+", "+actualDrawable.getNativeSurface().getClass().getName()); + } + + System.out.println("Window Caps PostGL : "+glad.getChosenGLCapabilities()); + System.out.println("Drawable Post-GL(1): "+glad.getClass().getName()+", "+glad.getNativeSurface().getClass().getName()); + + // Check caps of GLDrawable after realization + final GLCapabilitiesImmutable chosenGLCaps = glad.getChosenGLCapabilities(); + System.out.println("Chosen GL Caps(1): "+chosenGLCaps); + Assert.assertNotNull(chosenGLCaps); + Assert.assertTrue(chosenGLCaps.getGreenBits()>5); + Assert.assertTrue(chosenGLCaps.getBlueBits()>5); + Assert.assertTrue(chosenGLCaps.getRedBits()>5); + Assert.assertTrue(chosenGLCaps.getDepthBits()>4); + Assert.assertEquals(expGLCaps.isOnscreen(), chosenGLCaps.isOnscreen()); + Assert.assertEquals(expGLCaps.isFBO(), chosenGLCaps.isFBO()); + Assert.assertEquals(expGLCaps.isPBuffer(), chosenGLCaps.isPBuffer()); + Assert.assertEquals(expGLCaps.isBitmap(), chosenGLCaps.isBitmap()); + /** Single/Double buffer cannot be checked since result may vary .. + if(chosenGLCaps.isOnscreen() || chosenGLCaps.isFBO()) { + // dbl buffer may be disabled w/ offscreen pbuffer and bitmap + Assert.assertEquals(expGLCaps.getDoubleBuffered(), chosenGLCaps.getDoubleBuffered()); + } */ + + { + GLContext context = glad.getContext(); + System.out.println("Chosen GL CTX (2): "+context.getGLVersion()); + Assert.assertNotNull(context); + Assert.assertTrue(context.isCreated()); + } + + System.out.println("Chosen GL Caps(2): "+glad.getChosenGLCapabilities()); + System.out.println("Drawable Post-GL(2): "+glad.getClass().getName()+", "+glad.getNativeSurface().getClass().getName()); + + glad.addGLEventListener(demo); + + final SnapshotGLEventListener snapshotGLEventListener = new SnapshotGLEventListener(); + glad.addGLEventListener(snapshotGLEventListener); + + glad.display(); // initial resize/display + + // 1 - szStep = 2 + Assert.assertTrue("Size not reached: Expected "+(widthStep*szStep)+"x"+(heightStep*szStep)+", Is "+glad.getWidth()+"x"+glad.getHeight(), + AWTRobotUtil.waitForSize(glad, widthStep*szStep, heightStep*szStep)); + snapshotGLEventListener.setMakeSnapshot(); + glad.display(); + + // 2, 3 (resize + display) + szStep = 1; + setComponentSize(frame, nca, widthStep*szStep, heightStep*szStep); + Assert.assertTrue("Size not reached: Expected "+(widthStep*szStep)+"x"+(heightStep*szStep)+", Is "+glad.getWidth()+"x"+glad.getHeight(), + AWTRobotUtil.waitForSize(glad, widthStep*szStep, heightStep*szStep)); + glad.display(); + snapshotGLEventListener.setMakeSnapshot(); + glad.display(); + + // 4, 5 (resize + display) + szStep = 4; + setComponentSize(frame, nca, widthStep*szStep, heightStep*szStep); + Assert.assertTrue("Size not reached: Expected "+(widthStep*szStep)+"x"+(heightStep*szStep)+", Is "+glad.getWidth()+"x"+glad.getHeight(), + AWTRobotUtil.waitForSize(glad, widthStep*szStep, heightStep*szStep)); + glad.display(); + snapshotGLEventListener.setMakeSnapshot(); + glad.display(); + + Thread.sleep(50); + + try { + javax.swing.SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + frame.setVisible(false); + frame.remove(nca); + frame.dispose(); + }}); + } catch( Throwable throwable ) { + throwable.printStackTrace(); + Assume.assumeNoException( throwable ); + } + glad.destroy(); + System.out.println("Fin: "+nca); + System.out.println("Fin: "+glad); + } + + @Test + public void testAvailableInfo() { + GLDrawableFactory f = GLDrawableFactory.getDesktopFactory(); + if(null != f) { + System.err.println(JoglVersion.getDefaultOpenGLInfo(f.getDefaultDevice(), null, true).toString()); + } + f = GLDrawableFactory.getEGLFactory(); + if(null != f) { + System.err.println(JoglVersion.getDefaultOpenGLInfo(f.getDefaultDevice(), null, true).toString()); + } + } + + @Test + public void testGL2OnScreenDblBuf() throws InterruptedException { + final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2); + if(null == reqGLCaps) return; + doTest(false, reqGLCaps, new GearsES2(1)); + } + + @Test + public void testGL2OffScreenLayerAuto() throws InterruptedException { + final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2); + if(null == reqGLCaps) return; + doTest(true, reqGLCaps, new GearsES2(1)); + } + + @Test + public void testGL2OffScreenFBOMSAA() throws InterruptedException { + final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2); + if(null == reqGLCaps) return; + reqGLCaps.setFBO(true); + reqGLCaps.setOnscreen(true); // get native NEWT Window, not OffscreenWindow + reqGLCaps.setSampleBuffers(true); + reqGLCaps.setNumSamples(4); + doTest(true, reqGLCaps, new GearsES2(1)); + } + + @Test + public void testGL2OffScreenPbuffer() throws InterruptedException { + final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2); + if(null == reqGLCaps) return; + reqGLCaps.setPBuffer(true); + reqGLCaps.setOnscreen(true); // get native NEWT Window, not OffscreenWindow + doTest(true, reqGLCaps, new GearsES2(1)); + } + + public static void main(String args[]) throws IOException { + org.junit.runner.JUnitCore.main(TestGLAutoDrawableNewtCanvasAWTOnOffscrnCapsAWT.class.getName()); + } + +} diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLCapabilities01NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLCapabilities01NEWT.java deleted file mode 100644 index cd1107e25..000000000 --- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLCapabilities01NEWT.java +++ /dev/null @@ -1,266 +0,0 @@ -/** - * 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 java.io.IOException; - -import javax.media.nativewindow.CapabilitiesImmutable; -import javax.media.opengl.GLCapabilities; -import javax.media.opengl.GLCapabilitiesImmutable; -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.GLGraphicsConfigurationUtil; - -import org.junit.Assert; -import org.junit.Test; - -import com.jogamp.newt.NewtFactory; -import com.jogamp.newt.Window; -import com.jogamp.opengl.JoglVersion; -import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2; -import com.jogamp.opengl.test.junit.util.AWTRobotUtil; -import com.jogamp.opengl.test.junit.util.UITestCase; - -public class TestGLCapabilities01NEWT extends UITestCase { - static final int width = 100; - static final int height = 100; - - boolean checkProfile(String profile) { - if( !GLProfile.isAvailable(profile) ) { - System.err.println("Profile "+profile+" n/a"); - return false; - } - return true; - } - - void doTest(GLCapabilitiesImmutable reqGLCaps, GLEventListener demo) throws InterruptedException { - System.out.println("Requested GL Caps: "+reqGLCaps); - - final GLCapabilitiesImmutable expGLCaps; - if( GLGraphicsConfigurationUtil.isGLCapabilitiesOffscreenAutoSelection(reqGLCaps) ) { - final GLDrawableFactory f = GLDrawableFactory.getFactory(reqGLCaps.getGLProfile()); - final boolean fboAvailable = true ; // f.canCreateFBO(null, reqGLCaps.getGLProfile()); - final boolean pbufferAvailable = f.canCreateGLPbuffer(null); - expGLCaps = GLGraphicsConfigurationUtil.fixGLCapabilities(reqGLCaps, fboAvailable, pbufferAvailable); - } else { - expGLCaps = reqGLCaps; - } - System.out.println("Expected GL Caps: "+expGLCaps); - // - // Create native windowing resources .. X11/Win/OSX - // - final Window window = NewtFactory.createWindow(reqGLCaps); - Assert.assertNotNull(window); - window.setSize(width, height); - window.setVisible(true); - Assert.assertTrue(AWTRobotUtil.waitForVisible(window, true)); - Assert.assertTrue(AWTRobotUtil.waitForRealized(window, true)); - System.out.println("Window: "+window.getClass().getName()); - - // Check caps of NativeWindow config w/o GL - final CapabilitiesImmutable chosenCaps = window.getGraphicsConfiguration().getChosenCapabilities(); - System.out.println("Window Caps Pre_GL: "+chosenCaps); - Assert.assertNotNull(chosenCaps); - Assert.assertTrue(chosenCaps.getGreenBits()>5); - Assert.assertTrue(chosenCaps.getBlueBits()>5); - Assert.assertTrue(chosenCaps.getRedBits()>5); - - // - // Create native OpenGL resources .. XGL/WGL/CGL .. - // equivalent to GLAutoDrawable methods: setVisible(true) - // - final GLDrawableFactory factory = GLDrawableFactory.getFactory(reqGLCaps.getGLProfile()); - - final GLDrawable drawable = factory.createGLDrawable(window); - Assert.assertNotNull(drawable); - System.out.println("Drawable Pre-GL(0): "+drawable.getClass().getName()+", "+drawable.getNativeSurface().getClass().getName()); - - // - drawable.setRealized(true); - Assert.assertTrue(drawable.isRealized()); - - System.out.println("Window Caps PostGL : "+window.getGraphicsConfiguration().getChosenCapabilities()); - System.out.println("Drawable Post-GL(1): "+drawable.getClass().getName()+", "+drawable.getNativeSurface().getClass().getName()); - - // Check caps of GLDrawable after realization - final GLCapabilitiesImmutable chosenGLCaps = drawable.getChosenGLCapabilities(); - System.out.println("Chosen GL Caps(1): "+chosenGLCaps); - Assert.assertNotNull(chosenGLCaps); - Assert.assertTrue(chosenGLCaps.getGreenBits()>5); - Assert.assertTrue(chosenGLCaps.getBlueBits()>5); - Assert.assertTrue(chosenGLCaps.getRedBits()>5); - Assert.assertTrue(chosenGLCaps.getDepthBits()>4); - Assert.assertEquals(expGLCaps.isOnscreen(), chosenGLCaps.isOnscreen()); - Assert.assertEquals(expGLCaps.isFBO(), chosenGLCaps.isFBO()); - Assert.assertEquals(expGLCaps.isPBuffer(), chosenGLCaps.isPBuffer()); - Assert.assertEquals(expGLCaps.isBitmap(), chosenGLCaps.isBitmap()); - if(chosenGLCaps.isOnscreen() || chosenGLCaps.isFBO()) { - // dbl buffer may be disabled w/ offscreen pbuffer and bitmap - Assert.assertEquals(expGLCaps.getDoubleBuffered(), chosenGLCaps.getDoubleBuffered()); - } - - GLContext context = drawable.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("Chosen GL Caps(2): "+drawable.getChosenGLCapabilities()); - System.out.println("Drawable Post-GL(2): "+drawable.getClass().getName()+", "+drawable.getNativeSurface().getClass().getName()); - - drawable.setRealized(false); - window.destroy(); - } - - @Test - public void testAvailableInfo() { - GLDrawableFactory f = GLDrawableFactory.getDesktopFactory(); - if(null != f) { - System.err.println(JoglVersion.getDefaultOpenGLInfo(f.getDefaultDevice(), null, true).toString()); - } - f = GLDrawableFactory.getEGLFactory(); - if(null != f) { - System.err.println(JoglVersion.getDefaultOpenGLInfo(f.getDefaultDevice(), null, true).toString()); - } - } - - @Test - public void testGL2OnScreenDblBuf() throws InterruptedException { - if(!checkProfile(GLProfile.GL2)) { - return; - } - final GLCapabilities reqGLCaps = new GLCapabilities(GLProfile.get(GLProfile.GL2)); - doTest(reqGLCaps, new GearsES2(1)); - } - - @Test - public void testGL2OffScreenAutoDblBuf() throws InterruptedException { - if(!checkProfile(GLProfile.GL2)) { - return; - } - final GLCapabilities reqGLCaps = new GLCapabilities(GLProfile.get(GLProfile.GL2)); - reqGLCaps.setOnscreen(false); - doTest(reqGLCaps, new GearsES2(1)); - } - - @Test - public void testGL2OffScreenFBODblBuf() throws InterruptedException { - if(!checkProfile(GLProfile.GL2)) { - return; - } - final GLCapabilities reqGLCaps = new GLCapabilities(GLProfile.get(GLProfile.GL2)); - reqGLCaps.setOnscreen(false); - reqGLCaps.setFBO(true); - doTest(reqGLCaps, new GearsES2(1)); - } - - @Test - public void testGL2OffScreenPbufferDblBuf() throws InterruptedException { - if(!checkProfile(GLProfile.GL2)) { - return; - } - final GLCapabilities reqGLCaps = new GLCapabilities(GLProfile.get(GLProfile.GL2)); - reqGLCaps.setOnscreen(false); - reqGLCaps.setPBuffer(true); - doTest(reqGLCaps, new GearsES2(1)); - } - - @Test - public void testGL2OffScreenBitmapDblBuf() throws InterruptedException { - if(!checkProfile(GLProfile.GL2)) { - return; - } - final GLCapabilities reqGLCaps = new GLCapabilities(GLProfile.get(GLProfile.GL2)); - reqGLCaps.setOnscreen(false); - reqGLCaps.setBitmap(true); - doTest(reqGLCaps, new GearsES2(1)); - } - - @Test - public void testES2OnScreenDblBuf() throws InterruptedException { - if(!checkProfile(GLProfile.GLES2)) { - return; - } - final GLCapabilities reqGLCaps = new GLCapabilities(GLProfile.get(GLProfile.GLES2)); - doTest(reqGLCaps, new GearsES2(1)); - } - - @Test - public void testES2OffScreenAutoDblBuf() throws InterruptedException { - if(!checkProfile(GLProfile.GLES2)) { - return; - } - final GLCapabilities reqGLCaps = new GLCapabilities(GLProfile.get(GLProfile.GLES2)); - reqGLCaps.setOnscreen(false); - doTest(reqGLCaps, new GearsES2(1)); - } - - @Test - public void testES2OffScreenFBODblBuf() throws InterruptedException { - if(!checkProfile(GLProfile.GLES2)) { - return; - } - final GLCapabilities reqGLCaps = new GLCapabilities(GLProfile.get(GLProfile.GLES2)); - reqGLCaps.setOnscreen(false); - reqGLCaps.setFBO(true); - doTest(reqGLCaps, new GearsES2(1)); - } - - @Test - public void testES2OffScreenPbufferDblBuf() throws InterruptedException { - if(!checkProfile(GLProfile.GLES2)) { - return; - } - final GLCapabilities reqGLCaps = new GLCapabilities(GLProfile.get(GLProfile.GLES2)); - reqGLCaps.setOnscreen(false); - reqGLCaps.setPBuffer(true); - doTest(reqGLCaps, new GearsES2(1)); - } - - /** Not implemented ! - @Test - public void testES2OffScreenBitmapDblBuf() throws InterruptedException { - if(!checkProfile(GLProfile.GLES2)) { - return; - } - final GLCapabilities reqGLCaps = new GLCapabilities(GLProfile.get(GLProfile.GLES2)); - reqGLCaps.setOnscreen(false); - reqGLCaps.setBitmap(true); - doTest(reqGLCaps, new GearsES2(1)); - } */ - - public static void main(String args[]) throws IOException { - org.junit.runner.JUnitCore.main(TestGLCapabilities01NEWT.class.getName()); - } - -} diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLContextDrawableSwitchNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLContextDrawableSwitchNEWT.java index cece4c6d5..4c1130498 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLContextDrawableSwitchNEWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLContextDrawableSwitchNEWT.java @@ -39,13 +39,14 @@ import com.jogamp.newt.event.WindowUpdateEvent; import com.jogamp.newt.opengl.GLWindow; import javax.media.opengl.GLAutoDrawable; -import javax.media.opengl.GLAutoDrawableDelegate; 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 com.jogamp.opengl.GLAutoDrawableDelegate; import com.jogamp.opengl.util.Animator; import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2; @@ -81,14 +82,17 @@ public class TestGLContextDrawableSwitchNEWT extends UITestCase { Assert.assertTrue(AWTRobotUtil.waitForVisible(window, true)); Assert.assertTrue(AWTRobotUtil.waitForRealized(window, true)); - GLDrawableFactory factory = GLDrawableFactory.getFactory(caps.getGLProfile()); - GLDrawable drawable = factory.createGLDrawable(window); + final GLDrawableFactory factory = GLDrawableFactory.getFactory(caps.getGLProfile()); + final GLDrawable drawable = factory.createGLDrawable(window); Assert.assertNotNull(drawable); drawable.setRealized(true); Assert.assertTrue(drawable.isRealized()); - final GLAutoDrawableDelegate glad = new GLAutoDrawableDelegate(drawable, null, window, false) { + final GLContext context = drawable.createContext(null); + Assert.assertNotNull(context); + + final GLAutoDrawableDelegate glad = new GLAutoDrawableDelegate(drawable, context, window, false, null) { @Override protected void destroyImplInLock() { super.destroyImplInLock(); @@ -104,7 +108,7 @@ public class TestGLContextDrawableSwitchNEWT extends UITestCase { } @Override public void windowResized(WindowEvent e) { - glad.windowResizedOp(); + glad.windowResizedOp(window.getWidth(), window.getHeight()); } @Override public void windowDestroyNotify(WindowEvent e) { @@ -123,9 +127,13 @@ public class TestGLContextDrawableSwitchNEWT extends UITestCase { GLAutoDrawable glad1 = createGLAutoDrawable(caps, 64, 64, width, height, quitAdapter); // no GLContext! GLAutoDrawable glad2 = createGLAutoDrawable(caps, 2*64+width, 64, width+100, height+100, quitAdapter); // no GLContext! - // create single context using glad1 and assign it to glad1 + // create single context using glad1 and assign it to glad1, + // after destroying the prev. context! { - GLContext singleCtx = glad1.createContext(null); + final GLContext oldCtx = glad1.getContext(); + Assert.assertNotNull(oldCtx); + oldCtx.destroy(); + final GLContext singleCtx = glad1.createContext(null); Assert.assertNotNull(singleCtx); int res = singleCtx.makeCurrent(); Assert.assertTrue(GLContext.CONTEXT_CURRENT_NEW==res || GLContext.CONTEXT_CURRENT==res); diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLDrawable01NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLDrawable01NEWT.java deleted file mode 100644 index a6e9cfb07..000000000 --- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLDrawable01NEWT.java +++ /dev/null @@ -1,171 +0,0 @@ -/** - * 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 java.io.IOException; - -import javax.media.nativewindow.CapabilitiesImmutable; -import javax.media.opengl.GL; -import javax.media.opengl.GLCapabilities; -import javax.media.opengl.GLCapabilitiesImmutable; -import javax.media.opengl.GLContext; -import javax.media.opengl.GLDrawable; -import javax.media.opengl.GLDrawableFactory; -import javax.media.opengl.GLProfile; - -import org.junit.Assert; -import org.junit.Test; - -import com.jogamp.newt.NewtFactory; -import com.jogamp.newt.Window; -import com.jogamp.opengl.test.junit.util.AWTRobotUtil; -import com.jogamp.opengl.test.junit.util.UITestCase; - -public class TestGLDrawable01NEWT extends UITestCase { - static final int width = 200, height = 200; - - void doTest(String profile, boolean onscreen, boolean fbo, boolean pbuffer) throws InterruptedException { - if( !GLProfile.isAvailable(profile) ) { - System.err.println("Profile "+profile+" n/a"); - return; - } - - final GLProfile glp = GLProfile.get(profile); - final GLCapabilities reqGLCaps = new GLCapabilities(glp); - - reqGLCaps.setOnscreen(onscreen); - reqGLCaps.setPBuffer(!onscreen && pbuffer); - reqGLCaps.setFBO(!onscreen && fbo); - reqGLCaps.setDoubleBuffered(onscreen); - // System.out.println("Requested: "+caps); - - // - // Create native windowing resources .. X11/Win/OSX - // - Window window = NewtFactory.createWindow(reqGLCaps); - Assert.assertNotNull(window); - window.setSize(width, height); - window.setVisible(true); - AWTRobotUtil.waitForVisible(window, true); - AWTRobotUtil.waitForRealized(window, true); - // System.out.println("Created: "+window); - - // Check caps of NativeWindow config w/o GL - final CapabilitiesImmutable chosenCaps = window.getGraphicsConfiguration().getChosenCapabilities(); - Assert.assertNotNull(chosenCaps); - Assert.assertTrue(chosenCaps.getGreenBits()>5); - Assert.assertTrue(chosenCaps.getBlueBits()>5); - Assert.assertTrue(chosenCaps.getRedBits()>5); - - // - // Create native OpenGL resources .. XGL/WGL/CGL .. - // equivalent to GLAutoDrawable methods: setVisible(true) - // - final GLDrawableFactory factory = GLDrawableFactory.getFactory(glp); - - final GLDrawable drawable = factory.createGLDrawable(window); - Assert.assertNotNull(drawable); - // System.out.println("Pre: "+drawable); - // - drawable.setRealized(true); - Assert.assertTrue(drawable.isRealized()); - - // Check caps of GLDrawable after realization - final GLCapabilitiesImmutable chosenGLCaps = drawable.getChosenGLCapabilities(); - Assert.assertNotNull(chosenGLCaps); - Assert.assertTrue(chosenGLCaps.getGreenBits()>5); - Assert.assertTrue(chosenGLCaps.getBlueBits()>5); - Assert.assertTrue(chosenGLCaps.getRedBits()>5); - Assert.assertTrue(chosenGLCaps.getDepthBits()>4); - Assert.assertEquals(reqGLCaps.isOnscreen(), chosenGLCaps.isOnscreen()); - Assert.assertEquals(reqGLCaps.isOnscreen(), chosenGLCaps.getDoubleBuffered()); // offscreen shall be !dbl-buffer - // System.out.println("Post: "+drawable); - - GLContext context = drawable.createContext(null); - Assert.assertNotNull(context); - // System.out.println(context); - - int res = context.makeCurrent(); - Assert.assertTrue(GLContext.CONTEXT_CURRENT_NEW==res || GLContext.CONTEXT_CURRENT==res); - - // draw something .. - final GL gl = context.getGL(); - gl.glClearColor(1, 1, 1, 1); - gl.glEnable(GL.GL_DEPTH_TEST); - Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError()); - gl.glViewport(0, 0, width, height); - gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); - Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError()); - - drawable.swapBuffers(); - context.release(); - - Thread.sleep(50); - - context.destroy(); - drawable.setRealized(false); - window.destroy(); - // System.out.println("Final: "+window); - } - - @Test - public void testGL2OnScreen() throws InterruptedException { - doTest(GLProfile.GL2, true, false, false); - } - - @Test - public void testES2OnScreen() throws InterruptedException { - doTest(GLProfile.GLES2, true, false, false); - } - - @Test - public void testGL2PBuffer() throws InterruptedException { - doTest(GLProfile.GL2, false, false, true); - } - - @Test - public void testES2PBuffer() throws InterruptedException { - doTest(GLProfile.GLES2, false, false, true); - } - - // @Test // TODO: FBO-Drawable via createGLDrawable and pre-exisiting NativeSurface - public void testGL2FBO() throws InterruptedException { - doTest(GLProfile.GL2, false, true, false); - } - - // @Test // TODO: FBO-Drawable via createGLDrawable and pre-exisiting NativeSurface - public void testES2FBO() throws InterruptedException { - doTest(GLProfile.GLES2, false, true, false); - } - - public static void main(String args[]) throws IOException { - org.junit.runner.JUnitCore.main(TestGLDrawable01NEWT.class.getName()); - } - -} diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLExtensionQueryOffscreen.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLExtensionQueryOffscreen.java index e4245ef11..d4f3fece5 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLExtensionQueryOffscreen.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLExtensionQueryOffscreen.java @@ -32,14 +32,11 @@ import java.util.Collections; import java.util.SortedSet; import java.util.TreeSet; -import javax.media.nativewindow.AbstractGraphicsDevice; -import javax.media.opengl.DefaultGLCapabilitiesChooser; import javax.media.opengl.GL; -import javax.media.opengl.GLAutoDrawable; import javax.media.opengl.GLCapabilities; -import javax.media.opengl.GLCapabilitiesChooser; import javax.media.opengl.GLContext; import javax.media.opengl.GLDrawableFactory; +import javax.media.opengl.GLOffscreenAutoDrawable; import javax.media.opengl.GLProfile; import jogamp.opengl.GLDrawableFactoryImpl; @@ -77,13 +74,11 @@ public class TestGLExtensionQueryOffscreen { @Test public void testJogl2ExtensionCheck2() { - GLCapabilities caps = new GLCapabilities(GLProfile.getDefault()); - GLDrawableFactory factory = GLDrawableFactory.getDesktopFactory(); - GLCapabilitiesChooser glCapsChooser = new DefaultGLCapabilitiesChooser(); - AbstractGraphicsDevice agd = factory.getDefaultDevice(); + final GLCapabilities caps = new GLCapabilities(GLProfile.getDefault()); + final GLDrawableFactory factory = GLDrawableFactory.getFactory(caps.getGLProfile()); + final GLOffscreenAutoDrawable drawable = factory.createOffscreenAutoDrawable(null, caps, null, 256, 256, null); - GLAutoDrawable drawable = factory.createGLPbuffer(agd, caps, glCapsChooser, 256, 256, null); - GLContext context = drawable.getContext(); + final GLContext context = drawable.getContext(); context.makeCurrent(); String extensions; try { @@ -94,8 +89,8 @@ public class TestGLExtensionQueryOffscreen { String[] tabExtensions = extensions.split(" "); SortedSet
+ * + Container is the JFrame's implicit root content pane
+ *
+ * {@link JFrame} . {@link JPanel}+ . {@link Container} . {@link NewtCanvasAWT} . {@link GLWindow} + *
+ *
+ * + JPanel is set as JFrame's root content pane
+ *
- * TestFBODrawableNEWT.test01-F_rgba-I_rgba-S0_default-GL2-n0004-0800x0600.png - * TestFBODrawableNEWT.test01-F_rgba-I_rgba-S0_default-GL2-n0005-0800x0600.png + * TestGLDrawableAutoDelegateOnOffscrnCapsNEWT.testES2OffScreenFBOSglBuf____-n0001-msaa0-GLES2_-sw-fbobject-Bdbl-Frgb__Irgb_-S00_default-0400x0300.png + * TestGLDrawableAutoDelegateOnOffscrnCapsNEWT.testES2OffScreenPbufferDblBuf-n0003-msaa0-GLES2_-sw-pbuffer_-Bdbl-Frgb__Irgb_-S00_default-0200x0150.png + * TestGLDrawableAutoDelegateOnOffscrnCapsNEWT.testGL2OffScreenPbufferSglBuf-n0003-msaa0-GL2___-hw-pbuffer_-Bone-Frgb__Irgb_-S00_default-0200x0150.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.
@@ -137,30 +156,80 @@ public abstract class UITestCase {
* 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) {
+ public void snapshot(int sn, String postSNDetail, GL gl, GLReadBufferUtil readBufferUtil, String fileSuffix, String destPath) {
if(null == fileSuffix) {
fileSuffix = TextureIO.PNG;
}
- final StringWriter filenameSW = new StringWriter();
- {
+ final int maxSimpleTestNameLen = getMaxTestNameLen()+getClass().getSimpleName().length()+1;
+ final String simpleTestName = this.getSimpleTestName(".");
+ final String filenameBaseName;
+ {
final GLDrawable drawable = gl.getContext().getGLReadDrawable();
final GLCapabilitiesImmutable caps = drawable.getChosenGLCapabilities();
+ final String accel = caps.getHardwareAccelerated() ? "hw" : "sw" ;
+ final String scrnm;
+ if(caps.isOnscreen()) {
+ scrnm = "onscreen";
+ } else if(caps.isFBO()) {
+ scrnm = "fbobject";
+ } else if(caps.isPBuffer()) {
+ scrnm = "pbuffer_";
+ } else if(caps.isBitmap()) {
+ scrnm = "bitmap__";
+ } else {
+ scrnm = "unknown_";
+ }
+ final String dblb = caps.getDoubleBuffered() ? "dbl" : "one";
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() ;
+ final String aaext = caps.getSampleExtension();
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);
+
+ filenameBaseName = String.format("%-"+maxSimpleTestNameLen+"s-n%04d%s-%-6s-%s-%s-B%s-F%s_I%s-S%02d_%s-%04dx%04d.%s",
+ simpleTestName, sn, postSNDetail, drawable.getGLProfile().getName(), accel,
+ scrnm, dblb, F_pfmt, pfmt, samples, aaext,
+ drawable.getWidth(), drawable.getHeight(), fileSuffix).replace(' ', '_');
}
- final String filename = null != destPath ? destPath + File.separator + filenameSW.toString() : filenameSW.toString();
- System.err.println(Thread.currentThread().getName()+": ** screenshot: "+filename);
+ final String filename = null != destPath ? destPath + File.separator + filenameBaseName : filenameBaseName;
+ System.err.println(Thread.currentThread().getName()+": ** screenshot: "+filename+", maxTestNameLen "+maxSimpleTestNameLen+", <"+simpleTestName+">");
gl.glFinish(); // just make sure rendering finished ..
if(readBufferUtil.readPixels(gl, false)) {
readBufferUtil.write(new File(filename));
}
- }
+ }
+
+ public class SnapshotGLEventListener implements GLEventListener {
+ private final GLReadBufferUtil screenshot;
+ private volatile boolean makeShot = false;
+ private volatile int displayCount=0;
+ private volatile int reshapeCount=0;
+ public SnapshotGLEventListener(GLReadBufferUtil screenshot) {
+ this.screenshot = screenshot;
+ }
+ public SnapshotGLEventListener() {
+ this.screenshot = new GLReadBufferUtil(false, false);
+ }
+
+ 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+": "+drawable.getWidth()+"x"+drawable.getHeight()+", makeShot "+makeShot);
+ if(makeShot) {
+ makeShot=false;
+ snapshot(displayCount, null, gl, screenshot, TextureIO.PNG, null);
+ }
+ displayCount++;
+ }
+ public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
+ System.err.println(Thread.currentThread().getName()+": ** reshape: "+reshapeCount+": "+width+"x"+height+" - "+drawable.getWidth()+"x"+drawable.getHeight());
+ reshapeCount++;
+ }
+ public void setMakeSnapshot() {
+ makeShot=true;
+ }
+ };
+
}
--
cgit v1.2.3
From 7278244e321dd1d533223e9b6d668a6acd82bc76 Mon Sep 17 00:00:00 2001
From: Sven Gothel - * Implementation assumes linear matrix layout in column-major order - * matching OpenGL's implementation. - *
- *- * Derived from ProjectFloat.java - Created 11-jan-2004 - *
- * - * @author Erik Duijs - * @author Kenneth Russell - * @author Sven Gothel - */ -public class FloatUtil { - private static final float[] IDENTITY_MATRIX = - new float[] { - 1.0f, 0.0f, 0.0f, 0.0f, - 0.0f, 1.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 1.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 1.0f }; - - private static final float[] ZERO_MATRIX = - new float[] { - 0.0f, 0.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 0.0f }; - - /** - * Make matrix an identity matrix - */ - public static final void makeIdentityf(float[] m, int offset) { - for (int i = 0; i < 16; i++) { - m[i+offset] = IDENTITY_MATRIX[i]; - } - } - - /** - * Make matrix an identity matrix - */ - public static final void makeIdentityf(FloatBuffer m) { - final int oldPos = m.position(); - m.put(IDENTITY_MATRIX); - m.position(oldPos); - } - - /** - * Make matrix an zero matrix - */ - public static final void makeZero(float[] m, int offset) { - for (int i = 0; i < 16; i++) { - m[i+offset] = 0; - } - } - - /** - * Make matrix an zero matrix - */ - public static final void makeZero(FloatBuffer m) { - final int oldPos = m.position(); - m.put(ZERO_MATRIX); - m.position(oldPos); - } - - /** - * @param a 4x4 matrix in column-major order - * @param b 4x4 matrix in column-major order - * @param d result a*b in column-major order - */ - public static final void multMatrixf(final float[] a, int a_off, final float[] b, int b_off, float[] d, int d_off) { - for (int i = 0; i < 4; i++) { - // one row in column-major order - final float ai0=a[a_off+i+0*4], ai1=a[a_off+i+1*4], ai2=a[a_off+i+2*4], ai3=a[a_off+i+3*4]; // row-i of a - d[d_off+i+0*4] = ai0 * b[b_off+0+0*4] + ai1 * b[b_off+1+0*4] + ai2 * b[b_off+2+0*4] + ai3 * b[b_off+3+0*4] ; - d[d_off+i+1*4] = ai0 * b[b_off+0+1*4] + ai1 * b[b_off+1+1*4] + ai2 * b[b_off+2+1*4] + ai3 * b[b_off+3+1*4] ; - d[d_off+i+2*4] = ai0 * b[b_off+0+2*4] + ai1 * b[b_off+1+2*4] + ai2 * b[b_off+2+2*4] + ai3 * b[b_off+3+2*4] ; - d[d_off+i+3*4] = ai0 * b[b_off+0+3*4] + ai1 * b[b_off+1+3*4] + ai2 * b[b_off+2+3*4] + ai3 * b[b_off+3+3*4] ; - } - } - - /** - * @param a 4x4 matrix in column-major order - * @param b 4x4 matrix in column-major order - * @param d result a*b in column-major order - */ - public static final void multMatrixf(final float[] a, int a_off, final float[] b, int b_off, FloatBuffer d) { - final int dP = d.position(); - for (int i = 0; i < 4; i++) { - // one row in column-major order - final float ai0=a[a_off+i+0*4], ai1=a[a_off+i+1*4], ai2=a[a_off+i+2*4], ai3=a[a_off+i+3*4]; // row-i of a - d.put(dP+i+0*4 , ai0 * b[b_off+0+0*4] + ai1 * b[b_off+1+0*4] + ai2 * b[b_off+2+0*4] + ai3 * b[b_off+3+0*4] ); - d.put(dP+i+1*4 , ai0 * b[b_off+0+1*4] + ai1 * b[b_off+1+1*4] + ai2 * b[b_off+2+1*4] + ai3 * b[b_off+3+1*4] ); - d.put(dP+i+2*4 , ai0 * b[b_off+0+2*4] + ai1 * b[b_off+1+2*4] + ai2 * b[b_off+2+2*4] + ai3 * b[b_off+3+2*4] ); - d.put(dP+i+3*4 , ai0 * b[b_off+0+3*4] + ai1 * b[b_off+1+3*4] + ai2 * b[b_off+2+3*4] + ai3 * b[b_off+3+3*4] ); - } - } - - /** - * @param a 4x4 matrix in column-major order - * @param b 4x4 matrix in column-major order - * @param d result a*b in column-major order - */ - public static final void multMatrixf(final FloatBuffer a, final float[] b, int b_off, FloatBuffer d) { - final int aP = a.position(); - final int dP = d.position(); - for (int i = 0; i < 4; i++) { - // one row in column-major order - final float ai0=a.get(aP+i+0*4), ai1=a.get(aP+i+1*4), ai2=a.get(aP+i+2*4), ai3=a.get(aP+i+3*4); // row-i of a - d.put(dP+i+0*4 , ai0 * b[b_off+0+0*4] + ai1 * b[b_off+1+0*4] + ai2 * b[b_off+2+0*4] + ai3 * b[b_off+3+0*4] ); - d.put(dP+i+1*4 , ai0 * b[b_off+0+1*4] + ai1 * b[b_off+1+1*4] + ai2 * b[b_off+2+1*4] + ai3 * b[b_off+3+1*4] ); - d.put(dP+i+2*4 , ai0 * b[b_off+0+2*4] + ai1 * b[b_off+1+2*4] + ai2 * b[b_off+2+2*4] + ai3 * b[b_off+3+2*4] ); - d.put(dP+i+3*4 , ai0 * b[b_off+0+3*4] + ai1 * b[b_off+1+3*4] + ai2 * b[b_off+2+3*4] + ai3 * b[b_off+3+3*4] ); - } - } - - /** - * @param a 4x4 matrix in column-major order - * @param b 4x4 matrix in column-major order - * @param d result a*b in column-major order - */ - public static final void multMatrixf(final FloatBuffer a, final FloatBuffer b, FloatBuffer d) { - final int aP = a.position(); - final int bP = b.position(); - final int dP = d.position(); - for (int i = 0; i < 4; i++) { - // one row in column-major order - final float ai0=a.get(aP+i+0*4), ai1=a.get(aP+i+1*4), ai2=a.get(aP+i+2*4), ai3=a.get(aP+i+3*4); // row-i of a - d.put(dP+i+0*4 , ai0 * b.get(bP+0+0*4) + ai1 * b.get(bP+1+0*4) + ai2 * b.get(bP+2+0*4) + ai3 * b.get(bP+3+0*4) ); - d.put(dP+i+1*4 , ai0 * b.get(bP+0+1*4) + ai1 * b.get(bP+1+1*4) + ai2 * b.get(bP+2+1*4) + ai3 * b.get(bP+3+1*4) ); - d.put(dP+i+2*4 , ai0 * b.get(bP+0+2*4) + ai1 * b.get(bP+1+2*4) + ai2 * b.get(bP+2+2*4) + ai3 * b.get(bP+3+2*4) ); - d.put(dP+i+3*4 , ai0 * b.get(bP+0+3*4) + ai1 * b.get(bP+1+3*4) + ai2 * b.get(bP+2+3*4) + ai3 * b.get(bP+3+3*4) ); - } - } - - - /** - * Normalize vector - * - * @param v makes len(v)==1 - */ - public static final void normalize(float[] v) { - float r = (float) Math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); - - if ( r == 0.0 || r == 1.0) { - return; - } - - r = 1.0f / r; - - v[0] *= r; - v[1] *= r; - v[2] *= r; - } - - /** - * Normalize vector - * - * @param v makes len(v)==1 - */ - public static final void normalize(FloatBuffer v) { - final int vPos = v.position(); - - float r = (float) Math.sqrt(v.get(0+vPos) * v.get(0+vPos) + - v.get(1+vPos) * v.get(1+vPos) + - v.get(2+vPos) * v.get(2+vPos)); - - if ( r == 0.0 || r == 1.0) { - return; - } - - r = 1.0f / r; - - v.put(0+vPos, v.get(0+vPos) * r); - v.put(1+vPos, v.get(1+vPos) * r); - v.put(2+vPos, v.get(2+vPos) * r); - } - - - /** - * Calculate cross-product of 2 vector - * - * @param v1 3-component vector - * @param v2 3-component vector - * @param result v1 X v2 - */ - public static final void cross(float[] v1, float[] v2, float[] result) { - result[0] = v1[1] * v2[2] - v1[2] * v2[1]; - result[1] = v1[2] * v2[0] - v1[0] * v2[2]; - result[2] = v1[0] * v2[1] - v1[1] * v2[0]; - } - - /** - * Calculate cross-product of 2 vector - * - * @param v1 3-component vector - * @param v2 3-component vector - * @param result v1 X v2 - */ - public static final void cross(FloatBuffer v1, FloatBuffer v2, FloatBuffer result) { - final int v1Pos = v1.position(); - final int v2Pos = v2.position(); - final int rPos = result.position(); - - result.put(0+rPos, v1.get(1+v1Pos) * v2.get(2+v2Pos) - v1.get(2+v1Pos) * v2.get(1+v2Pos)); - result.put(1+rPos, v1.get(2+v1Pos) * v2.get(0+v2Pos) - v1.get(0+v1Pos) * v2.get(2+v2Pos)); - result.put(2+rPos, v1.get(0+v1Pos) * v2.get(1+v2Pos) - v1.get(1+v1Pos) * v2.get(0+v2Pos)); - } - - /** - * @param m_in 4x4 matrix in column-major order - * @param m_in_off - * @param v_in 4-component column-vector - * @param v_out m_in * v_in - */ - public static final void multMatrixVecf(float[] m_in, int m_in_off, float[] v_in, int v_in_off, float[] v_out, int v_out_off) { - for (int i = 0; i < 4; i++) { - // (one matrix row in column-major order) X (column vector) - v_out[i + v_out_off] = - v_in[0+v_in_off] * m_in[0*4+i+m_in_off] + - v_in[1+v_in_off] * m_in[1*4+i+m_in_off] + - v_in[2+v_in_off] * m_in[2*4+i+m_in_off] + - v_in[3+v_in_off] * m_in[3*4+i+m_in_off]; - } - } - - /** - * @param m_in 4x4 matrix in column-major order - * @param m_in_off - * @param v_in 4-component column-vector - * @param v_out m_in * v_in - */ - public static final void multMatrixVecf(float[] m_in, float[] v_in, float[] v_out) { - for (int i = 0; i < 4; i++) { - // (one matrix row in column-major order) X (column vector) - v_out[i] = - v_in[0] * m_in[0*4+i] + - v_in[1] * m_in[1*4+i] + - v_in[2] * m_in[2*4+i] + - v_in[3] * m_in[3*4+i]; - } - } - - /** - * @param m_in 4x4 matrix in column-major order - * @param v_in 4-component column-vector - * @param v_out m_in * v_in - */ - public static final void multMatrixVecf(FloatBuffer m_in, float[] v_in, int v_in_off, float[] v_out, int v_out_off) { - final int matrixPos = m_in.position(); - for (int i = 0; i < 4; i++) { - // (one matrix row in column-major order) X (column vector) - v_out[i+v_out_off] = - v_in[0+v_in_off] * m_in.get(0*4+i+matrixPos) + - v_in[1+v_in_off] * m_in.get(1*4+i+matrixPos) + - v_in[2+v_in_off] * m_in.get(2*4+i+matrixPos) + - v_in[3+v_in_off] * m_in.get(3*4+i+matrixPos); - } - } - - /** - * @param m_in 4x4 matrix in column-major order - * @param v_in 4-component column-vector - * @param v_out m_in * v_in - */ - public static final void multMatrixVecf(FloatBuffer m_in, float[] v_in, float[] v_out) { - final int matrixPos = m_in.position(); - for (int i = 0; i < 4; i++) { - // (one matrix row in column-major order) X (column vector) - v_out[i] = - v_in[0] * m_in.get(0*4+i+matrixPos) + - v_in[1] * m_in.get(1*4+i+matrixPos) + - v_in[2] * m_in.get(2*4+i+matrixPos) + - v_in[3] * m_in.get(3*4+i+matrixPos); - } - } - - /** - * @param m_in 4x4 matrix in column-major order - * @param v_in 4-component column-vector - * @param v_out m_in * v_in - */ - public static final void multMatrixVecf(FloatBuffer m_in, FloatBuffer v_in, FloatBuffer v_out) { - final int inPos = v_in.position(); - final int outPos = v_out.position(); - final int matrixPos = m_in.position(); - for (int i = 0; i < 4; i++) { - // (one matrix row in column-major order) X (column vector) - v_out.put(i + outPos, - v_in.get(0+inPos) * m_in.get(0*4+i+matrixPos) + - v_in.get(1+inPos) * m_in.get(1*4+i+matrixPos) + - v_in.get(2+inPos) * m_in.get(2*4+i+matrixPos) + - v_in.get(3+inPos) * m_in.get(3*4+i+matrixPos)); - } - } - - /** - * @param sb optional passed StringBuilder instance to be used - * @param f the format string of one floating point, i.e. "%10.5f", see {@link java.util.Formatter} - * @param a mxn matrix (rows x columns) - * @param aOffset offset toa
's current position
- * @param rows
- * @param columns
- * @param rowMajorOrder if true floats are layed out in row-major-order, otherwise column-major-order (OpenGL)
- * @param row row number to print
- * @return matrix row string representation
- */
- public static StringBuilder matrixRowToString(StringBuilder sb, String f, FloatBuffer a, int aOffset, int rows, int columns, boolean rowMajorOrder, int row) {
- if(null == sb) {
- sb = new StringBuilder();
- }
- final int a0 = aOffset + a.position();
- if(rowMajorOrder) {
- for(int c=0; ca
's current position
- * @param rows
- * @param columns
- * @param rowMajorOrder if true floats are layed out in row-major-order, otherwise column-major-order (OpenGL)
- * @return side by side representation
- */
- public static StringBuilder matrixToString(StringBuilder sb, String rowPrefix, String f, FloatBuffer a, int aOffset, FloatBuffer b, int bOffset, int rows, int columns, boolean rowMajorOrder) {
- if(null == sb) {
- sb = new StringBuilder();
- }
- final String prefix = ( null == rowPrefix ) ? "" : rowPrefix;
- for(int i=0; i+ * Implementation assumes linear matrix layout in column-major order + * matching OpenGL's implementation. + *
+ *+ * Derived from ProjectFloat.java - Created 11-jan-2004 + *
+ * + * @author Erik Duijs + * @author Kenneth Russell + * @author Sven Gothel + */ +public class FloatUtil { + private static final float[] IDENTITY_MATRIX = + new float[] { + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f }; + + private static final float[] ZERO_MATRIX = + new float[] { + 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f }; + + /** + * Make matrix an identity matrix + */ + public static final void makeIdentityf(float[] m, int offset) { + for (int i = 0; i < 16; i++) { + m[i+offset] = IDENTITY_MATRIX[i]; + } + } + + /** + * Make matrix an identity matrix + */ + public static final void makeIdentityf(FloatBuffer m) { + final int oldPos = m.position(); + m.put(IDENTITY_MATRIX); + m.position(oldPos); + } + + /** + * Make matrix an zero matrix + */ + public static final void makeZero(float[] m, int offset) { + for (int i = 0; i < 16; i++) { + m[i+offset] = 0; + } + } + + /** + * Make matrix an zero matrix + */ + public static final void makeZero(FloatBuffer m) { + final int oldPos = m.position(); + m.put(ZERO_MATRIX); + m.position(oldPos); + } + + /** + * @param a 4x4 matrix in column-major order + * @param b 4x4 matrix in column-major order + * @param d result a*b in column-major order + */ + public static final void multMatrixf(final float[] a, int a_off, final float[] b, int b_off, float[] d, int d_off) { + for (int i = 0; i < 4; i++) { + // one row in column-major order + final float ai0=a[a_off+i+0*4], ai1=a[a_off+i+1*4], ai2=a[a_off+i+2*4], ai3=a[a_off+i+3*4]; // row-i of a + d[d_off+i+0*4] = ai0 * b[b_off+0+0*4] + ai1 * b[b_off+1+0*4] + ai2 * b[b_off+2+0*4] + ai3 * b[b_off+3+0*4] ; + d[d_off+i+1*4] = ai0 * b[b_off+0+1*4] + ai1 * b[b_off+1+1*4] + ai2 * b[b_off+2+1*4] + ai3 * b[b_off+3+1*4] ; + d[d_off+i+2*4] = ai0 * b[b_off+0+2*4] + ai1 * b[b_off+1+2*4] + ai2 * b[b_off+2+2*4] + ai3 * b[b_off+3+2*4] ; + d[d_off+i+3*4] = ai0 * b[b_off+0+3*4] + ai1 * b[b_off+1+3*4] + ai2 * b[b_off+2+3*4] + ai3 * b[b_off+3+3*4] ; + } + } + + /** + * @param a 4x4 matrix in column-major order + * @param b 4x4 matrix in column-major order + * @param d result a*b in column-major order + */ + public static final void multMatrixf(final float[] a, int a_off, final float[] b, int b_off, FloatBuffer d) { + final int dP = d.position(); + for (int i = 0; i < 4; i++) { + // one row in column-major order + final float ai0=a[a_off+i+0*4], ai1=a[a_off+i+1*4], ai2=a[a_off+i+2*4], ai3=a[a_off+i+3*4]; // row-i of a + d.put(dP+i+0*4 , ai0 * b[b_off+0+0*4] + ai1 * b[b_off+1+0*4] + ai2 * b[b_off+2+0*4] + ai3 * b[b_off+3+0*4] ); + d.put(dP+i+1*4 , ai0 * b[b_off+0+1*4] + ai1 * b[b_off+1+1*4] + ai2 * b[b_off+2+1*4] + ai3 * b[b_off+3+1*4] ); + d.put(dP+i+2*4 , ai0 * b[b_off+0+2*4] + ai1 * b[b_off+1+2*4] + ai2 * b[b_off+2+2*4] + ai3 * b[b_off+3+2*4] ); + d.put(dP+i+3*4 , ai0 * b[b_off+0+3*4] + ai1 * b[b_off+1+3*4] + ai2 * b[b_off+2+3*4] + ai3 * b[b_off+3+3*4] ); + } + } + + /** + * @param a 4x4 matrix in column-major order + * @param b 4x4 matrix in column-major order + * @param d result a*b in column-major order + */ + public static final void multMatrixf(final FloatBuffer a, final float[] b, int b_off, FloatBuffer d) { + final int aP = a.position(); + final int dP = d.position(); + for (int i = 0; i < 4; i++) { + // one row in column-major order + final float ai0=a.get(aP+i+0*4), ai1=a.get(aP+i+1*4), ai2=a.get(aP+i+2*4), ai3=a.get(aP+i+3*4); // row-i of a + d.put(dP+i+0*4 , ai0 * b[b_off+0+0*4] + ai1 * b[b_off+1+0*4] + ai2 * b[b_off+2+0*4] + ai3 * b[b_off+3+0*4] ); + d.put(dP+i+1*4 , ai0 * b[b_off+0+1*4] + ai1 * b[b_off+1+1*4] + ai2 * b[b_off+2+1*4] + ai3 * b[b_off+3+1*4] ); + d.put(dP+i+2*4 , ai0 * b[b_off+0+2*4] + ai1 * b[b_off+1+2*4] + ai2 * b[b_off+2+2*4] + ai3 * b[b_off+3+2*4] ); + d.put(dP+i+3*4 , ai0 * b[b_off+0+3*4] + ai1 * b[b_off+1+3*4] + ai2 * b[b_off+2+3*4] + ai3 * b[b_off+3+3*4] ); + } + } + + /** + * @param a 4x4 matrix in column-major order + * @param b 4x4 matrix in column-major order + * @param d result a*b in column-major order + */ + public static final void multMatrixf(final FloatBuffer a, final FloatBuffer b, FloatBuffer d) { + final int aP = a.position(); + final int bP = b.position(); + final int dP = d.position(); + for (int i = 0; i < 4; i++) { + // one row in column-major order + final float ai0=a.get(aP+i+0*4), ai1=a.get(aP+i+1*4), ai2=a.get(aP+i+2*4), ai3=a.get(aP+i+3*4); // row-i of a + d.put(dP+i+0*4 , ai0 * b.get(bP+0+0*4) + ai1 * b.get(bP+1+0*4) + ai2 * b.get(bP+2+0*4) + ai3 * b.get(bP+3+0*4) ); + d.put(dP+i+1*4 , ai0 * b.get(bP+0+1*4) + ai1 * b.get(bP+1+1*4) + ai2 * b.get(bP+2+1*4) + ai3 * b.get(bP+3+1*4) ); + d.put(dP+i+2*4 , ai0 * b.get(bP+0+2*4) + ai1 * b.get(bP+1+2*4) + ai2 * b.get(bP+2+2*4) + ai3 * b.get(bP+3+2*4) ); + d.put(dP+i+3*4 , ai0 * b.get(bP+0+3*4) + ai1 * b.get(bP+1+3*4) + ai2 * b.get(bP+2+3*4) + ai3 * b.get(bP+3+3*4) ); + } + } + + /** + * @param a 4x4 matrix in column-major order + * @param b 4x4 matrix in column-major order + * @param d result a*b in column-major order + */ + public static final void multMatrixf(final FloatBuffer a, final FloatBuffer b, float[] d, int d_off) { + final int aP = a.position(); + final int bP = b.position(); + for (int i = 0; i < 4; i++) { + // one row in column-major order + final float ai0=a.get(aP+i+0*4), ai1=a.get(aP+i+1*4), ai2=a.get(aP+i+2*4), ai3=a.get(aP+i+3*4); // row-i of a + d[d_off+i+0*4] = ai0 * b.get(bP+0+0*4) + ai1 * b.get(bP+1+0*4) + ai2 * b.get(bP+2+0*4) + ai3 * b.get(bP+3+0*4) ; + d[d_off+i+1*4] = ai0 * b.get(bP+0+1*4) + ai1 * b.get(bP+1+1*4) + ai2 * b.get(bP+2+1*4) + ai3 * b.get(bP+3+1*4) ; + d[d_off+i+2*4] = ai0 * b.get(bP+0+2*4) + ai1 * b.get(bP+1+2*4) + ai2 * b.get(bP+2+2*4) + ai3 * b.get(bP+3+2*4) ; + d[d_off+i+3*4] = ai0 * b.get(bP+0+3*4) + ai1 * b.get(bP+1+3*4) + ai2 * b.get(bP+2+3*4) + ai3 * b.get(bP+3+3*4) ; + } + } + + /** + * Normalize vector + * + * @param v makes len(v)==1 + */ + public static final void normalize(float[] v) { + float r = (float) Math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); + + if ( r == 0.0 || r == 1.0) { + return; + } + + r = 1.0f / r; + + v[0] *= r; + v[1] *= r; + v[2] *= r; + } + + /** + * Normalize vector + * + * @param v makes len(v)==1 + */ + public static final void normalize(FloatBuffer v) { + final int vPos = v.position(); + + float r = (float) Math.sqrt(v.get(0+vPos) * v.get(0+vPos) + + v.get(1+vPos) * v.get(1+vPos) + + v.get(2+vPos) * v.get(2+vPos)); + + if ( r == 0.0 || r == 1.0) { + return; + } + + r = 1.0f / r; + + v.put(0+vPos, v.get(0+vPos) * r); + v.put(1+vPos, v.get(1+vPos) * r); + v.put(2+vPos, v.get(2+vPos) * r); + } + + + /** + * Calculate cross-product of 2 vector + * + * @param v1 3-component vector + * @param v2 3-component vector + * @param result v1 X v2 + */ + public static final void cross(float[] v1, float[] v2, float[] result) { + result[0] = v1[1] * v2[2] - v1[2] * v2[1]; + result[1] = v1[2] * v2[0] - v1[0] * v2[2]; + result[2] = v1[0] * v2[1] - v1[1] * v2[0]; + } + + /** + * Calculate cross-product of 2 vector + * + * @param v1 3-component vector + * @param v2 3-component vector + * @param result v1 X v2 + */ + public static final void cross(FloatBuffer v1, FloatBuffer v2, FloatBuffer result) { + final int v1Pos = v1.position(); + final int v2Pos = v2.position(); + final int rPos = result.position(); + + result.put(0+rPos, v1.get(1+v1Pos) * v2.get(2+v2Pos) - v1.get(2+v1Pos) * v2.get(1+v2Pos)); + result.put(1+rPos, v1.get(2+v1Pos) * v2.get(0+v2Pos) - v1.get(0+v1Pos) * v2.get(2+v2Pos)); + result.put(2+rPos, v1.get(0+v1Pos) * v2.get(1+v2Pos) - v1.get(1+v1Pos) * v2.get(0+v2Pos)); + } + + /** + * @param m_in 4x4 matrix in column-major order + * @param m_in_off + * @param v_in 4-component column-vector + * @param v_out m_in * v_in + */ + public static final void multMatrixVecf(float[] m_in, int m_in_off, float[] v_in, int v_in_off, float[] v_out, int v_out_off) { + for (int i = 0; i < 4; i++) { + // (one matrix row in column-major order) X (column vector) + v_out[i + v_out_off] = + v_in[0+v_in_off] * m_in[0*4+i+m_in_off] + + v_in[1+v_in_off] * m_in[1*4+i+m_in_off] + + v_in[2+v_in_off] * m_in[2*4+i+m_in_off] + + v_in[3+v_in_off] * m_in[3*4+i+m_in_off]; + } + } + + /** + * @param m_in 4x4 matrix in column-major order + * @param m_in_off + * @param v_in 4-component column-vector + * @param v_out m_in * v_in + */ + public static final void multMatrixVecf(float[] m_in, float[] v_in, float[] v_out) { + for (int i = 0; i < 4; i++) { + // (one matrix row in column-major order) X (column vector) + v_out[i] = + v_in[0] * m_in[0*4+i] + + v_in[1] * m_in[1*4+i] + + v_in[2] * m_in[2*4+i] + + v_in[3] * m_in[3*4+i]; + } + } + + /** + * @param m_in 4x4 matrix in column-major order + * @param v_in 4-component column-vector + * @param v_out m_in * v_in + */ + public static final void multMatrixVecf(FloatBuffer m_in, float[] v_in, int v_in_off, float[] v_out, int v_out_off) { + final int matrixPos = m_in.position(); + for (int i = 0; i < 4; i++) { + // (one matrix row in column-major order) X (column vector) + v_out[i+v_out_off] = + v_in[0+v_in_off] * m_in.get(0*4+i+matrixPos) + + v_in[1+v_in_off] * m_in.get(1*4+i+matrixPos) + + v_in[2+v_in_off] * m_in.get(2*4+i+matrixPos) + + v_in[3+v_in_off] * m_in.get(3*4+i+matrixPos); + } + } + + /** + * @param m_in 4x4 matrix in column-major order + * @param v_in 4-component column-vector + * @param v_out m_in * v_in + */ + public static final void multMatrixVecf(FloatBuffer m_in, float[] v_in, float[] v_out) { + final int matrixPos = m_in.position(); + for (int i = 0; i < 4; i++) { + // (one matrix row in column-major order) X (column vector) + v_out[i] = + v_in[0] * m_in.get(0*4+i+matrixPos) + + v_in[1] * m_in.get(1*4+i+matrixPos) + + v_in[2] * m_in.get(2*4+i+matrixPos) + + v_in[3] * m_in.get(3*4+i+matrixPos); + } + } + + /** + * @param m_in 4x4 matrix in column-major order + * @param v_in 4-component column-vector + * @param v_out m_in * v_in + */ + public static final void multMatrixVecf(FloatBuffer m_in, FloatBuffer v_in, FloatBuffer v_out) { + final int inPos = v_in.position(); + final int outPos = v_out.position(); + final int matrixPos = m_in.position(); + for (int i = 0; i < 4; i++) { + // (one matrix row in column-major order) X (column vector) + v_out.put(i + outPos, + v_in.get(0+inPos) * m_in.get(0*4+i+matrixPos) + + v_in.get(1+inPos) * m_in.get(1*4+i+matrixPos) + + v_in.get(2+inPos) * m_in.get(2*4+i+matrixPos) + + v_in.get(3+inPos) * m_in.get(3*4+i+matrixPos)); + } + } + + /** + * @param sb optional passed StringBuilder instance to be used + * @param f the format string of one floating point, i.e. "%10.5f", see {@link java.util.Formatter} + * @param a mxn matrix (rows x columns) + * @param aOffset offset toa
's current position
+ * @param rows
+ * @param columns
+ * @param rowMajorOrder if true floats are layed out in row-major-order, otherwise column-major-order (OpenGL)
+ * @param row row number to print
+ * @return matrix row string representation
+ */
+ public static StringBuilder matrixRowToString(StringBuilder sb, String f, FloatBuffer a, int aOffset, int rows, int columns, boolean rowMajorOrder, int row) {
+ if(null == sb) {
+ sb = new StringBuilder();
+ }
+ final int a0 = aOffset + a.position();
+ if(rowMajorOrder) {
+ for(int c=0; ca
's current position
+ * @param rows
+ * @param columns
+ * @param rowMajorOrder if true floats are layed out in row-major-order, otherwise column-major-order (OpenGL)
+ * @return side by side representation
+ */
+ public static StringBuilder matrixToString(StringBuilder sb, String rowPrefix, String f, FloatBuffer a, int aOffset, FloatBuffer b, int bOffset, int rows, int columns, boolean rowMajorOrder) {
+ if(null == sb) {
+ sb = new StringBuilder();
+ }
+ final String prefix = ( null == rowPrefix ) ? "" : rowPrefix;
+ for(int i=0; ia
's current position
+ * @param rows
+ * @param columns
+ * @param rowMajorOrder if true floats are layed out in row-major-order, otherwise column-major-order (OpenGL)
+ * @return side by side representation
+ */
+ public static StringBuilder matrixToString(StringBuilder sb, String rowPrefix, String f, float[] a, int aOffset, float[] b, int bOffset, int rows, int columns, boolean rowMajorOrder) {
+ if(null == sb) {
+ sb = new StringBuilder();
+ }
+ final String prefix = ( null == rowPrefix ) ? "" : rowPrefix;
+ for(int i=0; iROOT_DELTA
they are double
+ */
+ static final float ROOT_DELTA = (float) 1E-10;
+
+ /**
+ * Rectangle cross segment
+ */
+ public static final int CROSSING = 255;
+
+ /**
+ * Unknown crossing result
+ */
+ static final int UNKNOWN = 254;
+
+ /**
+ * Solves quadratic equation
+ * @param eqn - the coefficients of the equation
+ * @param res - the roots of the equation
+ * @return a number of roots
+ */
+ public static int solveQuad(float eqn[], float res[]) {
+ float a = eqn[2];
+ float b = eqn[1];
+ float c = eqn[0];
+ int rc = 0;
+ if (a == 0.0) {
+ if (b == 0.0) {
+ return -1;
+ }
+ res[rc++] = -c / b;
+ } else {
+ float d = b * b - 4.0f * a * c;
+ // d < 0.0
+ if (d < 0.0) {
+ return 0;
+ }
+ d = FloatUtil.sqrt(d);
+ res[rc++] = (- b + d) / (a * 2.0f);
+ // d != 0.0
+ if (d != 0.0) {
+ res[rc++] = (- b - d) / (a * 2.0f);
+ }
+ }
+ return fixRoots(res, rc);
+ }
+
+ /**
+ * Solves cubic equation
+ * @param eqn - the coefficients of the equation
+ * @param res - the roots of the equation
+ * @return a number of roots
+ */
+ public static int solveCubic(float eqn[], float res[]) {
+ float d = eqn[3];
+ if (d == 0) {
+ return solveQuad(eqn, res);
+ }
+ float a = eqn[2] / d;
+ float b = eqn[1] / d;
+ float c = eqn[0] / d;
+ int rc = 0;
+
+ float Q = (a * a - 3.0f * b) / 9.0f;
+ float R = (2.0f * a * a * a - 9.0f * a * b + 27.0f * c) / 54.0f;
+ float Q3 = Q * Q * Q;
+ float R2 = R * R;
+ float n = - a / 3.0f;
+
+ if (R2 < Q3) {
+ float t = FloatUtil.acos(R / FloatUtil.sqrt(Q3)) / 3.0f;
+ float p = 2.0f * FloatUtil.PI / 3.0f;
+ float m = -2.0f * FloatUtil.sqrt(Q);
+ res[rc++] = m * FloatUtil.cos(t) + n;
+ res[rc++] = m * FloatUtil.cos(t + p) + n;
+ res[rc++] = m * FloatUtil.cos(t - p) + n;
+ } else {
+// Debug.println("R2 >= Q3 (" + R2 + "/" + Q3 + ")");
+ float A = FloatUtil.pow(FloatUtil.abs(R) + FloatUtil.sqrt(R2 - Q3), 1.0f / 3.0f);
+ if (R > 0.0) {
+ A = -A;
+ }
+// if (A == 0.0) {
+ if (-ROOT_DELTA < A && A < ROOT_DELTA) {
+ res[rc++] = n;
+ } else {
+ float B = Q / A;
+ res[rc++] = A + B + n;
+// if (R2 == Q3) {
+ float delta = R2 - Q3;
+ if (-ROOT_DELTA < delta && delta < ROOT_DELTA) {
+ res[rc++] = - (A + B) / 2.0f + n;
+ }
+ }
+
+ }
+ return fixRoots(res, rc);
+ }
+
+ /**
+ * Excludes float roots. Roots are float if they lies enough close with each other.
+ * @param res - the roots
+ * @param rc - the roots count
+ * @return new roots count
+ */
+ static int fixRoots(float res[], int rc) {
+ int tc = 0;
+ for(int i = 0; i < rc; i++) {
+ out: {
+ for(int j = i + 1; j < rc; j++) {
+ if (isZero(res[i] - res[j])) {
+ break out;
+ }
+ }
+ res[tc++] = res[i];
+ }
+ }
+ return tc;
+ }
+
+ /**
+ * QuadCurve class provides basic functionality to find curve crossing and calculating bounds
+ */
+ public static class QuadCurve {
+
+ float ax, ay, bx, by;
+ float Ax, Ay, Bx, By;
+
+ public QuadCurve(float x1, float y1, float cx, float cy, float x2, float y2) {
+ ax = x2 - x1;
+ ay = y2 - y1;
+ bx = cx - x1;
+ by = cy - y1;
+
+ Bx = bx + bx; // Bx = 2.0 * bx
+ Ax = ax - Bx; // Ax = ax - 2.0 * bx
+
+ By = by + by; // By = 2.0 * by
+ Ay = ay - By; // Ay = ay - 2.0 * by
+ }
+
+ int cross(float res[], int rc, float py1, float py2) {
+ int cross = 0;
+
+ for (int i = 0; i < rc; i++) {
+ float t = res[i];
+
+ // CURVE-OUTSIDE
+ if (t < -DELTA || t > 1 + DELTA) {
+ continue;
+ }
+ // CURVE-START
+ if (t < DELTA) {
+ if (py1 < 0.0 && (bx != 0.0 ? bx : ax - bx) < 0.0) {
+ cross--;
+ }
+ continue;
+ }
+ // CURVE-END
+ if (t > 1 - DELTA) {
+ if (py1 < ay && (ax != bx ? ax - bx : bx) > 0.0) {
+ cross++;
+ }
+ continue;
+ }
+ // CURVE-INSIDE
+ float ry = t * (t * Ay + By);
+ // ry = t * t * Ay + t * By
+ if (ry > py2) {
+ float rxt = t * Ax + bx;
+ // rxt = 2.0 * t * Ax + Bx = 2.0 * t * Ax + 2.0 * bx
+ if (rxt > -DELTA && rxt < DELTA) {
+ continue;
+ }
+ cross += rxt > 0.0 ? 1 : -1;
+ }
+ } // for
+
+ return cross;
+ }
+
+ int solvePoint(float res[], float px) {
+ float eqn[] = {-px, Bx, Ax};
+ return solveQuad(eqn, res);
+ }
+
+ int solveExtrem(float res[]) {
+ int rc = 0;
+ if (Ax != 0.0) {
+ res[rc++] = - Bx / (Ax + Ax);
+ }
+ if (Ay != 0.0) {
+ res[rc++] = - By / (Ay + Ay);
+ }
+ return rc;
+ }
+
+ int addBound(float bound[], int bc, float res[], int rc, float minX, float maxX, boolean changeId, int id) {
+ for(int i = 0; i < rc; i++) {
+ float t = res[i];
+ if (t > -DELTA && t < 1 + DELTA) {
+ float rx = t * (t * Ax + Bx);
+ if (minX <= rx && rx <= maxX) {
+ bound[bc++] = t;
+ bound[bc++] = rx;
+ bound[bc++] = t * (t * Ay + By);
+ bound[bc++] = id;
+ if (changeId) {
+ id++;
+ }
+ }
+ }
+ }
+ return bc;
+ }
+
+ }
+
+ /**
+ * CubicCurve class provides basic functionality to find curve crossing and calculating bounds
+ */
+ public static class CubicCurve {
+
+ float ax, ay, bx, by, cx, cy;
+ float Ax, Ay, Bx, By, Cx, Cy;
+ float Ax3, Bx2;
+
+ public CubicCurve(float x1, float y1, float cx1, float cy1, float cx2, float cy2, float x2, float y2) {
+ ax = x2 - x1;
+ ay = y2 - y1;
+ bx = cx1 - x1;
+ by = cy1 - y1;
+ cx = cx2 - x1;
+ cy = cy2 - y1;
+
+ Cx = bx + bx + bx; // Cx = 3.0 * bx
+ Bx = cx + cx + cx - Cx - Cx; // Bx = 3.0 * cx - 6.0 * bx
+ Ax = ax - Bx - Cx; // Ax = ax - 3.0 * cx + 3.0 * bx
+
+ Cy = by + by + by; // Cy = 3.0 * by
+ By = cy + cy + cy - Cy - Cy; // By = 3.0 * cy - 6.0 * by
+ Ay = ay - By - Cy; // Ay = ay - 3.0 * cy + 3.0 * by
+
+ Ax3 = Ax + Ax + Ax;
+ Bx2 = Bx + Bx;
+ }
+
+ int cross(float res[], int rc, float py1, float py2) {
+ int cross = 0;
+ for (int i = 0; i < rc; i++) {
+ float t = res[i];
+
+ // CURVE-OUTSIDE
+ if (t < -DELTA || t > 1 + DELTA) {
+ continue;
+ }
+ // CURVE-START
+ if (t < DELTA) {
+ if (py1 < 0.0 && (bx != 0.0 ? bx : (cx != bx ? cx - bx : ax - cx)) < 0.0) {
+ cross--;
+ }
+ continue;
+ }
+ // CURVE-END
+ if (t > 1 - DELTA) {
+ if (py1 < ay && (ax != cx ? ax - cx : (cx != bx ? cx - bx : bx)) > 0.0) {
+ cross++;
+ }
+ continue;
+ }
+ // CURVE-INSIDE
+ float ry = t * (t * (t * Ay + By) + Cy);
+ // ry = t * t * t * Ay + t * t * By + t * Cy
+ if (ry > py2) {
+ float rxt = t * (t * Ax3 + Bx2) + Cx;
+ // rxt = 3.0 * t * t * Ax + 2.0 * t * Bx + Cx
+ if (rxt > -DELTA && rxt < DELTA) {
+ rxt = t * (Ax3 + Ax3) + Bx2;
+ // rxt = 6.0 * t * Ax + 2.0 * Bx
+ if (rxt < -DELTA || rxt > DELTA) {
+ // Inflection point
+ continue;
+ }
+ rxt = ax;
+ }
+ cross += rxt > 0.0 ? 1 : -1;
+ }
+ } //for
+
+ return cross;
+ }
+
+ int solvePoint(float res[], float px) {
+ float eqn[] = {-px, Cx, Bx, Ax};
+ return solveCubic(eqn, res);
+ }
+
+ int solveExtremX(float res[]) {
+ float eqn[] = {Cx, Bx2, Ax3};
+ return solveQuad(eqn, res);
+ }
+
+ int solveExtremY(float res[]) {
+ float eqn[] = {Cy, By + By, Ay + Ay + Ay};
+ return solveQuad(eqn, res);
+ }
+
+ int addBound(float bound[], int bc, float res[], int rc, float minX, float maxX, boolean changeId, int id) {
+ for(int i = 0; i < rc; i++) {
+ float t = res[i];
+ if (t > -DELTA && t < 1 + DELTA) {
+ float rx = t * (t * (t * Ax + Bx) + Cx);
+ if (minX <= rx && rx <= maxX) {
+ bound[bc++] = t;
+ bound[bc++] = rx;
+ bound[bc++] = t * (t * (t * Ay + By) + Cy);
+ bound[bc++] = id;
+ if (changeId) {
+ id++;
+ }
+ }
+ }
+ }
+ return bc;
+ }
+
+ }
+
+ /**
+ * Returns how many times ray from point (x,y) cross line.
+ */
+ public static int crossLine(float x1, float y1, float x2, float y2, float x, float y) {
+
+ // LEFT/RIGHT/UP/EMPTY
+ if ((x < x1 && x < x2) ||
+ (x > x1 && x > x2) ||
+ (y > y1 && y > y2) ||
+ (x1 == x2))
+ {
+ return 0;
+ }
+
+ // DOWN
+ if (y < y1 && y < y2) {
+ } else {
+ // INSIDE
+ if ((y2 - y1) * (x - x1) / (x2 - x1) <= y - y1) {
+ // INSIDE-UP
+ return 0;
+ }
+ }
+
+ // START
+ if (x == x1) {
+ return x1 < x2 ? 0 : -1;
+ }
+
+ // END
+ if (x == x2) {
+ return x1 < x2 ? 1 : 0;
+ }
+
+ // INSIDE-DOWN
+ return x1 < x2 ? 1 : -1;
+ }
+
+ /**
+ * Returns how many times ray from point (x,y) cross quard curve
+ */
+ public static int crossQuad(float x1, float y1, float cx, float cy, float x2, float y2, float x, float y) {
+
+ // LEFT/RIGHT/UP/EMPTY
+ if ((x < x1 && x < cx && x < x2) ||
+ (x > x1 && x > cx && x > x2) ||
+ (y > y1 && y > cy && y > y2) ||
+ (x1 == cx && cx == x2))
+ {
+ return 0;
+ }
+
+ // DOWN
+ if (y < y1 && y < cy && y < y2 && x != x1 && x != x2) {
+ if (x1 < x2) {
+ return x1 < x && x < x2 ? 1 : 0;
+ }
+ return x2 < x && x < x1 ? -1 : 0;
+ }
+
+ // INSIDE
+ QuadCurve c = new QuadCurve(x1, y1, cx, cy, x2, y2);
+ float px = x - x1;
+ float py = y - y1;
+ float res[] = new float[3];
+ int rc = c.solvePoint(res, px);
+
+ return c.cross(res, rc, py, py);
+ }
+
+ /**
+ * Returns how many times ray from point (x,y) cross cubic curve
+ */
+ public static int crossCubic(float x1, float y1, float cx1, float cy1, float cx2, float cy2, float x2, float y2, float x, float y) {
+
+ // LEFT/RIGHT/UP/EMPTY
+ if ((x < x1 && x < cx1 && x < cx2 && x < x2) ||
+ (x > x1 && x > cx1 && x > cx2 && x > x2) ||
+ (y > y1 && y > cy1 && y > cy2 && y > y2) ||
+ (x1 == cx1 && cx1 == cx2 && cx2 == x2))
+ {
+ return 0;
+ }
+
+ // DOWN
+ if (y < y1 && y < cy1 && y < cy2 && y < y2 && x != x1 && x != x2) {
+ if (x1 < x2) {
+ return x1 < x && x < x2 ? 1 : 0;
+ }
+ return x2 < x && x < x1 ? -1 : 0;
+ }
+
+ // INSIDE
+ CubicCurve c = new CubicCurve(x1, y1, cx1, cy1, cx2, cy2, x2, y2);
+ float px = x - x1;
+ float py = y - y1;
+ float res[] = new float[3];
+ int rc = c.solvePoint(res, px);
+ return c.cross(res, rc, py, py);
+ }
+
+ /**
+ * Returns how many times ray from point (x,y) cross path
+ */
+ public static int crossPath(PathIterator p, float x, float y) {
+ int cross = 0;
+ float mx, my, cx, cy;
+ mx = my = cx = cy = 0.0f;
+ final float coords[] = new float[6];
+
+ while (!p.isDone()) {
+ final int segmentType = p.currentSegment(coords);
+ switch (segmentType) {
+ case PathIterator.SEG_MOVETO:
+ if (cx != mx || cy != my) {
+ cross += crossLine(cx, cy, mx, my, x, y);
+ }
+ mx = cx = coords[0];
+ my = cy = coords[1];
+ break;
+ case PathIterator.SEG_LINETO:
+ cross += crossLine(cx, cy, cx = coords[0], cy = coords[1], x, y);
+ break;
+ case PathIterator.SEG_QUADTO:
+ cross += crossQuad(cx, cy, coords[0], coords[1], cx = coords[2], cy = coords[3], x, y);
+ break;
+ case PathIterator.SEG_CUBICTO:
+ cross += crossCubic(cx, cy, coords[0], coords[1], coords[2], coords[3], cx = coords[4], cy = coords[5], x, y);
+ break;
+ case PathIterator.SEG_CLOSE:
+ if (cy != my || cx != mx) {
+ cross += crossLine(cx, cy, cx = mx, cy = my, x, y);
+ }
+ break;
+ default:
+ throw new IllegalArgumentException("Unhandled Segment Type: "+segmentType);
+ }
+
+ // checks if the point (x,y) is the vertex of shape with PathIterator p
+ if (x == cx && y == cy) {
+ cross = 0;
+ cy = my;
+ break;
+ }
+ p.next();
+ }
+ if (cy != my) {
+ cross += crossLine(cx, cy, mx, my, x, y);
+ }
+ return cross;
+ }
+
+ /**
+ * Returns how many times ray from point (x,y) cross shape
+ */
+ public static int crossShape(Path2D s, float x, float y) {
+ if (!s.getBounds2D().contains(x, y)) {
+ return 0;
+ }
+ return crossPath(s.iterator(null), x, y);
+ }
+
+ /**
+ * Returns true if value enough small
+ */
+ public static boolean isZero(float val) {
+ return -DELTA < val && val < DELTA;
+ }
+
+ /**
+ * Sort bound array
+ */
+ static void sortBound(float bound[], int bc) {
+ for(int i = 0; i < bc - 4; i += 4) {
+ int k = i;
+ for(int j = i + 4; j < bc; j += 4) {
+ if (bound[k] > bound[j]) {
+ k = j;
+ }
+ }
+ if (k != i) {
+ float tmp = bound[i];
+ bound[i] = bound[k];
+ bound[k] = tmp;
+ tmp = bound[i + 1];
+ bound[i + 1] = bound[k + 1];
+ bound[k + 1] = tmp;
+ tmp = bound[i + 2];
+ bound[i + 2] = bound[k + 2];
+ bound[k + 2] = tmp;
+ tmp = bound[i + 3];
+ bound[i + 3] = bound[k + 3];
+ bound[k + 3] = tmp;
+ }
+ }
+ }
+
+ /**
+ * Returns are bounds intersect or not intersect rectangle
+ */
+ static int crossBound(float bound[], int bc, float py1, float py2) {
+
+ // LEFT/RIGHT
+ if (bc == 0) {
+ return 0;
+ }
+
+ // Check Y coordinate
+ int up = 0;
+ int down = 0;
+ for(int i = 2; i < bc; i += 4) {
+ if (bound[i] < py1) {
+ up++;
+ continue;
+ }
+ if (bound[i] > py2) {
+ down++;
+ continue;
+ }
+ return CROSSING;
+ }
+
+ // UP
+ if (down == 0) {
+ return 0;
+ }
+
+ if (up != 0) {
+ // bc >= 2
+ sortBound(bound, bc);
+ boolean sign = bound[2] > py2;
+ for(int i = 6; i < bc; i += 4) {
+ boolean sign2 = bound[i] > py2;
+ if (sign != sign2 && bound[i + 1] != bound[i - 3]) {
+ return CROSSING;
+ }
+ sign = sign2;
+ }
+ }
+ return UNKNOWN;
+ }
+
+ /**
+ * Returns how many times rectangle stripe cross line or the are intersect
+ */
+ public static int intersectLine(float x1, float y1, float x2, float y2, float rx1, float ry1, float rx2, float ry2) {
+
+ // LEFT/RIGHT/UP
+ if ((rx2 < x1 && rx2 < x2) ||
+ (rx1 > x1 && rx1 > x2) ||
+ (ry1 > y1 && ry1 > y2))
+ {
+ return 0;
+ }
+
+ // DOWN
+ if (ry2 < y1 && ry2 < y2) {
+ } else {
+
+ // INSIDE
+ if (x1 == x2) {
+ return CROSSING;
+ }
+
+ // Build bound
+ float bx1, bx2;
+ if (x1 < x2) {
+ bx1 = x1 < rx1 ? rx1 : x1;
+ bx2 = x2 < rx2 ? x2 : rx2;
+ } else {
+ bx1 = x2 < rx1 ? rx1 : x2;
+ bx2 = x1 < rx2 ? x1 : rx2;
+ }
+ float k = (y2 - y1) / (x2 - x1);
+ float by1 = k * (bx1 - x1) + y1;
+ float by2 = k * (bx2 - x1) + y1;
+
+ // BOUND-UP
+ if (by1 < ry1 && by2 < ry1) {
+ return 0;
+ }
+
+ // BOUND-DOWN
+ if (by1 > ry2 && by2 > ry2) {
+ } else {
+ return CROSSING;
+ }
+ }
+
+ // EMPTY
+ if (x1 == x2) {
+ return 0;
+ }
+
+ // CURVE-START
+ if (rx1 == x1) {
+ return x1 < x2 ? 0 : -1;
+ }
+
+ // CURVE-END
+ if (rx1 == x2) {
+ return x1 < x2 ? 1 : 0;
+ }
+
+ if (x1 < x2) {
+ return x1 < rx1 && rx1 < x2 ? 1 : 0;
+ }
+ return x2 < rx1 && rx1 < x1 ? -1 : 0;
+
+ }
+
+ /**
+ * Returns how many times rectangle stripe cross quad curve or the are intersect
+ */
+ public static int intersectQuad(float x1, float y1, float cx, float cy, float x2, float y2, float rx1, float ry1, float rx2, float ry2) {
+
+ // LEFT/RIGHT/UP ------------------------------------------------------
+ if ((rx2 < x1 && rx2 < cx && rx2 < x2) ||
+ (rx1 > x1 && rx1 > cx && rx1 > x2) ||
+ (ry1 > y1 && ry1 > cy && ry1 > y2))
+ {
+ return 0;
+ }
+
+ // DOWN ---------------------------------------------------------------
+ if (ry2 < y1 && ry2 < cy && ry2 < y2 && rx1 != x1 && rx1 != x2) {
+ if (x1 < x2) {
+ return x1 < rx1 && rx1 < x2 ? 1 : 0;
+ }
+ return x2 < rx1 && rx1 < x1 ? -1 : 0;
+ }
+
+ // INSIDE -------------------------------------------------------------
+ QuadCurve c = new QuadCurve(x1, y1, cx, cy, x2, y2);
+ float px1 = rx1 - x1;
+ float py1 = ry1 - y1;
+ float px2 = rx2 - x1;
+ float py2 = ry2 - y1;
+
+ float res1[] = new float[3];
+ float res2[] = new float[3];
+ int rc1 = c.solvePoint(res1, px1);
+ int rc2 = c.solvePoint(res2, px2);
+
+ // INSIDE-LEFT/RIGHT
+ if (rc1 == 0 && rc2 == 0) {
+ return 0;
+ }
+
+ // Build bound --------------------------------------------------------
+ float minX = px1 - DELTA;
+ float maxX = px2 + DELTA;
+ float bound[] = new float[28];
+ int bc = 0;
+ // Add roots
+ bc = c.addBound(bound, bc, res1, rc1, minX, maxX, false, 0);
+ bc = c.addBound(bound, bc, res2, rc2, minX, maxX, false, 1);
+ // Add extremal points`
+ rc2 = c.solveExtrem(res2);
+ bc = c.addBound(bound, bc, res2, rc2, minX, maxX, true, 2);
+ // Add start and end
+ if (rx1 < x1 && x1 < rx2) {
+ bound[bc++] = 0.0f;
+ bound[bc++] = 0.0f;
+ bound[bc++] = 0.0f;
+ bound[bc++] = 4;
+ }
+ if (rx1 < x2 && x2 < rx2) {
+ bound[bc++] = 1.0f;
+ bound[bc++] = c.ax;
+ bound[bc++] = c.ay;
+ bound[bc++] = 5;
+ }
+ // End build bound ----------------------------------------------------
+
+ int cross = crossBound(bound, bc, py1, py2);
+ if (cross != UNKNOWN) {
+ return cross;
+ }
+ return c.cross(res1, rc1, py1, py2);
+ }
+
+ /**
+ * Returns how many times rectangle stripe cross cubic curve or the are intersect
+ */
+ public static int intersectCubic(float x1, float y1, float cx1, float cy1, float cx2, float cy2, float x2, float y2, float rx1, float ry1, float rx2, float ry2) {
+
+ // LEFT/RIGHT/UP
+ if ((rx2 < x1 && rx2 < cx1 && rx2 < cx2 && rx2 < x2) ||
+ (rx1 > x1 && rx1 > cx1 && rx1 > cx2 && rx1 > x2) ||
+ (ry1 > y1 && ry1 > cy1 && ry1 > cy2 && ry1 > y2))
+ {
+ return 0;
+ }
+
+ // DOWN
+ if (ry2 < y1 && ry2 < cy1 && ry2 < cy2 && ry2 < y2 && rx1 != x1 && rx1 != x2) {
+ if (x1 < x2) {
+ return x1 < rx1 && rx1 < x2 ? 1 : 0;
+ }
+ return x2 < rx1 && rx1 < x1 ? -1 : 0;
+ }
+
+ // INSIDE
+ CubicCurve c = new CubicCurve(x1, y1, cx1, cy1, cx2, cy2, x2, y2);
+ float px1 = rx1 - x1;
+ float py1 = ry1 - y1;
+ float px2 = rx2 - x1;
+ float py2 = ry2 - y1;
+
+ float res1[] = new float[3];
+ float res2[] = new float[3];
+ int rc1 = c.solvePoint(res1, px1);
+ int rc2 = c.solvePoint(res2, px2);
+
+ // LEFT/RIGHT
+ if (rc1 == 0 && rc2 == 0) {
+ return 0;
+ }
+
+ float minX = px1 - DELTA;
+ float maxX = px2 + DELTA;
+
+ // Build bound --------------------------------------------------------
+ float bound[] = new float[40];
+ int bc = 0;
+ // Add roots
+ bc = c.addBound(bound, bc, res1, rc1, minX, maxX, false, 0);
+ bc = c.addBound(bound, bc, res2, rc2, minX, maxX, false, 1);
+ // Add extrimal points
+ rc2 = c.solveExtremX(res2);
+ bc = c.addBound(bound, bc, res2, rc2, minX, maxX, true, 2);
+ rc2 = c.solveExtremY(res2);
+ bc = c.addBound(bound, bc, res2, rc2, minX, maxX, true, 4);
+ // Add start and end
+ if (rx1 < x1 && x1 < rx2) {
+ bound[bc++] = 0.0f;
+ bound[bc++] = 0.0f;
+ bound[bc++] = 0.0f;
+ bound[bc++] = 6;
+ }
+ if (rx1 < x2 && x2 < rx2) {
+ bound[bc++] = 1.0f;
+ bound[bc++] = c.ax;
+ bound[bc++] = c.ay;
+ bound[bc++] = 7;
+ }
+ // End build bound ----------------------------------------------------
+
+ int cross = crossBound(bound, bc, py1, py2);
+ if (cross != UNKNOWN) {
+ return cross;
+ }
+ return c.cross(res1, rc1, py1, py2);
+ }
+
+ /**
+ * Returns how many times rectangle stripe cross path or the are intersect
+ */
+ public static int intersectPath(PathIterator p, float x, float y, float w, float h) {
+
+ int cross = 0;
+ int count;
+ float mx, my, cx, cy;
+ mx = my = cx = cy = 0.0f;
+ final float coords[] = new float[6];
+
+ float rx1 = x;
+ float ry1 = y;
+ float rx2 = x + w;
+ float ry2 = y + h;
+
+ while (!p.isDone()) {
+ count = 0;
+ final int segmentType = p.currentSegment(coords);
+ switch (segmentType) {
+ case PathIterator.SEG_MOVETO:
+ if (cx != mx || cy != my) {
+ count = intersectLine(cx, cy, mx, my, rx1, ry1, rx2, ry2);
+ }
+ mx = cx = coords[0];
+ my = cy = coords[1];
+ break;
+ case PathIterator.SEG_LINETO:
+ count = intersectLine(cx, cy, cx = coords[0], cy = coords[1], rx1, ry1, rx2, ry2);
+ break;
+ case PathIterator.SEG_QUADTO:
+ count = intersectQuad(cx, cy, coords[0], coords[1], cx = coords[2], cy = coords[3], rx1, ry1, rx2, ry2);
+ break;
+ case PathIterator.SEG_CUBICTO:
+ count = intersectCubic(cx, cy, coords[0], coords[1], coords[2], coords[3], cx = coords[4], cy = coords[5], rx1, ry1, rx2, ry2);
+ break;
+ case PathIterator.SEG_CLOSE:
+ if (cy != my || cx != mx) {
+ count = intersectLine(cx, cy, mx, my, rx1, ry1, rx2, ry2);
+ }
+ cx = mx;
+ cy = my;
+ break;
+ default:
+ throw new IllegalArgumentException("Unhandled Segment Type: "+segmentType);
+ }
+ if (count == CROSSING) {
+ return CROSSING;
+ }
+ cross += count;
+ p.next();
+ }
+ if (cy != my) {
+ count = intersectLine(cx, cy, mx, my, rx1, ry1, rx2, ry2);
+ if (count == CROSSING) {
+ return CROSSING;
+ }
+ cross += count;
+ }
+ return cross;
+ }
+
+ /**
+ * Returns how many times rectangle stripe cross shape or the are intersect
+ */
+ public static int intersectShape(Path2D s, float x, float y, float w, float h) {
+ if (!s.getBounds2D().intersects(x, y, w, h)) {
+ return 0;
+ }
+ return intersectPath(s.iterator(null), x, y, w, h);
+ }
+
+ /**
+ * Returns true if cross count correspond inside location for non zero path rule
+ */
+ public static boolean isInsideNonZero(int cross) {
+ return cross != 0;
+ }
+
+ /**
+ * Returns true if cross count correspond inside location for even-odd path rule
+ */
+ public static boolean isInsideEvenOdd(int cross) {
+ return (cross & 1) != 0;
+ }
+}
diff --git a/src/jogl/classes/jogamp/graph/geom/plane/Path2D.java b/src/jogl/classes/jogamp/graph/geom/plane/Path2D.java
index c895e8351..945eeceeb 100644
--- a/src/jogl/classes/jogamp/graph/geom/plane/Path2D.java
+++ b/src/jogl/classes/jogamp/graph/geom/plane/Path2D.java
@@ -21,11 +21,10 @@ package jogamp.graph.geom.plane;
import java.util.NoSuchElementException;
-import com.jogamp.graph.geom.AABBox;
import com.jogamp.graph.geom.Vertex;
import com.jogamp.graph.geom.opengl.SVertex;
+import com.jogamp.opengl.math.geom.AABBox;
-import jogamp.graph.math.plane.Crossing;
public final class Path2D implements Cloneable {
diff --git a/src/jogl/classes/jogamp/graph/math/plane/Crossing.java b/src/jogl/classes/jogamp/graph/math/plane/Crossing.java
deleted file mode 100644
index 51d81da54..000000000
--- a/src/jogl/classes/jogamp/graph/math/plane/Crossing.java
+++ /dev/null
@@ -1,904 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-/**
- * @author Denis M. Kishenko
- */
-package jogamp.graph.math.plane;
-
-import com.jogamp.opengl.FloatUtil;
-
-import jogamp.graph.geom.plane.Path2D;
-import jogamp.graph.geom.plane.PathIterator;
-
-
-public class Crossing {
-
- /**
- * Allowable tolerance for bounds comparison
- */
- static final float DELTA = (float) 1E-5;
-
- /**
- * If roots have distance less then ROOT_DELTA
they are double
- */
- static final float ROOT_DELTA = (float) 1E-10;
-
- /**
- * Rectangle cross segment
- */
- public static final int CROSSING = 255;
-
- /**
- * Unknown crossing result
- */
- static final int UNKNOWN = 254;
-
- /**
- * Solves quadratic equation
- * @param eqn - the coefficients of the equation
- * @param res - the roots of the equation
- * @return a number of roots
- */
- public static int solveQuad(float eqn[], float res[]) {
- float a = eqn[2];
- float b = eqn[1];
- float c = eqn[0];
- int rc = 0;
- if (a == 0.0) {
- if (b == 0.0) {
- return -1;
- }
- res[rc++] = -c / b;
- } else {
- float d = b * b - 4.0f * a * c;
- // d < 0.0
- if (d < 0.0) {
- return 0;
- }
- d = FloatUtil.sqrt(d);
- res[rc++] = (- b + d) / (a * 2.0f);
- // d != 0.0
- if (d != 0.0) {
- res[rc++] = (- b - d) / (a * 2.0f);
- }
- }
- return fixRoots(res, rc);
- }
-
- /**
- * Solves cubic equation
- * @param eqn - the coefficients of the equation
- * @param res - the roots of the equation
- * @return a number of roots
- */
- public static int solveCubic(float eqn[], float res[]) {
- float d = eqn[3];
- if (d == 0) {
- return solveQuad(eqn, res);
- }
- float a = eqn[2] / d;
- float b = eqn[1] / d;
- float c = eqn[0] / d;
- int rc = 0;
-
- float Q = (a * a - 3.0f * b) / 9.0f;
- float R = (2.0f * a * a * a - 9.0f * a * b + 27.0f * c) / 54.0f;
- float Q3 = Q * Q * Q;
- float R2 = R * R;
- float n = - a / 3.0f;
-
- if (R2 < Q3) {
- float t = FloatUtil.acos(R / FloatUtil.sqrt(Q3)) / 3.0f;
- float p = 2.0f * FloatUtil.PI / 3.0f;
- float m = -2.0f * FloatUtil.sqrt(Q);
- res[rc++] = m * FloatUtil.cos(t) + n;
- res[rc++] = m * FloatUtil.cos(t + p) + n;
- res[rc++] = m * FloatUtil.cos(t - p) + n;
- } else {
-// Debug.println("R2 >= Q3 (" + R2 + "/" + Q3 + ")");
- float A = FloatUtil.pow(FloatUtil.abs(R) + FloatUtil.sqrt(R2 - Q3), 1.0f / 3.0f);
- if (R > 0.0) {
- A = -A;
- }
-// if (A == 0.0) {
- if (-ROOT_DELTA < A && A < ROOT_DELTA) {
- res[rc++] = n;
- } else {
- float B = Q / A;
- res[rc++] = A + B + n;
-// if (R2 == Q3) {
- float delta = R2 - Q3;
- if (-ROOT_DELTA < delta && delta < ROOT_DELTA) {
- res[rc++] = - (A + B) / 2.0f + n;
- }
- }
-
- }
- return fixRoots(res, rc);
- }
-
- /**
- * Excludes float roots. Roots are float if they lies enough close with each other.
- * @param res - the roots
- * @param rc - the roots count
- * @return new roots count
- */
- static int fixRoots(float res[], int rc) {
- int tc = 0;
- for(int i = 0; i < rc; i++) {
- out: {
- for(int j = i + 1; j < rc; j++) {
- if (isZero(res[i] - res[j])) {
- break out;
- }
- }
- res[tc++] = res[i];
- }
- }
- return tc;
- }
-
- /**
- * QuadCurve class provides basic functionality to find curve crossing and calculating bounds
- */
- public static class QuadCurve {
-
- float ax, ay, bx, by;
- float Ax, Ay, Bx, By;
-
- public QuadCurve(float x1, float y1, float cx, float cy, float x2, float y2) {
- ax = x2 - x1;
- ay = y2 - y1;
- bx = cx - x1;
- by = cy - y1;
-
- Bx = bx + bx; // Bx = 2.0 * bx
- Ax = ax - Bx; // Ax = ax - 2.0 * bx
-
- By = by + by; // By = 2.0 * by
- Ay = ay - By; // Ay = ay - 2.0 * by
- }
-
- int cross(float res[], int rc, float py1, float py2) {
- int cross = 0;
-
- for (int i = 0; i < rc; i++) {
- float t = res[i];
-
- // CURVE-OUTSIDE
- if (t < -DELTA || t > 1 + DELTA) {
- continue;
- }
- // CURVE-START
- if (t < DELTA) {
- if (py1 < 0.0 && (bx != 0.0 ? bx : ax - bx) < 0.0) {
- cross--;
- }
- continue;
- }
- // CURVE-END
- if (t > 1 - DELTA) {
- if (py1 < ay && (ax != bx ? ax - bx : bx) > 0.0) {
- cross++;
- }
- continue;
- }
- // CURVE-INSIDE
- float ry = t * (t * Ay + By);
- // ry = t * t * Ay + t * By
- if (ry > py2) {
- float rxt = t * Ax + bx;
- // rxt = 2.0 * t * Ax + Bx = 2.0 * t * Ax + 2.0 * bx
- if (rxt > -DELTA && rxt < DELTA) {
- continue;
- }
- cross += rxt > 0.0 ? 1 : -1;
- }
- } // for
-
- return cross;
- }
-
- int solvePoint(float res[], float px) {
- float eqn[] = {-px, Bx, Ax};
- return solveQuad(eqn, res);
- }
-
- int solveExtrem(float res[]) {
- int rc = 0;
- if (Ax != 0.0) {
- res[rc++] = - Bx / (Ax + Ax);
- }
- if (Ay != 0.0) {
- res[rc++] = - By / (Ay + Ay);
- }
- return rc;
- }
-
- int addBound(float bound[], int bc, float res[], int rc, float minX, float maxX, boolean changeId, int id) {
- for(int i = 0; i < rc; i++) {
- float t = res[i];
- if (t > -DELTA && t < 1 + DELTA) {
- float rx = t * (t * Ax + Bx);
- if (minX <= rx && rx <= maxX) {
- bound[bc++] = t;
- bound[bc++] = rx;
- bound[bc++] = t * (t * Ay + By);
- bound[bc++] = id;
- if (changeId) {
- id++;
- }
- }
- }
- }
- return bc;
- }
-
- }
-
- /**
- * CubicCurve class provides basic functionality to find curve crossing and calculating bounds
- */
- public static class CubicCurve {
-
- float ax, ay, bx, by, cx, cy;
- float Ax, Ay, Bx, By, Cx, Cy;
- float Ax3, Bx2;
-
- public CubicCurve(float x1, float y1, float cx1, float cy1, float cx2, float cy2, float x2, float y2) {
- ax = x2 - x1;
- ay = y2 - y1;
- bx = cx1 - x1;
- by = cy1 - y1;
- cx = cx2 - x1;
- cy = cy2 - y1;
-
- Cx = bx + bx + bx; // Cx = 3.0 * bx
- Bx = cx + cx + cx - Cx - Cx; // Bx = 3.0 * cx - 6.0 * bx
- Ax = ax - Bx - Cx; // Ax = ax - 3.0 * cx + 3.0 * bx
-
- Cy = by + by + by; // Cy = 3.0 * by
- By = cy + cy + cy - Cy - Cy; // By = 3.0 * cy - 6.0 * by
- Ay = ay - By - Cy; // Ay = ay - 3.0 * cy + 3.0 * by
-
- Ax3 = Ax + Ax + Ax;
- Bx2 = Bx + Bx;
- }
-
- int cross(float res[], int rc, float py1, float py2) {
- int cross = 0;
- for (int i = 0; i < rc; i++) {
- float t = res[i];
-
- // CURVE-OUTSIDE
- if (t < -DELTA || t > 1 + DELTA) {
- continue;
- }
- // CURVE-START
- if (t < DELTA) {
- if (py1 < 0.0 && (bx != 0.0 ? bx : (cx != bx ? cx - bx : ax - cx)) < 0.0) {
- cross--;
- }
- continue;
- }
- // CURVE-END
- if (t > 1 - DELTA) {
- if (py1 < ay && (ax != cx ? ax - cx : (cx != bx ? cx - bx : bx)) > 0.0) {
- cross++;
- }
- continue;
- }
- // CURVE-INSIDE
- float ry = t * (t * (t * Ay + By) + Cy);
- // ry = t * t * t * Ay + t * t * By + t * Cy
- if (ry > py2) {
- float rxt = t * (t * Ax3 + Bx2) + Cx;
- // rxt = 3.0 * t * t * Ax + 2.0 * t * Bx + Cx
- if (rxt > -DELTA && rxt < DELTA) {
- rxt = t * (Ax3 + Ax3) + Bx2;
- // rxt = 6.0 * t * Ax + 2.0 * Bx
- if (rxt < -DELTA || rxt > DELTA) {
- // Inflection point
- continue;
- }
- rxt = ax;
- }
- cross += rxt > 0.0 ? 1 : -1;
- }
- } //for
-
- return cross;
- }
-
- int solvePoint(float res[], float px) {
- float eqn[] = {-px, Cx, Bx, Ax};
- return solveCubic(eqn, res);
- }
-
- int solveExtremX(float res[]) {
- float eqn[] = {Cx, Bx2, Ax3};
- return solveQuad(eqn, res);
- }
-
- int solveExtremY(float res[]) {
- float eqn[] = {Cy, By + By, Ay + Ay + Ay};
- return solveQuad(eqn, res);
- }
-
- int addBound(float bound[], int bc, float res[], int rc, float minX, float maxX, boolean changeId, int id) {
- for(int i = 0; i < rc; i++) {
- float t = res[i];
- if (t > -DELTA && t < 1 + DELTA) {
- float rx = t * (t * (t * Ax + Bx) + Cx);
- if (minX <= rx && rx <= maxX) {
- bound[bc++] = t;
- bound[bc++] = rx;
- bound[bc++] = t * (t * (t * Ay + By) + Cy);
- bound[bc++] = id;
- if (changeId) {
- id++;
- }
- }
- }
- }
- return bc;
- }
-
- }
-
- /**
- * Returns how many times ray from point (x,y) cross line.
- */
- public static int crossLine(float x1, float y1, float x2, float y2, float x, float y) {
-
- // LEFT/RIGHT/UP/EMPTY
- if ((x < x1 && x < x2) ||
- (x > x1 && x > x2) ||
- (y > y1 && y > y2) ||
- (x1 == x2))
- {
- return 0;
- }
-
- // DOWN
- if (y < y1 && y < y2) {
- } else {
- // INSIDE
- if ((y2 - y1) * (x - x1) / (x2 - x1) <= y - y1) {
- // INSIDE-UP
- return 0;
- }
- }
-
- // START
- if (x == x1) {
- return x1 < x2 ? 0 : -1;
- }
-
- // END
- if (x == x2) {
- return x1 < x2 ? 1 : 0;
- }
-
- // INSIDE-DOWN
- return x1 < x2 ? 1 : -1;
- }
-
- /**
- * Returns how many times ray from point (x,y) cross quard curve
- */
- public static int crossQuad(float x1, float y1, float cx, float cy, float x2, float y2, float x, float y) {
-
- // LEFT/RIGHT/UP/EMPTY
- if ((x < x1 && x < cx && x < x2) ||
- (x > x1 && x > cx && x > x2) ||
- (y > y1 && y > cy && y > y2) ||
- (x1 == cx && cx == x2))
- {
- return 0;
- }
-
- // DOWN
- if (y < y1 && y < cy && y < y2 && x != x1 && x != x2) {
- if (x1 < x2) {
- return x1 < x && x < x2 ? 1 : 0;
- }
- return x2 < x && x < x1 ? -1 : 0;
- }
-
- // INSIDE
- QuadCurve c = new QuadCurve(x1, y1, cx, cy, x2, y2);
- float px = x - x1;
- float py = y - y1;
- float res[] = new float[3];
- int rc = c.solvePoint(res, px);
-
- return c.cross(res, rc, py, py);
- }
-
- /**
- * Returns how many times ray from point (x,y) cross cubic curve
- */
- public static int crossCubic(float x1, float y1, float cx1, float cy1, float cx2, float cy2, float x2, float y2, float x, float y) {
-
- // LEFT/RIGHT/UP/EMPTY
- if ((x < x1 && x < cx1 && x < cx2 && x < x2) ||
- (x > x1 && x > cx1 && x > cx2 && x > x2) ||
- (y > y1 && y > cy1 && y > cy2 && y > y2) ||
- (x1 == cx1 && cx1 == cx2 && cx2 == x2))
- {
- return 0;
- }
-
- // DOWN
- if (y < y1 && y < cy1 && y < cy2 && y < y2 && x != x1 && x != x2) {
- if (x1 < x2) {
- return x1 < x && x < x2 ? 1 : 0;
- }
- return x2 < x && x < x1 ? -1 : 0;
- }
-
- // INSIDE
- CubicCurve c = new CubicCurve(x1, y1, cx1, cy1, cx2, cy2, x2, y2);
- float px = x - x1;
- float py = y - y1;
- float res[] = new float[3];
- int rc = c.solvePoint(res, px);
- return c.cross(res, rc, py, py);
- }
-
- /**
- * Returns how many times ray from point (x,y) cross path
- */
- public static int crossPath(PathIterator p, float x, float y) {
- int cross = 0;
- float mx, my, cx, cy;
- mx = my = cx = cy = 0.0f;
- final float coords[] = new float[6];
-
- while (!p.isDone()) {
- final int segmentType = p.currentSegment(coords);
- switch (segmentType) {
- case PathIterator.SEG_MOVETO:
- if (cx != mx || cy != my) {
- cross += crossLine(cx, cy, mx, my, x, y);
- }
- mx = cx = coords[0];
- my = cy = coords[1];
- break;
- case PathIterator.SEG_LINETO:
- cross += crossLine(cx, cy, cx = coords[0], cy = coords[1], x, y);
- break;
- case PathIterator.SEG_QUADTO:
- cross += crossQuad(cx, cy, coords[0], coords[1], cx = coords[2], cy = coords[3], x, y);
- break;
- case PathIterator.SEG_CUBICTO:
- cross += crossCubic(cx, cy, coords[0], coords[1], coords[2], coords[3], cx = coords[4], cy = coords[5], x, y);
- break;
- case PathIterator.SEG_CLOSE:
- if (cy != my || cx != mx) {
- cross += crossLine(cx, cy, cx = mx, cy = my, x, y);
- }
- break;
- default:
- throw new IllegalArgumentException("Unhandled Segment Type: "+segmentType);
- }
-
- // checks if the point (x,y) is the vertex of shape with PathIterator p
- if (x == cx && y == cy) {
- cross = 0;
- cy = my;
- break;
- }
- p.next();
- }
- if (cy != my) {
- cross += crossLine(cx, cy, mx, my, x, y);
- }
- return cross;
- }
-
- /**
- * Returns how many times ray from point (x,y) cross shape
- */
- public static int crossShape(Path2D s, float x, float y) {
- if (!s.getBounds2D().contains(x, y)) {
- return 0;
- }
- return crossPath(s.iterator(null), x, y);
- }
-
- /**
- * Returns true if value enough small
- */
- public static boolean isZero(float val) {
- return -DELTA < val && val < DELTA;
- }
-
- /**
- * Sort bound array
- */
- static void sortBound(float bound[], int bc) {
- for(int i = 0; i < bc - 4; i += 4) {
- int k = i;
- for(int j = i + 4; j < bc; j += 4) {
- if (bound[k] > bound[j]) {
- k = j;
- }
- }
- if (k != i) {
- float tmp = bound[i];
- bound[i] = bound[k];
- bound[k] = tmp;
- tmp = bound[i + 1];
- bound[i + 1] = bound[k + 1];
- bound[k + 1] = tmp;
- tmp = bound[i + 2];
- bound[i + 2] = bound[k + 2];
- bound[k + 2] = tmp;
- tmp = bound[i + 3];
- bound[i + 3] = bound[k + 3];
- bound[k + 3] = tmp;
- }
- }
- }
-
- /**
- * Returns are bounds intersect or not intersect rectangle
- */
- static int crossBound(float bound[], int bc, float py1, float py2) {
-
- // LEFT/RIGHT
- if (bc == 0) {
- return 0;
- }
-
- // Check Y coordinate
- int up = 0;
- int down = 0;
- for(int i = 2; i < bc; i += 4) {
- if (bound[i] < py1) {
- up++;
- continue;
- }
- if (bound[i] > py2) {
- down++;
- continue;
- }
- return CROSSING;
- }
-
- // UP
- if (down == 0) {
- return 0;
- }
-
- if (up != 0) {
- // bc >= 2
- sortBound(bound, bc);
- boolean sign = bound[2] > py2;
- for(int i = 6; i < bc; i += 4) {
- boolean sign2 = bound[i] > py2;
- if (sign != sign2 && bound[i + 1] != bound[i - 3]) {
- return CROSSING;
- }
- sign = sign2;
- }
- }
- return UNKNOWN;
- }
-
- /**
- * Returns how many times rectangle stripe cross line or the are intersect
- */
- public static int intersectLine(float x1, float y1, float x2, float y2, float rx1, float ry1, float rx2, float ry2) {
-
- // LEFT/RIGHT/UP
- if ((rx2 < x1 && rx2 < x2) ||
- (rx1 > x1 && rx1 > x2) ||
- (ry1 > y1 && ry1 > y2))
- {
- return 0;
- }
-
- // DOWN
- if (ry2 < y1 && ry2 < y2) {
- } else {
-
- // INSIDE
- if (x1 == x2) {
- return CROSSING;
- }
-
- // Build bound
- float bx1, bx2;
- if (x1 < x2) {
- bx1 = x1 < rx1 ? rx1 : x1;
- bx2 = x2 < rx2 ? x2 : rx2;
- } else {
- bx1 = x2 < rx1 ? rx1 : x2;
- bx2 = x1 < rx2 ? x1 : rx2;
- }
- float k = (y2 - y1) / (x2 - x1);
- float by1 = k * (bx1 - x1) + y1;
- float by2 = k * (bx2 - x1) + y1;
-
- // BOUND-UP
- if (by1 < ry1 && by2 < ry1) {
- return 0;
- }
-
- // BOUND-DOWN
- if (by1 > ry2 && by2 > ry2) {
- } else {
- return CROSSING;
- }
- }
-
- // EMPTY
- if (x1 == x2) {
- return 0;
- }
-
- // CURVE-START
- if (rx1 == x1) {
- return x1 < x2 ? 0 : -1;
- }
-
- // CURVE-END
- if (rx1 == x2) {
- return x1 < x2 ? 1 : 0;
- }
-
- if (x1 < x2) {
- return x1 < rx1 && rx1 < x2 ? 1 : 0;
- }
- return x2 < rx1 && rx1 < x1 ? -1 : 0;
-
- }
-
- /**
- * Returns how many times rectangle stripe cross quad curve or the are intersect
- */
- public static int intersectQuad(float x1, float y1, float cx, float cy, float x2, float y2, float rx1, float ry1, float rx2, float ry2) {
-
- // LEFT/RIGHT/UP ------------------------------------------------------
- if ((rx2 < x1 && rx2 < cx && rx2 < x2) ||
- (rx1 > x1 && rx1 > cx && rx1 > x2) ||
- (ry1 > y1 && ry1 > cy && ry1 > y2))
- {
- return 0;
- }
-
- // DOWN ---------------------------------------------------------------
- if (ry2 < y1 && ry2 < cy && ry2 < y2 && rx1 != x1 && rx1 != x2) {
- if (x1 < x2) {
- return x1 < rx1 && rx1 < x2 ? 1 : 0;
- }
- return x2 < rx1 && rx1 < x1 ? -1 : 0;
- }
-
- // INSIDE -------------------------------------------------------------
- QuadCurve c = new QuadCurve(x1, y1, cx, cy, x2, y2);
- float px1 = rx1 - x1;
- float py1 = ry1 - y1;
- float px2 = rx2 - x1;
- float py2 = ry2 - y1;
-
- float res1[] = new float[3];
- float res2[] = new float[3];
- int rc1 = c.solvePoint(res1, px1);
- int rc2 = c.solvePoint(res2, px2);
-
- // INSIDE-LEFT/RIGHT
- if (rc1 == 0 && rc2 == 0) {
- return 0;
- }
-
- // Build bound --------------------------------------------------------
- float minX = px1 - DELTA;
- float maxX = px2 + DELTA;
- float bound[] = new float[28];
- int bc = 0;
- // Add roots
- bc = c.addBound(bound, bc, res1, rc1, minX, maxX, false, 0);
- bc = c.addBound(bound, bc, res2, rc2, minX, maxX, false, 1);
- // Add extremal points`
- rc2 = c.solveExtrem(res2);
- bc = c.addBound(bound, bc, res2, rc2, minX, maxX, true, 2);
- // Add start and end
- if (rx1 < x1 && x1 < rx2) {
- bound[bc++] = 0.0f;
- bound[bc++] = 0.0f;
- bound[bc++] = 0.0f;
- bound[bc++] = 4;
- }
- if (rx1 < x2 && x2 < rx2) {
- bound[bc++] = 1.0f;
- bound[bc++] = c.ax;
- bound[bc++] = c.ay;
- bound[bc++] = 5;
- }
- // End build bound ----------------------------------------------------
-
- int cross = crossBound(bound, bc, py1, py2);
- if (cross != UNKNOWN) {
- return cross;
- }
- return c.cross(res1, rc1, py1, py2);
- }
-
- /**
- * Returns how many times rectangle stripe cross cubic curve or the are intersect
- */
- public static int intersectCubic(float x1, float y1, float cx1, float cy1, float cx2, float cy2, float x2, float y2, float rx1, float ry1, float rx2, float ry2) {
-
- // LEFT/RIGHT/UP
- if ((rx2 < x1 && rx2 < cx1 && rx2 < cx2 && rx2 < x2) ||
- (rx1 > x1 && rx1 > cx1 && rx1 > cx2 && rx1 > x2) ||
- (ry1 > y1 && ry1 > cy1 && ry1 > cy2 && ry1 > y2))
- {
- return 0;
- }
-
- // DOWN
- if (ry2 < y1 && ry2 < cy1 && ry2 < cy2 && ry2 < y2 && rx1 != x1 && rx1 != x2) {
- if (x1 < x2) {
- return x1 < rx1 && rx1 < x2 ? 1 : 0;
- }
- return x2 < rx1 && rx1 < x1 ? -1 : 0;
- }
-
- // INSIDE
- CubicCurve c = new CubicCurve(x1, y1, cx1, cy1, cx2, cy2, x2, y2);
- float px1 = rx1 - x1;
- float py1 = ry1 - y1;
- float px2 = rx2 - x1;
- float py2 = ry2 - y1;
-
- float res1[] = new float[3];
- float res2[] = new float[3];
- int rc1 = c.solvePoint(res1, px1);
- int rc2 = c.solvePoint(res2, px2);
-
- // LEFT/RIGHT
- if (rc1 == 0 && rc2 == 0) {
- return 0;
- }
-
- float minX = px1 - DELTA;
- float maxX = px2 + DELTA;
-
- // Build bound --------------------------------------------------------
- float bound[] = new float[40];
- int bc = 0;
- // Add roots
- bc = c.addBound(bound, bc, res1, rc1, minX, maxX, false, 0);
- bc = c.addBound(bound, bc, res2, rc2, minX, maxX, false, 1);
- // Add extrimal points
- rc2 = c.solveExtremX(res2);
- bc = c.addBound(bound, bc, res2, rc2, minX, maxX, true, 2);
- rc2 = c.solveExtremY(res2);
- bc = c.addBound(bound, bc, res2, rc2, minX, maxX, true, 4);
- // Add start and end
- if (rx1 < x1 && x1 < rx2) {
- bound[bc++] = 0.0f;
- bound[bc++] = 0.0f;
- bound[bc++] = 0.0f;
- bound[bc++] = 6;
- }
- if (rx1 < x2 && x2 < rx2) {
- bound[bc++] = 1.0f;
- bound[bc++] = c.ax;
- bound[bc++] = c.ay;
- bound[bc++] = 7;
- }
- // End build bound ----------------------------------------------------
-
- int cross = crossBound(bound, bc, py1, py2);
- if (cross != UNKNOWN) {
- return cross;
- }
- return c.cross(res1, rc1, py1, py2);
- }
-
- /**
- * Returns how many times rectangle stripe cross path or the are intersect
- */
- public static int intersectPath(PathIterator p, float x, float y, float w, float h) {
-
- int cross = 0;
- int count;
- float mx, my, cx, cy;
- mx = my = cx = cy = 0.0f;
- final float coords[] = new float[6];
-
- float rx1 = x;
- float ry1 = y;
- float rx2 = x + w;
- float ry2 = y + h;
-
- while (!p.isDone()) {
- count = 0;
- final int segmentType = p.currentSegment(coords);
- switch (segmentType) {
- case PathIterator.SEG_MOVETO:
- if (cx != mx || cy != my) {
- count = intersectLine(cx, cy, mx, my, rx1, ry1, rx2, ry2);
- }
- mx = cx = coords[0];
- my = cy = coords[1];
- break;
- case PathIterator.SEG_LINETO:
- count = intersectLine(cx, cy, cx = coords[0], cy = coords[1], rx1, ry1, rx2, ry2);
- break;
- case PathIterator.SEG_QUADTO:
- count = intersectQuad(cx, cy, coords[0], coords[1], cx = coords[2], cy = coords[3], rx1, ry1, rx2, ry2);
- break;
- case PathIterator.SEG_CUBICTO:
- count = intersectCubic(cx, cy, coords[0], coords[1], coords[2], coords[3], cx = coords[4], cy = coords[5], rx1, ry1, rx2, ry2);
- break;
- case PathIterator.SEG_CLOSE:
- if (cy != my || cx != mx) {
- count = intersectLine(cx, cy, mx, my, rx1, ry1, rx2, ry2);
- }
- cx = mx;
- cy = my;
- break;
- default:
- throw new IllegalArgumentException("Unhandled Segment Type: "+segmentType);
- }
- if (count == CROSSING) {
- return CROSSING;
- }
- cross += count;
- p.next();
- }
- if (cy != my) {
- count = intersectLine(cx, cy, mx, my, rx1, ry1, rx2, ry2);
- if (count == CROSSING) {
- return CROSSING;
- }
- cross += count;
- }
- return cross;
- }
-
- /**
- * Returns how many times rectangle stripe cross shape or the are intersect
- */
- public static int intersectShape(Path2D s, float x, float y, float w, float h) {
- if (!s.getBounds2D().intersects(x, y, w, h)) {
- return 0;
- }
- return intersectPath(s.iterator(null), x, y, w, h);
- }
-
- /**
- * Returns true if cross count correspond inside location for non zero path rule
- */
- public static boolean isInsideNonZero(int cross) {
- return cross != 0;
- }
-
- /**
- * Returns true if cross count correspond inside location for even-odd path rule
- */
- public static boolean isInsideEvenOdd(int cross) {
- return (cross & 1) != 0;
- }
-}
diff --git a/src/jogl/classes/jogamp/opengl/ProjectFloat.java b/src/jogl/classes/jogamp/opengl/ProjectFloat.java
index 18fe3e77e..439ddc76e 100644
--- a/src/jogl/classes/jogamp/opengl/ProjectFloat.java
+++ b/src/jogl/classes/jogamp/opengl/ProjectFloat.java
@@ -122,7 +122,7 @@ import java.nio.IntBuffer;
import javax.media.opengl.fixedfunc.GLMatrixFunc;
import com.jogamp.common.nio.Buffers;
-import com.jogamp.opengl.FloatUtil;
+import com.jogamp.opengl.math.FloatUtil;
/**
* ProjectFloat.java
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 b22be0a93..b594fab48 100644
--- a/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT00.java
+++ b/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT00.java
@@ -50,9 +50,9 @@ import com.jogamp.graph.curve.opengl.RenderState;
import com.jogamp.graph.curve.opengl.TextRenderer;
import com.jogamp.graph.font.Font;
import com.jogamp.graph.font.FontFactory;
-import com.jogamp.graph.geom.AABBox;
import com.jogamp.graph.geom.opengl.SVertex;
import com.jogamp.newt.opengl.GLWindow;
+import com.jogamp.opengl.math.geom.AABBox;
import com.jogamp.opengl.test.junit.util.UITestCase;
import com.jogamp.opengl.util.GLReadBufferUtil;
import com.jogamp.opengl.util.glsl.ShaderState;
diff --git a/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT10.java b/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT10.java
index ff7eb4ed1..2d989ef65 100644
--- a/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT10.java
+++ b/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT10.java
@@ -43,8 +43,8 @@ import com.jogamp.graph.curve.opengl.RenderState;
import com.jogamp.graph.curve.opengl.TextRenderer;
import com.jogamp.graph.font.Font;
import com.jogamp.graph.font.FontFactory;
-import com.jogamp.graph.geom.AABBox;
import com.jogamp.graph.geom.opengl.SVertex;
+import com.jogamp.opengl.math.geom.AABBox;
import com.jogamp.opengl.test.junit.util.NEWTGLContext;
import com.jogamp.opengl.test.junit.util.UITestCase;
import com.jogamp.opengl.util.glsl.ShaderState;
diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextRendererListenerBase01.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextRendererListenerBase01.java
index 7fb199a5d..658d4a4f1 100644
--- a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextRendererListenerBase01.java
+++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextRendererListenerBase01.java
@@ -39,10 +39,10 @@ import com.jogamp.graph.curve.opengl.RenderState;
import com.jogamp.graph.curve.opengl.TextRenderer;
import com.jogamp.graph.font.Font;
import com.jogamp.graph.font.FontFactory;
-import com.jogamp.graph.geom.AABBox;
import com.jogamp.newt.event.KeyEvent;
import com.jogamp.newt.event.KeyListener;
import com.jogamp.newt.opengl.GLWindow;
+import com.jogamp.opengl.math.geom.AABBox;
/**
*
diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/RIButton.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/RIButton.java
index bf403900d..12c90f87d 100644
--- a/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/RIButton.java
+++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/RIButton.java
@@ -32,9 +32,9 @@ import javax.media.opengl.GL2ES2;
import com.jogamp.graph.curve.opengl.RegionRenderer;
import com.jogamp.graph.curve.opengl.RenderState;
import com.jogamp.graph.font.Font;
-import com.jogamp.graph.geom.AABBox;
import com.jogamp.graph.geom.Vertex;
import com.jogamp.graph.geom.Vertex.Factory;
+import com.jogamp.opengl.math.geom.AABBox;
import com.jogamp.opengl.test.junit.graph.demos.ui.opengl.UIRegion;
/** GPU based resolution independent Button impl
diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/UIShape.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/UIShape.java
index 2f87fab66..c38f8f75c 100644
--- a/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/UIShape.java
+++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/UIShape.java
@@ -32,9 +32,9 @@ import javax.media.opengl.GL2ES2;
import com.jogamp.graph.curve.OutlineShape;
import com.jogamp.graph.curve.opengl.RegionRenderer;
import com.jogamp.graph.curve.opengl.RenderState;
-import com.jogamp.graph.geom.AABBox;
import com.jogamp.graph.geom.Vertex;
import com.jogamp.graph.geom.Vertex.Factory;
+import com.jogamp.opengl.math.geom.AABBox;
public abstract class UIShape {
private final Factory extends Vertex> vertexFactory;
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFloatUtil01MatrixMatrixMultNOUI.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFloatUtil01MatrixMatrixMultNOUI.java
index 42b5972bb..adeb700d7 100755
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFloatUtil01MatrixMatrixMultNOUI.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFloatUtil01MatrixMatrixMultNOUI.java
@@ -31,7 +31,7 @@ package com.jogamp.opengl.test.junit.jogl.acore;
import org.junit.Assert;
import org.junit.Test;
-import com.jogamp.opengl.FloatUtil;
+import com.jogamp.opengl.math.FloatUtil;
public class TestFloatUtil01MatrixMatrixMultNOUI {
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestPMVMatrix01NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestPMVMatrix01NEWT.java
index c44a82a20..d7e89facc 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestPMVMatrix01NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestPMVMatrix01NEWT.java
@@ -44,7 +44,7 @@ import org.junit.BeforeClass;
import org.junit.Test;
import com.jogamp.common.os.Platform;
-import com.jogamp.opengl.FloatUtil;
+import com.jogamp.opengl.math.FloatUtil;
import com.jogamp.opengl.test.junit.util.MiscUtils;
import com.jogamp.opengl.test.junit.util.UITestCase;
import com.jogamp.opengl.util.PMVMatrix;
--
cgit v1.2.3
From 1062e8ebfd6d2643bba9a68bbbc78bb44b3ede6a Mon Sep 17 00:00:00 2001
From: Sven Gothel - * For an unknown reason, on OSX/Java7 our root CALayer's frame position gets corrupted - * and is moved out of 'sight' .. or oddly half way to the upper right corner. + * If the sub CALayer implements the Objective-C NativeWindow protocol NWDedicatedSize (e.g. JOGL's MyNSOpenGLLayer), + * the dedicated size is passed to the layer, which propagates it appropriately. + *
+ *+ * On OSX/Java7 our root CALayer's frame position and size gets corrupted by its NSView, + * hence we have created the NWDedicatedSize protocol. *
* * @param rootCALayer the root surface layer, maybe null. @@ -184,13 +188,13 @@ public class OSXUtil implements ToolkitProperties { * @param width the expected width * @param height the expected height */ - public static void FixCALayerPosition(final long rootCALayer, final long subCALayer, final int width, final int height) { + public static void FixCALayerLayout(final long rootCALayer, final long subCALayer, final int width, final int height) { if( 0==rootCALayer && 0==subCALayer ) { return; } RunOnMainThread(false, new Runnable() { public void run() { - FixCALayerPosition0(rootCALayer, subCALayer, width, height); + FixCALayerLayout0(rootCALayer, subCALayer, width, height); } }); } @@ -346,7 +350,7 @@ public class OSXUtil implements ToolkitProperties { private static native long GetNSWindow0(long nsView); private static native long CreateCALayer0(int x, int y, int width, int height); private static native void AddCASublayer0(long rootCALayer, long subCALayer); - private static native void FixCALayerPosition0(long rootCALayer, long subCALayer, int width, int height); + private static native void FixCALayerLayout0(long rootCALayer, long subCALayer, int width, int height); private static native void RemoveCASublayer0(long rootCALayer, long subCALayer); private static native void DestroyCALayer0(long caLayer); private static native void RunOnMainThread0(Runnable runnable); diff --git a/src/nativewindow/native/macosx/NativeWindowProtocols.h b/src/nativewindow/native/macosx/NativeWindowProtocols.h new file mode 100644 index 000000000..b91a50dfd --- /dev/null +++ b/src/nativewindow/native/macosx/NativeWindowProtocols.h @@ -0,0 +1,34 @@ +/** + * Copyright 2013 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. + */ + +#import Common interface containing the subset of all profiles, GL3bc, GL3, GL2, GLES1 and GLES2.
-ClassJavadoc GL * This interface reflects common data types, texture and framebuffer functionality.
Common interface containing the subset of all profiles, GL3bc, GL3, GL2, GLES1 and GLES2.
+ClassJavadoc GL * This interface reflects common data types, texture and framebuffer functionality.
-ClassJavadoc GL2ES1 * Interface containing the common subset of GL2 and GLES1.
-ClassJavadoc GL2ES1 * This interface reflects only the fixed functionality of OpenGL
-ClassJavadoc GL2ES1 *
+ClassJavadoc GL2ES1 * Interface containing the common subset of GL2 and GLES1.
+ClassJavadoc GL2ES1 * This interface reflects only the fixed functionality of OpenGL
+ClassJavadoc GL2ES1 *
-ClassJavadoc GL2ES2 * Interface containing the common subset of GL3, GL2 and GLES2.
-ClassJavadoc GL2ES2 * This interface reflects only the programmable shader functionality of desktop and embedded OpenGL
-ClassJavadoc GL2ES2 *
+ClassJavadoc GL2ES2 * Interface containing the common subset of GL3, GL2 and GLES2.
+ClassJavadoc GL2ES2 * This interface reflects only the programmable shader functionality of desktop and embedded OpenGL
+ClassJavadoc GL2ES2 * This interface is almost GLES2 complete.
+ClassJavadoc GL2ES2 *
+ClassJavadoc GL2ES3 * Interface containing the common subset of core GL2 and GLES3 (OpenGL ES 3.0).
+ClassJavadoc GL2ES3 * This interface reflects only the programmable shader functionality of desktop and embedded OpenGL
+ClassJavadoc GL2ES3 * This interface is not GLES3 complete and merely exist to avoid duplicated definitions.
+ClassJavadoc GL2ES3 *
+ClassJavadoc GL3ES3 * Interface containing the common subset of core GL3 (OpenGL 3.1+) and GLES3 (OpenGL ES 3.0).
+ClassJavadoc GL3ES3 * This interface reflects only the programmable shader functionality of desktop and embedded OpenGL
+ClassJavadoc GL3ES3 * This interface is almost GLES3 complete, but lacks the GL_ARB_ES3_compatibility
extension.
+ClassJavadoc GL3ES3 *
+ClassJavadoc GL4ES3 * Interface containing the common subset of core GL4 (OpenGL 4.0+) and GLES3 (OpenGL ES 3.0).
+ClassJavadoc GL4ES3 * This interface reflects only the programmable shader functionality of desktop and embedded OpenGL
+ClassJavadoc GL4ES3 * This interface is GLES3 complete.
+ClassJavadoc GL4ES3 *
-ClassJavadoc GL2GL3 * Interface containing the common subset of core GL3 (OpenGL 3.1+) and GL2 (OpenGL 3.0),
-ClassJavadoc GL2GL3 * also known as the OpenGL 3.0 forward compatible, non deprecated subset.
-ClassJavadoc GL2GL3 * This interface reflects only the programmable shader functionality of desktop OpenGL
-ClassJavadoc GL2GL3 *
+ClassJavadoc GL2GL3 * Interface containing the common subset of core GL3 (OpenGL 3.1) and GL2 (OpenGL 3.0),
+ClassJavadoc GL2GL3 * also known as the OpenGL 3.0 forward compatible, non deprecated subset.
+ClassJavadoc GL2GL3 * This interface reflects only the programmable shader functionality of desktop OpenGL
+ClassJavadoc GL2GL3 *
+ClassJavadoc GL2 *
ClassJavadoc GL2 * This interface contains all core desktop OpenGL methods through
ClassJavadoc GL2 * version 3.0, inclusive, as well as most of it's extensions defined at the
ClassJavadoc GL2 * time of this specification. Early OpenGL extensions whose functionality
ClassJavadoc GL2 * was incorporated into core OpenGL by version 3.0, inclusive, are specifically
-ClassJavadoc GL2 * excluded.
+ClassJavadoc GL2 * excluded.
ClassJavadoc GL2 * Note: OpenGL 3.0 is the last subsumed version in the specification.
ClassJavadoc GL2 * You need to use a {@link GL3} or {@link GL3bc} OpenGL 3.1+ context to benefit
ClassJavadoc GL2 * from new functionality and versions.
-ClassJavadoc GL2 *
-ClassJavadoc GL3bc * This interface contains the OpenGL 3.x compatibility profile, ie includes all methods
-ClassJavadoc GL3bc * as defined in {@link GL2} and {@link GL3}.
-ClassJavadoc GL3bc *
-ClassJavadoc GL3 * This interface contains all core, forward compatible, OpenGL methods starting from 3.1,
-ClassJavadoc GL3 * inclusive, as well as most of it's extensions defined at the time of this specification.
+ClassJavadoc GL3 *
+ClassJavadoc GL3 * This interface contains the core, forward compatible, OpenGL methods of GL 3.x, with x >=1,
+ClassJavadoc GL3 * as well as most of it's extensions defined at the time of this specification.
ClassJavadoc GL3 * Note: OpenGL 3.0 forward compatible, non deprecated functionality is included in the
-ClassJavadoc GL3 * 3.1 specification, hence the {@link GL2GL3} implemented interface.
-ClassJavadoc GL3 * Note: OpenGL 3.1 forward compatible no more includes fixed point functionality.
-ClassJavadoc GL3 *
+ClassJavadoc GL3bc * This interface containing all core and compatibility OpenGL methods of GL 3.x, with x >= 1,
+ClassJavadoc GL3bc * as well as most of it's extensions defined at the time of this specification.
+ClassJavadoc GL3bc *
+ClassJavadoc GL4 * This interface containing all core OpenGL methods of GL 4.x, with x >= 0,
+ClassJavadoc GL4 * as well as most of it's extensions defined at the time of this specification.
+ClassJavadoc GL4 *
+ClassJavadoc GL4bc * This interface containing all core and compatibility OpenGL methods of GL 4.x, with x >= 0,
+ClassJavadoc GL4bc * as well as most of it's extensions defined at the time of this specification.
+ClassJavadoc GL4bc *
+ClassJavadoc GLES1 *
ClassJavadoc GLES1 * This interface contains all core embedded OpenGL methods of ES 1.x, with x >= 0, -ClassJavadoc GLES1 * inclusive, as well as most of it's extensions defined at the -ClassJavadoc GLES1 * time of this specification. -ClassJavadoc GLES1 *
+ClassJavadoc GLES1 * as well as most of it's extensions defined at the time of this specification. +ClassJavadoc GLES1 * ClassJavadoc GLES1 */ ClassJavadoc GLES2 /** -ClassJavadoc GLES2 *+ClassJavadoc GLES2 *
ClassJavadoc GLES2 * This interface contains all core embedded OpenGL methods of ES 2.x, with x >= 0, -ClassJavadoc GLES2 * inclusive, as well as most of it's extensions defined at the -ClassJavadoc GLES2 * time of this specification. -ClassJavadoc GLES2 *
+ClassJavadoc GLES2 * inclusive, as well as most of it's extensions defined at the time of this specification. +ClassJavadoc GLES2 * ClassJavadoc GLES2 */ +ClassJavadoc GLES3 /** +ClassJavadoc GLES3 *+ClassJavadoc GLES3 * This interface contains all core embedded OpenGL methods of ES 3.x, with x >= 0, +ClassJavadoc GLES3 * inclusive, as well as most of it's extensions defined at the time of this specification. +ClassJavadoc GLES3 *
+ClassJavadoc GLES3 */ + # Javadoc for the EGL class ClassJavadoc EGL /** ClassJavadoc EGL * Provides access to the embedded-specific OpenGL vendor extensions. @@ -805,11 +878,3 @@ ClassJavadoc XVisualInfo * extensions. No other access is provided to these dat ClassJavadoc XVisualInfo * this wrapper is not useful to end users, though it is used in the implementation. ClassJavadoc XVisualInfo */ -# Custom code for querying extensions and exposing -# wglAllocateMemoryNV/glXAllocateMemoryNV -CustomJavaCode GL2GL3 /** -CustomJavaCode GL2GL3 * Provides platform-independent access to thewglAllocateMemoryNV
/
-CustomJavaCode GL2GL3 * glXAllocateMemoryNV
extension.
-CustomJavaCode GL2GL3 */
-CustomJavaCode GL2GL3 public java.nio.ByteBuffer glAllocateMemoryNV(int arg0, float arg1, float arg2, float arg3);
-
diff --git a/make/config/jogl/gl-desktop.cfg b/make/config/jogl/gl-desktop.cfg
index a91f5ac5b..244271468 100644
--- a/make/config/jogl/gl-desktop.cfg
+++ b/make/config/jogl/gl-desktop.cfg
@@ -1,11 +1,6 @@
# This .cfg file provides common options used by the desktop OpenGL
# implementation on all platforms.
-# Inform the glue code generator of the association between #defines
-# and functions and the extensions in which they are defined
-GLHeader GL/gl.h
-GLHeader GL/glext.h
-
#Include gl-desktop-tracker.cfg
diff --git a/make/config/jogl/gl-es1.cfg b/make/config/jogl/gl-es1.cfg
index 2a7b64dd3..b73b1a731 100644
--- a/make/config/jogl/gl-es1.cfg
+++ b/make/config/jogl/gl-es1.cfg
@@ -30,13 +30,6 @@ EmitProcAddressTable true
ProcAddressTableClassName GLES1ProcAddressTable
GetProcAddressTableExpr ((GLES1ProcAddressTable)_context.getGLProcAddressTable())
-# Inform the glue code generator of the association between #defines
-# and functions and the extensions in which they are defined
-GLHeader GLES/gl.h
-GLHeader GLES/glext.h
-GLHeader GL/gl.h
-GLHeader GL/glext.h
-
# Force all of the methods to be emitted using dynamic linking so we
# don't need to link against any emulation library on the desktop or
# depend on the presence of an import library for a particular device
@@ -49,11 +42,6 @@ LocalProcAddressCallingConvention __ALL__ GL_APIENTRY
# Pick up on-line OpenGL javadoc thanks to user cylab on javagaming.org forums
TagNativeBinding true
-# Ignore certain extensions that will be picked up by the dynamic
-# lookup mechanism anyway if they are present
-IgnoreExtension GL_OES_fixed_point
-IgnoreExtension GL_OES_single_precision
-
# Add PixelStorei StateTracker
#
# Add input validation to glPixelStorei, just to be sure.
diff --git a/make/config/jogl/gl-es2.cfg b/make/config/jogl/gl-es2.cfg
deleted file mode 100644
index 8b6152bd0..000000000
--- a/make/config/jogl/gl-es2.cfg
+++ /dev/null
@@ -1,90 +0,0 @@
-# This .cfg file is used to generate the GL interface and implementing class.
-JavaOutputDir gensrc/classes
-NativeOutputDir gensrc/native/jogl/es2
-
-ExtendedInterfaceSymbolsIgnore ../build-temp/gensrc/classes/javax/media/opengl/GL.java
-ExtendedInterfaceSymbolsIgnore ../build-temp/gensrc/classes/javax/media/opengl/GL2ES2.java
-ExtendedInterfaceSymbolsIgnore ../src/jogl/classes/javax/media/opengl/GLBase.java
-
-Package javax.media.opengl
-Style InterfaceAndImpl
-JavaClass GLES2
-#Extends GLES2 GLBase
-#Extends GLES2 GL
-Extends GLES2 GL2ES2
-ImplPackage jogamp.opengl.es2
-ImplJavaClass GLES2Impl
-Implements GLES2Impl GLBase
-Implements GLES2Impl GL
-Implements GLES2Impl GL2ES2
-HierarchicalNativeOutput false
-Include gl-common.cfg
-Include gl-common-extensions.cfg
-Include gl2_es2-common.cfg
-
-RenameExtensionIntoCore GL_OES_texture_3D
-RenameExtensionIntoCore GL_OES_get_program_binary
-
-EmitProcAddressTable true
-ProcAddressTableClassName GLES2ProcAddressTable
-GetProcAddressTableExpr ((GLES2ProcAddressTable)_context.getGLProcAddressTable())
-
-# Inform the glue code generator of the association between #defines
-# and functions and the extensions in which they are defined
-GLHeader GLES2/gl2.h
-GLHeader GLES2/gl2ext.h
-GLHeader GL/gl.h
-GLHeader GL/glext.h
-
-# Force all of the methods to be emitted using dynamic linking so we
-# don't need to link against any emulation library on the desktop or
-# depend on the presence of an import library for a particular device
-ForceProcAddressGen __ALL__
-
-# Also force the calling conventions of the locally generated function
-# pointer typedefs for these routines to GL_APIENTRY
-LocalProcAddressCallingConvention __ALL__ GL_APIENTRY
-
-# Pick up on-line OpenGL javadoc thanks to user cylab on javagaming.org forums
-TagNativeBinding true
-
-# Add PixelStorei StateTracker
-#
-# Add input validation to glPixelStorei, just to be sure.
-CustomJavaCode GLES2Impl private static final int params_offset = 0; // just a helper for JavaPrologue ..
-
-JavaPrologue glPixelStorei if (pname != GL_PACK_ALIGNMENT && pname != GL_UNPACK_ALIGNMENT) {
-JavaPrologue glPixelStorei throw new GLException("Unsupported pixel store parameter name 0x" + Integer.toHexString(pname));
-JavaPrologue glPixelStorei }
-JavaPrologue glPixelStorei glStateTracker.setInt(pname, param);
-
-JavaPrologue glGetIntegerv if ( glStateTracker.getInt(pname, params, params_offset) ) { return; }
-
-IncludeAs CustomJavaCode GLES2 gl-if-CustomJavaCode-gles2.java
-
-CustomCCode #include GL_ARB_uniform_buffer_object
*/
+public static final int GL_INVALID_INDEX = 0xFFFFFFFF ;
+
+/** Part of GL_ARB_sync
*/
+public static final long GL_TIMEOUT_IGNORED = 0xFFFFFFFFFFFFFFFFL ;
+
+/** Part of GL_ARB_shader_image_load_store
*/
+public static final int GL_ALL_BARRIER_BITS = 0xFFFFFFFF ;
+
+public boolean glIsPBOPackEnabled();
+
+public boolean glIsPBOUnpackEnabled();
+
diff --git a/make/config/jogl/gl-if-CustomJavaCode-gl.java b/make/config/jogl/gl-if-CustomJavaCode-gl.java
index 9ea4f98b4..f9f33eec9 100644
--- a/make/config/jogl/gl-if-CustomJavaCode-gl.java
+++ b/make/config/jogl/gl-if-CustomJavaCode-gl.java
@@ -57,3 +57,11 @@
earmarked for ES 3.0 (hence kept in GL while fixing Bug 590) */
public static final int GL_HALF_FLOAT = 0x140B;
+ /** Part of GL_VERSION_1_4
, GL_ES_VERSION_2_0
, GL_OES_required_internalformat
. */
+ public static final int GL_DEPTH_COMPONENT16 = 0x81A5;
+ /** Part of GL_VERSION_1_0
, GL_OES_element_index_uint
, GL_ES_VERSION_2_0
*/
+ public static final int GL_UNSIGNED_INT = 0x1405;
+ /** Part of GL_VERSION_1_0
, GL_ES_VERSION_2_0
*/
+ public static final int GL_UNSIGNED_SHORT = 0x1403;
+
+
diff --git a/make/config/jogl/gl-if-CustomJavaCode-gl2_es2.java b/make/config/jogl/gl-if-CustomJavaCode-gl2_es2.java
index 4522d34c8..5ad235de5 100644
--- a/make/config/jogl/gl-if-CustomJavaCode-gl2_es2.java
+++ b/make/config/jogl/gl-if-CustomJavaCode-gl2_es2.java
@@ -39,10 +39,21 @@
* void {@native glDepthRange}(GLclampd zNear, GLclampd zFar);
if no native implementation is available. */
public void glDepthRangef(float zNear, float zFar);
+ public void glDepthRange(double zNear, double zFar);
+
/** Entry point to C language function:
* void {@native glClearDepthf}(GLclampf depth);
* GL_ES_VERSION_2_0
and GL_ARB_ES2_compatibility
.
* void {@native glClearDepth}(GLclampd depth);
if no native implementation is available. */
public void glClearDepthf(float depth);
+ public void glClearDepth( double depth );
+
+ public void glVertexAttribPointer(GLArrayData array);
+
+ public void glUniform(GLUniformData data);
+
+ /** Part of GL_VERSION_1_0
, GL_ES_VERSION_2_0
, GL_ANGLE_depth_texture
*/
+ public static final int GL_DEPTH_COMPONENT = 0x1902;
+
/** End: GL_ARB_ES2_compatibility functions, which are part of ES2 core as well */
diff --git a/make/config/jogl/gl-if-CustomJavaCode-gl2_gl3.java b/make/config/jogl/gl-if-CustomJavaCode-gl2_gl3.java
deleted file mode 100644
index 97fd6c4a6..000000000
--- a/make/config/jogl/gl-if-CustomJavaCode-gl2_gl3.java
+++ /dev/null
@@ -1,10 +0,0 @@
-
-/** Part of GL_ARB_uniform_buffer_object
*/
-public static final int GL_INVALID_INDEX = 0xFFFFFFFF ;
-
-/** Part of GL_ARB_sync
*/
-public static final long GL_TIMEOUT_IGNORED = 0xFFFFFFFFFFFFFFFFL ;
-
-/** Part of GL_ARB_shader_image_load_store
*/
-public static final int GL_ALL_BARRIER_BITS = 0xFFFFFFFF ;
-
diff --git a/make/config/jogl/gl-if-CustomJavaCode-gl_compat.java b/make/config/jogl/gl-if-CustomJavaCode-gl_compat.java
new file mode 100644
index 000000000..22ae54cbe
--- /dev/null
+++ b/make/config/jogl/gl-if-CustomJavaCode-gl_compat.java
@@ -0,0 +1,20 @@
+
+/**
+ * Part of GL_NV_vertex_array_range
.
+ *
+ * Provides platform-independent access to the wglAllocateMemoryNV
/
+ * glXAllocateMemoryNV
.
+ *
GL_NV_vertex_array_range
.
+ *
+ * Provides platform-independent access to the wglFreeMemoryNV
/
+ * glXFreeMemoryNV
.
+ *
void * {@native glMapBuffer}(GLenum target, GLenum access);
GL_VERSION_1_5
; GL_OES_mapbuffer
*/
+ private final java.nio.ByteBuffer glMapBufferImpl(int target, boolean useRange, long offset, long length, int access, long glProcAddress) {
+ if (glProcAddress == 0) {
+ throw new GLException("Method \""+(useRange?"glMapBufferRange":"glMapBuffer")+"\" not available");
+ }
+ final long sz = bufferSizeTracker.getBufferSize(bufferStateTracker, target, this);
+ if (0 == sz) {
+ return null;
+ }
+ if( !useRange ) {
+ length = sz;
+ offset = 0;
+ } else {
+ if( length + offset > sz ) {
+ throw new GLException("Out of range: offset "+offset+" + length "+length+" > size "+sz);
+ }
+ if( 0 > length || 0 > offset ) {
+ throw new GLException("Invalid values: offset "+offset+", length "+length);
+ }
+ if( 0 == length ) {
+ return null;
+ }
+ }
+ final long addr = useRange ? dispatch_glMapBufferRange(target, offset, length, access, glProcAddress) :
+ dispatch_glMapBuffer(target, access, glProcAddress);
+ if (0 == addr) {
+ return null;
+ }
+ ByteBuffer buffer;
+ MemoryObject memObj0 = new MemoryObject(addr, length); // object and key
+ MemoryObject memObj1 = MemoryObject.getOrAddSafe(arbMemCache, memObj0);
+ if(memObj0 == memObj1) {
+ // just added ..
+ if(null != memObj0.getBuffer()) {
+ throw new InternalError();
+ }
+ buffer = newDirectByteBuffer(addr, length);
+ Buffers.nativeOrder(buffer);
+ memObj0.setBuffer(buffer);
+ } else {
+ // already mapped
+ buffer = memObj1.getBuffer();
+ if(null == buffer) {
+ throw new InternalError();
+ }
+ }
+ buffer.position(0);
+ return buffer;
+ }
+ private native long dispatch_glMapBuffer(int target, int access, long glProcAddress);
+ private native long dispatch_glMapBufferRange(int target, long offset, long length, int access, long procAddress);
+
+
+ /** Entry point to C language function: GLvoid * {@native glMapNamedBufferEXT}(GLuint buffer, GLenum access);
GL_EXT_direct_state_access
*/
+ private final java.nio.ByteBuffer glMapNamedBufferImpl(int bufferName, int access, long glProcAddress) {
+ if (glProcAddress == 0) {
+ throw new GLException("Method \"glMapNamedBufferEXT\" not available");
+ }
+ final long sz = bufferSizeTracker.getDirectStateBufferSize(bufferName, this);
+ if (0 == sz) {
+ return null;
+ }
+ final long addr = dispatch_glMapNamedBufferEXT(bufferName, access, glProcAddress);
+ if (0 == addr) {
+ return null;
+ }
+ ByteBuffer buffer;
+ MemoryObject memObj0 = new MemoryObject(addr, sz); // object and key
+ MemoryObject memObj1 = MemoryObject.getOrAddSafe(arbMemCache, memObj0);
+ if(memObj0 == memObj1) {
+ // just added ..
+ if(null != memObj0.getBuffer()) {
+ throw new InternalError();
+ }
+ buffer = newDirectByteBuffer(addr, sz);
+ Buffers.nativeOrder(buffer);
+ memObj0.setBuffer(buffer);
+ } else {
+ // already mapped
+ buffer = memObj1.getBuffer();
+ if(null == buffer) {
+ throw new InternalError();
+ }
+ }
+ buffer.position(0);
+ return buffer;
+ }
+ private native long dispatch_glMapNamedBufferEXT(int buffer, int access, long procAddress);
+
+ private native ByteBuffer newDirectByteBuffer(long addr, long capacity);
diff --git a/make/config/jogl/gl-impl-CustomJavaCode-desktop.java b/make/config/jogl/gl-impl-CustomJavaCode-desktop.java
deleted file mode 100644
index 6a74b80a6..000000000
--- a/make/config/jogl/gl-impl-CustomJavaCode-desktop.java
+++ /dev/null
@@ -1,148 +0,0 @@
- private int[] imageSizeTemp = new int[1];
-
- private final int imageSizeInBytes(int format, int type, int width, int height, int depth, boolean pack) {
- return GLBuffers.sizeof(this, imageSizeTemp, format, type, width, height, depth, pack) ;
- }
-
- @Override
- public final boolean isGL4bc() {
- return _context.isGL4bc();
- }
-
- @Override
- public final boolean isGL4() {
- return _context.isGL4();
- }
-
- @Override
- public final boolean isGL3bc() {
- return _context.isGL3bc();
- }
-
- @Override
- public final boolean isGL3() {
- return _context.isGL3();
- }
-
- @Override
- public final boolean isGL2() {
- return _context.isGL2();
- }
-
- @Override
- public final boolean isGL2ES1() {
- return _context.isGL2ES1();
- }
-
- @Override
- public final boolean isGL2ES2() {
- return _context.isGL2ES2();
- }
-
- @Override
- public final boolean isGLES2Compatible() {
- return _context.isGLES2Compatible();
- }
-
- public final boolean isGL2GL3() {
- return _context.isGL2GL3();
- }
-
- @Override
- public final boolean hasGLSL() {
- return _context.hasGLSL();
- }
-
- @Override
- public final GL4bc getGL4bc() throws GLException {
- if(!isGL4bc()) {
- throw new GLException("Not a GL4bc implementation");
- }
- return this;
- }
-
- @Override
- public final GL4 getGL4() throws GLException {
- if(!isGL4()) {
- throw new GLException("Not a GL4 implementation");
- }
- return this;
- }
-
- @Override
- public final GL3bc getGL3bc() throws GLException {
- if(!isGL3bc()) {
- throw new GLException("Not a GL3bc implementation");
- }
- return this;
- }
-
- @Override
- public final GL3 getGL3() throws GLException {
- if(!isGL3()) {
- throw new GLException("Not a GL3 implementation");
- }
- return this;
- }
-
- @Override
- public final GL2 getGL2() throws GLException {
- if(!isGL2()) {
- throw new GLException("Not a GL2 implementation");
- }
- return this;
- }
-
- @Override
- public final GL2ES1 getGL2ES1() throws GLException {
- if(!isGL2ES1()) {
- throw new GLException("Not a GL2ES1 implementation");
- }
- return this;
- }
-
- @Override
- public final GL2ES2 getGL2ES2() throws GLException {
- if(!isGL2ES2()) {
- throw new GLException("Not a GL2ES2 implementation");
- }
- return this;
- }
-
- @Override
- public final GL2GL3 getGL2GL3() throws GLException {
- if(!isGL2GL3()) {
- throw new GLException("Not a GL2GL3 implementation");
- }
- return this;
- }
-
- @Override
- public final boolean isGLES1() {
- return false;
- }
-
- @Override
- public final boolean isGLES2() {
- return false;
- }
-
- @Override
- public final boolean isGLES() {
- return false;
- }
-
- @Override
- public final GLES1 getGLES1() throws GLException {
- throw new GLException("Not a GLES1 implementation");
- }
-
- @Override
- public final GLES2 getGLES2() throws GLException {
- throw new GLException("Not a GLES2 implementation");
- }
-
- @Override
- public final boolean isNPOTTextureAvailable() {
- return _context.isNPOTTextureAvailable();
- }
diff --git a/make/config/jogl/gl-impl-CustomJavaCode-gl4bc.java b/make/config/jogl/gl-impl-CustomJavaCode-gl4bc.java
index fbe7484c4..cacea322a 100644
--- a/make/config/jogl/gl-impl-CustomJavaCode-gl4bc.java
+++ b/make/config/jogl/gl-impl-CustomJavaCode-gl4bc.java
@@ -29,12 +29,223 @@ public GL4bcImpl(GLProfile glp, GLContextImpl context) {
this.glProfile = glp;
}
-/**
- * Provides platform-independent access to the wglAllocateMemoryNV /
- * glXAllocateMemoryNV extension.
- */
-public final java.nio.ByteBuffer glAllocateMemoryNV(int arg0, float arg1, float arg2, float arg3) {
- return _context.glAllocateMemoryNV(arg0, arg1, arg2, arg3);
+public final void finalizeInit() {
+ if(null != _context) {
+ haveARBPixelBufferObject = isExtensionAvailable("GL_ARB_pixel_buffer_object");
+ haveEXTPixelBufferObject = isExtensionAvailable("GL_EXT_pixel_buffer_object");
+ haveGL15 = isExtensionAvailable("GL_VERSION_1_5");
+ haveGL21 = isExtensionAvailable("GL_VERSION_2_1");
+ haveARBVertexBufferObject = isExtensionAvailable("GL_ARB_vertex_buffer_object");
+ haveARBVertexArrayObject = _context.getGLVersionNumber().compareTo(GLContext.Version300) >= 0 ||
+ isExtensionAvailable("GL_ARB_vertex_array_object");
+ } else {
+ haveARBPixelBufferObject = false;
+ haveEXTPixelBufferObject = false;
+ haveGL15 = false;
+ haveGL21 = false;
+ haveARBVertexBufferObject = false;
+ haveARBVertexArrayObject = false;
+ }
+}
+
+private int[] imageSizeTemp = new int[1];
+
+private final int imageSizeInBytes(int format, int type, int width, int height, int depth, boolean pack) {
+ return GLBuffers.sizeof(this, imageSizeTemp, format, type, width, height, depth, pack) ;
+}
+
+@Override
+public final boolean isGL4bc() {
+ return _context.isGL4bc();
+}
+
+@Override
+public final boolean isGL4() {
+ return _context.isGL4();
+}
+
+@Override
+public final boolean isGL3bc() {
+ return _context.isGL3bc();
+}
+
+@Override
+public final boolean isGL3() {
+ return _context.isGL3();
+}
+
+@Override
+public final boolean isGL2() {
+ return _context.isGL2();
+}
+
+@Override
+public final boolean isGL2ES1() {
+ return _context.isGL2ES1();
+}
+
+@Override
+public final boolean isGL2ES2() {
+ return _context.isGL2ES2();
+}
+
+@Override
+public final boolean isGL3ES3() {
+ return _context.isGL3ES3();
+}
+
+@Override
+public final boolean isGL4ES3() {
+ return _context.isGL4ES3();
+}
+
+@Override
+public final boolean isGLES2Compatible() {
+ return _context.isGLES2Compatible();
+}
+
+@Override
+public final boolean isGLES3Compatible() {
+ return _context.isGLES3Compatible();
+}
+
+@Override
+public final boolean isGL2GL3() {
+ return _context.isGL2GL3();
+}
+
+@Override
+public final boolean hasGLSL() {
+ return _context.hasGLSL();
+}
+
+@Override
+public final GL4bc getGL4bc() throws GLException {
+ if(!isGL4bc()) {
+ throw new GLException("Not a GL4bc implementation");
+ }
+ return this;
+}
+
+@Override
+public final GL4 getGL4() throws GLException {
+ if(!isGL4()) {
+ throw new GLException("Not a GL4 implementation");
+ }
+ return this;
+}
+
+@Override
+public final GL3bc getGL3bc() throws GLException {
+ if(!isGL3bc()) {
+ throw new GLException("Not a GL3bc implementation");
+ }
+ return this;
+}
+
+@Override
+public final GL3 getGL3() throws GLException {
+ if(!isGL3()) {
+ throw new GLException("Not a GL3 implementation");
+ }
+ return this;
+}
+
+@Override
+public final GL2 getGL2() throws GLException {
+ if(!isGL2()) {
+ throw new GLException("Not a GL2 implementation");
+ }
+ return this;
+}
+
+@Override
+public final GL2ES1 getGL2ES1() throws GLException {
+ if(!isGL2ES1()) {
+ throw new GLException("Not a GL2ES1 implementation");
+ }
+ return this;
+}
+
+@Override
+public final GL2ES2 getGL2ES2() throws GLException {
+ if(!isGL2ES2()) {
+ throw new GLException("Not a GL2ES2 implementation");
+ }
+ return this;
+}
+
+@Override
+public final GL3ES3 getGL3ES3() throws GLException {
+ if(!isGL3ES3()) {
+ throw new GLException("Not a GL3ES3 implementation");
+ }
+ return this;
+}
+
+@Override
+public final GL4ES3 getGL4ES3() throws GLException {
+ if(!isGL4ES3()) {
+ throw new GLException("Not a GL4ES3 implementation");
+ }
+ return this;
+}
+
+@Override
+public final GL2GL3 getGL2GL3() throws GLException {
+ if(!isGL2GL3()) {
+ throw new GLException("Not a GL2GL3 implementation");
+ }
+ return this;
+}
+
+@Override
+public final boolean isGLES1() {
+ return false;
+}
+
+@Override
+public final boolean isGLES2() {
+ return false;
+}
+
+@Override
+public final boolean isGLES3() {
+ return false;
+}
+
+@Override
+public final boolean isGLES() {
+ return false;
+}
+
+@Override
+public final GLES1 getGLES1() throws GLException {
+ throw new GLException("Not a GLES1 implementation");
+}
+
+@Override
+public final GLES2 getGLES2() throws GLException {
+ throw new GLException("Not a GLES2 implementation");
+}
+
+@Override
+public final GLES3 getGLES3() throws GLException {
+ throw new GLException("Not a GLES3 implementation");
+}
+
+@Override
+public final boolean isNPOTTextureAvailable() {
+ return _context.isNPOTTextureAvailable();
+}
+@Override
+public final java.nio.ByteBuffer glAllocateMemoryNV(int size, float readFrequency, float writeFrequency, float priority) {
+ return _context.glAllocateMemoryNV(size, readFrequency, writeFrequency, priority);
+}
+
+@Override
+public final void glFreeMemoryNV(java.nio.ByteBuffer pointer) {
+ _context.glFreeMemoryNV(pointer);
}
//
@@ -45,7 +256,6 @@ private final GLBufferSizeTracker bufferSizeTracker;
private final GLBufferStateTracker bufferStateTracker;
private final GLStateTracker glStateTracker;
-private boolean bufferObjectExtensionsInitialized = false;
private boolean haveARBPixelBufferObject;
private boolean haveEXTPixelBufferObject;
private boolean haveGL15;
@@ -53,20 +263,6 @@ private boolean haveGL21;
private boolean haveARBVertexBufferObject;
private boolean haveARBVertexArrayObject;
-private final void initBufferObjectExtensionChecks() {
- if ( bufferObjectExtensionsInitialized ) {
- return;
- }
- bufferObjectExtensionsInitialized = true;
- haveARBPixelBufferObject = isExtensionAvailable("GL_ARB_pixel_buffer_object");
- haveEXTPixelBufferObject = isExtensionAvailable("GL_EXT_pixel_buffer_object");
- haveGL15 = isExtensionAvailable("GL_VERSION_1_5");
- haveGL21 = isExtensionAvailable("GL_VERSION_2_1");
- haveARBVertexBufferObject = isExtensionAvailable("GL_ARB_vertex_buffer_object");
- haveARBVertexArrayObject = _context.getGLVersionNumber().compareTo(GLContext.Version300) >= 0 ||
- isExtensionAvailable("GL_ARB_vertex_array_object");
-}
-
private final boolean checkBufferObject(boolean extensionAvail,
boolean allowVAO,
boolean enabled,
@@ -111,7 +307,6 @@ private final boolean checkBufferObject(boolean extensionAvail,
}
private final boolean checkArrayVBODisabled(boolean throwException) {
- initBufferObjectExtensionChecks();
return checkBufferObject(haveGL15 || haveARBVertexBufferObject,
haveARBVertexArrayObject, // allowVAO
false, // enable
@@ -120,7 +315,6 @@ private final boolean checkArrayVBODisabled(boolean throwException) {
}
private final boolean checkArrayVBOEnabled(boolean throwException) {
- initBufferObjectExtensionChecks();
return checkBufferObject(haveGL15 || haveARBVertexBufferObject,
haveARBVertexArrayObject, // allowVAO
true, // enable
@@ -129,7 +323,6 @@ private final boolean checkArrayVBOEnabled(boolean throwException) {
}
private final boolean checkElementVBODisabled(boolean throwException) {
- initBufferObjectExtensionChecks();
return checkBufferObject(haveGL15 || haveARBVertexBufferObject,
haveARBVertexArrayObject, // allowVAO
false, // enable
@@ -138,7 +331,6 @@ private final boolean checkElementVBODisabled(boolean throwException) {
}
private final boolean checkElementVBOEnabled(boolean throwException) {
- initBufferObjectExtensionChecks();
return checkBufferObject(haveGL15 || haveARBVertexBufferObject,
haveARBVertexArrayObject, // allowVAO
true, // enable
@@ -147,7 +339,6 @@ private final boolean checkElementVBOEnabled(boolean throwException) {
}
private final boolean checkUnpackPBODisabled(boolean throwException) {
- initBufferObjectExtensionChecks();
return checkBufferObject(haveGL21 || haveARBPixelBufferObject || haveEXTPixelBufferObject,
false, // allowVAO
false, // enable
@@ -156,7 +347,6 @@ private final boolean checkUnpackPBODisabled(boolean throwException) {
}
private final boolean checkUnpackPBOEnabled(boolean throwException) {
- initBufferObjectExtensionChecks();
return checkBufferObject(haveGL21 || haveARBPixelBufferObject || haveEXTPixelBufferObject,
false, // allowVAO
true, // enable
@@ -165,7 +355,6 @@ private final boolean checkUnpackPBOEnabled(boolean throwException) {
}
private final boolean checkPackPBODisabled(boolean throwException) {
- initBufferObjectExtensionChecks();
return checkBufferObject(haveGL21 || haveARBPixelBufferObject || haveEXTPixelBufferObject,
false, // allowVAO
false, // enable
@@ -174,7 +363,6 @@ private final boolean checkPackPBODisabled(boolean throwException) {
}
private final boolean checkPackPBOEnabled(boolean throwException) {
- initBufferObjectExtensionChecks();
return checkBufferObject(haveGL21 || haveARBPixelBufferObject || haveEXTPixelBufferObject,
false, // allowVAO
true, // enable
@@ -192,87 +380,21 @@ public final boolean glIsPBOUnpackEnabled() {
return checkUnpackPBOEnabled(false);
}
-private final HashMap LPVOID glMapBuffer(GLenum target, GLenum access);
*/
+/** Entry point to C language function: void * {@native glMapBuffer}(GLenum target, GLenum access);
GL_VERSION_1_5
; GL_OES_mapbuffer
*/
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");
- }
- final long sz = bufferSizeTracker.getBufferSize(bufferStateTracker, target, this);
- if (0 == sz) {
- return null;
- }
- final long addr = dispatch_glMapBuffer(target, access, __addr_);
- if (0 == addr) {
- return null;
- }
- ByteBuffer buffer;
- MemoryObject memObj0 = new MemoryObject(addr, sz); // object and key
- MemoryObject memObj1 = MemoryObject.getOrAddSafe(arbMemCache, memObj0);
- if(memObj0 == memObj1) {
- // just added ..
- if(null != memObj0.getBuffer()) {
- throw new InternalError();
- }
- buffer = newDirectByteBuffer(addr, sz);
- Buffers.nativeOrder(buffer);
- memObj0.setBuffer(buffer);
- } else {
- // already mapped
- buffer = memObj1.getBuffer();
- if(null == buffer) {
- throw new InternalError();
- }
- }
- buffer.position(0);
- return buffer;
+ return glMapBufferImpl(target, false, 0, 0, access, ((GL4bcProcAddressTable)_context.getGLProcAddressTable())._addressof_glMapBuffer);
}
-/** Encapsulates function pointer for OpenGL function LPVOID glMapBuffer(GLenum target, GLenum access);
*/
-native private long dispatch_glMapBuffer(int target, int access, long glProcAddress);
+/** Entry point to C language function: void * {@native glMapBufferRange}(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);
GL_ES_VERSION_3_0
, GL_VERSION_3_0
; GL_EXT_map_buffer_range
*/
+public final ByteBuffer glMapBufferRange(int target, long offset, long length, int access) {
+ return glMapBufferImpl(target, true, offset, length, access, ((GL4bcProcAddressTable)_context.getGLProcAddressTable())._addressof_glMapBufferRange);
+}
/** Entry point to C language function: GLvoid * {@native glMapNamedBufferEXT}(GLuint buffer, GLenum access);
GL_EXT_direct_state_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");
- }
- final long sz = bufferSizeTracker.getDirectStateBufferSize(bufferName, this);
- if (0 == sz) {
- return null;
- }
- final long addr = dispatch_glMapNamedBufferEXT(bufferName, access, __addr_);
- if (0 == addr) {
- return null;
- }
- ByteBuffer buffer;
- MemoryObject memObj0 = new MemoryObject(addr, sz); // object and key
- MemoryObject memObj1 = MemoryObject.getOrAddSafe(arbMemCache, memObj0);
- if(memObj0 == memObj1) {
- // just added ..
- if(null != memObj0.getBuffer()) {
- throw new InternalError();
- }
- buffer = newDirectByteBuffer(addr, sz);
- Buffers.nativeOrder(buffer);
- memObj0.setBuffer(buffer);
- } else {
- // already mapped
- buffer = memObj1.getBuffer();
- if(null == buffer) {
- throw new InternalError();
- }
- }
- buffer.position(0);
- return buffer;
+ return glMapNamedBufferImpl(bufferName, access, ((GL4bcProcAddressTable)_context.getGLProcAddressTable())._addressof_glMapNamedBufferEXT);
}
-private native long dispatch_glMapNamedBufferEXT(int buffer, int access, long procAddress);
-
-native private ByteBuffer newDirectByteBuffer(long addr, long capacity);
-
@Override
public final void glVertexPointer(GLArrayData array) {
if(array.getComponentCount()==0) return;
diff --git a/make/config/jogl/gl-impl-CustomJavaCode-gles1.java b/make/config/jogl/gl-impl-CustomJavaCode-gles1.java
index 70425689a..2fa83dca6 100644
--- a/make/config/jogl/gl-impl-CustomJavaCode-gles1.java
+++ b/make/config/jogl/gl-impl-CustomJavaCode-gles1.java
@@ -47,6 +47,11 @@ public final boolean isGLES2() {
return false;
}
+@Override
+public final boolean isGLES3() {
+ return false;
+}
+
@Override
public final boolean isGLES() {
return true;
@@ -62,11 +67,26 @@ public final boolean isGL2ES2() {
return false;
}
+@Override
+public final boolean isGL3ES3() {
+ return false;
+}
+
+@Override
+public final boolean isGL4ES3() {
+ return false;
+}
+
@Override
public final boolean isGLES2Compatible() {
return false;
}
+@Override
+public final boolean isGLES3Compatible() {
+ return false;
+}
+
@Override
public final boolean isGL2GL3() {
return false;
@@ -117,6 +137,11 @@ public final GLES2 getGLES2() throws GLException {
throw new GLException("Not a GLES2 implementation");
}
+@Override
+public final GLES3 getGLES3() throws GLException {
+ throw new GLException("Not a GLES3 implementation");
+}
+
@Override
public final GL2ES1 getGL2ES1() throws GLException {
return this;
@@ -127,6 +152,16 @@ public final GL2ES2 getGL2ES2() throws GLException {
throw new GLException("Not a GL2ES2 implementation");
}
+@Override
+public final GL3ES3 getGL3ES3() throws GLException {
+ throw new GLException("Not a GL3ES3 implementation");
+}
+
+@Override
+public final GL4ES3 getGL4ES3() throws GLException {
+ throw new GLException("Not a GL4ES3 implementation");
+}
+
@Override
public final GL2GL3 getGL2GL3() throws GLException {
throw new GLException("Not a GL2GL3 implementation");
@@ -206,48 +241,15 @@ private final boolean checkPackPBOEnabled(boolean throwException) {
return false;
}
-private final HashMap LPVOID glMapBuffer(GLenum target, GLenum access);
*/
+/** Entry point to C language function: void * {@native glMapBuffer}(GLenum target, GLenum access);
GL_VERSION_1_5
; GL_OES_mapbuffer
*/
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");
- }
- final long sz = bufferSizeTracker.getBufferSize(bufferStateTracker, target, this);
- if (0 == sz) {
- return null;
- }
- final long addr = dispatch_glMapBuffer(target, access, __addr_);
- if (0 == addr) {
- return null;
- }
- ByteBuffer buffer;
- MemoryObject memObj0 = new MemoryObject(addr, sz); // object and key
- MemoryObject memObj1 = MemoryObject.getOrAddSafe(arbMemCache, memObj0);
- if(memObj0 == memObj1) {
- // just added ..
- if(null != memObj0.getBuffer()) {
- throw new InternalError();
- }
- buffer = newDirectByteBuffer(addr, sz);
- Buffers.nativeOrder(buffer);
- memObj0.setBuffer(buffer);
- } else {
- // already mapped
- buffer = memObj1.getBuffer();
- if(null == buffer) {
- throw new InternalError();
- }
- }
- buffer.position(0);
- return buffer;
+ return glMapBufferImpl(target, false, 0, 0, access, ((GLES1ProcAddressTable)_context.getGLProcAddressTable())._addressof_glMapBuffer);
}
-/** Encapsulates function pointer for OpenGL function LPVOID glMapBuffer(GLenum target, GLenum access);
*/
-native private long dispatch_glMapBuffer(int target, int access, long glProcAddress);
-
-native private ByteBuffer newDirectByteBuffer(long addr, long capacity);
+/** Entry point to C language function: void * {@native glMapBufferRange}(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);
GL_ES_VERSION_3_0
, GL_VERSION_3_0
; GL_EXT_map_buffer_range
*/
+public final ByteBuffer glMapBufferRange(int target, long offset, long length, int access) {
+ return glMapBufferImpl(target, true, offset, length, access, ((GLES1ProcAddressTable)_context.getGLProcAddressTable())._addressof_glMapBufferRange);
+}
@Override
public final void glVertexPointer(GLArrayData array) {
diff --git a/make/config/jogl/gl-impl-CustomJavaCode-gles2.java b/make/config/jogl/gl-impl-CustomJavaCode-gles2.java
deleted file mode 100644
index 37f3f33aa..000000000
--- a/make/config/jogl/gl-impl-CustomJavaCode-gles2.java
+++ /dev/null
@@ -1,262 +0,0 @@
-
-public GLES2Impl(GLProfile glp, GLContextImpl context) {
- this._context = context;
- if(null != context) {
- this.bufferSizeTracker = context.getBufferSizeTracker();
- this.bufferStateTracker = context.getBufferStateTracker();
- this.glStateTracker = context.getGLStateTracker();
- } else {
- this.bufferSizeTracker = null;
- this.bufferStateTracker = null;
- this.glStateTracker = null;
- }
- 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;
-}
-
-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");
-}
-
-//
-// Helpers for ensuring the correct amount of texture data
-//
-
-private final GLBufferSizeTracker bufferSizeTracker;
-private final GLBufferStateTracker bufferStateTracker;
-private final GLStateTracker glStateTracker;
-
-private final boolean checkBufferObject(boolean enabled,
- int state,
- String kind, boolean throwException) {
- final int buffer = bufferStateTracker.getBoundBufferObject(state, this);
- if (enabled) {
- if (0 == buffer) {
- if(throwException) {
- throw new GLException(kind + " must be enabled to call this method");
- }
- return false;
- }
- } else {
- if (0 != buffer) {
- if(throwException) {
- throw new GLException(kind + " must be disabled to call this method");
- }
- return false;
- }
- }
- return true;
-}
-
-private final boolean checkArrayVBODisabled(boolean throwException) {
- return checkBufferObject(false, // enabled
- GL.GL_ARRAY_BUFFER,
- "array vertex_buffer_object", throwException);
-}
-
-private final boolean checkArrayVBOEnabled(boolean throwException) {
- return checkBufferObject(true, // enabled
- GL.GL_ARRAY_BUFFER,
- "array vertex_buffer_object", throwException);
-}
-
-private final boolean checkElementVBODisabled(boolean throwException) {
- return checkBufferObject(false, // enabled
- GL.GL_ELEMENT_ARRAY_BUFFER,
- "element vertex_buffer_object", throwException);
-}
-
-private final boolean checkElementVBOEnabled(boolean throwException) {
- return checkBufferObject(true, // enabled
- GL.GL_ELEMENT_ARRAY_BUFFER,
- "element vertex_buffer_object", throwException);
-}
-
-private final boolean checkUnpackPBODisabled(boolean throwException) {
- // PBO n/a for ES 1.1 or ES 2.0
- return true;
-}
-
-private final boolean checkUnpackPBOEnabled(boolean throwException) {
- // PBO n/a for ES 1.1 or ES 2.0
- return false;
-}
-
-private final boolean checkPackPBODisabled(boolean throwException) {
- // PBO n/a for ES 1.1 or ES 2.0
- return true;
-}
-
-private final boolean checkPackPBOEnabled(boolean throwException) {
- // PBO n/a for ES 1.1 or ES 2.0
- return false;
-}
-
-private final HashMap LPVOID glMapBuffer(GLenum target, GLenum 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");
- }
- final long sz = bufferSizeTracker.getBufferSize(bufferStateTracker, target, this);
- if (0 == sz) {
- return null;
- }
- final long addr = dispatch_glMapBuffer(target, access, __addr_);
- if (0 == addr) {
- return null;
- }
- ByteBuffer buffer;
- MemoryObject memObj0 = new MemoryObject(addr, sz); // object and key
- MemoryObject memObj1 = MemoryObject.getOrAddSafe(arbMemCache, memObj0);
- if(memObj0 == memObj1) {
- // just added ..
- if(null != memObj0.getBuffer()) {
- throw new InternalError();
- }
- buffer = newDirectByteBuffer(addr, sz);
- Buffers.nativeOrder(buffer);
- memObj0.setBuffer(buffer);
- } else {
- // already mapped
- buffer = memObj1.getBuffer();
- if(null == buffer) {
- throw new InternalError();
- }
- }
- buffer.position(0);
- return buffer;
-}
-
-/** Encapsulates function pointer for OpenGL function LPVOID glMapBuffer(GLenum target, GLenum access);
*/
-native private long dispatch_glMapBuffer(int target, int access, long glProcAddress);
-
-native private ByteBuffer newDirectByteBuffer(long addr, long capacity);
-
-@Override
-public final void glClearDepth(double depth) {
- glClearDepthf((float)depth);
-}
-
-@Override
-public final void glDepthRange(double zNear, double zFar) {
- glDepthRangef((float)zNear, (float)zFar);
-}
-
diff --git a/make/config/jogl/gl-impl-CustomJavaCode-gles3.java b/make/config/jogl/gl-impl-CustomJavaCode-gles3.java
new file mode 100644
index 000000000..e0b0c6a09
--- /dev/null
+++ b/make/config/jogl/gl-impl-CustomJavaCode-gles3.java
@@ -0,0 +1,320 @@
+
+public GLES3Impl(GLProfile glp, GLContextImpl context) {
+ this._context = context;
+ if(null != context) {
+ this.bufferSizeTracker = context.getBufferSizeTracker();
+ this.bufferStateTracker = context.getBufferStateTracker();
+ this.glStateTracker = context.getGLStateTracker();
+ } else {
+ this.bufferSizeTracker = null;
+ this.bufferStateTracker = null;
+ this.glStateTracker = null;
+ }
+ this.glProfile = glp;
+ this._isES3 = glp.getImplName() == GLProfile.GLES3;
+}
+
+@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;
+}
+
+public final boolean isGL2() {
+ return false;
+}
+
+@Override
+public final boolean isGLES1() {
+ return false;
+}
+
+@Override
+public final boolean isGLES2() {
+ return true;
+}
+
+@Override
+public final boolean isGLES3() {
+ return _isES3;
+}
+
+@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 isGL3ES3() {
+ return _isES3;
+}
+
+@Override
+public final boolean isGL4ES3() {
+ return _isES3;
+}
+
+@Override
+public final boolean isGLES2Compatible() {
+ return true;
+}
+
+@Override
+public final boolean isGLES3Compatible() {
+ return _isES3;
+}
+
+
+@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 GLES3 getGLES3() 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 GL3ES3 getGL3ES3() throws GLException {
+ if(!_isES3) {
+ throw new GLException("Not a GL3ES3 implementation");
+ }
+ return this;
+}
+
+@Override
+public final GL4ES3 getGL4ES3() throws GLException {
+ if(!_isES3) {
+ throw new GLException("Not a GL4ES3 implementation");
+ }
+ return this;
+}
+
+@Override
+public final GL2GL3 getGL2GL3() throws GLException {
+ throw new GLException("Not a GL2GL3 implementation");
+}
+
+//
+// Helpers for ensuring the correct amount of texture data
+//
+
+private final boolean _isES3;
+private final GLBufferSizeTracker bufferSizeTracker;
+private final GLBufferStateTracker bufferStateTracker;
+private final GLStateTracker glStateTracker;
+
+private final boolean checkBufferObject(boolean extensionAvail,
+ boolean allowVAO,
+ boolean enabled,
+ int state,
+ String kind, boolean throwException) {
+ if ( !extensionAvail ) {
+ if ( !enabled ) {
+ return true;
+ }
+ if(throwException) {
+ throw new GLException("Required extensions not available to call this function");
+ }
+ return false;
+ }
+ int buffer = bufferStateTracker.getBoundBufferObject(state, this);
+ if ( enabled ) {
+ if ( 0 != buffer ) {
+ return true;
+ }
+ if ( allowVAO ) {
+ buffer = bufferStateTracker.getBoundBufferObject(GLES3.GL_VERTEX_ARRAY_BINDING, this);
+ if( 0 != buffer && !_context.isDefaultVAO(buffer) ) {
+ return true;
+ }
+ }
+ if ( throwException ) {
+ throw new GLException(kind + " must be enabled to call this method");
+ }
+ return false;
+ } else {
+ if ( 0 == buffer ) {
+ return true;
+ }
+ if ( throwException ) {
+ throw new GLException(kind + " must be disabled to call this method");
+ }
+ return false;
+ }
+}
+
+private final boolean checkArrayVBODisabled(boolean throwException) {
+ return checkBufferObject(true,
+ _isES3, // allowVAO
+ false, // enable
+ GL.GL_ARRAY_BUFFER,
+ "array vertex_buffer_object", throwException);
+}
+
+private final boolean checkArrayVBOEnabled(boolean throwException) {
+ return checkBufferObject(true,
+ _isES3, // allowVAO
+ true, // enable
+ GL.GL_ARRAY_BUFFER,
+ "array vertex_buffer_object", throwException);
+}
+
+private final boolean checkElementVBODisabled(boolean throwException) {
+ return checkBufferObject(true,
+ _isES3, // allowVAO
+ false, // enable
+ GL.GL_ELEMENT_ARRAY_BUFFER,
+ "element vertex_buffer_object", throwException);
+}
+
+private final boolean checkElementVBOEnabled(boolean throwException) {
+ return checkBufferObject(true,
+ _isES3, // allowVAO
+ true, // enable
+ GL.GL_ELEMENT_ARRAY_BUFFER,
+ "element vertex_buffer_object", throwException);
+}
+
+private final boolean checkUnpackPBODisabled(boolean throwException) {
+ return checkBufferObject(_isES3,
+ false, // allowVAO
+ false, // enable
+ GL2.GL_PIXEL_UNPACK_BUFFER,
+ "unpack pixel_buffer_object", throwException);
+}
+
+private final boolean checkUnpackPBOEnabled(boolean throwException) {
+ return checkBufferObject(_isES3,
+ false, // allowVAO
+ true, // enable
+ GL2.GL_PIXEL_UNPACK_BUFFER,
+ "unpack pixel_buffer_object", throwException);
+}
+
+private final boolean checkPackPBODisabled(boolean throwException) {
+ return checkBufferObject(_isES3,
+ false, // allowVAO
+ false, // enable
+ GL2.GL_PIXEL_PACK_BUFFER,
+ "pack pixel_buffer_object", throwException);
+}
+
+private final boolean checkPackPBOEnabled(boolean throwException) {
+ return checkBufferObject(_isES3,
+ false, // allowVAO
+ true, // enable
+ GL2.GL_PIXEL_PACK_BUFFER,
+ "pack pixel_buffer_object", throwException);
+}
+
+@Override
+public final boolean glIsPBOPackEnabled() {
+ return checkPackPBOEnabled(false);
+}
+
+@Override
+public final boolean glIsPBOUnpackEnabled() {
+ return checkUnpackPBOEnabled(false);
+}
+
+/** Entry point to C language function: void * {@native glMapBuffer}(GLenum target, GLenum access);
GL_VERSION_1_5
; GL_OES_mapbuffer
*/
+public final java.nio.ByteBuffer glMapBuffer(int target, int access) {
+ return glMapBufferImpl(target, false, 0, 0, access, ((GLES3ProcAddressTable)_context.getGLProcAddressTable())._addressof_glMapBuffer);
+}
+
+/** Entry point to C language function: void * {@native glMapBufferRange}(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);
GL_ES_VERSION_3_0
, GL_VERSION_3_0
; GL_EXT_map_buffer_range
*/
+public final ByteBuffer glMapBufferRange(int target, long offset, long length, int access) {
+ return glMapBufferImpl(target, true, offset, length, access, ((GLES3ProcAddressTable)_context.getGLProcAddressTable())._addressof_glMapBufferRange);
+}
+
+@Override
+public final void glClearDepth(double depth) {
+ glClearDepthf((float)depth);
+}
+
+@Override
+public final void glDepthRange(double zNear, double zFar) {
+ glDepthRangef((float)zNear, (float)zFar);
+}
+
diff --git a/make/config/jogl/gl2_es2-CustomJavaCode.cfg b/make/config/jogl/gl2_es2-CustomJavaCode.cfg
new file mode 100644
index 000000000..b769f3b29
--- /dev/null
+++ b/make/config/jogl/gl2_es2-CustomJavaCode.cfg
@@ -0,0 +1,13 @@
+
+JavaPrologue glReleaseShaderCompiler if ( !_context.isGLES2Compatible() ) {
+JavaPrologue glReleaseShaderCompiler return;
+JavaPrologue glReleaseShaderCompiler }
+
+JavaPrologue glShaderBinary if ( !_context.isGLES2Compatible() ) {
+JavaPrologue glShaderBinary throw new GLException("Method \"glShaderBinary\" not available");
+JavaPrologue glShaderBinary }
+
+JavaPrologue glGetShaderPrecisionFormat if ( !_context.isGLES2Compatible() ) {
+JavaPrologue glGetShaderPrecisionFormat throw new GLException("Method \"glGetShaderPrecisionFormat\" not available");
+JavaPrologue glGetShaderPrecisionFormat }
+
diff --git a/make/config/jogl/gl2_es2-common.cfg b/make/config/jogl/gl2_es2-common.cfg
index b769f3b29..2ad7fd3fd 100644
--- a/make/config/jogl/gl2_es2-common.cfg
+++ b/make/config/jogl/gl2_es2-common.cfg
@@ -1,13 +1,11 @@
-JavaPrologue glReleaseShaderCompiler if ( !_context.isGLES2Compatible() ) {
-JavaPrologue glReleaseShaderCompiler return;
-JavaPrologue glReleaseShaderCompiler }
+RenameExtensionIntoCore GL_KHR_debug
+RenameExtensionIntoCore GL_OES_texture_3D
+RenameExtensionIntoCore GL_OES_get_program_binary
+RenameExtensionIntoCore GL_OES_required_internalformat
+RenameExtensionIntoCore GL_EXT_unpack_subimage
-JavaPrologue glShaderBinary if ( !_context.isGLES2Compatible() ) {
-JavaPrologue glShaderBinary throw new GLException("Method \"glShaderBinary\" not available");
-JavaPrologue glShaderBinary }
+ForceExtension GL_EXT_occlusion_query_boolean
-JavaPrologue glGetShaderPrecisionFormat if ( !_context.isGLES2Compatible() ) {
-JavaPrologue glGetShaderPrecisionFormat throw new GLException("Method \"glGetShaderPrecisionFormat\" not available");
-JavaPrologue glGetShaderPrecisionFormat }
+ForceExtension GL_ARB_ES2_compatibility
diff --git a/make/config/jogl/gl2_es3-common.cfg b/make/config/jogl/gl2_es3-common.cfg
new file mode 100644
index 000000000..b5326b159
--- /dev/null
+++ b/make/config/jogl/gl2_es3-common.cfg
@@ -0,0 +1,9 @@
+
+RenameExtensionIntoCore GL_KHR_debug
+RenameExtensionIntoCore GL_OES_texture_3D
+IgnoreExtension GL_OES_get_program_binary
+RenameExtensionIntoCore GL_OES_required_internalformat
+RenameExtensionIntoCore GL_EXT_unpack_subimage
+
+ForceExtension GL_EXT_occlusion_query_boolean
+
diff --git a/make/config/jogl/gl3-common.cfg b/make/config/jogl/gl3-common.cfg
new file mode 100644
index 000000000..e11c50aa3
--- /dev/null
+++ b/make/config/jogl/gl3-common.cfg
@@ -0,0 +1,9 @@
+
+ForceExtension GL_ARB_debug_output
+RenameExtensionIntoCore GL_KHR_debug
+
+RenameExtensionIntoCore GL_OES_texture_3D
+IgnoreExtension GL_OES_get_program_binary
+RenameExtensionIntoCore GL_OES_required_internalformat
+RenameExtensionIntoCore GL_EXT_unpack_subimage
+
diff --git a/make/config/jogl/gl3-desktop.cfg b/make/config/jogl/gl3-desktop.cfg
index 96e59aa05..4a2c53371 100644
--- a/make/config/jogl/gl3-desktop.cfg
+++ b/make/config/jogl/gl3-desktop.cfg
@@ -1,11 +1,6 @@
# This .cfg file provides common options used by the desktop OpenGL
# implementation on all platforms.
-# Inform the glue code generator of the association between #defines
-# and functions and the extensions in which they are defined
-GLHeader GL3/gl3.h
-GLHeader GL3/gl3ext.h
-
#Include gl-desktop-tracker.cfg
#
diff --git a/make/config/jogl/gl3-headers.cfg b/make/config/jogl/gl3-headers.cfg
index 8b35a07b4..7ab5099c9 100644
--- a/make/config/jogl/gl3-headers.cfg
+++ b/make/config/jogl/gl3-headers.cfg
@@ -1,7 +1,6 @@
CustomCCode #include ");
+ writer.print(funcSym.getType().toString(symbolRenamed, tagNativeBinding));
+ writer.print("
");
+
newComment.append("+ * Remark: ES3 compatible desktop profiles are not included. + * To query whether core ES3 functionality is provided, use {@link #isGLES3Compatible()}. + *
+ * @see #isGLES3Compatible() + */ + public boolean isGLES3(); + /** * Indicates whether this GL object conforms to one of the OpenGL ES profiles, * see {@link #isGLES1()} and {@link #isGLES2()}. @@ -146,6 +156,21 @@ public interface GLBase { */ public boolean isGL2ES2(); + /** + * Indicates whether this GL object conforms to a GL3ES3 compatible profile. + */ + public boolean isGL3ES3(); + + /** + * Indicates whether this GL object conforms to a GL4ES3 compatible profile. + */ + public boolean isGL4ES3(); + + /** + * Indicates whether this GL object conforms to a GL2GL3 compatible profile. + */ + public boolean isGL2GL3(); + /** * Indicates whether this GL object is compatible with the core OpenGL ES2 functionality. * @return true if this context is an ES2 context or implements @@ -154,9 +179,11 @@ public interface GLBase { public boolean isGLES2Compatible(); /** - * Indicates whether this GL object conforms to a GL2GL3 compatible profile. + * Indicates whether this GL object is compatible with the core OpenGL ES3 functionality. + * @return true if this context is an ES3 context or implements + * the extensionGL_ARB_ES3_compatibility
, otherwise false
*/
- public boolean isGL2GL3();
+ public boolean isGLES3Compatible();
/** Indicates whether this GL object supports GLSL. */
public boolean hasGLSL();
@@ -209,6 +236,12 @@ public interface GLBase {
*/
public GLES2 getGLES2() throws GLException;
+ /**
+ * Casts this object to the GLES3 interface.
+ * @throws GLException if this GLObject is not a GLES3 implementation
+ */
+ public GLES3 getGLES3() throws GLException;
+
/**
* Casts this object to the GL2ES1 interface.
* @throws GLException if this GLObject is not a GL2ES1 implementation
@@ -221,6 +254,18 @@ public interface GLBase {
*/
public GL2ES2 getGL2ES2() throws GLException;
+ /**
+ * Casts this object to the GL3ES3 interface.
+ * @throws GLException if this GLObject is not a GL3ES3 implementation
+ */
+ public GL3ES3 getGL3ES3() throws GLException;
+
+ /**
+ * Casts this object to the GL4ES3 interface.
+ * @throws GLException if this GLObject is not a GL3ES3 implementation
+ */
+ public GL4ES3 getGL4ES3() throws GLException;
+
/**
* Casts this object to the GL2GL3 interface.
* @throws GLException if this GLObject is not a GL2GL3 implementation
diff --git a/src/jogl/classes/javax/media/opengl/GLContext.java b/src/jogl/classes/javax/media/opengl/GLContext.java
index daede5ac0..b27db18af 100644
--- a/src/jogl/classes/javax/media/opengl/GLContext.java
+++ b/src/jogl/classes/javax/media/opengl/GLContext.java
@@ -142,6 +142,13 @@ public abstract class GLContext {
protected static final VersionNumber Version800 = new VersionNumber(8, 0, 0);
+ //
+ // Cached keys, bits [0..15]
+ //
+
+ /** Cached bit mask covering bits [0..15], i.e. {@value}. */
+ protected static final int CTX_IMPL_CACHE_MASK = 0x0000FFFF;
+
/** ARB_create_context
related: created via ARB_create_context. Cache key value. See {@link #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)}. */
protected static final int CTX_IS_ARB_CREATED = 1 << 0;
/** ARB_create_context
related: desktop compatibility profile. Cache key value. See {@link #isGLCompatibilityProfile()}, {@link #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)}. */
@@ -154,20 +161,36 @@ public abstract class GLContext {
protected static final int CTX_OPTION_FORWARD = 1 << 4;
/** 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;
+ /** 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 << 6;
+ //
+ // Non cached keys, bits [16..31]
+ //
+
/** 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;
+ protected static final int CTX_IMPL_ES2_COMPAT = 1 << 16;
- /** Context supports basic FBO, details see {@link #hasBasicFBOSupport()}.
+ /** GL_ARB_ES3_compatibility
implementation related: Context is compatible w/ ES3. Not a cache key. See {@link #isGLES3Compatible()}, {@link #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)}. */
+ protected static final int CTX_IMPL_ES3_COMPAT = 1 << 17;
+
+ /**
+ * Context supports basic FBO, details see {@link #hasBasicFBOSupport()}.
* Not a cache key.
* @see #hasBasicFBOSupport()
* @see #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)
*/
- protected static final int CTX_IMPL_FBO = 1 << 9;
-
- /** 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 int CTX_IMPL_FBO = 1 << 18;
+ /**
+ * Context supports OES_single_precision
, fp32, fixed function point (FFP) compatibility entry points,
+ * see {@link #hasFP32CompatAPI()}.
+ * Not a cache key.
+ * @see #hasFP32CompatAPI()
+ * @see #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)
+ */
+ protected static final int CTX_IMPL_FP32_COMPAT_API = 1 << 19;
+
private static final ThreadLocalGL_ARB_ES2_compatibility
, otherwise false
+ * the extension GL_ARB_ES3_compatibility
or GL_ARB_ES2_compatibility
, otherwise false
*/
public final boolean isGLES2Compatible() {
- return 0 != ( ctxOptions & CTX_IMPL_ES2_COMPAT ) ;
+ return 0 != ( ctxOptions & ( CTX_IMPL_ES3_COMPAT | CTX_IMPL_ES2_COMPAT ) ) ;
+ }
+
+ /**
+ * @return true if this context is an ES3 context or implements
+ * the extension GL_ARB_ES3_compatibility
, otherwise false
+ */
+ public final boolean isGLES3Compatible() {
+ return 0 != ( ctxOptions & CTX_IMPL_ES3_COMPAT ) ;
}
/**
@@ -819,6 +850,15 @@ public abstract class GLContext {
return 0 != ( ctxOptions & CTX_IMPL_FBO ) ;
}
+ /**
+ * Returns true
if OES_single_precision
, fp32, fixed function point (FFP) compatibility entry points available,
+ * otherwise false
.
+ * @see #CTX_IMPL_FP32_COMPAT_API
+ */
+ public final boolean hasFP32CompatAPI() {
+ return 0 != ( ctxOptions & CTX_IMPL_FP32_COMPAT_API ) ;
+ }
+
/**
* Returns true
if full FBO support is available, otherwise false
.
* @@ -895,28 +935,30 @@ public abstract class GLContext { /** @see GLProfile#isGL3bc() */ public final boolean isGL3bc() { - return ctxVersion.compareTo(Version310) >= 0 - && 0 != (ctxOptions & CTX_IS_ARB_CREATED) - && 0 != (ctxOptions & CTX_PROFILE_COMPAT); + return 0 != (ctxOptions & CTX_IS_ARB_CREATED) && + 0 != (ctxOptions & CTX_PROFILE_COMPAT) && + ctxVersion.compareTo(Version310) >= 0 ; } /** @see GLProfile#isGL3() */ public final boolean isGL3() { - return ctxVersion.compareTo(Version310) >= 0 - && 0 != (ctxOptions & CTX_IS_ARB_CREATED) - && 0 != (ctxOptions & (CTX_PROFILE_COMPAT|CTX_PROFILE_CORE)); + return 0 != (ctxOptions & CTX_IS_ARB_CREATED) && + 0 != (ctxOptions & (CTX_PROFILE_COMPAT|CTX_PROFILE_CORE)) && + ctxVersion.compareTo(Version310) >= 0 ; } - /** Indicates whether this profile is capable of GL3 (core only). GL3 starts w/ OpenGL 3.1
Includes [ GL4, GL3 ].
*/ + /** Indicates whether this profile is capable of GL3 (core only). GL3 starts w/ OpenGL 3.1Includes [ GL4, GL3, GLES3 ].
*/ public final boolean isGL3core() { - return ctxVersion.compareTo(Version310) >= 0 - && 0 != (ctxOptions & CTX_IS_ARB_CREATED) - && 0 != (ctxOptions & CTX_PROFILE_CORE); + return ( 0 != ( ctxOptions & CTX_PROFILE_ES ) && ctxVersion.getMajor() >= 3 ) || + ( 0 != ( ctxOptions & CTX_IS_ARB_CREATED ) && + 0 != ( ctxOptions & CTX_PROFILE_CORE ) && + ctxVersion.compareTo(Version310) >= 0 + ) ; } /** @see GLProfile#isGL2() */ public final boolean isGL2() { - return ctxVersion.getMajor()>=1 && 0!=(ctxOptions & CTX_PROFILE_COMPAT); + return 0 != ( ctxOptions & CTX_PROFILE_COMPAT ) && ctxVersion.getMajor()>=1 ; } /** @see GLProfile#isGL2GL3() */ @@ -926,12 +968,17 @@ public abstract class GLContext { /** @see GLProfile#isGLES1() */ public final boolean isGLES1() { - return ctxVersion.getMajor() == 1 && 0 != ( ctxOptions & CTX_PROFILE_ES ) ; + return 0 != ( ctxOptions & CTX_PROFILE_ES ) && ctxVersion.getMajor() == 1 ; } /** @see GLProfile#isGLES2() */ public final boolean isGLES2() { - return ctxVersion.getMajor() == 2 && 0 != ( ctxOptions & CTX_PROFILE_ES ) ; + return 0 != ( ctxOptions & CTX_PROFILE_ES ) && ctxVersion.getMajor() >= 2 ; + } + + /** @see GLProfile#isGLES3() */ + public final boolean isGLES3() { + return 0 != ( ctxOptions & CTX_PROFILE_ES ) && ctxVersion.getMajor() >= 3 ; } /** @see GLProfile#isGLES() */ @@ -941,12 +988,22 @@ public abstract class GLContext { /** @see GLProfile#isGL2ES1() */ public final boolean isGL2ES1() { - return isGL2() || isGLES1() ; + return isGLES1() || isGL2(); } /** @see GLProfile#isGL2ES2() */ public final boolean isGL2ES2() { - return isGL2GL3() || isGLES2() ; + return isGLES2() || isGL2GL3(); + } + + /** @see GLProfile#isGL3ES3() */ + public final boolean isGL3ES3() { + return isGL4ES3() || isGL3(); + } + + /** @see GLProfile#isGL4ES3() */ + public final boolean isGL4ES3() { + return isGL4() || isGLES3() ; } /** @@ -1157,45 +1214,73 @@ public abstract class GLContext { /* 1.*/ { 0, 1, 2, 3, 4, 5 }, /* 2.*/ { 0, 1 }, /* 3.*/ { 0, 1, 2, 3 }, - /* 4.*/ { 0, 1, 2 } }; // FIXME add 4.3 ! + /* 4.*/ { 0, 1, 2, 3 } }; - private static final int GL_VERSIONS_VALID[][] = { + public static final int ES_VERSIONS[][] = { /* 0.*/ { -1 }, - /* 1.*/ { 0, 1, 2, 3, 4, 5 }, - /* 2.*/ { 0, 1 }, - /* 3.*/ { 0, 1, 2, 3 }, - /* 4.*/ { 0, 1, 2, 3, 4 } }; // 4.4 coming up soon ? + /* 1.*/ { 0, 1 }, + /* 2.*/ { 0 }, + /* 3.*/ { 0 } }; - public static final int getMaxMajor() { - return GL_VERSIONS.length-1; + public static final int getMaxMajor(int ctxProfile) { + return ( 0 != ( CTX_PROFILE_ES & ctxProfile ) ) ? ES_VERSIONS.length-1 : GL_VERSIONS.length-1; } - public static final int getMaxMinor(int major) { - if(1>major || major>=GL_VERSIONS.length) return -1; - return GL_VERSIONS[major].length-1; + public static final int getMaxMinor(int ctxProfile, int major) { + if( 1>major ) { + return -1; + } + if( ( 0 != ( CTX_PROFILE_ES & ctxProfile ) ) ) { + if( major>=ES_VERSIONS.length ) return -1; + return ES_VERSIONS[major].length-1; + } else { + if( major>=GL_VERSIONS.length ) return -1; + return GL_VERSIONS[major].length-1; + } } - public static final boolean isValidGLVersion(int major, int minor) { - if(1>major || major>=GL_VERSIONS_VALID.length) return false; - if(0>minor || minor>=GL_VERSIONS_VALID[major].length) return false; + public static final boolean isValidGLVersion(int ctxProfile, int major, int minor) { + if( 1>major || 0>minor ) { + return false; + } + if( ( 0 != ( CTX_PROFILE_ES & ctxProfile ) ) ) { + if( major>=ES_VERSIONS.length) return false; + if( minor>=ES_VERSIONS[major].length) return false; + } else { + if( major>=GL_VERSIONS.length) return false; + if( minor>=GL_VERSIONS[major].length) return false; + } return true; } - public static final boolean decrementGLVersion(int major[], int minor[]) { + public static final boolean decrementGLVersion(int ctxProfile, int major[], int minor[]) { if(null==major || major.length<1 ||null==minor || minor.length<1) { throw new GLException("invalid array arguments"); } int m = major[0]; int n = minor[0]; - if(!isValidGLVersion(m, n)) return false; + if( !isValidGLVersion(ctxProfile, m, n) ) { + return false; + } // decrement .. n -= 1; if(n < 0) { - m -= 1; - n = GL_VERSIONS[m].length-1; + if( ( 0 != ( CTX_PROFILE_ES & ctxProfile ) ) ) { + if( m >= 3) { + m -= 1; + } else { + m = 0; // major decr [1,2] -> 0 + } + n = ES_VERSIONS[m].length-1; + } else { + m -= 1; + n = GL_VERSIONS[m].length-1; + } + } + if( !isValidGLVersion(ctxProfile, m, n) ) { + return false; } - if(!isValidGLVersion(m, n)) return false; major[0]=m; minor[0]=n; @@ -1299,9 +1384,9 @@ public abstract class GLContext { } } - protected static StringBuffer dumpAvailableGLVersions(StringBuffer sb) { + protected static StringBuilder dumpAvailableGLVersions(StringBuilder sb) { if(null == sb) { - sb = new StringBuffer(); + sb = new StringBuilder(); } synchronized(deviceVersionAvailable) { final SetThis includes the generic subset profiles GL2GL3, GL2ES2 and GL2ES1.
* *+ * GLProfile.get(device, GLProfile.GL4ES3).getImpl()); + *+ *
Selection favors hardware rasterizer.
+ * + * @throws GLException if no GL4ES3 compatible profile is available for the default device. + * @see #isGL4ES3() + * @see #get(AbstractGraphicsDevice, String) + * @see #getImpl() + */ + public static GLProfile getGL4ES3(AbstractGraphicsDevice device) + throws GLException + { + return get(device, GL4ES3).getImpl(); + } + + /** + * Calls {@link #getGL4ES3(AbstractGraphicsDevice)} using the default device. + *Selection favors hardware rasterizer.
+ * @see #getGL4ES3(AbstractGraphicsDevice) + */ + public static GLProfile getGL4ES3() + throws GLException + { + return get(defaultDevice, GL4ES3).getImpl(); + } + /** * Returns the GL2GL3 profile implementation, hence compatible w/ GL2GL3.Includes [ GLES2 ].
*/ + /** Indicates whether this profile is capable of GLES2.Includes [ GLES3, GLES2 ].
*/ public final boolean isGLES2() { - return GLES2 == profile; + return GLES3 == profile || GLES2 == profile; } - /** Indicates whether this profile is capable of GLES.Includes [ GLES1, GLES2 ].
*/ + /** Indicates whether this profile is capable of GLES3.Includes [ GLES3 ].
*/ + public final boolean isGLES3() { + return GLES3 == profile; + } + + /** Indicates whether this profile is capable of GLES.Includes [ GLES3, GLES1, GLES2 ].
*/ public final boolean isGLES() { - return GLES2 == profile || GLES1 == profile; + return GLES3 == profile || GLES2 == profile || GLES1 == profile; } /** Indicates whether this profile is capable of GL2ES1.Includes [ GL4bc, GL3bc, GL2, GLES1, GL2ES1 ].
*/ @@ -1050,17 +1122,27 @@ public class GLProfile { return GL2ES1 == profile || isGLES1() || isGL2(); } - /** Indicates whether this profile is capable os GL2GL3.Includes [ GL4bc, GL4, GL3bc, GL3, GL2, GL2GL3 ].
*/ + /** Indicates whether this profile is capable of GL2GL3.Includes [ GL4bc, GL4, GL3bc, GL3, GL2, GL2GL3 ].
*/ public final boolean isGL2GL3() { return GL2GL3 == profile || isGL3() || isGL2(); } - - /** Indicates whether this profile is capable os GL2ES2.Includes [ GL4bc, GL4, GL3bc, GL3, GL2, GL2GL3, GL2ES2, GLES2 ].
*/ + + /** Indicates whether this profile is capable of GL2ES2.Includes [ GL4bc, GL4, GL3bc, GL3, GLES3, GL2, GL2GL3, GL2ES2, GLES2 ].
*/ public final boolean isGL2ES2() { return GL2ES2 == profile || isGLES2() || isGL2GL3(); } - /** Indicates whether this profile supports GLSL, ie. {@link #isGL2ES2()}. */ + /** Indicates whether this profile is capable of GL3ES3.Includes [ GL4bc, GL4, GL3bc, GL3, GLES3 ].
*/ + public final boolean isGL3ES3() { + return isGL4ES3() || isGL3(); + } + + /** Indicates whether this profile is capable of GL4ES3.Includes [ GL4bc, GL4, GLES3 ].
*/ + public final boolean isGL4ES3() { + return GL4ES3 == profile || isGLES3() || isGL4(); + } + + /** Indicates whether this profile supports GLSL, i.e. {@link #isGL2ES2()}. */ public final boolean hasGLSL() { return isGL2ES2() ; } @@ -1072,7 +1154,12 @@ public class GLProfile { /** Indicates whether this profile uses the native OpenGL ES2 implementations. */ public final boolean usesNativeGLES2() { - return GLES2 == getImplName(); + return GLES3 == getImplName() || GLES2 == getImplName(); + } + + /** Indicates whether this profile uses the native OpenGL ES2 implementations. */ + public final boolean usesNativeGLES3() { + return GLES3 == getImplName(); } /** Indicates whether this profile uses either of the native OpenGL ES implementations. */ @@ -1117,8 +1204,8 @@ public class GLProfile { public boolean isValidArrayDataType(int index, int comps, int type, boolean isVertexAttribPointer, boolean throwException) { - String arrayName = getGLArrayName(index); - if(isGLES1()) { + final String arrayName = getGLArrayName(index); + if( isGLES1() ) { if(isVertexAttribPointer) { if(throwException) { throw new GLException("Illegal array type for "+arrayName+" on profile GLES1: VertexAttribPointer"); @@ -1201,7 +1288,7 @@ public class GLProfile { } break; } - } else if(isGLES2()) { + } else if( isGLES2() ) { // simply ignore !isVertexAttribPointer case, since it is simulated anyway .. switch(type) { case GL.GL_UNSIGNED_BYTE: @@ -1386,7 +1473,7 @@ public class GLProfile { private static /*final*/ boolean hasDesktopGLFactory; private static /*final*/ boolean hasGL234Impl; private static /*final*/ boolean hasEGLFactory; - private static /*final*/ boolean hasGLES2Impl; + private static /*final*/ boolean hasGLES3Impl; private static /*final*/ boolean hasGLES1Impl; private static /*final*/ GLDrawableFactoryImpl eglFactory = null; @@ -1419,7 +1506,7 @@ public class GLProfile { // depends on hasEGLFactory hasGLES1Impl = ReflectionUtil.isClassAvailable("jogamp.opengl.es1.GLES1Impl", classloader); - hasGLES2Impl = ReflectionUtil.isClassAvailable("jogamp.opengl.es2.GLES2Impl", classloader); + hasGLES3Impl = ReflectionUtil.isClassAvailable("jogamp.opengl.es3.GLES3Impl", classloader); // // Iteration of desktop GL availability detection @@ -1471,8 +1558,8 @@ public class GLProfile { eglFactory = (GLDrawableFactoryImpl) GLDrawableFactory.getFactoryImpl(GLES2); if(null != eglFactory) { hasEGLFactory = true; - // update hasGLES1Impl, hasGLES2Impl based on EGL - hasGLES2Impl = null!=eglFactory.getGLDynamicLookupHelper(2) && hasGLES2Impl; + // update hasGLES1Impl, hasGLES3Impl based on EGL + hasGLES3Impl = null!=eglFactory.getGLDynamicLookupHelper(2) && hasGLES3Impl; hasGLES1Impl = null!=eglFactory.getGLDynamicLookupHelper(1) && hasGLES1Impl; } } catch (LinkageError le) { @@ -1493,7 +1580,7 @@ public class GLProfile { final AbstractGraphicsDevice defaultEGLDevice; if(null == eglFactory) { - hasGLES2Impl = false; + hasGLES3Impl = false; hasGLES1Impl = false; defaultEGLDevice = null; if(DEBUG) { @@ -1532,7 +1619,7 @@ public class GLProfile { 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 hasGLES3Impl "+hasGLES3Impl); System.err.println("GLProfile.init defaultDevice "+defaultDevice); System.err.println("GLProfile.init defaultDevice Desktop "+defaultDesktopDevice); System.err.println("GLProfile.init defaultDevice EGL "+defaultEGLDevice); @@ -1609,8 +1696,8 @@ public class GLProfile { final boolean deviceIsEGLCompatible = hasEGLFactory && eglFactory.getIsDeviceCompatible(device); - // also test GLES1 and GLES2 on desktop, since we have implementations / emulations available. - if( deviceIsEGLCompatible && ( hasGLES2Impl || hasGLES1Impl ) ) { + // also test GLES1, GLES2 and GLES3 on desktop, since we have implementations / emulations available. + if( deviceIsEGLCompatible && ( hasGLES3Impl || hasGLES1Impl ) ) { // 1st pretend we have all EGL profiles .. computeProfileMap(device, false /* desktopCtxUndef*/, true /* esCtxUndef */); @@ -1629,7 +1716,7 @@ public class GLProfile { // but it seems even EGL.eglInitialize(eglDisplay, null, null) // fails in some scenarios (eg VirtualBox 4.1.6) w/ EGL error 0x3001 (EGL_NOT_INITIALIZED). hasEGLFactory = false; - hasGLES2Impl = false; + hasGLES3Impl = false; hasGLES1Impl = false; } if (DEBUG) { @@ -1647,7 +1734,7 @@ public class GLProfile { System.err.println("GLProfile: desktoplFactory "+desktopFactory); System.err.println("GLProfile: eglFactory "+eglFactory); System.err.println("GLProfile: hasGLES1Impl "+hasGLES1Impl); - System.err.println("GLProfile: hasGLES2Impl "+hasGLES2Impl); + System.err.println("GLProfile: hasGLES3Impl "+hasGLES3Impl); } } @@ -1725,18 +1812,18 @@ public class GLProfile { final boolean isHardwareRasterizer[] = new boolean[1]; GLProfile defaultGLProfileAny = null; GLProfile defaultGLProfileHW = null; - HashMap+ * Method calls 'void finalizeInit()' of instance 'gl' as retrieved by reflection, if exist. + *
+ */ + private void finalizeInit(GL gl) { + Method finalizeInit = null; + try { + finalizeInit = ReflectionUtil.getMethod(gl.getClass(), "finalizeInit", new Class>[]{ }); + } catch ( Throwable t ) { + if(DEBUG) { + System.err.println("Catched "+t.getClass().getName()+": "+t.getMessage()); + t.printStackTrace(); + } + } + if( null != finalizeInit ) { + ReflectionUtil.callMethod(gl, finalizeInit, new Object[]{ }); + } + } public final ProcAddressTable getGLProcAddressTable() { return glProcAddressTable; @@ -1097,8 +1125,24 @@ public abstract class GLContextImpl extends GLContext { * ie for GLXExt, EGLExt, .. */ public abstract ProcAddressTable getPlatformExtProcAddressTable(); + + /** + * Part ofGL_NV_vertex_array_range
.
+ *
+ * Provides platform-independent access to the wglAllocateMemoryNV
/
+ * glXAllocateMemoryNV
.
+ *
GL_NV_vertex_array_range
.
+ *
+ * Provides platform-independent access to the wglFreeMemoryNV
/
+ * glXFreeMemoryNV
.
+ *
+ * Covering ES3 and ES2. + *
+ */ public final class EGLES2DynamicLibraryBundleInfo extends EGLDynamicLibraryBundleInfo { protected EGLES2DynamicLibraryBundleInfo() { super(); @@ -40,18 +45,33 @@ public final class EGLES2DynamicLibraryBundleInfo extends EGLDynamicLibraryBundl { final ListDefault: true
. */ + public static final int GEN_DEBUG = 1 << 0; + /**Default: true
. */ + public static final int GEN_TRACE = 1 << 1; + /**Default: false
. */ public static final int GEN_CUSTOM = 1 << 2; + /** + * By extra command-line argument:prolog_xor_downstream
.
+ * + * If true, either prolog (if exist) is called or downstream's method, but not both. + * By default, both methods would be called. + *
+ *Default: false
+ */ public static final int GEN_PROLOG_XOR_DOWNSTREAM = 1 << 3; + /** + * By extra command-line argument:gl_identity_by_assignable_class
.
+ *
+ * If true, implementation does not utilize downstream's isGL*()
+ * implementation, but determines whether the GL profile is matched by interface inheritance.
+ *
Default: false
+ */ + public static final int GEN_GL_IDENTITY_BY_ASSIGNABLE_CLASS = 1 << 4; + int mode; private String outputDir; private String outputPackage; @@ -110,8 +131,12 @@ public class BuildComposablePipeline { classDownstream = getClass(args[4]); mode = GEN_CUSTOM; if (args.length > 5) { - if (args[5].equals("prolog_xor_downstream")) { - mode |= GEN_PROLOG_XOR_DOWNSTREAM; + for(int i=5; iComposable pipeline which wraps an underlying {@link GL} implementation,"); - output.println(" providing error checking after each OpenGL method call. If an error occurs,"); - output.println(" causes a {@link GLException} to be thrown at exactly the point of failure."); - output.println(" Sample code which installs this pipeline:
"); - output.println(); - output.println(""); - output.println(" GL gl = drawable.setGL(new DebugGL(drawable.getGL()));"); - output.println(""); - output.println("*/"); + output.println("/**"); + output.println(" *
"); + output.println(" * Composable pipeline which wraps an underlying {@link GL} implementation,"); + output.println(" * providing error checking after each OpenGL method call. If an error occurs,"); + output.println(" * causes a {@link GLException} to be thrown at exactly the point of failure."); + output.println(" *
"); + output.println(" *"); + output.println(" * Sample code which installs this pipeline:"); + output.println(" *
"); + output.println(" * gl = drawable.setGL(new DebugGL(drawable.getGL()));"); + output.println(" *"); + output.println(" * For automatic instantiation see {@link GLPipelineFactory#create(String, Class, GL, Object[])}"); + output.println(" * "); + output.println(" */"); } protected boolean hasPreDownstreamCallHook(Method m) { @@ -1057,14 +1099,20 @@ public class BuildComposablePipeline { } protected void emitClassDocComment(PrintWriter output) { - output.println("/**
Composable pipeline which wraps an underlying {@link GL} implementation,"); - output.println(" providing tracing information to a user-specified {@link java.io.PrintStream}"); - output.println(" before and after each OpenGL method call. Sample code which installs this pipeline:
"); - output.println(); - output.println(""); - output.println(" GL gl = drawable.setGL(new TraceGL(drawable.getGL(), System.err));"); - output.println(""); - output.println("*/"); + output.println("/**"); + output.println(" *
"); + output.println(" * Composable pipeline which wraps an underlying {@link GL} implementation,"); + output.println(" * providing tracing information to a user-specified {@link java.io.PrintStream}"); + output.println(" * before and after each OpenGL method call."); + output.println(" *
"); + output.println(" *"); + output.println(" * Sample code which installs this pipeline:"); + output.println(" *
"); + output.println(" * gl = drawable.setGL(new TraceGL(drawable.getGL(), System.err));"); + output.println(" *"); + output.println(" * For automatic instantiation see {@link GLPipelineFactory#create(String, Class, GL, Object[])}"); + output.println(" * "); + output.println(" */"); } protected boolean hasPreDownstreamCallHook(Method m) { diff --git a/src/jogl/classes/javax/media/opengl/DebugGL2.java b/src/jogl/classes/javax/media/opengl/DebugGL2.java new file mode 100644 index 000000000..05bcf3d5e --- /dev/null +++ b/src/jogl/classes/javax/media/opengl/DebugGL2.java @@ -0,0 +1,21 @@ +package javax.media.opengl; + +/** + *
+ * Composable pipeline which wraps an underlying {@link GL} implementation, + * providing error checking after each OpenGL method call. If an error occurs, + * causes a {@link GLException} to be thrown at exactly the point of failure. + *
+ *+ * Sample code which installs this pipeline, manual: + *
+ * gl = drawable.setGL(new DebugGL(drawable.getGL())); + *+ * For automatic instantiation see {@link GLPipelineFactory#create(String, Class, GL, Object[])}. + * + */ +public class DebugGL2 extends DebugGL4bc { + public DebugGL2(GL2 downstream) { + super((GL4bc)downstream); + } +} diff --git a/src/jogl/classes/javax/media/opengl/DebugGL3.java b/src/jogl/classes/javax/media/opengl/DebugGL3.java new file mode 100644 index 000000000..c17f90667 --- /dev/null +++ b/src/jogl/classes/javax/media/opengl/DebugGL3.java @@ -0,0 +1,21 @@ +package javax.media.opengl; + +/** + *
+ * Composable pipeline which wraps an underlying {@link GL} implementation, + * providing error checking after each OpenGL method call. If an error occurs, + * causes a {@link GLException} to be thrown at exactly the point of failure. + *
+ *+ * Sample code which installs this pipeline, manual: + *
+ * gl = drawable.setGL(new DebugGL(drawable.getGL())); + *+ * For automatic instantiation see {@link GLPipelineFactory#create(String, Class, GL, Object[])}. + * + */ +public class DebugGL3 extends DebugGL4bc { + public DebugGL3(GL3 downstream) { + super((GL4bc)downstream); + } +} diff --git a/src/jogl/classes/javax/media/opengl/DebugGL3bc.java b/src/jogl/classes/javax/media/opengl/DebugGL3bc.java new file mode 100644 index 000000000..6e294d42b --- /dev/null +++ b/src/jogl/classes/javax/media/opengl/DebugGL3bc.java @@ -0,0 +1,21 @@ +package javax.media.opengl; + +/** + *
+ * Composable pipeline which wraps an underlying {@link GL} implementation, + * providing error checking after each OpenGL method call. If an error occurs, + * causes a {@link GLException} to be thrown at exactly the point of failure. + *
+ *+ * Sample code which installs this pipeline, manual: + *
+ * gl = drawable.setGL(new DebugGL(drawable.getGL())); + *+ * For automatic instantiation see {@link GLPipelineFactory#create(String, Class, GL, Object[])}. + * + */ +public class DebugGL3bc extends DebugGL4bc { + public DebugGL3bc(GL3bc downstream) { + super((GL4bc)downstream); + } +} diff --git a/src/jogl/classes/javax/media/opengl/DebugGL4.java b/src/jogl/classes/javax/media/opengl/DebugGL4.java new file mode 100644 index 000000000..d21d39390 --- /dev/null +++ b/src/jogl/classes/javax/media/opengl/DebugGL4.java @@ -0,0 +1,21 @@ +package javax.media.opengl; + +/** + *
+ * Composable pipeline which wraps an underlying {@link GL} implementation, + * providing error checking after each OpenGL method call. If an error occurs, + * causes a {@link GLException} to be thrown at exactly the point of failure. + *
+ *+ * Sample code which installs this pipeline, manual: + *
+ * gl = drawable.setGL(new DebugGL(drawable.getGL())); + *+ * For automatic instantiation see {@link GLPipelineFactory#create(String, Class, GL, Object[])}. + * + */ +public class DebugGL4 extends DebugGL4bc { + public DebugGL4(GL4 downstream) { + super((GL4bc)downstream); + } +} diff --git a/src/jogl/classes/javax/media/opengl/DebugGLES2.java b/src/jogl/classes/javax/media/opengl/DebugGLES2.java new file mode 100644 index 000000000..dee363c1b --- /dev/null +++ b/src/jogl/classes/javax/media/opengl/DebugGLES2.java @@ -0,0 +1,21 @@ +package javax.media.opengl; + +/** + *
+ * Composable pipeline which wraps an underlying {@link GL} implementation, + * providing error checking after each OpenGL method call. If an error occurs, + * causes a {@link GLException} to be thrown at exactly the point of failure. + *
+ *+ * Sample code which installs this pipeline, manual: + *
+ * gl = drawable.setGL(new DebugGL(drawable.getGL())); + *+ * For automatic instantiation see {@link GLPipelineFactory#create(String, Class, GL, Object[])}. + * + */ +public class DebugGLES2 extends DebugGLES3 { + public DebugGLES2(GLES2 downstream) { + super((GLES3)downstream); + } +} diff --git a/src/jogl/classes/javax/media/opengl/GLPipelineFactory.java b/src/jogl/classes/javax/media/opengl/GLPipelineFactory.java index 2bfc77d4a..c6bf26235 100644 --- a/src/jogl/classes/javax/media/opengl/GLPipelineFactory.java +++ b/src/jogl/classes/javax/media/opengl/GLPipelineFactory.java @@ -51,8 +51,23 @@ public class GLPipelineFactory { /** * Creates a pipelined GL instance using the given downstream
downstream
- * and optional arguments additionalArgs
for the constructor.additionalArgs
for the constructor.
*
+ * + * Sample code which installs a Debug and Trace pipeline + * automatic w/ user defined interface, here: GL2ES2: + *
+ * gl = drawable.setGL( GLPipelineFactory.create("javax.media.opengl.Debug", GL2ES2.class, gl, null) ); + * gl = drawable.setGL( GLPipelineFactory.create("javax.media.opengl.Trace", GL2ES2.class, gl, new Object[] { System.err } ) ); + *+ * or automatic w/ automatic defined class: + *
+ * gl = drawable.setGL( GLPipelineFactory.create("javax.media.opengl.Debug", null, gl, null) ); + * gl = drawable.setGL( GLPipelineFactory.create("javax.media.opengl.Trace", null, gl, new Object[] { System.err } ) ); + *+ * + * + *
* The upstream GL instance is determined as follows: *
pipelineClazzBaseName
as the class name's full basename, incl. package name+ * Composable pipeline which wraps an underlying {@link GL} implementation, + * providing tracing information to a user-specified {@link java.io.PrintStream} + * before and after each OpenGL method call. + *
+ *+ * Sample code which installs this pipeline, manual: + *
+ * gl = drawable.setGL(new TraceGL(drawable.getGL(), System.err)); + *+ * For automatic instantiation see {@link GLPipelineFactory#create(String, Class, GL, Object[])}. + * + */ +public class TraceGL2 extends TraceGL4bc { + public TraceGL2(GL2 downstream, PrintStream stream) { + super((GL4bc)downstream, stream); + } +} diff --git a/src/jogl/classes/javax/media/opengl/TraceGL3.java b/src/jogl/classes/javax/media/opengl/TraceGL3.java new file mode 100644 index 000000000..616b31f61 --- /dev/null +++ b/src/jogl/classes/javax/media/opengl/TraceGL3.java @@ -0,0 +1,23 @@ +package javax.media.opengl; + +import java.io.PrintStream; + +/** + *
+ * Composable pipeline which wraps an underlying {@link GL} implementation, + * providing tracing information to a user-specified {@link java.io.PrintStream} + * before and after each OpenGL method call. + *
+ *+ * Sample code which installs this pipeline, manual: + *
+ * gl = drawable.setGL(new TraceGL(drawable.getGL(), System.err)); + *+ * For automatic instantiation see {@link GLPipelineFactory#create(String, Class, GL, Object[])}. + * + */ +public class TraceGL3 extends TraceGL4bc { + public TraceGL3(GL3 downstream, PrintStream stream) { + super((GL4bc)downstream, stream); + } +} diff --git a/src/jogl/classes/javax/media/opengl/TraceGL3bc.java b/src/jogl/classes/javax/media/opengl/TraceGL3bc.java new file mode 100644 index 000000000..f3761d4d6 --- /dev/null +++ b/src/jogl/classes/javax/media/opengl/TraceGL3bc.java @@ -0,0 +1,23 @@ +package javax.media.opengl; + +import java.io.PrintStream; + +/** + *
+ * Composable pipeline which wraps an underlying {@link GL} implementation, + * providing tracing information to a user-specified {@link java.io.PrintStream} + * before and after each OpenGL method call. + *
+ *+ * Sample code which installs this pipeline, manual: + *
+ * gl = drawable.setGL(new TraceGL(drawable.getGL(), System.err)); + *+ * For automatic instantiation see {@link GLPipelineFactory#create(String, Class, GL, Object[])}. + * + */ +public class TraceGL3bc extends TraceGL4bc { + public TraceGL3bc(GL3bc downstream, PrintStream stream) { + super((GL4bc)downstream, stream); + } +} diff --git a/src/jogl/classes/javax/media/opengl/TraceGL4.java b/src/jogl/classes/javax/media/opengl/TraceGL4.java new file mode 100644 index 000000000..a12bf0f47 --- /dev/null +++ b/src/jogl/classes/javax/media/opengl/TraceGL4.java @@ -0,0 +1,23 @@ +package javax.media.opengl; + +import java.io.PrintStream; + +/** + *
+ * Composable pipeline which wraps an underlying {@link GL} implementation, + * providing tracing information to a user-specified {@link java.io.PrintStream} + * before and after each OpenGL method call. + *
+ *+ * Sample code which installs this pipeline, manual: + *
+ * gl = drawable.setGL(new TraceGL(drawable.getGL(), System.err)); + *+ * For automatic instantiation see {@link GLPipelineFactory#create(String, Class, GL, Object[])}. + * + */ +public class TraceGL4 extends TraceGL4bc { + public TraceGL4(GL4 downstream, PrintStream stream) { + super((GL4bc)downstream, stream); + } +} diff --git a/src/jogl/classes/javax/media/opengl/TraceGLES2.java b/src/jogl/classes/javax/media/opengl/TraceGLES2.java new file mode 100644 index 000000000..38d60e3ac --- /dev/null +++ b/src/jogl/classes/javax/media/opengl/TraceGLES2.java @@ -0,0 +1,23 @@ +package javax.media.opengl; + +import java.io.PrintStream; + +/** + *
+ * Composable pipeline which wraps an underlying {@link GL} implementation, + * providing tracing information to a user-specified {@link java.io.PrintStream} + * before and after each OpenGL method call. + *
+ *+ * Sample code which installs this pipeline, manual: + *
+ * gl = drawable.setGL(new TraceGL(drawable.getGL(), System.err)); + *+ * For automatic instantiation see {@link GLPipelineFactory#create(String, Class, GL, Object[])}. + * + */ +public class TraceGLES2 extends TraceGLES3 { + public TraceGLES2(GLES2 downstream, PrintStream stream) { + super((GLES3)downstream, stream); + } +} -- cgit v1.2.3 From bfb10d309d97c19a33f9b6758f647186f8e0ddd6 Mon Sep 17 00:00:00 2001 From: Sven Gothel
- A sample implementation is available as + An implementation is available as JOGL, a JogAmp module.
Other API bindings are available as JogAmp modules: @@ -31,137 +29,146 @@ bindings to the native OpenGL(R) 3D graphics library profiles:The NativeWindow Protocol is included in JogAmp's implementation
This package contains all Java bindings for all OpenGL profiles.
+See Inclusion Criteria explaining the OpenGL profile seperation.
+See OpenGL Runtime Requirements.
+The main OpenGL profile interfaces are:
This interface contains all OpenGL [ 1.0 .. 3.0 ] methods, + as well as most of it's extensions defined at the time of this specification.
+OpenGL extensions whose functionality was incorporated into core OpenGL ≤ 3.0, + are subsumed into the core namespace.
+ + +Future extensions will be added with a maintenance update
+This interface contains all core OpenGL [ 3.1 .. 3.3 ] methods, + as well as most of it's extensions defined at the time of this specification.
+Note: OpenGL [ 3.1 .. 3.3 ] core profile does not includes fixed point functionality.
+ + +Future extensions will be added with a maintenance update
+This interface contains the OpenGL [ 3.1 .. 3.3 ] compatibility profile, + as well as most of it's extensions defined at the time of this specification.
+Note: OpenGL [ 3.1 .. 3.3 ] compatibility profile does includes fixed point functionality.
+Future extensions will be added with a maintenance update
+This interface contains all core OpenGL [ 4.0 .. 4.3 ] methods, + as well as most of it's extensions defined at the time of this specification.
+Note: OpenGL [ 4.0 .. 4.3 ] core profile does not includes fixed point functionality.
+Future extensions will be added with a maintenance update
+This interface contains the OpenGL [ 4.0 .. 4.3 ] compatibility profile, + as well as most of it's extensions defined at the time of this specification.
+Note: OpenGL [ 4.0 .. 4.3 ] compatibility profile does includes fixed point functionality.
+Future extensions will be added with a maintenance update
+This interface contains all core embedded OpenGL methods of ES [ 1.0 .. 1.1 ], + as well as most of it's extensions defined at the time of this specification.
+Future extensions will be added with a maintenance update
+This interface contains all core embedded OpenGL methods of ES 2.0, + as well as most of it's extensions defined at the time of this specification.
+Future extensions will be added with a maintenance update
+This interface contains all core embedded OpenGL methods of ES 3.0, + as well as most of it's extensions defined at the time of this specification.
+Future extensions will be added with a maintenance update
+Additionally the packages contains interfaces resembling intersecting common profiles. + These common profiles may be utilize for cross profile code supposed to either run + on desktop and mobile devices, or across GL profiles themselves:
Common interface containing the profile type identification and conversion methods.
+Used to query which specialized profile class an instance of this object actually is and + offering a protocol to convert it to these types.
Common interface containing the subset of all profiles, GL4bc, GL4, GL3bc, GL3, GL2, GLES1, GLES2 and GLES3.
+This interface reflects common data types, texture and framebuffer functionality.
Interface containing the common subset of GL2 and GLES1.
+This interface reflects the fixed functionality of OpenGL, without the immediate mode API.
Interface containing the common subset of GL2 and GLES2.
+This interface reflects the programmable shader functionality of desktop and embedded OpenGL up until GLES2.
Interface containing the common subset of core GL4, core GL3, and GLES3.
+This interface reflects the programmable shader functionality of desktop and embedded OpenGL up until GLES3.
Interface containing the common subset of core GL3 (OpenGL 3.1+) and GL2 (OpenGL 3.0), + also known as the OpenGL 3.0 forward compatible, non deprecated subset.
+This interface reflects only the programmable shader functionality of desktop OpenGL
This package contains bindings for the OpenGL Graphics System Utility (GLU) Library version 1.3, inclusive, with the exception of the GLU NURBS routines -which are not exposed.
The rules for creating the Java language binding are described in the following
sections. These rules should be followed as closely as possible for all future
-APIs that share the javax.media.opengl namespace.
+APIs that share the javax.media.opengl namespace.
Extension suffixes, such as EXT, ARB, and vendor-specific suffixes, are
-retained so as to match C conventions.
+retained so as to match C conventions.
Integer return values that can only be GL_TRUE or GL_FALSE are mapped to
-boolean.
+boolean.
OpenGL functions that take pointer arguments fall into several categories:
Functions that take a typed pointer (e.g., GLfloat *) argument for immediate
use are given two bindings. The first takes a Java primitive array with a
type that matches the C pointer type (i.e., GLfloat* maps to float[]). The
second takes a typed Buffer object (i.e., GLfloat* maps to FloatBuffer).
-An example of an OpenGL API in this category is glColor3fv.
-
+An example of an OpenGL API in this category is glColor3fv.
Functions that take an untyped (void*) pointer argument for deferred use
are given a single binding that takes a Buffer object. The Buffer may be of
any type allowable by the function (and compatible with the other arguments
@@ -216,24 +223,24 @@ into this category generally have names ending with the suffix "pointer."
An example of an OpenGL API in this category is glVertexPointer. Because these
functions do not consume the data located at the given pointer immediately,
but only at some unspecified later time, it is not possible to use a Java
-primitive array whose memory location may change.
-
+primitive array whose memory location may change.
Functions that take a typed (e.g., GLfloat*) pointer argument for deferred
use are given a single binding that takes a typed Buffer object (i.e., GLfloat*
maps to FloatBuffer). The Buffer must be direct. That is, it may not have
been created from a Java primitive array using the wrap method. An example
-of an OpenGL API in this category is glFeedbackBuffer.
-
+of an OpenGL API in this category is glFeedbackBuffer.
Methods that read or write a specific number of values from an array or
Buffer argument do not read or write any subsequent elements of the array
-or Buffer.
-
+or Buffer.
An outgoing C char* pointer, if representing a null-terminated, read-only
C string, maps to a Java String. An outgoing C char** pointer, if similarly
representing an array of read-only C strings, maps to a Java String[] (array
of String objects). All other char* pointers, including those representing
mutable C strings as used in some Get methods, are mapped to byte[] and ByteBuffer.
-
+
Also, methods that accept multiple Buffer arguments require all direct
or all non-direct Buffers. Direct and non-direct buffers should never be
-mixed within an API call by an application.
+mixed within an API call by an application.
This feature is known as "auto-slicing," as it mimics the effect of calling
-slice() on the Buffer object without the overhead of explicit object creation.
+slice() on the Buffer object without the overhead of explicit object creation.
In the interest of efficiency, the Java API does not generally throw exceptions.
However, running an application with the DebugGL composable pipeline, which
-is part of the API, will force an exception to be thrown at the point of failure.
-
+is part of the API, will force an exception to be thrown at the point of failure.
Many errors are defined by OpenGL merely to set the error code, rather
than throwing an exception. For example, passing a bad enumerated parameter
value may result in the error flag being set to GL.GL_INVALID_VALUE. Attempting
to check for such errors in the binding layer would require either replicating
the error-checking logic of the underlying engine, or querying the error state
after every function. This would greatly impact performance by inhibiting
-the ability of the hardware to pipeline work.
+the ability of the hardware to pipeline work.
An implementation should take care to validate arguments correctly before
invoking native methods that could potentially access memory illegally. In
particular, methods that validate the contents of an array (such as a list
of GL attributes) or a Buffer should take precautions against exploits in
which a separate thread attempts to alter the contents of the argument during
the time interval following validation but preceding passage of the argument
-to the underlying native engine.
+to the underlying native engine.
OpenGL functions and OpenGL extensions have been included in the Java bindings +according the following rules:
GL3/gl3.h
.GL/glcorearb.h
.GL_ARB_compatibility
, is chosen because:
Bindings for OpenGL extensions not covered in this specification may be
supplied by individual vendors or groups. Such bindings may be considered
-for inclusion in a future version of the JSR. In order to avoid fragmentation,
+for inclusion in a future version of this specification. In order to avoid fragmentation,
vendors creating extension bindings should expose new extensions using the
method GL.getExtension. This method is intended to provide a mechanism for
vendors who wish to provide access to new OpenGL extensions without changing
-the public API of the core package.
-
+the public API of the core package.
Names for added extension methods and extension-defined constants and Java
-bindings for C parameters should follow the guidelines set forth in this specfication.
+bindings for C parameters should follow the guidelines set forth in this specification.
+ Therefore, any usage of these APIs is both platform and implementation specific.
- -The JOGL reference implementation require at least OpenGL version 1.1, +due to it's dynamical function binding starting with OpenGL 1.2.
+In future revisions of the API, this minimum standard may be raised.
+ ++JOGL provides {@link com.jogamp.opengl.JoglVersion} implementing {@link com.jogamp.common.util.JogampVersion}, +which provides users access to the specification and implementation version, +the build date and source code repository branch name and it's latest commit identifier. +
+ +http://www.jcp.org/en/jsr/detail?id=231-
-http://www.opengl.org/registry/doc/glspec41.core.20100725.withchanges.pdf-
-http://www.opengl.org/registry/doc/glspec41.compatibility.20100725.withchanges.pdf- -
-http://www.opengl.org/registry/doc/glspec30.20080923.pdf- -
-http://www.opengl.org/registry/doc/glspec21.20061201.pdf- -
http://www.opengl.org/registry/- - - -
-http://www.khronos.org/registry/gles/specs/2.0/es_full_spec_2.0.24.pdf- -
-http://www.khronos.org/registry/gles/specs/1.1/es_full_spec_1.1.12.pdf- -
-http://www.khronos.org/registry/gles/- -
http://www.opengl.org/documentation/specs/glu/glu1_3.pdf- -
http://www.opengl.org/about/arb/index.html- -
> 31 & ((1<
amax) return amax;
+ else return a;
+}
+
+/** Compute ceil(log2(x)).
+ * @param x value used to compute ceil(log2(x))
+ * @return computed ceiling of log2(x)
+ */
+static av_always_inline av_const int av_ceil_log2_c(int x)
+{
+ return av_log2((x - 1) << 1);
+}
+
+/**
+ * Count number of bits set to one in x
+ * @param x value to count bits of
+ * @return the number of bits set to one in x
+ */
+static av_always_inline av_const int av_popcount_c(uint32_t x)
+{
+ x -= (x >> 1) & 0x55555555;
+ x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
+ x = (x + (x >> 4)) & 0x0F0F0F0F;
+ x += x >> 8;
+ return (x + (x >> 16)) & 0x3F;
+}
+
+/**
+ * Count number of bits set to one in x
+ * @param x value to count bits of
+ * @return the number of bits set to one in x
+ */
+static av_always_inline av_const int av_popcount64_c(uint64_t x)
+{
+ return av_popcount(x) + av_popcount(x >> 32);
+}
+
+#define MKTAG(a,b,c,d) ((a) | ((b) << 8) | ((c) << 16) | ((unsigned)(d) << 24))
+#define MKBETAG(a,b,c,d) ((d) | ((c) << 8) | ((b) << 16) | ((unsigned)(a) << 24))
+
+/**
+ * Convert a UTF-8 character (up to 4 bytes) to its 32-bit UCS-4 encoded form.
+ *
+ * @param val Output value, must be an lvalue of type uint32_t.
+ * @param GET_BYTE Expression reading one byte from the input.
+ * Evaluated up to 7 times (4 for the currently
+ * assigned Unicode range). With a memory buffer
+ * input, this could be *ptr++.
+ * @param ERROR Expression to be evaluated on invalid input,
+ * typically a goto statement.
+ */
+#define GET_UTF8(val, GET_BYTE, ERROR)\
+ val= GET_BYTE;\
+ {\
+ int ones= 7 - av_log2(val ^ 255);\
+ if(ones==1)\
+ ERROR\
+ val&= 127>>ones;\
+ while(--ones > 0){\
+ int tmp= GET_BYTE - 128;\
+ if(tmp>>6)\
+ ERROR\
+ val= (val<<6) + tmp;\
+ }\
+ }
+
+/**
+ * Convert a UTF-16 character (2 or 4 bytes) to its 32-bit UCS-4 encoded form.
+ *
+ * @param val Output value, must be an lvalue of type uint32_t.
+ * @param GET_16BIT Expression returning two bytes of UTF-16 data converted
+ * to native byte order. Evaluated one or two times.
+ * @param ERROR Expression to be evaluated on invalid input,
+ * typically a goto statement.
+ */
+#define GET_UTF16(val, GET_16BIT, ERROR)\
+ val = GET_16BIT;\
+ {\
+ unsigned int hi = val - 0xD800;\
+ if (hi < 0x800) {\
+ val = GET_16BIT - 0xDC00;\
+ if (val > 0x3FFU || hi > 0x3FFU)\
+ ERROR\
+ val += (hi<<10) + 0x10000;\
+ }\
+ }\
+
+/**
+ * @def PUT_UTF8(val, tmp, PUT_BYTE)
+ * Convert a 32-bit Unicode character to its UTF-8 encoded form (up to 4 bytes long).
+ * @param val is an input-only argument and should be of type uint32_t. It holds
+ * a UCS-4 encoded Unicode character that is to be converted to UTF-8. If
+ * val is given as a function it is executed only once.
+ * @param tmp is a temporary variable and should be of type uint8_t. It
+ * represents an intermediate value during conversion that is to be
+ * output by PUT_BYTE.
+ * @param PUT_BYTE writes the converted UTF-8 bytes to any proper destination.
+ * It could be a function or a statement, and uses tmp as the input byte.
+ * For example, PUT_BYTE could be "*output++ = tmp;" PUT_BYTE will be
+ * executed up to 4 times for values in the valid UTF-8 range and up to
+ * 7 times in the general case, depending on the length of the converted
+ * Unicode character.
+ */
+#define PUT_UTF8(val, tmp, PUT_BYTE)\
+ {\
+ int bytes, shift;\
+ uint32_t in = val;\
+ if (in < 0x80) {\
+ tmp = in;\
+ PUT_BYTE\
+ } else {\
+ bytes = (av_log2(in) + 4) / 5;\
+ shift = (bytes - 1) * 6;\
+ tmp = (256 - (256 >> bytes)) | (in >> shift);\
+ PUT_BYTE\
+ while (shift >= 6) {\
+ shift -= 6;\
+ tmp = 0x80 | ((in >> shift) & 0x3f);\
+ PUT_BYTE\
+ }\
+ }\
+ }
+
+/**
+ * @def PUT_UTF16(val, tmp, PUT_16BIT)
+ * Convert a 32-bit Unicode character to its UTF-16 encoded form (2 or 4 bytes).
+ * @param val is an input-only argument and should be of type uint32_t. It holds
+ * a UCS-4 encoded Unicode character that is to be converted to UTF-16. If
+ * val is given as a function it is executed only once.
+ * @param tmp is a temporary variable and should be of type uint16_t. It
+ * represents an intermediate value during conversion that is to be
+ * output by PUT_16BIT.
+ * @param PUT_16BIT writes the converted UTF-16 data to any proper destination
+ * in desired endianness. It could be a function or a statement, and uses tmp
+ * as the input byte. For example, PUT_BYTE could be "*output++ = tmp;"
+ * PUT_BYTE will be executed 1 or 2 times depending on input character.
+ */
+#define PUT_UTF16(val, tmp, PUT_16BIT)\
+ {\
+ uint32_t in = val;\
+ if (in < 0x10000) {\
+ tmp = in;\
+ PUT_16BIT\
+ } else {\
+ tmp = 0xD800 | ((in - 0x10000) >> 10);\
+ PUT_16BIT\
+ tmp = 0xDC00 | ((in - 0x10000) & 0x3FF);\
+ PUT_16BIT\
+ }\
+ }\
+
+
+
+#include "mem.h"
+
+#ifdef HAVE_AV_CONFIG_H
+# include "internal.h"
+#endif /* HAVE_AV_CONFIG_H */
+
+#endif /* AVUTIL_COMMON_H */
+
+/*
+ * The following definitions are outside the multiple inclusion guard
+ * to ensure they are immediately available in intmath.h.
+ */
+
+#ifndef av_log2
+# define av_log2 av_log2_c
+#endif
+#ifndef av_log2_16bit
+# define av_log2_16bit av_log2_16bit_c
+#endif
+#ifndef av_ceil_log2
+# define av_ceil_log2 av_ceil_log2_c
+#endif
+#ifndef av_clip
+# define av_clip av_clip_c
+#endif
+#ifndef av_clip_uint8
+# define av_clip_uint8 av_clip_uint8_c
+#endif
+#ifndef av_clip_int8
+# define av_clip_int8 av_clip_int8_c
+#endif
+#ifndef av_clip_uint16
+# define av_clip_uint16 av_clip_uint16_c
+#endif
+#ifndef av_clip_int16
+# define av_clip_int16 av_clip_int16_c
+#endif
+#ifndef av_clipl_int32
+# define av_clipl_int32 av_clipl_int32_c
+#endif
+#ifndef av_clip_uintp2
+# define av_clip_uintp2 av_clip_uintp2_c
+#endif
+#ifndef av_clipf
+# define av_clipf av_clipf_c
+#endif
+#ifndef av_popcount
+# define av_popcount av_popcount_c
+#endif
+#ifndef av_popcount64
+# define av_popcount64 av_popcount64_c
+#endif
diff --git a/make/stub_includes/libav/lavc53.lavf53.lavu51/libavutil/cpu.h b/make/stub_includes/libav/lavc53.lavf53.lavu51/libavutil/cpu.h
new file mode 100644
index 000000000..df7bf4421
--- /dev/null
+++ b/make/stub_includes/libav/lavc53.lavf53.lavu51/libavutil/cpu.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVUTIL_CPU_H
+#define AVUTIL_CPU_H
+
+#define AV_CPU_FLAG_FORCE 0x80000000 /* force usage of selected flags (OR) */
+
+ /* lower 16 bits - CPU features */
+#define AV_CPU_FLAG_MMX 0x0001 ///< standard MMX
+#define AV_CPU_FLAG_MMX2 0x0002 ///< SSE integer functions or AMD MMX ext
+#define AV_CPU_FLAG_3DNOW 0x0004 ///< AMD 3DNOW
+#define AV_CPU_FLAG_SSE 0x0008 ///< SSE functions
+#define AV_CPU_FLAG_SSE2 0x0010 ///< PIV SSE2 functions
+#define AV_CPU_FLAG_SSE2SLOW 0x40000000 ///< SSE2 supported, but usually not faster
+#define AV_CPU_FLAG_3DNOWEXT 0x0020 ///< AMD 3DNowExt
+#define AV_CPU_FLAG_SSE3 0x0040 ///< Prescott SSE3 functions
+#define AV_CPU_FLAG_SSE3SLOW 0x20000000 ///< SSE3 supported, but usually not faster
+#define AV_CPU_FLAG_SSSE3 0x0080 ///< Conroe SSSE3 functions
+#define AV_CPU_FLAG_ATOM 0x10000000 ///< Atom processor, some SSSE3 instructions are slower
+#define AV_CPU_FLAG_SSE4 0x0100 ///< Penryn SSE4.1 functions
+#define AV_CPU_FLAG_SSE42 0x0200 ///< Nehalem SSE4.2 functions
+#define AV_CPU_FLAG_AVX 0x4000 ///< AVX functions: requires OS support even if YMM registers aren't used
+#define AV_CPU_FLAG_XOP 0x0400 ///< Bulldozer XOP functions
+#define AV_CPU_FLAG_FMA4 0x0800 ///< Bulldozer FMA4 functions
+#define AV_CPU_FLAG_IWMMXT 0x0100 ///< XScale IWMMXT
+#define AV_CPU_FLAG_ALTIVEC 0x0001 ///< standard
+
+/**
+ * Return the flags which specify extensions supported by the CPU.
+ */
+int av_get_cpu_flags(void);
+
+/* The following CPU-specific functions shall not be called directly. */
+int ff_get_cpu_flags_arm(void);
+int ff_get_cpu_flags_ppc(void);
+int ff_get_cpu_flags_x86(void);
+
+#endif /* AVUTIL_CPU_H */
diff --git a/make/stub_includes/libav/lavc53.lavf53.lavu51/libavutil/crc.h b/make/stub_includes/libav/lavc53.lavf53.lavu51/libavutil/crc.h
new file mode 100644
index 000000000..a93411941
--- /dev/null
+++ b/make/stub_includes/libav/lavc53.lavf53.lavu51/libavutil/crc.h
@@ -0,0 +1,44 @@
+/*
+ * copyright (c) 2006 Michael Niedermayer > 31 & ((1< amax) return amax;
+ else return a;
+}
+
+/** Compute ceil(log2(x)).
+ * @param x value used to compute ceil(log2(x))
+ * @return computed ceiling of log2(x)
+ */
+static av_always_inline av_const int av_ceil_log2_c(int x)
+{
+ return av_log2((x - 1) << 1);
+}
+
+/**
+ * Count number of bits set to one in x
+ * @param x value to count bits of
+ * @return the number of bits set to one in x
+ */
+static av_always_inline av_const int av_popcount_c(uint32_t x)
+{
+ x -= (x >> 1) & 0x55555555;
+ x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
+ x = (x + (x >> 4)) & 0x0F0F0F0F;
+ x += x >> 8;
+ return (x + (x >> 16)) & 0x3F;
+}
+
+/**
+ * Count number of bits set to one in x
+ * @param x value to count bits of
+ * @return the number of bits set to one in x
+ */
+static av_always_inline av_const int av_popcount64_c(uint64_t x)
+{
+ return av_popcount(x) + av_popcount(x >> 32);
+}
+
+#define MKTAG(a,b,c,d) ((a) | ((b) << 8) | ((c) << 16) | ((unsigned)(d) << 24))
+#define MKBETAG(a,b,c,d) ((d) | ((c) << 8) | ((b) << 16) | ((unsigned)(a) << 24))
+
+/**
+ * Convert a UTF-8 character (up to 4 bytes) to its 32-bit UCS-4 encoded form.
+ *
+ * @param val Output value, must be an lvalue of type uint32_t.
+ * @param GET_BYTE Expression reading one byte from the input.
+ * Evaluated up to 7 times (4 for the currently
+ * assigned Unicode range). With a memory buffer
+ * input, this could be *ptr++.
+ * @param ERROR Expression to be evaluated on invalid input,
+ * typically a goto statement.
+ */
+#define GET_UTF8(val, GET_BYTE, ERROR)\
+ val= GET_BYTE;\
+ {\
+ uint32_t top = (val & 128) >> 1;\
+ if ((val & 0xc0) == 0x80)\
+ ERROR\
+ while (val & top) {\
+ int tmp= GET_BYTE - 128;\
+ if(tmp>>6)\
+ ERROR\
+ val= (val<<6) + tmp;\
+ top <<= 5;\
+ }\
+ val &= (top << 1) - 1;\
+ }
+
+/**
+ * Convert a UTF-16 character (2 or 4 bytes) to its 32-bit UCS-4 encoded form.
+ *
+ * @param val Output value, must be an lvalue of type uint32_t.
+ * @param GET_16BIT Expression returning two bytes of UTF-16 data converted
+ * to native byte order. Evaluated one or two times.
+ * @param ERROR Expression to be evaluated on invalid input,
+ * typically a goto statement.
+ */
+#define GET_UTF16(val, GET_16BIT, ERROR)\
+ val = GET_16BIT;\
+ {\
+ unsigned int hi = val - 0xD800;\
+ if (hi < 0x800) {\
+ val = GET_16BIT - 0xDC00;\
+ if (val > 0x3FFU || hi > 0x3FFU)\
+ ERROR\
+ val += (hi<<10) + 0x10000;\
+ }\
+ }\
+
+/**
+ * @def PUT_UTF8(val, tmp, PUT_BYTE)
+ * Convert a 32-bit Unicode character to its UTF-8 encoded form (up to 4 bytes long).
+ * @param val is an input-only argument and should be of type uint32_t. It holds
+ * a UCS-4 encoded Unicode character that is to be converted to UTF-8. If
+ * val is given as a function it is executed only once.
+ * @param tmp is a temporary variable and should be of type uint8_t. It
+ * represents an intermediate value during conversion that is to be
+ * output by PUT_BYTE.
+ * @param PUT_BYTE writes the converted UTF-8 bytes to any proper destination.
+ * It could be a function or a statement, and uses tmp as the input byte.
+ * For example, PUT_BYTE could be "*output++ = tmp;" PUT_BYTE will be
+ * executed up to 4 times for values in the valid UTF-8 range and up to
+ * 7 times in the general case, depending on the length of the converted
+ * Unicode character.
+ */
+#define PUT_UTF8(val, tmp, PUT_BYTE)\
+ {\
+ int bytes, shift;\
+ uint32_t in = val;\
+ if (in < 0x80) {\
+ tmp = in;\
+ PUT_BYTE\
+ } else {\
+ bytes = (av_log2(in) + 4) / 5;\
+ shift = (bytes - 1) * 6;\
+ tmp = (256 - (256 >> bytes)) | (in >> shift);\
+ PUT_BYTE\
+ while (shift >= 6) {\
+ shift -= 6;\
+ tmp = 0x80 | ((in >> shift) & 0x3f);\
+ PUT_BYTE\
+ }\
+ }\
+ }
+
+/**
+ * @def PUT_UTF16(val, tmp, PUT_16BIT)
+ * Convert a 32-bit Unicode character to its UTF-16 encoded form (2 or 4 bytes).
+ * @param val is an input-only argument and should be of type uint32_t. It holds
+ * a UCS-4 encoded Unicode character that is to be converted to UTF-16. If
+ * val is given as a function it is executed only once.
+ * @param tmp is a temporary variable and should be of type uint16_t. It
+ * represents an intermediate value during conversion that is to be
+ * output by PUT_16BIT.
+ * @param PUT_16BIT writes the converted UTF-16 data to any proper destination
+ * in desired endianness. It could be a function or a statement, and uses tmp
+ * as the input byte. For example, PUT_BYTE could be "*output++ = tmp;"
+ * PUT_BYTE will be executed 1 or 2 times depending on input character.
+ */
+#define PUT_UTF16(val, tmp, PUT_16BIT)\
+ {\
+ uint32_t in = val;\
+ if (in < 0x10000) {\
+ tmp = in;\
+ PUT_16BIT\
+ } else {\
+ tmp = 0xD800 | ((in - 0x10000) >> 10);\
+ PUT_16BIT\
+ tmp = 0xDC00 | ((in - 0x10000) & 0x3FF);\
+ PUT_16BIT\
+ }\
+ }\
+
+
+
+#include "mem.h"
+
+#ifdef HAVE_AV_CONFIG_H
+# include "internal.h"
+#endif /* HAVE_AV_CONFIG_H */
+
+#endif /* AVUTIL_COMMON_H */
+
+/*
+ * The following definitions are outside the multiple inclusion guard
+ * to ensure they are immediately available in intmath.h.
+ */
+
+#ifndef av_ceil_log2
+# define av_ceil_log2 av_ceil_log2_c
+#endif
+#ifndef av_clip
+# define av_clip av_clip_c
+#endif
+#ifndef av_clip_uint8
+# define av_clip_uint8 av_clip_uint8_c
+#endif
+#ifndef av_clip_int8
+# define av_clip_int8 av_clip_int8_c
+#endif
+#ifndef av_clip_uint16
+# define av_clip_uint16 av_clip_uint16_c
+#endif
+#ifndef av_clip_int16
+# define av_clip_int16 av_clip_int16_c
+#endif
+#ifndef av_clipl_int32
+# define av_clipl_int32 av_clipl_int32_c
+#endif
+#ifndef av_clip_uintp2
+# define av_clip_uintp2 av_clip_uintp2_c
+#endif
+#ifndef av_sat_add32
+# define av_sat_add32 av_sat_add32_c
+#endif
+#ifndef av_sat_dadd32
+# define av_sat_dadd32 av_sat_dadd32_c
+#endif
+#ifndef av_clipf
+# define av_clipf av_clipf_c
+#endif
+#ifndef av_popcount
+# define av_popcount av_popcount_c
+#endif
+#ifndef av_popcount64
+# define av_popcount64 av_popcount64_c
+#endif
diff --git a/make/stub_includes/libav/lavc54.lavf54.lavu52/libavutil/cpu.h b/make/stub_includes/libav/lavc54.lavf54.lavu52/libavutil/cpu.h
new file mode 100644
index 000000000..4929512c6
--- /dev/null
+++ b/make/stub_includes/libav/lavc54.lavf54.lavu52/libavutil/cpu.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVUTIL_CPU_H
+#define AVUTIL_CPU_H
+
+#include "version.h"
+
+#define AV_CPU_FLAG_FORCE 0x80000000 /* force usage of selected flags (OR) */
+
+ /* lower 16 bits - CPU features */
+#define AV_CPU_FLAG_MMX 0x0001 ///< standard MMX
+#define AV_CPU_FLAG_MMXEXT 0x0002 ///< SSE integer functions or AMD MMX ext
+#if FF_API_CPU_FLAG_MMX2
+#define AV_CPU_FLAG_MMX2 0x0002 ///< SSE integer functions or AMD MMX ext
+#endif
+#define AV_CPU_FLAG_3DNOW 0x0004 ///< AMD 3DNOW
+#define AV_CPU_FLAG_SSE 0x0008 ///< SSE functions
+#define AV_CPU_FLAG_SSE2 0x0010 ///< PIV SSE2 functions
+#define AV_CPU_FLAG_SSE2SLOW 0x40000000 ///< SSE2 supported, but usually not faster
+#define AV_CPU_FLAG_3DNOWEXT 0x0020 ///< AMD 3DNowExt
+#define AV_CPU_FLAG_SSE3 0x0040 ///< Prescott SSE3 functions
+#define AV_CPU_FLAG_SSE3SLOW 0x20000000 ///< SSE3 supported, but usually not faster
+#define AV_CPU_FLAG_SSSE3 0x0080 ///< Conroe SSSE3 functions
+#define AV_CPU_FLAG_ATOM 0x10000000 ///< Atom processor, some SSSE3 instructions are slower
+#define AV_CPU_FLAG_SSE4 0x0100 ///< Penryn SSE4.1 functions
+#define AV_CPU_FLAG_SSE42 0x0200 ///< Nehalem SSE4.2 functions
+#define AV_CPU_FLAG_AVX 0x4000 ///< AVX functions: requires OS support even if YMM registers aren't used
+#define AV_CPU_FLAG_XOP 0x0400 ///< Bulldozer XOP functions
+#define AV_CPU_FLAG_FMA4 0x0800 ///< Bulldozer FMA4 functions
+#define AV_CPU_FLAG_CMOV 0x1000 ///< i686 cmov
+
+#define AV_CPU_FLAG_ALTIVEC 0x0001 ///< standard
+
+#define AV_CPU_FLAG_ARMV5TE (1 << 0)
+#define AV_CPU_FLAG_ARMV6 (1 << 1)
+#define AV_CPU_FLAG_ARMV6T2 (1 << 2)
+#define AV_CPU_FLAG_VFP (1 << 3)
+#define AV_CPU_FLAG_VFPV3 (1 << 4)
+#define AV_CPU_FLAG_NEON (1 << 5)
+
+/**
+ * Return the flags which specify extensions supported by the CPU.
+ */
+int av_get_cpu_flags(void);
+
+/**
+ * Set a mask on flags returned by av_get_cpu_flags().
+ * This function is mainly useful for testing.
+ *
+ * @warning this function is not thread safe.
+ */
+void av_set_cpu_flags_mask(int mask);
+
+/**
+ * Parse CPU flags from a string.
+ *
+ * @return a combination of AV_CPU_* flags, negative on error.
+ */
+int av_parse_cpu_flags(const char *s);
+
+/* The following CPU-specific functions shall not be called directly. */
+int ff_get_cpu_flags_arm(void);
+int ff_get_cpu_flags_ppc(void);
+int ff_get_cpu_flags_x86(void);
+
+#endif /* AVUTIL_CPU_H */
diff --git a/make/stub_includes/libav/lavc54.lavf54.lavu52/libavutil/crc.h b/make/stub_includes/libav/lavc54.lavf54.lavu52/libavutil/crc.h
new file mode 100644
index 000000000..0540619d2
--- /dev/null
+++ b/make/stub_includes/libav/lavc54.lavf54.lavu52/libavutil/crc.h
@@ -0,0 +1,74 @@
+/*
+ * copyright (c) 2006 Michael Niedermayer
+ * Note: If the first 23 bits of the additional bytes are not 0, then damaged
+ * MPEG bitstreams could cause overread and segfault.
+ */
+#define FF_INPUT_BUFFER_PADDING_SIZE 8
+
+/**
+ * @ingroup lavc_encoding
+ * minimum encoding buffer size
+ * Used to avoid some checks during header writing.
+ */
+#define FF_MIN_BUFFER_SIZE 16384
+
+
+/**
+ * @ingroup lavc_encoding
+ * motion estimation type.
+ */
+enum Motion_Est_ID {
+ ME_ZERO = 1, ///< no search, that is use 0,0 vector whenever one is needed
+ ME_FULL,
+ ME_LOG,
+ ME_PHODS,
+ ME_EPZS, ///< enhanced predictive zonal search
+ ME_X1, ///< reserved for experiments
+ ME_HEX, ///< hexagon based search
+ ME_UMH, ///< uneven multi-hexagon search
+ ME_ITER, ///< iterative search
+ ME_TESA, ///< transformed exhaustive search algorithm
+};
+
+/**
+ * @ingroup lavc_decoding
+ */
+enum AVDiscard{
+ /* We leave some space between them for extensions (drop some
+ * keyframes for intra-only or drop just some bidir frames). */
+ AVDISCARD_NONE =-16, ///< discard nothing
+ AVDISCARD_DEFAULT = 0, ///< discard useless packets like 0 size packets in avi
+ AVDISCARD_NONREF = 8, ///< discard all non reference
+ AVDISCARD_BIDIR = 16, ///< discard all bidirectional frames
+ AVDISCARD_NONKEY = 32, ///< discard all frames except keyframes
+ AVDISCARD_ALL = 48, ///< discard all
+};
+
+enum AVColorPrimaries{
+ AVCOL_PRI_BT709 = 1, ///< also ITU-R BT1361 / IEC 61966-2-4 / SMPTE RP177 Annex B
+ AVCOL_PRI_UNSPECIFIED = 2,
+ AVCOL_PRI_BT470M = 4,
+ AVCOL_PRI_BT470BG = 5, ///< also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM
+ AVCOL_PRI_SMPTE170M = 6, ///< also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC
+ AVCOL_PRI_SMPTE240M = 7, ///< functionally identical to above
+ AVCOL_PRI_FILM = 8,
+ AVCOL_PRI_NB , ///< Not part of ABI
+};
+
+enum AVColorTransferCharacteristic{
+ AVCOL_TRC_BT709 = 1, ///< also ITU-R BT1361
+ AVCOL_TRC_UNSPECIFIED = 2,
+ AVCOL_TRC_GAMMA22 = 4, ///< also ITU-R BT470M / ITU-R BT1700 625 PAL & SECAM
+ AVCOL_TRC_GAMMA28 = 5, ///< also ITU-R BT470BG
+ AVCOL_TRC_SMPTE240M = 7,
+ AVCOL_TRC_NB , ///< Not part of ABI
+};
+
+enum AVColorSpace{
+ AVCOL_SPC_RGB = 0,
+ AVCOL_SPC_BT709 = 1, ///< also ITU-R BT1361 / IEC 61966-2-4 xvYCC709 / SMPTE RP177 Annex B
+ AVCOL_SPC_UNSPECIFIED = 2,
+ AVCOL_SPC_FCC = 4,
+ AVCOL_SPC_BT470BG = 5, ///< also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM / IEC 61966-2-4 xvYCC601
+ AVCOL_SPC_SMPTE170M = 6, ///< also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC / functionally identical to above
+ AVCOL_SPC_SMPTE240M = 7,
+ AVCOL_SPC_YCOCG = 8, ///< Used by Dirac / VC-2 and H.264 FRext, see ITU-T SG16
+ AVCOL_SPC_NB , ///< Not part of ABI
+};
+
+enum AVColorRange{
+ AVCOL_RANGE_UNSPECIFIED = 0,
+ AVCOL_RANGE_MPEG = 1, ///< the normal 219*2^(n-8) "MPEG" YUV ranges
+ AVCOL_RANGE_JPEG = 2, ///< the normal 2^n-1 "JPEG" YUV ranges
+ AVCOL_RANGE_NB , ///< Not part of ABI
+};
+
+/**
+ * X X 3 4 X X are luma samples,
+ * 1 2 1-6 are possible chroma positions
+ * X X 5 6 X 0 is undefined/unknown position
+ */
+enum AVChromaLocation{
+ AVCHROMA_LOC_UNSPECIFIED = 0,
+ AVCHROMA_LOC_LEFT = 1, ///< mpeg2/4, h264 default
+ AVCHROMA_LOC_CENTER = 2, ///< mpeg1, jpeg, h263
+ AVCHROMA_LOC_TOPLEFT = 3, ///< DV
+ AVCHROMA_LOC_TOP = 4,
+ AVCHROMA_LOC_BOTTOMLEFT = 5,
+ AVCHROMA_LOC_BOTTOM = 6,
+ AVCHROMA_LOC_NB , ///< Not part of ABI
+};
+
+enum AVAudioServiceType {
+ AV_AUDIO_SERVICE_TYPE_MAIN = 0,
+ AV_AUDIO_SERVICE_TYPE_EFFECTS = 1,
+ AV_AUDIO_SERVICE_TYPE_VISUALLY_IMPAIRED = 2,
+ AV_AUDIO_SERVICE_TYPE_HEARING_IMPAIRED = 3,
+ AV_AUDIO_SERVICE_TYPE_DIALOGUE = 4,
+ AV_AUDIO_SERVICE_TYPE_COMMENTARY = 5,
+ AV_AUDIO_SERVICE_TYPE_EMERGENCY = 6,
+ AV_AUDIO_SERVICE_TYPE_VOICE_OVER = 7,
+ AV_AUDIO_SERVICE_TYPE_KARAOKE = 8,
+ AV_AUDIO_SERVICE_TYPE_NB , ///< Not part of ABI
+};
+
+/**
+ * @ingroup lavc_encoding
+ */
+typedef struct RcOverride{
+ int start_frame;
+ int end_frame;
+ int qscale; // If this is 0 then quality_factor will be used instead.
+ float quality_factor;
+} RcOverride;
+
+#define FF_MAX_B_FRAMES 16
+
+/* encoding support
+ These flags can be passed in AVCodecContext.flags before initialization.
+ Note: Not everything is supported yet.
+*/
+
+#define CODEC_FLAG_QSCALE 0x0002 ///< Use fixed qscale.
+#define CODEC_FLAG_4MV 0x0004 ///< 4 MV per MB allowed / advanced prediction for H.263.
+#define CODEC_FLAG_QPEL 0x0010 ///< Use qpel MC.
+#define CODEC_FLAG_GMC 0x0020 ///< Use GMC.
+#define CODEC_FLAG_MV0 0x0040 ///< Always try a MB with MV=<0,0>.
+/**
+ * The parent program guarantees that the input for B-frames containing
+ * streams is not written to for at least s->max_b_frames+1 frames, if
+ * this is not set the input will be copied.
+ */
+#define CODEC_FLAG_INPUT_PRESERVED 0x0100
+#define CODEC_FLAG_PASS1 0x0200 ///< Use internal 2pass ratecontrol in first pass mode.
+#define CODEC_FLAG_PASS2 0x0400 ///< Use internal 2pass ratecontrol in second pass mode.
+#define CODEC_FLAG_GRAY 0x2000 ///< Only decode/encode grayscale.
+#define CODEC_FLAG_EMU_EDGE 0x4000 ///< Don't draw edges.
+#define CODEC_FLAG_PSNR 0x8000 ///< error[?] variables will be set during encoding.
+#define CODEC_FLAG_TRUNCATED 0x00010000 /** Input bitstream might be truncated at a random
+ location instead of only at frame boundaries. */
+#define CODEC_FLAG_NORMALIZE_AQP 0x00020000 ///< Normalize adaptive quantization.
+#define CODEC_FLAG_INTERLACED_DCT 0x00040000 ///< Use interlaced DCT.
+#define CODEC_FLAG_LOW_DELAY 0x00080000 ///< Force low delay.
+#define CODEC_FLAG_GLOBAL_HEADER 0x00400000 ///< Place global headers in extradata instead of every keyframe.
+#define CODEC_FLAG_BITEXACT 0x00800000 ///< Use only bitexact stuff (except (I)DCT).
+/* Fx : Flag for h263+ extra options */
+#define CODEC_FLAG_AC_PRED 0x01000000 ///< H.263 advanced intra coding / MPEG-4 AC prediction
+#define CODEC_FLAG_LOOP_FILTER 0x00000800 ///< loop filter
+#define CODEC_FLAG_INTERLACED_ME 0x20000000 ///< interlaced motion estimation
+#define CODEC_FLAG_CLOSED_GOP 0x80000000
+#define CODEC_FLAG2_FAST 0x00000001 ///< Allow non spec compliant speedup tricks.
+#define CODEC_FLAG2_NO_OUTPUT 0x00000004 ///< Skip bitstream encoding.
+#define CODEC_FLAG2_LOCAL_HEADER 0x00000008 ///< Place global headers at every keyframe instead of in extradata.
+#if FF_API_MPV_GLOBAL_OPTS
+#define CODEC_FLAG_CBP_RD 0x04000000 ///< Use rate distortion optimization for cbp.
+#define CODEC_FLAG_QP_RD 0x08000000 ///< Use rate distortion optimization for qp selectioon.
+#define CODEC_FLAG2_STRICT_GOP 0x00000002 ///< Strictly enforce GOP size.
+#define CODEC_FLAG2_SKIP_RD 0x00004000 ///< RD optimal MB level residual skipping
+#endif
+#define CODEC_FLAG2_CHUNKS 0x00008000 ///< Input bitstream might be truncated at a packet boundaries instead of only at frame boundaries.
+
+/* Unsupported options :
+ * Syntax Arithmetic coding (SAC)
+ * Reference Picture Selection
+ * Independent Segment Decoding */
+/* /Fx */
+/* codec capabilities */
+
+#define CODEC_CAP_DRAW_HORIZ_BAND 0x0001 ///< Decoder can use draw_horiz_band callback.
+/**
+ * Codec uses get_buffer() for allocating buffers and supports custom allocators.
+ * If not set, it might not use get_buffer() at all or use operations that
+ * assume the buffer was allocated by avcodec_default_get_buffer.
+ */
+#define CODEC_CAP_DR1 0x0002
+#define CODEC_CAP_TRUNCATED 0x0008
+/* Codec can export data for HW decoding (XvMC). */
+#define CODEC_CAP_HWACCEL 0x0010
+/**
+ * Encoder or decoder requires flushing with NULL input at the end in order to
+ * give the complete and correct output.
+ *
+ * NOTE: If this flag is not set, the codec is guaranteed to never be fed with
+ * with NULL data. The user can still send NULL data to the public encode
+ * or decode function, but libavcodec will not pass it along to the codec
+ * unless this flag is set.
+ *
+ * Decoders:
+ * The decoder has a non-zero delay and needs to be fed with avpkt->data=NULL,
+ * avpkt->size=0 at the end to get the delayed data until the decoder no longer
+ * returns frames.
+ *
+ * Encoders:
+ * The encoder needs to be fed with NULL data at the end of encoding until the
+ * encoder no longer returns data.
+ *
+ * NOTE: For encoders implementing the AVCodec.encode2() function, setting this
+ * flag also means that the encoder must set the pts and duration for
+ * each output packet. If this flag is not set, the pts and duration will
+ * be determined by libavcodec from the input frame.
+ */
+#define CODEC_CAP_DELAY 0x0020
+/**
+ * Codec can be fed a final frame with a smaller size.
+ * This can be used to prevent truncation of the last audio samples.
+ */
+#define CODEC_CAP_SMALL_LAST_FRAME 0x0040
+/**
+ * Codec can export data for HW decoding (VDPAU).
+ */
+#define CODEC_CAP_HWACCEL_VDPAU 0x0080
+/**
+ * Codec can output multiple frames per AVPacket
+ * Normally demuxers return one frame at a time, demuxers which do not do
+ * are connected to a parser to split what they return into proper frames.
+ * This flag is reserved to the very rare category of codecs which have a
+ * bitstream that cannot be split into frames without timeconsuming
+ * operations like full decoding. Demuxers carring such bitstreams thus
+ * may return multiple frames in a packet. This has many disadvantages like
+ * prohibiting stream copy in many cases thus it should only be considered
+ * as a last resort.
+ */
+#define CODEC_CAP_SUBFRAMES 0x0100
+/**
+ * Codec is experimental and is thus avoided in favor of non experimental
+ * encoders
+ */
+#define CODEC_CAP_EXPERIMENTAL 0x0200
+/**
+ * Codec should fill in channel configuration and samplerate instead of container
+ */
+#define CODEC_CAP_CHANNEL_CONF 0x0400
+/**
+ * Codec is able to deal with negative linesizes
+ */
+#define CODEC_CAP_NEG_LINESIZES 0x0800
+/**
+ * Codec supports frame-level multithreading.
+ */
+#define CODEC_CAP_FRAME_THREADS 0x1000
+/**
+ * Codec supports slice-based (or partition-based) multithreading.
+ */
+#define CODEC_CAP_SLICE_THREADS 0x2000
+/**
+ * Codec supports changed parameters at any point.
+ */
+#define CODEC_CAP_PARAM_CHANGE 0x4000
+/**
+ * Codec supports avctx->thread_count == 0 (auto).
+ */
+#define CODEC_CAP_AUTO_THREADS 0x8000
+/**
+ * Audio encoder supports receiving a different number of samples in each call.
+ */
+#define CODEC_CAP_VARIABLE_FRAME_SIZE 0x10000
+
+//The following defines may change, don't expect compatibility if you use them.
+#define MB_TYPE_INTRA4x4 0x0001
+#define MB_TYPE_INTRA16x16 0x0002 //FIXME H.264-specific
+#define MB_TYPE_INTRA_PCM 0x0004 //FIXME H.264-specific
+#define MB_TYPE_16x16 0x0008
+#define MB_TYPE_16x8 0x0010
+#define MB_TYPE_8x16 0x0020
+#define MB_TYPE_8x8 0x0040
+#define MB_TYPE_INTERLACED 0x0080
+#define MB_TYPE_DIRECT2 0x0100 //FIXME
+#define MB_TYPE_ACPRED 0x0200
+#define MB_TYPE_GMC 0x0400
+#define MB_TYPE_SKIP 0x0800
+#define MB_TYPE_P0L0 0x1000
+#define MB_TYPE_P1L0 0x2000
+#define MB_TYPE_P0L1 0x4000
+#define MB_TYPE_P1L1 0x8000
+#define MB_TYPE_L0 (MB_TYPE_P0L0 | MB_TYPE_P1L0)
+#define MB_TYPE_L1 (MB_TYPE_P0L1 | MB_TYPE_P1L1)
+#define MB_TYPE_L0L1 (MB_TYPE_L0 | MB_TYPE_L1)
+#define MB_TYPE_QUANT 0x00010000
+#define MB_TYPE_CBP 0x00020000
+//Note bits 24-31 are reserved for codec specific use (h264 ref0, mpeg1 0mv, ...)
+
+/**
+ * Pan Scan area.
+ * This specifies the area which should be displayed.
+ * Note there may be multiple such areas for one frame.
+ */
+typedef struct AVPanScan{
+ /**
+ * id
+ * - encoding: Set by user.
+ * - decoding: Set by libavcodec.
+ */
+ int id;
+
+ /**
+ * width and height in 1/16 pel
+ * - encoding: Set by user.
+ * - decoding: Set by libavcodec.
+ */
+ int width;
+ int height;
+
+ /**
+ * position of the top left corner in 1/16 pel for up to 3 fields/frames
+ * - encoding: Set by user.
+ * - decoding: Set by libavcodec.
+ */
+ int16_t position[3][2];
+}AVPanScan;
+
+#define FF_QSCALE_TYPE_MPEG1 0
+#define FF_QSCALE_TYPE_MPEG2 1
+#define FF_QSCALE_TYPE_H264 2
+#define FF_QSCALE_TYPE_VP56 3
+
+#define FF_BUFFER_TYPE_INTERNAL 1
+#define FF_BUFFER_TYPE_USER 2 ///< direct rendering buffers (image is (de)allocated by user)
+#define FF_BUFFER_TYPE_SHARED 4 ///< Buffer from somewhere else; don't deallocate image (data/base), all other tables are not shared.
+#define FF_BUFFER_TYPE_COPY 8 ///< Just a (modified) copy of some other buffer, don't deallocate anything.
+
+#define FF_BUFFER_HINTS_VALID 0x01 // Buffer hints value is meaningful (if 0 ignore).
+#define FF_BUFFER_HINTS_READABLE 0x02 // Codec will read from buffer.
+#define FF_BUFFER_HINTS_PRESERVE 0x04 // User must not alter buffer content.
+#define FF_BUFFER_HINTS_REUSABLE 0x08 // Codec will reuse the buffer (update).
+
+/**
+ * @defgroup lavc_packet AVPacket
+ *
+ * Types and functions for working with AVPacket.
+ * @{
+ */
+enum AVPacketSideDataType {
+ AV_PKT_DATA_PALETTE,
+ AV_PKT_DATA_NEW_EXTRADATA,
+
+ /**
+ * An AV_PKT_DATA_PARAM_CHANGE side data packet is laid out as follows:
+ * @code
+ * u32le param_flags
+ * if (param_flags & AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_COUNT)
+ * s32le channel_count
+ * if (param_flags & AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_LAYOUT)
+ * u64le channel_layout
+ * if (param_flags & AV_SIDE_DATA_PARAM_CHANGE_SAMPLE_RATE)
+ * s32le sample_rate
+ * if (param_flags & AV_SIDE_DATA_PARAM_CHANGE_DIMENSIONS)
+ * s32le width
+ * s32le height
+ * @endcode
+ */
+ AV_PKT_DATA_PARAM_CHANGE,
+
+ /**
+ * An AV_PKT_DATA_H263_MB_INFO side data packet contains a number of
+ * structures with info about macroblocks relevant to splitting the
+ * packet into smaller packets on macroblock edges (e.g. as for RFC 2190).
+ * That is, it does not necessarily contain info about all macroblocks,
+ * as long as the distance between macroblocks in the info is smaller
+ * than the target payload size.
+ * Each MB info structure is 12 bytes, and is laid out as follows:
+ * @code
+ * u32le bit offset from the start of the packet
+ * u8 current quantizer at the start of the macroblock
+ * u8 GOB number
+ * u16le macroblock address within the GOB
+ * u8 horizontal MV predictor
+ * u8 vertical MV predictor
+ * u8 horizontal MV predictor for block number 3
+ * u8 vertical MV predictor for block number 3
+ * @endcode
+ */
+ AV_PKT_DATA_H263_MB_INFO,
+};
+
+/**
+ * This structure stores compressed data. It is typically exported by demuxers
+ * and then passed as input to decoders, or received as output from encoders and
+ * then passed to muxers.
+ *
+ * For video, it should typically contain one compressed frame. For audio it may
+ * contain several compressed frames.
+ *
+ * AVPacket is one of the few structs in Libav, whose size is a part of public
+ * ABI. Thus it may be allocated on stack and no new fields can be added to it
+ * without libavcodec and libavformat major bump.
+ *
+ * The semantics of data ownership depends on the destruct field.
+ * If it is set, the packet data is dynamically allocated and is valid
+ * indefinitely until av_free_packet() is called (which in turn calls the
+ * destruct callback to free the data). If destruct is not set, the packet data
+ * is typically backed by some static buffer somewhere and is only valid for a
+ * limited time (e.g. until the next read call when demuxing).
+ *
+ * The side data is always allocated with av_malloc() and is freed in
+ * av_free_packet().
+ */
+typedef struct AVPacket {
+ /**
+ * Presentation timestamp in AVStream->time_base units; the time at which
+ * the decompressed packet will be presented to the user.
+ * Can be AV_NOPTS_VALUE if it is not stored in the file.
+ * pts MUST be larger or equal to dts as presentation cannot happen before
+ * decompression, unless one wants to view hex dumps. Some formats misuse
+ * the terms dts and pts/cts to mean something different. Such timestamps
+ * must be converted to true pts/dts before they are stored in AVPacket.
+ */
+ int64_t pts;
+ /**
+ * Decompression timestamp in AVStream->time_base units; the time at which
+ * the packet is decompressed.
+ * Can be AV_NOPTS_VALUE if it is not stored in the file.
+ */
+ int64_t dts;
+ uint8_t *data;
+ int size;
+ int stream_index;
+ /**
+ * A combination of AV_PKT_FLAG values
+ */
+ int flags;
+ /**
+ * Additional packet data that can be provided by the container.
+ * Packet can contain several types of side information.
+ */
+ struct {
+ uint8_t *data;
+ int size;
+ enum AVPacketSideDataType type;
+ } *side_data;
+ int side_data_elems;
+
+ /**
+ * Duration of this packet in AVStream->time_base units, 0 if unknown.
+ * Equals next_pts - this_pts in presentation order.
+ */
+ int duration;
+ void (*destruct)(struct AVPacket *);
+ void *priv;
+ int64_t pos; ///< byte position in stream, -1 if unknown
+
+ /**
+ * Time difference in AVStream->time_base units from the pts of this
+ * packet to the point at which the output from the decoder has converged
+ * independent from the availability of previous frames. That is, the
+ * frames are virtually identical no matter if decoding started from
+ * the very first frame or from this keyframe.
+ * Is AV_NOPTS_VALUE if unknown.
+ * This field is not the display duration of the current packet.
+ * This field has no meaning if the packet does not have AV_PKT_FLAG_KEY
+ * set.
+ *
+ * The purpose of this field is to allow seeking in streams that have no
+ * keyframes in the conventional sense. It corresponds to the
+ * recovery point SEI in H.264 and match_time_delta in NUT. It is also
+ * essential for some types of subtitle streams to ensure that all
+ * subtitles are correctly displayed after seeking.
+ */
+ int64_t convergence_duration;
+} AVPacket;
+#define AV_PKT_FLAG_KEY 0x0001 ///< The packet contains a keyframe
+#define AV_PKT_FLAG_CORRUPT 0x0002 ///< The packet content is corrupted
+
+enum AVSideDataParamChangeFlags {
+ AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_COUNT = 0x0001,
+ AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_LAYOUT = 0x0002,
+ AV_SIDE_DATA_PARAM_CHANGE_SAMPLE_RATE = 0x0004,
+ AV_SIDE_DATA_PARAM_CHANGE_DIMENSIONS = 0x0008,
+};
+/**
+ * @}
+ */
+
+/**
+ * This structure describes decoded (raw) audio or video data.
+ *
+ * AVFrame must be allocated using avcodec_alloc_frame() and freed with
+ * avcodec_free_frame(). Note that this allocates only the AVFrame itself. The
+ * buffers for the data must be managed through other means.
+ *
+ * AVFrame is typically allocated once and then reused multiple times to hold
+ * different data (e.g. a single AVFrame to hold frames received from a
+ * decoder). In such a case, avcodec_get_frame_defaults() should be used to
+ * reset the frame to its original clean state before it is reused again.
+ *
+ * sizeof(AVFrame) is not a part of the public ABI, so new fields may be added
+ * to the end with a minor bump.
+ */
+typedef struct AVFrame {
+#define AV_NUM_DATA_POINTERS 8
+ /**
+ * pointer to the picture/channel planes.
+ * This might be different from the first allocated byte
+ * - encoding: Set by user
+ * - decoding: set by AVCodecContext.get_buffer()
+ */
+ uint8_t *data[AV_NUM_DATA_POINTERS];
+
+ /**
+ * Size, in bytes, of the data for each picture/channel plane.
+ *
+ * For audio, only linesize[0] may be set. For planar audio, each channel
+ * plane must be the same size.
+ *
+ * - encoding: Set by user
+ * - decoding: set by AVCodecContext.get_buffer()
+ */
+ int linesize[AV_NUM_DATA_POINTERS];
+
+ /**
+ * pointers to the data planes/channels.
+ *
+ * For video, this should simply point to data[].
+ *
+ * For planar audio, each channel has a separate data pointer, and
+ * linesize[0] contains the size of each channel buffer.
+ * For packed audio, there is just one data pointer, and linesize[0]
+ * contains the total size of the buffer for all channels.
+ *
+ * Note: Both data and extended_data will always be set by get_buffer(),
+ * but for planar audio with more channels that can fit in data,
+ * extended_data must be used by the decoder in order to access all
+ * channels.
+ *
+ * encoding: set by user
+ * decoding: set by AVCodecContext.get_buffer()
+ */
+ uint8_t **extended_data;
+
+ /**
+ * width and height of the video frame
+ * - encoding: unused
+ * - decoding: Read by user.
+ */
+ int width, height;
+
+ /**
+ * number of audio samples (per channel) described by this frame
+ * - encoding: Set by user
+ * - decoding: Set by libavcodec
+ */
+ int nb_samples;
+
+ /**
+ * format of the frame, -1 if unknown or unset
+ * Values correspond to enum AVPixelFormat for video frames,
+ * enum AVSampleFormat for audio)
+ * - encoding: unused
+ * - decoding: Read by user.
+ */
+ int format;
+
+ /**
+ * 1 -> keyframe, 0-> not
+ * - encoding: Set by libavcodec.
+ * - decoding: Set by libavcodec.
+ */
+ int key_frame;
+
+ /**
+ * Picture type of the frame, see ?_TYPE below.
+ * - encoding: Set by libavcodec. for coded_picture (and set by user for input).
+ * - decoding: Set by libavcodec.
+ */
+ enum AVPictureType pict_type;
+
+ /**
+ * pointer to the first allocated byte of the picture. Can be used in get_buffer/release_buffer.
+ * This isn't used by libavcodec unless the default get/release_buffer() is used.
+ * - encoding:
+ * - decoding:
+ */
+ uint8_t *base[AV_NUM_DATA_POINTERS];
+
+ /**
+ * sample aspect ratio for the video frame, 0/1 if unknown/unspecified
+ * - encoding: unused
+ * - decoding: Read by user.
+ */
+ AVRational sample_aspect_ratio;
+
+ /**
+ * presentation timestamp in time_base units (time when frame should be shown to user)
+ * If AV_NOPTS_VALUE then frame_rate = 1/time_base will be assumed.
+ * - encoding: MUST be set by user.
+ * - decoding: Set by libavcodec.
+ */
+ int64_t pts;
+
+ /**
+ * pts copied from the AVPacket that was decoded to produce this frame
+ * - encoding: unused
+ * - decoding: Read by user.
+ */
+ int64_t pkt_pts;
+
+ /**
+ * dts copied from the AVPacket that triggered returning this frame
+ * - encoding: unused
+ * - decoding: Read by user.
+ */
+ int64_t pkt_dts;
+
+ /**
+ * picture number in bitstream order
+ * - encoding: set by
+ * - decoding: Set by libavcodec.
+ */
+ int coded_picture_number;
+ /**
+ * picture number in display order
+ * - encoding: set by
+ * - decoding: Set by libavcodec.
+ */
+ int display_picture_number;
+
+ /**
+ * quality (between 1 (good) and FF_LAMBDA_MAX (bad))
+ * - encoding: Set by libavcodec. for coded_picture (and set by user for input).
+ * - decoding: Set by libavcodec.
+ */
+ int quality;
+
+ /**
+ * is this picture used as reference
+ * The values for this are the same as the MpegEncContext.picture_structure
+ * variable, that is 1->top field, 2->bottom field, 3->frame/both fields.
+ * Set to 4 for delayed, non-reference frames.
+ * - encoding: unused
+ * - decoding: Set by libavcodec. (before get_buffer() call)).
+ */
+ int reference;
+
+ /**
+ * QP table
+ * - encoding: unused
+ * - decoding: Set by libavcodec.
+ */
+ int8_t *qscale_table;
+ /**
+ * QP store stride
+ * - encoding: unused
+ * - decoding: Set by libavcodec.
+ */
+ int qstride;
+
+ /**
+ *
+ */
+ int qscale_type;
+
+ /**
+ * mbskip_table[mb]>=1 if MB didn't change
+ * stride= mb_width = (width+15)>>4
+ * - encoding: unused
+ * - decoding: Set by libavcodec.
+ */
+ uint8_t *mbskip_table;
+
+ /**
+ * motion vector table
+ * @code
+ * example:
+ * int mv_sample_log2= 4 - motion_subsample_log2;
+ * int mb_width= (width+15)>>4;
+ * int mv_stride= (mb_width << mv_sample_log2) + 1;
+ * motion_val[direction][x + y*mv_stride][0->mv_x, 1->mv_y];
+ * @endcode
+ * - encoding: Set by user.
+ * - decoding: Set by libavcodec.
+ */
+ int16_t (*motion_val[2])[2];
+
+ /**
+ * macroblock type table
+ * mb_type_base + mb_width + 2
+ * - encoding: Set by user.
+ * - decoding: Set by libavcodec.
+ */
+ uint32_t *mb_type;
+
+ /**
+ * DCT coefficients
+ * - encoding: unused
+ * - decoding: Set by libavcodec.
+ */
+ short *dct_coeff;
+
+ /**
+ * motion reference frame index
+ * the order in which these are stored can depend on the codec.
+ * - encoding: Set by user.
+ * - decoding: Set by libavcodec.
+ */
+ int8_t *ref_index[2];
+
+ /**
+ * for some private data of the user
+ * - encoding: unused
+ * - decoding: Set by user.
+ */
+ void *opaque;
+
+ /**
+ * error
+ * - encoding: Set by libavcodec. if flags&CODEC_FLAG_PSNR.
+ * - decoding: unused
+ */
+ uint64_t error[AV_NUM_DATA_POINTERS];
+
+ /**
+ * type of the buffer (to keep track of who has to deallocate data[*])
+ * - encoding: Set by the one who allocates it.
+ * - decoding: Set by the one who allocates it.
+ * Note: User allocated (direct rendering) & internal buffers cannot coexist currently.
+ */
+ int type;
+
+ /**
+ * When decoding, this signals how much the picture must be delayed.
+ * extra_delay = repeat_pict / (2*fps)
+ * - encoding: unused
+ * - decoding: Set by libavcodec.
+ */
+ int repeat_pict;
+
+ /**
+ * The content of the picture is interlaced.
+ * - encoding: Set by user.
+ * - decoding: Set by libavcodec. (default 0)
+ */
+ int interlaced_frame;
+
+ /**
+ * If the content is interlaced, is top field displayed first.
+ * - encoding: Set by user.
+ * - decoding: Set by libavcodec.
+ */
+ int top_field_first;
+
+ /**
+ * Tell user application that palette has changed from previous frame.
+ * - encoding: ??? (no palette-enabled encoder yet)
+ * - decoding: Set by libavcodec. (default 0).
+ */
+ int palette_has_changed;
+
+ /**
+ * codec suggestion on buffer type if != 0
+ * - encoding: unused
+ * - decoding: Set by libavcodec. (before get_buffer() call)).
+ */
+ int buffer_hints;
+
+ /**
+ * Pan scan.
+ * - encoding: Set by user.
+ * - decoding: Set by libavcodec.
+ */
+ AVPanScan *pan_scan;
+
+ /**
+ * reordered opaque 64bit (generally an integer or a double precision float
+ * PTS but can be anything).
+ * The user sets AVCodecContext.reordered_opaque to represent the input at
+ * that time,
+ * the decoder reorders values as needed and sets AVFrame.reordered_opaque
+ * to exactly one of the values provided by the user through AVCodecContext.reordered_opaque
+ * @deprecated in favor of pkt_pts
+ * - encoding: unused
+ * - decoding: Read by user.
+ */
+ int64_t reordered_opaque;
+
+ /**
+ * hardware accelerator private data (Libav-allocated)
+ * - encoding: unused
+ * - decoding: Set by libavcodec
+ */
+ void *hwaccel_picture_private;
+
+ /**
+ * the AVCodecContext which ff_thread_get_buffer() was last called on
+ * - encoding: Set by libavcodec.
+ * - decoding: Set by libavcodec.
+ */
+ struct AVCodecContext *owner;
+
+ /**
+ * used by multithreading to store frame-specific info
+ * - encoding: Set by libavcodec.
+ * - decoding: Set by libavcodec.
+ */
+ void *thread_opaque;
+
+ /**
+ * log2 of the size of the block which a single vector in motion_val represents:
+ * (4->16x16, 3->8x8, 2-> 4x4, 1-> 2x2)
+ * - encoding: unused
+ * - decoding: Set by libavcodec.
+ */
+ uint8_t motion_subsample_log2;
+
+ /**
+ * Sample rate of the audio data.
+ *
+ * - encoding: unused
+ * - decoding: set by get_buffer()
+ */
+ int sample_rate;
+
+ /**
+ * Channel layout of the audio data.
+ *
+ * - encoding: unused
+ * - decoding: set by get_buffer()
+ */
+ uint64_t channel_layout;
+} AVFrame;
+
+struct AVCodecInternal;
+
+enum AVFieldOrder {
+ AV_FIELD_UNKNOWN,
+ AV_FIELD_PROGRESSIVE,
+ AV_FIELD_TT, //< Top coded_first, top displayed first
+ AV_FIELD_BB, //< Bottom coded first, bottom displayed first
+ AV_FIELD_TB, //< Top coded first, bottom displayed first
+ AV_FIELD_BT, //< Bottom coded first, top displayed first
+};
+
+/**
+ * main external API structure.
+ * New fields can be added to the end with minor version bumps.
+ * Removal, reordering and changes to existing fields require a major
+ * version bump.
+ * sizeof(AVCodecContext) must not be used outside libav*.
+ */
+typedef struct AVCodecContext {
+ /**
+ * information on struct for av_log
+ * - set by avcodec_alloc_context3
+ */
+ const AVClass *av_class;
+ int log_level_offset;
+
+ enum AVMediaType codec_type; /* see AVMEDIA_TYPE_xxx */
+ const struct AVCodec *codec;
+ char codec_name[32];
+ enum AVCodecID codec_id; /* see AV_CODEC_ID_xxx */
+
+ /**
+ * fourcc (LSB first, so "ABCD" -> ('D'<<24) + ('C'<<16) + ('B'<<8) + 'A').
+ * This is used to work around some encoder bugs.
+ * A demuxer should set this to what is stored in the field used to identify the codec.
+ * If there are multiple such fields in a container then the demuxer should choose the one
+ * which maximizes the information about the used codec.
+ * If the codec tag field in a container is larger than 32 bits then the demuxer should
+ * remap the longer ID to 32 bits with a table or other structure. Alternatively a new
+ * extra_codec_tag + size could be added but for this a clear advantage must be demonstrated
+ * first.
+ * - encoding: Set by user, if not then the default based on codec_id will be used.
+ * - decoding: Set by user, will be converted to uppercase by libavcodec during init.
+ */
+ unsigned int codec_tag;
+
+ /**
+ * fourcc from the AVI stream header (LSB first, so "ABCD" -> ('D'<<24) + ('C'<<16) + ('B'<<8) + 'A').
+ * This is used to work around some encoder bugs.
+ * - encoding: unused
+ * - decoding: Set by user, will be converted to uppercase by libavcodec during init.
+ */
+ unsigned int stream_codec_tag;
+
+#if FF_API_SUB_ID
+ /**
+ * @deprecated this field is unused
+ */
+ attribute_deprecated int sub_id;
+#endif
+
+ void *priv_data;
+
+ /**
+ * Private context used for internal data.
+ *
+ * Unlike priv_data, this is not codec-specific. It is used in general
+ * libavcodec functions.
+ */
+ struct AVCodecInternal *internal;
+
+ /**
+ * Private data of the user, can be used to carry app specific stuff.
+ * - encoding: Set by user.
+ * - decoding: Set by user.
+ */
+ void *opaque;
+
+ /**
+ * the average bitrate
+ * - encoding: Set by user; unused for constant quantizer encoding.
+ * - decoding: Set by libavcodec. 0 or some bitrate if this info is available in the stream.
+ */
+ int bit_rate;
+
+ /**
+ * number of bits the bitstream is allowed to diverge from the reference.
+ * the reference can be CBR (for CBR pass1) or VBR (for pass2)
+ * - encoding: Set by user; unused for constant quantizer encoding.
+ * - decoding: unused
+ */
+ int bit_rate_tolerance;
+
+ /**
+ * Global quality for codecs which cannot change it per frame.
+ * This should be proportional to MPEG-1/2/4 qscale.
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int global_quality;
+
+ /**
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int compression_level;
+#define FF_COMPRESSION_DEFAULT -1
+
+ /**
+ * CODEC_FLAG_*.
+ * - encoding: Set by user.
+ * - decoding: Set by user.
+ */
+ int flags;
+
+ /**
+ * CODEC_FLAG2_*
+ * - encoding: Set by user.
+ * - decoding: Set by user.
+ */
+ int flags2;
+
+ /**
+ * some codecs need / can use extradata like Huffman tables.
+ * mjpeg: Huffman tables
+ * rv10: additional flags
+ * mpeg4: global headers (they can be in the bitstream or here)
+ * The allocated memory should be FF_INPUT_BUFFER_PADDING_SIZE bytes larger
+ * than extradata_size to avoid prolems if it is read with the bitstream reader.
+ * The bytewise contents of extradata must not depend on the architecture or CPU endianness.
+ * - encoding: Set/allocated/freed by libavcodec.
+ * - decoding: Set/allocated/freed by user.
+ */
+ uint8_t *extradata;
+ int extradata_size;
+
+ /**
+ * This is the fundamental unit of time (in seconds) in terms
+ * of which frame timestamps are represented. For fixed-fps content,
+ * timebase should be 1/framerate and timestamp increments should be
+ * identically 1.
+ * - encoding: MUST be set by user.
+ * - decoding: Set by libavcodec.
+ */
+ AVRational time_base;
+
+ /**
+ * For some codecs, the time base is closer to the field rate than the frame rate.
+ * Most notably, H.264 and MPEG-2 specify time_base as half of frame duration
+ * if no telecine is used ...
+ *
+ * Set to time_base ticks per frame. Default 1, e.g., H.264/MPEG-2 set it to 2.
+ */
+ int ticks_per_frame;
+
+ /**
+ * Codec delay.
+ *
+ * Video:
+ * Number of frames the decoded output will be delayed relative to the
+ * encoded input.
+ *
+ * Audio:
+ * For encoding, this is the number of "priming" samples added to the
+ * beginning of the stream. The decoded output will be delayed by this
+ * many samples relative to the input to the encoder. Note that this
+ * field is purely informational and does not directly affect the pts
+ * output by the encoder, which should always be based on the actual
+ * presentation time, including any delay.
+ * For decoding, this is the number of samples the decoder needs to
+ * output before the decoder's output is valid. When seeking, you should
+ * start decoding this many samples prior to your desired seek point.
+ *
+ * - encoding: Set by libavcodec.
+ * - decoding: Set by libavcodec.
+ */
+ int delay;
+
+
+ /* video only */
+ /**
+ * picture width / height.
+ * - encoding: MUST be set by user.
+ * - decoding: Set by libavcodec.
+ * Note: For compatibility it is possible to set this instead of
+ * coded_width/height before decoding.
+ */
+ int width, height;
+
+ /**
+ * Bitstream width / height, may be different from width/height.
+ * - encoding: unused
+ * - decoding: Set by user before init if known. Codec should override / dynamically change if needed.
+ */
+ int coded_width, coded_height;
+
+#define FF_ASPECT_EXTENDED 15
+
+ /**
+ * the number of pictures in a group of pictures, or 0 for intra_only
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int gop_size;
+
+ /**
+ * Pixel format, see AV_PIX_FMT_xxx.
+ * May be set by the demuxer if known from headers.
+ * May be overriden by the decoder if it knows better.
+ * - encoding: Set by user.
+ * - decoding: Set by user if known, overridden by libavcodec if known
+ */
+ enum AVPixelFormat pix_fmt;
+
+ /**
+ * Motion estimation algorithm used for video coding.
+ * 1 (zero), 2 (full), 3 (log), 4 (phods), 5 (epzs), 6 (x1), 7 (hex),
+ * 8 (umh), 9 (iter), 10 (tesa) [7, 8, 10 are x264 specific, 9 is snow specific]
+ * - encoding: MUST be set by user.
+ * - decoding: unused
+ */
+ int me_method;
+
+ /**
+ * If non NULL, 'draw_horiz_band' is called by the libavcodec
+ * decoder to draw a horizontal band. It improves cache usage. Not
+ * all codecs can do that. You must check the codec capabilities
+ * beforehand.
+ * When multithreading is used, it may be called from multiple threads
+ * at the same time; threads might draw different parts of the same AVFrame,
+ * or multiple AVFrames, and there is no guarantee that slices will be drawn
+ * in order.
+ * The function is also used by hardware acceleration APIs.
+ * It is called at least once during frame decoding to pass
+ * the data needed for hardware render.
+ * In that mode instead of pixel data, AVFrame points to
+ * a structure specific to the acceleration API. The application
+ * reads the structure and can change some fields to indicate progress
+ * or mark state.
+ * - encoding: unused
+ * - decoding: Set by user.
+ * @param height the height of the slice
+ * @param y the y position of the slice
+ * @param type 1->top field, 2->bottom field, 3->frame
+ * @param offset offset into the AVFrame.data from which the slice should be read
+ */
+ void (*draw_horiz_band)(struct AVCodecContext *s,
+ const AVFrame *src, int offset[AV_NUM_DATA_POINTERS],
+ int y, int type, int height);
+
+ /**
+ * callback to negotiate the pixelFormat
+ * @param fmt is the list of formats which are supported by the codec,
+ * it is terminated by -1 as 0 is a valid format, the formats are ordered by quality.
+ * The first is always the native one.
+ * @return the chosen format
+ * - encoding: unused
+ * - decoding: Set by user, if not set the native format will be chosen.
+ */
+ enum AVPixelFormat (*get_format)(struct AVCodecContext *s, const enum AVPixelFormat * fmt);
+
+ /**
+ * maximum number of B-frames between non-B-frames
+ * Note: The output will be delayed by max_b_frames+1 relative to the input.
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int max_b_frames;
+
+ /**
+ * qscale factor between IP and B-frames
+ * If > 0 then the last P-frame quantizer will be used (q= lastp_q*factor+offset).
+ * If < 0 then normal ratecontrol will be done (q= -normal_q*factor+offset).
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ float b_quant_factor;
+
+ /** obsolete FIXME remove */
+ int rc_strategy;
+#define FF_RC_STRATEGY_XVID 1
+
+ int b_frame_strategy;
+
+#if FF_API_MPV_GLOBAL_OPTS
+ /**
+ * luma single coefficient elimination threshold
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ attribute_deprecated int luma_elim_threshold;
+
+ /**
+ * chroma single coeff elimination threshold
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ attribute_deprecated int chroma_elim_threshold;
+#endif
+
+ /**
+ * qscale offset between IP and B-frames
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ float b_quant_offset;
+
+ /**
+ * Size of the frame reordering buffer in the decoder.
+ * For MPEG-2 it is 1 IPB or 0 low delay IP.
+ * - encoding: Set by libavcodec.
+ * - decoding: Set by libavcodec.
+ */
+ int has_b_frames;
+
+ /**
+ * 0-> h263 quant 1-> mpeg quant
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int mpeg_quant;
+
+ /**
+ * qscale factor between P and I-frames
+ * If > 0 then the last p frame quantizer will be used (q= lastp_q*factor+offset).
+ * If < 0 then normal ratecontrol will be done (q= -normal_q*factor+offset).
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ float i_quant_factor;
+
+ /**
+ * qscale offset between P and I-frames
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ float i_quant_offset;
+
+ /**
+ * luminance masking (0-> disabled)
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ float lumi_masking;
+
+ /**
+ * temporary complexity masking (0-> disabled)
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ float temporal_cplx_masking;
+
+ /**
+ * spatial complexity masking (0-> disabled)
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ float spatial_cplx_masking;
+
+ /**
+ * p block masking (0-> disabled)
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ float p_masking;
+
+ /**
+ * darkness masking (0-> disabled)
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ float dark_masking;
+
+ /**
+ * slice count
+ * - encoding: Set by libavcodec.
+ * - decoding: Set by user (or 0).
+ */
+ int slice_count;
+ /**
+ * prediction method (needed for huffyuv)
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int prediction_method;
+#define FF_PRED_LEFT 0
+#define FF_PRED_PLANE 1
+#define FF_PRED_MEDIAN 2
+
+ /**
+ * slice offsets in the frame in bytes
+ * - encoding: Set/allocated by libavcodec.
+ * - decoding: Set/allocated by user (or NULL).
+ */
+ int *slice_offset;
+
+ /**
+ * sample aspect ratio (0 if unknown)
+ * That is the width of a pixel divided by the height of the pixel.
+ * Numerator and denominator must be relatively prime and smaller than 256 for some video standards.
+ * - encoding: Set by user.
+ * - decoding: Set by libavcodec.
+ */
+ AVRational sample_aspect_ratio;
+
+ /**
+ * motion estimation comparison function
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int me_cmp;
+ /**
+ * subpixel motion estimation comparison function
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int me_sub_cmp;
+ /**
+ * macroblock comparison function (not supported yet)
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int mb_cmp;
+ /**
+ * interlaced DCT comparison function
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int ildct_cmp;
+#define FF_CMP_SAD 0
+#define FF_CMP_SSE 1
+#define FF_CMP_SATD 2
+#define FF_CMP_DCT 3
+#define FF_CMP_PSNR 4
+#define FF_CMP_BIT 5
+#define FF_CMP_RD 6
+#define FF_CMP_ZERO 7
+#define FF_CMP_VSAD 8
+#define FF_CMP_VSSE 9
+#define FF_CMP_NSSE 10
+#define FF_CMP_W53 11
+#define FF_CMP_W97 12
+#define FF_CMP_DCTMAX 13
+#define FF_CMP_DCT264 14
+#define FF_CMP_CHROMA 256
+
+ /**
+ * ME diamond size & shape
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int dia_size;
+
+ /**
+ * amount of previous MV predictors (2a+1 x 2a+1 square)
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int last_predictor_count;
+
+ /**
+ * prepass for motion estimation
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int pre_me;
+
+ /**
+ * motion estimation prepass comparison function
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int me_pre_cmp;
+
+ /**
+ * ME prepass diamond size & shape
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int pre_dia_size;
+
+ /**
+ * subpel ME quality
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int me_subpel_quality;
+
+ /**
+ * DTG active format information (additional aspect ratio
+ * information only used in DVB MPEG-2 transport streams)
+ * 0 if not set.
+ *
+ * - encoding: unused
+ * - decoding: Set by decoder.
+ */
+ int dtg_active_format;
+#define FF_DTG_AFD_SAME 8
+#define FF_DTG_AFD_4_3 9
+#define FF_DTG_AFD_16_9 10
+#define FF_DTG_AFD_14_9 11
+#define FF_DTG_AFD_4_3_SP_14_9 13
+#define FF_DTG_AFD_16_9_SP_14_9 14
+#define FF_DTG_AFD_SP_4_3 15
+
+ /**
+ * maximum motion estimation search range in subpel units
+ * If 0 then no limit.
+ *
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int me_range;
+
+ /**
+ * intra quantizer bias
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int intra_quant_bias;
+#define FF_DEFAULT_QUANT_BIAS 999999
+
+ /**
+ * inter quantizer bias
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int inter_quant_bias;
+
+#if FF_API_COLOR_TABLE_ID
+ /**
+ * color table ID
+ * - encoding: unused
+ * - decoding: Which clrtable should be used for 8bit RGB images.
+ * Tables have to be stored somewhere. FIXME
+ */
+ attribute_deprecated int color_table_id;
+#endif
+
+ /**
+ * slice flags
+ * - encoding: unused
+ * - decoding: Set by user.
+ */
+ int slice_flags;
+#define SLICE_FLAG_CODED_ORDER 0x0001 ///< draw_horiz_band() is called in coded order instead of display
+#define SLICE_FLAG_ALLOW_FIELD 0x0002 ///< allow draw_horiz_band() with field slices (MPEG2 field pics)
+#define SLICE_FLAG_ALLOW_PLANE 0x0004 ///< allow draw_horiz_band() with 1 component at a time (SVQ1)
+
+ /**
+ * XVideo Motion Acceleration
+ * - encoding: forbidden
+ * - decoding: set by decoder
+ */
+ int xvmc_acceleration;
+
+ /**
+ * macroblock decision mode
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int mb_decision;
+#define FF_MB_DECISION_SIMPLE 0 ///< uses mb_cmp
+#define FF_MB_DECISION_BITS 1 ///< chooses the one which needs the fewest bits
+#define FF_MB_DECISION_RD 2 ///< rate distortion
+
+ /**
+ * custom intra quantization matrix
+ * - encoding: Set by user, can be NULL.
+ * - decoding: Set by libavcodec.
+ */
+ uint16_t *intra_matrix;
+
+ /**
+ * custom inter quantization matrix
+ * - encoding: Set by user, can be NULL.
+ * - decoding: Set by libavcodec.
+ */
+ uint16_t *inter_matrix;
+
+ /**
+ * scene change detection threshold
+ * 0 is default, larger means fewer detected scene changes.
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int scenechange_threshold;
+
+ /**
+ * noise reduction strength
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int noise_reduction;
+
+#if FF_API_INTER_THRESHOLD
+ /**
+ * @deprecated this field is unused
+ */
+ attribute_deprecated int inter_threshold;
+#endif
+
+#if FF_API_MPV_GLOBAL_OPTS
+ /**
+ * @deprecated use mpegvideo private options instead
+ */
+ attribute_deprecated int quantizer_noise_shaping;
+#endif
+
+ /**
+ * Motion estimation threshold below which no motion estimation is
+ * performed, but instead the user specified motion vectors are used.
+ *
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int me_threshold;
+
+ /**
+ * Macroblock threshold below which the user specified macroblock types will be used.
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int mb_threshold;
+
+ /**
+ * precision of the intra DC coefficient - 8
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int intra_dc_precision;
+
+ /**
+ * Number of macroblock rows at the top which are skipped.
+ * - encoding: unused
+ * - decoding: Set by user.
+ */
+ int skip_top;
+
+ /**
+ * Number of macroblock rows at the bottom which are skipped.
+ * - encoding: unused
+ * - decoding: Set by user.
+ */
+ int skip_bottom;
+
+ /**
+ * Border processing masking, raises the quantizer for mbs on the borders
+ * of the picture.
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ float border_masking;
+
+ /**
+ * minimum MB lagrange multipler
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int mb_lmin;
+
+ /**
+ * maximum MB lagrange multipler
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int mb_lmax;
+
+ /**
+ *
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int me_penalty_compensation;
+
+ /**
+ *
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int bidir_refine;
+
+ /**
+ *
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int brd_scale;
+
+ /**
+ * minimum GOP size
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int keyint_min;
+
+ /**
+ * number of reference frames
+ * - encoding: Set by user.
+ * - decoding: Set by lavc.
+ */
+ int refs;
+
+ /**
+ * chroma qp offset from luma
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int chromaoffset;
+
+ /**
+ * Multiplied by qscale for each frame and added to scene_change_score.
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int scenechange_factor;
+
+ /**
+ *
+ * Note: Value depends upon the compare function used for fullpel ME.
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int mv0_threshold;
+
+ /**
+ * Adjust sensitivity of b_frame_strategy 1.
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int b_sensitivity;
+
+ /**
+ * Chromaticity coordinates of the source primaries.
+ * - encoding: Set by user
+ * - decoding: Set by libavcodec
+ */
+ enum AVColorPrimaries color_primaries;
+
+ /**
+ * Color Transfer Characteristic.
+ * - encoding: Set by user
+ * - decoding: Set by libavcodec
+ */
+ enum AVColorTransferCharacteristic color_trc;
+
+ /**
+ * YUV colorspace type.
+ * - encoding: Set by user
+ * - decoding: Set by libavcodec
+ */
+ enum AVColorSpace colorspace;
+
+ /**
+ * MPEG vs JPEG YUV range.
+ * - encoding: Set by user
+ * - decoding: Set by libavcodec
+ */
+ enum AVColorRange color_range;
+
+ /**
+ * This defines the location of chroma samples.
+ * - encoding: Set by user
+ * - decoding: Set by libavcodec
+ */
+ enum AVChromaLocation chroma_sample_location;
+
+ /**
+ * Number of slices.
+ * Indicates number of picture subdivisions. Used for parallelized
+ * decoding.
+ * - encoding: Set by user
+ * - decoding: unused
+ */
+ int slices;
+
+ /** Field order
+ * - encoding: set by libavcodec
+ * - decoding: Set by libavcodec
+ */
+ enum AVFieldOrder field_order;
+
+ /* audio only */
+ int sample_rate; ///< samples per second
+ int channels; ///< number of audio channels
+
+ /**
+ * audio sample format
+ * - encoding: Set by user.
+ * - decoding: Set by libavcodec.
+ */
+ enum AVSampleFormat sample_fmt; ///< sample format
+
+ /* The following data should not be initialized. */
+ /**
+ * Number of samples per channel in an audio frame.
+ *
+ * - encoding: set by libavcodec in avcodec_open2(). Each submitted frame
+ * except the last must contain exactly frame_size samples per channel.
+ * May be 0 when the codec has CODEC_CAP_VARIABLE_FRAME_SIZE set, then the
+ * frame size is not restricted.
+ * - decoding: may be set by some decoders to indicate constant frame size
+ */
+ int frame_size;
+
+ /**
+ * Frame counter, set by libavcodec.
+ *
+ * - decoding: total number of frames returned from the decoder so far.
+ * - encoding: total number of frames passed to the encoder so far.
+ *
+ * @note the counter is not incremented if encoding/decoding resulted in
+ * an error.
+ */
+ int frame_number;
+
+ /**
+ * number of bytes per packet if constant and known or 0
+ * Used by some WAV based audio codecs.
+ */
+ int block_align;
+
+ /**
+ * Audio cutoff bandwidth (0 means "automatic")
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int cutoff;
+
+#if FF_API_REQUEST_CHANNELS
+ /**
+ * Decoder should decode to this many channels if it can (0 for default)
+ * - encoding: unused
+ * - decoding: Set by user.
+ * @deprecated Deprecated in favor of request_channel_layout.
+ */
+ int request_channels;
+#endif
+
+ /**
+ * Audio channel layout.
+ * - encoding: set by user.
+ * - decoding: set by libavcodec.
+ */
+ uint64_t channel_layout;
+
+ /**
+ * Request decoder to use this channel layout if it can (0 for default)
+ * - encoding: unused
+ * - decoding: Set by user.
+ */
+ uint64_t request_channel_layout;
+
+ /**
+ * Type of service that the audio stream conveys.
+ * - encoding: Set by user.
+ * - decoding: Set by libavcodec.
+ */
+ enum AVAudioServiceType audio_service_type;
+
+ /**
+ * Used to request a sample format from the decoder.
+ * - encoding: unused.
+ * - decoding: Set by user.
+ */
+ enum AVSampleFormat request_sample_fmt;
+
+ /**
+ * Called at the beginning of each frame to get a buffer for it.
+ *
+ * The function will set AVFrame.data[], AVFrame.linesize[].
+ * AVFrame.extended_data[] must also be set, but it should be the same as
+ * AVFrame.data[] except for planar audio with more channels than can fit
+ * in AVFrame.data[]. In that case, AVFrame.data[] shall still contain as
+ * many data pointers as it can hold.
+ *
+ * if CODEC_CAP_DR1 is not set then get_buffer() must call
+ * avcodec_default_get_buffer() instead of providing buffers allocated by
+ * some other means.
+ *
+ * AVFrame.data[] should be 32- or 16-byte-aligned unless the CPU doesn't
+ * need it. avcodec_default_get_buffer() aligns the output buffer properly,
+ * but if get_buffer() is overridden then alignment considerations should
+ * be taken into account.
+ *
+ * @see avcodec_default_get_buffer()
+ *
+ * Video:
+ *
+ * If pic.reference is set then the frame will be read later by libavcodec.
+ * avcodec_align_dimensions2() should be used to find the required width and
+ * height, as they normally need to be rounded up to the next multiple of 16.
+ *
+ * If frame multithreading is used and thread_safe_callbacks is set,
+ * it may be called from a different thread, but not from more than one at
+ * once. Does not need to be reentrant.
+ *
+ * @see release_buffer(), reget_buffer()
+ * @see avcodec_align_dimensions2()
+ *
+ * Audio:
+ *
+ * Decoders request a buffer of a particular size by setting
+ * AVFrame.nb_samples prior to calling get_buffer(). The decoder may,
+ * however, utilize only part of the buffer by setting AVFrame.nb_samples
+ * to a smaller value in the output frame.
+ *
+ * Decoders cannot use the buffer after returning from
+ * avcodec_decode_audio4(), so they will not call release_buffer(), as it
+ * is assumed to be released immediately upon return. In some rare cases,
+ * a decoder may need to call get_buffer() more than once in a single
+ * call to avcodec_decode_audio4(). In that case, when get_buffer() is
+ * called again after it has already been called once, the previously
+ * acquired buffer is assumed to be released at that time and may not be
+ * reused by the decoder.
+ *
+ * As a convenience, av_samples_get_buffer_size() and
+ * av_samples_fill_arrays() in libavutil may be used by custom get_buffer()
+ * functions to find the required data size and to fill data pointers and
+ * linesize. In AVFrame.linesize, only linesize[0] may be set for audio
+ * since all planes must be the same size.
+ *
+ * @see av_samples_get_buffer_size(), av_samples_fill_arrays()
+ *
+ * - encoding: unused
+ * - decoding: Set by libavcodec, user can override.
+ */
+ int (*get_buffer)(struct AVCodecContext *c, AVFrame *pic);
+
+ /**
+ * Called to release buffers which were allocated with get_buffer.
+ * A released buffer can be reused in get_buffer().
+ * pic.data[*] must be set to NULL.
+ * May be called from a different thread if frame multithreading is used,
+ * but not by more than one thread at once, so does not need to be reentrant.
+ * - encoding: unused
+ * - decoding: Set by libavcodec, user can override.
+ */
+ void (*release_buffer)(struct AVCodecContext *c, AVFrame *pic);
+
+ /**
+ * Called at the beginning of a frame to get cr buffer for it.
+ * Buffer type (size, hints) must be the same. libavcodec won't check it.
+ * libavcodec will pass previous buffer in pic, function should return
+ * same buffer or new buffer with old frame "painted" into it.
+ * If pic.data[0] == NULL must behave like get_buffer().
+ * if CODEC_CAP_DR1 is not set then reget_buffer() must call
+ * avcodec_default_reget_buffer() instead of providing buffers allocated by
+ * some other means.
+ * - encoding: unused
+ * - decoding: Set by libavcodec, user can override.
+ */
+ int (*reget_buffer)(struct AVCodecContext *c, AVFrame *pic);
+
+
+ /* - encoding parameters */
+ float qcompress; ///< amount of qscale change between easy & hard scenes (0.0-1.0)
+ float qblur; ///< amount of qscale smoothing over time (0.0-1.0)
+
+ /**
+ * minimum quantizer
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int qmin;
+
+ /**
+ * maximum quantizer
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int qmax;
+
+ /**
+ * maximum quantizer difference between frames
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int max_qdiff;
+
+ /**
+ * ratecontrol qmin qmax limiting method
+ * 0-> clipping, 1-> use a nice continuous function to limit qscale wthin qmin/qmax.
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ float rc_qsquish;
+
+ float rc_qmod_amp;
+ int rc_qmod_freq;
+
+ /**
+ * decoder bitstream buffer size
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int rc_buffer_size;
+
+ /**
+ * ratecontrol override, see RcOverride
+ * - encoding: Allocated/set/freed by user.
+ * - decoding: unused
+ */
+ int rc_override_count;
+ RcOverride *rc_override;
+
+ /**
+ * rate control equation
+ * - encoding: Set by user
+ * - decoding: unused
+ */
+ const char *rc_eq;
+
+ /**
+ * maximum bitrate
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int rc_max_rate;
+
+ /**
+ * minimum bitrate
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int rc_min_rate;
+
+ float rc_buffer_aggressivity;
+
+ /**
+ * initial complexity for pass1 ratecontrol
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ float rc_initial_cplx;
+
+ /**
+ * Ratecontrol attempt to use, at maximum,
- * Note: If the first 23 bits of the additional bytes are not 0, then damaged
- * MPEG bitstreams could cause overread and segfault.
- */
-#define FF_INPUT_BUFFER_PADDING_SIZE 8
-
-/**
- * minimum encoding buffer size
- * Used to avoid some checks during header writing.
- */
-#define FF_MIN_BUFFER_SIZE 16384
-
-
-/**
- * motion estimation type.
- */
-enum Motion_Est_ID {
- ME_ZERO = 1, ///< no search, that is use 0,0 vector whenever one is needed
- ME_FULL,
- ME_LOG,
- ME_PHODS,
- ME_EPZS, ///< enhanced predictive zonal search
- ME_X1, ///< reserved for experiments
- ME_HEX, ///< hexagon based search
- ME_UMH, ///< uneven multi-hexagon search
- ME_ITER, ///< iterative search
- ME_TESA, ///< transformed exhaustive search algorithm
-};
-
-enum AVDiscard{
- /* We leave some space between them for extensions (drop some
- * keyframes for intra-only or drop just some bidir frames). */
- AVDISCARD_NONE =-16, ///< discard nothing
- AVDISCARD_DEFAULT= 0, ///< discard useless packets like 0 size packets in avi
- AVDISCARD_NONREF = 8, ///< discard all non reference
- AVDISCARD_BIDIR = 16, ///< discard all bidirectional frames
- AVDISCARD_NONKEY = 32, ///< discard all frames except keyframes
- AVDISCARD_ALL = 48, ///< discard all
-};
-
-enum AVColorPrimaries{
- AVCOL_PRI_BT709 =1, ///< also ITU-R BT1361 / IEC 61966-2-4 / SMPTE RP177 Annex B
- AVCOL_PRI_UNSPECIFIED=2,
- AVCOL_PRI_BT470M =4,
- AVCOL_PRI_BT470BG =5, ///< also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM
- AVCOL_PRI_SMPTE170M =6, ///< also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC
- AVCOL_PRI_SMPTE240M =7, ///< functionally identical to above
- AVCOL_PRI_FILM =8,
- AVCOL_PRI_NB , ///< Not part of ABI
-};
-
-enum AVColorTransferCharacteristic{
- AVCOL_TRC_BT709 =1, ///< also ITU-R BT1361
- AVCOL_TRC_UNSPECIFIED=2,
- AVCOL_TRC_GAMMA22 =4, ///< also ITU-R BT470M / ITU-R BT1700 625 PAL & SECAM
- AVCOL_TRC_GAMMA28 =5, ///< also ITU-R BT470BG
- AVCOL_TRC_NB , ///< Not part of ABI
-};
-
-enum AVColorSpace{
- AVCOL_SPC_RGB =0,
- AVCOL_SPC_BT709 =1, ///< also ITU-R BT1361 / IEC 61966-2-4 xvYCC709 / SMPTE RP177 Annex B
- AVCOL_SPC_UNSPECIFIED=2,
- AVCOL_SPC_FCC =4,
- AVCOL_SPC_BT470BG =5, ///< also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM / IEC 61966-2-4 xvYCC601
- AVCOL_SPC_SMPTE170M =6, ///< also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC / functionally identical to above
- AVCOL_SPC_SMPTE240M =7,
- AVCOL_SPC_NB , ///< Not part of ABI
-};
-
-enum AVColorRange{
- AVCOL_RANGE_UNSPECIFIED=0,
- AVCOL_RANGE_MPEG =1, ///< the normal 219*2^(n-8) "MPEG" YUV ranges
- AVCOL_RANGE_JPEG =2, ///< the normal 2^n-1 "JPEG" YUV ranges
- AVCOL_RANGE_NB , ///< Not part of ABI
-};
-
-/**
- * X X 3 4 X X are luma samples,
- * 1 2 1-6 are possible chroma positions
- * X X 5 6 X 0 is undefined/unknown position
- */
-enum AVChromaLocation{
- AVCHROMA_LOC_UNSPECIFIED=0,
- AVCHROMA_LOC_LEFT =1, ///< mpeg2/4, h264 default
- AVCHROMA_LOC_CENTER =2, ///< mpeg1, jpeg, h263
- AVCHROMA_LOC_TOPLEFT =3, ///< DV
- AVCHROMA_LOC_TOP =4,
- AVCHROMA_LOC_BOTTOMLEFT =5,
- AVCHROMA_LOC_BOTTOM =6,
- AVCHROMA_LOC_NB , ///< Not part of ABI
-};
-
-#if FF_API_FLAC_GLOBAL_OPTS
-/**
- * LPC analysis type
- */
-enum AVLPCType {
- AV_LPC_TYPE_DEFAULT = -1, ///< use the codec default LPC type
- AV_LPC_TYPE_NONE = 0, ///< do not use LPC prediction or use all zero coefficients
- AV_LPC_TYPE_FIXED = 1, ///< fixed LPC coefficients
- AV_LPC_TYPE_LEVINSON = 2, ///< Levinson-Durbin recursion
- AV_LPC_TYPE_CHOLESKY = 3, ///< Cholesky factorization
- AV_LPC_TYPE_NB , ///< Not part of ABI
-};
-#endif
-
-enum AVAudioServiceType {
- AV_AUDIO_SERVICE_TYPE_MAIN = 0,
- AV_AUDIO_SERVICE_TYPE_EFFECTS = 1,
- AV_AUDIO_SERVICE_TYPE_VISUALLY_IMPAIRED = 2,
- AV_AUDIO_SERVICE_TYPE_HEARING_IMPAIRED = 3,
- AV_AUDIO_SERVICE_TYPE_DIALOGUE = 4,
- AV_AUDIO_SERVICE_TYPE_COMMENTARY = 5,
- AV_AUDIO_SERVICE_TYPE_EMERGENCY = 6,
- AV_AUDIO_SERVICE_TYPE_VOICE_OVER = 7,
- AV_AUDIO_SERVICE_TYPE_KARAOKE = 8,
- AV_AUDIO_SERVICE_TYPE_NB , ///< Not part of ABI
-};
-
-typedef struct RcOverride{
- int start_frame;
- int end_frame;
- int qscale; // If this is 0 then quality_factor will be used instead.
- float quality_factor;
-} RcOverride;
-
-#define FF_MAX_B_FRAMES 16
-
-/* encoding support
- These flags can be passed in AVCodecContext.flags before initialization.
- Note: Not everything is supported yet.
-*/
-
-#define CODEC_FLAG_QSCALE 0x0002 ///< Use fixed qscale.
-#define CODEC_FLAG_4MV 0x0004 ///< 4 MV per MB allowed / advanced prediction for H.263.
-#define CODEC_FLAG_QPEL 0x0010 ///< Use qpel MC.
-#define CODEC_FLAG_GMC 0x0020 ///< Use GMC.
-#define CODEC_FLAG_MV0 0x0040 ///< Always try a MB with MV=<0,0>.
-/**
- * The parent program guarantees that the input for B-frames containing
- * streams is not written to for at least s->max_b_frames+1 frames, if
- * this is not set the input will be copied.
- */
-#define CODEC_FLAG_INPUT_PRESERVED 0x0100
-#define CODEC_FLAG_PASS1 0x0200 ///< Use internal 2pass ratecontrol in first pass mode.
-#define CODEC_FLAG_PASS2 0x0400 ///< Use internal 2pass ratecontrol in second pass mode.
-#define CODEC_FLAG_GRAY 0x2000 ///< Only decode/encode grayscale.
-#define CODEC_FLAG_EMU_EDGE 0x4000 ///< Don't draw edges.
-#define CODEC_FLAG_PSNR 0x8000 ///< error[?] variables will be set during encoding.
-#define CODEC_FLAG_TRUNCATED 0x00010000 /** Input bitstream might be truncated at a random
- location instead of only at frame boundaries. */
-#define CODEC_FLAG_NORMALIZE_AQP 0x00020000 ///< Normalize adaptive quantization.
-#define CODEC_FLAG_INTERLACED_DCT 0x00040000 ///< Use interlaced DCT.
-#define CODEC_FLAG_LOW_DELAY 0x00080000 ///< Force low delay.
-#define CODEC_FLAG_GLOBAL_HEADER 0x00400000 ///< Place global headers in extradata instead of every keyframe.
-#define CODEC_FLAG_BITEXACT 0x00800000 ///< Use only bitexact stuff (except (I)DCT).
-/* Fx : Flag for h263+ extra options */
-#define CODEC_FLAG_AC_PRED 0x01000000 ///< H.263 advanced intra coding / MPEG-4 AC prediction
-#define CODEC_FLAG_CBP_RD 0x04000000 ///< Use rate distortion optimization for cbp.
-#define CODEC_FLAG_QP_RD 0x08000000 ///< Use rate distortion optimization for qp selectioon.
-#define CODEC_FLAG_LOOP_FILTER 0x00000800 ///< loop filter
-#define CODEC_FLAG_INTERLACED_ME 0x20000000 ///< interlaced motion estimation
-#define CODEC_FLAG_CLOSED_GOP 0x80000000
-#define CODEC_FLAG2_FAST 0x00000001 ///< Allow non spec compliant speedup tricks.
-#define CODEC_FLAG2_STRICT_GOP 0x00000002 ///< Strictly enforce GOP size.
-#define CODEC_FLAG2_NO_OUTPUT 0x00000004 ///< Skip bitstream encoding.
-#define CODEC_FLAG2_LOCAL_HEADER 0x00000008 ///< Place global headers at every keyframe instead of in extradata.
-#define CODEC_FLAG2_SKIP_RD 0x00004000 ///< RD optimal MB level residual skipping
-#define CODEC_FLAG2_CHUNKS 0x00008000 ///< Input bitstream might be truncated at a packet boundaries instead of only at frame boundaries.
-/**
- * @defgroup deprecated_flags Deprecated codec flags
- * Use corresponding private codec options instead.
- * @{
- */
-#if FF_API_MPEGVIDEO_GLOBAL_OPTS
-#define CODEC_FLAG_OBMC 0x00000001 ///< OBMC
-#define CODEC_FLAG_H263P_AIV 0x00000008 ///< H.263 alternative inter VLC
-#define CODEC_FLAG_PART 0x0080 ///< Use data partitioning.
-#define CODEC_FLAG_ALT_SCAN 0x00100000 ///< Use alternate scan.
-#define CODEC_FLAG_H263P_UMV 0x02000000 ///< unlimited motion vector
-#define CODEC_FLAG_H263P_SLICE_STRUCT 0x10000000
-#define CODEC_FLAG_SVCD_SCAN_OFFSET 0x40000000 ///< Will reserve space for SVCD scan offset user data.
-#define CODEC_FLAG2_INTRA_VLC 0x00000800 ///< Use MPEG-2 intra VLC table.
-#define CODEC_FLAG2_DROP_FRAME_TIMECODE 0x00002000 ///< timecode is in drop frame format.
-#define CODEC_FLAG2_NON_LINEAR_QUANT 0x00010000 ///< Use MPEG-2 nonlinear quantizer.
-#endif
-#if FF_API_MJPEG_GLOBAL_OPTS
-#define CODEC_FLAG_EXTERN_HUFF 0x1000 ///< Use external Huffman table (for MJPEG).
-#endif
-#if FF_API_X264_GLOBAL_OPTS
-#define CODEC_FLAG2_BPYRAMID 0x00000010 ///< H.264 allow B-frames to be used as references.
-#define CODEC_FLAG2_WPRED 0x00000020 ///< H.264 weighted biprediction for B-frames
-#define CODEC_FLAG2_MIXED_REFS 0x00000040 ///< H.264 one reference per partition, as opposed to one reference per macroblock
-#define CODEC_FLAG2_8X8DCT 0x00000080 ///< H.264 high profile 8x8 transform
-#define CODEC_FLAG2_FASTPSKIP 0x00000100 ///< H.264 fast pskip
-#define CODEC_FLAG2_AUD 0x00000200 ///< H.264 access unit delimiters
-#define CODEC_FLAG2_BRDO 0x00000400 ///< B-frame rate-distortion optimization
-#define CODEC_FLAG2_MBTREE 0x00040000 ///< Use macroblock tree ratecontrol (x264 only)
-#define CODEC_FLAG2_PSY 0x00080000 ///< Use psycho visual optimizations.
-#define CODEC_FLAG2_SSIM 0x00100000 ///< Compute SSIM during encoding, error[] values are undefined.
-#define CODEC_FLAG2_INTRA_REFRESH 0x00200000 ///< Use periodic insertion of intra blocks instead of keyframes.
-#endif
-#if FF_API_SNOW_GLOBAL_OPTS
-#define CODEC_FLAG2_MEMC_ONLY 0x00001000 ///< Only do ME/MC (I frames -> ref, P frame -> ME+MC).
-#endif
-#if FF_API_LAME_GLOBAL_OPTS
-#define CODEC_FLAG2_BIT_RESERVOIR 0x00020000 ///< Use a bit reservoir when encoding if possible
-#endif
-/**
- * @}
- */
-
-/* Unsupported options :
- * Syntax Arithmetic coding (SAC)
- * Reference Picture Selection
- * Independent Segment Decoding */
-/* /Fx */
-/* codec capabilities */
-
-#define CODEC_CAP_DRAW_HORIZ_BAND 0x0001 ///< Decoder can use draw_horiz_band callback.
-/**
- * Codec uses get_buffer() for allocating buffers and supports custom allocators.
- * If not set, it might not use get_buffer() at all or use operations that
- * assume the buffer was allocated by avcodec_default_get_buffer.
- */
-#define CODEC_CAP_DR1 0x0002
-#if FF_API_PARSE_FRAME
-/* If 'parse_only' field is true, then avcodec_parse_frame() can be used. */
-#define CODEC_CAP_PARSE_ONLY 0x0004
-#endif
-#define CODEC_CAP_TRUNCATED 0x0008
-/* Codec can export data for HW decoding (XvMC). */
-#define CODEC_CAP_HWACCEL 0x0010
-/**
- * Encoder or decoder requires flushing with NULL input at the end in order to
- * give the complete and correct output.
- *
- * NOTE: If this flag is not set, the codec is guaranteed to never be fed with
- * with NULL data. The user can still send NULL data to the public encode
- * or decode function, but libavcodec will not pass it along to the codec
- * unless this flag is set.
- *
- * Decoders:
- * The decoder has a non-zero delay and needs to be fed with avpkt->data=NULL,
- * avpkt->size=0 at the end to get the delayed data until the decoder no longer
- * returns frames.
- *
- * Encoders:
- * The encoder needs to be fed with NULL data at the end of encoding until the
- * encoder no longer returns data.
- *
- * NOTE: For encoders implementing the AVCodec.encode2() function, setting this
- * flag also means that the encoder must set the pts and duration for
- * each output packet. If this flag is not set, the pts and duration will
- * be determined by libavcodec from the input frame.
- */
-#define CODEC_CAP_DELAY 0x0020
-/**
- * Codec can be fed a final frame with a smaller size.
- * This can be used to prevent truncation of the last audio samples.
- */
-#define CODEC_CAP_SMALL_LAST_FRAME 0x0040
-/**
- * Codec can export data for HW decoding (VDPAU).
- */
-#define CODEC_CAP_HWACCEL_VDPAU 0x0080
-/**
- * Codec can output multiple frames per AVPacket
- * Normally demuxers return one frame at a time, demuxers which do not do
- * are connected to a parser to split what they return into proper frames.
- * This flag is reserved to the very rare category of codecs which have a
- * bitstream that cannot be split into frames without timeconsuming
- * operations like full decoding. Demuxers carring such bitstreams thus
- * may return multiple frames in a packet. This has many disadvantages like
- * prohibiting stream copy in many cases thus it should only be considered
- * as a last resort.
- */
-#define CODEC_CAP_SUBFRAMES 0x0100
-/**
- * Codec is experimental and is thus avoided in favor of non experimental
- * encoders
- */
-#define CODEC_CAP_EXPERIMENTAL 0x0200
-/**
- * Codec should fill in channel configuration and samplerate instead of container
- */
-#define CODEC_CAP_CHANNEL_CONF 0x0400
-/**
- * Codec is able to deal with negative linesizes
- */
-#define CODEC_CAP_NEG_LINESIZES 0x0800
-/**
- * Codec supports frame-level multithreading.
- */
-#define CODEC_CAP_FRAME_THREADS 0x1000
-/**
- * Codec supports slice-based (or partition-based) multithreading.
- */
-#define CODEC_CAP_SLICE_THREADS 0x2000
-/**
- * Codec supports changed parameters at any point.
- */
-#define CODEC_CAP_PARAM_CHANGE 0x4000
-/**
- * Codec supports avctx->thread_count == 0 (auto).
- */
-#define CODEC_CAP_AUTO_THREADS 0x8000
-/**
- * Audio encoder supports receiving a different number of samples in each call.
- */
-#define CODEC_CAP_VARIABLE_FRAME_SIZE 0x10000
-
-//The following defines may change, don't expect compatibility if you use them.
-#define MB_TYPE_INTRA4x4 0x0001
-#define MB_TYPE_INTRA16x16 0x0002 //FIXME H.264-specific
-#define MB_TYPE_INTRA_PCM 0x0004 //FIXME H.264-specific
-#define MB_TYPE_16x16 0x0008
-#define MB_TYPE_16x8 0x0010
-#define MB_TYPE_8x16 0x0020
-#define MB_TYPE_8x8 0x0040
-#define MB_TYPE_INTERLACED 0x0080
-#define MB_TYPE_DIRECT2 0x0100 //FIXME
-#define MB_TYPE_ACPRED 0x0200
-#define MB_TYPE_GMC 0x0400
-#define MB_TYPE_SKIP 0x0800
-#define MB_TYPE_P0L0 0x1000
-#define MB_TYPE_P1L0 0x2000
-#define MB_TYPE_P0L1 0x4000
-#define MB_TYPE_P1L1 0x8000
-#define MB_TYPE_L0 (MB_TYPE_P0L0 | MB_TYPE_P1L0)
-#define MB_TYPE_L1 (MB_TYPE_P0L1 | MB_TYPE_P1L1)
-#define MB_TYPE_L0L1 (MB_TYPE_L0 | MB_TYPE_L1)
-#define MB_TYPE_QUANT 0x00010000
-#define MB_TYPE_CBP 0x00020000
-//Note bits 24-31 are reserved for codec specific use (h264 ref0, mpeg1 0mv, ...)
-
-/**
- * Pan Scan area.
- * This specifies the area which should be displayed.
- * Note there may be multiple such areas for one frame.
- */
-typedef struct AVPanScan{
- /**
- * id
- * - encoding: Set by user.
- * - decoding: Set by libavcodec.
- */
- int id;
-
- /**
- * width and height in 1/16 pel
- * - encoding: Set by user.
- * - decoding: Set by libavcodec.
- */
- int width;
- int height;
-
- /**
- * position of the top left corner in 1/16 pel for up to 3 fields/frames
- * - encoding: Set by user.
- * - decoding: Set by libavcodec.
- */
- int16_t position[3][2];
-}AVPanScan;
-
-#define FF_QSCALE_TYPE_MPEG1 0
-#define FF_QSCALE_TYPE_MPEG2 1
-#define FF_QSCALE_TYPE_H264 2
-#define FF_QSCALE_TYPE_VP56 3
-
-#define FF_BUFFER_TYPE_INTERNAL 1
-#define FF_BUFFER_TYPE_USER 2 ///< direct rendering buffers (image is (de)allocated by user)
-#define FF_BUFFER_TYPE_SHARED 4 ///< Buffer from somewhere else; don't deallocate image (data/base), all other tables are not shared.
-#define FF_BUFFER_TYPE_COPY 8 ///< Just a (modified) copy of some other buffer, don't deallocate anything.
-
-#if FF_API_OLD_FF_PICT_TYPES
-/* DEPRECATED, directly use the AV_PICTURE_TYPE_* enum values */
-#define FF_I_TYPE AV_PICTURE_TYPE_I ///< Intra
-#define FF_P_TYPE AV_PICTURE_TYPE_P ///< Predicted
-#define FF_B_TYPE AV_PICTURE_TYPE_B ///< Bi-dir predicted
-#define FF_S_TYPE AV_PICTURE_TYPE_S ///< S(GMC)-VOP MPEG4
-#define FF_SI_TYPE AV_PICTURE_TYPE_SI ///< Switching Intra
-#define FF_SP_TYPE AV_PICTURE_TYPE_SP ///< Switching Predicted
-#define FF_BI_TYPE AV_PICTURE_TYPE_BI
-#endif
-
-#define FF_BUFFER_HINTS_VALID 0x01 // Buffer hints value is meaningful (if 0 ignore).
-#define FF_BUFFER_HINTS_READABLE 0x02 // Codec will read from buffer.
-#define FF_BUFFER_HINTS_PRESERVE 0x04 // User must not alter buffer content.
-#define FF_BUFFER_HINTS_REUSABLE 0x08 // Codec will reuse the buffer (update).
-
-enum AVPacketSideDataType {
- AV_PKT_DATA_PALETTE,
- AV_PKT_DATA_NEW_EXTRADATA,
- AV_PKT_DATA_PARAM_CHANGE,
-};
-
-typedef struct AVPacket {
- /**
- * Presentation timestamp in AVStream->time_base units; the time at which
- * the decompressed packet will be presented to the user.
- * Can be AV_NOPTS_VALUE if it is not stored in the file.
- * pts MUST be larger or equal to dts as presentation cannot happen before
- * decompression, unless one wants to view hex dumps. Some formats misuse
- * the terms dts and pts/cts to mean something different. Such timestamps
- * must be converted to true pts/dts before they are stored in AVPacket.
- */
- int64_t pts;
- /**
- * Decompression timestamp in AVStream->time_base units; the time at which
- * the packet is decompressed.
- * Can be AV_NOPTS_VALUE if it is not stored in the file.
- */
- int64_t dts;
- uint8_t *data;
- int size;
- int stream_index;
- /**
- * A combination of AV_PKT_FLAG values
- */
- int flags;
- /**
- * Additional packet data that can be provided by the container.
- * Packet can contain several types of side information.
- */
- struct {
- uint8_t *data;
- int size;
- enum AVPacketSideDataType type;
- } *side_data;
- int side_data_elems;
-
- /**
- * Duration of this packet in AVStream->time_base units, 0 if unknown.
- * Equals next_pts - this_pts in presentation order.
- */
- int duration;
- void (*destruct)(struct AVPacket *);
- void *priv;
- int64_t pos; ///< byte position in stream, -1 if unknown
-
- /**
- * Time difference in AVStream->time_base units from the pts of this
- * packet to the point at which the output from the decoder has converged
- * independent from the availability of previous frames. That is, the
- * frames are virtually identical no matter if decoding started from
- * the very first frame or from this keyframe.
- * Is AV_NOPTS_VALUE if unknown.
- * This field is not the display duration of the current packet.
- * This field has no meaning if the packet does not have AV_PKT_FLAG_KEY
- * set.
- *
- * The purpose of this field is to allow seeking in streams that have no
- * keyframes in the conventional sense. It corresponds to the
- * recovery point SEI in H.264 and match_time_delta in NUT. It is also
- * essential for some types of subtitle streams to ensure that all
- * subtitles are correctly displayed after seeking.
- */
- int64_t convergence_duration;
-} AVPacket;
-#define AV_PKT_FLAG_KEY 0x0001 ///< The packet contains a keyframe
-#define AV_PKT_FLAG_CORRUPT 0x0002 ///< The packet content is corrupted
-
-/**
- * An AV_PKT_DATA_PARAM_CHANGE side data packet is laid out as follows:
- * u32le param_flags
- * if (param_flags & AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_COUNT)
- * s32le channel_count
- * if (param_flags & AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_LAYOUT)
- * u64le channel_layout
- * if (param_flags & AV_SIDE_DATA_PARAM_CHANGE_SAMPLE_RATE)
- * s32le sample_rate
- * if (param_flags & AV_SIDE_DATA_PARAM_CHANGE_DIMENSIONS)
- * s32le width
- * s32le height
- */
-
-enum AVSideDataParamChangeFlags {
- AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_COUNT = 0x0001,
- AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_LAYOUT = 0x0002,
- AV_SIDE_DATA_PARAM_CHANGE_SAMPLE_RATE = 0x0004,
- AV_SIDE_DATA_PARAM_CHANGE_DIMENSIONS = 0x0008,
-};
-
-/**
- * Audio Video Frame.
- * New fields can be added to the end of AVFRAME with minor version
- * bumps. Removal, reordering and changes to existing fields require
- * a major version bump.
- * sizeof(AVFrame) must not be used outside libav*.
- */
-typedef struct AVFrame {
-#if FF_API_DATA_POINTERS
-#define AV_NUM_DATA_POINTERS 4
-#else
-#define AV_NUM_DATA_POINTERS 8
-#endif
- /**
- * pointer to the picture/channel planes.
- * This might be different from the first allocated byte
- * - encoding: Set by user
- * - decoding: set by AVCodecContext.get_buffer()
- */
- uint8_t *data[AV_NUM_DATA_POINTERS];
-
- /**
- * Size, in bytes, of the data for each picture/channel plane.
- *
- * For audio, only linesize[0] may be set. For planar audio, each channel
- * plane must be the same size.
- *
- * - encoding: Set by user (video only)
- * - decoding: set by AVCodecContext.get_buffer()
- */
- int linesize[AV_NUM_DATA_POINTERS];
-
- /**
- * pointer to the first allocated byte of the picture. Can be used in get_buffer/release_buffer.
- * This isn't used by libavcodec unless the default get/release_buffer() is used.
- * - encoding:
- * - decoding:
- */
- uint8_t *base[AV_NUM_DATA_POINTERS];
- /**
- * 1 -> keyframe, 0-> not
- * - encoding: Set by libavcodec.
- * - decoding: Set by libavcodec.
- */
- int key_frame;
-
- /**
- * Picture type of the frame, see ?_TYPE below.
- * - encoding: Set by libavcodec. for coded_picture (and set by user for input).
- * - decoding: Set by libavcodec.
- */
- enum AVPictureType pict_type;
-
- /**
- * presentation timestamp in time_base units (time when frame should be shown to user)
- * If AV_NOPTS_VALUE then frame_rate = 1/time_base will be assumed.
- * - encoding: MUST be set by user.
- * - decoding: Set by libavcodec.
- */
- int64_t pts;
-
- /**
- * picture number in bitstream order
- * - encoding: set by
- * - decoding: Set by libavcodec.
- */
- int coded_picture_number;
- /**
- * picture number in display order
- * - encoding: set by
- * - decoding: Set by libavcodec.
- */
- int display_picture_number;
-
- /**
- * quality (between 1 (good) and FF_LAMBDA_MAX (bad))
- * - encoding: Set by libavcodec. for coded_picture (and set by user for input).
- * - decoding: Set by libavcodec.
- */
- int quality;
-
-#if FF_API_AVFRAME_AGE
- /**
- * @deprecated unused
- */
- attribute_deprecated int age;
-#endif
-
- /**
- * is this picture used as reference
- * The values for this are the same as the MpegEncContext.picture_structure
- * variable, that is 1->top field, 2->bottom field, 3->frame/both fields.
- * Set to 4 for delayed, non-reference frames.
- * - encoding: unused
- * - decoding: Set by libavcodec. (before get_buffer() call)).
- */
- int reference;
-
- /**
- * QP table
- * - encoding: unused
- * - decoding: Set by libavcodec.
- */
- int8_t *qscale_table;
- /**
- * QP store stride
- * - encoding: unused
- * - decoding: Set by libavcodec.
- */
- int qstride;
-
- /**
- * mbskip_table[mb]>=1 if MB didn't change
- * stride= mb_width = (width+15)>>4
- * - encoding: unused
- * - decoding: Set by libavcodec.
- */
- uint8_t *mbskip_table;
-
- /**
- * motion vector table
- * @code
- * example:
- * int mv_sample_log2= 4 - motion_subsample_log2;
- * int mb_width= (width+15)>>4;
- * int mv_stride= (mb_width << mv_sample_log2) + 1;
- * motion_val[direction][x + y*mv_stride][0->mv_x, 1->mv_y];
- * @endcode
- * - encoding: Set by user.
- * - decoding: Set by libavcodec.
- */
- int16_t (*motion_val[2])[2];
-
- /**
- * macroblock type table
- * mb_type_base + mb_width + 2
- * - encoding: Set by user.
- * - decoding: Set by libavcodec.
- */
- uint32_t *mb_type;
-
- /**
- * log2 of the size of the block which a single vector in motion_val represents:
- * (4->16x16, 3->8x8, 2-> 4x4, 1-> 2x2)
- * - encoding: unused
- * - decoding: Set by libavcodec.
- */
- uint8_t motion_subsample_log2;
-
- /**
- * for some private data of the user
- * - encoding: unused
- * - decoding: Set by user.
- */
- void *opaque;
-
- /**
- * error
- * - encoding: Set by libavcodec. if flags&CODEC_FLAG_PSNR.
- * - decoding: unused
- */
- uint64_t error[AV_NUM_DATA_POINTERS];
-
- /**
- * type of the buffer (to keep track of who has to deallocate data[*])
- * - encoding: Set by the one who allocates it.
- * - decoding: Set by the one who allocates it.
- * Note: User allocated (direct rendering) & internal buffers cannot coexist currently.
- */
- int type;
-
- /**
- * When decoding, this signals how much the picture must be delayed.
- * extra_delay = repeat_pict / (2*fps)
- * - encoding: unused
- * - decoding: Set by libavcodec.
- */
- int repeat_pict;
-
- /**
- *
- */
- int qscale_type;
-
- /**
- * The content of the picture is interlaced.
- * - encoding: Set by user.
- * - decoding: Set by libavcodec. (default 0)
- */
- int interlaced_frame;
-
- /**
- * If the content is interlaced, is top field displayed first.
- * - encoding: Set by user.
- * - decoding: Set by libavcodec.
- */
- int top_field_first;
-
- /**
- * Pan scan.
- * - encoding: Set by user.
- * - decoding: Set by libavcodec.
- */
- AVPanScan *pan_scan;
-
- /**
- * Tell user application that palette has changed from previous frame.
- * - encoding: ??? (no palette-enabled encoder yet)
- * - decoding: Set by libavcodec. (default 0).
- */
- int palette_has_changed;
-
- /**
- * codec suggestion on buffer type if != 0
- * - encoding: unused
- * - decoding: Set by libavcodec. (before get_buffer() call)).
- */
- int buffer_hints;
-
- /**
- * DCT coefficients
- * - encoding: unused
- * - decoding: Set by libavcodec.
- */
- short *dct_coeff;
-
- /**
- * motion reference frame index
- * the order in which these are stored can depend on the codec.
- * - encoding: Set by user.
- * - decoding: Set by libavcodec.
- */
- int8_t *ref_index[2];
-
- /**
- * reordered opaque 64bit (generally an integer or a double precision float
- * PTS but can be anything).
- * The user sets AVCodecContext.reordered_opaque to represent the input at
- * that time,
- * the decoder reorders values as needed and sets AVFrame.reordered_opaque
- * to exactly one of the values provided by the user through AVCodecContext.reordered_opaque
- * @deprecated in favor of pkt_pts
- * - encoding: unused
- * - decoding: Read by user.
- */
- int64_t reordered_opaque;
-
- /**
- * hardware accelerator private data (Libav-allocated)
- * - encoding: unused
- * - decoding: Set by libavcodec
- */
- void *hwaccel_picture_private;
-
- /**
- * reordered pts from the last AVPacket that has been input into the decoder
- * - encoding: unused
- * - decoding: Read by user.
- */
- int64_t pkt_pts;
-
- /**
- * dts from the last AVPacket that has been input into the decoder
- * - encoding: unused
- * - decoding: Read by user.
- */
- int64_t pkt_dts;
-
- /**
- * the AVCodecContext which ff_thread_get_buffer() was last called on
- * - encoding: Set by libavcodec.
- * - decoding: Set by libavcodec.
- */
- struct AVCodecContext *owner;
-
- /**
- * used by multithreading to store frame-specific info
- * - encoding: Set by libavcodec.
- * - decoding: Set by libavcodec.
- */
- void *thread_opaque;
-
- /**
- * number of audio samples (per channel) described by this frame
- * - encoding: unused
- * - decoding: Set by libavcodec
- */
- int nb_samples;
-
- /**
- * pointers to the data planes/channels.
- *
- * For video, this should simply point to data[].
- *
- * For planar audio, each channel has a separate data pointer, and
- * linesize[0] contains the size of each channel buffer.
- * For packed audio, there is just one data pointer, and linesize[0]
- * contains the total size of the buffer for all channels.
- *
- * Note: Both data and extended_data will always be set by get_buffer(),
- * but for planar audio with more channels that can fit in data,
- * extended_data must be used by the decoder in order to access all
- * channels.
- *
- * encoding: unused
- * decoding: set by AVCodecContext.get_buffer()
- */
- uint8_t **extended_data;
-
- /**
- * sample aspect ratio for the video frame, 0/1 if unknown\unspecified
- * - encoding: unused
- * - decoding: Read by user.
- */
- AVRational sample_aspect_ratio;
-
- /**
- * width and height of the video frame
- * - encoding: unused
- * - decoding: Read by user.
- */
- int width, height;
-
- /**
- * format of the frame, -1 if unknown or unset
- * Values correspond to enum PixelFormat for video frames,
- * enum AVSampleFormat for audio)
- * - encoding: unused
- * - decoding: Read by user.
- */
- int format;
-} AVFrame;
-
-struct AVCodecInternal;
-
-enum AVFieldOrder {
- AV_FIELD_UNKNOWN,
- AV_FIELD_PROGRESSIVE,
- AV_FIELD_TT, //< Top coded_first, top displayed first
- AV_FIELD_BB, //< Bottom coded first, bottom displayed first
- AV_FIELD_TB, //< Top coded first, bottom displayed first
- AV_FIELD_BT, //< Bottom coded first, top displayed first
-};
-
-/**
- * main external API structure.
- * New fields can be added to the end with minor version bumps.
- * Removal, reordering and changes to existing fields require a major
- * version bump.
- * sizeof(AVCodecContext) must not be used outside libav*.
- */
-typedef struct AVCodecContext {
- /**
- * information on struct for av_log
- * - set by avcodec_alloc_context3
- */
- const AVClass *av_class;
- /**
- * the average bitrate
- * - encoding: Set by user; unused for constant quantizer encoding.
- * - decoding: Set by libavcodec. 0 or some bitrate if this info is available in the stream.
- */
- int bit_rate;
-
- /**
- * number of bits the bitstream is allowed to diverge from the reference.
- * the reference can be CBR (for CBR pass1) or VBR (for pass2)
- * - encoding: Set by user; unused for constant quantizer encoding.
- * - decoding: unused
- */
- int bit_rate_tolerance;
-
- /**
- * CODEC_FLAG_*.
- * - encoding: Set by user.
- * - decoding: Set by user.
- */
- int flags;
-
- /**
- * Some codecs need additional format info. It is stored here.
- * If any muxer uses this then ALL demuxers/parsers AND encoders for the
- * specific codec MUST set it correctly otherwise stream copy breaks.
- * In general use of this field by muxers is not recommended.
- * - encoding: Set by libavcodec.
- * - decoding: Set by libavcodec. (FIXME: Is this OK?)
- */
- int sub_id;
-
- /**
- * Motion estimation algorithm used for video coding.
- * 1 (zero), 2 (full), 3 (log), 4 (phods), 5 (epzs), 6 (x1), 7 (hex),
- * 8 (umh), 9 (iter), 10 (tesa) [7, 8, 10 are x264 specific, 9 is snow specific]
- * - encoding: MUST be set by user.
- * - decoding: unused
- */
- int me_method;
-
- /**
- * some codecs need / can use extradata like Huffman tables.
- * mjpeg: Huffman tables
- * rv10: additional flags
- * mpeg4: global headers (they can be in the bitstream or here)
- * The allocated memory should be FF_INPUT_BUFFER_PADDING_SIZE bytes larger
- * than extradata_size to avoid prolems if it is read with the bitstream reader.
- * The bytewise contents of extradata must not depend on the architecture or CPU endianness.
- * - encoding: Set/allocated/freed by libavcodec.
- * - decoding: Set/allocated/freed by user.
- */
- uint8_t *extradata;
- int extradata_size;
-
- /**
- * This is the fundamental unit of time (in seconds) in terms
- * of which frame timestamps are represented. For fixed-fps content,
- * timebase should be 1/framerate and timestamp increments should be
- * identically 1.
- * - encoding: MUST be set by user.
- * - decoding: Set by libavcodec.
- */
- AVRational time_base;
-
- /* video only */
- /**
- * picture width / height.
- * - encoding: MUST be set by user.
- * - decoding: Set by libavcodec.
- * Note: For compatibility it is possible to set this instead of
- * coded_width/height before decoding.
- */
- int width, height;
-
-#define FF_ASPECT_EXTENDED 15
-
- /**
- * the number of pictures in a group of pictures, or 0 for intra_only
- * - encoding: Set by user.
- * - decoding: unused
- */
- int gop_size;
-
- /**
- * Pixel format, see PIX_FMT_xxx.
- * May be set by the demuxer if known from headers.
- * May be overriden by the decoder if it knows better.
- * - encoding: Set by user.
- * - decoding: Set by user if known, overridden by libavcodec if known
- */
- enum PixelFormat pix_fmt;
-
- /**
- * If non NULL, 'draw_horiz_band' is called by the libavcodec
- * decoder to draw a horizontal band. It improves cache usage. Not
- * all codecs can do that. You must check the codec capabilities
- * beforehand.
- * When multithreading is used, it may be called from multiple threads
- * at the same time; threads might draw different parts of the same AVFrame,
- * or multiple AVFrames, and there is no guarantee that slices will be drawn
- * in order.
- * The function is also used by hardware acceleration APIs.
- * It is called at least once during frame decoding to pass
- * the data needed for hardware render.
- * In that mode instead of pixel data, AVFrame points to
- * a structure specific to the acceleration API. The application
- * reads the structure and can change some fields to indicate progress
- * or mark state.
- * - encoding: unused
- * - decoding: Set by user.
- * @param height the height of the slice
- * @param y the y position of the slice
- * @param type 1->top field, 2->bottom field, 3->frame
- * @param offset offset into the AVFrame.data from which the slice should be read
- */
- void (*draw_horiz_band)(struct AVCodecContext *s,
- const AVFrame *src, int offset[AV_NUM_DATA_POINTERS],
- int y, int type, int height);
-
- /* audio only */
- int sample_rate; ///< samples per second
- int channels; ///< number of audio channels
-
- /**
- * audio sample format
- * - encoding: Set by user.
- * - decoding: Set by libavcodec.
- */
- enum AVSampleFormat sample_fmt; ///< sample format
-
- /* The following data should not be initialized. */
- /**
- * Samples per packet, initialized when calling 'init'.
- */
- int frame_size;
- int frame_number; ///< audio or video frame number
-
- /**
- * Number of frames the decoded output will be delayed relative to
- * the encoded input.
- * - encoding: Set by libavcodec.
- * - decoding: unused
- */
- int delay;
-
- /* - encoding parameters */
- float qcompress; ///< amount of qscale change between easy & hard scenes (0.0-1.0)
- float qblur; ///< amount of qscale smoothing over time (0.0-1.0)
-
- /**
- * minimum quantizer
- * - encoding: Set by user.
- * - decoding: unused
- */
- int qmin;
-
- /**
- * maximum quantizer
- * - encoding: Set by user.
- * - decoding: unused
- */
- int qmax;
-
- /**
- * maximum quantizer difference between frames
- * - encoding: Set by user.
- * - decoding: unused
- */
- int max_qdiff;
-
- /**
- * maximum number of B-frames between non-B-frames
- * Note: The output will be delayed by max_b_frames+1 relative to the input.
- * - encoding: Set by user.
- * - decoding: unused
- */
- int max_b_frames;
-
- /**
- * qscale factor between IP and B-frames
- * If > 0 then the last P-frame quantizer will be used (q= lastp_q*factor+offset).
- * If < 0 then normal ratecontrol will be done (q= -normal_q*factor+offset).
- * - encoding: Set by user.
- * - decoding: unused
- */
- float b_quant_factor;
-
- /** obsolete FIXME remove */
- int rc_strategy;
-#define FF_RC_STRATEGY_XVID 1
-
- int b_frame_strategy;
-
- struct AVCodec *codec;
-
- void *priv_data;
-
- int rtp_payload_size; /* The size of the RTP payload: the coder will */
- /* do its best to deliver a chunk with size */
- /* below rtp_payload_size, the chunk will start */
- /* with a start code on some codecs like H.263. */
- /* This doesn't take account of any particular */
- /* headers inside the transmitted RTP payload. */
-
-
- /* The RTP callback: This function is called */
- /* every time the encoder has a packet to send. */
- /* It depends on the encoder if the data starts */
- /* with a Start Code (it should). H.263 does. */
- /* mb_nb contains the number of macroblocks */
- /* encoded in the RTP payload. */
- void (*rtp_callback)(struct AVCodecContext *avctx, void *data, int size, int mb_nb);
-
- /* statistics, used for 2-pass encoding */
- int mv_bits;
- int header_bits;
- int i_tex_bits;
- int p_tex_bits;
- int i_count;
- int p_count;
- int skip_count;
- int misc_bits;
-
- /**
- * number of bits used for the previously encoded frame
- * - encoding: Set by libavcodec.
- * - decoding: unused
- */
- int frame_bits;
-
- /**
- * Private data of the user, can be used to carry app specific stuff.
- * - encoding: Set by user.
- * - decoding: Set by user.
- */
- void *opaque;
-
- char codec_name[32];
- enum AVMediaType codec_type; /* see AVMEDIA_TYPE_xxx */
- enum CodecID codec_id; /* see CODEC_ID_xxx */
-
- /**
- * fourcc (LSB first, so "ABCD" -> ('D'<<24) + ('C'<<16) + ('B'<<8) + 'A').
- * This is used to work around some encoder bugs.
- * A demuxer should set this to what is stored in the field used to identify the codec.
- * If there are multiple such fields in a container then the demuxer should choose the one
- * which maximizes the information about the used codec.
- * If the codec tag field in a container is larger than 32 bits then the demuxer should
- * remap the longer ID to 32 bits with a table or other structure. Alternatively a new
- * extra_codec_tag + size could be added but for this a clear advantage must be demonstrated
- * first.
- * - encoding: Set by user, if not then the default based on codec_id will be used.
- * - decoding: Set by user, will be converted to uppercase by libavcodec during init.
- */
- unsigned int codec_tag;
-
- /**
- * Work around bugs in encoders which sometimes cannot be detected automatically.
- * - encoding: Set by user
- * - decoding: Set by user
- */
- int workaround_bugs;
-#define FF_BUG_AUTODETECT 1 ///< autodetection
-#define FF_BUG_OLD_MSMPEG4 2
-#define FF_BUG_XVID_ILACE 4
-#define FF_BUG_UMP4 8
-#define FF_BUG_NO_PADDING 16
-#define FF_BUG_AMV 32
-#define FF_BUG_AC_VLC 0 ///< Will be removed, libavcodec can now handle these non-compliant files by default.
-#define FF_BUG_QPEL_CHROMA 64
-#define FF_BUG_STD_QPEL 128
-#define FF_BUG_QPEL_CHROMA2 256
-#define FF_BUG_DIRECT_BLOCKSIZE 512
-#define FF_BUG_EDGE 1024
-#define FF_BUG_HPEL_CHROMA 2048
-#define FF_BUG_DC_CLIP 4096
-#define FF_BUG_MS 8192 ///< Work around various bugs in Microsoft's broken decoders.
-#define FF_BUG_TRUNCATED 16384
-//#define FF_BUG_FAKE_SCALABILITY 16 //Autodetection should work 100%.
-
- /**
- * luma single coefficient elimination threshold
- * - encoding: Set by user.
- * - decoding: unused
- */
- int luma_elim_threshold;
-
- /**
- * chroma single coeff elimination threshold
- * - encoding: Set by user.
- * - decoding: unused
- */
- int chroma_elim_threshold;
-
- /**
- * strictly follow the standard (MPEG4, ...).
- * - encoding: Set by user.
- * - decoding: Set by user.
- * Setting this to STRICT or higher means the encoder and decoder will
- * generally do stupid things, whereas setting it to unofficial or lower
- * will mean the encoder might produce output that is not supported by all
- * spec-compliant decoders. Decoders don't differentiate between normal,
- * unofficial and experimental (that is, they always try to decode things
- * when they can) unless they are explicitly asked to behave stupidly
- * (=strictly conform to the specs)
- */
- int strict_std_compliance;
-#define FF_COMPLIANCE_VERY_STRICT 2 ///< Strictly conform to an older more strict version of the spec or reference software.
-#define FF_COMPLIANCE_STRICT 1 ///< Strictly conform to all the things in the spec no matter what consequences.
-#define FF_COMPLIANCE_NORMAL 0
-#define FF_COMPLIANCE_UNOFFICIAL -1 ///< Allow unofficial extensions
-#define FF_COMPLIANCE_EXPERIMENTAL -2 ///< Allow nonstandardized experimental things.
-
- /**
- * qscale offset between IP and B-frames
- * - encoding: Set by user.
- * - decoding: unused
- */
- float b_quant_offset;
-
-#if FF_API_ER
- /**
- * Error recognition; higher values will detect more errors but may
- * misdetect some more or less valid parts as errors.
- * - encoding: unused
- * - decoding: Set by user.
- */
- attribute_deprecated int error_recognition;
-#define FF_ER_CAREFUL 1
-#define FF_ER_COMPLIANT 2
-#define FF_ER_AGGRESSIVE 3
-#define FF_ER_VERY_AGGRESSIVE 4
-#define FF_ER_EXPLODE 5
-#endif /* FF_API_ER */
-
- /**
- * Called at the beginning of each frame to get a buffer for it.
- *
- * The function will set AVFrame.data[], AVFrame.linesize[].
- * AVFrame.extended_data[] must also be set, but it should be the same as
- * AVFrame.data[] except for planar audio with more channels than can fit
- * in AVFrame.data[]. In that case, AVFrame.data[] shall still contain as
- * many data pointers as it can hold.
- *
- * if CODEC_CAP_DR1 is not set then get_buffer() must call
- * avcodec_default_get_buffer() instead of providing buffers allocated by
- * some other means.
- *
- * AVFrame.data[] should be 32- or 16-byte-aligned unless the CPU doesn't
- * need it. avcodec_default_get_buffer() aligns the output buffer properly,
- * but if get_buffer() is overridden then alignment considerations should
- * be taken into account.
- *
- * @see avcodec_default_get_buffer()
- *
- * Video:
- *
- * If pic.reference is set then the frame will be read later by libavcodec.
- * avcodec_align_dimensions2() should be used to find the required width and
- * height, as they normally need to be rounded up to the next multiple of 16.
- *
- * If frame multithreading is used and thread_safe_callbacks is set,
- * it may be called from a different thread, but not from more than one at
- * once. Does not need to be reentrant.
- *
- * @see release_buffer(), reget_buffer()
- * @see avcodec_align_dimensions2()
- *
- * Audio:
- *
- * Decoders request a buffer of a particular size by setting
- * AVFrame.nb_samples prior to calling get_buffer(). The decoder may,
- * however, utilize only part of the buffer by setting AVFrame.nb_samples
- * to a smaller value in the output frame.
- *
- * Decoders cannot use the buffer after returning from
- * avcodec_decode_audio4(), so they will not call release_buffer(), as it
- * is assumed to be released immediately upon return.
- *
- * As a convenience, av_samples_get_buffer_size() and
- * av_samples_fill_arrays() in libavutil may be used by custom get_buffer()
- * functions to find the required data size and to fill data pointers and
- * linesize. In AVFrame.linesize, only linesize[0] may be set for audio
- * since all planes must be the same size.
- *
- * @see av_samples_get_buffer_size(), av_samples_fill_arrays()
- *
- * - encoding: unused
- * - decoding: Set by libavcodec, user can override.
- */
- int (*get_buffer)(struct AVCodecContext *c, AVFrame *pic);
-
- /**
- * Called to release buffers which were allocated with get_buffer.
- * A released buffer can be reused in get_buffer().
- * pic.data[*] must be set to NULL.
- * May be called from a different thread if frame multithreading is used,
- * but not by more than one thread at once, so does not need to be reentrant.
- * - encoding: unused
- * - decoding: Set by libavcodec, user can override.
- */
- void (*release_buffer)(struct AVCodecContext *c, AVFrame *pic);
-
- /**
- * Size of the frame reordering buffer in the decoder.
- * For MPEG-2 it is 1 IPB or 0 low delay IP.
- * - encoding: Set by libavcodec.
- * - decoding: Set by libavcodec.
- */
- int has_b_frames;
-
- /**
- * number of bytes per packet if constant and known or 0
- * Used by some WAV based audio codecs.
- */
- int block_align;
-
-#if FF_API_PARSE_FRAME
- /**
- * If true, only parsing is done. The frame data is returned.
- * Only MPEG audio decoders support this now.
- * - encoding: unused
- * - decoding: Set by user
- */
- attribute_deprecated int parse_only;
-#endif
-
- /**
- * 0-> h263 quant 1-> mpeg quant
- * - encoding: Set by user.
- * - decoding: unused
- */
- int mpeg_quant;
-
- /**
- * pass1 encoding statistics output buffer
- * - encoding: Set by libavcodec.
- * - decoding: unused
- */
- char *stats_out;
-
- /**
- * pass2 encoding statistics input buffer
- * Concatenated stuff from stats_out of pass1 should be placed here.
- * - encoding: Allocated/set/freed by user.
- * - decoding: unused
- */
- char *stats_in;
-
- /**
- * ratecontrol qmin qmax limiting method
- * 0-> clipping, 1-> use a nice continous function to limit qscale wthin qmin/qmax.
- * - encoding: Set by user.
- * - decoding: unused
- */
- float rc_qsquish;
-
- float rc_qmod_amp;
- int rc_qmod_freq;
-
- /**
- * ratecontrol override, see RcOverride
- * - encoding: Allocated/set/freed by user.
- * - decoding: unused
- */
- RcOverride *rc_override;
- int rc_override_count;
-
- /**
- * rate control equation
- * - encoding: Set by user
- * - decoding: unused
- */
- const char *rc_eq;
-
- /**
- * maximum bitrate
- * - encoding: Set by user.
- * - decoding: unused
- */
- int rc_max_rate;
-
- /**
- * minimum bitrate
- * - encoding: Set by user.
- * - decoding: unused
- */
- int rc_min_rate;
-
- /**
- * decoder bitstream buffer size
- * - encoding: Set by user.
- * - decoding: unused
- */
- int rc_buffer_size;
- float rc_buffer_aggressivity;
-
- /**
- * qscale factor between P and I-frames
- * If > 0 then the last p frame quantizer will be used (q= lastp_q*factor+offset).
- * If < 0 then normal ratecontrol will be done (q= -normal_q*factor+offset).
- * - encoding: Set by user.
- * - decoding: unused
- */
- float i_quant_factor;
-
- /**
- * qscale offset between P and I-frames
- * - encoding: Set by user.
- * - decoding: unused
- */
- float i_quant_offset;
-
- /**
- * initial complexity for pass1 ratecontrol
- * - encoding: Set by user.
- * - decoding: unused
- */
- float rc_initial_cplx;
-
- /**
- * DCT algorithm, see FF_DCT_* below
- * - encoding: Set by user.
- * - decoding: unused
- */
- int dct_algo;
-#define FF_DCT_AUTO 0
-#define FF_DCT_FASTINT 1
-#define FF_DCT_INT 2
-#define FF_DCT_MMX 3
-#define FF_DCT_MLIB 4
-#define FF_DCT_ALTIVEC 5
-#define FF_DCT_FAAN 6
-
- /**
- * luminance masking (0-> disabled)
- * - encoding: Set by user.
- * - decoding: unused
- */
- float lumi_masking;
-
- /**
- * temporary complexity masking (0-> disabled)
- * - encoding: Set by user.
- * - decoding: unused
- */
- float temporal_cplx_masking;
-
- /**
- * spatial complexity masking (0-> disabled)
- * - encoding: Set by user.
- * - decoding: unused
- */
- float spatial_cplx_masking;
-
- /**
- * p block masking (0-> disabled)
- * - encoding: Set by user.
- * - decoding: unused
- */
- float p_masking;
-
- /**
- * darkness masking (0-> disabled)
- * - encoding: Set by user.
- * - decoding: unused
- */
- float dark_masking;
-
- /**
- * IDCT algorithm, see FF_IDCT_* below.
- * - encoding: Set by user.
- * - decoding: Set by user.
- */
- int idct_algo;
-#define FF_IDCT_AUTO 0
-#define FF_IDCT_INT 1
-#define FF_IDCT_SIMPLE 2
-#define FF_IDCT_SIMPLEMMX 3
-#define FF_IDCT_LIBMPEG2MMX 4
-#define FF_IDCT_PS2 5
-#define FF_IDCT_MLIB 6
-#define FF_IDCT_ARM 7
-#define FF_IDCT_ALTIVEC 8
-#define FF_IDCT_SH4 9
-#define FF_IDCT_SIMPLEARM 10
-#define FF_IDCT_H264 11
-#define FF_IDCT_VP3 12
-#define FF_IDCT_IPP 13
-#define FF_IDCT_XVIDMMX 14
-#define FF_IDCT_CAVS 15
-#define FF_IDCT_SIMPLEARMV5TE 16
-#define FF_IDCT_SIMPLEARMV6 17
-#define FF_IDCT_SIMPLEVIS 18
-#define FF_IDCT_WMV2 19
-#define FF_IDCT_FAAN 20
-#define FF_IDCT_EA 21
-#define FF_IDCT_SIMPLENEON 22
-#define FF_IDCT_SIMPLEALPHA 23
-#define FF_IDCT_BINK 24
-
- /**
- * slice count
- * - encoding: Set by libavcodec.
- * - decoding: Set by user (or 0).
- */
- int slice_count;
- /**
- * slice offsets in the frame in bytes
- * - encoding: Set/allocated by libavcodec.
- * - decoding: Set/allocated by user (or NULL).
- */
- int *slice_offset;
-
- /**
- * error concealment flags
- * - encoding: unused
- * - decoding: Set by user.
- */
- int error_concealment;
-#define FF_EC_GUESS_MVS 1
-#define FF_EC_DEBLOCK 2
-
- /**
- * dsp_mask could be add used to disable unwanted CPU features
- * CPU features (i.e. MMX, SSE. ...)
- *
- * With the FORCE flag you may instead enable given CPU features.
- * (Dangerous: Usable in case of misdetection, improper usage however will
- * result into program crash.)
- */
- unsigned dsp_mask;
-
- /**
- * bits per sample/pixel from the demuxer (needed for huffyuv).
- * - encoding: Set by libavcodec.
- * - decoding: Set by user.
- */
- int bits_per_coded_sample;
-
- /**
- * prediction method (needed for huffyuv)
- * - encoding: Set by user.
- * - decoding: unused
- */
- int prediction_method;
-#define FF_PRED_LEFT 0
-#define FF_PRED_PLANE 1
-#define FF_PRED_MEDIAN 2
-
- /**
- * sample aspect ratio (0 if unknown)
- * That is the width of a pixel divided by the height of the pixel.
- * Numerator and denominator must be relatively prime and smaller than 256 for some video standards.
- * - encoding: Set by user.
- * - decoding: Set by libavcodec.
- */
- AVRational sample_aspect_ratio;
-
- /**
- * the picture in the bitstream
- * - encoding: Set by libavcodec.
- * - decoding: Set by libavcodec.
- */
- AVFrame *coded_frame;
-
- /**
- * debug
- * - encoding: Set by user.
- * - decoding: Set by user.
- */
- int debug;
-#define FF_DEBUG_PICT_INFO 1
-#define FF_DEBUG_RC 2
-#define FF_DEBUG_BITSTREAM 4
-#define FF_DEBUG_MB_TYPE 8
-#define FF_DEBUG_QP 16
-#define FF_DEBUG_MV 32
-#define FF_DEBUG_DCT_COEFF 0x00000040
-#define FF_DEBUG_SKIP 0x00000080
-#define FF_DEBUG_STARTCODE 0x00000100
-#define FF_DEBUG_PTS 0x00000200
-#define FF_DEBUG_ER 0x00000400
-#define FF_DEBUG_MMCO 0x00000800
-#define FF_DEBUG_BUGS 0x00001000
-#define FF_DEBUG_VIS_QP 0x00002000
-#define FF_DEBUG_VIS_MB_TYPE 0x00004000
-#define FF_DEBUG_BUFFERS 0x00008000
-#define FF_DEBUG_THREADS 0x00010000
-
- /**
- * debug
- * - encoding: Set by user.
- * - decoding: Set by user.
- */
- int debug_mv;
-#define FF_DEBUG_VIS_MV_P_FOR 0x00000001 //visualize forward predicted MVs of P frames
-#define FF_DEBUG_VIS_MV_B_FOR 0x00000002 //visualize forward predicted MVs of B frames
-#define FF_DEBUG_VIS_MV_B_BACK 0x00000004 //visualize backward predicted MVs of B frames
-
- /**
- * error
- * - encoding: Set by libavcodec if flags&CODEC_FLAG_PSNR.
- * - decoding: unused
- */
- uint64_t error[AV_NUM_DATA_POINTERS];
-
- /**
- * motion estimation comparison function
- * - encoding: Set by user.
- * - decoding: unused
- */
- int me_cmp;
- /**
- * subpixel motion estimation comparison function
- * - encoding: Set by user.
- * - decoding: unused
- */
- int me_sub_cmp;
- /**
- * macroblock comparison function (not supported yet)
- * - encoding: Set by user.
- * - decoding: unused
- */
- int mb_cmp;
- /**
- * interlaced DCT comparison function
- * - encoding: Set by user.
- * - decoding: unused
- */
- int ildct_cmp;
-#define FF_CMP_SAD 0
-#define FF_CMP_SSE 1
-#define FF_CMP_SATD 2
-#define FF_CMP_DCT 3
-#define FF_CMP_PSNR 4
-#define FF_CMP_BIT 5
-#define FF_CMP_RD 6
-#define FF_CMP_ZERO 7
-#define FF_CMP_VSAD 8
-#define FF_CMP_VSSE 9
-#define FF_CMP_NSSE 10
-#define FF_CMP_W53 11
-#define FF_CMP_W97 12
-#define FF_CMP_DCTMAX 13
-#define FF_CMP_DCT264 14
-#define FF_CMP_CHROMA 256
-
- /**
- * ME diamond size & shape
- * - encoding: Set by user.
- * - decoding: unused
- */
- int dia_size;
-
- /**
- * amount of previous MV predictors (2a+1 x 2a+1 square)
- * - encoding: Set by user.
- * - decoding: unused
- */
- int last_predictor_count;
-
- /**
- * prepass for motion estimation
- * - encoding: Set by user.
- * - decoding: unused
- */
- int pre_me;
-
- /**
- * motion estimation prepass comparison function
- * - encoding: Set by user.
- * - decoding: unused
- */
- int me_pre_cmp;
-
- /**
- * ME prepass diamond size & shape
- * - encoding: Set by user.
- * - decoding: unused
- */
- int pre_dia_size;
-
- /**
- * subpel ME quality
- * - encoding: Set by user.
- * - decoding: unused
- */
- int me_subpel_quality;
-
- /**
- * callback to negotiate the pixelFormat
- * @param fmt is the list of formats which are supported by the codec,
- * it is terminated by -1 as 0 is a valid format, the formats are ordered by quality.
- * The first is always the native one.
- * @return the chosen format
- * - encoding: unused
- * - decoding: Set by user, if not set the native format will be chosen.
- */
- enum PixelFormat (*get_format)(struct AVCodecContext *s, const enum PixelFormat * fmt);
-
- /**
- * DTG active format information (additional aspect ratio
- * information only used in DVB MPEG-2 transport streams)
- * 0 if not set.
- *
- * - encoding: unused
- * - decoding: Set by decoder.
- */
- int dtg_active_format;
-#define FF_DTG_AFD_SAME 8
-#define FF_DTG_AFD_4_3 9
-#define FF_DTG_AFD_16_9 10
-#define FF_DTG_AFD_14_9 11
-#define FF_DTG_AFD_4_3_SP_14_9 13
-#define FF_DTG_AFD_16_9_SP_14_9 14
-#define FF_DTG_AFD_SP_4_3 15
-
- /**
- * maximum motion estimation search range in subpel units
- * If 0 then no limit.
- *
- * - encoding: Set by user.
- * - decoding: unused
- */
- int me_range;
-
- /**
- * intra quantizer bias
- * - encoding: Set by user.
- * - decoding: unused
- */
- int intra_quant_bias;
-#define FF_DEFAULT_QUANT_BIAS 999999
-
- /**
- * inter quantizer bias
- * - encoding: Set by user.
- * - decoding: unused
- */
- int inter_quant_bias;
-
- /**
- * color table ID
- * - encoding: unused
- * - decoding: Which clrtable should be used for 8bit RGB images.
- * Tables have to be stored somewhere. FIXME
- */
- int color_table_id;
-
-#if FF_API_INTERNAL_CONTEXT
- /**
- * internal_buffer count
- * Don't touch, used by libavcodec default_get_buffer().
- * @deprecated this field was moved to an internal context
- */
- attribute_deprecated int internal_buffer_count;
-
- /**
- * internal_buffers
- * Don't touch, used by libavcodec default_get_buffer().
- * @deprecated this field was moved to an internal context
- */
- attribute_deprecated void *internal_buffer;
-#endif
-
- /**
- * Global quality for codecs which cannot change it per frame.
- * This should be proportional to MPEG-1/2/4 qscale.
- * - encoding: Set by user.
- * - decoding: unused
- */
- int global_quality;
-
-#define FF_CODER_TYPE_VLC 0
-#define FF_CODER_TYPE_AC 1
-#define FF_CODER_TYPE_RAW 2
-#define FF_CODER_TYPE_RLE 3
-#define FF_CODER_TYPE_DEFLATE 4
- /**
- * coder type
- * - encoding: Set by user.
- * - decoding: unused
- */
- int coder_type;
-
- /**
- * context model
- * - encoding: Set by user.
- * - decoding: unused
- */
- int context_model;
-#if 0
- /**
- *
- * - encoding: unused
- * - decoding: Set by user.
- */
- uint8_t * (*realloc)(struct AVCodecContext *s, uint8_t *buf, int buf_size);
-#endif
-
- /**
- * slice flags
- * - encoding: unused
- * - decoding: Set by user.
- */
- int slice_flags;
-#define SLICE_FLAG_CODED_ORDER 0x0001 ///< draw_horiz_band() is called in coded order instead of display
-#define SLICE_FLAG_ALLOW_FIELD 0x0002 ///< allow draw_horiz_band() with field slices (MPEG2 field pics)
-#define SLICE_FLAG_ALLOW_PLANE 0x0004 ///< allow draw_horiz_band() with 1 component at a time (SVQ1)
-
- /**
- * XVideo Motion Acceleration
- * - encoding: forbidden
- * - decoding: set by decoder
- */
- int xvmc_acceleration;
-
- /**
- * macroblock decision mode
- * - encoding: Set by user.
- * - decoding: unused
- */
- int mb_decision;
-#define FF_MB_DECISION_SIMPLE 0 ///< uses mb_cmp
-#define FF_MB_DECISION_BITS 1 ///< chooses the one which needs the fewest bits
-#define FF_MB_DECISION_RD 2 ///< rate distortion
-
- /**
- * custom intra quantization matrix
- * - encoding: Set by user, can be NULL.
- * - decoding: Set by libavcodec.
- */
- uint16_t *intra_matrix;
-
- /**
- * custom inter quantization matrix
- * - encoding: Set by user, can be NULL.
- * - decoding: Set by libavcodec.
- */
- uint16_t *inter_matrix;
-
- /**
- * fourcc from the AVI stream header (LSB first, so "ABCD" -> ('D'<<24) + ('C'<<16) + ('B'<<8) + 'A').
- * This is used to work around some encoder bugs.
- * - encoding: unused
- * - decoding: Set by user, will be converted to uppercase by libavcodec during init.
- */
- unsigned int stream_codec_tag;
-
- /**
- * scene change detection threshold
- * 0 is default, larger means fewer detected scene changes.
- * - encoding: Set by user.
- * - decoding: unused
- */
- int scenechange_threshold;
-
- /**
- * minimum Lagrange multipler
- * - encoding: Set by user.
- * - decoding: unused
- */
- int lmin;
-
- /**
- * maximum Lagrange multipler
- * - encoding: Set by user.
- * - decoding: unused
- */
- int lmax;
-
-#if FF_API_PALETTE_CONTROL
- /**
- * palette control structure
- * - encoding: ??? (no palette-enabled encoder yet)
- * - decoding: Set by user.
- */
- struct AVPaletteControl *palctrl;
-#endif
-
- /**
- * noise reduction strength
- * - encoding: Set by user.
- * - decoding: unused
- */
- int noise_reduction;
-
- /**
- * Called at the beginning of a frame to get cr buffer for it.
- * Buffer type (size, hints) must be the same. libavcodec won't check it.
- * libavcodec will pass previous buffer in pic, function should return
- * same buffer or new buffer with old frame "painted" into it.
- * If pic.data[0] == NULL must behave like get_buffer().
- * if CODEC_CAP_DR1 is not set then reget_buffer() must call
- * avcodec_default_reget_buffer() instead of providing buffers allocated by
- * some other means.
- * - encoding: unused
- * - decoding: Set by libavcodec, user can override.
- */
- int (*reget_buffer)(struct AVCodecContext *c, AVFrame *pic);
-
- /**
- * Number of bits which should be loaded into the rc buffer before decoding starts.
- * - encoding: Set by user.
- * - decoding: unused
- */
- int rc_initial_buffer_occupancy;
-
- /**
- *
- * - encoding: Set by user.
- * - decoding: unused
- */
- int inter_threshold;
-
- /**
- * CODEC_FLAG2_*
- * - encoding: Set by user.
- * - decoding: Set by user.
- */
- int flags2;
-
- /**
- * Simulates errors in the bitstream to test error concealment.
- * - encoding: Set by user.
- * - decoding: unused
- */
- int error_rate;
-
-#if FF_API_ANTIALIAS_ALGO
- /**
- * MP3 antialias algorithm, see FF_AA_* below.
- * - encoding: unused
- * - decoding: Set by user.
- */
- attribute_deprecated int antialias_algo;
-#define FF_AA_AUTO 0
-#define FF_AA_FASTINT 1 //not implemented yet
-#define FF_AA_INT 2
-#define FF_AA_FLOAT 3
-#endif
-
- /**
- * quantizer noise shaping
- * - encoding: Set by user.
- * - decoding: unused
- */
- int quantizer_noise_shaping;
-
- /**
- * thread count
- * is used to decide how many independent tasks should be passed to execute()
- * - encoding: Set by user.
- * - decoding: Set by user.
- */
- int thread_count;
-
- /**
- * The codec may call this to execute several independent things.
- * It will return only after finishing all tasks.
- * The user may replace this with some multithreaded implementation,
- * the default implementation will execute the parts serially.
- * @param count the number of things to execute
- * - encoding: Set by libavcodec, user can override.
- * - decoding: Set by libavcodec, user can override.
- */
- int (*execute)(struct AVCodecContext *c, int (*func)(struct AVCodecContext *c2, void *arg), void *arg2, int *ret, int count, int size);
-
- /**
- * thread opaque
- * Can be used by execute() to store some per AVCodecContext stuff.
- * - encoding: set by execute()
- * - decoding: set by execute()
- */
- void *thread_opaque;
-
- /**
- * Motion estimation threshold below which no motion estimation is
- * performed, but instead the user specified motion vectors are used.
- *
- * - encoding: Set by user.
- * - decoding: unused
- */
- int me_threshold;
-
- /**
- * Macroblock threshold below which the user specified macroblock types will be used.
- * - encoding: Set by user.
- * - decoding: unused
- */
- int mb_threshold;
-
- /**
- * precision of the intra DC coefficient - 8
- * - encoding: Set by user.
- * - decoding: unused
- */
- int intra_dc_precision;
-
- /**
- * noise vs. sse weight for the nsse comparsion function
- * - encoding: Set by user.
- * - decoding: unused
- */
- int nsse_weight;
-
- /**
- * Number of macroblock rows at the top which are skipped.
- * - encoding: unused
- * - decoding: Set by user.
- */
- int skip_top;
-
- /**
- * Number of macroblock rows at the bottom which are skipped.
- * - encoding: unused
- * - decoding: Set by user.
- */
- int skip_bottom;
-
- /**
- * profile
- * - encoding: Set by user.
- * - decoding: Set by libavcodec.
- */
- int profile;
-#define FF_PROFILE_UNKNOWN -99
-#define FF_PROFILE_RESERVED -100
-
-#define FF_PROFILE_AAC_MAIN 0
-#define FF_PROFILE_AAC_LOW 1
-#define FF_PROFILE_AAC_SSR 2
-#define FF_PROFILE_AAC_LTP 3
-
-#define FF_PROFILE_DTS 20
-#define FF_PROFILE_DTS_ES 30
-#define FF_PROFILE_DTS_96_24 40
-#define FF_PROFILE_DTS_HD_HRA 50
-#define FF_PROFILE_DTS_HD_MA 60
-
-#define FF_PROFILE_MPEG2_422 0
-#define FF_PROFILE_MPEG2_HIGH 1
-#define FF_PROFILE_MPEG2_SS 2
-#define FF_PROFILE_MPEG2_SNR_SCALABLE 3
-#define FF_PROFILE_MPEG2_MAIN 4
-#define FF_PROFILE_MPEG2_SIMPLE 5
-
-#define FF_PROFILE_H264_CONSTRAINED (1<<9) // 8+1; constraint_set1_flag
-#define FF_PROFILE_H264_INTRA (1<<11) // 8+3; constraint_set3_flag
-
-#define FF_PROFILE_H264_BASELINE 66
-#define FF_PROFILE_H264_CONSTRAINED_BASELINE (66|FF_PROFILE_H264_CONSTRAINED)
-#define FF_PROFILE_H264_MAIN 77
-#define FF_PROFILE_H264_EXTENDED 88
-#define FF_PROFILE_H264_HIGH 100
-#define FF_PROFILE_H264_HIGH_10 110
-#define FF_PROFILE_H264_HIGH_10_INTRA (110|FF_PROFILE_H264_INTRA)
-#define FF_PROFILE_H264_HIGH_422 122
-#define FF_PROFILE_H264_HIGH_422_INTRA (122|FF_PROFILE_H264_INTRA)
-#define FF_PROFILE_H264_HIGH_444 144
-#define FF_PROFILE_H264_HIGH_444_PREDICTIVE 244
-#define FF_PROFILE_H264_HIGH_444_INTRA (244|FF_PROFILE_H264_INTRA)
-#define FF_PROFILE_H264_CAVLC_444 44
-
-#define FF_PROFILE_VC1_SIMPLE 0
-#define FF_PROFILE_VC1_MAIN 1
-#define FF_PROFILE_VC1_COMPLEX 2
-#define FF_PROFILE_VC1_ADVANCED 3
-
-#define FF_PROFILE_MPEG4_SIMPLE 0
-#define FF_PROFILE_MPEG4_SIMPLE_SCALABLE 1
-#define FF_PROFILE_MPEG4_CORE 2
-#define FF_PROFILE_MPEG4_MAIN 3
-#define FF_PROFILE_MPEG4_N_BIT 4
-#define FF_PROFILE_MPEG4_SCALABLE_TEXTURE 5
-#define FF_PROFILE_MPEG4_SIMPLE_FACE_ANIMATION 6
-#define FF_PROFILE_MPEG4_BASIC_ANIMATED_TEXTURE 7
-#define FF_PROFILE_MPEG4_HYBRID 8
-#define FF_PROFILE_MPEG4_ADVANCED_REAL_TIME 9
-#define FF_PROFILE_MPEG4_CORE_SCALABLE 10
-#define FF_PROFILE_MPEG4_ADVANCED_CODING 11
-#define FF_PROFILE_MPEG4_ADVANCED_CORE 12
-#define FF_PROFILE_MPEG4_ADVANCED_SCALABLE_TEXTURE 13
-#define FF_PROFILE_MPEG4_SIMPLE_STUDIO 14
-#define FF_PROFILE_MPEG4_ADVANCED_SIMPLE 15
-
- /**
- * level
- * - encoding: Set by user.
- * - decoding: Set by libavcodec.
- */
- int level;
-#define FF_LEVEL_UNKNOWN -99
-
- /**
- * low resolution decoding, 1-> 1/2 size, 2->1/4 size
- * - encoding: unused
- * - decoding: Set by user.
- */
- int lowres;
-
- /**
- * Bitstream width / height, may be different from width/height if lowres enabled.
- * - encoding: unused
- * - decoding: Set by user before init if known. Codec should override / dynamically change if needed.
- */
- int coded_width, coded_height;
-
- /**
- * frame skip threshold
- * - encoding: Set by user.
- * - decoding: unused
- */
- int frame_skip_threshold;
-
- /**
- * frame skip factor
- * - encoding: Set by user.
- * - decoding: unused
- */
- int frame_skip_factor;
-
- /**
- * frame skip exponent
- * - encoding: Set by user.
- * - decoding: unused
- */
- int frame_skip_exp;
-
- /**
- * frame skip comparison function
- * - encoding: Set by user.
- * - decoding: unused
- */
- int frame_skip_cmp;
-
- /**
- * Border processing masking, raises the quantizer for mbs on the borders
- * of the picture.
- * - encoding: Set by user.
- * - decoding: unused
- */
- float border_masking;
-
- /**
- * minimum MB lagrange multipler
- * - encoding: Set by user.
- * - decoding: unused
- */
- int mb_lmin;
-
- /**
- * maximum MB lagrange multipler
- * - encoding: Set by user.
- * - decoding: unused
- */
- int mb_lmax;
-
- /**
- *
- * - encoding: Set by user.
- * - decoding: unused
- */
- int me_penalty_compensation;
-
- /**
- *
- * - encoding: unused
- * - decoding: Set by user.
- */
- enum AVDiscard skip_loop_filter;
-
- /**
- *
- * - encoding: unused
- * - decoding: Set by user.
- */
- enum AVDiscard skip_idct;
-
- /**
- *
- * - encoding: unused
- * - decoding: Set by user.
- */
- enum AVDiscard skip_frame;
-
- /**
- *
- * - encoding: Set by user.
- * - decoding: unused
- */
- int bidir_refine;
-
- /**
- *
- * - encoding: Set by user.
- * - decoding: unused
- */
- int brd_scale;
-
-#if FF_API_X264_GLOBAL_OPTS
- /**
- * constant rate factor - quality-based VBR - values ~correspond to qps
- * - encoding: Set by user.
- * - decoding: unused
- * @deprecated use 'crf' libx264 private option
- */
- attribute_deprecated float crf;
-
- /**
- * constant quantization parameter rate control method
- * - encoding: Set by user.
- * - decoding: unused
- * @deprecated use 'cqp' libx264 private option
- */
- attribute_deprecated int cqp;
-#endif
-
- /**
- * minimum GOP size
- * - encoding: Set by user.
- * - decoding: unused
- */
- int keyint_min;
-
- /**
- * number of reference frames
- * - encoding: Set by user.
- * - decoding: Set by lavc.
- */
- int refs;
-
- /**
- * chroma qp offset from luma
- * - encoding: Set by user.
- * - decoding: unused
- */
- int chromaoffset;
-
-#if FF_API_X264_GLOBAL_OPTS
- /**
- * Influence how often B-frames are used.
- * - encoding: Set by user.
- * - decoding: unused
- */
- attribute_deprecated int bframebias;
-#endif
-
- /**
- * trellis RD quantization
- * - encoding: Set by user.
- * - decoding: unused
- */
- int trellis;
-
-#if FF_API_X264_GLOBAL_OPTS
- /**
- * Reduce fluctuations in qp (before curve compression).
- * - encoding: Set by user.
- * - decoding: unused
- */
- attribute_deprecated float complexityblur;
-
- /**
- * in-loop deblocking filter alphac0 parameter
- * alpha is in the range -6...6
- * - encoding: Set by user.
- * - decoding: unused
- */
- attribute_deprecated int deblockalpha;
-
- /**
- * in-loop deblocking filter beta parameter
- * beta is in the range -6...6
- * - encoding: Set by user.
- * - decoding: unused
- */
- attribute_deprecated int deblockbeta;
-
- /**
- * macroblock subpartition sizes to consider - p8x8, p4x4, b8x8, i8x8, i4x4
- * - encoding: Set by user.
- * - decoding: unused
- */
- attribute_deprecated int partitions;
-#define X264_PART_I4X4 0x001 /* Analyze i4x4 */
-#define X264_PART_I8X8 0x002 /* Analyze i8x8 (requires 8x8 transform) */
-#define X264_PART_P8X8 0x010 /* Analyze p16x8, p8x16 and p8x8 */
-#define X264_PART_P4X4 0x020 /* Analyze p8x4, p4x8, p4x4 */
-#define X264_PART_B8X8 0x100 /* Analyze b16x8, b8x16 and b8x8 */
-
- /**
- * direct MV prediction mode - 0 (none), 1 (spatial), 2 (temporal), 3 (auto)
- * - encoding: Set by user.
- * - decoding: unused
- */
- attribute_deprecated int directpred;
-#endif
-
- /**
- * Audio cutoff bandwidth (0 means "automatic")
- * - encoding: Set by user.
- * - decoding: unused
- */
- int cutoff;
-
- /**
- * Multiplied by qscale for each frame and added to scene_change_score.
- * - encoding: Set by user.
- * - decoding: unused
- */
- int scenechange_factor;
-
- /**
- *
- * Note: Value depends upon the compare function used for fullpel ME.
- * - encoding: Set by user.
- * - decoding: unused
- */
- int mv0_threshold;
-
- /**
- * Adjust sensitivity of b_frame_strategy 1.
- * - encoding: Set by user.
- * - decoding: unused
- */
- int b_sensitivity;
-
- /**
- * - encoding: Set by user.
- * - decoding: unused
- */
- int compression_level;
-#define FF_COMPRESSION_DEFAULT -1
-
- /**
- * - encoding: Set by user.
- * - decoding: unused
- */
- int min_prediction_order;
-
- /**
- * - encoding: Set by user.
- * - decoding: unused
- */
- int max_prediction_order;
-
-#if FF_API_FLAC_GLOBAL_OPTS
- /**
- * @name FLAC options
- * @deprecated Use FLAC encoder private options instead.
- * @{
- */
-
- /**
- * LPC coefficient precision - used by FLAC encoder
- * - encoding: Set by user.
- * - decoding: unused
- */
- attribute_deprecated int lpc_coeff_precision;
-
- /**
- * search method for selecting prediction order
- * - encoding: Set by user.
- * - decoding: unused
- */
- attribute_deprecated int prediction_order_method;
-
- /**
- * - encoding: Set by user.
- * - decoding: unused
- */
- attribute_deprecated int min_partition_order;
-
- /**
- * - encoding: Set by user.
- * - decoding: unused
- */
- attribute_deprecated int max_partition_order;
- /**
- * @}
- */
-#endif
-
- /**
- * GOP timecode frame start number, in non drop frame format
- * - encoding: Set by user.
- * - decoding: unused
- */
- int64_t timecode_frame_start;
-
-#if FF_API_REQUEST_CHANNELS
- /**
- * Decoder should decode to this many channels if it can (0 for default)
- * - encoding: unused
- * - decoding: Set by user.
- * @deprecated Deprecated in favor of request_channel_layout.
- */
- int request_channels;
-#endif
-
-#if FF_API_DRC_SCALE
- /**
- * Percentage of dynamic range compression to be applied by the decoder.
- * The default value is 1.0, corresponding to full compression.
- * - encoding: unused
- * - decoding: Set by user.
- * @deprecated use AC3 decoder private option instead.
- */
- attribute_deprecated float drc_scale;
-#endif
-
- /**
- * opaque 64bit number (generally a PTS) that will be reordered and
- * output in AVFrame.reordered_opaque
- * @deprecated in favor of pkt_pts
- * - encoding: unused
- * - decoding: Set by user.
- */
- int64_t reordered_opaque;
-
- /**
- * Bits per sample/pixel of internal libavcodec pixel/sample format.
- * - encoding: set by user.
- * - decoding: set by libavcodec.
- */
- int bits_per_raw_sample;
-
- /**
- * Audio channel layout.
- * - encoding: set by user.
- * - decoding: set by libavcodec.
- */
- uint64_t channel_layout;
-
- /**
- * Request decoder to use this channel layout if it can (0 for default)
- * - encoding: unused
- * - decoding: Set by user.
- */
- uint64_t request_channel_layout;
-
- /**
- * Ratecontrol attempt to use, at maximum,