From 56a9f30fde429663514c6d5c810af2c43cb7ebf3 Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Sat, 7 Sep 2019 02:20:55 +0200 Subject: Bug 1391 Bug 1392: Implement GLRendererQuirks DontChooseFBConfigBestMatch and No10BitColorCompOffscreen Further enhance unit tests TestGLProfile03NEWTOffscreen, i.e. test all meta profile types on all offscreen drawable types (fbo, pbuffer and bitmap). Align unit test name numbers of TestGLProfile01NEWT to TestGLProfile03NEWTOffscreen. --- src/jogl/classes/jogamp/opengl/GLContextImpl.java | 10 ++- .../egl/EGLGraphicsConfigurationFactory.java | 88 +++++++++++++--------- .../wgl/WindowsWGLGraphicsConfiguration.java | 8 +- .../WindowsWGLGraphicsConfigurationFactory.java | 30 +++++++- .../x11/glx/X11GLXGraphicsConfiguration.java | 4 +- .../glx/X11GLXGraphicsConfigurationFactory.java | 52 ++++++++----- .../opengl/x11/glx/X11PbufferGLXDrawable.java | 4 +- 7 files changed, 129 insertions(+), 67 deletions(-) (limited to 'src/jogl/classes/jogamp') diff --git a/src/jogl/classes/jogamp/opengl/GLContextImpl.java b/src/jogl/classes/jogamp/opengl/GLContextImpl.java index 443e2d6af..0b1214720 100644 --- a/src/jogl/classes/jogamp/opengl/GLContextImpl.java +++ b/src/jogl/classes/jogamp/opengl/GLContextImpl.java @@ -2435,6 +2435,7 @@ public abstract class GLContextImpl extends GLContext { if( isDriverMesa ) { final VersionNumber mesaSafeFBOVersion = new VersionNumber(8, 0, 0); final VersionNumber mesaIntelBuggySharedCtx921 = new VersionNumber(9, 2, 1); + final VersionNumber mesaNo10BitColorCompPBuffer = new VersionNumber(18, 0, 0); // Mesa 18.0.0 final VersionNumber mesaSafeGL3Compat = new VersionNumber(18, 2, 0); // Mesa 18.2.0 final VersionNumber mesaSafeDoubleBufferedPBuffer = new VersionNumber(18, 2, 2); // Mesa 18.2.2 final VersionNumber mesaSafeSetSwapIntervalPostRetarget = mesaSafeDoubleBufferedPBuffer; // Mesa 18.2.2 @@ -2442,7 +2443,14 @@ public abstract class GLContextImpl extends GLContext { if( vendorVersion.compareTo(mesaSafeSetSwapIntervalPostRetarget) < 0 ) { final int quirk = GLRendererQuirks.NoSetSwapIntervalPostRetarget; if(DEBUG) { - System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: Renderer " + glRenderer); + System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: Renderer " + glRenderer + " / Mesa-Version "+vendorVersion); + } + quirks.addQuirk( quirk ); + } + if( vendorVersion.compareTo(mesaNo10BitColorCompPBuffer) >= 0 ) { // FIXME: When is it fixed ?? + final int quirk = GLRendererQuirks.No10BitColorCompOffscreen; + if(DEBUG) { + System.err.println("Quirks: "+GLRendererQuirks.toString(quirk)+": cause: Renderer " + glRenderer + " / Mesa-Version "+vendorVersion); } quirks.addQuirk( quirk ); } diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java index 5505fed52..98d16a0d2 100644 --- a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java +++ b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java @@ -43,13 +43,16 @@ import com.jogamp.nativewindow.AbstractGraphicsConfiguration; import com.jogamp.nativewindow.AbstractGraphicsDevice; import com.jogamp.nativewindow.AbstractGraphicsScreen; import com.jogamp.nativewindow.CapabilitiesChooser; +import com.jogamp.nativewindow.CapabilitiesFilter; import com.jogamp.nativewindow.CapabilitiesImmutable; import com.jogamp.nativewindow.GraphicsConfigurationFactory; import com.jogamp.nativewindow.NativeWindowFactory; import com.jogamp.nativewindow.VisualIDHolder; +import com.jogamp.nativewindow.CapabilitiesFilter.RemovalCriteria; import com.jogamp.nativewindow.VisualIDHolder.VIDType; import com.jogamp.opengl.GLCapabilities; import com.jogamp.opengl.GLCapabilitiesChooser; +import com.jogamp.opengl.GLCapabilitiesFilter; import com.jogamp.opengl.GLCapabilitiesImmutable; import com.jogamp.opengl.GLContext; import com.jogamp.opengl.GLDrawableFactory; @@ -331,8 +334,9 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact final int nativeVisualID, final boolean forceTransparentFlag) { final long eglDisplay = device.getHandle(); final GLProfile glp = capsChosen.getGLProfile(); + final GLRendererQuirks glrq = GLDrawableFactory.getEGLFactory().getRendererQuirks(device, glp); final int winattrmask = GLGraphicsConfigurationUtil.getExclusiveWinAttributeBits(capsChosen); - List availableCaps = null; + ArrayList availableCaps = null; int recommendedIndex = -1; final IntBuffer numConfigs = Buffers.newDirectIntBuffer(1); @@ -375,25 +379,33 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact } hasEGLChosenCaps = false; } - final boolean useRecommendedIndex = hasEGLChosenCaps && !forceTransparentFlag && capsChosen.isBackgroundOpaque(); // only use recommended idx if not translucent - final boolean skipCapsChooser = null == chooser && useRecommendedIndex; // fast path: skip choosing if using recommended idx and null chooser is used + final boolean isPBufferOrBitmap = capsChosen.isBitmap() || capsChosen.isPBuffer(); + final boolean dontChooseFBConfigBestMatch = GLRendererQuirks.exist(glrq, GLRendererQuirks.DontChooseFBConfigBestMatch) || + ( isPBufferOrBitmap && GLRendererQuirks.exist(glrq, GLRendererQuirks.No10BitColorCompOffscreen) ); + final boolean useRecommendedIndex = !dontChooseFBConfigBestMatch && + hasEGLChosenCaps && !forceTransparentFlag && capsChosen.isBackgroundOpaque(); + final boolean shallSkipCapsChooser = null == chooser && useRecommendedIndex; if( hasEGLChosenCaps ) { - availableCaps = eglConfigs2GLCaps(device, glp, configs, numConfigs.get(0), winattrmask, forceTransparentFlag, skipCapsChooser /* onlyFirsValid */); + availableCaps = eglConfigs2GLCaps(device, glp, configs, numConfigs.get(0), winattrmask, forceTransparentFlag, shallSkipCapsChooser /* onlyFirsValid */); if(availableCaps.size() > 0) { - final long recommendedEGLConfig = configs.get(0); - recommendedIndex = 0; + if( useRecommendedIndex ) { + recommendedIndex = 0; + } if (DEBUG) { + final long recommendedEGLConfig = configs.get(0); System.err.println("EGLGraphicsConfiguration.eglChooseConfig: #1 eglChooseConfig: recommended fbcfg " + toHexString(recommendedEGLConfig) + ", idx " + recommendedIndex); - System.err.println("EGLGraphicsConfiguration.eglChooseConfig: #1 useRecommendedIndex "+useRecommendedIndex+", skipCapsChooser "+skipCapsChooser); - System.err.println("EGLGraphicsConfiguration.eglChooseConfig: #1 fbcfg caps " + availableCaps.get(recommendedIndex)); + System.err.println("EGLGraphicsConfiguration.eglChooseConfig: #1 useRecommendedIndex "+useRecommendedIndex+", shallSkipCapsChooser "+shallSkipCapsChooser); + if( 0 <= recommendedIndex ) { + System.err.println("EGLGraphicsConfiguration.eglChooseConfig: #1 fbcfg recommended caps " + availableCaps.get(recommendedIndex)); + } } } else if (DEBUG) { System.err.println("EGLGraphicsConfiguration.eglChooseConfig: #1 eglChooseConfig: no caps for recommended fbcfg " + toHexString(configs.get(0))); - System.err.println("EGLGraphicsConfiguration.eglChooseConfig: #1 useRecommendedIndex "+useRecommendedIndex+", skipCapsChooser "+skipCapsChooser); + System.err.println("EGLGraphicsConfiguration.eglChooseConfig: #1 useRecommendedIndex "+useRecommendedIndex+", shallSkipCapsChooser "+shallSkipCapsChooser); } } else if (DEBUG) { System.err.println("EGLGraphicsConfiguration.eglChooseConfig: #1 eglChooseConfig: no configs"); - System.err.println("EGLGraphicsConfiguration.eglChooseConfig: #1 useRecommendedIndex "+useRecommendedIndex+", skipCapsChooser "+skipCapsChooser); + System.err.println("EGLGraphicsConfiguration.eglChooseConfig: #1 useRecommendedIndex "+useRecommendedIndex+", shallSkipCapsChooser "+shallSkipCapsChooser); } // 2nd choice: get all GLCapabilities available, no preferred recommendedIndex available @@ -419,43 +431,47 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact return null; } + final boolean skipCapsChooser = shallSkipCapsChooser && 0 <= recommendedIndex; if(DEBUG) { System.err.println("EGLGraphicsConfiguration.eglChooseConfig: got configs: "+availableCaps.size()); for(int i=0; i removedCaps = new ArrayList(); - for(int i=0; i> criteria = new ArrayList>(); + if( !skipCapsChooser && isPBufferOrBitmap && GLRendererQuirks.exist(glrq, GLRendererQuirks.No10BitColorCompOffscreen) ) { + criteria.add(new CapabilitiesFilter.RemoveMoreColorCompBits(8)); } - if(0==availableCaps.size()) { - availableCaps = removedCaps; - if(DEBUG) { - System.err.println("EGLGraphicsConfiguration.eglChooseConfig: post filter nativeVisualID "+toHexString(nativeVisualID)+" no config found, revert to all"); + if( VisualIDHolder.VID_UNDEFINED != nativeVisualID) { + criteria.add(new CapabilitiesFilter.RemoveUnmatchedNativeVisualID(nativeVisualID)); + } + if( 0 < capsChosen.getDepthBits() ) { + // Hack for HiSilicon/Vivante/Immersion.16 Renderer .. + criteria.add(new GLCapabilitiesFilter.RemoveLessDepthBits(1)); + } + if( criteria.size() > 0 ) { + final ArrayList removedCaps = CapabilitiesFilter.removeMatching(availableCaps, criteria); + if( removedCaps.size() > 0 ) { + if(DEBUG) { + System.err.println("EGLGraphicsConfiguration.eglChooseConfig: filtered configs: "+availableCaps.size()); + for(int i=0; i eglConfigs2GLCaps(final EGLGraphicsDevice device, final GLProfile glp, final PointerBuffer configs, final int num, final int winattrmask, final boolean forceTransparentFlag, final boolean onlyFirstValid) { + static ArrayList eglConfigs2GLCaps(final EGLGraphicsDevice device, final GLProfile glp, final PointerBuffer configs, final int num, final int winattrmask, final boolean forceTransparentFlag, final boolean onlyFirstValid) { final GLRendererQuirks defaultQuirks = GLRendererQuirks.getStickyDeviceQuirks( GLDrawableFactory.getEGLFactory().getDefaultDevice() ); - final List bucket = new ArrayList(num); + final ArrayList bucket = new ArrayList(num); for(int i=0; i wglARBPFIDs2GLCapabilities(final WindowsWGLDrawableFactory.SharedResource sharedResource, - final AbstractGraphicsDevice device, final GLProfile glp, - final long hdc, final int[] pfdIDs, final int winattrbits, - final boolean onlyFirstValid) { + static ArrayList wglARBPFIDs2GLCapabilities(final WindowsWGLDrawableFactory.SharedResource sharedResource, + final AbstractGraphicsDevice device, final GLProfile glp, + final long hdc, final int[] pfdIDs, final int winattrbits, + final boolean onlyFirstValid) { if (!sharedResource.hasARBPixelFormat()) { return null; } diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java index 99268f13f..c365e8734 100644 --- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java +++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java @@ -37,6 +37,7 @@ import com.jogamp.nativewindow.AbstractGraphicsConfiguration; import com.jogamp.nativewindow.AbstractGraphicsDevice; import com.jogamp.nativewindow.AbstractGraphicsScreen; import com.jogamp.nativewindow.CapabilitiesChooser; +import com.jogamp.nativewindow.CapabilitiesFilter; import com.jogamp.nativewindow.DefaultGraphicsScreen; import com.jogamp.nativewindow.GraphicsConfigurationFactory; import com.jogamp.nativewindow.CapabilitiesImmutable; @@ -46,6 +47,7 @@ import com.jogamp.nativewindow.ProxySurface; import com.jogamp.nativewindow.VisualIDHolder; import com.jogamp.opengl.GLCapabilitiesImmutable; import com.jogamp.opengl.GLCapabilitiesChooser; +import com.jogamp.opengl.GLCapabilitiesFilter; import com.jogamp.opengl.GLContext; import com.jogamp.opengl.GLDrawableFactory; import com.jogamp.opengl.GLException; @@ -354,6 +356,11 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat final int winattrbits = GLGraphicsConfigurationUtil.getExclusiveWinAttributeBits(capsChosen) & ~GLGraphicsConfigurationUtil.BITMAP_BIT; // w/o BITMAP final GLProfile glProfile = capsChosen.getGLProfile(); + final GLRendererQuirks glrq = factory.getRendererQuirks(device, glProfile); + final boolean isPBufferOrBitmap = capsChosen.isBitmap() || capsChosen.isPBuffer(); + final boolean dontChooseFBConfigBestMatch = GLRendererQuirks.exist(glrq, GLRendererQuirks.DontChooseFBConfigBestMatch) || + ( isPBufferOrBitmap && GLRendererQuirks.exist(glrq, GLRendererQuirks.No10BitColorCompOffscreen) ); + final boolean useRecommendedIndex = !dontChooseFBConfigBestMatch && capsChosen.isBackgroundOpaque(); final int pfdIDCount = WindowsWGLGraphicsConfiguration.wglARBPFDIDCount((WindowsWGLContext)sharedResource.getContext(), hdc); @@ -409,7 +416,9 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat hdc, iattributes, accelerationMode, fattributes); } if (null != pformats) { - recommendedIndex = 0; + if( useRecommendedIndex ) { + recommendedIndex = 0; + } } else { if(DEBUG) { System.err.println("updateGraphicsConfigurationARB: wglChoosePixelFormatARB failed with: "+capsChosen); @@ -429,9 +438,9 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat return false; } } - final boolean skipCapsChooser = 0 <= recommendedIndex && null == chooser && capsChosen.isBackgroundOpaque(); // fast path: skip choosing if using recommended idx and null chooser is used and if not translucent + final boolean skipCapsChooser = 0 <= recommendedIndex && null == chooser && useRecommendedIndex; - final List availableCaps = + final ArrayList availableCaps = WindowsWGLGraphicsConfiguration.wglARBPFIDs2GLCapabilities(sharedResource, device, glProfile, hdc, pformats, winattrbits, skipCapsChooser /* onlyFirstValid */); @@ -451,6 +460,21 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat pformats[recommendedIndex] + ", idx " + recommendedIndex +", "+availableCaps.get(recommendedIndex)); } } + if(DEBUG) { + System.err.println("updateGraphicsConfigurationARB: got configs: "+availableCaps.size()); + for(int i=0; i GLXFBConfig2GLCapabilities(final X11GraphicsDevice device, final GLProfile glp, final PointerBuffer fbcfgsL, + static ArrayList GLXFBConfig2GLCapabilities(final X11GraphicsDevice device, final GLProfile glp, final PointerBuffer fbcfgsL, final int winattrmask, final boolean isMultisampleAvailable, final boolean onlyFirstValid) { final IntBuffer tmp = Buffers.newDirectIntBuffer(1); final XRenderPictFormat xRenderPictFormat= XRenderPictFormat.create(); - final List result = new ArrayList(); + final ArrayList result = new ArrayList(); for (int i = 0; i < fbcfgsL.limit(); i++) { final long fbcfg = fbcfgsL.get(i); final GLCapabilitiesImmutable c = GLXFBConfig2GLCapabilities(device, glp, fbcfg, winattrmask, isMultisampleAvailable, tmp, xRenderPictFormat); diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfigurationFactory.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfigurationFactory.java index 4dc2d7e0b..739061bbe 100644 --- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfigurationFactory.java +++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfigurationFactory.java @@ -37,6 +37,7 @@ import com.jogamp.nativewindow.AbstractGraphicsConfiguration; import com.jogamp.nativewindow.AbstractGraphicsDevice; import com.jogamp.nativewindow.AbstractGraphicsScreen; import com.jogamp.nativewindow.CapabilitiesChooser; +import com.jogamp.nativewindow.CapabilitiesFilter; import com.jogamp.nativewindow.CapabilitiesImmutable; import com.jogamp.nativewindow.GraphicsConfigurationFactory; import com.jogamp.nativewindow.VisualIDHolder; @@ -44,11 +45,12 @@ import com.jogamp.nativewindow.VisualIDHolder.VIDType; import com.jogamp.opengl.DefaultGLCapabilitiesChooser; import com.jogamp.opengl.GLCapabilities; import com.jogamp.opengl.GLCapabilitiesChooser; +import com.jogamp.opengl.GLCapabilitiesFilter; import com.jogamp.opengl.GLCapabilitiesImmutable; import com.jogamp.opengl.GLDrawableFactory; import com.jogamp.opengl.GLException; import com.jogamp.opengl.GLProfile; - +import com.jogamp.opengl.GLRendererQuirks; import com.jogamp.common.ExceptionUtils; import com.jogamp.common.nio.Buffers; import com.jogamp.common.nio.PointerBuffer; @@ -295,7 +297,8 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF final IntBuffer count = Buffers.newDirectIntBuffer(1); count.put(0, -1); final int winattrmask = GLGraphicsConfigurationUtil.getExclusiveWinAttributeBits(capsChosen); - List availableCaps; + final GLRendererQuirks glrq = factory.getRendererQuirks(x11Device, glProfile); + ArrayList availableCaps; // 1st choice: get GLCapabilities based on users GLCapabilities setting recommendedIndex as preferred choice, // skipped if xvisualID is given final boolean hasGLXChosenCaps; @@ -305,21 +308,25 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF } else { hasGLXChosenCaps = false; } - final boolean useRecommendedIndex = hasGLXChosenCaps && capsChosen.isBackgroundOpaque(); // only use recommended idx if not translucent - final boolean skipCapsChooser = null == chooser && useRecommendedIndex; // fast path: skip choosing if using recommended idx and null chooser is used + final boolean isPBufferOrBitmap = capsChosen.isBitmap() || capsChosen.isPBuffer(); + final boolean dontChooseFBConfigMatch = GLRendererQuirks.exist(glrq, GLRendererQuirks.DontChooseFBConfigBestMatch) || + ( isPBufferOrBitmap && GLRendererQuirks.exist(glrq, GLRendererQuirks.No10BitColorCompOffscreen) ); + final boolean useRecommendedIndex = !dontChooseFBConfigMatch && + hasGLXChosenCaps && capsChosen.isBackgroundOpaque(); + final boolean shallSkipCapsChooser = null == chooser && useRecommendedIndex; if (hasGLXChosenCaps) { - availableCaps = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(x11Device, glProfile, fbcfgsL, winattrmask, isMultisampleAvailable, skipCapsChooser /* onlyFirstValid */); + availableCaps = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(x11Device, glProfile, fbcfgsL, winattrmask, isMultisampleAvailable, shallSkipCapsChooser /* onlyFirstValid */); if(availableCaps.size() > 0) { recommendedIndex = useRecommendedIndex ? 0 : -1; if (DEBUG) { System.err.println("glXChooseFBConfig recommended fbcfg " + toHexString(fbcfgsL.get(0)) + ", idx " + recommendedIndex); - System.err.println("useRecommendedIndex "+useRecommendedIndex+", skipCapsChooser "+skipCapsChooser); + System.err.println("useRecommendedIndex "+useRecommendedIndex+", shallSkipCapsChooser "+shallSkipCapsChooser); System.err.println("user caps " + capsChosen); System.err.println("fbcfg caps " + fbcfgsL.limit()+", availCaps "+availableCaps.get(0)); } } else if (DEBUG) { System.err.println("glXChooseFBConfig no caps for recommended fbcfg " + toHexString(fbcfgsL.get(0))); - System.err.println("useRecommendedIndex "+useRecommendedIndex+", skipCapsChooser "+skipCapsChooser); + System.err.println("useRecommendedIndex "+useRecommendedIndex+", shallSkipCapsChooser "+shallSkipCapsChooser); System.err.println("user caps " + capsChosen); } } else { @@ -340,21 +347,28 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF } availableCaps = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(x11Device, glProfile, fbcfgsL, winattrmask, isMultisampleAvailable, false /* onlyOneValid */); } - + final boolean skipCapsChooser = shallSkipCapsChooser && 0 <= recommendedIndex; if(DEBUG) { System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: got configs: "+availableCaps.size()); for(int i=0; i removedCaps; + if( !skipCapsChooser && isPBufferOrBitmap && GLRendererQuirks.exist(glrq, GLRendererQuirks.No10BitColorCompOffscreen) ) { + removedCaps = CapabilitiesFilter.removeMoreColorCompsAndUnmatchingNativeVisualID(availableCaps, 8, xvisualID); + } else { + removedCaps = CapabilitiesFilter.removeUnmatchingNativeVisualID(availableCaps, xvisualID); + } + if( removedCaps.size() > 0 ) { + if(DEBUG) { + System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: filtered configs: "+availableCaps.size()); + for(int i=0; i