/** * Sets the OpenGL context associated with this GLCanvas to be the current GL context. * * @exception SWTException * <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver * </ul> */ public void setCurrent() { checkWidget(); if (GLX.glXGetCurrentContext() == context) return; int /*long*/ window = OS.GTK_WIDGET_WINDOW(handle); int /*long*/ xDisplay = OS.gdk_x11_drawable_get_xdisplay(window); GLX.glXMakeCurrent(xDisplay, xWindow, context); }
protected static X11GLXGraphicsConfiguration createDefaultGraphicsConfiguration( AbstractGraphicsScreen absScreen, boolean onscreen, boolean usePBuffer) { if (absScreen == null) { throw new IllegalArgumentException("AbstractGraphicsScreen is null"); } if (!(absScreen instanceof X11GraphicsScreen)) { throw new IllegalArgumentException("Only X11GraphicsScreen are allowed here"); } X11GraphicsScreen x11Screen = (X11GraphicsScreen) absScreen; GLProfile glProfile = GLProfile.getDefault(); GLCapabilities caps = null; XVisualInfo xvis = null; long fbcfg = 0; int fbid = -1; // Utilizing FBConfig // GLCapabilities capsFB = null; long display = x11Screen.getDevice().getHandle(); try { NativeWindowFactory.getDefaultFactory().getToolkitLock().lock(); X11Lib.XLockDisplay(display); int screen = x11Screen.getIndex(); boolean isMultisampleAvailable = GLXUtil.isMultisampleAvailable(display); long visID = X11Lib.DefaultVisualID(display, x11Screen.getIndex()); xvis = X11GLXGraphicsConfiguration.XVisualID2XVisualInfo(display, visID); caps = X11GLXGraphicsConfiguration.XVisualInfo2GLCapabilities( glProfile, display, xvis, onscreen, usePBuffer, isMultisampleAvailable); int[] attribs = X11GLXGraphicsConfiguration.GLCapabilities2AttribList( caps, true, isMultisampleAvailable, display, screen); int[] count = {-1}; PointerBuffer fbcfgsL = GLX.glXChooseFBConfigCopied(display, screen, attribs, 0, count, 0); if (fbcfgsL == null || fbcfgsL.limit() < 1) { throw new Exception("Could not fetch FBConfig for " + caps); } fbcfg = fbcfgsL.get(0); capsFB = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities( glProfile, display, fbcfg, true, onscreen, usePBuffer, isMultisampleAvailable); fbid = X11GLXGraphicsConfiguration.glXFBConfig2FBConfigID(display, fbcfg); xvis = GLX.glXGetVisualFromFBConfigCopied(display, fbcfg); if (xvis == null) { throw new GLException("Error: Choosen FBConfig has no visual"); } } catch (Throwable t) { } finally { X11Lib.XUnlockDisplay(display); NativeWindowFactory.getDefaultFactory().getToolkitLock().unlock(); } return new X11GLXGraphicsConfiguration( x11Screen, (null != capsFB) ? capsFB : caps, caps, null, xvis, fbcfg, fbid); }
public static void getGLXVersion(long display, int major[], int minor[]) { if (0 == display) { throw new GLException("null display handle"); } if (major.length < 1 || minor.length < 1) { throw new GLException("passed int arrays size is not >= 1"); } if (!GLX.glXQueryVersion(display, major, 0, minor, 0)) { throw new GLException("glXQueryVersion failed"); } // Work around bugs in ATI's Linux drivers where they report they // only implement GLX version 1.2 on the server side if (major[0] == 1 && minor[0] == 2) { String str = GLX.glXGetClientString(display, GLX.GLX_VERSION); try { // e.g. "1.3" major[0] = Integer.valueOf(str.substring(0, 1)).intValue(); minor[0] = Integer.valueOf(str.substring(2, 3)).intValue(); } catch (Exception e) { major[0] = 1; minor[0] = 2; } } }
protected static X11ExternalGLXContext create(GLDrawableFactory factory, GLProfile glp) { long ctx = GLX.glXGetCurrentContext(); if (ctx == 0) { throw new GLException("Error: current context null"); } long display = GLX.glXGetCurrentDisplay(); if (display == 0) { throw new GLException("Error: current display null"); } long drawable = GLX.glXGetCurrentDrawable(); if (drawable == 0) { throw new GLException( "Error: attempted to make an external GLDrawable without a drawable/context current"); } IntBuffer val = Buffers.newDirectIntBuffer(1); int w, h; GLX.glXQueryDrawable(display, drawable, GLX.GLX_WIDTH, val); w = val.get(0); GLX.glXQueryDrawable(display, drawable, GLX.GLX_HEIGHT, val); h = val.get(0); GLX.glXQueryContext(display, ctx, GLX.GLX_SCREEN, val); X11GraphicsScreen x11Screen = (X11GraphicsScreen) X11GraphicsScreen.createScreenDevice(display, val.get(0), false); GLX.glXQueryContext(display, ctx, GLX.GLX_FBCONFIG_ID, val); X11GLXGraphicsConfiguration cfg = null; // sometimes glXQueryContext on an external context gives us a framebuffer config ID // of 0, which doesn't work in a subsequent call to glXChooseFBConfig; if this happens, // create and use a default config (this has been observed when running on CentOS 5.5 inside // of VMWare Server 2.0 with the Mesa 6.5.1 drivers) if (VisualIDHolder.VID_UNDEFINED == val.get(0) || !X11GLXGraphicsConfiguration.GLXFBConfigIDValid( display, x11Screen.getIndex(), val.get(0))) { GLCapabilities glcapsDefault = new GLCapabilities(GLProfile.getDefault()); cfg = X11GLXGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic( glcapsDefault, glcapsDefault, null, x11Screen, VisualIDHolder.VID_UNDEFINED); if (DEBUG) { System.err.println( "X11ExternalGLXContext invalid FBCONFIG_ID " + val.get(0) + ", using default cfg: " + cfg); } } else { cfg = X11GLXGraphicsConfiguration.create(glp, x11Screen, val.get(0)); } final WrappedSurface ns = new WrappedSurface(cfg, drawable, w, h, true); return new X11ExternalGLXContext(new Drawable(factory, ns), ctx); }
static List<GLCapabilitiesImmutable> getAvailableGLCapabilitiesFBConfig( X11GraphicsScreen x11Screen, GLProfile glProfile, boolean isMultisampleAvailable) { PointerBuffer fbcfgsL = null; // Utilizing FBConfig // AbstractGraphicsDevice absDevice = x11Screen.getDevice(); long display = absDevice.getHandle(); int screen = x11Screen.getIndex(); int[] count = {-1}; ArrayList<GLCapabilitiesImmutable> availableCaps = new ArrayList<GLCapabilitiesImmutable>(); fbcfgsL = GLX.glXChooseFBConfig(display, screen, null, 0, count, 0); if (fbcfgsL == null || fbcfgsL.limit() <= 0) { if (DEBUG) { System.err.println( "X11GLXGraphicsConfiguration.getAvailableGLCapabilitiesFBConfig: Failed glXChooseFBConfig (" + x11Screen + "): " + fbcfgsL + ", " + count[0]); } return null; } for (int i = 0; i < fbcfgsL.limit(); i++) { if (!X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities( availableCaps, glProfile, display, fbcfgsL.get(i), GLGraphicsConfigurationUtil.ALL_BITS, isMultisampleAvailable)) { if (DEBUG) { System.err.println( "X11GLXGraphicsConfiguration.getAvailableGLCapabilitiesFBConfig: FBConfig invalid (2): (" + x11Screen + "): fbcfg: " + toHexString(fbcfgsL.get(i))); } } } return availableCaps; }
@Override public SharedResourceRunner.Resource createSharedResource(String connection) { final X11GraphicsDevice sharedDevice = new X11GraphicsDevice( X11Util.openDisplay(connection), AbstractGraphicsDevice.DEFAULT_UNIT, true /* owner */); sharedDevice.lock(); try { final X11GraphicsScreen sharedScreen = new X11GraphicsScreen(sharedDevice, sharedDevice.getDefaultScreen()); GLXUtil.initGLXClientDataSingleton(sharedDevice); final String glXServerVendorName = GLX.glXQueryServerString(sharedDevice.getHandle(), 0, GLX.GLX_VENDOR); final boolean glXServerMultisampleAvailable = GLXUtil.isMultisampleAvailable( GLX.glXQueryServerString(sharedDevice.getHandle(), 0, GLX.GLX_EXTENSIONS)); final GLProfile glp = GLProfile.get(sharedDevice, GLProfile.GL_PROFILE_LIST_MIN_DESKTOP, false); if (null == glp) { throw new GLException("Couldn't get default GLProfile for device: " + sharedDevice); } final GLCapabilitiesImmutable caps = new GLCapabilities(glp); final GLDrawableImpl sharedDrawable = createOnscreenDrawableImpl( createDummySurfaceImpl(sharedDevice, false, caps, caps, null, 64, 64)); sharedDrawable.setRealized(true); final X11GLCapabilities chosenCaps = (X11GLCapabilities) sharedDrawable.getChosenGLCapabilities(); final boolean glxForcedOneOne = !chosenCaps.hasFBConfig(); final VersionNumber glXServerVersion; if (glxForcedOneOne) { glXServerVersion = versionOneOne; } else { glXServerVersion = GLXUtil.getGLXServerVersionNumber(sharedDevice); } final GLContextImpl sharedContext = (GLContextImpl) sharedDrawable.createContext(null); if (null == sharedContext) { throw new GLException("Couldn't create shared context for drawable: " + sharedDrawable); } boolean madeCurrent = false; sharedContext.makeCurrent(); try { madeCurrent = sharedContext.isCurrent(); } finally { sharedContext.release(); } if (sharedContext.hasRendererQuirk(GLRendererQuirks.DontCloseX11Display)) { X11Util.markAllDisplaysUnclosable(); } if (DEBUG) { System.err.println("SharedDevice: " + sharedDevice); System.err.println("SharedScreen: " + sharedScreen); System.err.println("SharedContext: " + sharedContext + ", madeCurrent " + madeCurrent); System.err.println("GLX Server Vendor: " + glXServerVendorName); System.err.println( "GLX Server Version: " + glXServerVersion + ", forced " + glxForcedOneOne); System.err.println("GLX Server Multisample: " + glXServerMultisampleAvailable); System.err.println("GLX Client Vendor: " + GLXUtil.getClientVendorName()); System.err.println("GLX Client Version: " + GLXUtil.getClientVersionNumber()); System.err.println("GLX Client Multisample: " + GLXUtil.isClientMultisampleAvailable()); } return new SharedResource( sharedDevice, sharedScreen, sharedDrawable, sharedContext, glXServerVersion, glXServerVendorName, glXServerMultisampleAvailable && GLXUtil.isClientMultisampleAvailable()); } catch (Throwable t) { throw new GLException( "X11GLXDrawableFactory - Could not initialize shared resources for " + connection, t); } finally { sharedDevice.unlock(); } }
protected static X11GLXGraphicsConfiguration chooseGraphicsConfigurationXVisual( GLCapabilities capabilities, GLCapabilitiesChooser chooser, X11GraphicsScreen x11Screen) { if (chooser == null) { chooser = new DefaultGLCapabilitiesChooser(); } // Until we have a rock-solid visual selection algorithm written // in pure Java, we're going to provide the underlying window // system's selection to the chooser as a hint GLProfile glProfile = capabilities.getGLProfile(); boolean onscreen = capabilities.isOnscreen(); GLCapabilities[] caps = null; int recommendedIndex = -1; XVisualInfo retXVisualInfo = null; int chosen = -1; AbstractGraphicsDevice absDevice = x11Screen.getDevice(); long display = absDevice.getHandle(); try { NativeWindowFactory.getDefaultFactory().getToolkitLock().lock(); X11Lib.XLockDisplay(display); int screen = x11Screen.getIndex(); boolean isMultisampleAvailable = GLXUtil.isMultisampleAvailable(display); int[] attribs = X11GLXGraphicsConfiguration.GLCapabilities2AttribList( capabilities, false, isMultisampleAvailable, display, screen); XVisualInfo[] infos = null; XVisualInfo recommendedVis = GLX.glXChooseVisualCopied(display, screen, attribs, 0); if (DEBUG) { System.err.print("!!! glXChooseVisual recommended "); if (recommendedVis == null) { System.err.println("null visual"); } else { System.err.println("visual id 0x" + Long.toHexString(recommendedVis.getVisualid())); } } int[] count = new int[1]; XVisualInfo template = XVisualInfo.create(); template.setScreen(screen); infos = X11Lib.XGetVisualInfoCopied(display, X11Lib.VisualScreenMask, template, count, 0); if (infos == null || infos.length < 1) { throw new GLException("Error while enumerating available XVisualInfos"); } caps = new GLCapabilities[infos.length]; for (int i = 0; i < infos.length; i++) { caps[i] = X11GLXGraphicsConfiguration.XVisualInfo2GLCapabilities( glProfile, display, infos[i], onscreen, false, isMultisampleAvailable); // Attempt to find the visual chosen by glXChooseVisual if (recommendedVis != null && recommendedVis.getVisualid() == infos[i].getVisualid()) { recommendedIndex = i; } } try { chosen = chooser.chooseCapabilities(capabilities, caps, recommendedIndex); } catch (NativeWindowException e) { if (DEBUG) { e.printStackTrace(); } chosen = -1; } if (chosen < 0) { // keep on going .. if (DEBUG) { System.err.println( "X11GLXGraphicsConfiguration.chooseGraphicsConfigurationXVisual Failed .. unable to choose config, using first"); } chosen = 0; // default .. } else if (chosen >= caps.length) { throw new GLException( "GLCapabilitiesChooser specified invalid index (expected 0.." + (caps.length - 1) + ")"); } if (infos[chosen] == null) { throw new GLException("GLCapabilitiesChooser chose an invalid visual"); } retXVisualInfo = XVisualInfo.create(infos[chosen]); } finally { X11Lib.XUnlockDisplay(display); NativeWindowFactory.getDefaultFactory().getToolkitLock().unlock(); } return new X11GLXGraphicsConfiguration( x11Screen, caps[chosen], capabilities, chooser, retXVisualInfo, 0, -1); }
protected static X11GLXGraphicsConfiguration chooseGraphicsConfigurationFBConfig( GLCapabilities capabilities, GLCapabilitiesChooser chooser, X11GraphicsScreen x11Screen) { int recommendedIndex = -1; GLCapabilities[] caps = null; PointerBuffer fbcfgsL = null; int chosen = -1; int retFBID = -1; XVisualInfo retXVisualInfo = null; GLProfile glProfile = capabilities.getGLProfile(); boolean onscreen = capabilities.isOnscreen(); boolean usePBuffer = capabilities.isPBuffer(); // Utilizing FBConfig // AbstractGraphicsDevice absDevice = x11Screen.getDevice(); long display = absDevice.getHandle(); try { NativeWindowFactory.getDefaultFactory().getToolkitLock().lock(); X11Lib.XLockDisplay(display); int screen = x11Screen.getIndex(); boolean isMultisampleAvailable = GLXUtil.isMultisampleAvailable(display); int[] attribs = X11GLXGraphicsConfiguration.GLCapabilities2AttribList( capabilities, true, isMultisampleAvailable, display, screen); int[] count = {-1}; fbcfgsL = GLX.glXChooseFBConfigCopied(display, screen, attribs, 0, count, 0); if (fbcfgsL == null || fbcfgsL.limit() < 1) { if (DEBUG) { System.err.println( "X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: Failed glXChooseFBConfig (" + x11Screen + "," + capabilities + "): " + fbcfgsL + ", " + count[0]); } return null; } if (!X11GLXGraphicsConfiguration.GLXFBConfigValid(display, fbcfgsL.get(0))) { if (DEBUG) { System.err.println( "X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: Failed - GLX FBConfig invalid: (" + x11Screen + "," + capabilities + "): " + fbcfgsL + ", fbcfg: 0x" + Long.toHexString(fbcfgsL.get(0))); } return null; } recommendedIndex = 0; // 1st match is always recommended .. caps = new GLCapabilities[fbcfgsL.limit()]; for (int i = 0; i < fbcfgsL.limit(); i++) { caps[i] = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities( glProfile, display, fbcfgsL.get(i), false, onscreen, usePBuffer, isMultisampleAvailable); } if (null == chooser) { chosen = recommendedIndex; } else { try { chosen = chooser.chooseCapabilities(capabilities, caps, recommendedIndex); } catch (NativeWindowException e) { if (DEBUG) { e.printStackTrace(); } chosen = -1; } } if (chosen < 0) { // keep on going .. if (DEBUG) { System.err.println( "X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig Failed .. unable to choose config, using first"); } chosen = 0; // default .. } else if (chosen >= caps.length) { throw new GLException( "GLCapabilitiesChooser specified invalid index (expected 0.." + (caps.length - 1) + ")"); } retFBID = X11GLXGraphicsConfiguration.glXFBConfig2FBConfigID(display, fbcfgsL.get(chosen)); retXVisualInfo = GLX.glXGetVisualFromFBConfigCopied(display, fbcfgsL.get(chosen)); if (retXVisualInfo == null) { if (DEBUG) { System.err.println( "X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: Failed glXGetVisualFromFBConfig (" + x11Screen + ", " + fbcfgsL.get(chosen) + " (Continue: " + (false == caps[chosen].isOnscreen()) + "):\n\t" + caps[chosen]); } if (caps[chosen].isOnscreen()) { // Onscreen drawables shall have a XVisual .. return null; } } } finally { X11Lib.XUnlockDisplay(display); NativeWindowFactory.getDefaultFactory().getToolkitLock().unlock(); } return new X11GLXGraphicsConfiguration( x11Screen, caps[chosen], capabilities, chooser, retXVisualInfo, fbcfgsL.get(chosen), retFBID); }
/** * Returns a GLData object describing the created context. * * @return GLData description of the OpenGL context attributes * @exception SWTException * <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver * </ul> */ public GLData getGLData() { checkWidget(); int /*long*/ window = OS.GTK_WIDGET_WINDOW(handle); int /*long*/ xDisplay = OS.gdk_x11_drawable_get_xdisplay(window); GLData data = new GLData(); int[] value = new int[1]; GLX.glXGetConfig(xDisplay, vinfo, GLX.GLX_DOUBLEBUFFER, value); data.doubleBuffer = value[0] != 0; GLX.glXGetConfig(xDisplay, vinfo, GLX.GLX_STEREO, value); data.stereo = value[0] != 0; GLX.glXGetConfig(xDisplay, vinfo, GLX.GLX_RED_SIZE, value); data.redSize = value[0]; GLX.glXGetConfig(xDisplay, vinfo, GLX.GLX_GREEN_SIZE, value); data.greenSize = value[0]; GLX.glXGetConfig(xDisplay, vinfo, GLX.GLX_BLUE_SIZE, value); data.blueSize = value[0]; GLX.glXGetConfig(xDisplay, vinfo, GLX.GLX_ALPHA_SIZE, value); data.alphaSize = value[0]; GLX.glXGetConfig(xDisplay, vinfo, GLX.GLX_DEPTH_SIZE, value); data.depthSize = value[0]; GLX.glXGetConfig(xDisplay, vinfo, GLX.GLX_STENCIL_SIZE, value); data.stencilSize = value[0]; GLX.glXGetConfig(xDisplay, vinfo, GLX.GLX_ACCUM_RED_SIZE, value); data.accumRedSize = value[0]; GLX.glXGetConfig(xDisplay, vinfo, GLX.GLX_ACCUM_GREEN_SIZE, value); data.accumGreenSize = value[0]; GLX.glXGetConfig(xDisplay, vinfo, GLX.GLX_ACCUM_BLUE_SIZE, value); data.accumBlueSize = value[0]; GLX.glXGetConfig(xDisplay, vinfo, GLX.GLX_ACCUM_ALPHA_SIZE, value); data.accumAlphaSize = value[0]; GLX.glXGetConfig(xDisplay, vinfo, GLX.GLX_SAMPLE_BUFFERS, value); data.sampleBuffers = value[0]; GLX.glXGetConfig(xDisplay, vinfo, GLX.GLX_SAMPLES, value); data.samples = value[0]; return data; }
/** * Workaround for apparent issue with ATI's proprietary drivers where direct contexts still send * GLX tokens for GL calls */ public static String getVendorName(long display) { return GLX.glXGetClientString(display, GLX.GLX_VENDOR); }
public static String getExtension(long display) { return GLX.glXGetClientString(display, GLX.GLX_EXTENSIONS); }
/** * Create a GLCanvas widget using the attributes described in the GLData object provided. * * @param parent a composite widget * @param style the bitwise OR'ing of widget styles * @param data the requested attributes of the GLCanvas * @exception IllegalArgumentException * <ul> * <li>ERROR_NULL_ARGUMENT when the data is null * <li>ERROR_UNSUPPORTED_DEPTH when the requested attributes cannot be provided * </ul> * </ul> */ public GLCanvas(Composite parent, int style, GLData data) { super(parent, style); if (data == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); int glxAttrib[] = new int[MAX_ATTRIBUTES]; int pos = 0; glxAttrib[pos++] = GLX.GLX_RGBA; if (data.doubleBuffer) glxAttrib[pos++] = GLX.GLX_DOUBLEBUFFER; if (data.stereo) glxAttrib[pos++] = GLX.GLX_STEREO; if (data.redSize > 0) { glxAttrib[pos++] = GLX.GLX_RED_SIZE; glxAttrib[pos++] = data.redSize; } if (data.greenSize > 0) { glxAttrib[pos++] = GLX.GLX_GREEN_SIZE; glxAttrib[pos++] = data.greenSize; } if (data.blueSize > 0) { glxAttrib[pos++] = GLX.GLX_BLUE_SIZE; glxAttrib[pos++] = data.blueSize; } if (data.alphaSize > 0) { glxAttrib[pos++] = GLX.GLX_ALPHA_SIZE; glxAttrib[pos++] = data.alphaSize; } if (data.depthSize > 0) { glxAttrib[pos++] = GLX.GLX_DEPTH_SIZE; glxAttrib[pos++] = data.depthSize; } if (data.stencilSize > 0) { glxAttrib[pos++] = GLX.GLX_STENCIL_SIZE; glxAttrib[pos++] = data.stencilSize; } if (data.accumRedSize > 0) { glxAttrib[pos++] = GLX.GLX_ACCUM_RED_SIZE; glxAttrib[pos++] = data.accumRedSize; } if (data.accumGreenSize > 0) { glxAttrib[pos++] = GLX.GLX_ACCUM_GREEN_SIZE; glxAttrib[pos++] = data.accumGreenSize; } if (data.accumBlueSize > 0) { glxAttrib[pos++] = GLX.GLX_ACCUM_BLUE_SIZE; glxAttrib[pos++] = data.accumBlueSize; } if (data.accumAlphaSize > 0) { glxAttrib[pos++] = GLX.GLX_ACCUM_ALPHA_SIZE; glxAttrib[pos++] = data.accumAlphaSize; } if (data.sampleBuffers > 0) { glxAttrib[pos++] = GLX.GLX_SAMPLE_BUFFERS; glxAttrib[pos++] = data.sampleBuffers; } if (data.samples > 0) { glxAttrib[pos++] = GLX.GLX_SAMPLES; glxAttrib[pos++] = data.samples; } glxAttrib[pos++] = 0; OS.gtk_widget_realize(handle); int /*long*/ window = OS.GTK_WIDGET_WINDOW(handle); int /*long*/ xDisplay = OS.gdk_x11_drawable_get_xdisplay(window); int /*long*/ infoPtr = GLX.glXChooseVisual(xDisplay, OS.XDefaultScreen(xDisplay), glxAttrib); if (infoPtr == 0) { dispose(); SWT.error(SWT.ERROR_UNSUPPORTED_DEPTH); } vinfo = new XVisualInfo(); GLX.memmove(vinfo, infoPtr, XVisualInfo.sizeof); OS.XFree(infoPtr); int /*long*/ screen = OS.gdk_screen_get_default(); int /*long*/ gdkvisual = OS.gdk_x11_screen_lookup_visual(screen, vinfo.visualid); // FIXME- share lists // context = GLX.glXCreateContext (xDisplay, info, share == null ? 0 : share.context, true); context = GLX.glXCreateContext(xDisplay, vinfo, 0, true); if (context == 0) SWT.error(SWT.ERROR_NO_HANDLES); GdkWindowAttr attrs = new GdkWindowAttr(); attrs.width = 1; attrs.height = 1; attrs.event_mask = OS.GDK_KEY_PRESS_MASK | OS.GDK_KEY_RELEASE_MASK | OS.GDK_FOCUS_CHANGE_MASK | OS.GDK_POINTER_MOTION_MASK | OS.GDK_BUTTON_PRESS_MASK | OS.GDK_BUTTON_RELEASE_MASK | OS.GDK_ENTER_NOTIFY_MASK | OS.GDK_LEAVE_NOTIFY_MASK | OS.GDK_EXPOSURE_MASK | OS.GDK_VISIBILITY_NOTIFY_MASK | OS.GDK_POINTER_MOTION_HINT_MASK; attrs.window_type = OS.GDK_WINDOW_CHILD; attrs.visual = gdkvisual; glWindow = OS.gdk_window_new(window, attrs, OS.GDK_WA_VISUAL); OS.gdk_window_set_user_data(glWindow, handle); if ((style & SWT.NO_BACKGROUND) != 0) OS.gdk_window_set_back_pixmap(window, 0, false); xWindow = OS.gdk_x11_drawable_get_xid(glWindow); OS.gdk_window_show(glWindow); Listener listener = new Listener() { public void handleEvent(Event event) { switch (event.type) { case SWT.Paint: /** * Bug in MESA. MESA does some nasty sort of polling to try and ensure that their * buffer sizes match the current X state. This state can be updated using * glViewport(). FIXME: There has to be a better way of doing this. */ int[] viewport = new int[4]; GLX.glGetIntegerv(GLX.GL_VIEWPORT, viewport); GLX.glViewport(viewport[0], viewport[1], viewport[2], viewport[3]); break; case SWT.Resize: Rectangle clientArea = getClientArea(); OS.gdk_window_move(glWindow, clientArea.x, clientArea.y); OS.gdk_window_resize(glWindow, clientArea.width, clientArea.height); break; case SWT.Dispose: int /*long*/ window = OS.GTK_WIDGET_WINDOW(handle); int /*long*/ xDisplay = OS.gdk_x11_drawable_get_xdisplay(window); if (context != 0) { if (GLX.glXGetCurrentContext() == context) { GLX.glXMakeCurrent(xDisplay, 0, 0); } GLX.glXDestroyContext(xDisplay, context); context = 0; } if (glWindow != 0) { OS.gdk_window_destroy(glWindow); glWindow = 0; } break; } } }; addListener(SWT.Resize, listener); addListener(SWT.Paint, listener); addListener(SWT.Dispose, listener); }
/** * Swaps the front and back color buffers. * * @exception SWTException * <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver * </ul> */ public void swapBuffers() { checkWidget(); int /*long*/ window = OS.GTK_WIDGET_WINDOW(handle); int /*long*/ xDisplay = OS.gdk_x11_drawable_get_xdisplay(window); GLX.glXSwapBuffers(xDisplay, xWindow); }
/** * Returns a boolean indicating whether the receiver's OpenGL context is the current context. * * @return true if the receiver holds the current OpenGL context, false otherwise * @exception SWTException * <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver * </ul> */ public boolean isCurrent() { checkWidget(); return GLX.glXGetCurrentContext() == context; }
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); }
protected void swapBuffersImpl() { GLX.glXSwapBuffers(getNativeWindow().getDisplayHandle(), getHandle()); }
private static X11GLXGraphicsConfiguration chooseGraphicsConfigurationXVisual( GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsReq, GLCapabilitiesChooser chooser, X11GraphicsScreen x11Screen) { if (chooser == null) { chooser = new DefaultGLCapabilitiesChooser(); } GLProfile glProfile = capsChosen.getGLProfile(); final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits( capsChosen.isOnscreen(), false /* pbuffer */); ArrayList availableCaps = new ArrayList(); int recommendedIndex = -1; 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, false, isMultisampleAvailable, display, screen); // 1st choice: get GLCapabilities based on users GLCapabilities setting recommendedIndex as // preferred choice XVisualInfo recommendedVis = GLX.glXChooseVisual(display, screen, attribs, 0); if (DEBUG) { System.err.print("glXChooseVisual recommended "); if (recommendedVis == null) { System.err.println("null visual"); } else { System.err.println("visual id " + toHexString(recommendedVis.getVisualid())); } } // 2nd choice: get all GLCapabilities available, preferred recommendedIndex might be available // if 1st choice was successful int[] count = new int[1]; XVisualInfo template = XVisualInfo.create(); template.setScreen(screen); XVisualInfo[] infos = X11Lib.XGetVisualInfo(display, X11Lib.VisualScreenMask, template, count, 0); if (infos == null || infos.length < 1) { throw new GLException("Error while enumerating available XVisualInfos"); } for (int i = 0; i < infos.length; i++) { if (!X11GLXGraphicsConfiguration.XVisualInfo2GLCapabilities( availableCaps, glProfile, display, infos[i], winattrmask, isMultisampleAvailable)) { if (DEBUG) { System.err.println( "X11GLXGraphicsConfiguration.chooseGraphicsConfigurationXVisual: XVisual invalid: (" + x11Screen + "): fbcfg: " + toHexString(infos[i].getVisualid())); } } else { // Attempt to find the visual chosenIndex by glXChooseVisual, if not translucent if (capsChosen.isBackgroundOpaque() && recommendedVis != null && recommendedVis.getVisualid() == infos[i].getVisualid()) { recommendedIndex = availableCaps.size() - 1; } } } int chosenIndex = chooseCapabilities(chooser, capsChosen, availableCaps, recommendedIndex); if (0 > chosenIndex) { if (DEBUG) { System.err.println( "X11GLXGraphicsConfiguration.chooseGraphicsConfigurationXVisual: failed, return null"); Thread.dumpStack(); } return null; } X11GLCapabilities chosenCaps = (X11GLCapabilities) availableCaps.get(chosenIndex); return new X11GLXGraphicsConfiguration(x11Screen, chosenCaps, capsReq, chooser); }
@Override public SharedResourceRunner.Resource createSharedResource( final AbstractGraphicsDevice adevice) { final X11GraphicsDevice device = new X11GraphicsDevice( X11Util.openDisplay(adevice.getConnection()), adevice.getUnitID(), true /* owner */); GLContextImpl context = null; boolean contextIsCurrent = false; device.lock(); try { final X11GraphicsScreen screen = new X11GraphicsScreen(device, device.getDefaultScreen()); GLXUtil.initGLXClientDataSingleton(device); final String glXServerVendorName = GLX.glXQueryServerString(device.getHandle(), 0, GLX.GLX_VENDOR); final boolean glXServerMultisampleAvailable = GLXUtil.isMultisampleAvailable( GLX.glXQueryServerString(device.getHandle(), 0, GLX.GLX_EXTENSIONS)); final GLProfile glp = GLProfile.get(device, GLProfile.GL_PROFILE_LIST_MIN_DESKTOP, false); if (null == glp) { throw new GLException("Couldn't get default GLProfile for device: " + device); } final GLCapabilitiesImmutable caps = new GLCapabilities(glp); final GLDrawableImpl drawable = createOnscreenDrawableImpl( createDummySurfaceImpl(device, false, caps, caps, null, 64, 64)); drawable.setRealized(true); final X11GLCapabilities chosenCaps = (X11GLCapabilities) drawable.getChosenGLCapabilities(); final boolean glxForcedOneOne = !chosenCaps.hasFBConfig(); final VersionNumber glXServerVersion; if (glxForcedOneOne) { glXServerVersion = versionOneOne; } else { glXServerVersion = GLXUtil.getGLXServerVersionNumber(device); } context = (GLContextImpl) drawable.createContext(null); if (null == context) { throw new GLException("Couldn't create shared context for drawable: " + drawable); } contextIsCurrent = GLContext.CONTEXT_NOT_CURRENT != context.makeCurrent(); final boolean allowsSurfacelessCtx; if (contextIsCurrent && context.getGLVersionNumber().compareTo(GLContext.Version3_0) >= 0) { allowsSurfacelessCtx = probeSurfacelessCtx(context, true /* restoreDrawable */); } else { setNoSurfacelessCtxQuirk(context); allowsSurfacelessCtx = false; } if (context.hasRendererQuirk(GLRendererQuirks.DontCloseX11Display)) { X11Util.markAllDisplaysUnclosable(); } if (DEBUG_SHAREDCTX) { System.err.println("SharedDevice: " + device); System.err.println("SharedScreen: " + screen); System.err.println("SharedContext: " + context + ", madeCurrent " + contextIsCurrent); System.err.println(" allowsSurfacelessCtx " + allowsSurfacelessCtx); System.err.println("GLX Server Vendor: " + glXServerVendorName); System.err.println( "GLX Server Version: " + glXServerVersion + ", forced " + glxForcedOneOne); System.err.println("GLX Server Multisample: " + glXServerMultisampleAvailable); System.err.println("GLX Client Vendor: " + GLXUtil.getClientVendorName()); System.err.println("GLX Client Version: " + GLXUtil.getClientVersionNumber()); System.err.println("GLX Client Multisample: " + GLXUtil.isClientMultisampleAvailable()); } return new SharedResource( device, screen, drawable, context, glXServerVersion, glXServerVendorName, glXServerMultisampleAvailable && GLXUtil.isClientMultisampleAvailable()); } catch (final Throwable t) { throw new GLException( "X11GLXDrawableFactory - Could not initialize shared resources for " + adevice, t); } finally { if (contextIsCurrent) { context.release(); } device.unlock(); } }