diff options
Diffstat (limited to 'src')
67 files changed, 1661 insertions, 609 deletions
diff --git a/src/jogl/classes/com/jogamp/gluegen/opengl/BuildStaticGLInfo.java b/src/jogl/classes/com/jogamp/gluegen/opengl/BuildStaticGLInfo.java index 3b08b5386..8644f1696 100644 --- a/src/jogl/classes/com/jogamp/gluegen/opengl/BuildStaticGLInfo.java +++ b/src/jogl/classes/com/jogamp/gluegen/opengl/BuildStaticGLInfo.java @@ -206,7 +206,7 @@ public class BuildStaticGLInfo { int type = 0; // 1-define, 2-function if ( 0 < block ) { // inside a #ifndef GL_XXX block and matching a function, if block > 0 String identifier = null; - if( 2 >= block ) { // not within sub-blocks > 2, i.e. further typedefs + if( 3 >= block ) { // not within sub-blocks > 3, i.e. further typedefs if ((m = funcPattern.matcher(line)).matches()) { identifier = m.group(funcIdentifierGroup).trim(); type = 2; @@ -264,14 +264,15 @@ public class BuildStaticGLInfo { } public void dump() { + System.err.println("BuildStaticGLInfo.dump():"); for (final String name : extensionToDeclarationMap.keySet()) { final Set<String> decls = extensionToDeclarationMap.get(name); - System.out.println("<" + name + "> :"); + System.err.println("<" + name + "> :"); final List<String> l = new ArrayList<String>(); l.addAll(decls); Collections.sort(l); for (final String str : l) { - System.out.println(" <" + str + ">"); + System.err.println(" <" + str + ">"); } } } diff --git a/src/jogl/classes/com/jogamp/gluegen/opengl/GLConfiguration.java b/src/jogl/classes/com/jogamp/gluegen/opengl/GLConfiguration.java index 5da45abfe..f8655feea 100644 --- a/src/jogl/classes/com/jogamp/gluegen/opengl/GLConfiguration.java +++ b/src/jogl/classes/com/jogamp/gluegen/opengl/GLConfiguration.java @@ -39,11 +39,15 @@ */ package com.jogamp.gluegen.opengl; +import static java.util.logging.Level.INFO; + import com.jogamp.gluegen.GlueEmitterControls; import com.jogamp.gluegen.GlueGen; import com.jogamp.gluegen.MethodBinding; +import com.jogamp.gluegen.cgram.types.AliasedSymbol; import com.jogamp.gluegen.procaddress.ProcAddressConfiguration; import com.jogamp.gluegen.runtime.opengl.GLNameResolver; + import java.io.File; import java.io.IOException; import java.util.ArrayList; @@ -59,11 +63,19 @@ import java.util.StringTokenizer; public class GLConfiguration extends ProcAddressConfiguration { // The following data members support ignoring an entire extension at a time - private final List<String> glHeaders = new ArrayList<String>(); + private final List<String> glSemHeaders = new ArrayList<String>(); private final Set<String> ignoredExtensions = new HashSet<String>(); private final Set<String> forcedExtensions = new HashSet<String>(); - private final Set<String> extensionsRenamedIntoCore = new HashSet<String>(); - private BuildStaticGLInfo glInfo; + private final Set<String> renameExtensionsIntoCore = new HashSet<String>(); + private BuildStaticGLInfo glSemInfo; + + // GLDocHeaders include GLSemHeaders! + boolean dropDocInfo = false; + private final List<String> glDocHeaders = new ArrayList<String>(); + // GLDocInfo include GLSemInfo! + private BuildStaticGLInfo glDocInfo; + private final Map<String, String> javaDocSymbolRenames = new HashMap<String, String>(); + private final Map<String, Set<String>> javaDocRenamedSymbols = new HashMap<String, Set<String>>(); // Maps function names to the kind of buffer object it deals with private final Map<String, GLEmitter.BufferObjectKind> bufferObjectKinds = new HashMap<String, GLEmitter.BufferObjectKind>(); @@ -97,14 +109,26 @@ public class GLConfiguration extends ProcAddressConfiguration { forcedExtensions.add(sym); } else if (cmd.equalsIgnoreCase("RenameExtensionIntoCore")) { final String sym = readString("RenameExtensionIntoCore", tok, filename, lineNo); - extensionsRenamedIntoCore.add(sym); + renameExtensionsIntoCore.add(sym); } else if (cmd.equalsIgnoreCase("AllowNonGLExtensions")) { allowNonGLExtensions = readBoolean("AllowNonGLExtensions", tok, filename, lineNo).booleanValue(); } else if (cmd.equalsIgnoreCase("AutoUnifyExtensions")) { autoUnifyExtensions = readBoolean("AutoUnifyExtensions", tok, filename, lineNo).booleanValue(); - } else if (cmd.equalsIgnoreCase("GLHeader")) { - final String sym = readString("GLHeader", tok, filename, lineNo); - glHeaders.add(sym); + } else if (cmd.equalsIgnoreCase("GLSemHeader")) { + final String sym = readString("GLSemHeader", tok, filename, lineNo); + if( !glSemHeaders.contains(sym) ) { + glSemHeaders.add(sym); + } + if( !dropDocInfo && !glDocHeaders.contains(sym) ) { + glDocHeaders.add(sym); + } + } else if (cmd.equalsIgnoreCase("GLDocHeader")) { + final String sym = readString("GLDocHeader", tok, filename, lineNo); + if( !dropDocInfo && !glDocHeaders.contains(sym) ) { + glDocHeaders.add(sym); + } + } else if (cmd.equalsIgnoreCase("DropAllGLDocHeader")) { + dropDocInfo = readBoolean("DropAllGLDocHeader", tok, filename, lineNo).booleanValue(); } else if (cmd.equalsIgnoreCase("BufferObjectKind")) { readBufferObjectKind(tok, filename, lineNo); } else if (cmd.equalsIgnoreCase("BufferObjectOnly")) { @@ -209,111 +233,133 @@ public class GLConfiguration extends ProcAddressConfiguration { } @Override - public void dumpIgnores() { - System.err.println("GL Ignored extensions: "); + public void logIgnores() { + LOG.log(INFO, "GL Ignored extensions: {0}", ignoredExtensions.size()); for (final String str : ignoredExtensions) { - System.err.println("\t" + str); + LOG.log(INFO, "\t{0}", str); } - System.err.println("GL Forced extensions: "); + LOG.log(INFO, "GL Forced extensions: {0}", forcedExtensions.size()); for (final String str : forcedExtensions) { - System.err.println("\t" + str); + LOG.log(INFO, "\t{0}", str); } - super.dumpIgnores(); + super.logIgnores(); } - protected boolean shouldIgnoreExtension(final String symbol, final boolean criteria) { - if (criteria && glInfo != null) { - final Set<String> extensionNames = glInfo.getExtension(symbol); - if( null != extensionNames ) { - boolean ignoredExtension = false; - for(final Iterator<String> i=extensionNames.iterator(); !ignoredExtension && i.hasNext(); ) { - final String extensionName = i.next(); - if ( extensionName != null && ignoredExtensions.contains(extensionName) ) { - if (DEBUG_IGNORES) { - System.err.print("Ignore symbol <" + symbol + "> of extension <" + extensionName + ">"); - if(extensionNames.size()==1) { - System.err.println(", single ."); - } else { - System.err.println(", WARNING MULTIPLE OCCURENCE: "+extensionNames); - } - } - ignoredExtension = true; - } - } - if( ignoredExtension ) { - ignoredExtension = !shouldForceExtension( symbol, true, symbol ); - if( ignoredExtension ) { - final Set<String> origSymbols = getRenamedJavaSymbols( symbol ); - if(null != origSymbols) { - for(final String origSymbol : origSymbols) { - if( shouldForceExtension( origSymbol, true, symbol ) ) { - ignoredExtension = false; - break; - } - } - } - } + @Override + public void logRenames() { + LOG.log(INFO, "GL Renamed extensions into core: {0}", renameExtensionsIntoCore.size()); + for (final String str : renameExtensionsIntoCore) { + LOG.log(INFO, "\t{0}", str); + } + super.logRenames(); + } + + protected boolean shouldIgnoreExtension(final AliasedSymbol symbol) { + final Set<String> symExtensionNames; + // collect current-name symbol extensions + { + final Set<String> s = glSemInfo.getExtension(symbol.getName()); + if( null != s ) { + symExtensionNames = s; + } else { + symExtensionNames = new HashSet<String>(); + } + } + // collect renamed symbol extensions + if( symbol.hasAliases() ) { + final Set<String> aliases = symbol.getAliasedNames(); + for(final String alias : aliases) { + final Set<String> s = glSemInfo.getExtension(alias); + if( null != s && s.size() > 0 ) { + symExtensionNames.addAll(s); } - if( ignoredExtension ) { - return true; + } + } + boolean ignoreExtension = symExtensionNames.size() > 0 && + ignoredExtensions.containsAll(symExtensionNames); + + if( LOG.isLoggable(INFO) ) { + final Set<String> ignoredSymExtensionNames = new HashSet<String>(); + final Set<String> notIgnoredSymExtensionNames = new HashSet<String>(); + for(final Iterator<String> i=symExtensionNames.iterator(); i.hasNext(); ) { + final String extensionName = i.next(); + if ( null != extensionName && ignoredExtensions.contains(extensionName) ) { + ignoredSymExtensionNames.add(extensionName); + } else { + notIgnoredSymExtensionNames.add(extensionName); } } - final boolean isGLEnum = GLNameResolver.isGLEnumeration(symbol); - final boolean isGLFunc = GLNameResolver.isGLFunction(symbol); + if( ignoreExtension ) { + LOG.log(INFO, "Ignored symbol {0} of all extensions <{1}>", symbol.getAliasedString(), symExtensionNames); + } else if( ignoredSymExtensionNames.size() > 0 ) { + LOG.log(INFO, "Not ignored symbol {0}; Ignored in <{1}>, but active in <{2}>", + symbol.getAliasedString(), ignoredSymExtensionNames, notIgnoredSymExtensionNames); + } + } + if( !ignoreExtension ) { + // Check whether the current-name denotes an ignored vendor extension + final String name = symbol.getName(); + final boolean isGLEnum = GLNameResolver.isGLEnumeration(name); + final boolean isGLFunc = GLNameResolver.isGLFunction(name); + String extSuffix = null; if (isGLFunc || isGLEnum) { - if (GLNameResolver.isExtensionVEN(symbol, isGLFunc)) { - final String extSuffix = GLNameResolver.getExtensionSuffix(symbol, isGLFunc); + if (GLNameResolver.isExtensionVEN(name, isGLFunc)) { + extSuffix = GLNameResolver.getExtensionSuffix(name, isGLFunc); if (getDropUniqVendorExtensions(extSuffix)) { - if (DEBUG_IGNORES) { - System.err.println("Ignore UniqVendorEXT: " + symbol + ", vendor " + extSuffix); - } - return true; + LOG.log(INFO, "Ignore UniqVendorEXT: {0}, vendor {1}, isGLFunc {2}, isGLEnum {3}", + symbol.getAliasedString(), extSuffix, isGLFunc, isGLEnum); + ignoreExtension = true; } } } + if (!ignoreExtension) { + LOG.log(INFO, "Not ignored UniqVendorEXT: {0}, vendor {1}, isGLFunc {2}, isGLEnum {3}", + symbol.getAliasedString(), extSuffix, isGLFunc, isGLEnum); + } } - return false; + if( ignoreExtension ) { + ignoreExtension = !shouldForceExtension( symbol, symExtensionNames); + } + return ignoreExtension; } - - public boolean shouldForceExtension(final String symbol, final boolean criteria, final String renamedSymbol) { - if (criteria && glInfo != null) { - final Set<String> extensionNames = glInfo.getExtension(symbol); - if( null != extensionNames ) { - for(final Iterator<String> i=extensionNames.iterator(); i.hasNext(); ) { - final String extensionName = i.next(); - if ( extensionName != null && forcedExtensions.contains(extensionName) ) { - if (DEBUG_IGNORES) { - System.err.print("Not Ignore symbol <" + symbol + " -> " + renamedSymbol + "> of extension <" + extensionName + ">"); - if(extensionNames.size()==1) { - System.err.println(", single ."); - } else { - System.err.println(", WARNING MULTIPLE OCCURENCE: "+extensionNames); - } - } - return true; - } - } + public boolean shouldForceExtension(final AliasedSymbol symbol, final Set<String> symExtensionNames) { + for(final Iterator<String> i=symExtensionNames.iterator(); i.hasNext(); ) { + final String extensionName = i.next(); + if ( extensionName != null && forcedExtensions.contains(extensionName) ) { + LOG.log(INFO, "Not ignored symbol {0} of extension <{1}>", + symbol.getAliasedString(), extensionName); + return true; } } return false; } + /** + * {@inheritDoc} + * <p> + * Implementation extends the exclusion query w/ {@link #shouldIgnoreExtension(AliasedSymbol) the list of ignored extensions}. + * </p> + * <p> + * If passing the former, it calls down to {@link #shouldIgnoreInInterface_Int(AliasedSymbol)}. + * </p> + */ @Override - public boolean shouldIgnoreInInterface(final String symbol) { - return shouldIgnoreInInterface(symbol, true); - } - - public boolean shouldIgnoreInInterface(final String symbol, final boolean checkEXT) { - return shouldIgnoreExtension(symbol, checkEXT) || super.shouldIgnoreInInterface(symbol); + public boolean shouldIgnoreInInterface(final AliasedSymbol symbol) { + return shouldIgnoreExtension(symbol) || shouldIgnoreInInterface_Int(symbol); } + /** + * {@inheritDoc} + * <p> + * Implementation extends the exclusion query w/ {@link #shouldIgnoreExtension(AliasedSymbol) the list of ignored extensions}. + * </p> + * <p> + * If passing the former, it calls down to {@link #shouldIgnoreInImpl_Int(AliasedSymbol)}. + * </p> + */ @Override - public boolean shouldIgnoreInImpl(final String symbol) { - return shouldIgnoreInImpl(symbol, true); - } - - public boolean shouldIgnoreInImpl(final String symbol, final boolean checkEXT) { - return shouldIgnoreExtension(symbol, checkEXT) || super.shouldIgnoreInImpl(symbol); + public boolean shouldIgnoreInImpl(final AliasedSymbol symbol) { + return shouldIgnoreExtension(symbol) || shouldIgnoreInImpl_Int(symbol); } /** Should we automatically ignore extensions that have already been @@ -348,27 +394,114 @@ public class GLConfiguration extends ProcAddressConfiguration { return bufferObjectOnly.contains(name); } - /** Parses any GL headers specified in the configuration file for - the purpose of being able to ignore an extension at a time. */ - public void parseGLHeaders(final GlueEmitterControls controls) throws IOException { - if (!glHeaders.isEmpty()) { - glInfo = new BuildStaticGLInfo(); - glInfo.setDebug(GlueGen.debug()); - for (final String file : glHeaders) { + /** + * Parses any GL headers specified in the configuration file for + * the purpose of being able to ignore an extension at a time. + * <p> + * Targeting semantic information, i.e. influences code generation. + * </p> + */ + public void parseGLSemHeaders(final GlueEmitterControls controls) throws IOException { + glSemInfo = new BuildStaticGLInfo(); + glSemInfo.setDebug(GlueGen.debug()); + if (!glSemHeaders.isEmpty()) { + for (final String file : glSemHeaders) { + final String fullPath = controls.findHeaderFile(file); + if (fullPath == null) { + throw new IOException("Unable to locate header file \"" + file + "\""); + } + glSemInfo.parse(fullPath); + } + } + } + + /** + * Returns the information about the association between #defines, + * function symbols and the OpenGL extensions they are defined in. + * <p> + * This instance targets semantic information, i.e. influences code generation. + * </p> + */ + public BuildStaticGLInfo getGLSemInfo() { + return glSemInfo; + } + + /** + * Parses any GL headers specified in the configuration file for + * the purpose of being able to ignore an extension at a time. + * <p> + * Targeting API documentation information, i.e. <i>not</i> influencing code generation. + * </p> + */ + public void parseGLDocHeaders(final GlueEmitterControls controls) throws IOException { + glDocInfo = new BuildStaticGLInfo(); + glDocInfo.setDebug(GlueGen.debug()); + if (!glDocHeaders.isEmpty()) { + for (final String file : glDocHeaders) { final String fullPath = controls.findHeaderFile(file); if (fullPath == null) { throw new IOException("Unable to locate header file \"" + file + "\""); } - glInfo.parse(fullPath); + glDocInfo.parse(fullPath); } } } - /** Returns the information about the association between #defines, - function symbols and the OpenGL extensions they are defined - in. */ - public BuildStaticGLInfo getGLInfo() { - return glInfo; + @Override + public Set<String> getAliasedDocNames(final AliasedSymbol symbol) { + return getRenamedJavaDocSymbols(symbol.getName()); + } + + /** + * Returns the information about the association between #defines, + * function symbols and the OpenGL extensions they are defined in. + * <p> + * This instance targets API documentation information, i.e. <i>not</i> influencing code generation. + * </p> + * <p> + * GLDocInfo include GLSemInfo! + * </p> + */ + public BuildStaticGLInfo getGLDocInfo() { + return glDocInfo; + } + + /** Returns a set of replaced javadoc names to the given <code>aliasedName</code>. */ + public Set<String> getRenamedJavaDocSymbols(final String aliasedName) { + return javaDocRenamedSymbols.get(aliasedName); + } + + /** + * {@inheritDoc} + * <p> + * Also adds a javadoc rename directive for the given symbol. + * </p> + */ + @Override + public void addJavaSymbolRename(final String origName, final String newName) { + super.addJavaSymbolRename(origName, newName); + if( !dropDocInfo ) { + addJavaDocSymbolRename(origName, newName); + } + } + + /** + * Adds a javadoc rename directive for the given symbol. + */ + public void addJavaDocSymbolRename(final String origName, final String newName) { + LOG.log(INFO, "\tDoc Rename {0} -> {1}", origName, newName); + final String prevValue = javaDocSymbolRenames.put(origName, newName); + if(null != prevValue && !prevValue.equals(newName)) { + throw new RuntimeException("Doc-Rename-Override Attampt: "+origName+" -> "+newName+ + ", but "+origName+" -> "+prevValue+" already exist. Run in 'debug' mode to analyze!"); + } + + Set<String> origNames = javaDocRenamedSymbols.get(newName); + if(null == origNames) { + origNames = new HashSet<String>(); + javaDocRenamedSymbols.put(newName, origNames); + } + origNames.add(origName); } /** Returns the OpenGL extensions that should have all of their @@ -376,6 +509,6 @@ public class GLConfiguration extends ProcAddressConfiguration { namespace; for example, glGenFramebuffersEXT to glGenFramebuffers and GL_FRAMEBUFFER_EXT to GL_FRAMEBUFFER. */ public Set<String> getExtensionsRenamedIntoCore() { - return extensionsRenamedIntoCore; + return renameExtensionsIntoCore; } } diff --git a/src/jogl/classes/com/jogamp/gluegen/opengl/GLEmitter.java b/src/jogl/classes/com/jogamp/gluegen/opengl/GLEmitter.java index bc230c83a..ccac4cf6b 100644 --- a/src/jogl/classes/com/jogamp/gluegen/opengl/GLEmitter.java +++ b/src/jogl/classes/com/jogamp/gluegen/opengl/GLEmitter.java @@ -39,9 +39,12 @@ */ package com.jogamp.gluegen.opengl; +import static java.util.logging.Level.INFO; + import com.jogamp.gluegen.ConstantDefinition; import com.jogamp.gluegen.FunctionEmitter; import com.jogamp.gluegen.GlueEmitterControls; +import com.jogamp.gluegen.GlueGen; import com.jogamp.gluegen.JavaConfiguration; import com.jogamp.gluegen.JavaEmitter; import com.jogamp.gluegen.JavaMethodBindingEmitter; @@ -49,6 +52,7 @@ import com.jogamp.gluegen.JavaType; import com.jogamp.gluegen.MethodBinding; import com.jogamp.gluegen.SymbolFilter; import com.jogamp.gluegen.cgram.types.FunctionSymbol; +import com.jogamp.gluegen.cgram.types.Type; import com.jogamp.gluegen.procaddress.ProcAddressEmitter; import com.jogamp.gluegen.procaddress.ProcAddressJavaMethodBindingEmitter; import com.jogamp.gluegen.runtime.opengl.GLNameResolver; @@ -56,7 +60,6 @@ import com.jogamp.gluegen.runtime.opengl.GLNameResolver; import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; -import java.util.Collection; import java.util.IdentityHashMap; import java.util.Iterator; import java.util.LinkedHashMap; @@ -78,34 +81,38 @@ public class GLEmitter extends ProcAddressEmitter { @Override public void beginEmission(final GlueEmitterControls controls) throws IOException { - getGLConfig().parseGLHeaders(controls); + getGLConfig().parseGLSemHeaders(controls); + if( null == getGLConfig().getGLSemInfo() ) { + throw new RuntimeException("No 'GLSemHeader' defined."); + } + getGLConfig().parseGLDocHeaders(controls); + if( null == getGLConfig().getGLDocInfo() ) { + throw new InternalError("XXX"); // since GLDocHeader contains all GLSemHeader .. + } renameExtensionsIntoCore(); - if (getGLConfig().getAutoUnifyExtensions()) { + if ( getGLConfig().getAutoUnifyExtensions() ) { unifyExtensions(controls); } super.beginEmission(controls); } protected void renameExtensionsIntoCore() { + final GLConfiguration config = getGLConfig(); + renameExtensionsIntoCore(config, config.getGLSemInfo(), true); + renameExtensionsIntoCore(config, config.getGLDocInfo(), false); + } + protected void renameExtensionsIntoCore(final GLConfiguration config, final BuildStaticGLInfo glInfo, final boolean isSemHeader) { // This method handles renaming of entire extensions into the // OpenGL core namespace. For example, it is used to move certain // OpenGL ES (OES) extensions into the core namespace which are // already in the core namespace in desktop OpenGL. It builds upon // renaming mechanisms that are built elsewhere. - final GLConfiguration config = getGLConfig(); - final Set<String> extensionsRenamedIntoCore = config.getExtensionsRenamedIntoCore(); - final BuildStaticGLInfo glInfo = config.getGLInfo(); - if (null == glInfo) { - if (extensionsRenamedIntoCore.size() > 0) { - throw new RuntimeException("ExtensionRenamedIntoCore (num: " + extensionsRenamedIntoCore.size() + "), but no GLHeader"); - } - return; - } - for (final String extension : extensionsRenamedIntoCore) { - if(JavaConfiguration.DEBUG_RENAMES) { - System.err.println("<RenameExtensionIntoCore: "+extension+" BEGIN"); - } + final String headerType = isSemHeader ? "GLSemHeader" : "GLDocHeader"; + final Set<String> extensionSet = isSemHeader ? config.getExtensionsRenamedIntoCore() : glInfo.getExtensions(); + + for (final String extension : extensionSet) { + LOG.log(INFO, "<RenameExtensionIntoCore: {0} BEGIN {1}", extension, headerType); final Set<String> declarations = glInfo.getDeclarations(extension); if (declarations != null) { for (final Iterator<String> iterator = declarations.iterator(); iterator.hasNext();) { @@ -118,14 +125,18 @@ public class GLEmitter extends ProcAddressEmitter { if (isGLFunction || isGLEnumeration) { final String renamed = GLNameResolver.normalize(decl, isGLFunction); if (!renamed.equals(decl)) { - config.addJavaSymbolRename(decl, renamed); + if( isSemHeader ) { + // Sem + Doc + config.addJavaSymbolRename(decl, renamed); + } else { + // Doc only + config.addJavaDocSymbolRename(decl, renamed); + } } } } } - if(JavaConfiguration.DEBUG_RENAMES) { - System.err.println("RenameExtensionIntoCore: "+extension+" END>"); - } + LOG.log(INFO, "RenameExtensionIntoCore: {0} END>", extension, headerType); } } @@ -135,35 +146,28 @@ public class GLEmitter extends ProcAddressEmitter { private List<FunctionSymbol> functions; @Override - public void filterSymbols(final List<ConstantDefinition> constants, - final List<FunctionSymbol> functions) { - this.constants = constants; - this.functions = functions; - doWork(); - } - - @Override public List<ConstantDefinition> getConstants() { return constants; } - @Override public List<FunctionSymbol> getFunctions() { return functions; } - private void doWork() { - final BuildStaticGLInfo glInfo = getGLConfig().getGLInfo(); + @Override + public void filterSymbols(final List<ConstantDefinition> inConstList, + final List<FunctionSymbol> inFuncList) { + final BuildStaticGLInfo glInfo = getGLConfig().getGLSemInfo(); if (glInfo == null) { return; } // Try to retain a "good" ordering for these symbols final Map<String, ConstantDefinition> constantMap = new LinkedHashMap<String, ConstantDefinition>(); - for (final ConstantDefinition def : constants) { + for (final ConstantDefinition def : inConstList) { constantMap.put(def.getName(), def); } final Map<String, FunctionSymbol> functionMap = new LinkedHashMap<String, FunctionSymbol>(); - for (final FunctionSymbol sym : functions) { + for (final FunctionSymbol sym : inFuncList) { functionMap.put(sym.getName(), sym); } @@ -277,6 +281,10 @@ public class GLEmitter extends ProcAddressEmitter { // Need to expand each one of the generated bindings to take a // Java long instead of a Buffer for each void* argument + if( GlueGen.debug() ) { + System.err.println("expandMethodBinding: j "+binding.toString()); + System.err.println("expandMethodBinding: c "+binding.getCSymbol()); + } // for (MethodBinding cur : bindings) { int j=0; @@ -294,24 +302,38 @@ public class GLEmitter extends ProcAddressEmitter { } MethodBinding result = cur; + int replacedCount = 0; for (int i = 0; i < cur.getNumArguments(); i++) { - if (cur.getJavaArgumentType(i).isNIOBuffer()) { + final JavaType jt = cur.getJavaArgumentType(i); + if( jt.isOpaqued() ) { + replacedCount++; // already replaced, i.e. due to opaque + } else if ( jt.isNIOBuffer() ) { result = result.replaceJavaArgumentType(i, JavaType.createForClass(Long.TYPE)); + replacedCount++; + } + if( GlueGen.debug() ) { + final Type ct = cur.getCArgumentType(i); + System.err.println(" ["+i+"]: #"+replacedCount+", "+ct.getDebugString()+", "+jt.getDebugString()); } } - if (result == cur) { + if ( 0 == replacedCount ) { throw new RuntimeException("Error: didn't find any void* arguments for BufferObject function " - + binding.getName()); + + binding.toString()); } - newBindings.add(result); // Now need to flag this MethodBinding so that we generate the // correct flags in the emitters later bufferObjectMethodBindings.put(result, result); - if( bufferObjectOnly ) { - bindings.remove(j); + if( result != cur ) { + // replaced + newBindings.add(result); + if( bufferObjectOnly ) { + bindings.remove(j); + } else { + j++; + } } else { j++; } @@ -323,12 +345,14 @@ public class GLEmitter extends ProcAddressEmitter { @Override protected boolean needsModifiedEmitters(final FunctionSymbol sym) { - if ((!needsProcAddressWrapper(sym) && !needsBufferObjectVariant(sym)) - || getConfig().isUnimplemented(sym.getName())) { + if ( ( !callThroughProcAddress(sym) && !needsBufferObjectVariant(sym) ) || + getConfig().isUnimplemented(sym) + ) + { return false; + } else { + return true; } - - return true; } public boolean isBufferObjectMethodBinding(final MethodBinding binding) { @@ -337,14 +361,10 @@ public class GLEmitter extends ProcAddressEmitter { @Override public void emitDefine(final ConstantDefinition def, final String optionalComment) throws Exception { - final BuildStaticGLInfo glInfo = getGLConfig().getGLInfo(); - if (null == glInfo) { - throw new Exception("No GLInfo for: " + def); - } final String symbolRenamed = def.getName(); final StringBuilder newComment = new StringBuilder(); newComment.append("Part of "); - if (0 == addExtensionsOfSymbols2Buffer(newComment, ", ", "; ", symbolRenamed, def.getAliasedNames())) { + if (0 == addExtensionsOfSymbols2Doc(newComment, ", ", ", ", symbolRenamed)) { if (def.isEnum()) { final String enumName = def.getEnumName(); if (null != enumName) { @@ -361,16 +381,13 @@ public class GLEmitter extends ProcAddressEmitter { // #define GL_EXT_lala 1 // ... // #endif - if (JavaConfiguration.DEBUG_IGNORES) { - final StringBuilder sb = new StringBuilder(); - JavaEmitter.addStrings2Buffer(sb, ", ", symbolRenamed, def.getAliasedNames()); - System.err.println("Dropping marker: " + sb.toString()); - } + final StringBuilder sb = new StringBuilder(); + JavaEmitter.addStrings2Buffer(sb, ", ", symbolRenamed, def.getAliasedNames()); + LOG.log(INFO, "Dropping marker: {0}", sb.toString()); return; } } } - if (null != optionalComment) { newComment.append("<br>"); newComment.append(optionalComment); @@ -379,9 +396,9 @@ public class GLEmitter extends ProcAddressEmitter { super.emitDefine(def, newComment.toString()); } - private int addExtensionListOfSymbol2Buffer(final BuildStaticGLInfo glInfo, final StringBuilder buf, final String sep1, final String name) { + private int addExtensionListOfSymbol2Doc(final BuildStaticGLInfo glDocInfo, final StringBuilder buf, final String sep1, final String name) { int num = 0; - final Set<String> extensionNames = glInfo.getExtension(name); + final Set<String> extensionNames = glDocInfo.getExtension(name); if(null!=extensionNames) { for(final Iterator<String> i=extensionNames.iterator(); i.hasNext(); ) { final String extensionName = i.next(); @@ -398,49 +415,35 @@ public class GLEmitter extends ProcAddressEmitter { } return num; } - private int addExtensionListOfAliasedSymbols2Buffer(final BuildStaticGLInfo glInfo, final StringBuilder buf, final String sep1, final String sep2, final String name, final Collection<String> exclude) { + private int addExtensionListOfAliasedSymbols2Doc(final BuildStaticGLInfo glDocInfo, final StringBuilder buf, final String sep1, final String sep2, final String name) { int num = 0; if(null != name) { - num += addExtensionListOfSymbol2Buffer(glInfo, buf, sep1, name); // extensions of given name - boolean needsSep2 = 0<num; - final Set<String> origNames = cfg.getRenamedJavaSymbols(name); - if(null != origNames) { - for(final String origName : origNames) { - if(!exclude.contains(origName)) { - if (needsSep2) { - buf.append(sep2); // diff-name seperator - } - final int num2 = addExtensionListOfSymbol2Buffer(glInfo, buf, sep1, origName); // extensions of orig-name - needsSep2 = num<num2; - num += num2; + num += addExtensionListOfSymbol2Doc(glDocInfo, buf, sep1, name); // extensions of given name + boolean needsSep2 = num > 0; + final Set<String> aliases = ((GLConfiguration)cfg).getRenamedJavaDocSymbols(name); + if(null != aliases) { + for(final String alias : aliases) { + if (needsSep2) { + buf.append(sep2); } + final int num2 = addExtensionListOfSymbol2Doc(glDocInfo, buf, sep1, alias); // extensions of orig-name + needsSep2 = num2 > 0; + num += num2; } } } return num; } - public int addExtensionsOfSymbols2Buffer(StringBuilder buf, final String sep1, final String sep2, final String first, final Collection<String> col) { - final BuildStaticGLInfo glInfo = getGLConfig().getGLInfo(); - if (null == glInfo) { - throw new RuntimeException("No GLInfo for: " + first); + public int addExtensionsOfSymbols2Doc(StringBuilder buf, final String sep1, final String sep2, final String first) { + final BuildStaticGLInfo glDocInfo = getGLConfig().getGLDocInfo(); + if (null == glDocInfo) { + throw new RuntimeException("No GLDocInfo for: " + first); } - int num = 0; if (null == buf) { buf = new StringBuilder(); } - - num += addExtensionListOfAliasedSymbols2Buffer(glInfo, buf, sep1, sep2, first, col); - boolean needsSep2 = 0<num; - for(final Iterator<String> iter = col.iterator(); iter.hasNext(); ) { - if(needsSep2) { - buf.append(sep2); // diff-name seperator - } - final int num2 = addExtensionListOfAliasedSymbols2Buffer(glInfo, buf, sep1, sep2, iter.next(), col); - needsSep2 = num<num2; - num += num2; - } - return num; + return addExtensionListOfAliasedSymbols2Doc(glDocInfo, buf, sep1, sep2, first); } //---------------------------------------------------------------------- diff --git a/src/jogl/classes/com/jogamp/gluegen/opengl/GLJavaMethodBindingEmitter.java b/src/jogl/classes/com/jogamp/gluegen/opengl/GLJavaMethodBindingEmitter.java index d491a3712..afd9163ee 100644 --- a/src/jogl/classes/com/jogamp/gluegen/opengl/GLJavaMethodBindingEmitter.java +++ b/src/jogl/classes/com/jogamp/gluegen/opengl/GLJavaMethodBindingEmitter.java @@ -103,7 +103,6 @@ public class GLJavaMethodBindingEmitter extends ProcAddressJavaMethodBindingEmit @Override protected void emitBindingCSignature(final MethodBinding binding, final PrintWriter writer) { - final String symbolRenamed = binding.getName(); final StringBuilder newComment = new StringBuilder(); @@ -113,18 +112,25 @@ public class GLJavaMethodBindingEmitter extends ProcAddressJavaMethodBindingEmit writer.print(" </code> "); newComment.append("<br>Part of "); - if (0 == glEmitter.addExtensionsOfSymbols2Buffer(newComment, ", ", "; ", symbolRenamed, binding.getAliasedNames())) { + if (0 == glEmitter.addExtensionsOfSymbols2Doc(newComment, ", ", ", ", symbolRenamed)) { if (glEmitter.getGLConfig().getAllowNonGLExtensions()) { newComment.append("CORE FUNC"); } else { - final StringBuilder sb = new StringBuilder(); - JavaEmitter.addStrings2Buffer(sb, ", ", symbolRenamed, binding.getAliasedNames()); - final RuntimeException ex = new RuntimeException("Couldn't find extension to: " + binding + " ; " + sb.toString()); - glEmitter.getGLConfig().getGLInfo().dump(); - // glEmitter.getGLConfig().dumpRenames(); - throw ex; + if( !((GLConfiguration)cfg).dropDocInfo ) { + final StringBuilder sb = new StringBuilder(); + JavaEmitter.addStrings2Buffer(sb, ", ", symbolRenamed, binding.getAliasedNames()); + final RuntimeException ex = new RuntimeException("Couldn't find extension to: " + binding + " ; " + sb.toString()); + System.err.println(ex.getMessage()); + glEmitter.getGLConfig().getGLDocInfo().dump(); + // glEmitter.getGLConfig().dumpRenames(); + throw ex; + } else { + newComment.append("UNDEFINED"); + } } } + newComment.append("<br>"); + emitAliasedDocNamesComment(funcSym, newComment); writer.print(newComment.toString()); } } diff --git a/src/jogl/classes/com/jogamp/opengl/FBObject.java b/src/jogl/classes/com/jogamp/opengl/FBObject.java index e1ddc9c66..c36727fe4 100644 --- a/src/jogl/classes/com/jogamp/opengl/FBObject.java +++ b/src/jogl/classes/com/jogamp/opengl/FBObject.java @@ -1248,7 +1248,7 @@ public class FBObject { return("FBO missing draw buffer"); case GL2GL3.GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER: return("FBO missing read buffer"); - case GL2ES3.GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE: + case GL.GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE: return("FBO missing multisample buffer"); case GL3.GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS: return("FBO missing layer targets"); @@ -1280,7 +1280,7 @@ public class FBObject { case GL.GL_FRAMEBUFFER_INCOMPLETE_FORMATS: case GL2GL3.GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER: case GL2GL3.GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER: - case GL2ES3.GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE: + case GL.GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE: case GL3.GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS: if(0 == colorbufferCount || null == depth) { // we are in transition @@ -2500,8 +2500,8 @@ public class FBObject { if(!bound || fbName != gl.getBoundFramebuffer(GL.GL_FRAMEBUFFER)) { checkInitialized(); if( fullFBOSupport ) { - gl.glBindFramebuffer(GL2ES3.GL_DRAW_FRAMEBUFFER, getWriteFramebuffer()); // this fb, msaa or normal - gl.glBindFramebuffer(GL2ES3.GL_READ_FRAMEBUFFER, getReadFramebuffer()); // msaa: sampling sink, normal: this fb + gl.glBindFramebuffer(GL.GL_DRAW_FRAMEBUFFER, getWriteFramebuffer()); // this fb, msaa or normal + gl.glBindFramebuffer(GL.GL_READ_FRAMEBUFFER, getReadFramebuffer()); // msaa: sampling sink, normal: this fb } else { gl.glBindFramebuffer(GL.GL_FRAMEBUFFER, getWriteFramebuffer()); // normal: read/write } @@ -2524,8 +2524,8 @@ public class FBObject { if(fullFBOSupport) { // default read/draw buffers, may utilize GLContext/GLDrawable override of // GLContext.getDefaultDrawFramebuffer() and GLContext.getDefaultReadFramebuffer() - gl.glBindFramebuffer(GL2ES3.GL_DRAW_FRAMEBUFFER, 0); - gl.glBindFramebuffer(GL2ES3.GL_READ_FRAMEBUFFER, 0); + gl.glBindFramebuffer(GL.GL_DRAW_FRAMEBUFFER, 0); + gl.glBindFramebuffer(GL.GL_READ_FRAMEBUFFER, 0); } else { gl.glBindFramebuffer(GL.GL_FRAMEBUFFER, 0); // default draw buffer } @@ -2594,8 +2594,8 @@ public class FBObject { if( checkError ) { checkPreGLError(gl); } - gl.glBindFramebuffer(GL2ES3.GL_READ_FRAMEBUFFER, fbName); // read from this MSAA fb - gl.glBindFramebuffer(GL2ES3.GL_DRAW_FRAMEBUFFER, samplingSink.getWriteFramebuffer()); // write to sampling sink + gl.glBindFramebuffer(GL.GL_READ_FRAMEBUFFER, fbName); // read from this MSAA fb + gl.glBindFramebuffer(GL.GL_DRAW_FRAMEBUFFER, samplingSink.getWriteFramebuffer()); // write to sampling sink ((GL2ES3)gl).glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, // since MSAA is supported, casting to GL2ES3 is OK GL.GL_COLOR_BUFFER_BIT, GL.GL_NEAREST); if( checkError ) { @@ -2607,8 +2607,8 @@ public class FBObject { if(fullFBOSupport) { // default read/draw buffers, may utilize GLContext/GLDrawable override of // GLContext.getDefaultDrawFramebuffer() and GLContext.getDefaultReadFramebuffer() - gl.glBindFramebuffer(GL2ES3.GL_DRAW_FRAMEBUFFER, 0); - gl.glBindFramebuffer(GL2ES3.GL_READ_FRAMEBUFFER, 0); + gl.glBindFramebuffer(GL.GL_DRAW_FRAMEBUFFER, 0); + gl.glBindFramebuffer(GL.GL_READ_FRAMEBUFFER, 0); } else { gl.glBindFramebuffer(GL.GL_FRAMEBUFFER, 0); // default draw buffer } diff --git a/src/jogl/classes/com/jogamp/opengl/GLBase.java b/src/jogl/classes/com/jogamp/opengl/GLBase.java index 19b7808fc..dee5f1488 100644 --- a/src/jogl/classes/com/jogamp/opengl/GLBase.java +++ b/src/jogl/classes/com/jogamp/opengl/GLBase.java @@ -61,19 +61,11 @@ package com.jogamp.opengl; * * <UL> * - * <LI> The memory allocators for the NVidia vertex_array_range (VAR) - * extension, in particular <code>wglAllocateMemoryNV</code> / - * <code>glXAllocateMemoryNV</code> and associated routines. {@link - * #glAllocateMemoryNV} has been provided for window system-independent - * access to VAR. {@link #isFunctionAvailable} will translate an argument - * of "glAllocateMemoryNV" or "glFreeMemoryNV" into the appropriate - * window system-specific name. </P> - * * <LI> WGL_ARB_pbuffer, WGL_ARB_pixel_format, and other * platform-specific pbuffer functionality; the availability of * pbuffers can be queried on Windows, X11 and Mac OS X platforms by * querying {@link #isExtensionAvailable} with an argument of - * "GL_ARB_pbuffer" or "GL_ARB_pixel_format". + * "GL_ARB_pbuffer" or "GL_ARB_pixel_format".</LI> * * </UL> <P> * @@ -232,6 +224,19 @@ public interface GLBase { public boolean isGLES3Compatible(); /** + * Indicates whether this GL object is compatible with the core OpenGL ES3.1 functionality. + * <p> + * Return true if the underlying context is an ES3 context ≥ 3.1 or implements + * the extension <code>GL_ARB_ES3_1_compatibility</code>, otherwise false. + * </p> + * <p> + * Includes [ GL ≥ 4.5, GL ≥ 3.1 w/ GL_ARB_ES3_1_compatibility and GLES3 ≥ 3.1 ] + * </p> + * @see GLContext#isGLES31Compatible() + */ + public boolean isGLES31Compatible(); + + /** * Indicates whether this GL object supports GLSL. * @see GLContext#hasGLSL() */ diff --git a/src/jogl/classes/com/jogamp/opengl/GLContext.java b/src/jogl/classes/com/jogamp/opengl/GLContext.java index 6366c4e37..5ecd5e1e1 100644 --- a/src/jogl/classes/com/jogamp/opengl/GLContext.java +++ b/src/jogl/classes/com/jogamp/opengl/GLContext.java @@ -193,10 +193,13 @@ public abstract class GLContext { // /** <code>GL_ARB_ES2_compatibility</code> 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 << 10; + protected static final int CTX_IMPL_ES2_COMPAT = 1 << 10; /** <code>GL_ARB_ES3_compatibility</code> 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 << 11; + protected static final int CTX_IMPL_ES3_COMPAT = 1 << 11; + + /** <code>GL_ARB_ES3_1_compatibility</code> implementation related: Context is compatible w/ ES3. Not a cache key. See {@link #isGLES31Compatible()}, {@link #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)}. */ + protected static final int CTX_IMPL_ES31_COMPAT = 1 << 12; /** * Context supports basic FBO, details see {@link #hasBasicFBOSupport()}. @@ -204,7 +207,7 @@ public abstract class GLContext { * @see #hasBasicFBOSupport() * @see #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile) */ - protected static final int CTX_IMPL_FBO = 1 << 12; + protected static final int CTX_IMPL_FBO = 1 << 13; /** * Context supports <code>OES_single_precision</code>, fp32, fixed function point (FFP) compatibility entry points, @@ -213,7 +216,7 @@ public abstract class GLContext { * @see #hasFP32CompatAPI() * @see #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile) */ - protected static final int CTX_IMPL_FP32_COMPAT_API = 1 << 13; + protected static final int CTX_IMPL_FP32_COMPAT_API = 1 << 14; private static final ThreadLocal<GLContext> currentContext = new ThreadLocal<GLContext>(); @@ -911,6 +914,17 @@ public abstract class GLContext { } /** + * Return true if this context is an ES3 context ≥ 3.1 or implements + * the extension <code>GL_ARB_ES3_1_compatibility</code>, otherwise false. + * <p> + * Includes [ GL ≥ 4.5, GL ≥ 3.1 w/ GL_ARB_ES3_1_compatibility and GLES3 ≥ 3.1 ] + * </p> + */ + public final boolean isGLES31Compatible() { + return 0 != ( ctxOptions & CTX_IMPL_ES31_COMPAT ) ; + } + + /** * @return true if impl. is a hardware rasterizer, otherwise false. * @see #isHardwareRasterizer(AbstractGraphicsDevice, GLProfile) * @see GLProfile#isHardwareRasterizer() @@ -988,7 +1002,7 @@ public abstract class GLContext { final GL gl = getGL(); final int[] val = new int[] { 0 } ; try { - gl.glGetIntegerv(GL2ES3.GL_MAX_SAMPLES, val, 0); + gl.glGetIntegerv(GL.GL_MAX_SAMPLES, val, 0); final int glerr = gl.glGetError(); if(GL.GL_NO_ERROR == glerr) { return val[0]; @@ -1958,6 +1972,29 @@ public abstract class GLContext { } return 0 != ( ctp[0] & CTX_IMPL_ES3_COMPAT ); } + /** + * Returns true if a ES3 ≥ 3.1 compatible profile is available, + * i.e. either a ≥ 4.5 context or a ≥ 3.1 context supporting <code>GL_ARB_ES3_1_compatibility</code>, + * otherwise false. + * <p> + * Includes [ GL ≥ 4.5, GL ≥ 3.1 w/ GL_ARB_ES3_1_compatibility and GLES3 ≥ 3.1 ] + * </p> + */ + public static final boolean isGLES31CompatibleAvailable(final AbstractGraphicsDevice device) { + final int major[] = { 0 }; + final int minor[] = { 0 }; + final int ctp[] = { 0 }; + boolean ok; + + ok = GLContext.getAvailableGLVersion(device, 3, GLContext.CTX_PROFILE_ES, major, minor, ctp); + if( !ok ) { + ok = GLContext.getAvailableGLVersion(device, 3, GLContext.CTX_PROFILE_CORE, major, minor, ctp); + } + if( !ok ) { + GLContext.getAvailableGLVersion(device, 3, GLContext.CTX_PROFILE_COMPAT, major, minor, ctp); + } + return 0 != ( ctp[0] & CTX_IMPL_ES31_COMPAT ); + } public static boolean isGL4bcAvailable(final AbstractGraphicsDevice device, final boolean isHardware[]) { return isGLVersionAvailable(device, 4, CTX_PROFILE_COMPAT, isHardware); diff --git a/src/jogl/classes/com/jogamp/opengl/GLExtensions.java b/src/jogl/classes/com/jogamp/opengl/GLExtensions.java index 1593da25c..1bf8071ea 100644 --- a/src/jogl/classes/com/jogamp/opengl/GLExtensions.java +++ b/src/jogl/classes/com/jogamp/opengl/GLExtensions.java @@ -52,6 +52,7 @@ public class GLExtensions { public static final String ARB_ES2_compatibility = "GL_ARB_ES2_compatibility"; public static final String ARB_ES3_compatibility = "GL_ARB_ES3_compatibility"; + public static final String ARB_ES3_1_compatibility = "GL_ARB_ES3_1_compatibility"; public static final String EXT_abgr = "GL_EXT_abgr"; public static final String OES_rgb8_rgba8 = "GL_OES_rgb8_rgba8"; diff --git a/src/jogl/classes/com/jogamp/opengl/JoglVersion.java b/src/jogl/classes/com/jogamp/opengl/JoglVersion.java index 5070f3e4e..af16348a8 100644 --- a/src/jogl/classes/com/jogamp/opengl/JoglVersion.java +++ b/src/jogl/classes/com/jogamp/opengl/JoglVersion.java @@ -29,7 +29,6 @@ package com.jogamp.opengl; import com.jogamp.common.GlueGenVersion; -import com.jogamp.opengl.*; import com.jogamp.common.os.Platform; import com.jogamp.common.util.VersionUtil; diff --git a/src/jogl/classes/com/jogamp/opengl/awt/GLJPanel.java b/src/jogl/classes/com/jogamp/opengl/awt/GLJPanel.java index 91b2f5e0c..5bf4c106c 100644 --- a/src/jogl/classes/com/jogamp/opengl/awt/GLJPanel.java +++ b/src/jogl/classes/com/jogamp/opengl/awt/GLJPanel.java @@ -1994,7 +1994,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing System.err.println(getThreadName()+": GLJPanel.OffscreenBackend.postGL.0.0: isGL2ES3, readBuffer 0x"+Integer.toHexString(gl2es3.getDefaultReadBuffer())); System.err.println(getThreadName()+": GLJPanel.OffscreenBackend.postGL.0.0: def-readBuffer 0x"+Integer.toHexString(gl2es3.getDefaultReadBuffer())); System.err.println(getThreadName()+": GLJPanel.OffscreenBackend.postGL.0.0: def-readFBO 0x"+Integer.toHexString(gl2es3.getDefaultReadFramebuffer())); - System.err.println(getThreadName()+": GLJPanel.OffscreenBackend.postGL.0.0: bound-readFBO 0x"+Integer.toHexString(gl2es3.getBoundFramebuffer(GL2ES3.GL_READ_FRAMEBUFFER))); + System.err.println(getThreadName()+": GLJPanel.OffscreenBackend.postGL.0.0: bound-readFBO 0x"+Integer.toHexString(gl2es3.getBoundFramebuffer(GL.GL_READ_FRAMEBUFFER))); } } @@ -2030,7 +2030,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing System.err.println(getThreadName()+": GLJPanel.OffscreenBackend.postGL.0.1: isGL2ES3, readBuffer 0x"+Integer.toHexString(gl.getDefaultReadBuffer())); System.err.println(getThreadName()+": GLJPanel.OffscreenBackend.postGL.0.1: def-readBuffer 0x"+Integer.toHexString(gl.getDefaultReadBuffer())); System.err.println(getThreadName()+": GLJPanel.OffscreenBackend.postGL.0.1: def-readFBO 0x"+Integer.toHexString(gl.getDefaultReadFramebuffer())); - System.err.println(getThreadName()+": GLJPanel.OffscreenBackend.postGL.0.1: bound-readFBO 0x"+Integer.toHexString(gl.getBoundFramebuffer(GL2ES3.GL_READ_FRAMEBUFFER))); + System.err.println(getThreadName()+": GLJPanel.OffscreenBackend.postGL.0.1: bound-readFBO 0x"+Integer.toHexString(gl.getBoundFramebuffer(GL.GL_READ_FRAMEBUFFER))); System.err.println(getThreadName()+": GLJPanel.OffscreenBackend.postGL.0.1: "+GLJPanel.this.getName()+" pixelAttribs "+pixelAttribs); } gl.glReadPixels(0, 0, panelWidth, panelHeight, pixelAttribs.format, pixelAttribs.type, readBackInts); @@ -2042,7 +2042,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing System.err.println(getThreadName()+": GLJPanel.OffscreenBackend.postGL.0.2: isGL2ES3, readBuffer 0x"+Integer.toHexString(gl.getDefaultReadBuffer())); System.err.println(getThreadName()+": GLJPanel.OffscreenBackend.postGL.0.2: def-readBuffer 0x"+Integer.toHexString(gl.getDefaultReadBuffer())); System.err.println(getThreadName()+": GLJPanel.OffscreenBackend.postGL.0.2: def-readFBO 0x"+Integer.toHexString(gl.getDefaultReadFramebuffer())); - System.err.println(getThreadName()+": GLJPanel.OffscreenBackend.postGL.0.2: bound-readFBO 0x"+Integer.toHexString(gl.getBoundFramebuffer(GL2ES3.GL_READ_FRAMEBUFFER))); + System.err.println(getThreadName()+": GLJPanel.OffscreenBackend.postGL.0.2: bound-readFBO 0x"+Integer.toHexString(gl.getBoundFramebuffer(GL.GL_READ_FRAMEBUFFER))); } if( viewportChange ) { gl.glViewport(usrViewport[0], usrViewport[1], usrViewport[2], usrViewport[3]); @@ -2391,8 +2391,8 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing gl.glBindTexture(fboTextureTarget, frameBufferTexture[0]); final int[] width = new int[1]; final int[] height = new int[1]; - gl.glGetTexLevelParameteriv(fboTextureTarget, 0, GL2GL3.GL_TEXTURE_WIDTH, width, 0); - gl.glGetTexLevelParameteriv(fboTextureTarget, 0, GL2GL3.GL_TEXTURE_HEIGHT, height, 0); + gl.glGetTexLevelParameteriv(fboTextureTarget, 0, GL2ES3.GL_TEXTURE_WIDTH, width, 0); + gl.glGetTexLevelParameteriv(fboTextureTarget, 0, GL2ES3.GL_TEXTURE_HEIGHT, height, 0); gl.glGenRenderbuffers(1, frameBufferDepthBuffer, 0); if (DEBUG) { diff --git a/src/jogl/classes/com/jogamp/opengl/util/GLBuffers.java b/src/jogl/classes/com/jogamp/opengl/util/GLBuffers.java index 6a2a02387..3340af8ab 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/GLBuffers.java +++ b/src/jogl/classes/com/jogamp/opengl/util/GLBuffers.java @@ -717,7 +717,7 @@ public class GLBuffers extends Buffers { break; case GL.GL_RGB: case GL2ES3.GL_RGB_INTEGER: - case GL2GL3.GL_BGR: + case GL.GL_BGR: case GL2GL3.GL_BGR_INTEGER: compCount = 3; break; diff --git a/src/jogl/classes/com/jogamp/opengl/util/GLPixelBuffer.java b/src/jogl/classes/com/jogamp/opengl/util/GLPixelBuffer.java index 4575de959..c82f63898 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/GLPixelBuffer.java +++ b/src/jogl/classes/com/jogamp/opengl/util/GLPixelBuffer.java @@ -270,7 +270,7 @@ public class GLPixelBuffer { break; } break; - case GL2GL3.GL_BGR: + case GL.GL_BGR: if( GL.GL_UNSIGNED_BYTE == glDataType ) { pixFmt = PixelFormat.BGR888; } @@ -392,7 +392,7 @@ public class GLPixelBuffer { break; case BGR888: if( glp.isGL2GL3() ) { - df = GL2GL3.GL_BGR; + df = GL.GL_BGR; } break; case RGBx8888: diff --git a/src/jogl/classes/com/jogamp/opengl/util/GLReadBufferUtil.java b/src/jogl/classes/com/jogamp/opengl/util/GLReadBufferUtil.java index c2067a9f2..cc3462f99 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/GLReadBufferUtil.java +++ b/src/jogl/classes/com/jogamp/opengl/util/GLReadBufferUtil.java @@ -176,7 +176,7 @@ public class GLReadBufferUtil { final int reqCompCount = hasAlpha ? 4 : 3; final PixelFormat.Composition hostPixelComp = pixelBufferProvider.getHostPixelComp(gl.getGLProfile(), reqCompCount); final GLPixelAttributes pixelAttribs = pixelBufferProvider.getAttributes(gl, reqCompCount, true); - final int componentCount = pixelAttribs.pfmt.comp.componenCount(); + final int componentCount = pixelAttribs.pfmt.comp.componentCount(); hasAlpha = 0 <= pixelAttribs.pfmt.comp.find(PixelFormat.CType.A); final int alignment = 4 == componentCount ? 4 : 1 ; final int internalFormat = 4 == componentCount ? GL.GL_RGBA : GL.GL_RGB; diff --git a/src/jogl/classes/com/jogamp/opengl/util/awt/AWTGLPixelBuffer.java b/src/jogl/classes/com/jogamp/opengl/util/awt/AWTGLPixelBuffer.java index 6b0b3784d..d2f89cb9b 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/awt/AWTGLPixelBuffer.java +++ b/src/jogl/classes/com/jogamp/opengl/util/awt/AWTGLPixelBuffer.java @@ -235,7 +235,7 @@ public class AWTGLPixelBuffer extends GLPixelBuffer { if( null == hostPixComp ) { throw new IllegalArgumentException("Null hostPixComp"); } - final int awtFormat = getAWTFormat(gl.getGLProfile(), hostPixComp.componenCount()); + final int awtFormat = getAWTFormat(gl.getGLProfile(), hostPixComp.componentCount()); final BufferedImage image = new BufferedImage(width, height, awtFormat); final int[] readBackIntBuffer = ((DataBufferInt) image.getRaster().getDataBuffer()).getData(); final Buffer ibuffer = IntBuffer.wrap( readBackIntBuffer ); @@ -291,7 +291,7 @@ public class AWTGLPixelBuffer extends GLPixelBuffer { r.dispose(); } r = allocateImpl(hostPixComp, pixelAttributes, pack, - getAWTFormat(gl.getGLProfile(), hostPixComp.componenCount()), width, height, depth, minByteSize); + getAWTFormat(gl.getGLProfile(), hostPixComp.componentCount()), width, height, depth, minByteSize); bufferMap.put(bufferKey, r); } return r; diff --git a/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderCode.java b/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderCode.java index bb1c5e9b1..f8a66fe45 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderCode.java +++ b/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderCode.java @@ -136,8 +136,8 @@ public class ShaderCode { case GL2ES2.GL_VERTEX_SHADER: case GL2ES2.GL_FRAGMENT_SHADER: case GL3.GL_GEOMETRY_SHADER: - case GL4.GL_TESS_CONTROL_SHADER: - case GL4.GL_TESS_EVALUATION_SHADER: + case GL3.GL_TESS_CONTROL_SHADER: + case GL3.GL_TESS_EVALUATION_SHADER: break; default: throw new GLException("Unknown shader type: "+type); @@ -166,8 +166,8 @@ public class ShaderCode { case GL2ES2.GL_VERTEX_SHADER: case GL2ES2.GL_FRAGMENT_SHADER: case GL3.GL_GEOMETRY_SHADER: - case GL4.GL_TESS_CONTROL_SHADER: - case GL4.GL_TESS_EVALUATION_SHADER: + case GL3.GL_TESS_CONTROL_SHADER: + case GL3.GL_TESS_EVALUATION_SHADER: break; default: throw new GLException("Unknown shader type: "+type); @@ -292,9 +292,9 @@ public class ShaderCode { return binary?SUFFIX_FRAGMENT_BINARY:SUFFIX_FRAGMENT_SOURCE; case GL3.GL_GEOMETRY_SHADER: return binary?SUFFIX_GEOMETRY_BINARY:SUFFIX_GEOMETRY_SOURCE; - case GL4.GL_TESS_CONTROL_SHADER: + case GL3.GL_TESS_CONTROL_SHADER: return binary?SUFFIX_TESS_CONTROL_BINARY:SUFFIX_TESS_CONTROL_SOURCE; - case GL4.GL_TESS_EVALUATION_SHADER: + case GL3.GL_TESS_EVALUATION_SHADER: return binary?SUFFIX_TESS_EVALUATION_BINARY:SUFFIX_TESS_EVALUATION_SOURCE; default: throw new GLException("illegal shader type: "+type); @@ -520,9 +520,9 @@ public class ShaderCode { return "FRAGMENT_SHADER"; case GL3.GL_GEOMETRY_SHADER: return "GEOMETRY_SHADER"; - case GL4.GL_TESS_CONTROL_SHADER: + case GL3.GL_TESS_CONTROL_SHADER: return "TESS_CONTROL_SHADER"; - case GL4.GL_TESS_EVALUATION_SHADER: + case GL3.GL_TESS_EVALUATION_SHADER: return "TESS_EVALUATION_SHADER"; } return "UNKNOWN_SHADER"; @@ -1019,8 +1019,8 @@ public class ShaderCode { switch ( shaderType ) { case GL2ES2.GL_VERTEX_SHADER: case GL3.GL_GEOMETRY_SHADER: - case GL4.GL_TESS_CONTROL_SHADER: - case GL4.GL_TESS_EVALUATION_SHADER: + case GL3.GL_TESS_CONTROL_SHADER: + case GL3.GL_TESS_EVALUATION_SHADER: defaultPrecision = gl3_default_precision_vp_gp; break; case GL2ES2.GL_FRAGMENT_SHADER: defaultPrecision = gl3_default_precision_fp; break; diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/TextureData.java b/src/jogl/classes/com/jogamp/opengl/util/texture/TextureData.java index ce1acc6d7..615d8c24f 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/texture/TextureData.java +++ b/src/jogl/classes/com/jogamp/opengl/util/texture/TextureData.java @@ -42,7 +42,6 @@ import java.nio.Buffer; import com.jogamp.opengl.GLProfile; import com.jogamp.common.nio.Buffers; -import com.jogamp.opengl.util.GLBuffers; import com.jogamp.opengl.util.GLPixelBuffer.GLPixelAttributes; /** diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/TextureIO.java b/src/jogl/classes/com/jogamp/opengl/util/texture/TextureIO.java index 27571ae0d..54a552f33 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/texture/TextureIO.java +++ b/src/jogl/classes/com/jogamp/opengl/util/texture/TextureIO.java @@ -60,6 +60,7 @@ import com.jogamp.nativewindow.util.DimensionImmutable; import com.jogamp.nativewindow.util.PixelFormat; import com.jogamp.opengl.GL; import com.jogamp.opengl.GL2; +import com.jogamp.opengl.GL2ES3; import com.jogamp.opengl.GL2GL3; import com.jogamp.opengl.GLContext; import com.jogamp.opengl.GLException; @@ -597,9 +598,9 @@ public class TextureIO { final GL2GL3 gl = _gl.getGL2GL3(); texture.bind(gl); - final int internalFormat = glGetTexLevelParameteri(gl, GL.GL_TEXTURE_2D, 0, GL2GL3.GL_TEXTURE_INTERNAL_FORMAT); - final int width = glGetTexLevelParameteri(gl, GL.GL_TEXTURE_2D, 0, GL2GL3.GL_TEXTURE_WIDTH); - final int height = glGetTexLevelParameteri(gl, GL.GL_TEXTURE_2D, 0, GL2GL3.GL_TEXTURE_HEIGHT); + final int internalFormat = glGetTexLevelParameteri(gl, GL.GL_TEXTURE_2D, 0, GL2ES3.GL_TEXTURE_INTERNAL_FORMAT); + final int width = glGetTexLevelParameteri(gl, GL.GL_TEXTURE_2D, 0, GL2ES3.GL_TEXTURE_WIDTH); + final int height = glGetTexLevelParameteri(gl, GL.GL_TEXTURE_2D, 0, GL2ES3.GL_TEXTURE_HEIGHT); final int border = glGetTexLevelParameteri(gl, GL.GL_TEXTURE_2D, 0, GL2.GL_TEXTURE_BORDER); TextureData data = null; if (internalFormat == GL.GL_COMPRESSED_RGB_S3TC_DXT1_EXT || @@ -617,7 +618,7 @@ public class TextureIO { int fetchedFormat = 0; switch (internalFormat) { case GL.GL_RGB: - case GL2GL3.GL_BGR: + case GL.GL_BGR: case GL.GL_RGB8: bytesPerPixel = 3; fetchedFormat = GL.GL_RGB; @@ -1303,7 +1304,7 @@ public class TextureIO { final int pixelType = pixelAttribs.type; if ((pixelFormat == GL.GL_RGB || pixelFormat == GL.GL_RGBA || - pixelFormat == GL2GL3.GL_BGR || + pixelFormat == GL.GL_BGR || pixelFormat == GL.GL_BGRA ) && (pixelType == GL.GL_BYTE || pixelType == GL.GL_UNSIGNED_BYTE)) { diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/TextureState.java b/src/jogl/classes/com/jogamp/opengl/util/texture/TextureState.java index 1866c5921..12332dbe7 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/texture/TextureState.java +++ b/src/jogl/classes/com/jogamp/opengl/util/texture/TextureState.java @@ -29,8 +29,8 @@ package com.jogamp.opengl.util.texture; import com.jogamp.opengl.GL; import com.jogamp.opengl.GL2ES2; +import com.jogamp.opengl.GL2ES3; import com.jogamp.opengl.GL2GL3; -import com.jogamp.opengl.GL3; import com.jogamp.opengl.GLException; /** @@ -61,11 +61,11 @@ public class TextureState { case GL2ES2.GL_TEXTURE_3D: texBindQName = GL2ES2.GL_TEXTURE_BINDING_3D; break; case GL2GL3.GL_TEXTURE_1D: texBindQName = GL2GL3.GL_TEXTURE_BINDING_1D; break; case GL2GL3.GL_TEXTURE_1D_ARRAY: texBindQName = GL2GL3.GL_TEXTURE_BINDING_1D_ARRAY; break; - case GL.GL_TEXTURE_2D_ARRAY: texBindQName = GL.GL_TEXTURE_BINDING_2D_ARRAY; break; + case GL2ES3.GL_TEXTURE_2D_ARRAY: texBindQName = GL2ES3.GL_TEXTURE_BINDING_2D_ARRAY; break; case GL2GL3.GL_TEXTURE_RECTANGLE: texBindQName = GL2GL3.GL_TEXTURE_BINDING_RECTANGLE; break; case GL2GL3.GL_TEXTURE_BUFFER: texBindQName = GL2GL3.GL_TEXTURE_BINDING_BUFFER; break; - case GL3.GL_TEXTURE_2D_MULTISAMPLE: texBindQName = GL3.GL_TEXTURE_BINDING_2D_MULTISAMPLE; break; - case GL3.GL_TEXTURE_2D_MULTISAMPLE_ARRAY: texBindQName = GL3.GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY; break; + case GL2ES2.GL_TEXTURE_2D_MULTISAMPLE: texBindQName = GL2ES2.GL_TEXTURE_BINDING_2D_MULTISAMPLE; break; + case GL2ES2.GL_TEXTURE_2D_MULTISAMPLE_ARRAY: texBindQName = GL2ES2.GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY; break; default: texBindQName = 0; } return texBindQName; diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/awt/AWTTextureData.java b/src/jogl/classes/com/jogamp/opengl/util/texture/awt/AWTTextureData.java index aa0be8e9b..692061cec 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/texture/awt/AWTTextureData.java +++ b/src/jogl/classes/com/jogamp/opengl/util/texture/awt/AWTTextureData.java @@ -232,7 +232,7 @@ public class AWTTextureData extends TextureData { // we can pass the image data directly to OpenGL only if // we have an integral number of pixels in each scanline if ((scanlineStride % 3) == 0) { - pixelAttributes = new GLPixelAttributes(GL2GL3.GL_BGR, GL.GL_UNSIGNED_BYTE); + pixelAttributes = new GLPixelAttributes(GL.GL_BGR, GL.GL_UNSIGNED_BYTE); rowLength = scanlineStride / 3; alignment = 1; } else { diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/spi/NetPbmTextureWriter.java b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/NetPbmTextureWriter.java index 700de593f..99954ae86 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/texture/spi/NetPbmTextureWriter.java +++ b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/NetPbmTextureWriter.java @@ -44,7 +44,6 @@ import java.nio.*; import java.nio.channels.FileChannel; import com.jogamp.opengl.*; - import com.jogamp.common.util.IOUtil; import com.jogamp.opengl.util.texture.*; @@ -112,7 +111,7 @@ public class NetPbmTextureWriter implements TextureWriter { final int pixelType = data.getPixelType(); if ((pixelFormat == GL.GL_RGB || pixelFormat == GL.GL_RGBA || - pixelFormat == GL2GL3.GL_BGR || + pixelFormat == GL.GL_BGR || pixelFormat == GL.GL_BGRA ) && (pixelType == GL.GL_BYTE || pixelType == GL.GL_UNSIGNED_BYTE)) { @@ -125,7 +124,7 @@ public class NetPbmTextureWriter implements TextureWriter { final int comps = ( pixelFormat == GL.GL_RGBA || pixelFormat == GL.GL_BGRA ) ? 4 : 3 ; - if( pixelFormat == GL2GL3.GL_BGR || pixelFormat == GL.GL_BGRA ) { + if( pixelFormat == GL.GL_BGR || pixelFormat == GL.GL_BGRA ) { // Must reverse order of red and blue channels to get correct results for (int i = 0; i < buf.remaining(); i += comps) { final byte red = buf.get(i + 0); diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/spi/TGAImage.java b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/TGAImage.java index bb872714c..831927a90 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/texture/spi/TGAImage.java +++ b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/TGAImage.java @@ -42,8 +42,8 @@ package com.jogamp.opengl.util.texture.spi; import java.io.*; import java.nio.*; import java.nio.channels.*; -import com.jogamp.opengl.*; +import com.jogamp.opengl.*; import com.jogamp.common.util.IOUtil; /** @@ -352,7 +352,7 @@ public class TGAImage { bpp = header.pixelDepth / 8; switch (header.pixelDepth) { case 24: - format = glp.isGL2GL3() ? GL2GL3.GL_BGR : GL.GL_RGB; + format = glp.isGL2GL3() ? GL.GL_BGR : GL.GL_RGB; break; case 32: boolean useBGRA = glp.isGL2GL3(); diff --git a/src/jogl/classes/jogamp/opengl/GLBufferStateTracker.java b/src/jogl/classes/jogamp/opengl/GLBufferStateTracker.java index 0742f7b05..2aa4c4297 100644 --- a/src/jogl/classes/jogamp/opengl/GLBufferStateTracker.java +++ b/src/jogl/classes/jogamp/opengl/GLBufferStateTracker.java @@ -41,7 +41,6 @@ package jogamp.opengl; import com.jogamp.opengl.*; - import com.jogamp.common.util.IntIntHashMap; import com.jogamp.common.util.PropertyAccess; @@ -103,7 +102,7 @@ public class GLBufferStateTracker { // Start with known unbound targets for known keys // setBoundBufferObject(GL2ES3.GL_VERTEX_ARRAY_BINDING, 0); // not using default VAO (removed in GL3 core) - only explicit setBoundBufferObject(GL.GL_ARRAY_BUFFER, 0); - setBoundBufferObject(GL4.GL_DRAW_INDIRECT_BUFFER, 0); + setBoundBufferObject(GL3ES3.GL_DRAW_INDIRECT_BUFFER, 0); setBoundBufferObject(GL.GL_ELEMENT_ARRAY_BUFFER, 0); setBoundBufferObject(GL2ES3.GL_PIXEL_PACK_BUFFER, 0); setBoundBufferObject(GL2ES3.GL_PIXEL_UNPACK_BUFFER, 0); @@ -131,16 +130,16 @@ public class GLBufferStateTracker { private static final int getQueryName(final int target) { switch (target) { case GL.GL_ARRAY_BUFFER: return GL.GL_ARRAY_BUFFER_BINDING; - case GL4.GL_ATOMIC_COUNTER_BUFFER: return GL4.GL_ATOMIC_COUNTER_BUFFER_BINDING; + case GL2ES3.GL_ATOMIC_COUNTER_BUFFER: return GL2ES3.GL_ATOMIC_COUNTER_BUFFER_BINDING; case GL2ES3.GL_COPY_READ_BUFFER: return GL2ES3.GL_COPY_READ_BUFFER_BINDING; case GL2ES3.GL_COPY_WRITE_BUFFER: return GL2ES3.GL_COPY_WRITE_BUFFER_BINDING; - case GL4.GL_DRAW_INDIRECT_BUFFER: return GL4.GL_DRAW_INDIRECT_BUFFER_BINDING; - case GL4.GL_DISPATCH_INDIRECT_BUFFER: return GL4.GL_DISPATCH_INDIRECT_BUFFER_BINDING; + case GL3ES3.GL_DRAW_INDIRECT_BUFFER: return GL3ES3.GL_DRAW_INDIRECT_BUFFER_BINDING; + case GL3ES3.GL_DISPATCH_INDIRECT_BUFFER: return GL3ES3.GL_DISPATCH_INDIRECT_BUFFER_BINDING; case GL.GL_ELEMENT_ARRAY_BUFFER: return GL.GL_ELEMENT_ARRAY_BUFFER_BINDING; - case GL2ES3.GL_PIXEL_PACK_BUFFER: return GL2ES3.GL_PIXEL_PACK_BUFFER_BINDING; - case GL2ES3.GL_PIXEL_UNPACK_BUFFER: return GL2ES3.GL_PIXEL_UNPACK_BUFFER_BINDING; - // FIXME case GL4.GL_QUERY_BUFFER: return GL4.GL_QUERY_BUFFER_BINDING; - case GL4.GL_SHADER_STORAGE_BUFFER: return GL4.GL_SHADER_STORAGE_BUFFER_BINDING; + case GL2ES3.GL_PIXEL_PACK_BUFFER: return GL2ES3.GL_PIXEL_PACK_BUFFER_BINDING; + case GL2ES3.GL_PIXEL_UNPACK_BUFFER: return GL2ES3.GL_PIXEL_UNPACK_BUFFER_BINDING; + case GL4.GL_QUERY_BUFFER: return GL4.GL_QUERY_BUFFER_BINDING; + case GL3ES3.GL_SHADER_STORAGE_BUFFER: return GL3ES3.GL_SHADER_STORAGE_BUFFER_BINDING; case GL2GL3.GL_TEXTURE_BUFFER: return GL2GL3.GL_TEXTURE_BINDING_BUFFER; case GL2ES3.GL_TRANSFORM_FEEDBACK_BUFFER: return GL2ES3.GL_TRANSFORM_FEEDBACK_BUFFER_BINDING; case GL2ES3.GL_UNIFORM_BUFFER: return GL2ES3.GL_UNIFORM_BUFFER_BINDING; @@ -154,16 +153,16 @@ public class GLBufferStateTracker { private static final void checkTargetName(final int target) { switch (target) { case GL.GL_ARRAY_BUFFER: - case GL4.GL_ATOMIC_COUNTER_BUFFER: + case GL2ES3.GL_ATOMIC_COUNTER_BUFFER: case GL2ES3.GL_COPY_READ_BUFFER: case GL2ES3.GL_COPY_WRITE_BUFFER: - case GL4.GL_DRAW_INDIRECT_BUFFER: - case GL4.GL_DISPATCH_INDIRECT_BUFFER: + case GL3ES3.GL_DRAW_INDIRECT_BUFFER: + case GL3ES3.GL_DISPATCH_INDIRECT_BUFFER: case GL.GL_ELEMENT_ARRAY_BUFFER: case GL2ES3.GL_PIXEL_PACK_BUFFER: case GL2ES3.GL_PIXEL_UNPACK_BUFFER: - // FIXME case GL4.GL_QUERY_BUFFER: - case GL4.GL_SHADER_STORAGE_BUFFER: + case GL4.GL_QUERY_BUFFER: + case GL3ES3.GL_SHADER_STORAGE_BUFFER: case GL2GL3.GL_TEXTURE_BUFFER: case GL2ES3.GL_TRANSFORM_FEEDBACK_BUFFER: case GL2ES3.GL_UNIFORM_BUFFER: diff --git a/src/jogl/classes/jogamp/opengl/GLContextImpl.java b/src/jogl/classes/jogamp/opengl/GLContextImpl.java index 1ff64725a..c56dc74da 100644 --- a/src/jogl/classes/jogamp/opengl/GLContextImpl.java +++ b/src/jogl/classes/jogamp/opengl/GLContextImpl.java @@ -41,7 +41,6 @@ package jogamp.opengl; import java.lang.reflect.Method; -import java.nio.ByteBuffer; import java.nio.IntBuffer; import java.security.AccessController; import java.security.PrivilegedAction; @@ -1315,32 +1314,15 @@ public abstract class GLContextImpl extends GLContext { */ public abstract ProcAddressTable getPlatformExtProcAddressTable(); - /** - * Part of <code>GL_NV_vertex_array_range</code>. - * <p> - * Provides platform-independent access to the <code>wglAllocateMemoryNV</code> / - * <code>glXAllocateMemoryNV</code>. - * </p> - */ - public abstract ByteBuffer glAllocateMemoryNV(int size, float readFrequency, float writeFrequency, float priority); - - /** - * Part of <code>GL_NV_vertex_array_range</code>. - * <p> - * Provides platform-independent access to the <code>wglFreeMemoryNV</code> / - * <code>glXFreeMemoryNV</code>. - * </p> - */ - public abstract void glFreeMemoryNV(ByteBuffer pointer); - /** Maps the given "platform-independent" function name to a real function - name. Currently this is only used to map "glAllocateMemoryNV" and - associated routines to wglAllocateMemoryNV / glXAllocateMemoryNV. */ + name. Currently not used. */ protected final String mapToRealGLFunctionName(final String glFunctionName) { final Map<String, String> map = getFunctionNameMap(); - final String lookup = ( null != map ) ? map.get(glFunctionName) : null; - if (lookup != null) { - return lookup; + if( null != map ) { + final String lookup = map.get(glFunctionName); + if (lookup != null) { + return lookup; + } } return glFunctionName; } @@ -1353,9 +1335,11 @@ public abstract class GLContextImpl extends GLContext { */ protected final String mapToRealGLExtensionName(final String glExtensionName) { final Map<String, String> map = getExtensionNameMap(); - final String lookup = ( null != map ) ? map.get(glExtensionName) : null; - if (lookup != null) { - return lookup; + if( null != map ) { + final String lookup = map.get(glExtensionName); + if (lookup != null) { + return lookup; + } } return glExtensionName; } @@ -1673,7 +1657,7 @@ public abstract class GLContextImpl extends GLContext { } if( major < 2 ) { // there is no ES2/3-compat for a profile w/ major < 2 - ctxProfileBits &= ~ ( GLContext.CTX_IMPL_ES2_COMPAT | GLContext.CTX_IMPL_ES3_COMPAT ) ; + ctxProfileBits &= ~ ( GLContext.CTX_IMPL_ES2_COMPAT | GLContext.CTX_IMPL_ES3_COMPAT | GLContext.CTX_IMPL_ES31_COMPAT ) ; } if(!isCurrentContextHardwareRasterizer()) { @@ -1767,10 +1751,19 @@ public abstract class GLContextImpl extends GLContext { if( major >= 3 ) { ctxProfileBits |= CTX_IMPL_ES3_COMPAT | CTX_IMPL_ES2_COMPAT ; ctxProfileBits |= CTX_IMPL_FBO; + if( minor >= 1 ) { + ctxProfileBits |= CTX_IMPL_ES31_COMPAT; + } } else if( major >= 2 ) { ctxProfileBits |= CTX_IMPL_ES2_COMPAT; ctxProfileBits |= CTX_IMPL_FBO; } + } else if( ( major > 4 || major == 4 && minor >= 5 ) || + ( ( major > 3 || major == 3 && minor >= 1 ) && isExtensionAvailable( GLExtensions.ARB_ES3_1_compatibility ) ) ) { + // See GLContext.isGLES31CompatibleAvailable(..)/isGLES31Compatible() + // Includes [ GL ≥ 4.5, GL ≥ 3.1 w/ GL_ARB_ES3_1_compatibility and GLES ≥ 3.1 ] + ctxProfileBits |= CTX_IMPL_ES31_COMPAT | CTX_IMPL_ES3_COMPAT | CTX_IMPL_ES2_COMPAT ; + ctxProfileBits |= CTX_IMPL_FBO; } else if( ( major > 4 || major == 4 && minor >= 3 ) || ( ( major > 3 || major == 3 && minor >= 1 ) && isExtensionAvailable( GLExtensions.ARB_ES3_compatibility ) ) ) { // See GLContext.isGLES3CompatibleAvailable(..)/isGLES3Compatible() @@ -2443,10 +2436,10 @@ public abstract class GLContextImpl extends GLContext { } switch(target) { case GL.GL_FRAMEBUFFER: - case GL2ES3.GL_DRAW_FRAMEBUFFER: + case GL.GL_DRAW_FRAMEBUFFER: boundFBOTarget[0] = framebufferName; // draw break; - case GL2ES3.GL_READ_FRAMEBUFFER: + case GL.GL_READ_FRAMEBUFFER: boundFBOTarget[1] = framebufferName; // read break; default: // ignore untracked target @@ -2456,9 +2449,9 @@ public abstract class GLContextImpl extends GLContext { public final int getBoundFramebuffer(final int target) { switch(target) { case GL.GL_FRAMEBUFFER: - case GL2ES3.GL_DRAW_FRAMEBUFFER: + case GL.GL_DRAW_FRAMEBUFFER: return boundFBOTarget[0]; // draw - case GL2ES3.GL_READ_FRAMEBUFFER: + case GL.GL_READ_FRAMEBUFFER: return boundFBOTarget[1]; // read default: throw new InternalError("Invalid FBO target name: "+toHexString(target)); diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLContext.java b/src/jogl/classes/jogamp/opengl/egl/EGLContext.java index 910afcd22..9d7ad64f9 100644 --- a/src/jogl/classes/jogamp/opengl/egl/EGLContext.java +++ b/src/jogl/classes/jogamp/opengl/egl/EGLContext.java @@ -36,7 +36,6 @@ package jogamp.opengl.egl; -import java.nio.ByteBuffer; import java.nio.IntBuffer; import java.util.Map; @@ -507,14 +506,4 @@ public class EGLContext extends GLContextImpl { protected void copyImpl(final GLContext source, final int mask) throws GLException { throw new GLException("Not yet implemented"); } - - @Override - public final ByteBuffer glAllocateMemoryNV(final int size, final float readFrequency, final float writeFrequency, final float priority) { - throw new GLException("Should not call this"); - } - - @Override - public final void glFreeMemoryNV(final ByteBuffer pointer) { - throw new GLException("Should not call this"); - } } diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java index 51b243f37..3c22e612f 100644 --- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java +++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java @@ -40,7 +40,6 @@ package jogamp.opengl.macosx.cgl; -import java.nio.ByteBuffer; import java.nio.IntBuffer; import java.util.Map; @@ -422,18 +421,6 @@ public class MacOSXCGLContext extends GLContextImpl } @Override - public final ByteBuffer glAllocateMemoryNV(final int size, final float readFrequency, final float writeFrequency, final float priority) { - // FIXME: apparently the Apple extension doesn't require a custom memory allocator - throw new GLException("Not yet implemented"); - } - - @Override - public final void glFreeMemoryNV(final ByteBuffer pointer) { - // FIXME: apparently the Apple extension doesn't require a custom memory allocator - throw new GLException("Not yet implemented"); - } - - @Override protected final void updateGLXProcAddressTable() { final AbstractGraphicsConfiguration aconfig = drawable.getNativeSurface().getGraphicsConfiguration(); final AbstractGraphicsDevice adevice = aconfig.getScreen().getDevice(); diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java index ec4575a9c..966a4dcf5 100644 --- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java +++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java @@ -40,7 +40,6 @@ package jogamp.opengl.windows.wgl; -import java.nio.ByteBuffer; import java.nio.IntBuffer; import java.util.HashMap; import java.util.Map; @@ -63,7 +62,6 @@ import jogamp.opengl.GLContextImpl; import jogamp.opengl.GLDrawableImpl; public class WindowsWGLContext extends GLContextImpl { - static final Map<String, String> functionNameMap; static final Map<String, String> extensionNameMap; private boolean wglGetExtensionsStringEXTInitialized; private boolean wglGetExtensionsStringEXTAvailable; @@ -77,10 +75,6 @@ public class WindowsWGLContext extends GLContextImpl { private int hasSwapGroupNV = 0; static { - functionNameMap = new HashMap<String, String>(); - functionNameMap.put("glAllocateMemoryNV", "wglAllocateMemoryNV"); - functionNameMap.put("glFreeMemoryNV", "wglFreeMemoryNV"); - extensionNameMap = new HashMap<String, String>(); extensionNameMap.put(GLExtensions.ARB_pbuffer, WindowsWGLDrawableFactory.WGL_ARB_pbuffer); extensionNameMap.put(GLExtensions.ARB_pixel_format, WindowsWGLDrawableFactory.WGL_ARB_pixel_format); @@ -192,7 +186,7 @@ public class WindowsWGLContext extends GLContextImpl { } @Override - protected Map<String, String> getFunctionNameMap() { return functionNameMap; } + protected Map<String, String> getFunctionNameMap() { return null; } @Override protected Map<String, String> getExtensionNameMap() { return extensionNameMap; } @@ -572,15 +566,4 @@ public class WindowsWGLContext extends GLContextImpl { } return res; } - - @Override - public final ByteBuffer glAllocateMemoryNV(final int size, final float readFrequency, final float writeFrequency, final float priority) { - return getWGLExt().wglAllocateMemoryNV(size, readFrequency, writeFrequency, priority); - } - - @Override - public final void glFreeMemoryNV(final ByteBuffer pointer) { - getWGLExt().wglFreeMemoryNV(pointer); - } - } diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java index 19056a73b..4665dc17c 100644 --- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java +++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java @@ -40,7 +40,6 @@ package jogamp.opengl.x11.glx; -import java.nio.ByteBuffer; import java.nio.IntBuffer; import java.util.HashMap; import java.util.Map; @@ -68,7 +67,6 @@ import com.jogamp.nativewindow.x11.X11GraphicsDevice; import com.jogamp.opengl.GLExtensions; public class X11GLXContext extends GLContextImpl { - private static final Map<String, String> functionNameMap; private static final Map<String, String> extensionNameMap; private GLXExt _glXExt; // Table that holds the addresses of the native C-language entry points for @@ -86,10 +84,6 @@ public class X11GLXContext extends GLContextImpl { protected volatile boolean isGLXVersionGreaterEqualOneThree; static { - functionNameMap = new HashMap<String, String>(); - functionNameMap.put("glAllocateMemoryNV", "glXAllocateMemoryNV"); - functionNameMap.put("glFreeMemoryNV", "glXFreeMemoryNV"); - extensionNameMap = new HashMap<String, String>(); extensionNameMap.put(GLExtensions.ARB_pbuffer, X11GLXDrawableFactory.GLX_SGIX_pbuffer); extensionNameMap.put(GLExtensions.ARB_pixel_format, X11GLXDrawableFactory.GLX_SGIX_pbuffer); // good enough @@ -134,7 +128,7 @@ public class X11GLXContext extends GLContextImpl { } @Override - protected Map<String, String> getFunctionNameMap() { return functionNameMap; } + protected Map<String, String> getFunctionNameMap() { return null; } @Override protected Map<String, String> getExtensionNameMap() { return extensionNameMap; } @@ -647,16 +641,6 @@ public class X11GLXContext extends GLContextImpl { } @Override - public final ByteBuffer glAllocateMemoryNV(final int size, final float readFrequency, final float writeFrequency, final float priority) { - return getGLXExt().glXAllocateMemoryNV(size, readFrequency, writeFrequency, priority); - } - - @Override - public final void glFreeMemoryNV(final ByteBuffer pointer) { - getGLXExt().glXFreeMemoryNV(pointer); - } - - @Override public String toString() { final StringBuilder sb = new StringBuilder(); sb.append(getClass().getSimpleName()); diff --git a/src/jogl/native/EGLContext.c b/src/jogl/native/EGLContext.c index 7bf60b850..fac0670e6 100644 --- a/src/jogl/native/EGLContext.c +++ b/src/jogl/native/EGLContext.c @@ -16,10 +16,11 @@ */ JNIEXPORT jlong JNICALL Java_jogamp_opengl_egl_EGLContext_dispatch_1eglGetProcAddress0__Ljava_lang_String_2J(JNIEnv *env, jclass _unused, jstring procname, jlong procAddress) { - typedef __EGLFuncPtr (EGLAPIENTRY*_local_PFNEGLGETPROCADDRESSPROC)(const char * procname); + typedef void (* EGLAPIENTRY _local_EGLFuncPtr)(void); + typedef _local_EGLFuncPtr (EGLAPIENTRY*_local_PFNEGLGETPROCADDRESSPROC)(const char * procname); _local_PFNEGLGETPROCADDRESSPROC ptr_eglGetProcAddress; const char* _strchars_procname = NULL; - __EGLFuncPtr _res; + _local_EGLFuncPtr _res; if ( NULL != procname ) { _strchars_procname = (*env)->GetStringUTFChars(env, procname, (jboolean*)NULL); if ( NULL == _strchars_procname ) { diff --git a/src/jogl/native/GLDebugMessageHandler.c b/src/jogl/native/GLDebugMessageHandler.c index 0aa7a01e7..5c18b94b1 100644 --- a/src/jogl/native/GLDebugMessageHandler.c +++ b/src/jogl/native/GLDebugMessageHandler.c @@ -21,11 +21,11 @@ static jmethodID glDebugMessageARB = NULL; // int source, int type, int id, int severity, String msg static jmethodID glDebugMessageAMD = NULL; // int id, int category, int severity, String msg -typedef void (APIENTRY* _local_PFNGLDEBUGMESSAGECALLBACKARBPROC) (GLDEBUGPROCARB callback, const GLvoid *userParam); -typedef void (APIENTRY* _local_GLDEBUGPROCARB)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,GLvoid *userParam); +typedef void (APIENTRY* _local_GLDEBUGPROCARB)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); +typedef void (APIENTRY* _local_PFNGLDEBUGMESSAGECALLBACKARBPROC) (_local_GLDEBUGPROCARB callback, const void *userParam); -typedef void (APIENTRY* _local_PFNGLDEBUGMESSAGECALLBACKAMDPROC) (GLDEBUGPROCAMD callback, const GLvoid *userParam); -typedef void (APIENTRY* _local_GLDEBUGPROCAMD)(GLuint id,GLenum category,GLenum severity,GLsizei length,const GLchar *message,GLvoid *userParam); +typedef void (APIENTRY* _local_GLDEBUGPROCAMD)(GLuint id,GLenum category,GLenum severity,GLsizei length,const GLchar *message,void *userParam); +typedef void (APIENTRY* _local_PFNGLDEBUGMESSAGECALLBACKAMDPROC) (_local_GLDEBUGPROCAMD callback, void *userParam); /* * Class: jogamp_opengl_GLDebugMessageHandler diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/NativeWindowFactory.java b/src/nativewindow/classes/com/jogamp/nativewindow/NativeWindowFactory.java index cba3a9214..d01e3a203 100644 --- a/src/nativewindow/classes/com/jogamp/nativewindow/NativeWindowFactory.java +++ b/src/nativewindow/classes/com/jogamp/nativewindow/NativeWindowFactory.java @@ -70,8 +70,11 @@ import com.jogamp.nativewindow.x11.X11GraphicsScreen; adapt their components to the {@link NativeWindow} interface, which provides a platform-independent mechanism of accessing the information required to perform operations like - hardware-accelerated rendering using the OpenGL API. */ - + hardware-accelerated rendering using the OpenGL API. + * <p> + * FIXME: Bug 973 Needs service provider interface (SPI) for TK dependent implementation + * </p> + */ public abstract class NativeWindowFactory { protected static final boolean DEBUG; @@ -421,6 +424,9 @@ public abstract class NativeWindowFactory { } /** Don't know if we shall add this factory here .. + * <p> + * FIXME: Bug 973 Needs service provider interface (SPI) for TK dependent implementation + * </p> public static AbstractGraphicsDevice createGraphicsDevice(String type, String connection, int unitID, long handle, ToolkitLock locker) { if(TYPE_EGL == type) { return new @@ -632,6 +638,9 @@ public abstract class NativeWindowFactory { * If the visualID is {@link VisualIDHolder#VID_UNDEFINED} and the platform requires it * at creation time (see above), it is not valid for further processing. * </p> + * <p> + * FIXME: Bug 973 Needs service provider interface (SPI) for TK dependent implementation + * </p> */ public static boolean isNativeVisualIDValidForProcessing(final int visualID) { return NativeWindowFactory.TYPE_X11 != NativeWindowFactory.getNativeWindowType(false) || @@ -645,7 +654,18 @@ public abstract class NativeWindowFactory { * </p> */ public static AbstractGraphicsDevice createDevice(final String displayConnection, final boolean own) { - final String nwt = NativeWindowFactory.getNativeWindowType(true); + return createDevice(NativeWindowFactory.getNativeWindowType(true), displayConnection, own); + } + /** + * Creates a native device type, following the given {@link #getNativeWindowType(boolean) native-window-type}. + * <p> + * The device will be opened if <code>own</code> is true, otherwise no native handle will ever be acquired. + * </p> + * <p> + * FIXME: Bug 973 Needs service provider interface (SPI) for TK dependent implementation + * </p> + */ + public static AbstractGraphicsDevice createDevice(final String nwt, final String displayConnection, final boolean own) { if( NativeWindowFactory.TYPE_X11 == nwt ) { if( own ) { return new X11GraphicsDevice(displayConnection, AbstractGraphicsDevice.DEFAULT_UNIT, null /* ToolkitLock */); @@ -656,16 +676,13 @@ public abstract class NativeWindowFactory { return new WindowsGraphicsDevice(AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT); } else if( NativeWindowFactory.TYPE_MACOSX == nwt ) { return new MacOSXGraphicsDevice(AbstractGraphicsDevice.DEFAULT_UNIT); - /** - * FIXME: Needs service provider interface (SPI) for TK dependent implementation - } else if( NativeWindowFactory.TYPE_BCM_VC_IV == nwt ) { - } else if( NativeWindowFactory.TYPE_ANDROID== nwt ) { } else if( NativeWindowFactory.TYPE_EGL == nwt ) { - } else if( NativeWindowFactory.TYPE_BCM_VC_IV == nwt ) { + throw new UnsupportedOperationException("n/a for windowing system: "+nwt); } else if( NativeWindowFactory.TYPE_AWT == nwt ) { - */ + throw new UnsupportedOperationException("n/a for windowing system: "+nwt); + } else { + return new DefaultGraphicsDevice(nwt, displayConnection, AbstractGraphicsDevice.DEFAULT_UNIT); } - throw new UnsupportedOperationException("n/a for windowing system: "+nwt); } /** @@ -691,6 +708,9 @@ public abstract class NativeWindowFactory { /** * @param nw * @return top-left client-area position in window units + * <p> + * FIXME: Bug 973 Needs service provider interface (SPI) for TK dependent implementation + * </p> */ public static PointImmutable getLocationOnScreen(final NativeWindow nw) { final String nwt = NativeWindowFactory.getNativeWindowType(true); diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/awt/JAWTWindow.java b/src/nativewindow/classes/com/jogamp/nativewindow/awt/JAWTWindow.java index f1442abee..d315e1876 100644 --- a/src/nativewindow/classes/com/jogamp/nativewindow/awt/JAWTWindow.java +++ b/src/nativewindow/classes/com/jogamp/nativewindow/awt/JAWTWindow.java @@ -805,27 +805,10 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface, * </p> */ @Override - public Point getLocationOnScreen(Point storage) { + public Point getLocationOnScreen(final Point storage) { Point los = getLocationOnScreenNative(storage); if(null == los) { - if(!Thread.holdsLock(component.getTreeLock())) { - // avoid deadlock .. - if(DEBUG) { - System.err.println("Warning: JAWT Lock hold, but not the AWT tree lock: "+this); - ExceptionUtils.dumpStack(System.err); - } - if( null == storage ) { - storage = new Point(); - } - getLocationOnScreenNonBlocking(storage, component); - return storage; - } - final java.awt.Point awtLOS = component.getLocationOnScreen(); - if(null!=storage) { - los = storage.translate(awtLOS.x, awtLOS.y); - } else { - los = new Point(awtLOS.x, awtLOS.y); - } + los = AWTMisc.getLocationOnScreenSafe(storage, component, DEBUG); } return los; } @@ -854,35 +837,6 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface, } protected abstract Point getLocationOnScreenNativeImpl(int x, int y); - protected static Component getLocationOnScreenNonBlocking(final Point storage, Component comp) { - final java.awt.Insets insets = new java.awt.Insets(0, 0, 0, 0); // DEBUG - Component last = null; - while(null != comp) { - final int dx = comp.getX(); - final int dy = comp.getY(); - if( DEBUG ) { - final java.awt.Insets ins = AWTMisc.getInsets(comp, false); - if( null != ins ) { - insets.bottom += ins.bottom; - insets.top += ins.top; - insets.left += ins.left; - insets.right += ins.right; - } - System.err.print("LOS: "+storage+" + "+comp.getClass().getName()+"["+dx+"/"+dy+", vis "+comp.isVisible()+", ins "+ins+" -> "+insets+"] -> "); - } - storage.translate(dx, dy); - if( DEBUG ) { - System.err.println(storage); - } - last = comp; - if( comp instanceof Window ) { // top-level heavy-weight ? - break; - } - comp = comp.getParent(); - } - return last; - } - @Override public boolean hasFocus() { return component.hasFocus(); diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/util/PixelFormat.java b/src/nativewindow/classes/com/jogamp/nativewindow/util/PixelFormat.java index 8b1e91564..748e14f0d 100644 --- a/src/nativewindow/classes/com/jogamp/nativewindow/util/PixelFormat.java +++ b/src/nativewindow/classes/com/jogamp/nativewindow/util/PixelFormat.java @@ -425,7 +425,7 @@ public enum PixelFormat { boolean isInterleaved(); /** Number of components per pixel, e.g. 3 for {@link PixelFormat#RGBx8888 RGBx8888}. */ - int componenCount(); + int componentCount(); /** Number of bits per pixel, e.g. 24 bits for {@link PixelFormat#RGBx8888 RGBx8888}. */ int bitsPerPixel(); /** @@ -602,7 +602,7 @@ public enum PixelFormat { @Override public final boolean isInterleaved() { return true; } @Override - public final int componenCount() { return compMask.length; } + public final int componentCount() { return compMask.length; } @Override public final int bitsPerPixel() { return bitsPerPixel; } @Override diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/util/PixelFormatUtil.java b/src/nativewindow/classes/com/jogamp/nativewindow/util/PixelFormatUtil.java index 180f02d72..42f6ccb8a 100644 --- a/src/nativewindow/classes/com/jogamp/nativewindow/util/PixelFormatUtil.java +++ b/src/nativewindow/classes/com/jogamp/nativewindow/util/PixelFormatUtil.java @@ -46,12 +46,12 @@ public class PixelFormatUtil { public static class ComponentMap { /** * Contains the source index for each destination index, - * length is {@link Composition#componenCount()} of destination. + * length is {@link Composition#componentCount()} of destination. */ final int[] dst2src; /** * Contains the destination index for each source index, - * length is {@link Composition#componenCount()} of source. + * length is {@link Composition#componentCount()} of source. */ final int[] src2dst; @@ -62,8 +62,8 @@ public class PixelFormatUtil { final boolean hasSrcRGB; public ComponentMap(final PixelFormat.Composition src, final PixelFormat.Composition dst) { - final int sCompCount = src.componenCount(); - final int dCompCount = dst.componenCount(); + final int sCompCount = src.componentCount(); + final int dCompCount = dst.componentCount(); final PixelFormat.CType[] sCompOrder = src.componentOrder(); final PixelFormat.CType[] dCompOrder = dst.componentOrder(); @@ -513,8 +513,8 @@ public class PixelFormatUtil { final Bitstream<ByteBuffer> dstBitStream, final PixelFormat.Composition srcComp, final Bitstream<ByteBuffer> srcBitStream) throws IllegalStateException, IOException { - final int sCompCount = srcComp.componenCount(); - final int dCompCount = dstComp.componenCount(); + final int sCompCount = srcComp.componentCount(); + final int dCompCount = dstComp.componentCount(); final int[] sc = new int[sCompCount]; final int[] dcDef = new int[dCompCount]; final int[] srcCompBitCount = srcComp.componentBitCount(); diff --git a/src/nativewindow/classes/jogamp/nativewindow/awt/AWTMisc.java b/src/nativewindow/classes/jogamp/nativewindow/awt/AWTMisc.java index 0c072d05b..3900f03db 100644 --- a/src/nativewindow/classes/jogamp/nativewindow/awt/AWTMisc.java +++ b/src/nativewindow/classes/jogamp/nativewindow/awt/AWTMisc.java @@ -44,11 +44,13 @@ import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JRootPane; import javax.swing.WindowConstants; + import com.jogamp.nativewindow.NativeWindowException; import com.jogamp.nativewindow.WindowClosingProtocol; import com.jogamp.nativewindow.util.PixelRectangle; import com.jogamp.nativewindow.util.PixelFormat; import com.jogamp.nativewindow.util.PixelFormatUtil; + import javax.swing.MenuSelectionManager; import com.jogamp.nativewindow.awt.DirectDataBufferInt; @@ -115,6 +117,59 @@ public class AWTMisc { return null; } + public static com.jogamp.nativewindow.util.Point getLocationOnScreenSafe(com.jogamp.nativewindow.util.Point storage, + final Component component, + final boolean verbose) + { + if(!Thread.holdsLock(component.getTreeLock())) { + // avoid deadlock .. + if( null == storage ) { + storage = new com.jogamp.nativewindow.util.Point(); + } + getLocationOnScreenNonBlocking(storage, component, verbose); + return storage; + } + final java.awt.Point awtLOS = component.getLocationOnScreen(); + com.jogamp.nativewindow.util.Point los; + if(null!=storage) { + los = storage.translate(awtLOS.x, awtLOS.y); + } else { + los = new com.jogamp.nativewindow.util.Point(awtLOS.x, awtLOS.y); + } + return los; + } + public static Component getLocationOnScreenNonBlocking(final com.jogamp.nativewindow.util.Point storage, + Component comp, + final boolean verbose) + { + final java.awt.Insets insets = new java.awt.Insets(0, 0, 0, 0); // DEBUG + Component last = null; + while(null != comp) { + final int dx = comp.getX(); + final int dy = comp.getY(); + if( verbose ) { + final java.awt.Insets ins = getInsets(comp, false); + if( null != ins ) { + insets.bottom += ins.bottom; + insets.top += ins.top; + insets.left += ins.left; + insets.right += ins.right; + } + System.err.print("LOS: "+storage+" + "+comp.getClass().getName()+"["+dx+"/"+dy+", vis "+comp.isVisible()+", ins "+ins+" -> "+insets+"] -> "); + } + storage.translate(dx, dy); + if( verbose ) { + System.err.println(storage); + } + last = comp; + if( comp instanceof Window ) { // top-level heavy-weight ? + break; + } + comp = comp.getParent(); + } + return last; + } + public static interface ComponentAction { /** * @param c the component to perform the action on diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java index e733b7233..93c3dbaf7 100644 --- a/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java +++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java @@ -49,14 +49,19 @@ import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.Map; +import com.jogamp.nativewindow.AbstractGraphicsDevice; +import com.jogamp.nativewindow.AbstractGraphicsScreen; import com.jogamp.nativewindow.NativeWindowException; import com.jogamp.nativewindow.NativeWindowFactory; import com.jogamp.nativewindow.ToolkitLock; +import com.jogamp.nativewindow.awt.AWTGraphicsScreen; import jogamp.common.os.PlatformPropsImpl; import jogamp.nativewindow.Debug; import jogamp.nativewindow.NWJNILibLoader; +import jogamp.nativewindow.jawt.x11.X11SunJDKReflection; import jogamp.nativewindow.macosx.OSXUtil; +import jogamp.nativewindow.x11.X11Lib; import com.jogamp.common.os.Platform; import com.jogamp.common.util.PropertyAccess; @@ -545,6 +550,21 @@ public class JAWTUtil { return jawtToolkitLock; } + public static final int getMonitorIndex(final GraphicsDevice device) { + int idx = -1; + if( null != getCGDisplayIDMethodOnOSX ) { + // OSX specific + try { + final Object res = getCGDisplayIDMethodOnOSX.invoke(device); + if (res instanceof Integer) { + final int displayID = ((Integer)res).intValue(); + idx = OSXUtil.GetNSScreenIdx(displayID); + } + } catch (final Throwable t) {} + } + return idx; + } + /** * Returns the pixel scale factor of the given {@link GraphicsDevice}, if supported. * <p> @@ -628,5 +648,73 @@ public class JAWTUtil { } return changed; } + + private static String getThreadName() { + return Thread.currentThread().getName(); + } + private static String toHexString(final long val) { + return "0x" + Long.toHexString(val); + } + + /** + * @param awtComp must be {@link java.awt.Component#isDisplayable() displayable} + * and must have a {@link java.awt.Component#getGraphicsConfiguration() GraphicsConfiguration} + * @return AbstractGraphicsDevice instance reflecting the {@code awtComp} + * @throws IllegalArgumentException if {@code awtComp} is not {@link java.awt.Component#isDisplayable() displayable} + * or has {@code null} {@link java.awt.Component#getGraphicsConfiguration() GraphicsConfiguration}. + * @see #getAbstractGraphicsScreen(java.awt.Component) + */ + public static AbstractGraphicsDevice createDevice(final java.awt.Component awtComp) throws IllegalArgumentException { + if( !awtComp.isDisplayable() ) { + throw new IllegalArgumentException("Given AWT-Component is not displayable: "+awtComp); + } + final GraphicsDevice device; + final GraphicsConfiguration gc = awtComp.getGraphicsConfiguration(); + if(null!=gc) { + device = gc.getDevice(); + } else { + throw new IllegalArgumentException("Given AWT-Component has no GraphicsConfiguration set: "+awtComp); + } + + final String displayConnection; + final String nwt = NativeWindowFactory.getNativeWindowType(true); + if( NativeWindowFactory.TYPE_X11 == nwt ) { + final long displayHandleAWT = X11SunJDKReflection.graphicsDeviceGetDisplay(device); + if( 0 == displayHandleAWT ) { + displayConnection = null; // default + if(DEBUG) { + System.err.println(getThreadName()+" - JAWTUtil.createDevice: Null AWT dpy, default X11 display"); + } + } else { + /** + * Using the AWT display handle works fine with NVidia. + * However we experienced different results w/ AMD drivers, + * some work, but some behave erratic. + * I.e. hangs in XQueryExtension(..) via X11GraphicsScreen. + */ + displayConnection = X11Lib.XDisplayString(displayHandleAWT); + if(DEBUG) { + System.err.println(getThreadName()+" - JAWTUtil.createDevice: AWT dpy "+displayConnection+" / "+toHexString(displayHandleAWT)); + } + } + } else { + displayConnection = null; // default + } + return NativeWindowFactory.createDevice(displayConnection, true /* own */); + } + + /** + * @param awtComp must be {@link java.awt.Component#isDisplayable() displayable} + * and must have a {@link java.awt.Component#getGraphicsConfiguration() GraphicsConfiguration} + * @return AbstractGraphicsScreen instance reflecting the {@code awtComp} + * @throws IllegalArgumentException if {@code awtComp} is not {@link java.awt.Component#isDisplayable() displayable} + * or has {@code null} {@link java.awt.Component#getGraphicsConfiguration() GraphicsConfiguration}. + * @see #createDevice(java.awt.Component) + */ + public static AbstractGraphicsScreen getAbstractGraphicsScreen(final java.awt.Component awtComp) throws IllegalArgumentException { + final AbstractGraphicsDevice adevice = createDevice(awtComp); + return NativeWindowFactory.createScreen(adevice, AWTGraphicsScreen.findScreenIndex(awtComp.getGraphicsConfiguration().getDevice())); + } + } diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java index 6ac480120..6f3f1ed6b 100644 --- a/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java +++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java @@ -145,7 +145,7 @@ public class MacOSXJAWTWindow extends JAWTWindow implements MutableSurface { // CALayer position will be determined in native code. // See detailed description in {@link JAWTUtil#JAWT_OSX_CALAYER_QUIRK_LAYOUT} final Point p0 = new Point(); - final Component outterComp = getLocationOnScreenNonBlocking(p0, component); + final Component outterComp = AWTMisc.getLocationOnScreenNonBlocking(p0, component, DEBUG); final java.awt.Insets outterInsets = AWTMisc.getInsets(outterComp, true); final Point p1 = (Point)p0.cloneMutable(); p1.translate(-outterComp.getX(), -outterComp.getY()); @@ -178,7 +178,7 @@ public class MacOSXJAWTWindow extends JAWTWindow implements MutableSurface { // CALayer position will be determined in native code. // See detailed description in {@link JAWTUtil#JAWT_OSX_CALAYER_QUIRK_LAYOUT} final Point p0 = new Point(); - final Component outterComp = getLocationOnScreenNonBlocking(p0, component); + final Component outterComp = AWTMisc.getLocationOnScreenNonBlocking(p0, component, DEBUG); final java.awt.Insets outterInsets = AWTMisc.getInsets(outterComp, true); final Point p1 = (Point)p0.cloneMutable(); p1.translate(-outterComp.getX(), -outterComp.getY()); @@ -405,7 +405,7 @@ public class MacOSXJAWTWindow extends JAWTWindow implements MutableSurface { if( null == storage ) { storage = new Point(); } - getLocationOnScreenNonBlocking(storage, component); + AWTMisc.getLocationOnScreenNonBlocking(storage, component, DEBUG); return storage; } @Override diff --git a/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java b/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java index 8ec7b7e95..a5970b87c 100644 --- a/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java +++ b/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java @@ -107,6 +107,9 @@ public class OSXUtil implements ToolkitProperties { return (Insets) GetInsets0(windowOrView); } + public static int GetNSScreenIdx(final int displayID) { + return GetNSScreenIdx0(displayID); + } public static double GetPixelScaleByScreenIdx(final int screenIndex) { return GetPixelScale0(screenIndex); } @@ -395,6 +398,7 @@ public class OSXUtil implements ToolkitProperties { 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 int GetNSScreenIdx0(int displayID); private static native double GetPixelScale0(int screenIndex); private static native double GetPixelScale1(int displayID); private static native double GetPixelScale2(long windowOrView); diff --git a/src/nativewindow/native/macosx/OSXmisc.m b/src/nativewindow/native/macosx/OSXmisc.m index 2cc272a41..87494e946 100644 --- a/src/nativewindow/native/macosx/OSXmisc.m +++ b/src/nativewindow/native/macosx/OSXmisc.m @@ -156,6 +156,18 @@ static NSScreen * OSXUtil_getNSScreenByCGDirectDisplayID(CGDirectDisplayID displ } return (NSScreen *) [screens objectAtIndex: 0]; } +static int OSXUtil_getNSScreenIdxByCGDirectDisplayID(CGDirectDisplayID displayID) { + NSArray *screens = [NSScreen screens]; + int i; + for(i=[screens count]-1; i>=0; i--) { + NSScreen * screen = (NSScreen *) [screens objectAtIndex: i]; + CGDirectDisplayID dID = OSXUtil_getCGDirectDisplayIDByNSScreen(screen); + if( dID == displayID ) { + return i; + } + } + return -1; +} /* * Class: Java_jogamp_nativewindow_macosx_OSXUtil @@ -263,6 +275,22 @@ JNIEXPORT jobject JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_GetInsets0 /* * Class: Java_jogamp_nativewindow_macosx_OSXUtil + * Method: GetNSScreenIdx0 + * Signature: (I)I + */ +JNIEXPORT jint JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_GetNSScreenIdx0 + (JNIEnv *env, jclass unused, jint displayID) +{ + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + + int idx = OSXUtil_getNSScreenIdxByCGDirectDisplayID((CGDirectDisplayID)displayID); + [pool release]; + + return idx; +} + +/* + * Class: Java_jogamp_nativewindow_macosx_OSXUtil * Method: GetPixelScale0 * Signature: (I)D */ diff --git a/src/nativewindow/native/x11/Xmisc.c b/src/nativewindow/native/x11/Xmisc.c index a2e744cd8..efb4620ba 100644 --- a/src/nativewindow/native/x11/Xmisc.c +++ b/src/nativewindow/native/x11/Xmisc.c @@ -52,12 +52,12 @@ #include <dlfcn.h> #undef __USE_GNU +#include "Xmisc.h" + /* Current versions of Solaris don't expose the XF86 extensions, although with the recent transition to Xorg this will probably happen in an upcoming release */ -#if !defined(__sun_obsolete) && !defined(_HPUX) -#include <X11/extensions/xf86vmode.h> -#else +#if defined(__sun_obsolete) || defined(_HPUX) /* Need to provide stubs for these */ Bool XF86VidModeGetGammaRampSize( Display *display, diff --git a/src/nativewindow/native/x11/Xmisc.h b/src/nativewindow/native/x11/Xmisc.h index 91f2ac5d9..d8868f802 100644 --- a/src/nativewindow/native/x11/Xmisc.h +++ b/src/nativewindow/native/x11/Xmisc.h @@ -39,4 +39,30 @@ #include <X11/Xlib.h> #include <X11/Xutil.h> +#if !defined(__sun_obsolete) && !defined(_HPUX) +#include <X11/extensions/xf86vmode.h> +#else +Bool XF86VidModeGetGammaRampSize( + Display* /* dpy */, + int /* screen */, + int* /* size */ +); +Bool XF86VidModeGetGammaRamp( + Display* /* dpy */, + int /* screen */, + int /* size */, + unsigned short* /* red array */, + unsigned short* /* green array */, + unsigned short* /* blue array */ +); +Bool XF86VidModeSetGammaRamp( + Display* /* dpy */, + int /* screen */, + int /* size */, + unsigned short* /* red array */, + unsigned short* /* green array */, + unsigned short* /* blue array */ +); +#endif /* defined(__sun_obsolete) || defined(_HPUX) */ + #endif /* Xmisc_h */ diff --git a/src/newt/classes/com/jogamp/newt/MonitorDevice.java b/src/newt/classes/com/jogamp/newt/MonitorDevice.java index 4d9c6493a..ec38ce3c3 100644 --- a/src/newt/classes/com/jogamp/newt/MonitorDevice.java +++ b/src/newt/classes/com/jogamp/newt/MonitorDevice.java @@ -35,7 +35,6 @@ import com.jogamp.nativewindow.util.DimensionImmutable; import com.jogamp.nativewindow.util.Rectangle; import com.jogamp.nativewindow.util.RectangleImmutable; import com.jogamp.nativewindow.util.SurfaceSize; - import com.jogamp.common.util.ArrayHashSet; /** @@ -65,15 +64,17 @@ public abstract class MonitorDevice { protected final DimensionImmutable sizeMM; // in [mm] protected final MonitorMode originalMode; protected final ArrayHashSet<MonitorMode> supportedModes; // FIXME: May need to support mutable mode, i.e. adding modes on the fly! - protected MonitorMode currentMode; - protected boolean modeChanged; protected final float[] pixelScale; protected final Rectangle viewportPU; // in pixel units protected final Rectangle viewportWU; // in window units + protected boolean isClone; + protected MonitorMode currentMode; + protected boolean modeChanged; /** * @param screen associated {@link Screen} * @param nativeId unique monitor device ID + * @param isClone flag * @param sizeMM size in millimeters * @param currentMode * @param pixelScale pre-fetched current pixel-scale, maybe {@code null} for {@link ScalableSurface#IDENTITY_PIXELSCALE}. @@ -81,19 +82,21 @@ public abstract class MonitorDevice { * @param viewportWU viewport in window-units * @param supportedModes all supported {@link MonitorMode}s */ - protected MonitorDevice(final Screen screen, final int nativeId, final DimensionImmutable sizeMM, - final MonitorMode currentMode, - final float[] pixelScale, final Rectangle viewportPU, final Rectangle viewportWU, - final ArrayHashSet<MonitorMode> supportedModes) { + protected MonitorDevice(final Screen screen, final int nativeId, final boolean isClone, + final DimensionImmutable sizeMM, + final MonitorMode currentMode, final float[] pixelScale, final Rectangle viewportPU, + final Rectangle viewportWU, final ArrayHashSet<MonitorMode> supportedModes) { this.screen = screen; this.nativeId = nativeId; this.sizeMM = sizeMM; this.originalMode = currentMode; this.supportedModes = supportedModes; - this.currentMode = currentMode; this.pixelScale = null != pixelScale ? pixelScale : new float[] { 1.0f, 1.0f }; this.viewportPU = viewportPU; this.viewportWU = viewportWU; + + this.isClone = isClone; + this.currentMode = currentMode; this.modeChanged = false; } @@ -134,6 +137,9 @@ public abstract class MonitorDevice { /** @return the immutable unique native Id of this monitor device. */ public final int getId() { return nativeId; } + /** @return {@code true} if this device represents a <i>clone</i>, otherwise return {@code false}. */ + public final boolean isClone() { return isClone; } + /** * @return the immutable monitor size in millimeters. */ @@ -310,20 +316,22 @@ public abstract class MonitorDevice { * <p> * The returned {@link MonitorMode} is element of the lists {@link #getSupportedModes()} and {@link Screen#getMonitorModes()}. * </p> + * @throws IllegalStateException if the {@link #getScreen() associated screen} is not {@link Screen#isNativeValid() valid natively}. * @see #getCurrentMode() */ - public abstract MonitorMode queryCurrentMode(); + public abstract MonitorMode queryCurrentMode() throws IllegalStateException; /** * Set the current {@link com.jogamp.newt.MonitorMode}. * @param mode to be made current, must be element of the list {@link #getSupportedModes()} and {@link Screen#getMonitorModes()}. * @return true if successful, otherwise false + * @throws IllegalStateException if the {@link #getScreen() associated screen} is not {@link Screen#isNativeValid() valid natively}. */ - public abstract boolean setCurrentMode(MonitorMode mode); + public abstract boolean setCurrentMode(MonitorMode mode) throws IllegalStateException; @Override public String toString() { - return "Monitor[Id "+Display.toHexString(nativeId)+", "+sizeMM+" mm, pixelScale ["+pixelScale[0]+", "+pixelScale[1]+ + return "Monitor[Id "+Display.toHexString(nativeId)+", clone "+isClone+", "+sizeMM+" mm, pixelScale ["+pixelScale[0]+", "+pixelScale[1]+ "], viewport "+viewportPU+ " [pixels], "+viewportWU+" [window], orig "+originalMode+", curr "+currentMode+ ", modeChanged "+modeChanged+", modeCount "+supportedModes.size()+"]"; } diff --git a/src/newt/classes/com/jogamp/newt/Screen.java b/src/newt/classes/com/jogamp/newt/Screen.java index 65031a565..b8f096fc3 100644 --- a/src/newt/classes/com/jogamp/newt/Screen.java +++ b/src/newt/classes/com/jogamp/newt/Screen.java @@ -210,7 +210,8 @@ public abstract class Screen { /** * Returns the {@link MonitorDevice} with the highest {@link MonitorDevice#getViewportInWindowUnits() viewport} - * {@link RectangleImmutable#coverage(RectangleImmutable) coverage} of the given rectangle in window units. + * {@link RectangleImmutable#coverage(RectangleImmutable) coverage} of the given rectangle in window units, + * which is not a {@link MonitorDevice#isClone() clone}. * <p> * If no coverage is detected the first {@link MonitorDevice} is returned. * </p> @@ -220,12 +221,15 @@ public abstract class Screen { MonitorDevice res = null; float maxCoverage = Float.MIN_VALUE; final List<MonitorDevice> monitors = getMonitorDevices(); - for(int i=monitors.size()-1; i>=0; i--) { + final int monitorCount = monitors.size(); + for(int i=0; i<monitorCount; i++) { final MonitorDevice monitor = monitors.get(i); - final float coverage = monitor.getViewportInWindowUnits().coverage(r); - if( coverage > maxCoverage ) { - maxCoverage = coverage; - res = monitor; + if( !monitor.isClone() ) { + final float coverage = monitor.getViewportInWindowUnits().coverage(r); + if( coverage > maxCoverage ) { + maxCoverage = coverage; + res = monitor; + } } } if( maxCoverage > 0.0f && null != res ) { @@ -234,6 +238,18 @@ public abstract class Screen { return monitors.get(0); } + public final MonitorDevice getMonitor(final int monitorId) { + final List<MonitorDevice> monitors = getMonitorDevices(); + final int monitorCount = monitors.size(); + for(int i=0; i<monitorCount; i++) { + final MonitorDevice monitor = monitors.get(i); + if( monitor.getId() == monitorId ) { + return monitor; + } + } + return null; + } + /** * Calculates the union of all monitor's {@link MonitorDevice#getViewport() viewport} in pixel- and window units. * <p> diff --git a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java index d638b3ae5..3ef017d1b 100644 --- a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java +++ b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java @@ -1004,6 +1004,11 @@ public class GLWindow extends GLAutoDrawableBase implements GLAutoDrawable, Wind glWindow.addGLEventListener(new GLEventListener() { @Override public void init(final GLAutoDrawable drawable) { + final MonitorDevice monitor = glWindow.getMainMonitor(); + System.err.println("Main Monitor: "+monitor); + final float[] pixelPerMM = monitor.getPixelsPerMM(new float[2]); + System.err.println(" pixel/mm ["+pixelPerMM[0]+", "+pixelPerMM[1]+"]"); + System.err.println(" pixel/in ["+pixelPerMM[0]*25.4f+", "+pixelPerMM[1]*25.4f+"]"); final GL gl = drawable.getGL(); System.err.println(JoglVersion.getGLInfo(gl, null)); System.err.println("Requested: "+drawable.getNativeSurface().getGraphicsConfiguration().getRequestedCapabilities()); diff --git a/src/newt/classes/jogamp/newt/MonitorDeviceImpl.java b/src/newt/classes/jogamp/newt/MonitorDeviceImpl.java index 7c7d54680..3f039a9f4 100644 --- a/src/newt/classes/jogamp/newt/MonitorDeviceImpl.java +++ b/src/newt/classes/jogamp/newt/MonitorDeviceImpl.java @@ -31,7 +31,6 @@ package jogamp.newt; import com.jogamp.nativewindow.ScalableSurface; import com.jogamp.nativewindow.util.DimensionImmutable; import com.jogamp.nativewindow.util.Rectangle; - import com.jogamp.common.util.ArrayHashSet; import com.jogamp.newt.MonitorDevice; import com.jogamp.newt.MonitorMode; @@ -42,6 +41,7 @@ public class MonitorDeviceImpl extends MonitorDevice { /** * @param screen associated {@link Screen} * @param nativeId unique monitor device ID + * @param isClone TODO * @param sizeMM size in millimeters * @param currentMode * @param pixelScale pre-fetched current pixel-scale, maybe {@code null} for {@link ScalableSurface#IDENTITY_PIXELSCALE}. @@ -49,16 +49,19 @@ public class MonitorDeviceImpl extends MonitorDevice { * @param viewportWU viewport in window-units * @param supportedModes all supported {@link MonitorMode}s */ - public MonitorDeviceImpl(final ScreenImpl screen, final int nativeId, final DimensionImmutable sizeMM, - final MonitorMode currentMode, - final float[] pixelScale, final Rectangle viewportPU, final Rectangle viewportWU, - final ArrayHashSet<MonitorMode> supportedModes) { - super(screen, nativeId, sizeMM, currentMode, pixelScale, viewportPU, viewportWU, supportedModes); + public MonitorDeviceImpl(final ScreenImpl screen, final int nativeId, final boolean isClone, + final DimensionImmutable sizeMM, + final MonitorMode currentMode, final float[] pixelScale, final Rectangle viewportPU, + final Rectangle viewportWU, final ArrayHashSet<MonitorMode> supportedModes) { + super(screen, nativeId, isClone, sizeMM, currentMode, pixelScale, viewportPU, viewportWU, supportedModes); } @Override - public final MonitorMode queryCurrentMode() { + public final MonitorMode queryCurrentMode() throws IllegalStateException { final ScreenImpl screenImpl = (ScreenImpl)screen; + if( !screenImpl.isNativeValid() ) { + throw new IllegalStateException("Screen is not created natively: "+screenImpl); + } final ScreenMonitorState sms = screenImpl.getScreenMonitorStatus(true); sms.lock(); try { @@ -87,11 +90,14 @@ public class MonitorDeviceImpl extends MonitorDevice { } @Override - public final boolean setCurrentMode(final MonitorMode mode) { + public final boolean setCurrentMode(final MonitorMode mode) throws IllegalStateException { + final ScreenImpl screenImpl = (ScreenImpl)screen; + if( !screenImpl.isNativeValid() ) { + throw new IllegalStateException("Screen is not created natively: "+screenImpl); + } if(Screen.DEBUG) { System.err.println("Screen.setCurrentMode.0: "+this+" -> "+mode); } - final ScreenImpl screenImpl = (ScreenImpl)screen; final ScreenMonitorState sms = screenImpl.getScreenMonitorStatus(true); sms.lock(); try { @@ -157,4 +163,7 @@ public class MonitorDeviceImpl extends MonitorDevice { return supportedModes; } + /* pp */ final void setIsClone(final boolean isClone) { + this.isClone = isClone; + } } diff --git a/src/newt/classes/jogamp/newt/MonitorModeProps.java b/src/newt/classes/jogamp/newt/MonitorModeProps.java index 3f9e0be78..eacf77e25 100644 --- a/src/newt/classes/jogamp/newt/MonitorModeProps.java +++ b/src/newt/classes/jogamp/newt/MonitorModeProps.java @@ -31,13 +31,17 @@ package jogamp.newt; import com.jogamp.common.util.ArrayHashSet; import com.jogamp.newt.MonitorDevice; import com.jogamp.newt.MonitorMode; +import com.jogamp.newt.Screen; +import java.util.ArrayList; import java.util.List; + import com.jogamp.nativewindow.ScalableSurface; import com.jogamp.nativewindow.util.Dimension; import com.jogamp.nativewindow.util.DimensionImmutable; import com.jogamp.nativewindow.util.Rectangle; import com.jogamp.nativewindow.util.SurfaceSize; +import com.jogamp.opengl.math.FloatUtil; import jogamp.newt.MonitorDeviceImpl; import jogamp.newt.ScreenImpl; @@ -128,6 +132,7 @@ public class MonitorModeProps { * <ul> * <li>count</li> * <li>id</li> + * <li>IsClone</li> * <li>ScreenSizeMM[width, height] (2 elements)</li> * <li>Rotated Viewport pixel-units (4 elements)</li> * <li>Rotated Viewport window-units (4 elements)</li> @@ -142,7 +147,7 @@ public class MonitorModeProps { * WARNING: must be synchronized with ScreenMode.h, native implementation * </p> */ - public static final int MIN_MONITOR_DEVICE_PROPERTIES = 15; + public static final int MIN_MONITOR_DEVICE_PROPERTIES = 16; public static final int IDX_MONITOR_DEVICE_VIEWPORT = 1 // count + 1 // native mode @@ -285,6 +290,7 @@ public class MonitorModeProps { offset++; final List<MonitorMode> allMonitorModes = cache.monitorModes.getData(); final int id = monitorProperties[offset++]; + final boolean isClone = 0 == monitorProperties[offset++] ? false : true; final DimensionImmutable sizeMM = streamInResolution(monitorProperties, offset); offset+=NUM_RESOLUTION_PROPERTIES; final Rectangle viewportPU = new Rectangle(monitorProperties[offset++], monitorProperties[offset++], monitorProperties[offset++], monitorProperties[offset++]); final Rectangle viewportWU = new Rectangle(monitorProperties[offset++], monitorProperties[offset++], monitorProperties[offset++], monitorProperties[offset++]); @@ -304,7 +310,7 @@ public class MonitorModeProps { } } } - MonitorDevice monitorDevice = new MonitorDeviceImpl(screen, id, sizeMM, currentMode, pixelScale, viewportPU, viewportWU, supportedModes); + MonitorDevice monitorDevice = new MonitorDeviceImpl(screen, id, isClone, sizeMM, currentMode, pixelScale, viewportPU, viewportWU, supportedModes); if(null!=cache) { monitorDevice = cache.monitorDevices.getOrAdd(monitorDevice); } @@ -365,10 +371,11 @@ public class MonitorModeProps { } offset++; final int id = monitorProperties[offset++]; + final boolean isClone = 0 == monitorProperties[offset++] ? false : true; final DimensionImmutable sizeMM = streamInResolution(monitorProperties, offset); offset+=NUM_RESOLUTION_PROPERTIES; final Rectangle viewportPU = new Rectangle(monitorProperties[offset++], monitorProperties[offset++], monitorProperties[offset++], monitorProperties[offset++]); final Rectangle viewportWU = new Rectangle(monitorProperties[offset++], monitorProperties[offset++], monitorProperties[offset++], monitorProperties[offset++]); - MonitorDevice monitorDevice = new MonitorDeviceImpl(screen, id, sizeMM, currentMode, pixelScale, viewportPU, viewportWU, supportedModes); + MonitorDevice monitorDevice = new MonitorDeviceImpl(screen, id, isClone, sizeMM, currentMode, pixelScale, viewportPU, viewportWU, supportedModes); if(null!=cache) { monitorDevice = cache.monitorDevices.getOrAdd(monitorDevice); } @@ -393,6 +400,7 @@ public class MonitorModeProps { int idx=0; data[idx++] = data.length; data[idx++] = monitorDevice.getId(); + data[idx++] = monitorDevice.isClone() ? 1 : 0; data[idx++] = monitorDevice.getSizeMM().getWidth(); data[idx++] = monitorDevice.getSizeMM().getHeight(); data[idx++] = monitorDevice.getViewport().getX(); @@ -415,7 +423,36 @@ public class MonitorModeProps { return data; } - public final void swapRotatePair(final int rotation, final int[] pairs, int offset, final int numPairs) { + /** Identify monitor devices in <i>cloned</i> mode, i.e. consecutive devices being 100% covered by preceding devices. */ + /* pp */ static void identifyClonedMonitorDevices(final MonitorModeProps.Cache cache) { + final ArrayList<MonitorDevice> monitors = cache.monitorDevices.toArrayList(); + final int monitorCount = monitors.size(); + for(int i=0; i<monitorCount; i++) { + final MonitorDevice a = monitors.get(i); + if( !a.isClone() ) { + for(int j=i+1; j<monitorCount; j++) { + final MonitorDevice b = monitors.get(j); + if( !b.isClone() ) { + final float coverage = b.getViewport().coverage( a.getViewport() ); + if( FloatUtil.isZero( 1f - coverage, FloatUtil.EPSILON ) ) { + ((MonitorDeviceImpl)b).setIsClone(true); + if( Screen.DEBUG ) { + System.err.printf("MonitorCloneTest[%d of %d]: %f -> _is_ covered%n", j, i, coverage); + System.err.printf(" Monitor[%d] %s%n", j, b.toString()); + System.err.printf(" Monitor[%d] %s%n", i, a.toString()); + } + } else if( Screen.DEBUG ) { + System.err.printf("MonitorDevice-CloneTest[%d of %d]: %f -> not covered%n", j, i, coverage); + System.err.printf(" Monitor[%d] %s%n", j, b.toString()); + System.err.printf(" Monitor[%d] %s%n", i, a.toString()); + } + } + } + } + } + } + + public static final void swapRotatePair(final int rotation, final int[] pairs, int offset, final int numPairs) { if( MonitorMode.ROTATE_0 == rotation || MonitorMode.ROTATE_180 == rotation ) { // nop return; diff --git a/src/newt/classes/jogamp/newt/ScreenImpl.java b/src/newt/classes/jogamp/newt/ScreenImpl.java index b8383b631..36e42e52c 100644 --- a/src/newt/classes/jogamp/newt/ScreenImpl.java +++ b/src/newt/classes/jogamp/newt/ScreenImpl.java @@ -500,6 +500,7 @@ public abstract class ScreenImpl extends Screen implements MonitorModeListener { int i = 0; props[i++] = MonitorModeProps.MIN_MONITOR_DEVICE_PROPERTIES; props[i++] = monitorId; + props[i++] = 0; // is-clone props[i++] = default_sm_widthmm; props[i++] = default_sm_heightmm; props[i++] = 0; // rotated viewport x pixel-units @@ -608,6 +609,7 @@ public abstract class ScreenImpl extends Screen implements MonitorModeListener { private final int collectNativeMonitorModes(final MonitorModeProps.Cache cache) { if(!DEBUG_TEST_SCREENMODE_DISABLED) { collectNativeMonitorModesAndDevicesImpl(cache); + MonitorModeProps.identifyClonedMonitorDevices(cache); } // filter out insufficient modes for(int i=cache.monitorModes.size()-1; i>=0; i--) { diff --git a/src/newt/classes/jogamp/newt/awt/NewtFactoryAWT.java b/src/newt/classes/jogamp/newt/awt/NewtFactoryAWT.java index 23e9c4370..4faa5de9c 100644 --- a/src/newt/classes/jogamp/newt/awt/NewtFactoryAWT.java +++ b/src/newt/classes/jogamp/newt/awt/NewtFactoryAWT.java @@ -28,17 +28,30 @@ package jogamp.newt.awt; +import java.awt.GraphicsDevice; + import com.jogamp.nativewindow.AbstractGraphicsConfiguration; import com.jogamp.nativewindow.CapabilitiesImmutable; import com.jogamp.nativewindow.NativeWindow; import com.jogamp.nativewindow.NativeWindowException; import com.jogamp.nativewindow.NativeWindowFactory; +import jogamp.nativewindow.awt.AWTMisc; +import jogamp.nativewindow.jawt.JAWTUtil; +import jogamp.nativewindow.jawt.x11.X11SunJDKReflection; +import jogamp.nativewindow.x11.X11Lib; import jogamp.newt.Debug; import com.jogamp.nativewindow.awt.AWTGraphicsConfiguration; +import com.jogamp.nativewindow.awt.AWTGraphicsScreen; import com.jogamp.nativewindow.awt.JAWTWindow; +import com.jogamp.nativewindow.util.Point; +import com.jogamp.nativewindow.util.Rectangle; +import com.jogamp.nativewindow.util.RectangleImmutable; +import com.jogamp.newt.Display; +import com.jogamp.newt.MonitorDevice; import com.jogamp.newt.NewtFactory; +import com.jogamp.newt.Screen; public class NewtFactoryAWT extends NewtFactory { public static final boolean DEBUG_IMPLEMENTATION = Debug.debug("Window"); @@ -83,5 +96,102 @@ public class NewtFactoryAWT extends NewtFactory { config.getScreen().getDevice().close(); } + /** + * @param awtComp + * @throws IllegalArgumentException if {@code awtComp} is not {@link java.awt.Component#isDisplayable() displayable} + * or has {@code null} {@link java.awt.Component#getGraphicsConfiguration() GraphicsConfiguration}. + */ + private static void checkComponentValid(final java.awt.Component awtComp) throws IllegalArgumentException { + if( !awtComp.isDisplayable() ) { + throw new IllegalArgumentException("Given AWT-Component is not displayable: "+awtComp); + } + if( null == awtComp.getGraphicsConfiguration() ) { + throw new IllegalArgumentException("Given AWT-Component has no GraphicsConfiguration set: "+awtComp); + } + } + + /** + * @param awtComp must be {@link java.awt.Component#isDisplayable() displayable} + * and must have a {@link java.awt.Component#getGraphicsConfiguration() GraphicsConfiguration} + * @param reuse attempt to reuse an existing {@link Display} with same <code>name</code> if set true, otherwise create a new instance. + * @return {@link Display} instance reflecting the {@code awtComp} + * @throws IllegalArgumentException if {@code awtComp} is not {@link java.awt.Component#isDisplayable() displayable} + * or has {@code null} {@link java.awt.Component#getGraphicsConfiguration() GraphicsConfiguration}. + * @see #getAbstractGraphicsScreen(java.awt.Component) + */ + public static Display createDisplay(final java.awt.Component awtComp, final boolean reuse) throws IllegalArgumentException { + checkComponentValid(awtComp); + final GraphicsDevice device = awtComp.getGraphicsConfiguration().getDevice(); + + final String displayConnection; + final String nwt = NativeWindowFactory.getNativeWindowType(true); + if( NativeWindowFactory.TYPE_X11 == nwt ) { + final long displayHandleAWT = X11SunJDKReflection.graphicsDeviceGetDisplay(device); + if( 0 == displayHandleAWT ) { + displayConnection = null; // default + } else { + /** + * Using the AWT display handle works fine with NVidia. + * However we experienced different results w/ AMD drivers, + * some work, but some behave erratic. + * I.e. hangs in XQueryExtension(..) via X11GraphicsScreen. + */ + displayConnection = X11Lib.XDisplayString(displayHandleAWT); + } + } else { + displayConnection = null; // default + } + return NewtFactory.createDisplay(displayConnection, reuse); + } + + /** + * @param awtComp must be {@link java.awt.Component#isDisplayable() displayable} + * and must have a {@link java.awt.Component#getGraphicsConfiguration() GraphicsConfiguration} + * @param reuse attempt to reuse an existing {@link Display} with same <code>name</code> if set true, otherwise create a new instance. + * @return {@link Screen} instance reflecting the {@code awtComp} + * @throws IllegalArgumentException if {@code awtComp} is not {@link java.awt.Component#isDisplayable() displayable} + * or has {@code null} {@link java.awt.Component#getGraphicsConfiguration() GraphicsConfiguration}. + * @see #createDevice(java.awt.Component) + */ + public static Screen createScreen(final java.awt.Component awtComp, final boolean reuse) throws IllegalArgumentException { + final Display display = createDisplay(awtComp, reuse); + return NewtFactory.createScreen(display, AWTGraphicsScreen.findScreenIndex(awtComp.getGraphicsConfiguration().getDevice())); + } + + /** + * Retrieves the {@link MonitorDevice} for the given displayable {@code awtComp}. + * <p> + * In case this method shall be called multiple times, it is advised to keep the given {@link Screen} instance + * natively created during operation. This should be done via the initial {@link Screen#addReference()}. + * After operation, user shall destroy the instance accordingly via the final {@link Screen#removeReference()}. + * </p> + * @param screen the {@link Screen} instance matching {@code awtComp}, i.e. via {@link #createScreen(java.awt.Component, boolean)}. + * @param awtComp must be {@link java.awt.Component#isDisplayable() displayable} + * and must have a {@link java.awt.Component#getGraphicsConfiguration() GraphicsConfiguration} + * @return {@link MonitorDevice} instance reflecting the {@code awtComp} + * @throws IllegalArgumentException if {@code awtComp} is not {@link java.awt.Component#isDisplayable() displayable} + * or has {@code null} {@link java.awt.Component#getGraphicsConfiguration() GraphicsConfiguration}. + * @see #createScreen(java.awt.Component, boolean) + */ + public static MonitorDevice getMonitorDevice(final Screen screen, final java.awt.Component awtComp) throws IllegalArgumentException { + checkComponentValid(awtComp); + final String nwt = NativeWindowFactory.getNativeWindowType(true); + MonitorDevice res = null; + screen.addReference(); + try { + if( NativeWindowFactory.TYPE_MACOSX == nwt ) { + res = screen.getMonitor( JAWTUtil.getMonitorIndex( awtComp.getGraphicsConfiguration().getDevice() ) ); + } + if( null == res ) { + // Fallback, use AWT component coverage + final Point los = AWTMisc.getLocationOnScreenSafe(null, awtComp, false); + final RectangleImmutable r = new Rectangle(los.getX(), los.getY(), awtComp.getWidth(), awtComp.getHeight()); + res = screen.getMainMonitor(r); + } + } finally { + screen.removeReference(); + } + return res; + } } diff --git a/src/newt/classes/jogamp/newt/driver/android/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/android/ScreenDriver.java index 273ff2b45..60e6e7d5f 100644 --- a/src/newt/classes/jogamp/newt/driver/android/ScreenDriver.java +++ b/src/newt/classes/jogamp/newt/driver/android/ScreenDriver.java @@ -104,6 +104,7 @@ public class ScreenDriver extends jogamp.newt.ScreenImpl { int i = 0; props[i++] = props.length; props[i++] = 0; // crt_idx + props[i++] = 0; // is-clone i = getScreenSizeMM(outMetrics, props, i); // sizeMM props[i++] = 0; // rotated viewport x pixel-units props[i++] = 0; // rotated viewport y pixel-units diff --git a/src/newt/classes/jogamp/newt/driver/awt/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/awt/ScreenDriver.java index eb92e0d13..aba7a1ab9 100644 --- a/src/newt/classes/jogamp/newt/driver/awt/ScreenDriver.java +++ b/src/newt/classes/jogamp/newt/driver/awt/ScreenDriver.java @@ -109,6 +109,7 @@ public class ScreenDriver extends ScreenImpl { int i = 0; props[i++] = props.length; props[i++] = 0; // crt_idx + props[i++] = 0; // is-clone props[i++] = ScreenImpl.default_sm_widthmm; // FIXME props[i++] = ScreenImpl.default_sm_heightmm; // FIXME props[i++] = 0; // rotated viewport x pixel-units diff --git a/src/newt/classes/jogamp/newt/driver/bcm/egl/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/bcm/egl/ScreenDriver.java index e65d79e2a..704fad73f 100644 --- a/src/newt/classes/jogamp/newt/driver/bcm/egl/ScreenDriver.java +++ b/src/newt/classes/jogamp/newt/driver/bcm/egl/ScreenDriver.java @@ -84,6 +84,7 @@ public class ScreenDriver extends jogamp.newt.ScreenImpl { i = 0; props[i++] = props.length; props[i++] = 0; // crt_idx + props[i++] = 0; // is-clone props[i++] = ScreenImpl.default_sm_widthmm; // FIXME props[i++] = ScreenImpl.default_sm_heightmm; // FIXME props[i++] = 0; // rotated viewport x pixel-units diff --git a/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/ScreenDriver.java index 42a63f91e..8d46adeab 100644 --- a/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/ScreenDriver.java +++ b/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/ScreenDriver.java @@ -77,6 +77,7 @@ public class ScreenDriver extends ScreenImpl { i = 0; props[i++] = props.length; props[i++] = 0; // crt_idx + props[i++] = 0; // is-clone props[i++] = ScreenImpl.default_sm_widthmm; // FIXME props[i++] = ScreenImpl.default_sm_heightmm; // FIXME props[i++] = 0; // rotated viewport x pixel-units diff --git a/src/newt/classes/jogamp/newt/driver/intel/gdl/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/intel/gdl/ScreenDriver.java index bd99fd18c..b55378459 100644 --- a/src/newt/classes/jogamp/newt/driver/intel/gdl/ScreenDriver.java +++ b/src/newt/classes/jogamp/newt/driver/intel/gdl/ScreenDriver.java @@ -86,6 +86,7 @@ public class ScreenDriver extends jogamp.newt.ScreenImpl { i = 0; props[i++] = props.length; props[i++] = 0; // crt_idx + props[i++] = 0; // is-clone props[i++] = ScreenImpl.default_sm_widthmm; // FIXME props[i++] = ScreenImpl.default_sm_heightmm; // FIXME props[i++] = 0; // rotated viewport x pixel-units diff --git a/src/newt/classes/jogamp/newt/driver/kd/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/kd/ScreenDriver.java index 975e0f96e..1e878bc3a 100644 --- a/src/newt/classes/jogamp/newt/driver/kd/ScreenDriver.java +++ b/src/newt/classes/jogamp/newt/driver/kd/ScreenDriver.java @@ -82,6 +82,7 @@ public class ScreenDriver extends ScreenImpl { i = 0; props[i++] = props.length; props[i++] = 0; // crt_idx + props[i++] = 0; // is-clone props[i++] = ScreenImpl.default_sm_widthmm; // FIXME props[i++] = ScreenImpl.default_sm_heightmm; // FIXME props[i++] = 0; // rotated viewport x pixel-units diff --git a/src/newt/classes/jogamp/newt/driver/windows/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/windows/ScreenDriver.java index b476ee38a..013f9f9ca 100644 --- a/src/newt/classes/jogamp/newt/driver/windows/ScreenDriver.java +++ b/src/newt/classes/jogamp/newt/driver/windows/ScreenDriver.java @@ -65,65 +65,81 @@ public class ScreenDriver extends ScreenImpl { protected void closeNativeImpl() { } - private final String getAdapterName(final int crt_idx) { - return getAdapterName0(crt_idx); + private final String getAdapterName(final int adapter_idx) { + return getAdapterName0(adapter_idx); } - private final String getActiveMonitorName(final String adapterName, final int monitor_idx) { - return getActiveMonitorName0(adapterName, monitor_idx); + private final String getMonitorName(final String adapterName, final int monitor_idx, final boolean onlyActive) { + return getMonitorName0(adapterName, monitor_idx, onlyActive); } - private final MonitorMode getMonitorModeImpl(final MonitorModeProps.Cache cache, final String adapterName, final int crtModeIdx) { + private final MonitorMode getMonitorModeImpl(final MonitorModeProps.Cache cache, final String adapterName, final int mode_idx) { if( null == adapterName ) { return null; } - final String activeMonitorName = getActiveMonitorName(adapterName, 0); - final int[] modeProps = null != activeMonitorName ? getMonitorMode0(adapterName, crtModeIdx) : null; + final int[] modeProps = getMonitorMode0(adapterName, mode_idx); if ( null == modeProps || 0 >= modeProps.length) { return null; } return MonitorModeProps.streamInMonitorMode(null, cache, modeProps, 0); } + private static final int getMonitorId(final int adapterIdx, final int monitorIdx) { + if( adapterIdx > 0xff ) { + throw new InternalError("Unsupported adapter idx > 0xff: "+adapterIdx); + } + if( monitorIdx > 0xff ) { + throw new InternalError("Unsupported monitor idx > 0xff: "+monitorIdx); + } + return ( adapterIdx & 0x000000ff ) << 8 | ( monitorIdx & 0x000000ff ); + } + private static final int getAdapterIndex(final int monitorId) { + return ( monitorId >>> 8 ) & 0x000000ff; + } + private static final int getMonitorIndex(final int monitorId) { + return monitorId & 0x000000ff; + } + @Override protected void collectNativeMonitorModesAndDevicesImpl(final MonitorModeProps.Cache cache) { - int crtIdx = 0; ArrayHashSet<MonitorMode> supportedModes = new ArrayHashSet<MonitorMode>(); - String adapterName = getAdapterName(crtIdx); - while( null != adapterName ) { - int crtModeIdx = 0; - MonitorMode mode; - do { - mode = getMonitorModeImpl(cache, adapterName, crtModeIdx); - if( null != mode ) { - supportedModes.getOrAdd(mode); - // next mode on same monitor - crtModeIdx++; - } - } while( null != mode); - if( 0 < crtModeIdx ) { - // has at least one mode -> add device - final MonitorMode currentMode = getMonitorModeImpl(cache, adapterName, -1); - if ( null != currentMode ) { // enabled - final int[] monitorProps = getMonitorDevice0(adapterName, crtIdx); - // merge monitor-props + supported modes - MonitorModeProps.streamInMonitorDevice(cache, this, currentMode, null, supportedModes, monitorProps, 0, null); - - // next monitor, 1st mode - supportedModes= new ArrayHashSet<MonitorMode>(); + String adapterName; + for(int adapterIdx=0; null != ( adapterName = getAdapterName(adapterIdx) ); adapterIdx++ ) { + for(int monitorIdx=0; null != getMonitorName(adapterName, monitorIdx, true); monitorIdx++ ) { + int modeIdx = 0; + MonitorMode mode; + do { + mode = getMonitorModeImpl(cache, adapterName, modeIdx); + if( null != mode ) { + supportedModes.getOrAdd(mode); + // next mode on same monitor + modeIdx++; + } + } while( null != mode); + if( 0 < modeIdx ) { + // has at least one mode -> add device + final MonitorMode currentMode = getMonitorModeImpl(cache, adapterName, -1); + if ( null != currentMode ) { // enabled + final int[] monitorProps = getMonitorDevice0(adapterName, adapterIdx, monitorIdx, getMonitorId(adapterIdx, monitorIdx)); + // merge monitor-props + supported modes + MonitorModeProps.streamInMonitorDevice(cache, this, currentMode, null, supportedModes, monitorProps, 0, null); + + // next monitor, 1st mode + supportedModes = new ArrayHashSet<MonitorMode>(); + } } } - crtIdx++; - adapterName = getAdapterName(crtIdx); } } @Override protected boolean updateNativeMonitorDeviceViewportImpl(final MonitorDevice monitor, final float[] pixelScale, final Rectangle viewportPU, final Rectangle viewportWU) { - final String adapterName = getAdapterName(monitor.getId()); + final int monitorId = monitor.getId(); + final int adapterIdx = getAdapterIndex(monitorId); + final int monitorIdx = getMonitorIndex(monitorId); + final String adapterName = getAdapterName(adapterIdx); if( null != adapterName ) { - final String activeMonitorName = getActiveMonitorName(adapterName, 0); - if( null != activeMonitorName ) { - final int[] monitorProps = getMonitorDevice0(adapterName, monitor.getId()); + if( null != getMonitorName(adapterName, monitorIdx, true) ) { + final int[] monitorProps = getMonitorDevice0(adapterName, adapterIdx, monitorIdx, getMonitorId(adapterIdx, monitorIdx)); int offset = MonitorModeProps.IDX_MONITOR_DEVICE_VIEWPORT; viewportPU.set(monitorProps[offset++], monitorProps[offset++], monitorProps[offset++], monitorProps[offset++]); viewportWU.set(monitorProps[offset++], monitorProps[offset++], monitorProps[offset++], monitorProps[offset++]); @@ -135,12 +151,12 @@ public class ScreenDriver extends ScreenImpl { @Override protected MonitorMode queryCurrentMonitorModeImpl(final MonitorDevice monitor) { - return getMonitorModeImpl(null, getAdapterName(monitor.getId()), -1); + return getMonitorModeImpl(null, getAdapterName(getAdapterIndex(monitor.getId())), -1); } @Override protected boolean setCurrentMonitorModeImpl(final MonitorDevice monitor, final MonitorMode mode) { - return setMonitorMode0(monitor.getId(), + return setMonitorMode0(getAdapterIndex(monitor.getId()), -1, -1, // no fixed position! mode.getSurfaceSize().getResolution().getWidth(), mode.getSurfaceSize().getResolution().getHeight(), @@ -168,9 +184,9 @@ public class ScreenDriver extends ScreenImpl { private native int getVirtualHeightImpl0(); private static native void dumpMonitorInfo0(); - private native String getAdapterName0(int crt_index); - private native String getActiveMonitorName0(String adapterName, int crtModeIdx); - private native int[] getMonitorMode0(String adapterName, int crtModeIdx); - private native int[] getMonitorDevice0(String adapterName, int monitor_index); - private native boolean setMonitorMode0(int monitor_index, int x, int y, int width, int height, int bits, int freq, int flags, int rot); + private native String getAdapterName0(int adapter_idx); + private native String getMonitorName0(String adapterName, int monitor_idx, boolean onlyActive); + private native int[] getMonitorMode0(String adapterName, int mode_idx); + private native int[] getMonitorDevice0(String adapterName, int adapter_idx, int monitor_idx, int monitorId); + private native boolean setMonitorMode0(int adapter_idx, int x, int y, int width, int height, int bits, int freq, int flags, int rot); } diff --git a/src/newt/classes/jogamp/newt/driver/x11/RandR11.java b/src/newt/classes/jogamp/newt/driver/x11/RandR11.java index d11703e47..a4c578b26 100644 --- a/src/newt/classes/jogamp/newt/driver/x11/RandR11.java +++ b/src/newt/classes/jogamp/newt/driver/x11/RandR11.java @@ -186,6 +186,7 @@ class RandR11 implements RandR { int i = 0; props[i++] = props.length; props[i++] = crt_idx; + props[i++] = 0; // is-clone props[i++] = widthMM; props[i++] = heightMM; props[i++] = 0; // rotated viewport x pixel-units diff --git a/src/newt/native/MacWindow.m b/src/newt/native/MacWindow.m index e0f8be856..690aaa505 100644 --- a/src/newt/native/MacWindow.m +++ b/src/newt/native/MacWindow.m @@ -517,6 +517,7 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_macosx_ScreenDriver_getMonit int offset = 0; prop[offset++] = propCount; prop[offset++] = crt_idx; + prop[offset++] = 0; // is-clone prop[offset++] = (jint) sizeMM.width; prop[offset++] = (jint) sizeMM.height; prop[offset++] = (jint) dBounds.origin.x; // rotated viewport x (pixel units, will be fixed in java code) diff --git a/src/newt/native/ScreenMode.h b/src/newt/native/ScreenMode.h index 56c424b11..18e773107 100644 --- a/src/newt/native/ScreenMode.h +++ b/src/newt/native/ScreenMode.h @@ -40,7 +40,7 @@ #define NUM_MONITOR_MODE_PROPERTIES_ALL 8 /* count + the above */ -#define MIN_MONITOR_DEVICE_PROPERTIES 15 /* count + id, ScreenSizeMM[width, height], rotated Viewport pixel-units, rotated Viewport pixel-units, currentMonitorModeId, rotation, supportedModeId+ */ +#define MIN_MONITOR_DEVICE_PROPERTIES 16 /* count + id + is_clone, ScreenSizeMM[width, height], rotated Viewport pixel-units, rotated Viewport pixel-units, currentMonitorModeId, rotation, supportedModeId+ */ /* Viewport := [x, y, width, height] (4 elements) */ #define FLAG_INTERLACE ( 1 << 0 ) diff --git a/src/newt/native/WindowsEDID.c b/src/newt/native/WindowsEDID.c new file mode 100644 index 000000000..d84773dc6 --- /dev/null +++ b/src/newt/native/WindowsEDID.c @@ -0,0 +1,419 @@ +/** + * Copyright 2015 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. + * + *** + * + * This code is inspired by Ofek Shilon's code and blog post: + * <http://ofekshilon.com/2014/06/19/reading-specific-monitor-dimensions/> + * See: function 'NewtEDID_GetMonitorSizeFromEDIDByModelName' + * + * In contrast to Ofek's code, function 'NewtEDID_GetMonitorSizeFromEDIDByDevice' + * uses the proper link from + * DISPLAY_DEVICE.DeviceID -> SP_DEVICE_INTERFACE_DETAIL_DATA.DevicePath, + * where DISPLAY_DEVICE.DeviceID is the monitor's enumeration via: + * EnumDisplayDevices(adapterName, monitor_idx, &ddMon, EDD_GET_DEVICE_INTERFACE_NAME); + * Hence the path to the registry-entry is well determined instead of just comparing + * the monitor's model name. + * + */ + +#include <Windows.h> +#include <Windowsx.h> +#include <tchar.h> +#include <stdlib.h> +#include <stdio.h> +#include <stddef.h> + +#include <SetupApi.h> +#include <cfgmgr32.h> // for MAX_DEVICE_ID_LEN + +#include "WindowsEDID.h" + +// #define VERBOSE_ON 1 + +#ifdef VERBOSE_ON + #define DBG_PRINT(x, ...) _ftprintf(stderr, __T(x), ##__VA_ARGS__); fflush(stderr) +#else + #define DBG_PRINT(...) +#endif + +#define NAME_SIZE 128 + +/* GetProcAddress doesn't exist in A/W variants under desktop Windows */ +#ifndef UNDER_CE +#define GetProcAddressA GetProcAddress +#endif + +#ifndef EDD_GET_DEVICE_INTERFACE_NAME +#define EDD_GET_DEVICE_INTERFACE_NAME 0x00000001 +#endif + +static const GUID GUID_CLASS_MONITOR = { 0x4d36e96e, 0xe325, 0x11ce, 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18 }; +static const GUID GUID_DEVINTERFACE_MONITOR = { 0xe6f07b5f, 0xee97, 0x4a90, 0xb0, 0x76, 0x33, 0xf5, 0x7b, 0xf4, 0xea, 0xa7 }; + +#ifdef _UNICODE +typedef HDEVINFO (WINAPI *SetupDiGetClassDevsPROCADDR)(CONST GUID *ClassGuid,PCWSTR Enumerator,HWND hwndParent,DWORD Flags); +typedef WINBOOL (WINAPI *SetupDiGetDeviceInstanceIdPROCADDR)(HDEVINFO DeviceInfoSet,PSP_DEVINFO_DATA DeviceInfoData,PCWSTR DeviceInstanceId,DWORD DeviceInstanceIdSize,PDWORD RequiredSize); +typedef WINBOOL (WINAPI *SetupDiGetDeviceInterfaceDetailPROCADDR)(HDEVINFO DeviceInfoSet,PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData,PSP_DEVICE_INTERFACE_DETAIL_DATA_W DeviceInterfaceDetailData,DWORD DeviceInterfaceDetailDataSize,PDWORD RequiredSize,PSP_DEVINFO_DATA DeviceInfoData); +#else +typedef HDEVINFO (WINAPI *SetupDiGetClassDevsPROCADDR)(CONST GUID *ClassGuid,PCSTR Enumerator,HWND hwndParent,DWORD Flags); +typedef WINBOOL (WINAPI *SetupDiGetDeviceInstanceIdPROCADDR)(HDEVINFO DeviceInfoSet,PSP_DEVINFO_DATA DeviceInfoData,PSTR DeviceInstanceId,DWORD DeviceInstanceIdSize,PDWORD RequiredSize); +typedef WINBOOL (WINAPI *SetupDiGetDeviceInterfaceDetailPROCADDR)(HDEVINFO DeviceInfoSet,PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData,PSP_DEVICE_INTERFACE_DETAIL_DATA_A DeviceInterfaceDetailData,DWORD DeviceInterfaceDetailDataSize,PDWORD RequiredSize,PSP_DEVINFO_DATA DeviceInfoData); +#endif + +typedef WINBOOL (WINAPI *SetupDiEnumDeviceInfoPROCADDR)(HDEVINFO DeviceInfoSet,DWORD MemberIndex,PSP_DEVINFO_DATA DeviceInfoData); +typedef WINBOOL (WINAPI *SetupDiEnumDeviceInterfacesPROCADDR)(HDEVINFO DeviceInfoSet,PSP_DEVINFO_DATA DeviceInfoData,CONST GUID *InterfaceClassGuid,DWORD MemberIndex,PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData); +typedef HKEY (WINAPI *SetupDiOpenDevRegKeyPROCADDR)(HDEVINFO DeviceInfoSet,PSP_DEVINFO_DATA DeviceInfoData,DWORD Scope,DWORD HwProfile,DWORD KeyType,REGSAM samDesired); +typedef WINBOOL (WINAPI *SetupDiDestroyDeviceInfoListPROCADDR)(HDEVINFO DeviceInfoSet); + +static int WinSetupAPI_avail = 0; +static SetupDiGetClassDevsPROCADDR WinSetup_SetupDiGetClassDevs = NULL; +static SetupDiGetDeviceInstanceIdPROCADDR WinSetup_SetupDiGetDeviceInstanceId = NULL; +static SetupDiGetDeviceInterfaceDetailPROCADDR WinSetup_SetupDiGetDeviceInterfaceDetail = NULL; +static SetupDiEnumDeviceInfoPROCADDR WinSetup_SetupDiEnumDeviceInfo = NULL; +static SetupDiEnumDeviceInterfacesPROCADDR WinSetup_SetupDiEnumDeviceInterfaces = NULL; +static SetupDiOpenDevRegKeyPROCADDR WinSetup_SetupDiOpenDevRegKey = NULL; +static SetupDiDestroyDeviceInfoListPROCADDR WinSetup_SetupDiDestroyDeviceInfoList = NULL; + +static int _init = 0; + +int NewtEDID_init() { + if( !_init ) { + WinSetupAPI_avail = 0; + HANDLE setup = LoadLibrary(TEXT("setupapi.dll")); + if( setup ) { + #ifdef _UNICODE + WinSetup_SetupDiGetClassDevs = (SetupDiGetClassDevsPROCADDR) GetProcAddressA(setup, "SetupDiGetClassDevsW"); + WinSetup_SetupDiGetDeviceInstanceId = (SetupDiGetDeviceInstanceIdPROCADDR) GetProcAddressA(setup, "SetupDiGetDeviceInstanceIdW"); + WinSetup_SetupDiGetDeviceInterfaceDetail = (SetupDiGetDeviceInterfaceDetailPROCADDR) GetProcAddressA(setup, "SetupDiGetDeviceInterfaceDetailW"); + #else + WinSetup_SetupDiGetClassDevs = (SetupDiGetClassDevsPROCADDR) GetProcAddressA(setup, "SetupDiGetClassDevsA"); + WinSetup_SetupDiGetDeviceInstanceId = (SetupDiGetDeviceInstanceIdPROCADDR) GetProcAddressA(setup, "SetupDiGetDeviceInstanceIdA"); + WinSetup_SetupDiGetDeviceInterfaceDetail = (SetupDiGetDeviceInterfaceDetailPROCADDR) GetProcAddressA(setup, "SetupDiGetDeviceInterfaceDetailA"); + #endif + WinSetup_SetupDiEnumDeviceInfo = (SetupDiEnumDeviceInfoPROCADDR) GetProcAddressA(setup, "SetupDiEnumDeviceInfo"); + WinSetup_SetupDiEnumDeviceInterfaces = (SetupDiEnumDeviceInterfacesPROCADDR) GetProcAddressA(setup, "SetupDiEnumDeviceInterfaces"); + WinSetup_SetupDiOpenDevRegKey = (SetupDiOpenDevRegKeyPROCADDR) GetProcAddressA(setup, "SetupDiOpenDevRegKey"); + WinSetup_SetupDiDestroyDeviceInfoList = (SetupDiDestroyDeviceInfoListPROCADDR) GetProcAddressA(setup, "SetupDiDestroyDeviceInfoList"); + if( NULL != WinSetup_SetupDiGetClassDevs && + NULL != WinSetup_SetupDiGetDeviceInstanceId && + NULL != WinSetup_SetupDiGetDeviceInterfaceDetail && + NULL != WinSetup_SetupDiEnumDeviceInfo && + NULL != WinSetup_SetupDiEnumDeviceInterfaces && + NULL != WinSetup_SetupDiOpenDevRegKey && + NULL != WinSetup_SetupDiDestroyDeviceInfoList ) { + WinSetupAPI_avail = 1; + } + } + _init = 1; + } + return WinSetupAPI_avail; +} + +static _TCHAR* Get2ndSlashBlock(const _TCHAR* sIn, _TCHAR* sOut, size_t sOutLen) +{ + _TCHAR* s = _tcschr(sIn, '\\'); + if( NULL != s ) { + s += 1; // skip '\\' + _TCHAR* t = _tcschr(s, '\\'); + if( NULL != t ) { + size_t len = t - s; + if( len > 0 ) { + if( sOutLen >= len ) { + _tcsncpy_s(sOut, sOutLen, s, len); + return sOut; + } + } + } + } + return NULL; +} + +static int GetMonitorSizeFromEDIDByRegKey(const HKEY hEDIDRegKey, int* widthMm, int* heightMm, int *widthCm, int *heightCm) +{ + DWORD dwType, actualValueNameLength = NAME_SIZE; + _TCHAR valueName[NAME_SIZE]; + + BYTE edidData[1024]; + DWORD edidSize = sizeof(edidData); + + *widthMm = -1; + *heightMm = -1; + *widthCm = -1; + *heightCm = -1; + + LONG retValue; + DWORD i; + for (i = 0, retValue = ERROR_SUCCESS; retValue != ERROR_NO_MORE_ITEMS; i++) { + retValue = RegEnumValue(hEDIDRegKey, i, &valueName[0], + &actualValueNameLength, NULL, &dwType, + edidData, // buffer + &edidSize); // buffer size + + if ( retValue == ERROR_SUCCESS && edidSize >= 23 && + 0 == _tcscmp(valueName, _T("EDID")) ) + { + DBG_PRINT("*** EDID Version %d.%d, data-size %d\n", (int)edidData[18], (int)edidData[19], edidSize); + if( edidSize >= 69 ) { + // 54 + 12 = 66: Horizontal display size, mm, 8 lsbits (0–4095 mm, 161 in) + // 54 + 13 = 67: Vertical display size, mm, 8 lsbits (0–4095 mm, 161 in) + // 54 + 14 = 68: + // Bits 7–4 Horizontal display size, mm, 4 msbits + // Bits 3–0 Vertical display size, mm, 4 msbits + *widthMm = ( (int)(edidData[68] & 0xF0) << 4 ) | (int)edidData[66]; + *heightMm = ( (int)(edidData[68] & 0x0F) << 8 ) | (int)edidData[67]; + } + *widthCm = (int) edidData[21]; + *heightCm = (int) edidData[22]; + return 1; // valid EDID found + } + } + return 0; // EDID not found +} + +int NewtEDID_GetMonitorSizeFromEDIDByModelName(const DISPLAY_DEVICE* ddMon, int* widthMm, int* heightMm, int *widthCm, int *heightCm) +{ + _TCHAR useDevModelNameStore[MAX_DEVICE_ID_LEN]; + _TCHAR *useDevModelName = Get2ndSlashBlock(ddMon->DeviceID, useDevModelNameStore, MAX_DEVICE_ID_LEN); + if( NULL == useDevModelName ) { + return 0; + } + + HDEVINFO devInfo = WinSetup_SetupDiGetClassDevs( + &GUID_CLASS_MONITOR, //class GUID + NULL, //enumerator + NULL, //HWND + DIGCF_PRESENT | DIGCF_PROFILE); // Flags //DIGCF_ALLCLASSES| + + if (NULL == devInfo) { + return 0; + } + + int bRes = 0; + DWORD i; + DWORD lastError = ERROR_SUCCESS; + for (i = 0; !bRes && ERROR_SUCCESS == lastError; i++) { + SP_DEVINFO_DATA devInfoData; + memset(&devInfoData, 0, sizeof(devInfoData)); + devInfoData.cbSize = sizeof(devInfoData); + + if (WinSetup_SetupDiEnumDeviceInfo(devInfo, i, &devInfoData)) { + _TCHAR devModelName[MAX_DEVICE_ID_LEN]; + WinSetup_SetupDiGetDeviceInstanceId(devInfo, &devInfoData, devModelName, MAX_PATH, NULL); + + if( NULL != _tcsstr(devModelName, useDevModelName) ) { + HKEY hEDIDRegKey = WinSetup_SetupDiOpenDevRegKey(devInfo, &devInfoData, + DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ); + + if ( 0 != hEDIDRegKey && hEDIDRegKey != INVALID_HANDLE_VALUE ) { + bRes = GetMonitorSizeFromEDIDByRegKey(hEDIDRegKey, widthMm, heightMm, widthCm, heightCm); + RegCloseKey(hEDIDRegKey); + } + } + } + lastError = GetLastError(); + } + WinSetup_SetupDiDestroyDeviceInfoList(devInfo); + return bRes; +} + +int NewtEDID_GetMonitorSizeFromEDIDByDevice(const DISPLAY_DEVICE* ddMon, int* widthMm, int* heightMm, int *widthCm, int *heightCm) +{ + HDEVINFO devInfo = WinSetup_SetupDiGetClassDevs( + &GUID_DEVINTERFACE_MONITOR, + NULL, //enumerator + NULL, //HWND + DIGCF_DEVICEINTERFACE | DIGCF_PRESENT); // Flags //DIGCF_ALLCLASSES| + + if (NULL == devInfo) { + return 0; + } + + DWORD devIfaceDetailDataSize = offsetof(SP_DEVICE_INTERFACE_DETAIL_DATA, DevicePath) + MAX_PATH * sizeof(TCHAR); + PSP_DEVICE_INTERFACE_DETAIL_DATA pDevIfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA) malloc(devIfaceDetailDataSize); + + int bRes = 0; + DWORD i; + DWORD lastError = ERROR_SUCCESS; + for (i = 0; !bRes && ERROR_SUCCESS == lastError; i++) { + SP_DEVICE_INTERFACE_DATA devIfaceData; + memset(&devIfaceData, 0, sizeof(devIfaceData)); + devIfaceData.cbSize = sizeof(devIfaceData); + + if ( WinSetup_SetupDiEnumDeviceInterfaces(devInfo, NULL, &GUID_DEVINTERFACE_MONITOR, i, &devIfaceData) ) { + memset(pDevIfaceDetailData, 0, devIfaceDetailDataSize); + pDevIfaceDetailData->cbSize = sizeof(*pDevIfaceDetailData); + DWORD devIfaceDetailDataReqSize = 0; + SP_DEVINFO_DATA devInfoData2; + memset(&devInfoData2, 0, sizeof(devInfoData2)); + devInfoData2.cbSize = sizeof(devInfoData2); + if( WinSetup_SetupDiGetDeviceInterfaceDetail(devInfo, &devIfaceData, pDevIfaceDetailData, devIfaceDetailDataSize, + &devIfaceDetailDataReqSize, &devInfoData2) ) { + int found = 0 == _tcsicmp(pDevIfaceDetailData->DevicePath, ddMon->DeviceID); + DBG_PRINT("*** Got[%d].2 found %d, devicePath <%s>\n", i, found, pDevIfaceDetailData->DevicePath); + if( found ) { + HKEY hEDIDRegKey = WinSetup_SetupDiOpenDevRegKey(devInfo, &devInfoData2, + DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ); + DBG_PRINT("*** Got[%d] hEDIDRegKey %p\n", i, (void*)hEDIDRegKey); + if ( 0 != hEDIDRegKey && hEDIDRegKey != INVALID_HANDLE_VALUE ) { + bRes = GetMonitorSizeFromEDIDByRegKey(hEDIDRegKey, widthMm, heightMm, widthCm, heightCm); + RegCloseKey(hEDIDRegKey); + } + } + } else { + lastError = GetLastError(); + DBG_PRINT("*** fail.2 at %d, werr %d\n", i, lastError); + } + } else { + lastError = GetLastError(); + DBG_PRINT("*** fail.1 at %d, werr %d\n", i, lastError); + } + } + DBG_PRINT("*** Result: found %d, enum-iter %d, werr %d\n", bRes, i, (int)lastError); + WinSetup_SetupDiDestroyDeviceInfoList(devInfo); + free(pDevIfaceDetailData); + return bRes; +} + +int NewtEDID_GetIndexedDisplayDevice(int useDevIdx, int useMonIdx, DISPLAY_DEVICE* ddMonOut, int getDeviceInterfaceName, int verbose) +{ + DISPLAY_DEVICE ddAdp; + DWORD devIdx; // device index + DWORD monIdx; // monitor index + + memset(&ddAdp, 0, sizeof(ddAdp)); + ddAdp.cb = sizeof(ddAdp); + + const DWORD dwFlagsMonitor = 0 != getDeviceInterfaceName ? EDD_GET_DEVICE_INTERFACE_NAME : 0; + + for(devIdx = 0; + ( devIdx <= useDevIdx || 0 > useDevIdx ) && EnumDisplayDevices(0, devIdx, &ddAdp, 0); + devIdx++) + { + if( NULL != ddAdp.DeviceName && 0 != _tcslen(ddAdp.DeviceName) ) { + if( verbose ) { + _ftprintf(stderr, __T("*** [%02d:__]: deviceName <%s> flags 0x%X active %d\n"), + devIdx, ddAdp.DeviceName, ddAdp.StateFlags, ( 0 != ( ddAdp.StateFlags & DISPLAY_DEVICE_ACTIVE ) ) ); + _ftprintf(stderr, __T(" deviceString <%s> \n"), ddAdp.DeviceString); + _ftprintf(stderr, __T(" deviceID <%s> \n"), ddAdp.DeviceID); + } + if( devIdx == useDevIdx || 0 > useDevIdx ) { + DISPLAY_DEVICE ddMon; + memset(&ddMon, 0, sizeof(ddMon)); + ddMon.cb = sizeof(ddMon); + + for(monIdx = 0; + ( monIdx <= useMonIdx || 0 > useMonIdx ) && EnumDisplayDevices(ddAdp.DeviceName, monIdx, &ddMon, dwFlagsMonitor); + monIdx++) + { + if( NULL != ddMon.DeviceName && 0 < _tcslen(ddMon.DeviceName) ) { + if( verbose ) { + _ftprintf(stderr, __T("*** [%02d:%02d]: deviceName <%s> flags 0x%X active %d\n"), + devIdx, monIdx, ddMon.DeviceName, ddMon.StateFlags, ( 0 != ( ddMon.StateFlags & DISPLAY_DEVICE_ACTIVE ) ) ); + _ftprintf(stderr, __T(" deviceString <%s> \n"), ddMon.DeviceString); + _ftprintf(stderr, __T(" deviceID <%s> \n"), ddMon.DeviceID); + } + if( monIdx == useMonIdx ) { + *ddMonOut = ddMon; + return 1; + } + } + memset(&ddMon, 0, sizeof(ddMon)); + ddMon.cb = sizeof(ddMon); + } + } + } + memset(&ddAdp, 0, sizeof(ddAdp)); + ddAdp.cb = sizeof(ddAdp); + } + memset(ddMonOut, 0, sizeof(*ddMonOut)); + ddMonOut->cb = sizeof(*ddMonOut); + return 0; +} + +#ifdef WINDOWS_EDID_WITH_MAIN + +int _tmain(int argc, _TCHAR* argv []) +{ +#ifdef _UNICODE + _ftprintf(stderr, __T("_UNICODE enabled\n")); +#else + fprintf(stderr, "_UNICODE disabled\n"); +#endif + if( !NewtEDID_init() ) { + _ftprintf(stderr, __T("setupapi not available\n")); + return 1; + } + DISPLAY_DEVICE ddMon; + + if( 3 != argc ) { + NewtEDID_GetIndexedDisplayDevice(-1, -1, &ddMon, 0 /* getDeviceInterfaceName */, 1 /* verbose */); + _ftprintf(stderr, __T("Usage: %s dev-idx mon-idx\n"), argv[0]); + return 1; + } + int useDevIdx = _tstoi(argv[1]); + int useMonIdx = _tstoi(argv[2]); + int widthMm, heightMm; + int widthCm, heightCm; + + // + // Proper method + // + if( 0 == NewtEDID_GetIndexedDisplayDevice(useDevIdx, useMonIdx, &ddMon, 1 /* getDeviceInterfaceName */, 0 /* verbose */) ) { + _ftprintf(stderr, __T("No monitor found at dev %d : mon %d\n"), useDevIdx, useMonIdx); + return 1; + } + _ftprintf(stderr, __T("Found monitor at dev %d : mon %d:\n"), useDevIdx, useMonIdx); + _ftprintf(stderr, __T(" Device Name : %s\n"), ddMon.DeviceName); + _ftprintf(stderr, __T(" Device String: %s\n"), ddMon.DeviceString); + _ftprintf(stderr, __T(" Device ID : %s\n"), ddMon.DeviceID); + fflush(NULL); + + if( NewtEDID_GetMonitorSizeFromEDIDByDevice(&ddMon, &widthMm, &heightMm, &widthCm, &heightCm) ) { + _ftprintf(stderr, __T("Proper: Found EDID size [%d, %d] [mm], [%d, %d] [cm]\n"), widthMm, heightMm, widthCm, heightCm); + } + + // + // Monitor model name method + // + if( 0 == NewtEDID_GetIndexedDisplayDevice(useDevIdx, useMonIdx, &ddMon, 0 /* getDeviceInterfaceName */, 0 /* verbose */) ) { + _ftprintf(stderr, __T("No monitor found at dev %d : mon %d\n"), useDevIdx, useMonIdx); + return 1; + } + _ftprintf(stderr, __T("Found monitor at dev %d : mon %d:\n"), useDevIdx, useMonIdx); + _ftprintf(stderr, __T(" Device Name : %s\n"), ddMon.DeviceName); + _ftprintf(stderr, __T(" Device String: %s\n"), ddMon.DeviceString); + _ftprintf(stderr, __T(" Device ID : %s\n"), ddMon.DeviceID); + fflush(NULL); + + if( NewtEDID_GetMonitorSizeFromEDIDByModelName(&ddMon, &widthMm, &heightMm, &widthCm, &heightCm) ) { + _ftprintf(stderr, __T("ModelN: Found EDID size [%d, %d] [mm], [%d, %d] [cm]\n"), widthMm, heightMm, widthCm, heightCm); + } + return 0; +} + +#endif /* WINDOWS_EDID_WITH_MAIN */ diff --git a/src/newt/native/WindowsEDID.h b/src/newt/native/WindowsEDID.h new file mode 100644 index 000000000..ea80ca6df --- /dev/null +++ b/src/newt/native/WindowsEDID.h @@ -0,0 +1,40 @@ +/** + * Copyright 2015 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. + */ + +#ifndef _WINDOWS_EDID_H_ +#define _WINDOWS_EDID_H_ + +#include <Windows.h> +#include <Wingdi.h> + +int NewtEDID_init(); +int NewtEDID_GetMonitorSizeFromEDIDByModelName(const DISPLAY_DEVICE* ddMon, int* widthMm, int* heightMm, int *widthCm, int *heightCm); +int NewtEDID_GetMonitorSizeFromEDIDByDevice(const DISPLAY_DEVICE* ddMon, int* widthMm, int* heightMm, int *widthCm, int *heightCm); +int NewtEDID_GetIndexedDisplayDevice(int useDevIdx, int useMonIdx, DISPLAY_DEVICE* ddMonOut, int getDeviceInterfaceName, int verbose); + +#endif /* _WINDOWS_EDID_H_ */ diff --git a/src/newt/native/WindowsWindow.c b/src/newt/native/WindowsWindow.c index 70d0c6f83..7e15cd925 100644 --- a/src/newt/native/WindowsWindow.c +++ b/src/newt/native/WindowsWindow.c @@ -108,6 +108,10 @@ #define TOUCH_COORD_TO_PIXEL(l) (l/100) #endif +#ifndef EDD_GET_DEVICE_INTERFACE_NAME +#define EDD_GET_DEVICE_INTERFACE_NAME 0x00000001 +#endif + #ifndef MONITOR_DEFAULTTONULL #define MONITOR_DEFAULTTONULL 0 #endif @@ -139,16 +143,18 @@ #include "NewtCommon.h" +#include "WindowsEDID.h" + // #define VERBOSE_ON 1 // #define DEBUG_KEYS 1 #ifdef VERBOSE_ON - #define DBG_PRINT(...) fprintf(stderr, __VA_ARGS__); fflush(stderr) + #define DBG_PRINT(x, ...) _ftprintf(stderr, __T(x), ##__VA_ARGS__); fflush(stderr) #else #define DBG_PRINT(...) #endif -#define STD_PRINT(...) fprintf(stderr, __VA_ARGS__); fflush(stderr) +#define STD_PRINT(x, ...) _ftprintf(stderr, __T(x), ##__VA_ARGS__); fflush(stderr) static jmethodID insetsChangedID = NULL; static jmethodID sizeChangedID = NULL; @@ -175,6 +181,8 @@ static IsTouchWindowPROCADDR WinTouch_IsTouchWindow = NULL; static RegisterTouchWindowPROCADDR WinTouch_RegisterTouchWindow = NULL; static UnregisterTouchWindowPROCADDR WinTouch_UnregisterTouchWindow = NULL; +static int NewtEDID_avail = 0; + static RECT* UpdateInsets(JNIEnv *env, jobject window, HWND hwnd); typedef struct { @@ -1629,11 +1637,15 @@ static int NewtScreen_RotationNewtCCW2NativeCCW(JNIEnv *env, jint newt) { return native; } -static LPCTSTR NewtScreen_getAdapterName(DISPLAY_DEVICE * device, int crt_idx) { +static LPCTSTR NewtScreen_getAdapterName(DISPLAY_DEVICE * device, int adapter_idx) { + if( 0 > adapter_idx ) { + DBG_PRINT("*** WindowsWindow: getAdapterName(adapter_idx %d < 0)\n", adapter_idx); + return NULL; + } memset(device, 0, sizeof(DISPLAY_DEVICE)); device->cb = sizeof(DISPLAY_DEVICE); - if( FALSE == EnumDisplayDevices(NULL, crt_idx, device, 0) ) { - DBG_PRINT("*** WindowsWindow: getAdapterName.EnumDisplayDevices(crt_idx %d) -> FALSE\n", crt_idx); + if( FALSE == EnumDisplayDevices(NULL, adapter_idx, device, 0) ) { + DBG_PRINT("*** WindowsWindow: getAdapterName.EnumDisplayDevices(adapter_idx %d) -> FALSE\n", adapter_idx); return NULL; } @@ -1645,19 +1657,22 @@ static LPCTSTR NewtScreen_getAdapterName(DISPLAY_DEVICE * device, int crt_idx) { } static LPCTSTR NewtScreen_getMonitorName(LPCTSTR adapterName, DISPLAY_DEVICE * device, int monitor_idx, BOOL onlyActive) { + if( 0 > monitor_idx ) { + DBG_PRINT("*** WindowsWindow: getMonitorName(monitor_idx %d < 0)\n", monitor_idx); + return NULL; + } memset(device, 0, sizeof(DISPLAY_DEVICE)); device->cb = sizeof(DISPLAY_DEVICE); - if( 0 == monitor_idx ) { - if( FALSE == EnumDisplayDevices(adapterName, monitor_idx, device, 0) ) { - DBG_PRINT("*** WindowsWindow: getDisplayName.EnumDisplayDevices(monitor_idx %d).adapter -> FALSE\n", monitor_idx); + if( FALSE == EnumDisplayDevices(adapterName, monitor_idx, device, EDD_GET_DEVICE_INTERFACE_NAME) ) { + DBG_PRINT("*** WindowsWindow: getMonitorName.EnumDisplayDevices(monitor_idx %d).adapter -> FALSE\n", monitor_idx); + return NULL; + } + if( onlyActive ) { + if( 0 == ( device->StateFlags & DISPLAY_DEVICE_ACTIVE ) ) { + DBG_PRINT("*** WindowsWindow: !DISPLAY_DEVICE_ACTIVE(monitor_idx %d).display\n", monitor_idx); return NULL; } } - - if( onlyActive && 0 == ( device->StateFlags & DISPLAY_DEVICE_ACTIVE ) ) { - DBG_PRINT("*** WindowsWindow: !DISPLAY_DEVICE_ACTIVE(monitor_idx %d).display\n", monitor_idx); - return NULL; - } if( NULL == device->DeviceName || 0 == _tcslen(device->DeviceName) ) { return NULL; } @@ -1665,6 +1680,23 @@ static LPCTSTR NewtScreen_getMonitorName(LPCTSTR adapterName, DISPLAY_DEVICE * d return device->DeviceName; } +static int NewtScreen_getFirstActiveNonCloneMonitor(LPCTSTR adapterName, DISPLAY_DEVICE * device) { + memset(device, 0, sizeof(DISPLAY_DEVICE)); + device->cb = sizeof(DISPLAY_DEVICE); + int monitor_idx; + for(monitor_idx=0; EnumDisplayDevices(adapterName, monitor_idx, device, EDD_GET_DEVICE_INTERFACE_NAME); monitor_idx++) { + if( NULL != device->DeviceName && + 0 < _tcslen(device->DeviceName) && + 0 != ( device->StateFlags & DISPLAY_DEVICE_ACTIVE ) && + 0 == ( device->StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER ) ) { + return monitor_idx; + } + memset(device, 0, sizeof(DISPLAY_DEVICE)); + device->cb = sizeof(DISPLAY_DEVICE); + } + return -1; +} + JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_dumpMonitorInfo0 (JNIEnv *env, jclass clazz) { @@ -1672,10 +1704,18 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_dumpMonitorI int i = 0, j; LPCTSTR aName, dName; while(NULL != (aName = NewtScreen_getAdapterName(&aDevice, i))) { - fprintf(stderr, "*** [%d]: <%s> flags 0x%X active %d\n", i, aName, aDevice.StateFlags, ( 0 != ( aDevice.StateFlags & DISPLAY_DEVICE_ACTIVE ) ) ); + STD_PRINT("*** [%02d:__]: deviceName <%s> flags 0x%X active %d\n", + i, aDevice.DeviceName, aDevice.StateFlags, ( 0 != ( aDevice.StateFlags & DISPLAY_DEVICE_ACTIVE ) ) ); + STD_PRINT(" deviceString <%s> \n", aDevice.DeviceString); + STD_PRINT(" deviceID <%s> \n", aDevice.DeviceID); j=0; while(NULL != (dName = NewtScreen_getMonitorName(aName, &dDevice, j, FALSE))) { - fprintf(stderr, "*** [%d][%d]: <%s> flags 0x%X active %d\n", i, j, dName, dDevice.StateFlags, ( 0 != ( dDevice.StateFlags & DISPLAY_DEVICE_ACTIVE ) ) ); + STD_PRINT("*** [%02d:%02d]: deviceName <%s> flags 0x%X active %d, mirror %d\n", + i, j, dDevice.DeviceName, dDevice.StateFlags, + 0 != ( dDevice.StateFlags & DISPLAY_DEVICE_ACTIVE ), + 0 != ( dDevice.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER ) ); + STD_PRINT(" deviceString <%s> \n", dDevice.DeviceString); + STD_PRINT(" deviceID <%s> \n", dDevice.DeviceID); j++; } i++; @@ -1692,11 +1732,11 @@ static HDC NewtScreen_createDisplayDC(LPCTSTR displayDeviceName) { * Signature: (I)Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getAdapterName0 - (JNIEnv *env, jobject obj, jint crt_idx) + (JNIEnv *env, jobject obj, jint adapter_idx) { DISPLAY_DEVICE device; - LPCTSTR adapterName = NewtScreen_getAdapterName(&device, crt_idx); - DBG_PRINT("*** WindowsWindow: getAdapterName(crt_idx %d) -> %s, active %d\n", crt_idx, + LPCTSTR adapterName = NewtScreen_getAdapterName(&device, adapter_idx); + DBG_PRINT("*** WindowsWindow: getAdapterName(adapter_idx %d) -> %s, active %d\n", adapter_idx, (NULL==adapterName?"nil":adapterName), 0 == ( device.StateFlags & DISPLAY_DEVICE_ACTIVE )); if(NULL == adapterName) { return NULL; @@ -1710,22 +1750,22 @@ JNIEXPORT jstring JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getAdapte /* * Class: jogamp_newt_driver_windows_ScreenDriver - * Method: getActiveMonitorName0 - * Signature: (Ljava/lang/String;I)Ljava/lang/String; + * Method: getMonitorName0 + * Signature: (Ljava/lang/String;IZ)Ljava/lang/String; */ -JNIEXPORT jstring JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getActiveMonitorName0 - (JNIEnv *env, jobject obj, jstring jAdapterName, jint monitor_idx) +JNIEXPORT jstring JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getMonitorName0 + (JNIEnv *env, jobject obj, jstring jAdapterName, jint monitor_idx, jboolean onlyActive) { DISPLAY_DEVICE device; LPCTSTR monitorName; #ifdef UNICODE LPCTSTR adapterName = NewtCommon_GetNullTerminatedStringChars(env, jAdapterName); - monitorName = NewtScreen_getMonitorName(adapterName, &device, monitor_idx, TRUE); + monitorName = NewtScreen_getMonitorName(adapterName, &device, monitor_idx, onlyActive); DBG_PRINT("*** WindowsWindow: getMonitorName(%s, monitor_idx %d) -> %s\n", adapterName, monitor_idx, (NULL==monitorName?"nil":monitorName)); free((void*) adapterName); #else LPCTSTR adapterName = (*env)->GetStringUTFChars(env, jAdapterName, NULL); - monitorName = NewtScreen_getMonitorName(adapterName, &device, monitor_idx, TRUE); + monitorName = NewtScreen_getMonitorName(adapterName, &device, monitor_idx, onlyActive); DBG_PRINT("*** WindowsWindow: getMonitorName(%s, monitor_idx %d) -> %s\n", adapterName, monitor_idx, (NULL==monitorName?"nil":monitorName)); (*env)->ReleaseStringUTFChars(env, jAdapterName, adapterName); #endif @@ -1815,12 +1855,11 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getMoni /* * Class: jogamp_newt_driver_windows_ScreenDriver * Method: getMonitorDevice0 - * Signature: (Ljava/lang/String;I)[I + * Signature: (Ljava/lang/String;II)[I */ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getMonitorDevice0 - (JNIEnv *env, jobject obj, jstring jAdapterName, jint monitor_idx) + (JNIEnv *env, jobject obj, jstring jAdapterName, jint adapter_idx, jint monitor_idx, jint monitor_id) { - DISPLAY_DEVICE device; LPCTSTR adapterName; { #ifdef UNICODE @@ -1830,10 +1869,37 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getMoni #endif } - HDC hdc = NewtScreen_createDisplayDC(adapterName); - int widthmm = GetDeviceCaps(hdc, HORZSIZE); - int heightmm = GetDeviceCaps(hdc, VERTSIZE); - DeleteDC(hdc); + DBG_PRINT("*** WindowsWindow: adapter[name %s, idx %d], monitor[idx %d, id %d], EDID-avail %d\n", + adapterName, adapter_idx, monitor_idx, monitor_id, NewtEDID_avail); + int gotsize = 0; + int widthmm, heightmm; + DISPLAY_DEVICE monitorDevice; + LPCTSTR monitorName = NewtScreen_getMonitorName(adapterName, &monitorDevice, monitor_idx, TRUE); + if( NewtEDID_avail ) { + int widthcm, heightcm; + if( NULL != monitorName && + NewtEDID_GetMonitorSizeFromEDIDByDevice(&monitorDevice, &widthmm, &heightmm, &widthcm, &heightcm) ) { + DBG_PRINT("*** WindowsWindow: EDID %d x %d [mm], %d x %d [cm]\n", widthmm, heightmm, widthcm, heightcm); + if( 0 <= widthmm && 0 <= heightmm ) { + gotsize = 1; // got mm values + DBG_PRINT("*** WindowsWindow: %d x %d [mm] (EDID mm)\n", widthmm, heightmm); + } else if( 0 <= widthcm && 0 <= heightcm ) { + // fallback using cm values + widthmm = widthcm * 10; + heightmm = heightcm * 10; + gotsize = 1; + DBG_PRINT("*** WindowsWindow: %d x %d [mm] (EDID cm)\n", widthmm, heightmm); + } + } + } + if( !gotsize ) { + // fallback using buggy API resulting in erroneous values + HDC hdc = NewtScreen_createDisplayDC(adapterName); + widthmm = GetDeviceCaps(hdc, HORZSIZE); + heightmm = GetDeviceCaps(hdc, VERTSIZE); + DeleteDC(hdc); + DBG_PRINT("*** WindowsWindow: %d x %d [mm] (Buggy API)\n", widthmm, heightmm); + } int devModeID = ENUM_CURRENT_SETTINGS; DEVMODE dm; @@ -1856,7 +1922,8 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getMoni int propIndex = 0; prop[propIndex++] = propCount; - prop[propIndex++] = monitor_idx; + prop[propIndex++] = monitor_id; + prop[propIndex++] = NULL != monitorName && 0 != ( monitorDevice.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER ); prop[propIndex++] = widthmm; prop[propIndex++] = heightmm; prop[propIndex++] = dm.dmPosition.x; // rotated viewport pixel units @@ -1883,18 +1950,22 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getMoni * Signature: (IIIIIIIII)Z */ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_setMonitorMode0 - (JNIEnv *env, jobject object, jint monitor_idx, jint x, jint y, jint width, jint height, jint bits, jint rate, jint flags, jint rot) + (JNIEnv *env, jobject object, jint adapter_idx, jint x, jint y, jint width, jint height, jint bits, jint rate, jint flags, jint rot) { DISPLAY_DEVICE adapterDevice, monitorDevice; - LPCTSTR adapterName = NewtScreen_getAdapterName(&adapterDevice, monitor_idx); + LPCTSTR adapterName = NewtScreen_getAdapterName(&adapterDevice, adapter_idx); if(NULL == adapterName) { - DBG_PRINT("*** WindowsWindow: setMonitorMode.getAdapterName(monitor_idx %d) -> NULL\n", monitor_idx); + DBG_PRINT("*** WindowsWindow: setMonitorMode.getAdapterName(adapter_idx %d) -> NULL\n", adapter_idx); return JNI_FALSE; } - LPCTSTR monitorName = NewtScreen_getMonitorName(adapterName, &monitorDevice, 0, TRUE); - if(NULL == monitorName) { - DBG_PRINT("*** WindowsWindow: setMonitorMode.getMonitorName(monitor_idx 0) -> NULL\n"); - return JNI_FALSE; + + { + // Just test whether there is an active non-mirror monitor attached + int monitor_idx = NewtScreen_getFirstActiveNonCloneMonitor(adapterName, &monitorDevice); + if( 0 > monitor_idx ) { + DBG_PRINT("*** WindowsWindow: setMonitorMode.getFirstActiveNonCloneMonitor(%s) -> n/a\n", adapterName); + return JNI_FALSE; + } } DEVMODE dm; @@ -1981,6 +2052,7 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_windows_WindowDriver_initIDs0 WinTouch_func_avail = 0; } } + NewtEDID_avail = NewtEDID_init(); } return JNI_TRUE; } diff --git a/src/newt/native/X11Display.c b/src/newt/native/X11Display.c index b62a9b234..60daf1af2 100644 --- a/src/newt/native/X11Display.c +++ b/src/newt/native/X11Display.c @@ -30,7 +30,7 @@ #include <X11/Xcursor/Xcursor.h> -// #include <X11/XKBlib.h> // XKB disabled for now +#include <X11/XKBlib.h> jclass X11NewtWindowClazz = NULL; jmethodID insetsChangedID = NULL; diff --git a/src/newt/native/X11RandR13.c b/src/newt/native/X11RandR13.c index 4e92a32b4..1d721efcb 100644 --- a/src/newt/native/X11RandR13.c +++ b/src/newt/native/X11RandR13.c @@ -26,7 +26,7 @@ * or implied, of JogAmp Community. */ -#include "X11Common.h" +#include "X11Screen.h" /* * Class: jogamp_newt_driver_x11_RandR13 @@ -67,9 +67,16 @@ static void dumpOutputs(const char *prefix, Display *dpy, XRRScreenResources *re for(i=0; i<noutput; i++) { RROutput output = outputs[i]; XRROutputInfo * xrrOutputInfo = XRRGetOutputInfo (dpy, resources, output); - fprintf(stderr, " Output[%d]: id %#lx, crtx 0x%X, name %s (%d), %lux%lu, ncrtc %d, .., nmode %d (preferred %d)\n", - i, output, xrrOutputInfo->crtc, SAFE_STRING(xrrOutputInfo->name), xrrOutputInfo->nameLen, xrrOutputInfo->mm_width, xrrOutputInfo->mm_height, - xrrOutputInfo->ncrtc, xrrOutputInfo->nmode, xrrOutputInfo->npreferred); + fprintf(stderr, " Output[%d]: id %#lx, crtx 0x%lX, name %s (%d), %lux%lu, ncrtc %d, nclone %d, nmode %d (preferred %d)\n", + i, output, xrrOutputInfo->crtc, SAFE_STRING(xrrOutputInfo->name), xrrOutputInfo->nameLen, + xrrOutputInfo->mm_width, xrrOutputInfo->mm_height, + xrrOutputInfo->ncrtc, xrrOutputInfo->nclone, xrrOutputInfo->nmode, xrrOutputInfo->npreferred); + for(j=0; j<xrrOutputInfo->ncrtc; j++) { + fprintf(stderr, " Output[%d].Crtc[%d].id %#lx\n", i, j, xrrOutputInfo->crtcs[j]); + } + for(j=0; j<xrrOutputInfo->nclone; j++) { + fprintf(stderr, " Output[%d].Clones[%d].id %#lx\n", i, j, xrrOutputInfo->clones[j]); + } for(j=0; j<xrrOutputInfo->nmode; j++) { fprintf(stderr, " Output[%d].Mode[%d].id %#lx\n", i, j, xrrOutputInfo->modes[j]); } @@ -424,6 +431,7 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_RandR13_getMonitorDevice prop[propIndex++] = propCount; prop[propIndex++] = crt_idx; + prop[propIndex++] = 0; // is_clone, does not work: 0 < xrrOutputInfo->nclone ? 1 : 0; prop[propIndex++] = xrrOutputInfo->mm_width; prop[propIndex++] = xrrOutputInfo->mm_height; prop[propIndex++] = xrrCrtcInfo->x; // rotated viewport pixel units diff --git a/src/newt/native/X11Window.c b/src/newt/native/X11Window.c index 2cc66c78d..43506c6a6 100644 --- a/src/newt/native/X11Window.c +++ b/src/newt/native/X11Window.c @@ -489,7 +489,7 @@ static Bool WaitForUnmapNotify( Display *dpy, XEvent *event, XPointer arg ) { } static void NewtWindows_setPosSize(Display *dpy, Window w, jint x, jint y, jint width, jint height) { - if(width>0 && height>0 || x>=0 && y>=0) { // resize/position if requested + if( ( width>0 && height>0 ) || ( x>=0 && y>=0 ) ) { // resize/position if requested XWindowChanges xwc; int flags = CWX | CWY; diff --git a/src/newt/native/bcm_vc_iv.c b/src/newt/native/bcm_vc_iv.c index ee59f0aa6..6b1ee3aaf 100644 --- a/src/newt/native/bcm_vc_iv.c +++ b/src/newt/native/bcm_vc_iv.c @@ -357,7 +357,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_bcm_vc_iv_WindowDriver_CreateWin VC_RECT_T src_rect; if( 0 == display ) { - return; + return 0; } dst_rect.x = x; dst_rect.y = y; diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/awt/TestGearsES2GLJPanelAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/awt/TestGearsES2GLJPanelAWT.java index 4b17f3011..dfc2d1165 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/awt/TestGearsES2GLJPanelAWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/awt/TestGearsES2GLJPanelAWT.java @@ -31,8 +31,6 @@ package com.jogamp.opengl.test.junit.jogl.demos.es2.awt; import java.awt.AWTException; import java.awt.BorderLayout; import java.awt.Dimension; -import java.awt.DisplayMode; -import java.awt.GraphicsDevice; import java.lang.reflect.InvocationTargetException; import com.jogamp.nativewindow.ScalableSurface; @@ -44,9 +42,12 @@ import com.jogamp.opengl.GLCapabilitiesImmutable; import com.jogamp.opengl.GLEventListener; import com.jogamp.opengl.GLProfile; import com.jogamp.opengl.awt.GLJPanel; + import javax.swing.JFrame; import javax.swing.SwingUtilities; +import jogamp.newt.awt.NewtFactoryAWT; + import org.junit.AfterClass; import org.junit.Assert; import org.junit.Assume; @@ -55,13 +56,9 @@ import org.junit.Test; import org.junit.FixMethodOrder; import org.junit.runners.MethodSorters; -import com.jogamp.newt.Display; import com.jogamp.newt.MonitorDevice; -import com.jogamp.newt.NewtFactory; import com.jogamp.newt.Screen; import com.jogamp.newt.event.KeyEvent; -import com.jogamp.newt.event.MonitorEvent; -import com.jogamp.newt.event.MonitorModeListener; import com.jogamp.newt.event.TraceKeyAdapter; import com.jogamp.newt.event.TraceWindowAdapter; import com.jogamp.newt.event.awt.AWTKeyAdapter; @@ -178,6 +175,10 @@ public class TestGearsES2GLJPanelAWT extends UITestCase { Assert.assertEquals(true, AWTRobotUtil.waitForVisible(frame, true)); Assert.assertEquals(true, AWTRobotUtil.waitForRealized(glJPanel, true)); + final Screen screen = NewtFactoryAWT.createScreen(glJPanel, true); + screen.addReference(); // initial native creation - keep alive! + System.err.println("GetPixelScale: AWT -> Screen: "+screen); + final float[] hasSurfacePixelScale1 = glJPanel.getCurrentSurfaceScale(new float[2]); System.err.println("HiDPI PixelScale: "+reqSurfacePixelScale[0]+"x"+reqSurfacePixelScale[1]+" (req) -> "+ valReqSurfacePixelScale[0]+"x"+valReqSurfacePixelScale[1]+" (val) -> "+ @@ -200,36 +201,30 @@ public class TestGearsES2GLJPanelAWT extends UITestCase { if( e.isAutoRepeat() ) { return; } - if(e.getKeyChar()=='p') { + if( e.getKeySymbol() == KeyEvent.VK_P ) { System.err.println(); - final java.awt.Point los = glJPanel.getLocationOnScreen(); - final RectangleImmutable r = new Rectangle(los.x, los.y, glJPanel.getWidth(), glJPanel.getHeight()); - final GraphicsDevice gd = glJPanel.getGraphicsConfiguration().getDevice(); - final DisplayMode dm = gd.getDisplayMode(); - System.err.printf("GetPixelScale: AWT DisplayMode %d x %d pixel-units%n", dm.getWidth(), dm.getHeight()); - System.err.printf("GetPixelScale: NW Screen: %s%n", glJPanel.getNativeSurface().getGraphicsConfiguration().getScreen()); - System.err.printf("GetPixelScale: Panel Bounds: %s window-units%n", r.toString()); - System.err.printf("GetPixelScale: Panel Resolution: %d x %d pixel-units%n", glJPanel.getSurfaceWidth(), glJPanel.getSurfaceHeight()); { - final Display dpy = NewtFactory.createDisplay(null); - final Screen screen = NewtFactory.createScreen(dpy, 0); - screen.addReference(); - final MonitorModeListener sml = new MonitorModeListener() { - @Override - public void monitorModeChangeNotify(final MonitorEvent me) { - } - @Override - public void monitorModeChanged(final MonitorEvent me, final boolean success) { - } - }; - screen.addMonitorModeListener(sml); - try { - final MonitorDevice md = screen.getMainMonitor(r); - System.err.printf("GetPixelScale: %s%n", md.toString()); - } finally { - screen.removeReference(); - } + // Just for manual validation! + final java.awt.Point los = glJPanel.getLocationOnScreen(); + final RectangleImmutable r = new Rectangle(los.x, los.y, glJPanel.getWidth(), glJPanel.getHeight()); + System.err.printf("GetPixelScale: Panel Bounds: %s window-units%n", r.toString()); + System.err.printf("GetPixelScale: Panel Resolution: %d x %d pixel-units%n", glJPanel.getSurfaceWidth(), glJPanel.getSurfaceHeight()); + } + final MonitorDevice monitor = NewtFactoryAWT.getMonitorDevice(screen, glJPanel); + System.err.printf("GetPixelScale: %s%n", monitor.toString()); + final float[] pixelPerMM; + final boolean cached; + if( e.isShiftDown() ) { + // SHIFT: query current mode! + pixelPerMM = monitor.getPixelsPerMM(monitor.queryCurrentMode(), new float[2]); + cached = false; + } else { + // Default: Use cached mode! + pixelPerMM = monitor.getPixelsPerMM(new float[2]); + cached = true; } + System.err.println(" pixel/mm ["+pixelPerMM[0]+", "+pixelPerMM[1]+"], cached-mode "+cached); + System.err.println(" pixel/in ["+pixelPerMM[0]*25.4f+", "+pixelPerMM[1]*25.4f+"], cached-mode "+cached); System.err.println(); } else if(e.getKeyChar()=='x') { final float[] hadSurfacePixelScale = glJPanel.getCurrentSurfaceScale(new float[2]); @@ -313,6 +308,7 @@ public class TestGearsES2GLJPanelAWT extends UITestCase { glJPanel.destroy(); frame.dispose(); } } ); + screen.removeReference(); // final native destroy } @Test diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPixelFormatUtil00NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPixelFormatUtil00NEWT.java index 16158a0f0..d822f237d 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPixelFormatUtil00NEWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPixelFormatUtil00NEWT.java @@ -237,7 +237,7 @@ public class TestPixelFormatUtil00NEWT extends UITestCase { * Note: Fixes bit-rounding errors, i.e. RGBA5551: A 0.6f -> 0x01 -> 1f ... -> RGBA8888: A 0xff */ static final float sourceNorm(final PixelFormat.Composition srcComp, final int sIdx, final float f) { - if( sIdx >= 0 && sIdx < srcComp.componenCount() ) { + if( sIdx >= 0 && sIdx < srcComp.componentCount() ) { return srcComp.toFloat(srcComp.fromFloat(f, sIdx, false), sIdx, false); } else { return 0f; @@ -245,7 +245,7 @@ public class TestPixelFormatUtil00NEWT extends UITestCase { } static final byte rescaleComp(final PixelFormat.Composition srcComp, final int sIdx, final PixelFormat.Composition dstComp, final int dIdx, final float f) { - if( dIdx >= 0 && dIdx < dstComp.componenCount() ) { + if( dIdx >= 0 && dIdx < dstComp.componentCount() ) { return (byte)dstComp.fromFloat(sourceNorm(srcComp, sIdx, f), dIdx, false); } else { return (byte)0; @@ -543,7 +543,7 @@ public class TestPixelFormatUtil00NEWT extends UITestCase { if( PixelFormat.LUMINANCE != srcFmt && PixelFormat.LUMINANCE == destFmt ) { // Cannot convert: RGB* -> LUM -> RGB* System.err.println("CONVERT["+i+"]["+j+"]: Conv2: Dropped due to RGB* -> LUM"); - } else if( srcFmt.comp.componenCount() > destFmt.comp.componenCount() ) { + } else if( srcFmt.comp.componentCount() > destFmt.comp.componentCount() ) { // Cannot convert back if: src.componentCount > dest.componentCount System.err.println("CONVERT["+i+"]["+j+"]: Conv2: Dropped due to src.componentCount > dest.componentCount"); } else { @@ -632,7 +632,7 @@ public class TestPixelFormatUtil00NEWT extends UITestCase { final PixelFormat.Composition imgComp = image.getPixelformat().comp; final ByteBuffer bb = image.getPixels(); final int bytesPerPixel = imgComp.bytesPerPixel(); - final int compCount = imgComp.componenCount(); + final int compCount = imgComp.componentCount(); final int[] compBitCount = imgComp.componentBitCount(); final int srcPixOffset = y * image.getStride()+x*bytesPerPixel; diff --git a/src/test/com/jogamp/opengl/test/junit/newt/mm/TestScreenMode00aNEWT.java b/src/test/com/jogamp/opengl/test/junit/newt/mm/TestScreenMode00aNEWT.java index be15e3b7e..5285673e9 100644 --- a/src/test/com/jogamp/opengl/test/junit/newt/mm/TestScreenMode00aNEWT.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/mm/TestScreenMode00aNEWT.java @@ -112,7 +112,7 @@ public class TestScreenMode00aNEWT extends UITestCase { final Rectangle viewport = new Rectangle(0, 0, 1920, 1080); final ArrayHashSet<MonitorMode> supportedModes = new ArrayHashSet<MonitorMode>(); supportedModes.add(modeOut); - final MonitorDevice monOut = new MonitorDeviceImpl(null, -1, sizeMM, modeOut, null, viewport, viewport, supportedModes); + final MonitorDevice monOut = new MonitorDeviceImpl(null, -1, false, sizeMM, modeOut, null, viewport, viewport, supportedModes); System.err.println("01 out : "+monOut); cache.monitorDevices.add(monOut); { @@ -169,6 +169,8 @@ public class TestScreenMode00aNEWT extends UITestCase { final List<MonitorDevice> monitors = screen.getMonitorDevices(); Assert.assertTrue(monitors.size()>0); + + // Dump all Monitor's and its modes int j=0; for(final Iterator<MonitorDevice> iMonitor=monitors.iterator(); iMonitor.hasNext(); j++) { final MonitorDevice monitor = iMonitor.next(); @@ -186,7 +188,16 @@ public class TestScreenMode00aNEWT extends UITestCase { mmPre = mm; } Assert.assertTrue(allMonitorModes.containsAll(modes)); + } + // Dump all Monitor's and its DPI and current/original mode + j=0; + for(final Iterator<MonitorDevice> iMonitor=monitors.iterator(); iMonitor.hasNext(); j++) { + final MonitorDevice monitor = iMonitor.next(); + System.err.println(j+": "+monitor); + final float[] pixelPerMM = monitor.getPixelsPerMM(new float[2]); + System.err.println(j+" pixel/mm ["+pixelPerMM[0]+", "+pixelPerMM[1]+"]"); + System.err.println(j+" pixel/in ["+pixelPerMM[0]*25.4f+", "+pixelPerMM[1]*25.4f+"]"); final MonitorMode sm_o = monitor.getOriginalMode(); Assert.assertNotNull(sm_o); final MonitorMode sm_c = monitor.queryCurrentMode(); @@ -195,21 +206,21 @@ public class TestScreenMode00aNEWT extends UITestCase { Assert.assertNotNull(sm_c); Assert.assertEquals(sm_o, sm_c); } - + final RectangleImmutable zero = new Rectangle(); - + final Rectangle monitorViewPU = new Rectangle(); final Rectangle monitorViewWU = new Rectangle(); MonitorDevice.unionOfViewports(monitorViewPU, monitorViewWU, monitors); - System.err.println("Test.0: Monitor union viewport: "+monitorViewPU+" [pu] / "+monitorViewWU+" [wu]"); + System.err.println("Test.0: Monitor union viewport: "+monitorViewPU+" [pu] / "+monitorViewWU+" [wu]"); Assert.assertNotEquals(zero, monitorViewPU); - Assert.assertNotEquals(zero, monitorViewWU); - + Assert.assertNotEquals(zero, monitorViewWU); + final RectangleImmutable screenViewPU = screen.getViewport(); - final RectangleImmutable screenViewWU = screen.getViewportInWindowUnits(); - System.err.println("Test.1: Screen viewport: "+screenViewPU+" [pu] / "+screenViewWU+" [wu]"); + final RectangleImmutable screenViewWU = screen.getViewportInWindowUnits(); + System.err.println("Test.1: Screen viewport: "+screenViewPU+" [pu] / "+screenViewWU+" [wu]"); Assert.assertNotEquals(zero, screenViewPU); - Assert.assertNotEquals(zero, screenViewWU); + Assert.assertNotEquals(zero, screenViewWU); screen.removeReference(); |