aboutsummaryrefslogtreecommitdiffstats
path: root/src/newt/classes
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2019-11-28 02:00:29 +0100
committerSven Gothel <[email protected]>2019-11-28 02:00:29 +0100
commit3e19c2267500c0c459e7dce8d2087387a56f3296 (patch)
tree1c6e2e64b7f5f5ee8d6178824dc6ff2e0a3bdbbe /src/newt/classes
parent976e89ff24da3b2cdf206e8ef8f222f54fb467de (diff)
Bug 1156 - Implement DRM/GBM Support for JOGL(EGL) and NEWT
Adding new classes DRMLib (gluegen of drm + gbm), DRMUtil and DRMMode GBMDummyUpstreamSurfaceHook to new package jogamp.nativewindow.drm, allowing full awareness of DRM + GBM within NativeWindow for JOGL + NEWT. DRMMode replaces the previous native code of collecting drmMode* attributes: active connector, used mode, encoder etc and also supports multiple active connectors. DRMUtil handles the global static drmFd (file descriptor), currently only the GNU/Linux DRM device is supported. GBMDummyUpstreamSurfaceHook provides a simple dummy GBM surface. NativeWindow provides the new nativewindow_drm.so and nativewindow-os-drm.jar, which are included in most 'all' jar packages. build property: setup.addNativeEGLGBM -> setup.addNativeDRMGBM Changes NativeWindowFactory: - TYPE_EGL_GBM -> TYPE_DRM_GBM while keeping the package ID of '.egl.gbm' for NEWT (using EGL) - Initializing DRMUtil at initialization Changes EGLDrawableFactory: - Using native GBM device for the default EGL display creation instead of EGL_DEFAULT_DISPLAY. This resolves issues as seen in Bug 1402, as well in cases w/o surfaceless support. - GL profile mapping uses surfaceless when available for GBM, otherwise uses createDummySurfaceImpl (dummy GBM surface via GBMDummyUpstreamSurfaceHook) - createDummySurfaceImpl uses a dummy GBM surface via GBMDummyUpstreamSurfaceHook - DesktopGL not available with GBM, see Bug 1401 NEWT's DRM + GBM + EGL Driver - Using DRMLib, DRMUtil and DRMMode, removed most native code but WindowDriver swapBuffer - ScreenDriver uses DRMMode, however currently only first connected CRT. - WindowDriver aligns position and size to screen, positions other than 0/0 causes DRM failure - WindowDriver reconfigure n/a NEWT TODO: - DRM Cursor support (mouse pointer) - Pointer event handling
Diffstat (limited to 'src/newt/classes')
-rw-r--r--src/newt/classes/jogamp/newt/driver/egl/gbm/DisplayDriver.java29
-rw-r--r--src/newt/classes/jogamp/newt/driver/egl/gbm/ScreenDriver.java58
-rw-r--r--src/newt/classes/jogamp/newt/driver/egl/gbm/WindowDriver.java163
3 files changed, 159 insertions, 91 deletions
diff --git a/src/newt/classes/jogamp/newt/driver/egl/gbm/DisplayDriver.java b/src/newt/classes/jogamp/newt/driver/egl/gbm/DisplayDriver.java
index 4d9835826..847532bb4 100644
--- a/src/newt/classes/jogamp/newt/driver/egl/gbm/DisplayDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/egl/gbm/DisplayDriver.java
@@ -31,6 +31,8 @@ import com.jogamp.nativewindow.AbstractGraphicsDevice;
import com.jogamp.nativewindow.NativeWindowException;
import com.jogamp.opengl.GLProfile;
+import jogamp.nativewindow.drm.DRMLib;
+import jogamp.nativewindow.drm.DRMUtil;
import jogamp.newt.DisplayImpl;
import jogamp.newt.NEWTJNILibLoader;
import jogamp.opengl.egl.EGLDisplayUtil;
@@ -50,31 +52,23 @@ public class DisplayDriver extends DisplayImpl {
if (!WindowDriver.initIDs()) {
throw new NativeWindowException("Failed to initialize egl.gbm Window jmethodIDs");
}
- drmHandle = initDrm(DEBUG);
- }
-
- static void validateDrm() {
- if( 0 == drmHandle ) {
- throw new NativeWindowException("Failed to initialize egl.gbm DRM handle");
- }
}
public static void initSingleton() {
// just exist to ensure static init has been run
}
- private static void shutdownHook() {
- freeDrm(drmHandle);
- }
-
public DisplayDriver() {
gbmHandle = 0;
}
@Override
protected void createNativeImpl() {
- validateDrm();
- gbmHandle = OpenGBMDisplay0(drmHandle);
+ final int drmFd = DRMUtil.getDrmFd();
+ if( 0 > drmFd ) {
+ throw new NativeWindowException("Failed to initialize DRM");
+ }
+ gbmHandle = DRMLib.gbm_create_device(drmFd);
aDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(gbmHandle, AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT);
aDevice.open();
}
@@ -82,11 +76,10 @@ public class DisplayDriver extends DisplayImpl {
@Override
protected void closeNativeImpl(final AbstractGraphicsDevice aDevice) {
aDevice.close();
- CloseGBMDisplay0(gbmHandle);
+ DRMLib.gbm_device_destroy(gbmHandle);
gbmHandle = 0;
}
- /* pp */ static final long getDrmHandle() { validateDrm(); return drmHandle; }
/* pp */ final long getGBMHandle() { return gbmHandle; }
@Override
@@ -98,14 +91,8 @@ public class DisplayDriver extends DisplayImpl {
// Internals only
//
private static native boolean initIDs();
- private static native long initDrm(boolean verbose);
- private static native void freeDrm(long drmHandle);
-
- private static native long OpenGBMDisplay0(long drmHandle);
- private static native void CloseGBMDisplay0(long gbmHandle);
private static native void DispatchMessages0();
- private static final long drmHandle;
private long gbmHandle;
}
diff --git a/src/newt/classes/jogamp/newt/driver/egl/gbm/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/egl/gbm/ScreenDriver.java
index 2ff7ab299..7d6c2b41c 100644
--- a/src/newt/classes/jogamp/newt/driver/egl/gbm/ScreenDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/egl/gbm/ScreenDriver.java
@@ -31,6 +31,9 @@ import com.jogamp.nativewindow.DefaultGraphicsScreen;
import com.jogamp.nativewindow.util.Rectangle;
import com.jogamp.newt.MonitorDevice;
import com.jogamp.newt.MonitorMode;
+
+import jogamp.nativewindow.drm.DRMUtil;
+import jogamp.nativewindow.drm.DrmMode;
import jogamp.newt.MonitorModeProps;
import jogamp.newt.ScreenImpl;
@@ -45,26 +48,40 @@ public class ScreenDriver extends ScreenImpl {
@Override
protected void createNativeImpl() {
aScreen = new DefaultGraphicsScreen(getDisplay().getGraphicsDevice(), screen_idx);
- initNative( DisplayDriver.getDrmHandle() );
+ drmMode = DrmMode.create(DRMUtil.getDrmFd(), true /* preferNativeMode */);
+ if( DEBUG ) {
+ drmMode.print(System.err);
+ }
}
@Override
- protected void closeNativeImpl() { }
+ protected void closeNativeImpl() {
+ drmMode.destroy();
+ drmMode = null;
+ }
@Override
protected int validateScreenIndex(final int idx) {
- return 0; // only one screen available
+ // FIXME add multi-monitor support
+ /**
+ if( 0 <= idx && idx < drmMode.count ) {
+ return idx;
+ } */
+ return 0;
}
@Override
protected void collectNativeMonitorModesAndDevicesImpl(final MonitorModeProps.Cache cache) {
+ // FIXME add multi-monitor multi-mode support
+ final int scridx = 0; // getIndex();
+
int[] props = new int[ MonitorModeProps.NUM_MONITOR_MODE_PROPERTIES_ALL ];
int i = 0;
props[i++] = MonitorModeProps.NUM_MONITOR_MODE_PROPERTIES_ALL;
- props[i++] = cachedWidth; // width
- props[i++] = cachedHeight; // height
+ props[i++] = drmMode.getModes()[scridx].getHdisplay();
+ props[i++] = drmMode.getModes()[scridx].getVdisplay();
props[i++] = ScreenImpl.default_sm_bpp; // FIXME
- props[i++] = cachedVRrefresh * 100;
+ props[i++] = drmMode.getModes()[scridx].getVrefresh() * 100;
props[i++] = 0; // flags
props[i++] = 0; // mode_idx
props[i++] = 0; // rotation
@@ -76,45 +93,40 @@ public class ScreenDriver extends ScreenImpl {
props[i++] = 0; // crt_idx
props[i++] = 0; // is-clone
props[i++] = 1; // is-primary
- props[i++] = ScreenImpl.default_sm_widthmm; // FIXME
- props[i++] = ScreenImpl.default_sm_heightmm; // FIXME
+ props[i++] = drmMode.getConnectors()[scridx].getMmWidth();
+ props[i++] = drmMode.getConnectors()[scridx].getMmHeight();
props[i++] = 0; // rotated viewport x pixel-units
props[i++] = 0; // rotated viewport y pixel-units
- props[i++] = cachedWidth; // rotated viewport width pixel-units
- props[i++] = cachedHeight; // rotated viewport height pixel-units
+ props[i++] = drmMode.getModes()[scridx].getHdisplay(); // rotated viewport width pixel-units
+ props[i++] = drmMode.getModes()[scridx].getVdisplay(); // rotated viewport height pixel-units
props[i++] = 0; // rotated viewport x window-units
props[i++] = 0; // rotated viewport y window-units
- props[i++] = cachedWidth; // rotated viewport width window-units
- props[i++] = cachedHeight; // rotated viewport height window-units
+ props[i++] = drmMode.getModes()[scridx].getHdisplay(); // rotated viewport width window-units
+ props[i++] = drmMode.getModes()[scridx].getVdisplay(); // rotated viewport height window-units
MonitorModeProps.streamInMonitorDevice(cache, this, currentMode, null, cache.monitorModes, props, 0, null);
}
@Override
protected MonitorMode queryCurrentMonitorModeImpl(final MonitorDevice monitor) {
+ // FIXME add multi-monitor multi-mode support
return monitor.getSupportedModes().get(0);
}
@Override
protected boolean setCurrentMonitorModeImpl(final MonitorDevice monitor, final MonitorMode mode) {
+ // FIXME add multi-monitor multi-mode support
return false;
}
@Override
protected void calcVirtualScreenOriginAndSize(final Rectangle viewport, final Rectangle viewportInWindowUnits) {
- viewport.set(0, 0, cachedWidth, cachedHeight);
+ // FIXME add multi-monitor support
+ final int scridx = 0; // getIndex();
+ viewport.set(0, 0, drmMode.getModes()[scridx].getHdisplay(), drmMode.getModes()[scridx].getVdisplay());
viewportInWindowUnits.set(viewport);
}
- /** Called from {@link #initNative(long)}. */
- protected void notifyScreenMode(final int width, final int height, final int vrefresh) {
- cachedWidth = width; // write to static field intended
- cachedHeight = height; // write to static field intended
- cachedVRrefresh = vrefresh;
- }
-
- private static int cachedWidth = 0;
- private static int cachedHeight = 0;
- private static int cachedVRrefresh = 0;
+ /* pp */ DrmMode drmMode;
protected static native boolean initIDs();
protected native void initNative(long drmHandle);
diff --git a/src/newt/classes/jogamp/newt/driver/egl/gbm/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/egl/gbm/WindowDriver.java
index 8517a132f..7253fac52 100644
--- a/src/newt/classes/jogamp/newt/driver/egl/gbm/WindowDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/egl/gbm/WindowDriver.java
@@ -27,17 +27,27 @@
*/
package jogamp.newt.driver.egl.gbm;
+import java.nio.ByteBuffer;
+import java.nio.IntBuffer;
+
+import com.jogamp.common.nio.Buffers;
+import com.jogamp.nativewindow.AbstractGraphicsDevice;
import com.jogamp.nativewindow.AbstractGraphicsScreen;
import com.jogamp.nativewindow.NativeWindowException;
import com.jogamp.nativewindow.egl.EGLGraphicsDevice;
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.opengl.GLCapabilitiesChooser;
import com.jogamp.opengl.GLCapabilitiesImmutable;
import com.jogamp.opengl.GLException;
import com.jogamp.opengl.egl.EGL;
+import jogamp.nativewindow.drm.DRMLib;
+import jogamp.nativewindow.drm.DRMUtil;
+import jogamp.nativewindow.drm.DrmMode;
+import jogamp.nativewindow.drm.drmModeModeInfo;
import jogamp.newt.WindowImpl;
import jogamp.newt.driver.linux.LinuxEventDeviceTracker;
import jogamp.newt.driver.linux.LinuxMouseTracker;
@@ -120,21 +130,66 @@ public class WindowDriver extends WindowImpl {
}
}
+ /**
+ * Align given rectangle to given screen bounds.
+ *
+ * @param screen
+ * @param rect the {@link RectangleImmutable} in pixel units
+ * @param definePosSize if {@code true} issue {@link #definePosition(int, int)} and {@link #defineSize(int, int)}
+ * if either has changed.
+ * @return If position or size has been aligned a new {@link RectangleImmutable} instance w/ clamped values
+ * will be returned, otherwise the given {@code rect} is returned.
+ */
+ private RectangleImmutable alignRect2Screen(final ScreenDriver screen, final RectangleImmutable rect, final boolean definePosSize) {
+ int x = rect.getX();
+ int y = rect.getY();
+ int w = rect.getWidth();
+ int h = rect.getHeight();
+ final int s_w = screen.getWidth();
+ final int s_h = screen.getHeight();
+ boolean modPos = false;
+ boolean modSize = false;
+ if( 0 != x ) {
+ x = 0;
+ modPos = true;
+ }
+ if( 0 != y ) {
+ y = 0;
+ modPos = true;
+ }
+ if( s_w != w ) {
+ w = s_w;
+ modSize = true;
+ }
+ if( s_h != h ) {
+ h = s_h;
+ modSize = true;
+ }
+ if( modPos || modSize ) {
+ if( definePosSize ) {
+ if( modPos ) {
+ definePosition(x, y);
+ }
+ if( modSize ) {
+ defineSize(w, h);
+ }
+ }
+ return new Rectangle(x, y, w, h);
+ } else {
+ return rect;
+ }
+ }
+
@Override
protected boolean canCreateNativeImpl() {
// clamp if required incl. redefinition of position and size
- clampRect((ScreenDriver) getScreen(), new Rectangle(getX(), getY(), getWidth(), getHeight()), true);
- return true; // default: always able to be created
- }
+ // clampRect((ScreenDriver) getScreen(), new Rectangle(getX(), getY(), getWidth(), getHeight()), true);
- static int fourcc_code(final char a, final char b, final char c, final char d) {
- // return ( (int)(a) | ((int)(b) << 8) | ((int)(c) << 16) | ((int)(d) << 24) );
- return ( (a) | ((b) << 8) | ((c) << 16) | ((d) << 24) );
+ // Turns out DRM / GBM can only handle full screen size FB and crtc-modesetting (?)
+ alignRect2Screen((ScreenDriver) getScreen(), new Rectangle(getX(), getY(), getWidth(), getHeight()), true);
+
+ return true; // default: always able to be created
}
- /** [31:0] x:R:G:B 8:8:8:8 little endian */
- static final int GBM_FORMAT_XRGB8888 = fourcc_code('X', 'R', '2', '4');
- /** [31:0] A:R:G:B 8:8:8:8 little endian */
- static final int GBM_FORMAT_ARGB8888 = fourcc_code('A', 'R', '2', '4');
@Override
protected void createNativeImpl() {
@@ -148,7 +203,12 @@ public class WindowDriver extends WindowImpl {
// Create own screen/device resource instance allowing independent ownership,
// while still utilizing shared EGL resources.
final AbstractGraphicsScreen aScreen = screen.getGraphicsScreen();
- final int nativeVisualID = capsRequested.isBackgroundOpaque() ? GBM_FORMAT_XRGB8888 : GBM_FORMAT_ARGB8888;
+ final int nativeVisualID = capsRequested.isBackgroundOpaque() ? DRMUtil.GBM_FORMAT_XRGB8888 : DRMUtil.GBM_FORMAT_ARGB8888;
+
+ final boolean ctDesktopGL = false;
+ if( !EGL.eglBindAPI( ctDesktopGL ? EGL.EGL_OPENGL_API : EGL.EGL_OPENGL_ES_API) ) {
+ throw new GLException("Caught: eglBindAPI to "+(ctDesktopGL ? "ES" : "GL")+" failed , error "+toHexString(EGL.eglGetError()));
+ }
final EGLGraphicsConfiguration eglConfig = EGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(
(GLCapabilitiesImmutable)capsRequested, (GLCapabilitiesImmutable)capsRequested, (GLCapabilitiesChooser)capabilitiesChooser,
@@ -157,8 +217,8 @@ public class WindowDriver extends WindowImpl {
throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this);
}
setGraphicsConfiguration(eglConfig);
- final long nativeWindowHandle = CreateWindow0(DisplayDriver.getDrmHandle(), display.getGBMHandle(),
- getX(), getY(), getWidth(), getHeight(), nativeVisualID);
+ final long nativeWindowHandle = DRMLib.gbm_surface_create(display.getGBMHandle(), getWidth(), getHeight(), nativeVisualID,
+ DRMLib.GBM_BO_USE_SCANOUT | DRMLib.GBM_BO_USE_RENDERING);
if (nativeWindowHandle == 0) {
throw new NativeWindowException("Error creating egl window: "+eglConfig);
}
@@ -174,15 +234,7 @@ public class WindowDriver extends WindowImpl {
throw new NativeWindowException("Creation of eglSurface failed: "+eglConfig+", windowHandle 0x"+Long.toHexString(nativeWindowHandle)+", error "+toHexString(EGL.eglGetError()));
}
- if(false) {
- /**
- if(!EGL.eglSwapBuffers(display.getHandle(), eglSurface)) {
- throw new GLException("Error swapping buffers, eglError "+toHexString(EGL.eglGetError())+", "+this);
- } */
- lastBO = FirstSwapSurface0(DisplayDriver.getDrmHandle(), nativeWindowHandle, display.getHandle(), eglSurface);
- } else {
- lastBO = 0;
- }
+ lastBO = 0;
if( null != linuxEventDeviceTracker ) {
addWindowListener(linuxEventDeviceTracker);
@@ -196,8 +248,7 @@ public class WindowDriver extends WindowImpl {
@Override
protected void closeNativeImpl() {
- final DisplayDriver display = (DisplayDriver) getScreen().getDisplay();
- final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) getGraphicsConfiguration().getScreen().getDevice();
+ final Display display = getScreen().getDisplay();
if( null != linuxMouseTracker ) {
removeWindowListener(linuxMouseTracker);
@@ -209,7 +260,7 @@ public class WindowDriver extends WindowImpl {
lastBO = 0;
if(0 != eglSurface) {
try {
- if (!EGL.eglDestroySurface(eglDevice.getHandle(), eglSurface)) {
+ if (!EGL.eglDestroySurface(display.getHandle(), eglSurface)) {
throw new GLException("Error destroying window surface (eglDestroySurface)");
}
} catch (final Throwable t) {
@@ -219,11 +270,9 @@ public class WindowDriver extends WindowImpl {
}
}
if( 0 != windowHandleClose ) {
- CloseWindow0(display.getGBMHandle(), windowHandleClose);
+ DRMLib.gbm_surface_destroy(windowHandleClose);
windowHandleClose = 0;
}
-
- eglDevice.close();
}
@Override
@@ -233,21 +282,21 @@ public class WindowDriver extends WindowImpl {
@Override
public boolean surfaceSwap() {
- final DisplayDriver display = (DisplayDriver) getScreen().getDisplay();
+ final ScreenDriver screen = (ScreenDriver) getScreen();
+ final DisplayDriver display = (DisplayDriver) screen.getDisplay();
final long nativeWindowHandle = getWindowHandle();
+ final DrmMode d = screen.drmMode;
+ if(!EGL.eglSwapBuffers(display.getHandle(), eglSurface)) {
+ throw new GLException("Error swapping buffers, eglError "+toHexString(EGL.eglGetError())+", "+this);
+ }
if( 0 == lastBO ) {
- /** if(!EGL.eglSwapBuffers(display.getHandle(), eglSurface)) {
- throw new GLException("Error swapping buffers, eglError "+toHexString(EGL.eglGetError())+", "+this);
- } */
- lastBO = FirstSwapSurface0(DisplayDriver.getDrmHandle(), nativeWindowHandle, display.getHandle(), eglSurface);
+ lastBO = FirstSwapSurface(d.drmFd, d.getCrtcIDs()[0], getX(), getY(), d.getConnectors()[0].getConnector_id(),
+ d.getModes()[0], nativeWindowHandle);
+ } else {
+ lastBO = NextSwapSurface(d.drmFd, d.getCrtcIDs()[0], getX(), getY(), d.getConnectors()[0].getConnector_id(),
+ d.getModes()[0], nativeWindowHandle, lastBO);
}
-
- /**if(!EGL.eglSwapBuffers(display.getHandle(), eglSurface)) {
- throw new GLException("Error swapping buffers, eglError "+toHexString(EGL.eglGetError())+", "+this);
- } */
- lastBO = NextSwapSurface0(DisplayDriver.getDrmHandle(), nativeWindowHandle, lastBO, display.getHandle(), eglSurface);
- System.exit(1);
return true; // eglSwapBuffers done!
}
@@ -273,11 +322,11 @@ public class WindowDriver extends WindowImpl {
@Override
protected boolean reconfigureWindowImpl(final int x, final int y, final int width, final int height, final int flags) {
- final RectangleImmutable rect = clampRect((ScreenDriver) getScreen(), new Rectangle(x, y, width, height), false);
+ // final RectangleImmutable rect = clampRect((ScreenDriver) getScreen(), new Rectangle(x, y, width, height), false);
// reconfigure0 will issue position/size changed events if required
- reconfigure0(getWindowHandle(), rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight(), flags);
+ // reconfigure0(getWindowHandle(), rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight(), flags);
- return true;
+ return false;
}
@Override
@@ -295,9 +344,29 @@ public class WindowDriver extends WindowImpl {
private long lastBO;
protected static native boolean initIDs();
- private native long CreateWindow0(long drmHandle, long gbmHandle, int x, int y, int width, int height, int nativeVisualID);
- private native void CloseWindow0(long gbmDisplay, long eglWindowHandle);
- private native void reconfigure0(long eglWindowHandle, int x, int y, int width, int height, int flags);
- private native long FirstSwapSurface0(long drmHandle, long gbmSurface, long eglDisplay, long eglSurface);
- private native long NextSwapSurface0(long drmHandle, long gbmSurface, long lastBO, long eglDisplay, long eglSurface);
+ // private native void reconfigure0(long eglWindowHandle, int x, int y, int width, int height, int flags);
+
+ private long FirstSwapSurface(final int drmFd, final int crtc_id, final int x, final int y, final int connector_id, final drmModeModeInfo drmMode, final long gbmSurface) {
+ final ByteBuffer bb = drmMode.getBuffer();
+ if(!Buffers.isDirect(bb)) {
+ throw new IllegalArgumentException("drmMode's buffer is not direct (NIO)");
+ }
+ return FirstSwapSurface0(drmFd, crtc_id, x, y, connector_id,
+ bb, Buffers.getDirectBufferByteOffset(bb),
+ gbmSurface);
+ }
+ private native long FirstSwapSurface0(int drmFd, int crtc_id, int x, int y, int connector_id, Object mode, int mode_byte_offset,
+ long gbmSurface);
+
+ private long NextSwapSurface(final int drmFd, final int crtc_id, final int x, final int y, final int connector_id, final drmModeModeInfo drmMode, final long gbmSurface, final long lastBO) {
+ final ByteBuffer bb = drmMode.getBuffer();
+ if(!Buffers.isDirect(bb)) {
+ throw new IllegalArgumentException("drmMode's buffer is not direct (NIO)");
+ }
+ return NextSwapSurface0(drmFd, crtc_id, x, y, connector_id,
+ bb, Buffers.getDirectBufferByteOffset(bb),
+ gbmSurface, lastBO);
+ }
+ private native long NextSwapSurface0(int drmFd, int crtc_id, int x, int y, int connector_id, Object mode, int mode_byte_offset,
+ long gbmSurface, long lastBO);
}