@Override protected final GLDrawableImpl createOffscreenDrawableImpl(NativeSurface target) { if (target == null) { throw new IllegalArgumentException("Null target"); } AbstractGraphicsConfiguration config = target.getGraphicsConfiguration(); GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable) config.getChosenCapabilities(); if (!caps.isPBuffer()) { return new X11PixmapGLXDrawable(this, target); } // PBuffer GLDrawable Creation GLDrawableImpl pbufferDrawable; AbstractGraphicsDevice device = config.getScreen().getDevice(); /** * Due to the ATI Bug https://bugzilla.mozilla.org/show_bug.cgi?id=486277, we need to have a * context current on the same Display to create a PBuffer. The dummy context shall also use the * same Display, since switching Display in this regard is another ATI bug. */ SharedResource sr = (SharedResource) sharedResourceRunner.getOrCreateShared(device); if (null != sr && sr.isGLXVendorATI() && null == GLContext.getCurrent()) { sr.getContext().makeCurrent(); try { pbufferDrawable = new X11PbufferGLXDrawable(this, target); } finally { sr.getContext().release(); } } else { pbufferDrawable = new X11PbufferGLXDrawable(this, target); } return pbufferDrawable; }
@Override protected GLDrawableImpl createOffscreenDrawableImpl(NativeSurface target) { if (target == null) { throw new IllegalArgumentException("Null target"); } AbstractGraphicsConfiguration config = target.getGraphicsConfiguration(); GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable) config.getChosenCapabilities(); if (!caps.isPBuffer()) { throw new GLException("Non pbuffer not yet implemented"); } // PBuffer GLDrawable Creation return new EGLPbufferDrawable(this, EGLWrappedSurface.get(target)); }
static X11GLXGraphicsConfiguration chooseGraphicsConfigurationStatic( GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsReq, GLCapabilitiesChooser chooser, X11GraphicsScreen x11Screen) { if (x11Screen == null) { throw new IllegalArgumentException("AbstractGraphicsScreen is null"); } if (capsChosen == null) { capsChosen = new GLCapabilities(null); } X11GraphicsDevice x11Device = (X11GraphicsDevice) x11Screen.getDevice(); X11GLXDrawableFactory factory = (X11GLXDrawableFactory) GLDrawableFactory.getDesktopFactory(); capsChosen = GLGraphicsConfigurationUtil.fixGLCapabilities( capsChosen, factory.canCreateGLPbuffer(x11Device)); boolean usePBuffer = capsChosen.isPBuffer(); X11GLXGraphicsConfiguration res = null; if (factory.isGLXVersionGreaterEqualOneThree(x11Device)) { res = chooseGraphicsConfigurationFBConfig(capsChosen, capsReq, chooser, x11Screen); } if (null == res) { if (usePBuffer) { throw new GLException( "Error: Couldn't create X11GLXGraphicsConfiguration based on FBConfig for " + capsChosen); } res = chooseGraphicsConfigurationXVisual(capsChosen, capsReq, chooser, x11Screen); } if (null == res) { throw new GLException( "Error: Couldn't create X11GLXGraphicsConfiguration based on FBConfig and XVisual for " + capsChosen); } if (DEBUG) { System.err.println( "X11GLXGraphicsConfiguration.chooseGraphicsConfigurationStatic(" + x11Screen + "," + capsChosen + "): " + res); } return res; }
private static X11GLXGraphicsConfiguration chooseGraphicsConfigurationFBConfig( GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsReq, GLCapabilitiesChooser chooser, X11GraphicsScreen x11Screen) { int recommendedIndex = -1; PointerBuffer fbcfgsL = null; GLProfile glProfile = capsChosen.getGLProfile(); boolean onscreen = capsChosen.isOnscreen(); boolean usePBuffer = capsChosen.isPBuffer(); // Utilizing FBConfig // AbstractGraphicsDevice absDevice = x11Screen.getDevice(); long display = absDevice.getHandle(); int screen = x11Screen.getIndex(); final X11GLXDrawableFactory factory = (X11GLXDrawableFactory) GLDrawableFactory.getDesktopFactory(); final boolean isMultisampleAvailable = factory.isGLXMultisampleAvailable(absDevice); int[] attribs = X11GLXGraphicsConfiguration.GLCapabilities2AttribList( capsChosen, true, isMultisampleAvailable, display, screen); int[] count = {-1}; ArrayList /*<X11GLCapabilities>*/ availableCaps = new ArrayList(); final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer); // 1st choice: get GLCapabilities based on users GLCapabilities setting recommendedIndex as // preferred choice fbcfgsL = GLX.glXChooseFBConfig(display, screen, attribs, 0, count, 0); if (fbcfgsL != null && fbcfgsL.limit() > 0) { for (int i = 0; i < fbcfgsL.limit(); i++) { if (!X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities( availableCaps, glProfile, display, fbcfgsL.get(i), winattrmask, isMultisampleAvailable)) { if (DEBUG) { System.err.println( "X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: FBConfig invalid (1): (" + x11Screen + "," + capsChosen + "): fbcfg: " + toHexString(fbcfgsL.get(i))); } } } if (availableCaps.size() > 0) { recommendedIndex = capsChosen.isBackgroundOpaque() ? 0 : -1; // only use recommended idx if not translucent if (DEBUG) { System.err.println( "glXChooseFBConfig recommended fbcfg " + toHexString(fbcfgsL.get(0)) + ", idx " + recommendedIndex); System.err.println("user caps " + capsChosen); System.err.println("fbcfg caps " + availableCaps.get(0)); } } else if (DEBUG) { System.err.println( "glXChooseFBConfig no caps for recommended fbcfg " + toHexString(fbcfgsL.get(0))); System.err.println("user caps " + capsChosen); } } // 2nd choice: get all GLCapabilities available, no preferred recommendedIndex available if (0 == availableCaps.size()) { // reset .. recommendedIndex = -1; fbcfgsL = GLX.glXChooseFBConfig(display, screen, null, 0, count, 0); if (fbcfgsL == null || fbcfgsL.limit() <= 0) { if (DEBUG) { System.err.println( "X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: Failed glXChooseFBConfig (" + x11Screen + "," + capsChosen + "): " + fbcfgsL + ", " + count[0]); } return null; } for (int i = 0; i < fbcfgsL.limit(); i++) { if (!X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities( availableCaps, glProfile, display, fbcfgsL.get(i), winattrmask, isMultisampleAvailable)) { if (DEBUG) { System.err.println( "X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: FBConfig invalid (2): (" + x11Screen + "): fbcfg: " + toHexString(fbcfgsL.get(i))); } } } } int chosenIndex = chooseCapabilities(chooser, capsChosen, availableCaps, recommendedIndex); if (0 > chosenIndex) { if (DEBUG) { System.err.println( "X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: failed, return null"); Thread.dumpStack(); } return null; } X11GLCapabilities chosenCaps = (X11GLCapabilities) availableCaps.get(chosenIndex); return new X11GLXGraphicsConfiguration(x11Screen, chosenCaps, capsReq, chooser); }
void doTest(final GLCapabilitiesImmutable reqGLCaps, final GLEventListener demo) throws InterruptedException { System.out.println("Requested GL Caps: " + reqGLCaps); final GLDrawableFactory factory = GLDrawableFactory.getFactory(reqGLCaps.getGLProfile()); final GLCapabilitiesImmutable expGLCaps = GLGraphicsConfigurationUtil.fixGLCapabilities(reqGLCaps, factory, null); System.out.println("Expected GL Caps: " + expGLCaps); // // Create native OpenGL resources .. XGL/WGL/CGL .. // equivalent to GLAutoDrawable methods: setVisible(true) // final GLOffscreenAutoDrawable glad = factory.createOffscreenAutoDrawable( null, reqGLCaps, null, widthStep * szStep, heightStep * szStep); Assert.assertNotNull(glad); System.out.println( "Drawable Pre-GL(0): " + glad.getClass().getName() + ", " + glad.getNativeSurface().getClass().getName()); Assert.assertTrue(glad.isRealized()); // Check caps of NativeWindow config w/o GL final CapabilitiesImmutable chosenCaps = glad.getChosenGLCapabilities(); System.out.println("Drawable Caps Pre_GL : " + chosenCaps); Assert.assertNotNull(chosenCaps); Assert.assertTrue(chosenCaps.getGreenBits() > 4); Assert.assertTrue(chosenCaps.getBlueBits() > 4); Assert.assertTrue(chosenCaps.getRedBits() > 4); glad.display(); // force native context creation // Check caps of GLDrawable after realization final GLCapabilitiesImmutable chosenGLCaps = glad.getChosenGLCapabilities(); System.out.println("Chosen GL CTX (1): " + glad.getContext().getGLVersion()); System.out.println("Chosen GL Caps(1): " + chosenGLCaps); System.out.println( "Chosen GL Caps(2): " + glad.getNativeSurface().getGraphicsConfiguration().getChosenCapabilities()); Assert.assertNotNull(chosenGLCaps); Assert.assertTrue(chosenGLCaps.getGreenBits() > 4); Assert.assertTrue(chosenGLCaps.getBlueBits() > 4); Assert.assertTrue(chosenGLCaps.getRedBits() > 4); Assert.assertTrue(chosenGLCaps.getDepthBits() > 4); Assert.assertEquals(expGLCaps.isOnscreen(), chosenGLCaps.isOnscreen()); Assert.assertEquals(expGLCaps.isFBO(), chosenGLCaps.isFBO()); Assert.assertEquals(expGLCaps.isPBuffer(), chosenGLCaps.isPBuffer()); Assert.assertEquals(expGLCaps.isBitmap(), chosenGLCaps.isBitmap()); /** * Single/Double buffer cannot be checked since result may vary .. if(chosenGLCaps.isOnscreen() * || chosenGLCaps.isFBO()) { // dbl buffer may be disabled w/ offscreen pbuffer and bitmap * Assert.assertEquals(expGLCaps.getDoubleBuffered(), chosenGLCaps.getDoubleBuffered()); } */ glad.addGLEventListener(demo); final SnapshotGLEventListener snapshotGLEventListener = new SnapshotGLEventListener(); glad.addGLEventListener(snapshotGLEventListener); glad.display(); // initial resize/display // 1 - szStep = 2 Assert.assertTrue( "Size not reached: Expected " + (widthStep * szStep) + "x" + (heightStep * szStep) + ", Is " + glad.getSurfaceWidth() + "x" + glad.getSurfaceHeight(), AWTRobotUtil.waitForSize(glad, widthStep * szStep, heightStep * szStep)); snapshotGLEventListener.setMakeSnapshot(); glad.display(); // 2, 3 (resize + display) szStep = 1; glad.setSurfaceSize(widthStep * szStep, heightStep * szStep); Assert.assertTrue( "Size not reached: Expected " + (widthStep * szStep) + "x" + (heightStep * szStep) + ", Is " + glad.getSurfaceWidth() + "x" + glad.getSurfaceHeight(), AWTRobotUtil.waitForSize(glad, widthStep * szStep, heightStep * szStep)); snapshotGLEventListener.setMakeSnapshot(); glad.display(); // 4, 5 (resize + display) szStep = 4; glad.setSurfaceSize(widthStep * szStep, heightStep * szStep); Assert.assertTrue( "Size not reached: Expected " + (widthStep * szStep) + "x" + (heightStep * szStep) + ", Is " + glad.getSurfaceWidth() + "x" + glad.getSurfaceHeight(), AWTRobotUtil.waitForSize(glad, widthStep * szStep, heightStep * szStep)); snapshotGLEventListener.setMakeSnapshot(); glad.display(); Thread.sleep(50); glad.destroy(); System.out.println("Fin Drawable: " + glad); }
/** * Takes a snapshot of the drawable's current front framebuffer. Example filenames: * * <pre> * TestGLDrawableAutoDelegateOnOffscrnCapsNEWT.testES2OffScreenFBOSglBuf____-n0001-msaa0-GLES2_-sw-fbobject-Bdbl-Frgb__Irgb_-S00_default-0400x0300.png * TestGLDrawableAutoDelegateOnOffscrnCapsNEWT.testES2OffScreenPbufferDblBuf-n0003-msaa0-GLES2_-sw-pbuffer_-Bdbl-Frgb__Irgb_-S00_default-0200x0150.png * TestGLDrawableAutoDelegateOnOffscrnCapsNEWT.testGL2OffScreenPbufferSglBuf-n0003-msaa0-GL2___-hw-pbuffer_-Bone-Frgb__Irgb_-S00_default-0200x0150.png * </pre> * * @param sn sequential number * @param postSNDetail optional detail to be added to the filename after <code>sn</code> * @param gl the current GL context object. It's read drawable is being used as the pixel source * and to gather some details which will end up in the filename. * @param readBufferUtil the {@link GLReadBufferUtil} to be used to read the pixels for the * screenshot. * @param fileSuffix Optional file suffix without a <i>dot</i> defining the file type, i.e. <code> * "png"</code>. If <code>null</code> the <code>"png"</code> as defined in {@link * TextureIO#PNG} is being used. * @param destPath Optional platform dependent file path. It shall use {@link File#separatorChar} * as is directory separator. It shall not end with a directory separator, {@link * File#separatorChar}. If <code>null</code> the current working directory is being used. */ public void snapshot( int sn, String postSNDetail, GL gl, GLReadBufferUtil readBufferUtil, String fileSuffix, String destPath) { if (null == fileSuffix) { fileSuffix = TextureIO.PNG; } final int maxSimpleTestNameLen = getMaxTestNameLen() + getClass().getSimpleName().length() + 1; final String simpleTestName = this.getSimpleTestName("."); final String filenameBaseName; { final GLDrawable drawable = gl.getContext().getGLReadDrawable(); final GLCapabilitiesImmutable caps = drawable.getChosenGLCapabilities(); final String accel = caps.getHardwareAccelerated() ? "hw" : "sw"; final String scrnm; if (caps.isOnscreen()) { scrnm = "onscreen"; } else if (caps.isFBO()) { scrnm = "fbobject"; } else if (caps.isPBuffer()) { scrnm = "pbuffer_"; } else if (caps.isBitmap()) { scrnm = "bitmap__"; } else { scrnm = "unknown_"; } final String dblb = caps.getDoubleBuffered() ? "dbl" : "one"; final String F_pfmt = readBufferUtil.hasAlpha() ? "rgba" : "rgb_"; final String pfmt = caps.getAlphaBits() > 0 ? "rgba" : "rgb_"; final int samples = caps.getNumSamples(); final String aaext = caps.getSampleExtension(); postSNDetail = null != postSNDetail ? "-" + postSNDetail : ""; filenameBaseName = String.format( "%-" + maxSimpleTestNameLen + "s-n%04d%s-%-6s-%s-%s-B%s-F%s_I%s-S%02d_%s-%04dx%04d.%s", simpleTestName, sn, postSNDetail, drawable.getGLProfile().getName(), accel, scrnm, dblb, F_pfmt, pfmt, samples, aaext, drawable.getWidth(), drawable.getHeight(), fileSuffix) .replace(' ', '_'); } final String filename = null != destPath ? destPath + File.separator + filenameBaseName : filenameBaseName; System.err.println( Thread.currentThread().getName() + ": ** screenshot: " + filename + ", maxTestNameLen " + maxSimpleTestNameLen + ", <" + simpleTestName + ">"); gl.glFinish(); // just make sure rendering finished .. if (readBufferUtil.readPixels(gl, false)) { readBufferUtil.write(new File(filename)); } }
public static IntBuffer GLCapabilities2AttribList(GLCapabilitiesImmutable caps) { final IntBuffer attrs = Buffers.newDirectIntBuffer(32); int idx = 0; attrs.put(idx++, EGL.EGL_SURFACE_TYPE); final int surfaceType; if (caps.isOnscreen()) { surfaceType = EGL.EGL_WINDOW_BIT; } else if (caps.isFBO()) { surfaceType = EGL.EGL_PBUFFER_BIT; // native replacement! } else if (caps.isPBuffer()) { surfaceType = EGL.EGL_PBUFFER_BIT; } else if (caps.isBitmap()) { surfaceType = EGL.EGL_PIXMAP_BIT; } else { throw new GLException("no surface type set in caps: " + caps); } attrs.put(idx++, surfaceType); attrs.put(idx++, EGL.EGL_RED_SIZE); attrs.put(idx++, caps.getRedBits()); attrs.put(idx++, EGL.EGL_GREEN_SIZE); attrs.put(idx++, caps.getGreenBits()); attrs.put(idx++, EGL.EGL_BLUE_SIZE); attrs.put(idx++, caps.getBlueBits()); if (caps.getAlphaBits() > 0) { attrs.put(idx++, EGL.EGL_ALPHA_SIZE); attrs.put(idx++, caps.getAlphaBits()); } if (caps.getStencilBits() > 0) { attrs.put(idx++, EGL.EGL_STENCIL_SIZE); attrs.put(idx++, caps.getStencilBits()); } attrs.put(idx++, EGL.EGL_DEPTH_SIZE); attrs.put(idx++, caps.getDepthBits()); if (caps.getSampleBuffers()) { if (caps.getSampleExtension().equals(GLGraphicsConfigurationUtil.NV_coverage_sample)) { attrs.put(idx++, EGLExt.EGL_COVERAGE_BUFFERS_NV); attrs.put(idx++, 1); attrs.put(idx++, EGLExt.EGL_COVERAGE_SAMPLES_NV); attrs.put(idx++, caps.getNumSamples()); } else { // try default .. attrs.put(idx++, EGL.EGL_SAMPLE_BUFFERS); attrs.put(idx++, 1); attrs.put(idx++, EGL.EGL_SAMPLES); attrs.put(idx++, caps.getNumSamples()); } } attrs.put(idx++, EGL.EGL_TRANSPARENT_TYPE); attrs.put(idx++, caps.isBackgroundOpaque() ? EGL.EGL_NONE : EGL.EGL_TRANSPARENT_TYPE); // 22 if (!caps.isBackgroundOpaque()) { attrs.put(idx++, EGL.EGL_TRANSPARENT_RED_VALUE); attrs.put( idx++, caps.getTransparentRedValue() >= 0 ? caps.getTransparentRedValue() : EGL.EGL_DONT_CARE); attrs.put(idx++, EGL.EGL_TRANSPARENT_GREEN_VALUE); attrs.put( idx++, caps.getTransparentGreenValue() >= 0 ? caps.getTransparentGreenValue() : EGL.EGL_DONT_CARE); attrs.put(idx++, EGL.EGL_TRANSPARENT_BLUE_VALUE); attrs.put( idx++, caps.getTransparentBlueValue() >= 0 ? caps.getTransparentBlueValue() : EGL.EGL_DONT_CARE); /** * Not define in EGL attrs.put(idx++, EGL.EGL_TRANSPARENT_ALPHA_VALUE; attrs.put(idx++, * caps.getTransparentAlphaValue()>=0?caps.getTransparentAlphaValue():EGL.EGL_DONT_CARE; */ } // 28 attrs.put(idx++, EGL.EGL_RENDERABLE_TYPE); if (caps.getGLProfile().usesNativeGLES1()) { attrs.put(idx++, EGL.EGL_OPENGL_ES_BIT); } else if (caps.getGLProfile().usesNativeGLES2()) { attrs.put(idx++, EGL.EGL_OPENGL_ES2_BIT); } else if (caps.getGLProfile().usesNativeGLES3()) { if (GLRendererQuirks.existStickyDeviceQuirk( GLDrawableFactory.getEGLFactory().getDefaultDevice(), GLRendererQuirks.GLES3ViaEGLES2Config)) { attrs.put(idx++, EGL.EGL_OPENGL_ES2_BIT); } else { attrs.put(idx++, EGLExt.EGL_OPENGL_ES3_BIT_KHR); } } else { attrs.put(idx++, EGL.EGL_OPENGL_BIT); } // 30 attrs.put(idx++, EGL.EGL_NONE); return attrs; }