aboutsummaryrefslogtreecommitdiffstats
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
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
-rw-r--r--make/build-common.xml12
-rw-r--r--make/build-nativewindow.xml92
-rw-r--r--make/build-newt.xml35
-rw-r--r--make/config/nativewindow/drm-gbm-lib.cfg106
-rwxr-xr-x[-rw-r--r--]make/scripts/gluegen-gl.sh23
-rw-r--r--make/scripts/tests.sh6
-rw-r--r--make/stub_includes/drm/drm-gbm-lib.c37
-rw-r--r--make/stub_includes/drm/drm.h1005
-rw-r--r--make/stub_includes/drm/drm_mode.h895
-rw-r--r--make/stub_includes/drm/gbm.h406
-rw-r--r--make/stub_includes/drm/xf86drm.h883
-rw-r--r--make/stub_includes/drm/xf86drmMode.h555
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java2
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java130
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java23
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java12
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/GraphicsConfigurationFactory.java18
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/NativeWindowFactory.java11
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/VisualIDHolder.java8
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/drm/DRMUtil.java154
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/drm/DrmMode.java304
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/drm/GBMDummyUpstreamSurfaceHook.java105
-rw-r--r--src/nativewindow/native/JVM_JNI8.c2
-rw-r--r--src/nativewindow/native/drm/DRMmisc.c89
-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
-rw-r--r--src/newt/native/drm_gbm.c83
-rw-r--r--src/newt/native/drm_gbm.h (renamed from src/newt/native/egl_gbm.h)11
-rw-r--r--src/newt/native/drm_gbm_legacy.c306
-rw-r--r--src/newt/native/egl_gbm.c353
-rw-r--r--src/newt/native/egl_gbm_drmflip.c230
32 files changed, 5384 insertions, 762 deletions
diff --git a/make/build-common.xml b/make/build-common.xml
index 1d8928cf2..d33803d93 100644
--- a/make/build-common.xml
+++ b/make/build-common.xml
@@ -1,5 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ - Some environment defs affecting native compilation
+ setup.addNativeDRMGBM ( always true if 'isLinux' )
+-->
<project name="JOGLCommonStuff" basedir="." default="common.init">
<description>Common JOGL Stuff</description>
@@ -112,9 +116,14 @@
</or>
</condition>
+ <condition property="setup.addNativeDRMGBM">
+ <isset property="isLinux"/>
+ </condition>
+
<echo message="setup.noAWT: ${setup.noAWT}" />
<echo message="setup.noNativeAWT: ${setup.noNativeAWT}" />
<echo message="setup.noNativeDesktop: ${setup.noNativeDesktop}" />
+ <echo message="setup.addNativeDRMGBM: ${setup.addNativeDRMGBM}" />
<!-- Load the user specified properties file that defines various host
- specific paths. The user will be notified if this is does not
@@ -283,6 +292,7 @@
<property name="nativewindow.jar" value="${build.nativewindow}/nativewindow.jar" />
<property name="nativewindow-awt.jar" value="${build.nativewindow}/nativewindow-awt.jar" />
+ <property name="nativewindow-os-drm.jar" value="${build.nativewindow}/nativewindow-os-drm.jar" />
<property name="nativewindow-os-x11.jar" value="${build.nativewindow}/nativewindow-os-x11.jar" />
<property name="nativewindow-os-win.jar" value="${build.nativewindow}/nativewindow-os-win.jar" />
<property name="nativewindow-os-osx.jar" value="${build.nativewindow}/nativewindow-os-osx.jar" />
@@ -291,6 +301,7 @@
<path id="nativewindow_all_atoms.classpath">
<pathelement location="${nativewindow.jar}" />
<pathelement location="${nativewindow-awt.jar}" />
+ <pathelement location="${nativewindow-os-drm.jar}" />
<pathelement location="${nativewindow-os-x11.jar}" />
<pathelement location="${nativewindow-os-win.jar}" />
<pathelement location="${nativewindow-os-osx.jar}" />
@@ -298,6 +309,7 @@
</path>
<path id="nativewindow_all-noawt_atoms.classpath">
<pathelement location="${nativewindow.jar}" />
+ <pathelement location="${nativewindow-os-drm.jar}" />
<pathelement location="${nativewindow-os-x11.jar}" />
<pathelement location="${nativewindow-os-win.jar}" />
<pathelement location="${nativewindow-os-osx.jar}" />
diff --git a/make/build-nativewindow.xml b/make/build-nativewindow.xml
index f1b5cd4a9..c95c9dbef 100644
--- a/make/build-nativewindow.xml
+++ b/make/build-nativewindow.xml
@@ -72,6 +72,9 @@
<property name="java.part.awt"
value="com/jogamp/nativewindow/awt/* jogamp/nativewindow/jawt/** jogamp/nativewindow/**/awt/**"/>
+ <property name="java.part.drm"
+ value="com/jogamp/nativewindow/drm/* jogamp/nativewindow/drm/*" />
+
<property name="java.part.x11"
value="com/jogamp/nativewindow/x11/* jogamp/nativewindow/x11/*" />
@@ -275,6 +278,19 @@
<antcall target="java.generate.cleantemp" inheritRefs="true" />
+ <echo message="Generating platform-specifics: DRM" />
+ <dirset id="stub.includes.fileset.drm" dir="." includes="${stub.includes}/drm/* ${stub.includes.gluegen}/gluegen/**" />
+ <gluegen src="${stub.includes}/drm/drm-gbm-lib.c"
+ outputRootDir="${build.nativewindow}"
+ config="${config.nativewindow}/drm-gbm-lib.cfg"
+ includeRefid="stub.includes.fileset.drm"
+ literalInclude="${stub.includes.gluegen.gg}, ${stub.includes}/drm, ${src.c}/drm"
+ emitter="com.jogamp.gluegen.JavaEmitter"
+ debug="false"
+ dumpCPP="false">
+ <classpath refid="gluegen.classpath" />
+ </gluegen>
+
<echo message="Generating platform-specifics: X11" />
<antcall target="java.generate.platforms" inheritRefs="true">
<param name="window.os.system" value="x11"/>
@@ -323,6 +339,24 @@
-->
<!-- Perform the first pass: Native headers. -->
+ <target name="javah.drmgbm" if="setup.addNativeDRMGBM">
+ <javac srcdir="${src.java}:${src.generated.java}"
+ destdir="${classes}"
+ excludes="${java.excludes.all}"
+ nativeheaderdir="${src.generated.c}/drm"
+ fork="yes"
+ includeAntRuntime="false"
+ memoryMaximumSize="${javac.memorymax}"
+ encoding="UTF-8"
+ source="${target.sourcelevel}"
+ target="${target.targetlevel}"
+ bootclasspath="${target.rt.jar}"
+ debug="${javacdebug}" debuglevel="${javacdebuglevel}">
+ <classpath refid="swt_gluegen.classpath"/>
+ <include name="jogamp/nativewindow/drm/DRMLib.java" />
+ <include name="jogamp/nativewindow/drm/DRMUtil.java" />
+ </javac>
+ </target>
<target name="javah.x11" if="isX11">
<javac srcdir="${src.java}:${src.generated.java}"
destdir="${classes}"
@@ -395,7 +429,7 @@
</javac>
</target>
- <target name="java.compile.javase" depends="java.generate, javah.x11, javah.windows, javah.macos, javah.ios">
+ <target name="java.compile.javase" depends="java.generate, javah.drmgbm, javah.x11, javah.windows, javah.macos, javah.ios">
<!-- Perform the second pass Java compile; everything. -->
<javac destdir="${classes}"
excludes="${java.excludes.all}"
@@ -478,6 +512,21 @@
<syslibset dir="/usr/local/lib" libs="Xrender"/>
</linker>
+ <linker id="linker.cfg.linux.nativewindow.drm" extends="linker.cfg.linux">
+ <syslibset libs="drm"/>
+ <syslibset libs="gbm"/>
+ </linker>
+
+ <linker id="linker.cfg.linux.armv6.nativewindow.drm" extends="linker.cfg.linux.armv6">
+ <syslibset dir="${TARGET_PLATFORM_USRLIBS}" libs="drm" />
+ <syslibset dir="${TARGET_PLATFORM_USRLIBS}" libs="gbm" />
+ </linker>
+
+ <linker id="linker.cfg.linux.aarch64.nativewindow.drm" extends="linker.cfg.linux.aarch64">
+ <syslibset dir="${TARGET_PLATFORM_USRLIBS}" libs="drm" />
+ <syslibset dir="${TARGET_PLATFORM_USRLIBS}" libs="gbm" />
+ </linker>
+
<linker id="linker.cfg.linux.nativewindow.x11" extends="linker.cfg.linux">
<syslibset libs="X11"/>
<syslibset libs="Xxf86vm" />
@@ -602,66 +651,77 @@
<echo message="Linux.x86" />
<property name="compiler.cfg.id" value="compiler.cfg.linux.x86" />
<property name="linker.cfg.id.oswin" value="linker.cfg.linux.x86.nativewindow.x11" />
+ <property name="linker.cfg.id.drm" value="linker.cfg.linux.nativewindow.drm" />
</target>
<target name="c.configure.linux.amd64" if="isLinuxAMD64">
<echo message="Linux.AMD64" />
<property name="compiler.cfg.id" value="compiler.cfg.linux.amd64" />
<property name="linker.cfg.id.oswin" value="linker.cfg.linux.amd64.nativewindow.x11" />
+ <property name="linker.cfg.id.drm" value="linker.cfg.linux.nativewindow.drm" />
</target>
<target name="c.configure.linux.armv6" if="isLinuxARMv6">
<echo message="Linux.armv6" />
<property name="compiler.cfg.id" value="compiler.cfg.linux.armv6.nativewindow.x11" />
<property name="linker.cfg.id.oswin" value="linker.cfg.linux.armv6.nativewindow.x11" />
+ <property name="linker.cfg.id.drm" value="linker.cfg.linux.armv6.nativewindow.drm" />
</target>
<target name="c.configure.linux.aarch64" if="isLinuxARM64">
<echo message="Linux.aarch64" />
<property name="compiler.cfg.id" value="compiler.cfg.linux.aarch64.nativewindow.x11" />
<property name="linker.cfg.id.oswin" value="linker.cfg.linux.aarch64.nativewindow.x11" />
+ <property name="linker.cfg.id.drm" value="linker.cfg.linux.aarch64.nativewindow.drm" />
</target>
<target name="c.configure.linux.ia64" if="isLinuxIA64">
<echo message="Linux.IA64" />
<property name="compiler.cfg.id" value="compiler.cfg.linux" />
<property name="linker.cfg.id.oswin" value="linker.cfg.linux.nativewindow.x11" />
+ <property name="linker.cfg.id.drm" value="linker.cfg.linux.nativewindow.drm" />
</target>
<target name="c.configure.linux.hppa" if="isLinuxHppa">
<echo message="Linux.HPPA" />
<property name="compiler.cfg.id" value="compiler.cfg.linux" />
<property name="linker.cfg.id.oswin" value="linker.cfg.linux.nativewindow.x11" />
+ <property name="linker.cfg.id.drm" value="linker.cfg.linux.nativewindow.drm" />
</target>
<target name="c.configure.linux.mips" if="isLinuxMips">
<echo message="Linux.MIPS" />
<property name="compiler.cfg.id" value="compiler.cfg.linux" />
<property name="linker.cfg.id.oswin" value="linker.cfg.linux.nativewindow.x11" />
+ <property name="linker.cfg.id.drm" value="linker.cfg.linux.nativewindow.drm" />
</target>
<target name="c.configure.linux.mipsel" if="isLinuxMipsel">
<echo message="Linux.MIPSEL" />
<property name="compiler.cfg.id" value="compiler.cfg.linux" />
<property name="linker.cfg.id.oswin" value="linker.cfg.linux.nativewindow.x11" />
+ <property name="linker.cfg.id.drm" value="linker.cfg.linux.nativewindow.drm" />
</target>
<target name="c.configure.linux.ppc" if="isLinuxPpc">
<echo message="Linux.PPC" />
<property name="compiler.cfg.id" value="compiler.cfg.linux" />
<property name="linker.cfg.id.oswin" value="linker.cfg.linux.nativewindow.x11" />
+ <property name="linker.cfg.id.drm" value="linker.cfg.linux.nativewindow.drm" />
</target>
<target name="c.configure.linux.s390" if="isLinuxs390">
<echo message="Linux.S390" />
<property name="compiler.cfg.id" value="compiler.cfg.linux" />
<property name="linker.cfg.id.oswin" value="linker.cfg.linux.nativewindow.x11" />
+ <property name="linker.cfg.id.drm" value="linker.cfg.linux.nativewindow.drm" />
</target>
<target name="c.configure.linux.sparc" if="isLinuxSparc">
<echo message="Linux.SPARC" />
<property name="compiler.cfg.id" value="compiler.cfg.linux" />
<property name="linker.cfg.id.oswin" value="linker.cfg.linux.nativewindow.x11" />
+ <property name="linker.cfg.id.drm" value="linker.cfg.linux.nativewindow.drm" />
</target>
<target name="c.configure.linux" depends="c.configure.linux.armv6,c.configure.linux.aarch64,c.configure.linux.x86,c.configure.linux.amd64,c.configure.linux.ia64,c.configure.linux.hppa,c.configure.linux.mips,c.configure.linux.mipsel,c.configure.linux.ppc,c.configure.linux.s390,c.configure.linux.sparc,c.configure.x11" if="isLinux" />
@@ -776,6 +836,14 @@
<include name="${rootrel.generated.c}/Windows/JAWT*.c" if="isWindows"/>
</patternset>
+ <patternset id="c.src.files.drmgbm">
+ <include name="${rootrel.generated.c}/drm/DRMLib_JNI.c"/>
+ <include name="${rootrel.generated.c}/drm/drm*.c"/>
+ <include name="${rootrel.src.c}/drm/DRMmisc.c"/>
+ <include name="${rootrel.src.c}/NativewindowCommon.c"/>
+ <include name="${rootrel.src.c}/JVM_JNI8.c"/>
+ </patternset>
+
<patternset id="c.src.files.x11">
<include name="${rootrel.generated.c}/X11/X11*.c"/>
<include name="${rootrel.src.c}/x11/Xmisc.c"/>
@@ -846,6 +914,8 @@
<includepath path="${src.c}/ios" if="isIOS"/>
<includepath path="${src.c}/win32" if="isWindows"/>
<includepath path="${src.c}"/>
+ <includepath path="${src.generated.c}/drm" if="setup.addNativeDRMGBM" />
+ <includepath path="stub_includes/drm" if="setup.addNativeDRMGBM" />
<!-- This must come last to not override real include paths -->
<!-- includepath path="stub_includes/macosx" if="isOSX" / -->
@@ -888,6 +958,13 @@
linker.cfg.id="${linker.cfg.id.oswin}"/>
</target>
+ <target name="c.build.nativewindow.windowlib.drmgbm" if="setup.addNativeDRMGBM">
+ <c.build c.compiler.src.files="c.src.files.drmgbm"
+ output.lib.name="nativewindow_drm"
+ compiler.cfg.id="${compiler.cfg.id}"
+ linker.cfg.id="${linker.cfg.id.drm}"/>
+ </target>
+
<target name="c.build.nativewindow.windowlib.x11" if="isX11">
<c.build c.compiler.src.files="c.src.files.x11"
output.lib.name="nativewindow_x11"
@@ -916,7 +993,7 @@
linker.cfg.id="${linker.cfg.id.oswin}"/>
</target>
- <target name="c.build.nativewindow.windowlib" depends="c.build.nativewindow.windowlib.x11, c.build.nativewindow.windowlib.windows, c.build.nativewindow.windowlib.macosx, c.build.nativewindow.windowlib.ios"/>
+ <target name="c.build.nativewindow.windowlib" depends="c.build.nativewindow.windowlib.drmgbm, c.build.nativewindow.windowlib.x11, c.build.nativewindow.windowlib.windows, c.build.nativewindow.windowlib.macosx, c.build.nativewindow.windowlib.ios"/>
<target name="c.manifest" if="isVC8Family">
<!-- exec mt, the Microsoft Manifest Tool, to include DLL manifests in order to resolve the location of msvcr80.dll -->
@@ -970,6 +1047,13 @@
</jar>
</target>
+ <target name="build-jars-drm" depends="setup-manifestfile">
+ <jar manifest="${build.nativewindow}/manifest.mf" destfile="${nativewindow-os-drm.jar}" filesonly="true">
+ <fileset dir="${classes}"
+ includes="${java.part.drm}" />
+ </jar>
+ </target>
+
<target name="build-jars-x11" depends="setup-manifestfile">
<jar manifest="${build.nativewindow}/manifest.mf" destfile="${nativewindow-os-x11.jar}" filesonly="true">
<fileset dir="${classes}"
@@ -998,11 +1082,11 @@
</jar>
</target>
- <target name="build-jars-javase" depends="setup-manifestfile,build-jars-awt,build-jars-x11,build-jars-windows,build-jars-macosx,build-jars-ios">
+ <target name="build-jars-javase" depends="setup-manifestfile,build-jars-awt,build-jars-drm,build-jars-x11,build-jars-windows,build-jars-macosx,build-jars-ios">
<jar manifest="${build.nativewindow}/manifest.mf" destfile="${nativewindow.jar}" filesonly="true">
<fileset dir="${classes}"
includes="${java.part.core}"
- excludes="${java.part.awt} ${java.part.x11} ${java.part.windows}"/>
+ excludes="${java.part.awt} ${java.part.drm} ${java.part.x11} ${java.part.windows}"/>
</jar>
<native.tag.jar objdir="${obj.nativewindow}"
nativejarfile="${build.nativewindow}/nativewindow-natives-${os.and.arch}.jar"
diff --git a/make/build-newt.xml b/make/build-newt.xml
index 541077b9d..626f388b4 100644
--- a/make/build-newt.xml
+++ b/make/build-newt.xml
@@ -49,7 +49,6 @@
setup.addNativeKD
setup.addNativeIntelGDL
setup.addNativeBroadcom ( always true if 'isLinux' )
- setup.addNativeEGLGBM ( always true if 'isLinux' )
- Internal settings, may not be necessary to set them manually,
since all JAR archives are orthogonal.
@@ -76,10 +75,6 @@
<isset property="isLinux"/>
</condition>
- <condition property="setup.addNativeEGLGBM">
- <isset property="isLinux"/>
- </condition>
-
<condition property="setup.nonatives">
<and>
<isfalse value="${isWindows}" />
@@ -90,7 +85,7 @@
<isfalse value="${setup.addNativeKD}" />
<isfalse value="${setup.addNativeIntelGDL}" />
<isfalse value="${setup.addNativeBroadcom}" />
- <isfalse value="${setup.addNativeEGLGBM}" />
+ <isfalse value="${setup.addNativeDRMGBM}" />
</and>
</condition>
@@ -103,7 +98,6 @@
<echo message="setup.addNativeKD: ${setup.addNativeKD}" />
<echo message="setup.addNativeIntelGDL: ${setup.addNativeIntelGDL}" />
<echo message="setup.addNativeBroadcom: ${setup.addNativeBroadcom}" />
- <echo message="setup.addNativeEGLGBM: ${setup.addNativeEGLGBM}" />
<echo message="setup.nonatives: ${setup.nonatives}" />
<!-- partitioning -->
@@ -525,13 +519,6 @@
<!-- syslibset libs="EGL"/ -->
</linker>
- <linker id="linker.cfg.linux.newt.egl_gbm" extends="linker.cfg.linux">
- <syslibset libs="drm"/>
- <syslibset libs="gbm"/>
- <syslibset libs="EGL"/>
- <syslibset libs="GLESv2"/>
- </linker>
-
<linker id="linker.cfg.linux.newt.x11" extends="linker.cfg.linux">
<syslibset libs="X11"/>
<syslibset libs="Xrandr"/>
@@ -539,6 +526,8 @@
<syslibset libs="Xi"/>
<!--syslibset libs="xcb" /-->
<!--syslibset libs="X11-xcb" /-->
+ <syslibset libs="drm"/>
+ <syslibset libs="gbm"/>
</linker>
<linker id="linker.cfg.linux.x86.newt.x11" extends="linker.cfg.linux.x86">
@@ -548,6 +537,8 @@
<syslibset libs="Xi"/>
<!--syslibset libs="xcb" /-->
<!--syslibset libs="X11-xcb" /-->
+ <syslibset libs="drm"/>
+ <syslibset libs="gbm"/>
</linker>
<linker id="linker.cfg.linux.amd64.newt.x11" extends="linker.cfg.linux.amd64">
@@ -557,12 +548,8 @@
<syslibset libs="Xi"/>
<!--syslibset libs="xcb" /-->
<!--syslibset libs="X11-xcb" /-->
- <syslibset libs="gbm"/>
- <!--
<syslibset libs="drm"/>
<syslibset libs="gbm"/>
- <syslibset libs="EGL"/>
- <syslibset libs="GLESv2"/> -->
</linker>
<linker id="linker.cfg.linux.armv6.newt.x11" extends="linker.cfg.linux.armv6">
@@ -570,6 +557,8 @@
<syslibset dir="${TARGET_PLATFORM_USRLIBS}" libs="Xrandr" />
<syslibset dir="${TARGET_PLATFORM_USRLIBS}" libs="Xcursor" />
<syslibset dir="${TARGET_PLATFORM_USRLIBS}" libs="Xi" />
+ <syslibset dir="${TARGET_PLATFORM_USRLIBS}" libs="drm" />
+ <syslibset dir="${TARGET_PLATFORM_USRLIBS}" libs="gbm" />
</linker>
<linker id="linker.cfg.linux.aarch64.newt.x11" extends="linker.cfg.linux.aarch64">
@@ -577,6 +566,8 @@
<syslibset dir="${TARGET_PLATFORM_USRLIBS}" libs="Xrandr" />
<syslibset dir="${TARGET_PLATFORM_USRLIBS}" libs="Xcursor" />
<syslibset dir="${TARGET_PLATFORM_USRLIBS}" libs="Xi" />
+ <syslibset dir="${TARGET_PLATFORM_USRLIBS}" libs="drm" />
+ <syslibset dir="${TARGET_PLATFORM_USRLIBS}" libs="gbm" />
</linker>
<linker id="linker.cfg.android.newt" extends="linker.cfg.android">
@@ -901,8 +892,8 @@
<include name="${rootrel.src.c}/IntelGDL.c" if="setup.addNativeIntelGDL"/>
<include name="${rootrel.src.c}/bcm_egl.c" if="setup.addNativeBroadcom"/>
<include name="${rootrel.src.c}/bcm_vc_iv.c" if="setup.addNativeBroadcom"/>
- <include name="${rootrel.src.c}/egl_gbm.c" if="setup.addNativeEGLGBM"/>
- <include name="${rootrel.src.c}/egl_gbm_drmflip.c" if="setup.addNativeEGLGBM"/>
+ <include name="${rootrel.src.c}/drm_gbm.c" if="setup.addNativeDRMGBM"/>
+ <include name="${rootrel.src.c}/drm_gbm_legacy.c" if="setup.addNativeDRMGBM"/>
</patternset>
<echo message="Compiling @{output.lib.name}" />
@@ -951,8 +942,8 @@
<includepath path="stub_includes/embedded/IntelGDL" if="setup.addNativeIntelGDL" />
<includepath path="${src.generated.c}/bcm/egl" if="setup.addNativeBroadcom" />
<includepath path="${src.generated.c}/bcm/vc/iv" if="setup.addNativeBroadcom" />
- <includepath path="${src.generated.c}/egl/gbm" if="setup.addNativeEGLGBM" />
- <includepath path="/usr/include/libdrm" if="setup.addNativeEGLGBM" />
+ <includepath path="${src.generated.c}/egl/gbm" if="setup.addNativeDRMGBM" />
+ <includepath path="stub_includes/drm" if="setup.addNativeDRMGBM" />
<!-- This must come last to not override real include paths -->
<!-- includepath path="stub_includes/macosx" if="isOSX" / -->
</compiler>
diff --git a/make/config/nativewindow/drm-gbm-lib.cfg b/make/config/nativewindow/drm-gbm-lib.cfg
new file mode 100644
index 000000000..ad1311ce1
--- /dev/null
+++ b/make/config/nativewindow/drm-gbm-lib.cfg
@@ -0,0 +1,106 @@
+# This .cfg file is used to generate the interface to the GLX routines
+# used internally by the X11GLContext implementation.
+Package jogamp.nativewindow.drm
+JavaClass DRMLib
+Style AllStatic
+
+HierarchicalNativeOutput false
+
+JavaOutputDir gensrc/classes
+NativeOutputDir gensrc/native/drm
+
+# Imports needed by all glue code
+Import java.nio.*
+Import java.util.*
+
+# XID needs to be treated as a long for 32/64 bit compatibility
+Opaque boolean Bool
+Opaque long void *
+Opaque long gbm_device*;
+Opaque long gbm_bo*;
+Opaque long gbm_surface*;
+Opaque long union gbm_bo_handle;
+
+# IncludeAs CustomJavaCode X11Lib x11-CustomJavaCode.java
+
+ArgumentIsString drmOpen 0 1
+ArgumentIsString drmCheckModesettingSupported 0
+# ReturnsString XDisplayString
+# ReturnValueCapacity XRenderFindVisualFormat sizeof(XRenderPictFormat)
+
+ReturnedArrayLength drmModeRes.connectors getCount_connectors()
+ReturnedArrayLength drmModeRes.crtcs getCount_crtcs()
+ReturnedArrayLength drmModeRes.encoders getCount_encoders()
+ReturnedArrayLength drmModeConnector.modes getCount_modes()
+ReturnedArrayLength drmModeConnector.props getCount_props()
+ReturnedArrayLength drmModeConnector.prop_values getCount_props()
+ReturnedArrayLength drmModeConnector.encoders getCount_encoders()
+ReturnsString drmModeModeInfo.name
+
+IgnoreNot ^(drm|DRM_|gbm_|GBM_).+
+
+Ignore drmHandleEvent
+
+Ignore drmModeAtomicReq
+Ignore drmModeAtomicAlloc
+Ignore drmModeAtomicDuplicate
+Ignore drmModeAtomicMerge
+Ignore drmModeAtomicFree
+Ignore drmModeAtomicGetCursor
+Ignore drmModeAtomicSetCursor
+Ignore drmModeAtomicAddProperty
+Ignore drmModeAtomicCommit
+
+Ignore drmModeClip
+Ignore drmModeDirtyFB
+
+Ignore drmModeLesseeListRes
+Ignore drmModeListLessees
+Ignore drmModeGetLease
+Ignore drmModeObjectListRes
+
+Ignore drmModeObjectProperties
+Ignore drmModeObjectGetProperties
+Ignore drmModeFreeObjectProperties
+
+Ignore drmModePropertyBlobRes
+Ignore drmModeGetPropertyBlob
+Ignore drmModeFreePropertyBlob
+
+Ignore drmModePropertyRes
+Ignore drmModeGetProperty
+Ignore drmModeFreeProperty
+
+Ignore drmModePlane
+Ignore drmModeGetPlane
+Ignore drmModeFreePlane
+Ignore drmModePlaneRes
+Ignore drmModeGetPlaneResources
+Ignore drmModeFreePlaneResources
+
+Ignore GBM_BO_FORMAT.+
+Ignore gbm_bo_handle
+Ignore gbm_bo_get_handle
+Ignore gbm_bo_get_handle_for_plane
+Ignore gbm_bo_set_user_data
+
+ManuallyImplement drmOpenFile
+
+CustomJavaCode DRMLib public static final int DRM_MODE_TYPE_BUILTIN = (1<<0);
+# CustomJavaCode DRMLib public static final int DRM_MODE_TYPE_CLOCK_C = ((1<<1) | DRM_MODE_TYPE_BUILTIN);
+# CustomJavaCode DRMLib public static final int DRM_MODE_TYPE_CRTC_C = ((1<<2) | DRM_MODE_TYPE_BUILTIN);
+CustomJavaCode DRMLib public static final int DRM_MODE_TYPE_PREFERRED = (1<<3);
+# CustomJavaCode DRMLib public static final int DRM_MODE_TYPE_DEFAULT = (1<<4);
+# CustomJavaCode DRMLib public static final int DRM_MODE_TYPE_USERDEF = (1<<5);
+CustomJavaCode DRMLib public static final int DRM_MODE_TYPE_DRIVER = (1<<6);
+CustomJavaCode DRMLib public static native int drmOpenFile(String filename);
+
+CustomCCode #include <stdlib.h>
+CustomCCode #include <errno.h>
+CustomCCode #include <string.h>
+CustomCCode #include <fcntl.h>
+CustomCCode #include <inttypes.h>
+CustomCCode #include <xf86drm.h>
+CustomCCode #include <xf86drmMode.h>
+CustomCCode #include <gbm.h>
+
diff --git a/make/scripts/gluegen-gl.sh b/make/scripts/gluegen-gl.sh
index 6b978c16a..b94658523 100644..100755
--- a/make/scripts/gluegen-gl.sh
+++ b/make/scripts/gluegen-gl.sh
@@ -1,4 +1,4 @@
-#! /bin/bash
+#!/bin/bash
rootrel=build-x86_64
#rootrel=build-x86_64-clang
@@ -11,6 +11,23 @@ function copy_temp() {
cp -a $builddir/jogl/gensrc/classes/* $buildtmp/gensrc/classes/
}
+function gluegen_drmgbm() {
+rm -f ../$rootrel/nativewindow/gensrc/classes/jogamp/nativewindow/drm/*
+rm -f ../$rootrel/nativewindow/gensrc/native/drm/*
+java \
+-classpath \
+../../gluegen/$rootrel/gluegen.jar:../$rootrel/jogl/gluegen-gl.jar \
+com.jogamp.gluegen.GlueGen \
+--debug \
+-O../$rootrel/nativewindow \
+-Ecom.jogamp.gluegen.JavaEmitter \
+-C./config/nativewindow/drm-gbm-lib.cfg \
+-Istub_includes/drm \
+-I../../gluegen/make/stub_includes/gluegen \
+-Istub_includes/jni \
+stub_includes/drm/drm-gbm-lib.c
+}
+
function gluegen_jawt_x11() {
java \
-classpath \
@@ -881,11 +898,13 @@ copy_temp
function gluegen_all() {
# bash scripts/make.jogl.all.linux-x86_64.sh -f build-jogl.xml build.gluegen-gl.jar
+ gluegen_drmgbm
+#
# gluegen_jawt_x11
#
# gluegen_if_gl
# gluegen_gl2es1
- gluegen_es1
+# gluegen_es1
# gluegen_gl2es2
# gluegen_es2
# gluegen_gl2es3
diff --git a/make/scripts/tests.sh b/make/scripts/tests.sh
index ddfa6c113..92b3670bf 100644
--- a/make/scripts/tests.sh
+++ b/make/scripts/tests.sh
@@ -119,9 +119,9 @@ function jrun() {
#D_ARGS="-Dnewt.debug=all"
#D_ARGS="-Djogl.debug=all -Dnewt.debug=all"
#D_ARGS="-Djogl.debug=all -Dnativewindow.debug=all"
- #D_ARGS="-Djogamp.debug=all -Dnativewindow.debug=all -Djogl.debug=all -Dnewt.debug=all"
- #D_ARGS="-Djogamp.debug=all -Dnativewindow.debug=all -Djogl.debug=all -Dnewt.debug=all -Djogl.disable.opengldesktop"
- D_ARGS="-Dnativewindow.debug=all -Djogl.debug=all -Dnewt.debug=all -Djogl.disable.opengldesktop"
+ #D_ARGS="-Dnativewindow.debug=all -Djogl.debug=all -Dnewt.debug=all"
+ #D_ARGS="-Dnativewindow.debug=all -Djogl.debug=all -Dnewt.debug=all -Djogl.disable.opengldesktop"
+ #D_ARGS="-Dnativewindow.debug=all -Djogl.debug=all -Dnewt.debug=all -Djogl.disable.opengldesktop -Djogl.quirks.force=NoSurfacelessCtx"
#D_ARGS="-Dnativewindow.debug.JAWT -Djogamp.debug.UnsafeUtil"
#D_ARGS="-Dnativewindow.debug.OSXUtil -Dnativewindow.debug.JAWT -Djogl.debug.GLContext"
diff --git a/make/stub_includes/drm/drm-gbm-lib.c b/make/stub_includes/drm/drm-gbm-lib.c
new file mode 100644
index 000000000..5c8836a0a
--- /dev/null
+++ b/make/stub_includes/drm/drm-gbm-lib.c
@@ -0,0 +1,37 @@
+/**
+ * Copyright 2019 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+// #include <xf86drm.h>
+extern int drmAvailable(void);
+extern int drmOpenFile(const char *filename);
+extern int drmOpen(const char *drivername, const char *busid);
+extern int drmClose(int fd);
+
+#include <xf86drmMode.h>
+#include <gbm.h>
+
diff --git a/make/stub_includes/drm/drm.h b/make/stub_includes/drm/drm.h
new file mode 100644
index 000000000..5e1cd0e88
--- /dev/null
+++ b/make/stub_includes/drm/drm.h
@@ -0,0 +1,1005 @@
+/**
+ * \file drm.h
+ * Header for the Direct Rendering Manager
+ *
+ * \author Rickard E. (Rik) Faith <[email protected]>
+ *
+ * \par Acknowledgments:
+ * Dec 1999, Richard Henderson <[email protected]>, move to generic \c cmpxchg.
+ */
+
+/*
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef _DRM_H_
+#define _DRM_H_
+
+#if defined(__linux__)
+
+#include <linux/types.h>
+#include <asm/ioctl.h>
+typedef unsigned int drm_handle_t;
+
+#else /* One of the BSDs */
+
+#include <stdint.h>
+#include <sys/ioccom.h>
+#include <sys/types.h>
+typedef int8_t __s8;
+typedef uint8_t __u8;
+typedef int16_t __s16;
+typedef uint16_t __u16;
+typedef int32_t __s32;
+typedef uint32_t __u32;
+typedef int64_t __s64;
+typedef uint64_t __u64;
+typedef size_t __kernel_size_t;
+typedef unsigned long drm_handle_t;
+
+#endif
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#define DRM_NAME "drm" /**< Name in kernel, /dev, and /proc */
+#define DRM_MIN_ORDER 5 /**< At least 2^5 bytes = 32 bytes */
+#define DRM_MAX_ORDER 22 /**< Up to 2^22 bytes = 4MB */
+#define DRM_RAM_PERCENT 10 /**< How much system ram can we lock? */
+
+#define _DRM_LOCK_HELD 0x80000000U /**< Hardware lock is held */
+#define _DRM_LOCK_CONT 0x40000000U /**< Hardware lock is contended */
+#define _DRM_LOCK_IS_HELD(lock) ((lock) & _DRM_LOCK_HELD)
+#define _DRM_LOCK_IS_CONT(lock) ((lock) & _DRM_LOCK_CONT)
+#define _DRM_LOCKING_CONTEXT(lock) ((lock) & ~(_DRM_LOCK_HELD|_DRM_LOCK_CONT))
+
+typedef unsigned int drm_context_t;
+typedef unsigned int drm_drawable_t;
+typedef unsigned int drm_magic_t;
+
+/**
+ * Cliprect.
+ *
+ * \warning: If you change this structure, make sure you change
+ * XF86DRIClipRectRec in the server as well
+ *
+ * \note KW: Actually it's illegal to change either for
+ * backwards-compatibility reasons.
+ */
+struct drm_clip_rect {
+ unsigned short x1;
+ unsigned short y1;
+ unsigned short x2;
+ unsigned short y2;
+};
+
+/**
+ * Drawable information.
+ */
+struct drm_drawable_info {
+ unsigned int num_rects;
+ struct drm_clip_rect *rects;
+};
+
+/**
+ * Texture region,
+ */
+struct drm_tex_region {
+ unsigned char next;
+ unsigned char prev;
+ unsigned char in_use;
+ unsigned char padding;
+ unsigned int age;
+};
+
+/**
+ * Hardware lock.
+ *
+ * The lock structure is a simple cache-line aligned integer. To avoid
+ * processor bus contention on a multiprocessor system, there should not be any
+ * other data stored in the same cache line.
+ */
+struct drm_hw_lock {
+ __volatile__ unsigned int lock; /**< lock variable */
+ char padding[60]; /**< Pad to cache line */
+};
+
+/**
+ * DRM_IOCTL_VERSION ioctl argument type.
+ *
+ * \sa drmGetVersion().
+ */
+struct drm_version {
+ int version_major; /**< Major version */
+ int version_minor; /**< Minor version */
+ int version_patchlevel; /**< Patch level */
+ __kernel_size_t name_len; /**< Length of name buffer */
+ char *name; /**< Name of driver */
+ __kernel_size_t date_len; /**< Length of date buffer */
+ char *date; /**< User-space buffer to hold date */
+ __kernel_size_t desc_len; /**< Length of desc buffer */
+ char *desc; /**< User-space buffer to hold desc */
+};
+
+/**
+ * DRM_IOCTL_GET_UNIQUE ioctl argument type.
+ *
+ * \sa drmGetBusid() and drmSetBusId().
+ */
+struct drm_unique {
+ __kernel_size_t unique_len; /**< Length of unique */
+ char *unique; /**< Unique name for driver instantiation */
+};
+
+struct drm_list {
+ int count; /**< Length of user-space structures */
+ struct drm_version *version;
+};
+
+struct drm_block {
+ int unused;
+};
+
+/**
+ * DRM_IOCTL_CONTROL ioctl argument type.
+ *
+ * \sa drmCtlInstHandler() and drmCtlUninstHandler().
+ */
+struct drm_control {
+ enum {
+ DRM_ADD_COMMAND,
+ DRM_RM_COMMAND,
+ DRM_INST_HANDLER,
+ DRM_UNINST_HANDLER
+ } func;
+ int irq;
+};
+
+/**
+ * Type of memory to map.
+ */
+enum drm_map_type {
+ _DRM_FRAME_BUFFER = 0, /**< WC (no caching), no core dump */
+ _DRM_REGISTERS = 1, /**< no caching, no core dump */
+ _DRM_SHM = 2, /**< shared, cached */
+ _DRM_AGP = 3, /**< AGP/GART */
+ _DRM_SCATTER_GATHER = 4, /**< Scatter/gather memory for PCI DMA */
+ _DRM_CONSISTENT = 5 /**< Consistent memory for PCI DMA */
+};
+
+/**
+ * Memory mapping flags.
+ */
+enum drm_map_flags {
+ _DRM_RESTRICTED = 0x01, /**< Cannot be mapped to user-virtual */
+ _DRM_READ_ONLY = 0x02,
+ _DRM_LOCKED = 0x04, /**< shared, cached, locked */
+ _DRM_KERNEL = 0x08, /**< kernel requires access */
+ _DRM_WRITE_COMBINING = 0x10, /**< use write-combining if available */
+ _DRM_CONTAINS_LOCK = 0x20, /**< SHM page that contains lock */
+ _DRM_REMOVABLE = 0x40, /**< Removable mapping */
+ _DRM_DRIVER = 0x80 /**< Managed by driver */
+};
+
+struct drm_ctx_priv_map {
+ unsigned int ctx_id; /**< Context requesting private mapping */
+ void *handle; /**< Handle of map */
+};
+
+/**
+ * DRM_IOCTL_GET_MAP, DRM_IOCTL_ADD_MAP and DRM_IOCTL_RM_MAP ioctls
+ * argument type.
+ *
+ * \sa drmAddMap().
+ */
+struct drm_map {
+ unsigned long offset; /**< Requested physical address (0 for SAREA)*/
+ unsigned long size; /**< Requested physical size (bytes) */
+ enum drm_map_type type; /**< Type of memory to map */
+ enum drm_map_flags flags; /**< Flags */
+ void *handle; /**< User-space: "Handle" to pass to mmap() */
+ /**< Kernel-space: kernel-virtual address */
+ int mtrr; /**< MTRR slot used */
+ /* Private data */
+};
+
+/**
+ * DRM_IOCTL_GET_CLIENT ioctl argument type.
+ */
+struct drm_client {
+ int idx; /**< Which client desired? */
+ int auth; /**< Is client authenticated? */
+ unsigned long pid; /**< Process ID */
+ unsigned long uid; /**< User ID */
+ unsigned long magic; /**< Magic */
+ unsigned long iocs; /**< Ioctl count */
+};
+
+enum drm_stat_type {
+ _DRM_STAT_LOCK,
+ _DRM_STAT_OPENS,
+ _DRM_STAT_CLOSES,
+ _DRM_STAT_IOCTLS,
+ _DRM_STAT_LOCKS,
+ _DRM_STAT_UNLOCKS,
+ _DRM_STAT_VALUE, /**< Generic value */
+ _DRM_STAT_BYTE, /**< Generic byte counter (1024bytes/K) */
+ _DRM_STAT_COUNT, /**< Generic non-byte counter (1000/k) */
+
+ _DRM_STAT_IRQ, /**< IRQ */
+ _DRM_STAT_PRIMARY, /**< Primary DMA bytes */
+ _DRM_STAT_SECONDARY, /**< Secondary DMA bytes */
+ _DRM_STAT_DMA, /**< DMA */
+ _DRM_STAT_SPECIAL, /**< Special DMA (e.g., priority or polled) */
+ _DRM_STAT_MISSED /**< Missed DMA opportunity */
+ /* Add to the *END* of the list */
+};
+
+/**
+ * DRM_IOCTL_GET_STATS ioctl argument type.
+ */
+struct drm_stats {
+ unsigned long count;
+ struct {
+ unsigned long value;
+ enum drm_stat_type type;
+ } data[15];
+};
+
+/**
+ * Hardware locking flags.
+ */
+enum drm_lock_flags {
+ _DRM_LOCK_READY = 0x01, /**< Wait until hardware is ready for DMA */
+ _DRM_LOCK_QUIESCENT = 0x02, /**< Wait until hardware quiescent */
+ _DRM_LOCK_FLUSH = 0x04, /**< Flush this context's DMA queue first */
+ _DRM_LOCK_FLUSH_ALL = 0x08, /**< Flush all DMA queues first */
+ /* These *HALT* flags aren't supported yet
+ -- they will be used to support the
+ full-screen DGA-like mode. */
+ _DRM_HALT_ALL_QUEUES = 0x10, /**< Halt all current and future queues */
+ _DRM_HALT_CUR_QUEUES = 0x20 /**< Halt all current queues */
+};
+
+/**
+ * DRM_IOCTL_LOCK, DRM_IOCTL_UNLOCK and DRM_IOCTL_FINISH ioctl argument type.
+ *
+ * \sa drmGetLock() and drmUnlock().
+ */
+struct drm_lock {
+ int context;
+ enum drm_lock_flags flags;
+};
+
+/**
+ * DMA flags
+ *
+ * \warning
+ * These values \e must match xf86drm.h.
+ *
+ * \sa drm_dma.
+ */
+enum drm_dma_flags {
+ /* Flags for DMA buffer dispatch */
+ _DRM_DMA_BLOCK = 0x01, /**<
+ * Block until buffer dispatched.
+ *
+ * \note The buffer may not yet have
+ * been processed by the hardware --
+ * getting a hardware lock with the
+ * hardware quiescent will ensure
+ * that the buffer has been
+ * processed.
+ */
+ _DRM_DMA_WHILE_LOCKED = 0x02, /**< Dispatch while lock held */
+ _DRM_DMA_PRIORITY = 0x04, /**< High priority dispatch */
+
+ /* Flags for DMA buffer request */
+ _DRM_DMA_WAIT = 0x10, /**< Wait for free buffers */
+ _DRM_DMA_SMALLER_OK = 0x20, /**< Smaller-than-requested buffers OK */
+ _DRM_DMA_LARGER_OK = 0x40 /**< Larger-than-requested buffers OK */
+};
+
+/**
+ * DRM_IOCTL_ADD_BUFS and DRM_IOCTL_MARK_BUFS ioctl argument type.
+ *
+ * \sa drmAddBufs().
+ */
+struct drm_buf_desc {
+ int count; /**< Number of buffers of this size */
+ int size; /**< Size in bytes */
+ int low_mark; /**< Low water mark */
+ int high_mark; /**< High water mark */
+ enum {
+ _DRM_PAGE_ALIGN = 0x01, /**< Align on page boundaries for DMA */
+ _DRM_AGP_BUFFER = 0x02, /**< Buffer is in AGP space */
+ _DRM_SG_BUFFER = 0x04, /**< Scatter/gather memory buffer */
+ _DRM_FB_BUFFER = 0x08, /**< Buffer is in frame buffer */
+ _DRM_PCI_BUFFER_RO = 0x10 /**< Map PCI DMA buffer read-only */
+ } flags;
+ unsigned long agp_start; /**<
+ * Start address of where the AGP buffers are
+ * in the AGP aperture
+ */
+};
+
+/**
+ * DRM_IOCTL_INFO_BUFS ioctl argument type.
+ */
+struct drm_buf_info {
+ int count; /**< Entries in list */
+ struct drm_buf_desc *list;
+};
+
+/**
+ * DRM_IOCTL_FREE_BUFS ioctl argument type.
+ */
+struct drm_buf_free {
+ int count;
+ int *list;
+};
+
+/**
+ * Buffer information
+ *
+ * \sa drm_buf_map.
+ */
+struct drm_buf_pub {
+ int idx; /**< Index into the master buffer list */
+ int total; /**< Buffer size */
+ int used; /**< Amount of buffer in use (for DMA) */
+ void *address; /**< Address of buffer */
+};
+
+/**
+ * DRM_IOCTL_MAP_BUFS ioctl argument type.
+ */
+struct drm_buf_map {
+ int count; /**< Length of the buffer list */
+#ifdef __cplusplus
+ void *virt;
+#else
+ void *virtual; /**< Mmap'd area in user-virtual */
+#endif
+ struct drm_buf_pub *list; /**< Buffer information */
+};
+
+/**
+ * DRM_IOCTL_DMA ioctl argument type.
+ *
+ * Indices here refer to the offset into the buffer list in drm_buf_get.
+ *
+ * \sa drmDMA().
+ */
+struct drm_dma {
+ int context; /**< Context handle */
+ int send_count; /**< Number of buffers to send */
+ int *send_indices; /**< List of handles to buffers */
+ int *send_sizes; /**< Lengths of data to send */
+ enum drm_dma_flags flags; /**< Flags */
+ int request_count; /**< Number of buffers requested */
+ int request_size; /**< Desired size for buffers */
+ int *request_indices; /**< Buffer information */
+ int *request_sizes;
+ int granted_count; /**< Number of buffers granted */
+};
+
+enum drm_ctx_flags {
+ _DRM_CONTEXT_PRESERVED = 0x01,
+ _DRM_CONTEXT_2DONLY = 0x02
+};
+
+/**
+ * DRM_IOCTL_ADD_CTX ioctl argument type.
+ *
+ * \sa drmCreateContext() and drmDestroyContext().
+ */
+struct drm_ctx {
+ drm_context_t handle;
+ enum drm_ctx_flags flags;
+};
+
+/**
+ * DRM_IOCTL_RES_CTX ioctl argument type.
+ */
+struct drm_ctx_res {
+ int count;
+ struct drm_ctx *contexts;
+};
+
+/**
+ * DRM_IOCTL_ADD_DRAW and DRM_IOCTL_RM_DRAW ioctl argument type.
+ */
+struct drm_draw {
+ drm_drawable_t handle;
+};
+
+/**
+ * DRM_IOCTL_UPDATE_DRAW ioctl argument type.
+ */
+typedef enum {
+ DRM_DRAWABLE_CLIPRECTS
+} drm_drawable_info_type_t;
+
+struct drm_update_draw {
+ drm_drawable_t handle;
+ unsigned int type;
+ unsigned int num;
+ unsigned long long data;
+};
+
+/**
+ * DRM_IOCTL_GET_MAGIC and DRM_IOCTL_AUTH_MAGIC ioctl argument type.
+ */
+struct drm_auth {
+ drm_magic_t magic;
+};
+
+/**
+ * DRM_IOCTL_IRQ_BUSID ioctl argument type.
+ *
+ * \sa drmGetInterruptFromBusID().
+ */
+struct drm_irq_busid {
+ int irq; /**< IRQ number */
+ int busnum; /**< bus number */
+ int devnum; /**< device number */
+ int funcnum; /**< function number */
+};
+
+enum drm_vblank_seq_type {
+ _DRM_VBLANK_ABSOLUTE = 0x0, /**< Wait for specific vblank sequence number */
+ _DRM_VBLANK_RELATIVE = 0x1, /**< Wait for given number of vblanks */
+ /* bits 1-6 are reserved for high crtcs */
+ _DRM_VBLANK_HIGH_CRTC_MASK = 0x0000003e,
+ _DRM_VBLANK_EVENT = 0x4000000, /**< Send event instead of blocking */
+ _DRM_VBLANK_FLIP = 0x8000000, /**< Scheduled buffer swap should flip */
+ _DRM_VBLANK_NEXTONMISS = 0x10000000, /**< If missed, wait for next vblank */
+ _DRM_VBLANK_SECONDARY = 0x20000000, /**< Secondary display controller */
+ _DRM_VBLANK_SIGNAL = 0x40000000 /**< Send signal instead of blocking, unsupported */
+};
+#define _DRM_VBLANK_HIGH_CRTC_SHIFT 1
+
+#define _DRM_VBLANK_TYPES_MASK (_DRM_VBLANK_ABSOLUTE | _DRM_VBLANK_RELATIVE)
+#define _DRM_VBLANK_FLAGS_MASK (_DRM_VBLANK_EVENT | _DRM_VBLANK_SIGNAL | \
+ _DRM_VBLANK_SECONDARY | _DRM_VBLANK_NEXTONMISS)
+
+struct drm_wait_vblank_request {
+ enum drm_vblank_seq_type type;
+ unsigned int sequence;
+ unsigned long signal;
+};
+
+struct drm_wait_vblank_reply {
+ enum drm_vblank_seq_type type;
+ unsigned int sequence;
+ long tval_sec;
+ long tval_usec;
+};
+
+/**
+ * DRM_IOCTL_WAIT_VBLANK ioctl argument type.
+ *
+ * \sa drmWaitVBlank().
+ */
+union drm_wait_vblank {
+ struct drm_wait_vblank_request request;
+ struct drm_wait_vblank_reply reply;
+};
+
+#define _DRM_PRE_MODESET 1
+#define _DRM_POST_MODESET 2
+
+/**
+ * DRM_IOCTL_MODESET_CTL ioctl argument type
+ *
+ * \sa drmModesetCtl().
+ */
+struct drm_modeset_ctl {
+ __u32 crtc;
+ __u32 cmd;
+};
+
+/**
+ * DRM_IOCTL_AGP_ENABLE ioctl argument type.
+ *
+ * \sa drmAgpEnable().
+ */
+struct drm_agp_mode {
+ unsigned long mode; /**< AGP mode */
+};
+
+/**
+ * DRM_IOCTL_AGP_ALLOC and DRM_IOCTL_AGP_FREE ioctls argument type.
+ *
+ * \sa drmAgpAlloc() and drmAgpFree().
+ */
+struct drm_agp_buffer {
+ unsigned long size; /**< In bytes -- will round to page boundary */
+ unsigned long handle; /**< Used for binding / unbinding */
+ unsigned long type; /**< Type of memory to allocate */
+ unsigned long physical; /**< Physical used by i810 */
+};
+
+/**
+ * DRM_IOCTL_AGP_BIND and DRM_IOCTL_AGP_UNBIND ioctls argument type.
+ *
+ * \sa drmAgpBind() and drmAgpUnbind().
+ */
+struct drm_agp_binding {
+ unsigned long handle; /**< From drm_agp_buffer */
+ unsigned long offset; /**< In bytes -- will round to page boundary */
+};
+
+/**
+ * DRM_IOCTL_AGP_INFO ioctl argument type.
+ *
+ * \sa drmAgpVersionMajor(), drmAgpVersionMinor(), drmAgpGetMode(),
+ * drmAgpBase(), drmAgpSize(), drmAgpMemoryUsed(), drmAgpMemoryAvail(),
+ * drmAgpVendorId() and drmAgpDeviceId().
+ */
+struct drm_agp_info {
+ int agp_version_major;
+ int agp_version_minor;
+ unsigned long mode;
+ unsigned long aperture_base; /* physical address */
+ unsigned long aperture_size; /* bytes */
+ unsigned long memory_allowed; /* bytes */
+ unsigned long memory_used;
+
+ /* PCI information */
+ unsigned short id_vendor;
+ unsigned short id_device;
+};
+
+/**
+ * DRM_IOCTL_SG_ALLOC ioctl argument type.
+ */
+struct drm_scatter_gather {
+ unsigned long size; /**< In bytes -- will round to page boundary */
+ unsigned long handle; /**< Used for mapping / unmapping */
+};
+
+/**
+ * DRM_IOCTL_SET_VERSION ioctl argument type.
+ */
+struct drm_set_version {
+ int drm_di_major;
+ int drm_di_minor;
+ int drm_dd_major;
+ int drm_dd_minor;
+};
+
+/** DRM_IOCTL_GEM_CLOSE ioctl argument type */
+struct drm_gem_close {
+ /** Handle of the object to be closed. */
+ __u32 handle;
+ __u32 pad;
+};
+
+/** DRM_IOCTL_GEM_FLINK ioctl argument type */
+struct drm_gem_flink {
+ /** Handle for the object being named */
+ __u32 handle;
+
+ /** Returned global name */
+ __u32 name;
+};
+
+/** DRM_IOCTL_GEM_OPEN ioctl argument type */
+struct drm_gem_open {
+ /** Name of object being opened */
+ __u32 name;
+
+ /** Returned handle for the object */
+ __u32 handle;
+
+ /** Returned size of the object */
+ __u64 size;
+};
+
+#define DRM_CAP_DUMB_BUFFER 0x1
+#define DRM_CAP_VBLANK_HIGH_CRTC 0x2
+#define DRM_CAP_DUMB_PREFERRED_DEPTH 0x3
+#define DRM_CAP_DUMB_PREFER_SHADOW 0x4
+#define DRM_CAP_PRIME 0x5
+#define DRM_PRIME_CAP_IMPORT 0x1
+#define DRM_PRIME_CAP_EXPORT 0x2
+#define DRM_CAP_TIMESTAMP_MONOTONIC 0x6
+#define DRM_CAP_ASYNC_PAGE_FLIP 0x7
+/*
+ * The CURSOR_WIDTH and CURSOR_HEIGHT capabilities return a valid widthxheight
+ * combination for the hardware cursor. The intention is that a hardware
+ * agnostic userspace can query a cursor plane size to use.
+ *
+ * Note that the cross-driver contract is to merely return a valid size;
+ * drivers are free to attach another meaning on top, eg. i915 returns the
+ * maximum plane size.
+ */
+#define DRM_CAP_CURSOR_WIDTH 0x8
+#define DRM_CAP_CURSOR_HEIGHT 0x9
+#define DRM_CAP_ADDFB2_MODIFIERS 0x10
+#define DRM_CAP_PAGE_FLIP_TARGET 0x11
+#define DRM_CAP_CRTC_IN_VBLANK_EVENT 0x12
+#define DRM_CAP_SYNCOBJ 0x13
+
+/** DRM_IOCTL_GET_CAP ioctl argument type */
+struct drm_get_cap {
+ __u64 capability;
+ __u64 value;
+};
+
+/**
+ * DRM_CLIENT_CAP_STEREO_3D
+ *
+ * if set to 1, the DRM core will expose the stereo 3D capabilities of the
+ * monitor by advertising the supported 3D layouts in the flags of struct
+ * drm_mode_modeinfo.
+ */
+#define DRM_CLIENT_CAP_STEREO_3D 1
+
+/**
+ * DRM_CLIENT_CAP_UNIVERSAL_PLANES
+ *
+ * If set to 1, the DRM core will expose all planes (overlay, primary, and
+ * cursor) to userspace.
+ */
+#define DRM_CLIENT_CAP_UNIVERSAL_PLANES 2
+
+/**
+ * DRM_CLIENT_CAP_ATOMIC
+ *
+ * If set to 1, the DRM core will expose atomic properties to userspace
+ */
+#define DRM_CLIENT_CAP_ATOMIC 3
+
+/**
+ * DRM_CLIENT_CAP_ASPECT_RATIO
+ *
+ * If set to 1, the DRM core will provide aspect ratio information in modes.
+ */
+#define DRM_CLIENT_CAP_ASPECT_RATIO 4
+
+/**
+ * DRM_CLIENT_CAP_WRITEBACK_CONNECTORS
+ *
+ * If set to 1, the DRM core will expose special connectors to be used for
+ * writing back to memory the scene setup in the commit. Depends on client
+ * also supporting DRM_CLIENT_CAP_ATOMIC
+ */
+#define DRM_CLIENT_CAP_WRITEBACK_CONNECTORS 5
+
+/** DRM_IOCTL_SET_CLIENT_CAP ioctl argument type */
+struct drm_set_client_cap {
+ __u64 capability;
+ __u64 value;
+};
+
+#define DRM_RDWR O_RDWR
+#define DRM_CLOEXEC O_CLOEXEC
+struct drm_prime_handle {
+ __u32 handle;
+
+ /** Flags.. only applicable for handle->fd */
+ __u32 flags;
+
+ /** Returned dmabuf file descriptor */
+ __s32 fd;
+};
+
+struct drm_syncobj_create {
+ __u32 handle;
+#define DRM_SYNCOBJ_CREATE_SIGNALED (1 << 0)
+ __u32 flags;
+};
+
+struct drm_syncobj_destroy {
+ __u32 handle;
+ __u32 pad;
+};
+
+#define DRM_SYNCOBJ_FD_TO_HANDLE_FLAGS_IMPORT_SYNC_FILE (1 << 0)
+#define DRM_SYNCOBJ_HANDLE_TO_FD_FLAGS_EXPORT_SYNC_FILE (1 << 0)
+struct drm_syncobj_handle {
+ __u32 handle;
+ __u32 flags;
+
+ __s32 fd;
+ __u32 pad;
+};
+
+#define DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL (1 << 0)
+#define DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT (1 << 1)
+struct drm_syncobj_wait {
+ __u64 handles;
+ /* absolute timeout */
+ __s64 timeout_nsec;
+ __u32 count_handles;
+ __u32 flags;
+ __u32 first_signaled; /* only valid when not waiting all */
+ __u32 pad;
+};
+
+struct drm_syncobj_array {
+ __u64 handles;
+ __u32 count_handles;
+ __u32 pad;
+};
+
+/* Query current scanout sequence number */
+struct drm_crtc_get_sequence {
+ __u32 crtc_id; /* requested crtc_id */
+ __u32 active; /* return: crtc output is active */
+ __u64 sequence; /* return: most recent vblank sequence */
+ __s64 sequence_ns; /* return: most recent time of first pixel out */
+};
+
+/* Queue event to be delivered at specified sequence. Time stamp marks
+ * when the first pixel of the refresh cycle leaves the display engine
+ * for the display
+ */
+#define DRM_CRTC_SEQUENCE_RELATIVE 0x00000001 /* sequence is relative to current */
+#define DRM_CRTC_SEQUENCE_NEXT_ON_MISS 0x00000002 /* Use next sequence if we've missed */
+
+struct drm_crtc_queue_sequence {
+ __u32 crtc_id;
+ __u32 flags;
+ __u64 sequence; /* on input, target sequence. on output, actual sequence */
+ __u64 user_data; /* user data passed to event */
+};
+
+#if defined(__cplusplus)
+}
+#endif
+
+#include "drm_mode.h"
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#define DRM_IOCTL_BASE 'd'
+#define DRM_IO(nr) _IO(DRM_IOCTL_BASE,nr)
+#define DRM_IOR(nr,type) _IOR(DRM_IOCTL_BASE,nr,type)
+#define DRM_IOW(nr,type) _IOW(DRM_IOCTL_BASE,nr,type)
+#define DRM_IOWR(nr,type) _IOWR(DRM_IOCTL_BASE,nr,type)
+
+#define DRM_IOCTL_VERSION DRM_IOWR(0x00, struct drm_version)
+#define DRM_IOCTL_GET_UNIQUE DRM_IOWR(0x01, struct drm_unique)
+#define DRM_IOCTL_GET_MAGIC DRM_IOR( 0x02, struct drm_auth)
+#define DRM_IOCTL_IRQ_BUSID DRM_IOWR(0x03, struct drm_irq_busid)
+#define DRM_IOCTL_GET_MAP DRM_IOWR(0x04, struct drm_map)
+#define DRM_IOCTL_GET_CLIENT DRM_IOWR(0x05, struct drm_client)
+#define DRM_IOCTL_GET_STATS DRM_IOR( 0x06, struct drm_stats)
+#define DRM_IOCTL_SET_VERSION DRM_IOWR(0x07, struct drm_set_version)
+#define DRM_IOCTL_MODESET_CTL DRM_IOW(0x08, struct drm_modeset_ctl)
+#define DRM_IOCTL_GEM_CLOSE DRM_IOW (0x09, struct drm_gem_close)
+#define DRM_IOCTL_GEM_FLINK DRM_IOWR(0x0a, struct drm_gem_flink)
+#define DRM_IOCTL_GEM_OPEN DRM_IOWR(0x0b, struct drm_gem_open)
+#define DRM_IOCTL_GET_CAP DRM_IOWR(0x0c, struct drm_get_cap)
+#define DRM_IOCTL_SET_CLIENT_CAP DRM_IOW( 0x0d, struct drm_set_client_cap)
+
+#define DRM_IOCTL_SET_UNIQUE DRM_IOW( 0x10, struct drm_unique)
+#define DRM_IOCTL_AUTH_MAGIC DRM_IOW( 0x11, struct drm_auth)
+#define DRM_IOCTL_BLOCK DRM_IOWR(0x12, struct drm_block)
+#define DRM_IOCTL_UNBLOCK DRM_IOWR(0x13, struct drm_block)
+#define DRM_IOCTL_CONTROL DRM_IOW( 0x14, struct drm_control)
+#define DRM_IOCTL_ADD_MAP DRM_IOWR(0x15, struct drm_map)
+#define DRM_IOCTL_ADD_BUFS DRM_IOWR(0x16, struct drm_buf_desc)
+#define DRM_IOCTL_MARK_BUFS DRM_IOW( 0x17, struct drm_buf_desc)
+#define DRM_IOCTL_INFO_BUFS DRM_IOWR(0x18, struct drm_buf_info)
+#define DRM_IOCTL_MAP_BUFS DRM_IOWR(0x19, struct drm_buf_map)
+#define DRM_IOCTL_FREE_BUFS DRM_IOW( 0x1a, struct drm_buf_free)
+
+#define DRM_IOCTL_RM_MAP DRM_IOW( 0x1b, struct drm_map)
+
+#define DRM_IOCTL_SET_SAREA_CTX DRM_IOW( 0x1c, struct drm_ctx_priv_map)
+#define DRM_IOCTL_GET_SAREA_CTX DRM_IOWR(0x1d, struct drm_ctx_priv_map)
+
+#define DRM_IOCTL_SET_MASTER DRM_IO(0x1e)
+#define DRM_IOCTL_DROP_MASTER DRM_IO(0x1f)
+
+#define DRM_IOCTL_ADD_CTX DRM_IOWR(0x20, struct drm_ctx)
+#define DRM_IOCTL_RM_CTX DRM_IOWR(0x21, struct drm_ctx)
+#define DRM_IOCTL_MOD_CTX DRM_IOW( 0x22, struct drm_ctx)
+#define DRM_IOCTL_GET_CTX DRM_IOWR(0x23, struct drm_ctx)
+#define DRM_IOCTL_SWITCH_CTX DRM_IOW( 0x24, struct drm_ctx)
+#define DRM_IOCTL_NEW_CTX DRM_IOW( 0x25, struct drm_ctx)
+#define DRM_IOCTL_RES_CTX DRM_IOWR(0x26, struct drm_ctx_res)
+#define DRM_IOCTL_ADD_DRAW DRM_IOWR(0x27, struct drm_draw)
+#define DRM_IOCTL_RM_DRAW DRM_IOWR(0x28, struct drm_draw)
+#define DRM_IOCTL_DMA DRM_IOWR(0x29, struct drm_dma)
+#define DRM_IOCTL_LOCK DRM_IOW( 0x2a, struct drm_lock)
+#define DRM_IOCTL_UNLOCK DRM_IOW( 0x2b, struct drm_lock)
+#define DRM_IOCTL_FINISH DRM_IOW( 0x2c, struct drm_lock)
+
+#define DRM_IOCTL_PRIME_HANDLE_TO_FD DRM_IOWR(0x2d, struct drm_prime_handle)
+#define DRM_IOCTL_PRIME_FD_TO_HANDLE DRM_IOWR(0x2e, struct drm_prime_handle)
+
+#define DRM_IOCTL_AGP_ACQUIRE DRM_IO( 0x30)
+#define DRM_IOCTL_AGP_RELEASE DRM_IO( 0x31)
+#define DRM_IOCTL_AGP_ENABLE DRM_IOW( 0x32, struct drm_agp_mode)
+#define DRM_IOCTL_AGP_INFO DRM_IOR( 0x33, struct drm_agp_info)
+#define DRM_IOCTL_AGP_ALLOC DRM_IOWR(0x34, struct drm_agp_buffer)
+#define DRM_IOCTL_AGP_FREE DRM_IOW( 0x35, struct drm_agp_buffer)
+#define DRM_IOCTL_AGP_BIND DRM_IOW( 0x36, struct drm_agp_binding)
+#define DRM_IOCTL_AGP_UNBIND DRM_IOW( 0x37, struct drm_agp_binding)
+
+#define DRM_IOCTL_SG_ALLOC DRM_IOWR(0x38, struct drm_scatter_gather)
+#define DRM_IOCTL_SG_FREE DRM_IOW( 0x39, struct drm_scatter_gather)
+
+#define DRM_IOCTL_WAIT_VBLANK DRM_IOWR(0x3a, union drm_wait_vblank)
+
+#define DRM_IOCTL_CRTC_GET_SEQUENCE DRM_IOWR(0x3b, struct drm_crtc_get_sequence)
+#define DRM_IOCTL_CRTC_QUEUE_SEQUENCE DRM_IOWR(0x3c, struct drm_crtc_queue_sequence)
+
+#define DRM_IOCTL_UPDATE_DRAW DRM_IOW(0x3f, struct drm_update_draw)
+
+#define DRM_IOCTL_MODE_GETRESOURCES DRM_IOWR(0xA0, struct drm_mode_card_res)
+#define DRM_IOCTL_MODE_GETCRTC DRM_IOWR(0xA1, struct drm_mode_crtc)
+#define DRM_IOCTL_MODE_SETCRTC DRM_IOWR(0xA2, struct drm_mode_crtc)
+#define DRM_IOCTL_MODE_CURSOR DRM_IOWR(0xA3, struct drm_mode_cursor)
+#define DRM_IOCTL_MODE_GETGAMMA DRM_IOWR(0xA4, struct drm_mode_crtc_lut)
+#define DRM_IOCTL_MODE_SETGAMMA DRM_IOWR(0xA5, struct drm_mode_crtc_lut)
+#define DRM_IOCTL_MODE_GETENCODER DRM_IOWR(0xA6, struct drm_mode_get_encoder)
+#define DRM_IOCTL_MODE_GETCONNECTOR DRM_IOWR(0xA7, struct drm_mode_get_connector)
+#define DRM_IOCTL_MODE_ATTACHMODE DRM_IOWR(0xA8, struct drm_mode_mode_cmd) /* deprecated (never worked) */
+#define DRM_IOCTL_MODE_DETACHMODE DRM_IOWR(0xA9, struct drm_mode_mode_cmd) /* deprecated (never worked) */
+
+#define DRM_IOCTL_MODE_GETPROPERTY DRM_IOWR(0xAA, struct drm_mode_get_property)
+#define DRM_IOCTL_MODE_SETPROPERTY DRM_IOWR(0xAB, struct drm_mode_connector_set_property)
+#define DRM_IOCTL_MODE_GETPROPBLOB DRM_IOWR(0xAC, struct drm_mode_get_blob)
+#define DRM_IOCTL_MODE_GETFB DRM_IOWR(0xAD, struct drm_mode_fb_cmd)
+#define DRM_IOCTL_MODE_ADDFB DRM_IOWR(0xAE, struct drm_mode_fb_cmd)
+#define DRM_IOCTL_MODE_RMFB DRM_IOWR(0xAF, unsigned int)
+#define DRM_IOCTL_MODE_PAGE_FLIP DRM_IOWR(0xB0, struct drm_mode_crtc_page_flip)
+#define DRM_IOCTL_MODE_DIRTYFB DRM_IOWR(0xB1, struct drm_mode_fb_dirty_cmd)
+
+#define DRM_IOCTL_MODE_CREATE_DUMB DRM_IOWR(0xB2, struct drm_mode_create_dumb)
+#define DRM_IOCTL_MODE_MAP_DUMB DRM_IOWR(0xB3, struct drm_mode_map_dumb)
+#define DRM_IOCTL_MODE_DESTROY_DUMB DRM_IOWR(0xB4, struct drm_mode_destroy_dumb)
+#define DRM_IOCTL_MODE_GETPLANERESOURCES DRM_IOWR(0xB5, struct drm_mode_get_plane_res)
+#define DRM_IOCTL_MODE_GETPLANE DRM_IOWR(0xB6, struct drm_mode_get_plane)
+#define DRM_IOCTL_MODE_SETPLANE DRM_IOWR(0xB7, struct drm_mode_set_plane)
+#define DRM_IOCTL_MODE_ADDFB2 DRM_IOWR(0xB8, struct drm_mode_fb_cmd2)
+#define DRM_IOCTL_MODE_OBJ_GETPROPERTIES DRM_IOWR(0xB9, struct drm_mode_obj_get_properties)
+#define DRM_IOCTL_MODE_OBJ_SETPROPERTY DRM_IOWR(0xBA, struct drm_mode_obj_set_property)
+#define DRM_IOCTL_MODE_CURSOR2 DRM_IOWR(0xBB, struct drm_mode_cursor2)
+#define DRM_IOCTL_MODE_ATOMIC DRM_IOWR(0xBC, struct drm_mode_atomic)
+#define DRM_IOCTL_MODE_CREATEPROPBLOB DRM_IOWR(0xBD, struct drm_mode_create_blob)
+#define DRM_IOCTL_MODE_DESTROYPROPBLOB DRM_IOWR(0xBE, struct drm_mode_destroy_blob)
+
+#define DRM_IOCTL_SYNCOBJ_CREATE DRM_IOWR(0xBF, struct drm_syncobj_create)
+#define DRM_IOCTL_SYNCOBJ_DESTROY DRM_IOWR(0xC0, struct drm_syncobj_destroy)
+#define DRM_IOCTL_SYNCOBJ_HANDLE_TO_FD DRM_IOWR(0xC1, struct drm_syncobj_handle)
+#define DRM_IOCTL_SYNCOBJ_FD_TO_HANDLE DRM_IOWR(0xC2, struct drm_syncobj_handle)
+#define DRM_IOCTL_SYNCOBJ_WAIT DRM_IOWR(0xC3, struct drm_syncobj_wait)
+#define DRM_IOCTL_SYNCOBJ_RESET DRM_IOWR(0xC4, struct drm_syncobj_array)
+#define DRM_IOCTL_SYNCOBJ_SIGNAL DRM_IOWR(0xC5, struct drm_syncobj_array)
+
+#define DRM_IOCTL_MODE_CREATE_LEASE DRM_IOWR(0xC6, struct drm_mode_create_lease)
+#define DRM_IOCTL_MODE_LIST_LESSEES DRM_IOWR(0xC7, struct drm_mode_list_lessees)
+#define DRM_IOCTL_MODE_GET_LEASE DRM_IOWR(0xC8, struct drm_mode_get_lease)
+#define DRM_IOCTL_MODE_REVOKE_LEASE DRM_IOWR(0xC9, struct drm_mode_revoke_lease)
+
+/**
+ * Device specific ioctls should only be in their respective headers
+ * The device specific ioctl range is from 0x40 to 0x9f.
+ * Generic IOCTLS restart at 0xA0.
+ *
+ * \sa drmCommandNone(), drmCommandRead(), drmCommandWrite(), and
+ * drmCommandReadWrite().
+ */
+#define DRM_COMMAND_BASE 0x40
+#define DRM_COMMAND_END 0xA0
+
+/**
+ * Header for events written back to userspace on the drm fd. The
+ * type defines the type of event, the length specifies the total
+ * length of the event (including the header), and user_data is
+ * typically a 64 bit value passed with the ioctl that triggered the
+ * event. A read on the drm fd will always only return complete
+ * events, that is, if for example the read buffer is 100 bytes, and
+ * there are two 64 byte events pending, only one will be returned.
+ *
+ * Event types 0 - 0x7fffffff are generic drm events, 0x80000000 and
+ * up are chipset specific.
+ */
+struct drm_event {
+ __u32 type;
+ __u32 length;
+};
+
+#define DRM_EVENT_VBLANK 0x01
+#define DRM_EVENT_FLIP_COMPLETE 0x02
+#define DRM_EVENT_CRTC_SEQUENCE 0x03
+
+struct drm_event_vblank {
+ struct drm_event base;
+ __u64 user_data;
+ __u32 tv_sec;
+ __u32 tv_usec;
+ __u32 sequence;
+ __u32 crtc_id; /* 0 on older kernels that do not support this */
+};
+
+/* Event delivered at sequence. Time stamp marks when the first pixel
+ * of the refresh cycle leaves the display engine for the display
+ */
+struct drm_event_crtc_sequence {
+ struct drm_event base;
+ __u64 user_data;
+ __s64 time_ns;
+ __u64 sequence;
+};
+
+/* typedef area */
+typedef struct drm_clip_rect drm_clip_rect_t;
+typedef struct drm_drawable_info drm_drawable_info_t;
+typedef struct drm_tex_region drm_tex_region_t;
+typedef struct drm_hw_lock drm_hw_lock_t;
+typedef struct drm_version drm_version_t;
+typedef struct drm_unique drm_unique_t;
+typedef struct drm_list drm_list_t;
+typedef struct drm_block drm_block_t;
+typedef struct drm_control drm_control_t;
+typedef enum drm_map_type drm_map_type_t;
+typedef enum drm_map_flags drm_map_flags_t;
+typedef struct drm_ctx_priv_map drm_ctx_priv_map_t;
+typedef struct drm_map drm_map_t;
+typedef struct drm_client drm_client_t;
+typedef enum drm_stat_type drm_stat_type_t;
+typedef struct drm_stats drm_stats_t;
+typedef enum drm_lock_flags drm_lock_flags_t;
+typedef struct drm_lock drm_lock_t;
+typedef enum drm_dma_flags drm_dma_flags_t;
+typedef struct drm_buf_desc drm_buf_desc_t;
+typedef struct drm_buf_info drm_buf_info_t;
+typedef struct drm_buf_free drm_buf_free_t;
+typedef struct drm_buf_pub drm_buf_pub_t;
+typedef struct drm_buf_map drm_buf_map_t;
+typedef struct drm_dma drm_dma_t;
+typedef union drm_wait_vblank drm_wait_vblank_t;
+typedef struct drm_agp_mode drm_agp_mode_t;
+typedef enum drm_ctx_flags drm_ctx_flags_t;
+typedef struct drm_ctx drm_ctx_t;
+typedef struct drm_ctx_res drm_ctx_res_t;
+typedef struct drm_draw drm_draw_t;
+typedef struct drm_update_draw drm_update_draw_t;
+typedef struct drm_auth drm_auth_t;
+typedef struct drm_irq_busid drm_irq_busid_t;
+typedef enum drm_vblank_seq_type drm_vblank_seq_type_t;
+
+typedef struct drm_agp_buffer drm_agp_buffer_t;
+typedef struct drm_agp_binding drm_agp_binding_t;
+typedef struct drm_agp_info drm_agp_info_t;
+typedef struct drm_scatter_gather drm_scatter_gather_t;
+typedef struct drm_set_version drm_set_version_t;
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
diff --git a/make/stub_includes/drm/drm_mode.h b/make/stub_includes/drm/drm_mode.h
new file mode 100644
index 000000000..d3e0fe31e
--- /dev/null
+++ b/make/stub_includes/drm/drm_mode.h
@@ -0,0 +1,895 @@
+/*
+ * Copyright (c) 2007 Dave Airlie <[email protected]>
+ * Copyright (c) 2007 Jakob Bornecrantz <[email protected]>
+ * Copyright (c) 2008 Red Hat Inc.
+ * Copyright (c) 2007-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA
+ * Copyright (c) 2007-2008 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef _DRM_MODE_H
+#define _DRM_MODE_H
+
+#include "drm.h"
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#define DRM_DISPLAY_INFO_LEN 32
+#define DRM_CONNECTOR_NAME_LEN 32
+#define DRM_DISPLAY_MODE_LEN 32
+#define DRM_PROP_NAME_LEN 32
+
+#define DRM_MODE_TYPE_BUILTIN (1<<0) /* deprecated */
+#define DRM_MODE_TYPE_CLOCK_C ((1<<1) | DRM_MODE_TYPE_BUILTIN) /* deprecated */
+#define DRM_MODE_TYPE_CRTC_C ((1<<2) | DRM_MODE_TYPE_BUILTIN) /* deprecated */
+#define DRM_MODE_TYPE_PREFERRED (1<<3)
+#define DRM_MODE_TYPE_DEFAULT (1<<4) /* deprecated */
+#define DRM_MODE_TYPE_USERDEF (1<<5)
+#define DRM_MODE_TYPE_DRIVER (1<<6)
+
+#define DRM_MODE_TYPE_ALL (DRM_MODE_TYPE_PREFERRED | \
+ DRM_MODE_TYPE_USERDEF | \
+ DRM_MODE_TYPE_DRIVER)
+
+/* Video mode flags */
+/* bit compatible with the xrandr RR_ definitions (bits 0-13)
+ *
+ * ABI warning: Existing userspace really expects
+ * the mode flags to match the xrandr definitions. Any
+ * changes that don't match the xrandr definitions will
+ * likely need a new client cap or some other mechanism
+ * to avoid breaking existing userspace. This includes
+ * allocating new flags in the previously unused bits!
+ */
+#define DRM_MODE_FLAG_PHSYNC (1<<0)
+#define DRM_MODE_FLAG_NHSYNC (1<<1)
+#define DRM_MODE_FLAG_PVSYNC (1<<2)
+#define DRM_MODE_FLAG_NVSYNC (1<<3)
+#define DRM_MODE_FLAG_INTERLACE (1<<4)
+#define DRM_MODE_FLAG_DBLSCAN (1<<5)
+#define DRM_MODE_FLAG_CSYNC (1<<6)
+#define DRM_MODE_FLAG_PCSYNC (1<<7)
+#define DRM_MODE_FLAG_NCSYNC (1<<8)
+#define DRM_MODE_FLAG_HSKEW (1<<9) /* hskew provided */
+#define DRM_MODE_FLAG_BCAST (1<<10) /* deprecated */
+#define DRM_MODE_FLAG_PIXMUX (1<<11) /* deprecated */
+#define DRM_MODE_FLAG_DBLCLK (1<<12)
+#define DRM_MODE_FLAG_CLKDIV2 (1<<13)
+ /*
+ * When adding a new stereo mode don't forget to adjust DRM_MODE_FLAGS_3D_MAX
+ * (define not exposed to user space).
+ */
+#define DRM_MODE_FLAG_3D_MASK (0x1f<<14)
+#define DRM_MODE_FLAG_3D_NONE (0<<14)
+#define DRM_MODE_FLAG_3D_FRAME_PACKING (1<<14)
+#define DRM_MODE_FLAG_3D_FIELD_ALTERNATIVE (2<<14)
+#define DRM_MODE_FLAG_3D_LINE_ALTERNATIVE (3<<14)
+#define DRM_MODE_FLAG_3D_SIDE_BY_SIDE_FULL (4<<14)
+#define DRM_MODE_FLAG_3D_L_DEPTH (5<<14)
+#define DRM_MODE_FLAG_3D_L_DEPTH_GFX_GFX_DEPTH (6<<14)
+#define DRM_MODE_FLAG_3D_TOP_AND_BOTTOM (7<<14)
+#define DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF (8<<14)
+
+/* Picture aspect ratio options */
+#define DRM_MODE_PICTURE_ASPECT_NONE 0
+#define DRM_MODE_PICTURE_ASPECT_4_3 1
+#define DRM_MODE_PICTURE_ASPECT_16_9 2
+#define DRM_MODE_PICTURE_ASPECT_64_27 3
+#define DRM_MODE_PICTURE_ASPECT_256_135 4
+
+/* Content type options */
+#define DRM_MODE_CONTENT_TYPE_NO_DATA 0
+#define DRM_MODE_CONTENT_TYPE_GRAPHICS 1
+#define DRM_MODE_CONTENT_TYPE_PHOTO 2
+#define DRM_MODE_CONTENT_TYPE_CINEMA 3
+#define DRM_MODE_CONTENT_TYPE_GAME 4
+
+/* Aspect ratio flag bitmask (4 bits 22:19) */
+#define DRM_MODE_FLAG_PIC_AR_MASK (0x0F<<19)
+#define DRM_MODE_FLAG_PIC_AR_NONE \
+ (DRM_MODE_PICTURE_ASPECT_NONE<<19)
+#define DRM_MODE_FLAG_PIC_AR_4_3 \
+ (DRM_MODE_PICTURE_ASPECT_4_3<<19)
+#define DRM_MODE_FLAG_PIC_AR_16_9 \
+ (DRM_MODE_PICTURE_ASPECT_16_9<<19)
+#define DRM_MODE_FLAG_PIC_AR_64_27 \
+ (DRM_MODE_PICTURE_ASPECT_64_27<<19)
+#define DRM_MODE_FLAG_PIC_AR_256_135 \
+ (DRM_MODE_PICTURE_ASPECT_256_135<<19)
+
+#define DRM_MODE_FLAG_ALL (DRM_MODE_FLAG_PHSYNC | \
+ DRM_MODE_FLAG_NHSYNC | \
+ DRM_MODE_FLAG_PVSYNC | \
+ DRM_MODE_FLAG_NVSYNC | \
+ DRM_MODE_FLAG_INTERLACE | \
+ DRM_MODE_FLAG_DBLSCAN | \
+ DRM_MODE_FLAG_CSYNC | \
+ DRM_MODE_FLAG_PCSYNC | \
+ DRM_MODE_FLAG_NCSYNC | \
+ DRM_MODE_FLAG_HSKEW | \
+ DRM_MODE_FLAG_DBLCLK | \
+ DRM_MODE_FLAG_CLKDIV2 | \
+ DRM_MODE_FLAG_3D_MASK)
+
+/* DPMS flags */
+/* bit compatible with the xorg definitions. */
+#define DRM_MODE_DPMS_ON 0
+#define DRM_MODE_DPMS_STANDBY 1
+#define DRM_MODE_DPMS_SUSPEND 2
+#define DRM_MODE_DPMS_OFF 3
+
+/* Scaling mode options */
+#define DRM_MODE_SCALE_NONE 0 /* Unmodified timing (display or
+ software can still scale) */
+#define DRM_MODE_SCALE_FULLSCREEN 1 /* Full screen, ignore aspect */
+#define DRM_MODE_SCALE_CENTER 2 /* Centered, no scaling */
+#define DRM_MODE_SCALE_ASPECT 3 /* Full screen, preserve aspect */
+
+/* Dithering mode options */
+#define DRM_MODE_DITHERING_OFF 0
+#define DRM_MODE_DITHERING_ON 1
+#define DRM_MODE_DITHERING_AUTO 2
+
+/* Dirty info options */
+#define DRM_MODE_DIRTY_OFF 0
+#define DRM_MODE_DIRTY_ON 1
+#define DRM_MODE_DIRTY_ANNOTATE 2
+
+/* Link Status options */
+#define DRM_MODE_LINK_STATUS_GOOD 0
+#define DRM_MODE_LINK_STATUS_BAD 1
+
+/*
+ * DRM_MODE_ROTATE_<degrees>
+ *
+ * Signals that a drm plane is been rotated <degrees> degrees in counter
+ * clockwise direction.
+ *
+ * This define is provided as a convenience, looking up the property id
+ * using the name->prop id lookup is the preferred method.
+ */
+#define DRM_MODE_ROTATE_0 (1<<0)
+#define DRM_MODE_ROTATE_90 (1<<1)
+#define DRM_MODE_ROTATE_180 (1<<2)
+#define DRM_MODE_ROTATE_270 (1<<3)
+
+/*
+ * DRM_MODE_ROTATE_MASK
+ *
+ * Bitmask used to look for drm plane rotations.
+ */
+#define DRM_MODE_ROTATE_MASK (\
+ DRM_MODE_ROTATE_0 | \
+ DRM_MODE_ROTATE_90 | \
+ DRM_MODE_ROTATE_180 | \
+ DRM_MODE_ROTATE_270)
+
+/*
+ * DRM_MODE_REFLECT_<axis>
+ *
+ * Signals that the contents of a drm plane is reflected along the <axis> axis,
+ * in the same way as mirroring.
+ * See kerneldoc chapter "Plane Composition Properties" for more details.
+ *
+ * This define is provided as a convenience, looking up the property id
+ * using the name->prop id lookup is the preferred method.
+ */
+#define DRM_MODE_REFLECT_X (1<<4)
+#define DRM_MODE_REFLECT_Y (1<<5)
+
+/*
+ * DRM_MODE_REFLECT_MASK
+ *
+ * Bitmask used to look for drm plane reflections.
+ */
+#define DRM_MODE_REFLECT_MASK (\
+ DRM_MODE_REFLECT_X | \
+ DRM_MODE_REFLECT_Y)
+
+/* Content Protection Flags */
+#define DRM_MODE_CONTENT_PROTECTION_UNDESIRED 0
+#define DRM_MODE_CONTENT_PROTECTION_DESIRED 1
+#define DRM_MODE_CONTENT_PROTECTION_ENABLED 2
+
+struct drm_mode_modeinfo {
+ __u32 clock;
+ __u16 hdisplay;
+ __u16 hsync_start;
+ __u16 hsync_end;
+ __u16 htotal;
+ __u16 hskew;
+ __u16 vdisplay;
+ __u16 vsync_start;
+ __u16 vsync_end;
+ __u16 vtotal;
+ __u16 vscan;
+
+ __u32 vrefresh;
+
+ __u32 flags;
+ __u32 type;
+ char name[DRM_DISPLAY_MODE_LEN];
+};
+
+struct drm_mode_card_res {
+ __u64 fb_id_ptr;
+ __u64 crtc_id_ptr;
+ __u64 connector_id_ptr;
+ __u64 encoder_id_ptr;
+ __u32 count_fbs;
+ __u32 count_crtcs;
+ __u32 count_connectors;
+ __u32 count_encoders;
+ __u32 min_width;
+ __u32 max_width;
+ __u32 min_height;
+ __u32 max_height;
+};
+
+struct drm_mode_crtc {
+ __u64 set_connectors_ptr;
+ __u32 count_connectors;
+
+ __u32 crtc_id; /**< Id */
+ __u32 fb_id; /**< Id of framebuffer */
+
+ __u32 x; /**< x Position on the framebuffer */
+ __u32 y; /**< y Position on the framebuffer */
+
+ __u32 gamma_size;
+ __u32 mode_valid;
+ struct drm_mode_modeinfo mode;
+};
+
+#define DRM_MODE_PRESENT_TOP_FIELD (1<<0)
+#define DRM_MODE_PRESENT_BOTTOM_FIELD (1<<1)
+
+/* Planes blend with or override other bits on the CRTC */
+struct drm_mode_set_plane {
+ __u32 plane_id;
+ __u32 crtc_id;
+ __u32 fb_id; /* fb object contains surface format type */
+ __u32 flags; /* see above flags */
+
+ /* Signed dest location allows it to be partially off screen */
+ __s32 crtc_x;
+ __s32 crtc_y;
+ __u32 crtc_w;
+ __u32 crtc_h;
+
+ /* Source values are 16.16 fixed point */
+ __u32 src_x;
+ __u32 src_y;
+ __u32 src_h;
+ __u32 src_w;
+};
+
+struct drm_mode_get_plane {
+ __u32 plane_id;
+
+ __u32 crtc_id;
+ __u32 fb_id;
+
+ __u32 possible_crtcs;
+ __u32 gamma_size;
+
+ __u32 count_format_types;
+ __u64 format_type_ptr;
+};
+
+struct drm_mode_get_plane_res {
+ __u64 plane_id_ptr;
+ __u32 count_planes;
+};
+
+#define DRM_MODE_ENCODER_NONE 0
+#define DRM_MODE_ENCODER_DAC 1
+#define DRM_MODE_ENCODER_TMDS 2
+#define DRM_MODE_ENCODER_LVDS 3
+#define DRM_MODE_ENCODER_TVDAC 4
+#define DRM_MODE_ENCODER_VIRTUAL 5
+#define DRM_MODE_ENCODER_DSI 6
+#define DRM_MODE_ENCODER_DPMST 7
+#define DRM_MODE_ENCODER_DPI 8
+
+struct drm_mode_get_encoder {
+ __u32 encoder_id;
+ __u32 encoder_type;
+
+ __u32 crtc_id; /**< Id of crtc */
+
+ __u32 possible_crtcs;
+ __u32 possible_clones;
+};
+
+/* This is for connectors with multiple signal types. */
+/* Try to match DRM_MODE_CONNECTOR_X as closely as possible. */
+enum drm_mode_subconnector {
+ DRM_MODE_SUBCONNECTOR_Automatic = 0,
+ DRM_MODE_SUBCONNECTOR_Unknown = 0,
+ DRM_MODE_SUBCONNECTOR_DVID = 3,
+ DRM_MODE_SUBCONNECTOR_DVIA = 4,
+ DRM_MODE_SUBCONNECTOR_Composite = 5,
+ DRM_MODE_SUBCONNECTOR_SVIDEO = 6,
+ DRM_MODE_SUBCONNECTOR_Component = 8,
+ DRM_MODE_SUBCONNECTOR_SCART = 9,
+};
+
+#define DRM_MODE_CONNECTOR_Unknown 0
+#define DRM_MODE_CONNECTOR_VGA 1
+#define DRM_MODE_CONNECTOR_DVII 2
+#define DRM_MODE_CONNECTOR_DVID 3
+#define DRM_MODE_CONNECTOR_DVIA 4
+#define DRM_MODE_CONNECTOR_Composite 5
+#define DRM_MODE_CONNECTOR_SVIDEO 6
+#define DRM_MODE_CONNECTOR_LVDS 7
+#define DRM_MODE_CONNECTOR_Component 8
+#define DRM_MODE_CONNECTOR_9PinDIN 9
+#define DRM_MODE_CONNECTOR_DisplayPort 10
+#define DRM_MODE_CONNECTOR_HDMIA 11
+#define DRM_MODE_CONNECTOR_HDMIB 12
+#define DRM_MODE_CONNECTOR_TV 13
+#define DRM_MODE_CONNECTOR_eDP 14
+#define DRM_MODE_CONNECTOR_VIRTUAL 15
+#define DRM_MODE_CONNECTOR_DSI 16
+#define DRM_MODE_CONNECTOR_DPI 17
+#define DRM_MODE_CONNECTOR_WRITEBACK 18
+
+struct drm_mode_get_connector {
+
+ __u64 encoders_ptr;
+ __u64 modes_ptr;
+ __u64 props_ptr;
+ __u64 prop_values_ptr;
+
+ __u32 count_modes;
+ __u32 count_props;
+ __u32 count_encoders;
+
+ __u32 encoder_id; /**< Current Encoder */
+ __u32 connector_id; /**< Id */
+ __u32 connector_type;
+ __u32 connector_type_id;
+
+ __u32 connection;
+ __u32 mm_width; /**< width in millimeters */
+ __u32 mm_height; /**< height in millimeters */
+ __u32 subpixel;
+
+ __u32 pad;
+};
+
+#define DRM_MODE_PROP_PENDING (1<<0) /* deprecated, do not use */
+#define DRM_MODE_PROP_RANGE (1<<1)
+#define DRM_MODE_PROP_IMMUTABLE (1<<2)
+#define DRM_MODE_PROP_ENUM (1<<3) /* enumerated type with text strings */
+#define DRM_MODE_PROP_BLOB (1<<4)
+#define DRM_MODE_PROP_BITMASK (1<<5) /* bitmask of enumerated types */
+
+/* non-extended types: legacy bitmask, one bit per type: */
+#define DRM_MODE_PROP_LEGACY_TYPE ( \
+ DRM_MODE_PROP_RANGE | \
+ DRM_MODE_PROP_ENUM | \
+ DRM_MODE_PROP_BLOB | \
+ DRM_MODE_PROP_BITMASK)
+
+/* extended-types: rather than continue to consume a bit per type,
+ * grab a chunk of the bits to use as integer type id.
+ */
+#define DRM_MODE_PROP_EXTENDED_TYPE 0x0000ffc0
+#define DRM_MODE_PROP_TYPE(n) ((n) << 6)
+#define DRM_MODE_PROP_OBJECT DRM_MODE_PROP_TYPE(1)
+#define DRM_MODE_PROP_SIGNED_RANGE DRM_MODE_PROP_TYPE(2)
+
+/* the PROP_ATOMIC flag is used to hide properties from userspace that
+ * is not aware of atomic properties. This is mostly to work around
+ * older userspace (DDX drivers) that read/write each prop they find,
+ * witout being aware that this could be triggering a lengthy modeset.
+ */
+#define DRM_MODE_PROP_ATOMIC 0x80000000
+
+struct drm_mode_property_enum {
+ __u64 value;
+ char name[DRM_PROP_NAME_LEN];
+};
+
+struct drm_mode_get_property {
+ __u64 values_ptr; /* values and blob lengths */
+ __u64 enum_blob_ptr; /* enum and blob id ptrs */
+
+ __u32 prop_id;
+ __u32 flags;
+ char name[DRM_PROP_NAME_LEN];
+
+ __u32 count_values;
+ /* This is only used to count enum values, not blobs. The _blobs is
+ * simply because of a historical reason, i.e. backwards compat. */
+ __u32 count_enum_blobs;
+};
+
+struct drm_mode_connector_set_property {
+ __u64 value;
+ __u32 prop_id;
+ __u32 connector_id;
+};
+
+#define DRM_MODE_OBJECT_CRTC 0xcccccccc
+#define DRM_MODE_OBJECT_CONNECTOR 0xc0c0c0c0
+#define DRM_MODE_OBJECT_ENCODER 0xe0e0e0e0
+#define DRM_MODE_OBJECT_MODE 0xdededede
+#define DRM_MODE_OBJECT_PROPERTY 0xb0b0b0b0
+#define DRM_MODE_OBJECT_FB 0xfbfbfbfb
+#define DRM_MODE_OBJECT_BLOB 0xbbbbbbbb
+#define DRM_MODE_OBJECT_PLANE 0xeeeeeeee
+#define DRM_MODE_OBJECT_ANY 0
+
+struct drm_mode_obj_get_properties {
+ __u64 props_ptr;
+ __u64 prop_values_ptr;
+ __u32 count_props;
+ __u32 obj_id;
+ __u32 obj_type;
+};
+
+struct drm_mode_obj_set_property {
+ __u64 value;
+ __u32 prop_id;
+ __u32 obj_id;
+ __u32 obj_type;
+};
+
+struct drm_mode_get_blob {
+ __u32 blob_id;
+ __u32 length;
+ __u64 data;
+};
+
+struct drm_mode_fb_cmd {
+ __u32 fb_id;
+ __u32 width;
+ __u32 height;
+ __u32 pitch;
+ __u32 bpp;
+ __u32 depth;
+ /* driver specific handle */
+ __u32 handle;
+};
+
+#define DRM_MODE_FB_INTERLACED (1<<0) /* for interlaced framebuffers */
+#define DRM_MODE_FB_MODIFIERS (1<<1) /* enables ->modifer[] */
+
+struct drm_mode_fb_cmd2 {
+ __u32 fb_id;
+ __u32 width;
+ __u32 height;
+ __u32 pixel_format; /* fourcc code from drm_fourcc.h */
+ __u32 flags; /* see above flags */
+
+ /*
+ * In case of planar formats, this ioctl allows up to 4
+ * buffer objects with offsets and pitches per plane.
+ * The pitch and offset order is dictated by the fourcc,
+ * e.g. NV12 (http://fourcc.org/yuv.php#NV12) is described as:
+ *
+ * YUV 4:2:0 image with a plane of 8 bit Y samples
+ * followed by an interleaved U/V plane containing
+ * 8 bit 2x2 subsampled colour difference samples.
+ *
+ * So it would consist of Y as offsets[0] and UV as
+ * offsets[1]. Note that offsets[0] will generally
+ * be 0 (but this is not required).
+ *
+ * To accommodate tiled, compressed, etc formats, a
+ * modifier can be specified. The default value of zero
+ * indicates "native" format as specified by the fourcc.
+ * Vendor specific modifier token. Note that even though
+ * it looks like we have a modifier per-plane, we in fact
+ * do not. The modifier for each plane must be identical.
+ * Thus all combinations of different data layouts for
+ * multi plane formats must be enumerated as separate
+ * modifiers.
+ */
+ __u32 handles[4];
+ __u32 pitches[4]; /* pitch for each plane */
+ __u32 offsets[4]; /* offset of each plane */
+ __u64 modifier[4]; /* ie, tiling, compress */
+};
+
+#define DRM_MODE_FB_DIRTY_ANNOTATE_COPY 0x01
+#define DRM_MODE_FB_DIRTY_ANNOTATE_FILL 0x02
+#define DRM_MODE_FB_DIRTY_FLAGS 0x03
+
+#define DRM_MODE_FB_DIRTY_MAX_CLIPS 256
+
+/*
+ * Mark a region of a framebuffer as dirty.
+ *
+ * Some hardware does not automatically update display contents
+ * as a hardware or software draw to a framebuffer. This ioctl
+ * allows userspace to tell the kernel and the hardware what
+ * regions of the framebuffer have changed.
+ *
+ * The kernel or hardware is free to update more then just the
+ * region specified by the clip rects. The kernel or hardware
+ * may also delay and/or coalesce several calls to dirty into a
+ * single update.
+ *
+ * Userspace may annotate the updates, the annotates are a
+ * promise made by the caller that the change is either a copy
+ * of pixels or a fill of a single color in the region specified.
+ *
+ * If the DRM_MODE_FB_DIRTY_ANNOTATE_COPY flag is given then
+ * the number of updated regions are half of num_clips given,
+ * where the clip rects are paired in src and dst. The width and
+ * height of each one of the pairs must match.
+ *
+ * If the DRM_MODE_FB_DIRTY_ANNOTATE_FILL flag is given the caller
+ * promises that the region specified of the clip rects is filled
+ * completely with a single color as given in the color argument.
+ */
+
+struct drm_mode_fb_dirty_cmd {
+ __u32 fb_id;
+ __u32 flags;
+ __u32 color;
+ __u32 num_clips;
+ __u64 clips_ptr;
+};
+
+struct drm_mode_mode_cmd {
+ __u32 connector_id;
+ struct drm_mode_modeinfo mode;
+};
+
+#define DRM_MODE_CURSOR_BO 0x01
+#define DRM_MODE_CURSOR_MOVE 0x02
+#define DRM_MODE_CURSOR_FLAGS 0x03
+
+/*
+ * depending on the value in flags different members are used.
+ *
+ * CURSOR_BO uses
+ * crtc_id
+ * width
+ * height
+ * handle - if 0 turns the cursor off
+ *
+ * CURSOR_MOVE uses
+ * crtc_id
+ * x
+ * y
+ */
+struct drm_mode_cursor {
+ __u32 flags;
+ __u32 crtc_id;
+ __s32 x;
+ __s32 y;
+ __u32 width;
+ __u32 height;
+ /* driver specific handle */
+ __u32 handle;
+};
+
+struct drm_mode_cursor2 {
+ __u32 flags;
+ __u32 crtc_id;
+ __s32 x;
+ __s32 y;
+ __u32 width;
+ __u32 height;
+ /* driver specific handle */
+ __u32 handle;
+ __s32 hot_x;
+ __s32 hot_y;
+};
+
+struct drm_mode_crtc_lut {
+ __u32 crtc_id;
+ __u32 gamma_size;
+
+ /* pointers to arrays */
+ __u64 red;
+ __u64 green;
+ __u64 blue;
+};
+
+struct drm_color_ctm {
+ /*
+ * Conversion matrix in S31.32 sign-magnitude
+ * (not two's complement!) format.
+ */
+ __u64 matrix[9];
+};
+
+struct drm_color_lut {
+ /*
+ * Data is U0.16 fixed point format.
+ */
+ __u16 red;
+ __u16 green;
+ __u16 blue;
+ __u16 reserved;
+};
+
+#define DRM_MODE_PAGE_FLIP_EVENT 0x01
+#define DRM_MODE_PAGE_FLIP_ASYNC 0x02
+#define DRM_MODE_PAGE_FLIP_TARGET_ABSOLUTE 0x4
+#define DRM_MODE_PAGE_FLIP_TARGET_RELATIVE 0x8
+#define DRM_MODE_PAGE_FLIP_TARGET (DRM_MODE_PAGE_FLIP_TARGET_ABSOLUTE | \
+ DRM_MODE_PAGE_FLIP_TARGET_RELATIVE)
+#define DRM_MODE_PAGE_FLIP_FLAGS (DRM_MODE_PAGE_FLIP_EVENT | \
+ DRM_MODE_PAGE_FLIP_ASYNC | \
+ DRM_MODE_PAGE_FLIP_TARGET)
+
+/*
+ * Request a page flip on the specified crtc.
+ *
+ * This ioctl will ask KMS to schedule a page flip for the specified
+ * crtc. Once any pending rendering targeting the specified fb (as of
+ * ioctl time) has completed, the crtc will be reprogrammed to display
+ * that fb after the next vertical refresh. The ioctl returns
+ * immediately, but subsequent rendering to the current fb will block
+ * in the execbuffer ioctl until the page flip happens. If a page
+ * flip is already pending as the ioctl is called, EBUSY will be
+ * returned.
+ *
+ * Flag DRM_MODE_PAGE_FLIP_EVENT requests that drm sends back a vblank
+ * event (see drm.h: struct drm_event_vblank) when the page flip is
+ * done. The user_data field passed in with this ioctl will be
+ * returned as the user_data field in the vblank event struct.
+ *
+ * Flag DRM_MODE_PAGE_FLIP_ASYNC requests that the flip happen
+ * 'as soon as possible', meaning that it not delay waiting for vblank.
+ * This may cause tearing on the screen.
+ *
+ * The reserved field must be zero.
+ */
+
+struct drm_mode_crtc_page_flip {
+ __u32 crtc_id;
+ __u32 fb_id;
+ __u32 flags;
+ __u32 reserved;
+ __u64 user_data;
+};
+
+/*
+ * Request a page flip on the specified crtc.
+ *
+ * Same as struct drm_mode_crtc_page_flip, but supports new flags and
+ * re-purposes the reserved field:
+ *
+ * The sequence field must be zero unless either of the
+ * DRM_MODE_PAGE_FLIP_TARGET_ABSOLUTE/RELATIVE flags is specified. When
+ * the ABSOLUTE flag is specified, the sequence field denotes the absolute
+ * vblank sequence when the flip should take effect. When the RELATIVE
+ * flag is specified, the sequence field denotes the relative (to the
+ * current one when the ioctl is called) vblank sequence when the flip
+ * should take effect. NOTE: DRM_IOCTL_WAIT_VBLANK must still be used to
+ * make sure the vblank sequence before the target one has passed before
+ * calling this ioctl. The purpose of the
+ * DRM_MODE_PAGE_FLIP_TARGET_ABSOLUTE/RELATIVE flags is merely to clarify
+ * the target for when code dealing with a page flip runs during a
+ * vertical blank period.
+ */
+
+struct drm_mode_crtc_page_flip_target {
+ __u32 crtc_id;
+ __u32 fb_id;
+ __u32 flags;
+ __u32 sequence;
+ __u64 user_data;
+};
+
+/* create a dumb scanout buffer */
+struct drm_mode_create_dumb {
+ __u32 height;
+ __u32 width;
+ __u32 bpp;
+ __u32 flags;
+ /* handle, pitch, size will be returned */
+ __u32 handle;
+ __u32 pitch;
+ __u64 size;
+};
+
+/* set up for mmap of a dumb scanout buffer */
+struct drm_mode_map_dumb {
+ /** Handle for the object being mapped. */
+ __u32 handle;
+ __u32 pad;
+ /**
+ * Fake offset to use for subsequent mmap call
+ *
+ * This is a fixed-size type for 32/64 compatibility.
+ */
+ __u64 offset;
+};
+
+struct drm_mode_destroy_dumb {
+ __u32 handle;
+};
+
+/* page-flip flags are valid, plus: */
+#define DRM_MODE_ATOMIC_TEST_ONLY 0x0100
+#define DRM_MODE_ATOMIC_NONBLOCK 0x0200
+#define DRM_MODE_ATOMIC_ALLOW_MODESET 0x0400
+
+#define DRM_MODE_ATOMIC_FLAGS (\
+ DRM_MODE_PAGE_FLIP_EVENT |\
+ DRM_MODE_PAGE_FLIP_ASYNC |\
+ DRM_MODE_ATOMIC_TEST_ONLY |\
+ DRM_MODE_ATOMIC_NONBLOCK |\
+ DRM_MODE_ATOMIC_ALLOW_MODESET)
+
+struct drm_mode_atomic {
+ __u32 flags;
+ __u32 count_objs;
+ __u64 objs_ptr;
+ __u64 count_props_ptr;
+ __u64 props_ptr;
+ __u64 prop_values_ptr;
+ __u64 reserved;
+ __u64 user_data;
+};
+
+struct drm_format_modifier_blob {
+#define FORMAT_BLOB_CURRENT 1
+ /* Version of this blob format */
+ __u32 version;
+
+ /* Flags */
+ __u32 flags;
+
+ /* Number of fourcc formats supported */
+ __u32 count_formats;
+
+ /* Where in this blob the formats exist (in bytes) */
+ __u32 formats_offset;
+
+ /* Number of drm_format_modifiers */
+ __u32 count_modifiers;
+
+ /* Where in this blob the modifiers exist (in bytes) */
+ __u32 modifiers_offset;
+
+ /* __u32 formats[] */
+ /* struct drm_format_modifier modifiers[] */
+};
+
+struct drm_format_modifier {
+ /* Bitmask of formats in get_plane format list this info applies to. The
+ * offset allows a sliding window of which 64 formats (bits).
+ *
+ * Some examples:
+ * In today's world with < 65 formats, and formats 0, and 2 are
+ * supported
+ * 0x0000000000000005
+ * ^-offset = 0, formats = 5
+ *
+ * If the number formats grew to 128, and formats 98-102 are
+ * supported with the modifier:
+ *
+ * 0x0000007c00000000 0000000000000000
+ * ^
+ * |__offset = 64, formats = 0x7c00000000
+ *
+ */
+ __u64 formats;
+ __u32 offset;
+ __u32 pad;
+
+ /* The modifier that applies to the >get_plane format list bitmask. */
+ __u64 modifier;
+};
+
+/**
+ * Create a new 'blob' data property, copying length bytes from data pointer,
+ * and returning new blob ID.
+ */
+struct drm_mode_create_blob {
+ /** Pointer to data to copy. */
+ __u64 data;
+ /** Length of data to copy. */
+ __u32 length;
+ /** Return: new property ID. */
+ __u32 blob_id;
+};
+
+/**
+ * Destroy a user-created blob property.
+ */
+struct drm_mode_destroy_blob {
+ __u32 blob_id;
+};
+
+/**
+ * Lease mode resources, creating another drm_master.
+ */
+struct drm_mode_create_lease {
+ /** Pointer to array of object ids (__u32) */
+ __u64 object_ids;
+ /** Number of object ids */
+ __u32 object_count;
+ /** flags for new FD (O_CLOEXEC, etc) */
+ __u32 flags;
+
+ /** Return: unique identifier for lessee. */
+ __u32 lessee_id;
+ /** Return: file descriptor to new drm_master file */
+ __u32 fd;
+};
+
+/**
+ * List lesses from a drm_master
+ */
+struct drm_mode_list_lessees {
+ /** Number of lessees.
+ * On input, provides length of the array.
+ * On output, provides total number. No
+ * more than the input number will be written
+ * back, so two calls can be used to get
+ * the size and then the data.
+ */
+ __u32 count_lessees;
+ __u32 pad;
+
+ /** Pointer to lessees.
+ * pointer to __u64 array of lessee ids
+ */
+ __u64 lessees_ptr;
+};
+
+/**
+ * Get leased objects
+ */
+struct drm_mode_get_lease {
+ /** Number of leased objects.
+ * On input, provides length of the array.
+ * On output, provides total number. No
+ * more than the input number will be written
+ * back, so two calls can be used to get
+ * the size and then the data.
+ */
+ __u32 count_objects;
+ __u32 pad;
+
+ /** Pointer to objects.
+ * pointer to __u32 array of object ids
+ */
+ __u64 objects_ptr;
+};
+
+/**
+ * Revoke lease
+ */
+struct drm_mode_revoke_lease {
+ /** Unique ID of lessee
+ */
+ __u32 lessee_id;
+};
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
diff --git a/make/stub_includes/drm/gbm.h b/make/stub_includes/drm/gbm.h
new file mode 100644
index 000000000..e95f9e349
--- /dev/null
+++ b/make/stub_includes/drm/gbm.h
@@ -0,0 +1,406 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Benjamin Franzke <[email protected]>
+ */
+
+#ifndef _GBM_H_
+#define _GBM_H_
+
+#define __GBM__ 1
+
+#include <stddef.h>
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * \file gbm.h
+ * \brief Generic Buffer Manager
+ */
+
+struct gbm_device;
+struct gbm_bo;
+struct gbm_surface;
+
+/**
+ * \mainpage The Generic Buffer Manager
+ *
+ * This module provides an abstraction that the caller can use to request a
+ * buffer from the underlying memory management system for the platform.
+ *
+ * This allows the creation of portable code whilst still allowing access to
+ * the underlying memory manager.
+ */
+
+/**
+ * Abstraction representing the handle to a buffer allocated by the
+ * manager
+ */
+union gbm_bo_handle {
+ void *ptr;
+ int32_t s32;
+ uint32_t u32;
+ int64_t s64;
+ uint64_t u64;
+};
+
+/** Format of the allocated buffer */
+enum gbm_bo_format {
+ /** RGB with 8 bits per channel in a 32 bit value */
+ GBM_BO_FORMAT_XRGB8888,
+ /** ARGB with 8 bits per channel in a 32 bit value */
+ GBM_BO_FORMAT_ARGB8888
+};
+
+
+/**
+ * The FourCC format codes are taken from the drm_fourcc.h definition, and
+ * re-namespaced. New GBM formats must not be added, unless they are
+ * identical ports from drm_fourcc.
+ */
+#define __gbm_fourcc_code(a,b,c,d) ((uint32_t)(a) | ((uint32_t)(b) << 8) | \
+ ((uint32_t)(c) << 16) | ((uint32_t)(d) << 24))
+
+#define GBM_FORMAT_BIG_ENDIAN (1<<31) /* format is big endian instead of little endian */
+
+/* color index */
+#define GBM_FORMAT_C8 __gbm_fourcc_code('C', '8', ' ', ' ') /* [7:0] C */
+
+/* 8 bpp Red */
+#define GBM_FORMAT_R8 __gbm_fourcc_code('R', '8', ' ', ' ') /* [7:0] R */
+
+/* 16 bpp RG */
+#define GBM_FORMAT_GR88 __gbm_fourcc_code('G', 'R', '8', '8') /* [15:0] G:R 8:8 little endian */
+
+/* 8 bpp RGB */
+#define GBM_FORMAT_RGB332 __gbm_fourcc_code('R', 'G', 'B', '8') /* [7:0] R:G:B 3:3:2 */
+#define GBM_FORMAT_BGR233 __gbm_fourcc_code('B', 'G', 'R', '8') /* [7:0] B:G:R 2:3:3 */
+
+/* 16 bpp RGB */
+#define GBM_FORMAT_XRGB4444 __gbm_fourcc_code('X', 'R', '1', '2') /* [15:0] x:R:G:B 4:4:4:4 little endian */
+#define GBM_FORMAT_XBGR4444 __gbm_fourcc_code('X', 'B', '1', '2') /* [15:0] x:B:G:R 4:4:4:4 little endian */
+#define GBM_FORMAT_RGBX4444 __gbm_fourcc_code('R', 'X', '1', '2') /* [15:0] R:G:B:x 4:4:4:4 little endian */
+#define GBM_FORMAT_BGRX4444 __gbm_fourcc_code('B', 'X', '1', '2') /* [15:0] B:G:R:x 4:4:4:4 little endian */
+
+#define GBM_FORMAT_ARGB4444 __gbm_fourcc_code('A', 'R', '1', '2') /* [15:0] A:R:G:B 4:4:4:4 little endian */
+#define GBM_FORMAT_ABGR4444 __gbm_fourcc_code('A', 'B', '1', '2') /* [15:0] A:B:G:R 4:4:4:4 little endian */
+#define GBM_FORMAT_RGBA4444 __gbm_fourcc_code('R', 'A', '1', '2') /* [15:0] R:G:B:A 4:4:4:4 little endian */
+#define GBM_FORMAT_BGRA4444 __gbm_fourcc_code('B', 'A', '1', '2') /* [15:0] B:G:R:A 4:4:4:4 little endian */
+
+#define GBM_FORMAT_XRGB1555 __gbm_fourcc_code('X', 'R', '1', '5') /* [15:0] x:R:G:B 1:5:5:5 little endian */
+#define GBM_FORMAT_XBGR1555 __gbm_fourcc_code('X', 'B', '1', '5') /* [15:0] x:B:G:R 1:5:5:5 little endian */
+#define GBM_FORMAT_RGBX5551 __gbm_fourcc_code('R', 'X', '1', '5') /* [15:0] R:G:B:x 5:5:5:1 little endian */
+#define GBM_FORMAT_BGRX5551 __gbm_fourcc_code('B', 'X', '1', '5') /* [15:0] B:G:R:x 5:5:5:1 little endian */
+
+#define GBM_FORMAT_ARGB1555 __gbm_fourcc_code('A', 'R', '1', '5') /* [15:0] A:R:G:B 1:5:5:5 little endian */
+#define GBM_FORMAT_ABGR1555 __gbm_fourcc_code('A', 'B', '1', '5') /* [15:0] A:B:G:R 1:5:5:5 little endian */
+#define GBM_FORMAT_RGBA5551 __gbm_fourcc_code('R', 'A', '1', '5') /* [15:0] R:G:B:A 5:5:5:1 little endian */
+#define GBM_FORMAT_BGRA5551 __gbm_fourcc_code('B', 'A', '1', '5') /* [15:0] B:G:R:A 5:5:5:1 little endian */
+
+#define GBM_FORMAT_RGB565 __gbm_fourcc_code('R', 'G', '1', '6') /* [15:0] R:G:B 5:6:5 little endian */
+#define GBM_FORMAT_BGR565 __gbm_fourcc_code('B', 'G', '1', '6') /* [15:0] B:G:R 5:6:5 little endian */
+
+/* 24 bpp RGB */
+#define GBM_FORMAT_RGB888 __gbm_fourcc_code('R', 'G', '2', '4') /* [23:0] R:G:B little endian */
+#define GBM_FORMAT_BGR888 __gbm_fourcc_code('B', 'G', '2', '4') /* [23:0] B:G:R little endian */
+
+/* 32 bpp RGB */
+#define GBM_FORMAT_XRGB8888 __gbm_fourcc_code('X', 'R', '2', '4') /* [31:0] x:R:G:B 8:8:8:8 little endian */
+#define GBM_FORMAT_XBGR8888 __gbm_fourcc_code('X', 'B', '2', '4') /* [31:0] x:B:G:R 8:8:8:8 little endian */
+#define GBM_FORMAT_RGBX8888 __gbm_fourcc_code('R', 'X', '2', '4') /* [31:0] R:G:B:x 8:8:8:8 little endian */
+#define GBM_FORMAT_BGRX8888 __gbm_fourcc_code('B', 'X', '2', '4') /* [31:0] B:G:R:x 8:8:8:8 little endian */
+
+#define GBM_FORMAT_ARGB8888 __gbm_fourcc_code('A', 'R', '2', '4') /* [31:0] A:R:G:B 8:8:8:8 little endian */
+#define GBM_FORMAT_ABGR8888 __gbm_fourcc_code('A', 'B', '2', '4') /* [31:0] A:B:G:R 8:8:8:8 little endian */
+#define GBM_FORMAT_RGBA8888 __gbm_fourcc_code('R', 'A', '2', '4') /* [31:0] R:G:B:A 8:8:8:8 little endian */
+#define GBM_FORMAT_BGRA8888 __gbm_fourcc_code('B', 'A', '2', '4') /* [31:0] B:G:R:A 8:8:8:8 little endian */
+
+#define GBM_FORMAT_XRGB2101010 __gbm_fourcc_code('X', 'R', '3', '0') /* [31:0] x:R:G:B 2:10:10:10 little endian */
+#define GBM_FORMAT_XBGR2101010 __gbm_fourcc_code('X', 'B', '3', '0') /* [31:0] x:B:G:R 2:10:10:10 little endian */
+#define GBM_FORMAT_RGBX1010102 __gbm_fourcc_code('R', 'X', '3', '0') /* [31:0] R:G:B:x 10:10:10:2 little endian */
+#define GBM_FORMAT_BGRX1010102 __gbm_fourcc_code('B', 'X', '3', '0') /* [31:0] B:G:R:x 10:10:10:2 little endian */
+
+#define GBM_FORMAT_ARGB2101010 __gbm_fourcc_code('A', 'R', '3', '0') /* [31:0] A:R:G:B 2:10:10:10 little endian */
+#define GBM_FORMAT_ABGR2101010 __gbm_fourcc_code('A', 'B', '3', '0') /* [31:0] A:B:G:R 2:10:10:10 little endian */
+#define GBM_FORMAT_RGBA1010102 __gbm_fourcc_code('R', 'A', '3', '0') /* [31:0] R:G:B:A 10:10:10:2 little endian */
+#define GBM_FORMAT_BGRA1010102 __gbm_fourcc_code('B', 'A', '3', '0') /* [31:0] B:G:R:A 10:10:10:2 little endian */
+
+/* packed YCbCr */
+#define GBM_FORMAT_YUYV __gbm_fourcc_code('Y', 'U', 'Y', 'V') /* [31:0] Cr0:Y1:Cb0:Y0 8:8:8:8 little endian */
+#define GBM_FORMAT_YVYU __gbm_fourcc_code('Y', 'V', 'Y', 'U') /* [31:0] Cb0:Y1:Cr0:Y0 8:8:8:8 little endian */
+#define GBM_FORMAT_UYVY __gbm_fourcc_code('U', 'Y', 'V', 'Y') /* [31:0] Y1:Cr0:Y0:Cb0 8:8:8:8 little endian */
+#define GBM_FORMAT_VYUY __gbm_fourcc_code('V', 'Y', 'U', 'Y') /* [31:0] Y1:Cb0:Y0:Cr0 8:8:8:8 little endian */
+
+#define GBM_FORMAT_AYUV __gbm_fourcc_code('A', 'Y', 'U', 'V') /* [31:0] A:Y:Cb:Cr 8:8:8:8 little endian */
+
+/*
+ * 2 plane YCbCr
+ * index 0 = Y plane, [7:0] Y
+ * index 1 = Cr:Cb plane, [15:0] Cr:Cb little endian
+ * or
+ * index 1 = Cb:Cr plane, [15:0] Cb:Cr little endian
+ */
+#define GBM_FORMAT_NV12 __gbm_fourcc_code('N', 'V', '1', '2') /* 2x2 subsampled Cr:Cb plane */
+#define GBM_FORMAT_NV21 __gbm_fourcc_code('N', 'V', '2', '1') /* 2x2 subsampled Cb:Cr plane */
+#define GBM_FORMAT_NV16 __gbm_fourcc_code('N', 'V', '1', '6') /* 2x1 subsampled Cr:Cb plane */
+#define GBM_FORMAT_NV61 __gbm_fourcc_code('N', 'V', '6', '1') /* 2x1 subsampled Cb:Cr plane */
+
+/*
+ * 3 plane YCbCr
+ * index 0: Y plane, [7:0] Y
+ * index 1: Cb plane, [7:0] Cb
+ * index 2: Cr plane, [7:0] Cr
+ * or
+ * index 1: Cr plane, [7:0] Cr
+ * index 2: Cb plane, [7:0] Cb
+ */
+#define GBM_FORMAT_YUV410 __gbm_fourcc_code('Y', 'U', 'V', '9') /* 4x4 subsampled Cb (1) and Cr (2) planes */
+#define GBM_FORMAT_YVU410 __gbm_fourcc_code('Y', 'V', 'U', '9') /* 4x4 subsampled Cr (1) and Cb (2) planes */
+#define GBM_FORMAT_YUV411 __gbm_fourcc_code('Y', 'U', '1', '1') /* 4x1 subsampled Cb (1) and Cr (2) planes */
+#define GBM_FORMAT_YVU411 __gbm_fourcc_code('Y', 'V', '1', '1') /* 4x1 subsampled Cr (1) and Cb (2) planes */
+#define GBM_FORMAT_YUV420 __gbm_fourcc_code('Y', 'U', '1', '2') /* 2x2 subsampled Cb (1) and Cr (2) planes */
+#define GBM_FORMAT_YVU420 __gbm_fourcc_code('Y', 'V', '1', '2') /* 2x2 subsampled Cr (1) and Cb (2) planes */
+#define GBM_FORMAT_YUV422 __gbm_fourcc_code('Y', 'U', '1', '6') /* 2x1 subsampled Cb (1) and Cr (2) planes */
+#define GBM_FORMAT_YVU422 __gbm_fourcc_code('Y', 'V', '1', '6') /* 2x1 subsampled Cr (1) and Cb (2) planes */
+#define GBM_FORMAT_YUV444 __gbm_fourcc_code('Y', 'U', '2', '4') /* non-subsampled Cb (1) and Cr (2) planes */
+#define GBM_FORMAT_YVU444 __gbm_fourcc_code('Y', 'V', '2', '4') /* non-subsampled Cr (1) and Cb (2) planes */
+
+
+/**
+ * Flags to indicate the intended use for the buffer - these are passed into
+ * gbm_bo_create(). The caller must set the union of all the flags that are
+ * appropriate
+ *
+ * \sa Use gbm_device_is_format_supported() to check if the combination of format
+ * and use flags are supported
+ */
+enum gbm_bo_flags {
+ /**
+ * Buffer is going to be presented to the screen using an API such as KMS
+ */
+ GBM_BO_USE_SCANOUT = (1 << 0),
+ /**
+ * Buffer is going to be used as cursor
+ */
+ GBM_BO_USE_CURSOR = (1 << 1),
+ /**
+ * Deprecated
+ */
+ GBM_BO_USE_CURSOR_64X64 = GBM_BO_USE_CURSOR,
+ /**
+ * Buffer is to be used for rendering - for example it is going to be used
+ * as the storage for a color buffer
+ */
+ GBM_BO_USE_RENDERING = (1 << 2),
+ /**
+ * Buffer can be used for gbm_bo_write. This is guaranteed to work
+ * with GBM_BO_USE_CURSOR, but may not work for other combinations.
+ */
+ GBM_BO_USE_WRITE = (1 << 3),
+ /**
+ * Buffer is linear, i.e. not tiled.
+ */
+ GBM_BO_USE_LINEAR = (1 << 4),
+};
+
+int
+gbm_device_get_fd(struct gbm_device *gbm);
+
+const char *
+gbm_device_get_backend_name(struct gbm_device *gbm);
+
+int
+gbm_device_is_format_supported(struct gbm_device *gbm,
+ uint32_t format, uint32_t usage);
+
+int
+gbm_device_get_format_modifier_plane_count(struct gbm_device *gbm,
+ uint32_t format,
+ uint64_t modifier);
+
+void
+gbm_device_destroy(struct gbm_device *gbm);
+
+struct gbm_device *
+gbm_create_device(int fd);
+
+struct gbm_bo *
+gbm_bo_create(struct gbm_device *gbm,
+ uint32_t width, uint32_t height,
+ uint32_t format, uint32_t flags);
+
+struct gbm_bo *
+gbm_bo_create_with_modifiers(struct gbm_device *gbm,
+ uint32_t width, uint32_t height,
+ uint32_t format,
+ const uint64_t *modifiers,
+ const unsigned int count);
+#define GBM_BO_IMPORT_WL_BUFFER 0x5501
+#define GBM_BO_IMPORT_EGL_IMAGE 0x5502
+#define GBM_BO_IMPORT_FD 0x5503
+#define GBM_BO_IMPORT_FD_MODIFIER 0x5504
+
+struct gbm_import_fd_data {
+ int fd;
+ uint32_t width;
+ uint32_t height;
+ uint32_t stride;
+ uint32_t format;
+};
+
+struct gbm_import_fd_modifier_data {
+ uint32_t width;
+ uint32_t height;
+ uint32_t format;
+ uint32_t num_fds;
+ int fds[4];
+ int strides[4];
+ int offsets[4];
+ uint64_t modifier;
+};
+
+struct gbm_bo *
+gbm_bo_import(struct gbm_device *gbm, uint32_t type,
+ void *buffer, uint32_t usage);
+
+/**
+ * Flags to indicate the type of mapping for the buffer - these are
+ * passed into gbm_bo_map(). The caller must set the union of all the
+ * flags that are appropriate.
+ *
+ * These flags are independent of the GBM_BO_USE_* creation flags. However,
+ * mapping the buffer may require copying to/from a staging buffer.
+ *
+ * See also: pipe_transfer_usage
+ */
+enum gbm_bo_transfer_flags {
+ /**
+ * Buffer contents read back (or accessed directly) at transfer
+ * create time.
+ */
+ GBM_BO_TRANSFER_READ = (1 << 0),
+ /**
+ * Buffer contents will be written back at unmap time
+ * (or modified as a result of being accessed directly).
+ */
+ GBM_BO_TRANSFER_WRITE = (1 << 1),
+ /**
+ * Read/modify/write
+ */
+ GBM_BO_TRANSFER_READ_WRITE = (GBM_BO_TRANSFER_READ | GBM_BO_TRANSFER_WRITE),
+};
+
+void *
+gbm_bo_map(struct gbm_bo *bo,
+ uint32_t x, uint32_t y, uint32_t width, uint32_t height,
+ uint32_t flags, uint32_t *stride, void **map_data);
+
+void
+gbm_bo_unmap(struct gbm_bo *bo, void *map_data);
+
+uint32_t
+gbm_bo_get_width(struct gbm_bo *bo);
+
+uint32_t
+gbm_bo_get_height(struct gbm_bo *bo);
+
+uint32_t
+gbm_bo_get_stride(struct gbm_bo *bo);
+
+uint32_t
+gbm_bo_get_stride_for_plane(struct gbm_bo *bo, int plane);
+
+uint32_t
+gbm_bo_get_format(struct gbm_bo *bo);
+
+uint32_t
+gbm_bo_get_bpp(struct gbm_bo *bo);
+
+uint32_t
+gbm_bo_get_offset(struct gbm_bo *bo, int plane);
+
+struct gbm_device *
+gbm_bo_get_device(struct gbm_bo *bo);
+
+union gbm_bo_handle
+gbm_bo_get_handle(struct gbm_bo *bo);
+
+int
+gbm_bo_get_fd(struct gbm_bo *bo);
+
+uint64_t
+gbm_bo_get_modifier(struct gbm_bo *bo);
+
+int
+gbm_bo_get_plane_count(struct gbm_bo *bo);
+
+union gbm_bo_handle
+gbm_bo_get_handle_for_plane(struct gbm_bo *bo, int plane);
+
+int
+gbm_bo_write(struct gbm_bo *bo, const void *buf, size_t count);
+
+void
+gbm_bo_set_user_data(struct gbm_bo *bo, void *data,
+ void (*destroy_user_data)(struct gbm_bo *, void *));
+
+void *
+gbm_bo_get_user_data(struct gbm_bo *bo);
+
+void
+gbm_bo_destroy(struct gbm_bo *bo);
+
+struct gbm_surface *
+gbm_surface_create(struct gbm_device *gbm,
+ uint32_t width, uint32_t height,
+ uint32_t format, uint32_t flags);
+
+struct gbm_surface *
+gbm_surface_create_with_modifiers(struct gbm_device *gbm,
+ uint32_t width, uint32_t height,
+ uint32_t format,
+ const uint64_t *modifiers,
+ const unsigned int count);
+
+struct gbm_bo *
+gbm_surface_lock_front_buffer(struct gbm_surface *surface);
+
+void
+gbm_surface_release_buffer(struct gbm_surface *surface, struct gbm_bo *bo);
+
+int
+gbm_surface_has_free_buffers(struct gbm_surface *surface);
+
+void
+gbm_surface_destroy(struct gbm_surface *surface);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/make/stub_includes/drm/xf86drm.h b/make/stub_includes/drm/xf86drm.h
new file mode 100644
index 000000000..ee09ce23f
--- /dev/null
+++ b/make/stub_includes/drm/xf86drm.h
@@ -0,0 +1,883 @@
+/**
+ * \file xf86drm.h
+ * OS-independent header for DRM user-level library interface.
+ *
+ * \author Rickard E. (Rik) Faith <[email protected]>
+ */
+
+/*
+ * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef _XF86DRM_H_
+#define _XF86DRM_H_
+
+#include <stdarg.h>
+#include <sys/types.h>
+#include <stdint.h>
+#include <drm.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#ifndef DRM_MAX_MINOR
+#define DRM_MAX_MINOR 16
+#endif
+
+#if defined(__linux__)
+
+#define DRM_IOCTL_NR(n) _IOC_NR(n)
+#define DRM_IOC_VOID _IOC_NONE
+#define DRM_IOC_READ _IOC_READ
+#define DRM_IOC_WRITE _IOC_WRITE
+#define DRM_IOC_READWRITE _IOC_READ|_IOC_WRITE
+#define DRM_IOC(dir, group, nr, size) _IOC(dir, group, nr, size)
+
+#else /* One of the *BSDs */
+
+#include <sys/ioccom.h>
+#define DRM_IOCTL_NR(n) ((n) & 0xff)
+#define DRM_IOC_VOID IOC_VOID
+#define DRM_IOC_READ IOC_OUT
+#define DRM_IOC_WRITE IOC_IN
+#define DRM_IOC_READWRITE IOC_INOUT
+#define DRM_IOC(dir, group, nr, size) _IOC(dir, group, nr, size)
+
+#endif
+
+ /* Defaults, if nothing set in xf86config */
+#define DRM_DEV_UID 0
+#define DRM_DEV_GID 0
+/* Default /dev/dri directory permissions 0755 */
+#define DRM_DEV_DIRMODE \
+ (S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH)
+#define DRM_DEV_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)
+
+#ifdef __OpenBSD__
+#define DRM_DIR_NAME "/dev"
+#define DRM_DEV_NAME "%s/drm%d"
+#define DRM_CONTROL_DEV_NAME "%s/drmC%d"
+#define DRM_RENDER_DEV_NAME "%s/drmR%d"
+#else
+#define DRM_DIR_NAME "/dev/dri"
+#define DRM_DEV_NAME "%s/card%d"
+#define DRM_CONTROL_DEV_NAME "%s/controlD%d"
+#define DRM_RENDER_DEV_NAME "%s/renderD%d"
+#define DRM_PROC_NAME "/proc/dri/" /* For backward Linux compatibility */
+#endif
+
+#define DRM_ERR_NO_DEVICE (-1001)
+#define DRM_ERR_NO_ACCESS (-1002)
+#define DRM_ERR_NOT_ROOT (-1003)
+#define DRM_ERR_INVALID (-1004)
+#define DRM_ERR_NO_FD (-1005)
+
+#define DRM_AGP_NO_HANDLE 0
+
+typedef unsigned int drmSize, *drmSizePtr; /**< For mapped regions */
+typedef void *drmAddress, **drmAddressPtr; /**< For mapped regions */
+
+#if (__GNUC__ >= 3)
+#define DRM_PRINTFLIKE(f, a) __attribute__ ((format(__printf__, f, a)))
+#else
+#define DRM_PRINTFLIKE(f, a)
+#endif
+
+typedef struct _drmServerInfo {
+ int (*debug_print)(const char *format, va_list ap) DRM_PRINTFLIKE(1,0);
+ int (*load_module)(const char *name);
+ void (*get_perms)(gid_t *, mode_t *);
+} drmServerInfo, *drmServerInfoPtr;
+
+typedef struct drmHashEntry {
+ int fd;
+ void (*f)(int, void *, void *);
+ void *tagTable;
+} drmHashEntry;
+
+extern int drmIoctl(int fd, unsigned long request, void *arg);
+extern void *drmGetHashTable(void);
+extern drmHashEntry *drmGetEntry(int fd);
+
+/**
+ * Driver version information.
+ *
+ * \sa drmGetVersion() and drmSetVersion().
+ */
+typedef struct _drmVersion {
+ int version_major; /**< Major version */
+ int version_minor; /**< Minor version */
+ int version_patchlevel; /**< Patch level */
+ int name_len; /**< Length of name buffer */
+ char *name; /**< Name of driver */
+ int date_len; /**< Length of date buffer */
+ char *date; /**< User-space buffer to hold date */
+ int desc_len; /**< Length of desc buffer */
+ char *desc; /**< User-space buffer to hold desc */
+} drmVersion, *drmVersionPtr;
+
+typedef struct _drmStats {
+ unsigned long count; /**< Number of data */
+ struct {
+ unsigned long value; /**< Value from kernel */
+ const char *long_format; /**< Suggested format for long_name */
+ const char *long_name; /**< Long name for value */
+ const char *rate_format; /**< Suggested format for rate_name */
+ const char *rate_name; /**< Short name for value per second */
+ int isvalue; /**< True if value (vs. counter) */
+ const char *mult_names; /**< Multiplier names (e.g., "KGM") */
+ int mult; /**< Multiplier value (e.g., 1024) */
+ int verbose; /**< Suggest only in verbose output */
+ } data[15];
+} drmStatsT;
+
+
+ /* All of these enums *MUST* match with the
+ kernel implementation -- so do *NOT*
+ change them! (The drmlib implementation
+ will just copy the flags instead of
+ translating them.) */
+typedef enum {
+ DRM_FRAME_BUFFER = 0, /**< WC, no caching, no core dump */
+ DRM_REGISTERS = 1, /**< no caching, no core dump */
+ DRM_SHM = 2, /**< shared, cached */
+ DRM_AGP = 3, /**< AGP/GART */
+ DRM_SCATTER_GATHER = 4, /**< PCI scatter/gather */
+ DRM_CONSISTENT = 5 /**< PCI consistent */
+} drmMapType;
+
+typedef enum {
+ DRM_RESTRICTED = 0x0001, /**< Cannot be mapped to client-virtual */
+ DRM_READ_ONLY = 0x0002, /**< Read-only in client-virtual */
+ DRM_LOCKED = 0x0004, /**< Physical pages locked */
+ DRM_KERNEL = 0x0008, /**< Kernel requires access */
+ DRM_WRITE_COMBINING = 0x0010, /**< Use write-combining, if available */
+ DRM_CONTAINS_LOCK = 0x0020, /**< SHM page that contains lock */
+ DRM_REMOVABLE = 0x0040 /**< Removable mapping */
+} drmMapFlags;
+
+/**
+ * \warning These values *MUST* match drm.h
+ */
+typedef enum {
+ /** \name Flags for DMA buffer dispatch */
+ /*@{*/
+ DRM_DMA_BLOCK = 0x01, /**<
+ * Block until buffer dispatched.
+ *
+ * \note the buffer may not yet have been
+ * processed by the hardware -- getting a
+ * hardware lock with the hardware quiescent
+ * will ensure that the buffer has been
+ * processed.
+ */
+ DRM_DMA_WHILE_LOCKED = 0x02, /**< Dispatch while lock held */
+ DRM_DMA_PRIORITY = 0x04, /**< High priority dispatch */
+ /*@}*/
+
+ /** \name Flags for DMA buffer request */
+ /*@{*/
+ DRM_DMA_WAIT = 0x10, /**< Wait for free buffers */
+ DRM_DMA_SMALLER_OK = 0x20, /**< Smaller-than-requested buffers OK */
+ DRM_DMA_LARGER_OK = 0x40 /**< Larger-than-requested buffers OK */
+ /*@}*/
+} drmDMAFlags;
+
+typedef enum {
+ DRM_PAGE_ALIGN = 0x01,
+ DRM_AGP_BUFFER = 0x02,
+ DRM_SG_BUFFER = 0x04,
+ DRM_FB_BUFFER = 0x08,
+ DRM_PCI_BUFFER_RO = 0x10
+} drmBufDescFlags;
+
+typedef enum {
+ DRM_LOCK_READY = 0x01, /**< Wait until hardware is ready for DMA */
+ DRM_LOCK_QUIESCENT = 0x02, /**< Wait until hardware quiescent */
+ DRM_LOCK_FLUSH = 0x04, /**< Flush this context's DMA queue first */
+ DRM_LOCK_FLUSH_ALL = 0x08, /**< Flush all DMA queues first */
+ /* These *HALT* flags aren't supported yet
+ -- they will be used to support the
+ full-screen DGA-like mode. */
+ DRM_HALT_ALL_QUEUES = 0x10, /**< Halt all current and future queues */
+ DRM_HALT_CUR_QUEUES = 0x20 /**< Halt all current queues */
+} drmLockFlags;
+
+typedef enum {
+ DRM_CONTEXT_PRESERVED = 0x01, /**< This context is preserved and
+ never swapped. */
+ DRM_CONTEXT_2DONLY = 0x02 /**< This context is for 2D rendering only. */
+} drm_context_tFlags, *drm_context_tFlagsPtr;
+
+typedef struct _drmBufDesc {
+ int count; /**< Number of buffers of this size */
+ int size; /**< Size in bytes */
+ int low_mark; /**< Low water mark */
+ int high_mark; /**< High water mark */
+} drmBufDesc, *drmBufDescPtr;
+
+typedef struct _drmBufInfo {
+ int count; /**< Number of buffers described in list */
+ drmBufDescPtr list; /**< List of buffer descriptions */
+} drmBufInfo, *drmBufInfoPtr;
+
+typedef struct _drmBuf {
+ int idx; /**< Index into the master buffer list */
+ int total; /**< Buffer size */
+ int used; /**< Amount of buffer in use (for DMA) */
+ drmAddress address; /**< Address */
+} drmBuf, *drmBufPtr;
+
+/**
+ * Buffer mapping information.
+ *
+ * Used by drmMapBufs() and drmUnmapBufs() to store information about the
+ * mapped buffers.
+ */
+typedef struct _drmBufMap {
+ int count; /**< Number of buffers mapped */
+ drmBufPtr list; /**< Buffers */
+} drmBufMap, *drmBufMapPtr;
+
+typedef struct _drmLock {
+ volatile unsigned int lock;
+ char padding[60];
+ /* This is big enough for most current (and future?) architectures:
+ DEC Alpha: 32 bytes
+ Intel Merced: ?
+ Intel P5/PPro/PII/PIII: 32 bytes
+ Intel StrongARM: 32 bytes
+ Intel i386/i486: 16 bytes
+ MIPS: 32 bytes (?)
+ Motorola 68k: 16 bytes
+ Motorola PowerPC: 32 bytes
+ Sun SPARC: 32 bytes
+ */
+} drmLock, *drmLockPtr;
+
+/**
+ * Indices here refer to the offset into
+ * list in drmBufInfo
+ */
+typedef struct _drmDMAReq {
+ drm_context_t context; /**< Context handle */
+ int send_count; /**< Number of buffers to send */
+ int *send_list; /**< List of handles to buffers */
+ int *send_sizes; /**< Lengths of data to send, in bytes */
+ drmDMAFlags flags; /**< Flags */
+ int request_count; /**< Number of buffers requested */
+ int request_size; /**< Desired size of buffers requested */
+ int *request_list; /**< Buffer information */
+ int *request_sizes; /**< Minimum acceptable sizes */
+ int granted_count; /**< Number of buffers granted at this size */
+} drmDMAReq, *drmDMAReqPtr;
+
+typedef struct _drmRegion {
+ drm_handle_t handle;
+ unsigned int offset;
+ drmSize size;
+ drmAddress map;
+} drmRegion, *drmRegionPtr;
+
+typedef struct _drmTextureRegion {
+ unsigned char next;
+ unsigned char prev;
+ unsigned char in_use;
+ unsigned char padding; /**< Explicitly pad this out */
+ unsigned int age;
+} drmTextureRegion, *drmTextureRegionPtr;
+
+
+typedef enum {
+ DRM_VBLANK_ABSOLUTE = 0x0, /**< Wait for specific vblank sequence number */
+ DRM_VBLANK_RELATIVE = 0x1, /**< Wait for given number of vblanks */
+ /* bits 1-6 are reserved for high crtcs */
+ DRM_VBLANK_HIGH_CRTC_MASK = 0x0000003e,
+ DRM_VBLANK_EVENT = 0x4000000, /**< Send event instead of blocking */
+ DRM_VBLANK_FLIP = 0x8000000, /**< Scheduled buffer swap should flip */
+ DRM_VBLANK_NEXTONMISS = 0x10000000, /**< If missed, wait for next vblank */
+ DRM_VBLANK_SECONDARY = 0x20000000, /**< Secondary display controller */
+ DRM_VBLANK_SIGNAL = 0x40000000 /* Send signal instead of blocking */
+} drmVBlankSeqType;
+#define DRM_VBLANK_HIGH_CRTC_SHIFT 1
+
+typedef struct _drmVBlankReq {
+ drmVBlankSeqType type;
+ unsigned int sequence;
+ unsigned long signal;
+} drmVBlankReq, *drmVBlankReqPtr;
+
+typedef struct _drmVBlankReply {
+ drmVBlankSeqType type;
+ unsigned int sequence;
+ long tval_sec;
+ long tval_usec;
+} drmVBlankReply, *drmVBlankReplyPtr;
+
+typedef union _drmVBlank {
+ drmVBlankReq request;
+ drmVBlankReply reply;
+} drmVBlank, *drmVBlankPtr;
+
+typedef struct _drmSetVersion {
+ int drm_di_major;
+ int drm_di_minor;
+ int drm_dd_major;
+ int drm_dd_minor;
+} drmSetVersion, *drmSetVersionPtr;
+
+#define __drm_dummy_lock(lock) (*(__volatile__ unsigned int *)lock)
+
+#define DRM_LOCK_HELD 0x80000000U /**< Hardware lock is held */
+#define DRM_LOCK_CONT 0x40000000U /**< Hardware lock is contended */
+
+#if defined(__GNUC__) && (__GNUC__ >= 2)
+# if defined(__i386) || defined(__AMD64__) || defined(__x86_64__) || defined(__amd64__)
+ /* Reflect changes here to drmP.h */
+#define DRM_CAS(lock,old,new,__ret) \
+ do { \
+ int __dummy; /* Can't mark eax as clobbered */ \
+ __asm__ __volatile__( \
+ "lock ; cmpxchg %4,%1\n\t" \
+ "setnz %0" \
+ : "=d" (__ret), \
+ "=m" (__drm_dummy_lock(lock)), \
+ "=a" (__dummy) \
+ : "2" (old), \
+ "r" (new)); \
+ } while (0)
+
+#elif defined(__alpha__)
+
+#define DRM_CAS(lock, old, new, ret) \
+ do { \
+ int tmp, old32; \
+ __asm__ __volatile__( \
+ " addl $31, %5, %3\n" \
+ "1: ldl_l %0, %2\n" \
+ " cmpeq %0, %3, %1\n" \
+ " beq %1, 2f\n" \
+ " mov %4, %0\n" \
+ " stl_c %0, %2\n" \
+ " beq %0, 3f\n" \
+ " mb\n" \
+ "2: cmpeq %1, 0, %1\n" \
+ ".subsection 2\n" \
+ "3: br 1b\n" \
+ ".previous" \
+ : "=&r"(tmp), "=&r"(ret), \
+ "=m"(__drm_dummy_lock(lock)), \
+ "=&r"(old32) \
+ : "r"(new), "r"(old) \
+ : "memory"); \
+ } while (0)
+
+#elif defined(__sparc__)
+
+#define DRM_CAS(lock,old,new,__ret) \
+do { register unsigned int __old __asm("o0"); \
+ register unsigned int __new __asm("o1"); \
+ register volatile unsigned int *__lock __asm("o2"); \
+ __old = old; \
+ __new = new; \
+ __lock = (volatile unsigned int *)lock; \
+ __asm__ __volatile__( \
+ /*"cas [%2], %3, %0"*/ \
+ ".word 0xd3e29008\n\t" \
+ /*"membar #StoreStore | #StoreLoad"*/ \
+ ".word 0x8143e00a" \
+ : "=&r" (__new) \
+ : "0" (__new), \
+ "r" (__lock), \
+ "r" (__old) \
+ : "memory"); \
+ __ret = (__new != __old); \
+} while(0)
+
+#elif defined(__ia64__)
+
+#ifdef __INTEL_COMPILER
+/* this currently generates bad code (missing stop bits)... */
+#include <ia64intrin.h>
+
+#define DRM_CAS(lock,old,new,__ret) \
+ do { \
+ unsigned long __result, __old = (old) & 0xffffffff; \
+ __mf(); \
+ __result = _InterlockedCompareExchange_acq(&__drm_dummy_lock(lock), (new), __old);\
+ __ret = (__result) != (__old); \
+/* __ret = (__sync_val_compare_and_swap(&__drm_dummy_lock(lock), \
+ (old), (new)) \
+ != (old)); */\
+ } while (0)
+
+#else
+#define DRM_CAS(lock,old,new,__ret) \
+ do { \
+ unsigned int __result, __old = (old); \
+ __asm__ __volatile__( \
+ "mf\n" \
+ "mov ar.ccv=%2\n" \
+ ";;\n" \
+ "cmpxchg4.acq %0=%1,%3,ar.ccv" \
+ : "=r" (__result), "=m" (__drm_dummy_lock(lock)) \
+ : "r" ((unsigned long)__old), "r" (new) \
+ : "memory"); \
+ __ret = (__result) != (__old); \
+ } while (0)
+
+#endif
+
+#elif defined(__powerpc__)
+
+#define DRM_CAS(lock,old,new,__ret) \
+ do { \
+ __asm__ __volatile__( \
+ "sync;" \
+ "0: lwarx %0,0,%1;" \
+ " xor. %0,%3,%0;" \
+ " bne 1f;" \
+ " stwcx. %2,0,%1;" \
+ " bne- 0b;" \
+ "1: " \
+ "sync;" \
+ : "=&r"(__ret) \
+ : "r"(lock), "r"(new), "r"(old) \
+ : "cr0", "memory"); \
+ } while (0)
+
+#endif /* architecture */
+#endif /* __GNUC__ >= 2 */
+
+#ifndef DRM_CAS
+#define DRM_CAS(lock,old,new,ret) do { ret=1; } while (0) /* FAST LOCK FAILS */
+#endif
+
+#if defined(__alpha__)
+#define DRM_CAS_RESULT(_result) long _result
+#elif defined(__powerpc__)
+#define DRM_CAS_RESULT(_result) int _result
+#else
+#define DRM_CAS_RESULT(_result) char _result
+#endif
+
+#define DRM_LIGHT_LOCK(fd,lock,context) \
+ do { \
+ DRM_CAS_RESULT(__ret); \
+ DRM_CAS(lock,context,DRM_LOCK_HELD|context,__ret); \
+ if (__ret) drmGetLock(fd,context,0); \
+ } while(0)
+
+ /* This one counts fast locks -- for
+ benchmarking only. */
+#define DRM_LIGHT_LOCK_COUNT(fd,lock,context,count) \
+ do { \
+ DRM_CAS_RESULT(__ret); \
+ DRM_CAS(lock,context,DRM_LOCK_HELD|context,__ret); \
+ if (__ret) drmGetLock(fd,context,0); \
+ else ++count; \
+ } while(0)
+
+#define DRM_LOCK(fd,lock,context,flags) \
+ do { \
+ if (flags) drmGetLock(fd,context,flags); \
+ else DRM_LIGHT_LOCK(fd,lock,context); \
+ } while(0)
+
+#define DRM_UNLOCK(fd,lock,context) \
+ do { \
+ DRM_CAS_RESULT(__ret); \
+ DRM_CAS(lock,DRM_LOCK_HELD|context,context,__ret); \
+ if (__ret) drmUnlock(fd,context); \
+ } while(0)
+
+ /* Simple spin locks */
+#define DRM_SPINLOCK(spin,val) \
+ do { \
+ DRM_CAS_RESULT(__ret); \
+ do { \
+ DRM_CAS(spin,0,val,__ret); \
+ if (__ret) while ((spin)->lock); \
+ } while (__ret); \
+ } while(0)
+
+#define DRM_SPINLOCK_TAKE(spin,val) \
+ do { \
+ DRM_CAS_RESULT(__ret); \
+ int cur; \
+ do { \
+ cur = (*spin).lock; \
+ DRM_CAS(spin,cur,val,__ret); \
+ } while (__ret); \
+ } while(0)
+
+#define DRM_SPINLOCK_COUNT(spin,val,count,__ret) \
+ do { \
+ int __i; \
+ __ret = 1; \
+ for (__i = 0; __ret && __i < count; __i++) { \
+ DRM_CAS(spin,0,val,__ret); \
+ if (__ret) for (;__i < count && (spin)->lock; __i++); \
+ } \
+ } while(0)
+
+#define DRM_SPINUNLOCK(spin,val) \
+ do { \
+ DRM_CAS_RESULT(__ret); \
+ if ((*spin).lock == val) { /* else server stole lock */ \
+ do { \
+ DRM_CAS(spin,val,0,__ret); \
+ } while (__ret); \
+ } \
+ } while(0)
+
+
+
+/* General user-level programmer's API: unprivileged */
+extern int drmAvailable(void);
+extern int drmOpen(const char *name, const char *busid);
+
+#define DRM_NODE_PRIMARY 0
+#define DRM_NODE_CONTROL 1
+#define DRM_NODE_RENDER 2
+#define DRM_NODE_MAX 3
+
+extern int drmOpenWithType(const char *name, const char *busid,
+ int type);
+
+extern int drmOpenControl(int minor);
+extern int drmOpenRender(int minor);
+extern int drmClose(int fd);
+extern drmVersionPtr drmGetVersion(int fd);
+extern drmVersionPtr drmGetLibVersion(int fd);
+extern int drmGetCap(int fd, uint64_t capability, uint64_t *value);
+extern void drmFreeVersion(drmVersionPtr);
+extern int drmGetMagic(int fd, drm_magic_t * magic);
+extern char *drmGetBusid(int fd);
+extern int drmGetInterruptFromBusID(int fd, int busnum, int devnum,
+ int funcnum);
+extern int drmGetMap(int fd, int idx, drm_handle_t *offset,
+ drmSize *size, drmMapType *type,
+ drmMapFlags *flags, drm_handle_t *handle,
+ int *mtrr);
+extern int drmGetClient(int fd, int idx, int *auth, int *pid,
+ int *uid, unsigned long *magic,
+ unsigned long *iocs);
+extern int drmGetStats(int fd, drmStatsT *stats);
+extern int drmSetInterfaceVersion(int fd, drmSetVersion *version);
+extern int drmCommandNone(int fd, unsigned long drmCommandIndex);
+extern int drmCommandRead(int fd, unsigned long drmCommandIndex,
+ void *data, unsigned long size);
+extern int drmCommandWrite(int fd, unsigned long drmCommandIndex,
+ void *data, unsigned long size);
+extern int drmCommandWriteRead(int fd, unsigned long drmCommandIndex,
+ void *data, unsigned long size);
+
+/* General user-level programmer's API: X server (root) only */
+extern void drmFreeBusid(const char *busid);
+extern int drmSetBusid(int fd, const char *busid);
+extern int drmAuthMagic(int fd, drm_magic_t magic);
+extern int drmAddMap(int fd,
+ drm_handle_t offset,
+ drmSize size,
+ drmMapType type,
+ drmMapFlags flags,
+ drm_handle_t * handle);
+extern int drmRmMap(int fd, drm_handle_t handle);
+extern int drmAddContextPrivateMapping(int fd, drm_context_t ctx_id,
+ drm_handle_t handle);
+
+extern int drmAddBufs(int fd, int count, int size,
+ drmBufDescFlags flags,
+ int agp_offset);
+extern int drmMarkBufs(int fd, double low, double high);
+extern int drmCreateContext(int fd, drm_context_t * handle);
+extern int drmSetContextFlags(int fd, drm_context_t context,
+ drm_context_tFlags flags);
+extern int drmGetContextFlags(int fd, drm_context_t context,
+ drm_context_tFlagsPtr flags);
+extern int drmAddContextTag(int fd, drm_context_t context, void *tag);
+extern int drmDelContextTag(int fd, drm_context_t context);
+extern void *drmGetContextTag(int fd, drm_context_t context);
+extern drm_context_t * drmGetReservedContextList(int fd, int *count);
+extern void drmFreeReservedContextList(drm_context_t *);
+extern int drmSwitchToContext(int fd, drm_context_t context);
+extern int drmDestroyContext(int fd, drm_context_t handle);
+extern int drmCreateDrawable(int fd, drm_drawable_t * handle);
+extern int drmDestroyDrawable(int fd, drm_drawable_t handle);
+extern int drmUpdateDrawableInfo(int fd, drm_drawable_t handle,
+ drm_drawable_info_type_t type,
+ unsigned int num, void *data);
+extern int drmCtlInstHandler(int fd, int irq);
+extern int drmCtlUninstHandler(int fd);
+extern int drmSetClientCap(int fd, uint64_t capability,
+ uint64_t value);
+
+extern int drmCrtcGetSequence(int fd, uint32_t crtcId,
+ uint64_t *sequence, uint64_t *ns);
+extern int drmCrtcQueueSequence(int fd, uint32_t crtcId,
+ uint32_t flags, uint64_t sequence,
+ uint64_t *sequence_queued,
+ uint64_t user_data);
+/* General user-level programmer's API: authenticated client and/or X */
+extern int drmMap(int fd,
+ drm_handle_t handle,
+ drmSize size,
+ drmAddressPtr address);
+extern int drmUnmap(drmAddress address, drmSize size);
+extern drmBufInfoPtr drmGetBufInfo(int fd);
+extern drmBufMapPtr drmMapBufs(int fd);
+extern int drmUnmapBufs(drmBufMapPtr bufs);
+extern int drmDMA(int fd, drmDMAReqPtr request);
+extern int drmFreeBufs(int fd, int count, int *list);
+extern int drmGetLock(int fd,
+ drm_context_t context,
+ drmLockFlags flags);
+extern int drmUnlock(int fd, drm_context_t context);
+extern int drmFinish(int fd, int context, drmLockFlags flags);
+extern int drmGetContextPrivateMapping(int fd, drm_context_t ctx_id,
+ drm_handle_t * handle);
+
+/* AGP/GART support: X server (root) only */
+extern int drmAgpAcquire(int fd);
+extern int drmAgpRelease(int fd);
+extern int drmAgpEnable(int fd, unsigned long mode);
+extern int drmAgpAlloc(int fd, unsigned long size,
+ unsigned long type, unsigned long *address,
+ drm_handle_t *handle);
+extern int drmAgpFree(int fd, drm_handle_t handle);
+extern int drmAgpBind(int fd, drm_handle_t handle,
+ unsigned long offset);
+extern int drmAgpUnbind(int fd, drm_handle_t handle);
+
+/* AGP/GART info: authenticated client and/or X */
+extern int drmAgpVersionMajor(int fd);
+extern int drmAgpVersionMinor(int fd);
+extern unsigned long drmAgpGetMode(int fd);
+extern unsigned long drmAgpBase(int fd); /* Physical location */
+extern unsigned long drmAgpSize(int fd); /* Bytes */
+extern unsigned long drmAgpMemoryUsed(int fd);
+extern unsigned long drmAgpMemoryAvail(int fd);
+extern unsigned int drmAgpVendorId(int fd);
+extern unsigned int drmAgpDeviceId(int fd);
+
+/* PCI scatter/gather support: X server (root) only */
+extern int drmScatterGatherAlloc(int fd, unsigned long size,
+ drm_handle_t *handle);
+extern int drmScatterGatherFree(int fd, drm_handle_t handle);
+
+extern int drmWaitVBlank(int fd, drmVBlankPtr vbl);
+
+/* Support routines */
+extern void drmSetServerInfo(drmServerInfoPtr info);
+extern int drmError(int err, const char *label);
+extern void *drmMalloc(int size);
+extern void drmFree(void *pt);
+
+/* Hash table routines */
+extern void *drmHashCreate(void);
+extern int drmHashDestroy(void *t);
+extern int drmHashLookup(void *t, unsigned long key, void **value);
+extern int drmHashInsert(void *t, unsigned long key, void *value);
+extern int drmHashDelete(void *t, unsigned long key);
+extern int drmHashFirst(void *t, unsigned long *key, void **value);
+extern int drmHashNext(void *t, unsigned long *key, void **value);
+
+/* PRNG routines */
+extern void *drmRandomCreate(unsigned long seed);
+extern int drmRandomDestroy(void *state);
+extern unsigned long drmRandom(void *state);
+extern double drmRandomDouble(void *state);
+
+/* Skip list routines */
+
+extern void *drmSLCreate(void);
+extern int drmSLDestroy(void *l);
+extern int drmSLLookup(void *l, unsigned long key, void **value);
+extern int drmSLInsert(void *l, unsigned long key, void *value);
+extern int drmSLDelete(void *l, unsigned long key);
+extern int drmSLNext(void *l, unsigned long *key, void **value);
+extern int drmSLFirst(void *l, unsigned long *key, void **value);
+extern void drmSLDump(void *l);
+extern int drmSLLookupNeighbors(void *l, unsigned long key,
+ unsigned long *prev_key, void **prev_value,
+ unsigned long *next_key, void **next_value);
+
+extern int drmOpenOnce(void *unused, const char *BusID, int *newlyopened);
+extern int drmOpenOnceWithType(const char *BusID, int *newlyopened, int type);
+extern void drmCloseOnce(int fd);
+extern void drmMsg(const char *format, ...) DRM_PRINTFLIKE(1, 2);
+
+extern int drmSetMaster(int fd);
+extern int drmDropMaster(int fd);
+
+#define DRM_EVENT_CONTEXT_VERSION 4
+
+typedef struct _drmEventContext {
+
+ /* This struct is versioned so we can add more pointers if we
+ * add more events. */
+ int version;
+
+ void (*vblank_handler)(int fd,
+ unsigned int sequence,
+ unsigned int tv_sec,
+ unsigned int tv_usec,
+ void *user_data);
+
+ void (*page_flip_handler)(int fd,
+ unsigned int sequence,
+ unsigned int tv_sec,
+ unsigned int tv_usec,
+ void *user_data);
+
+ void (*page_flip_handler2)(int fd,
+ unsigned int sequence,
+ unsigned int tv_sec,
+ unsigned int tv_usec,
+ unsigned int crtc_id,
+ void *user_data);
+
+ void (*sequence_handler)(int fd,
+ uint64_t sequence,
+ uint64_t ns,
+ uint64_t user_data);
+} drmEventContext, *drmEventContextPtr;
+
+extern int drmHandleEvent(int fd, drmEventContextPtr evctx);
+
+extern char *drmGetDeviceNameFromFd(int fd);
+
+/* Improved version of drmGetDeviceNameFromFd which attributes for any type of
+ * device/node - card, control or renderD.
+ */
+extern char *drmGetDeviceNameFromFd2(int fd);
+extern int drmGetNodeTypeFromFd(int fd);
+
+extern int drmPrimeHandleToFD(int fd, uint32_t handle, uint32_t flags, int *prime_fd);
+extern int drmPrimeFDToHandle(int fd, int prime_fd, uint32_t *handle);
+
+extern char *drmGetPrimaryDeviceNameFromFd(int fd);
+extern char *drmGetRenderDeviceNameFromFd(int fd);
+
+#define DRM_BUS_PCI 0
+#define DRM_BUS_USB 1
+#define DRM_BUS_PLATFORM 2
+#define DRM_BUS_HOST1X 3
+
+typedef struct _drmPciBusInfo {
+ uint16_t domain;
+ uint8_t bus;
+ uint8_t dev;
+ uint8_t func;
+} drmPciBusInfo, *drmPciBusInfoPtr;
+
+typedef struct _drmPciDeviceInfo {
+ uint16_t vendor_id;
+ uint16_t device_id;
+ uint16_t subvendor_id;
+ uint16_t subdevice_id;
+ uint8_t revision_id;
+} drmPciDeviceInfo, *drmPciDeviceInfoPtr;
+
+typedef struct _drmUsbBusInfo {
+ uint8_t bus;
+ uint8_t dev;
+} drmUsbBusInfo, *drmUsbBusInfoPtr;
+
+typedef struct _drmUsbDeviceInfo {
+ uint16_t vendor;
+ uint16_t product;
+} drmUsbDeviceInfo, *drmUsbDeviceInfoPtr;
+
+#define DRM_PLATFORM_DEVICE_NAME_LEN 512
+
+typedef struct _drmPlatformBusInfo {
+ char fullname[DRM_PLATFORM_DEVICE_NAME_LEN];
+} drmPlatformBusInfo, *drmPlatformBusInfoPtr;
+
+typedef struct _drmPlatformDeviceInfo {
+ char **compatible; /* NULL terminated list of compatible strings */
+} drmPlatformDeviceInfo, *drmPlatformDeviceInfoPtr;
+
+#define DRM_HOST1X_DEVICE_NAME_LEN 512
+
+typedef struct _drmHost1xBusInfo {
+ char fullname[DRM_HOST1X_DEVICE_NAME_LEN];
+} drmHost1xBusInfo, *drmHost1xBusInfoPtr;
+
+typedef struct _drmHost1xDeviceInfo {
+ char **compatible; /* NULL terminated list of compatible strings */
+} drmHost1xDeviceInfo, *drmHost1xDeviceInfoPtr;
+
+typedef struct _drmDevice {
+ char **nodes; /* DRM_NODE_MAX sized array */
+ int available_nodes; /* DRM_NODE_* bitmask */
+ int bustype;
+ union {
+ drmPciBusInfoPtr pci;
+ drmUsbBusInfoPtr usb;
+ drmPlatformBusInfoPtr platform;
+ drmHost1xBusInfoPtr host1x;
+ } businfo;
+ union {
+ drmPciDeviceInfoPtr pci;
+ drmUsbDeviceInfoPtr usb;
+ drmPlatformDeviceInfoPtr platform;
+ drmHost1xDeviceInfoPtr host1x;
+ } deviceinfo;
+} drmDevice, *drmDevicePtr;
+
+extern int drmGetDevice(int fd, drmDevicePtr *device);
+extern void drmFreeDevice(drmDevicePtr *device);
+
+extern int drmGetDevices(drmDevicePtr devices[], int max_devices);
+extern void drmFreeDevices(drmDevicePtr devices[], int count);
+
+#define DRM_DEVICE_GET_PCI_REVISION (1 << 0)
+extern int drmGetDevice2(int fd, uint32_t flags, drmDevicePtr *device);
+extern int drmGetDevices2(uint32_t flags, drmDevicePtr devices[], int max_devices);
+
+extern int drmDevicesEqual(drmDevicePtr a, drmDevicePtr b);
+
+extern int drmSyncobjCreate(int fd, uint32_t flags, uint32_t *handle);
+extern int drmSyncobjDestroy(int fd, uint32_t handle);
+extern int drmSyncobjHandleToFD(int fd, uint32_t handle, int *obj_fd);
+extern int drmSyncobjFDToHandle(int fd, int obj_fd, uint32_t *handle);
+
+extern int drmSyncobjImportSyncFile(int fd, uint32_t handle, int sync_file_fd);
+extern int drmSyncobjExportSyncFile(int fd, uint32_t handle, int *sync_file_fd);
+extern int drmSyncobjWait(int fd, uint32_t *handles, unsigned num_handles,
+ int64_t timeout_nsec, unsigned flags,
+ uint32_t *first_signaled);
+extern int drmSyncobjReset(int fd, const uint32_t *handles, uint32_t handle_count);
+extern int drmSyncobjSignal(int fd, const uint32_t *handles, uint32_t handle_count);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
diff --git a/make/stub_includes/drm/xf86drmMode.h b/make/stub_includes/drm/xf86drmMode.h
new file mode 100644
index 000000000..1866afba0
--- /dev/null
+++ b/make/stub_includes/drm/xf86drmMode.h
@@ -0,0 +1,555 @@
+/*
+ * \file xf86drmMode.h
+ * Header for DRM modesetting interface.
+ *
+ * \author Jakob Bornecrantz <[email protected]>
+ *
+ * \par Acknowledgements:
+ * Feb 2007, Dave Airlie <[email protected]>
+ */
+
+/*
+ * Copyright (c) 2007-2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright (c) 2007-2008 Dave Airlie <[email protected]>
+ * Copyright (c) 2007-2008 Jakob Bornecrantz <[email protected]>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ */
+
+#ifndef _XF86DRMMODE_H_
+#define _XF86DRMMODE_H_
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#ifndef __GLUEGEN__
+
+#include <drm.h>
+
+#endif /* __GLUEGEN__ */
+
+/*
+ * This is the interface for modesetting for drm.
+ *
+ * In order to use this interface you must include either <stdint.h> or another
+ * header defining uint32_t, int32_t and uint16_t.
+ *
+ * It aims to provide a randr1.2 compatible interface for modesettings in the
+ * kernel, the interface is also ment to be used by libraries like EGL.
+ *
+ * More information can be found in randrproto.txt which can be found here:
+ * http://gitweb.freedesktop.org/?p=xorg/proto/randrproto.git
+ *
+ * There are some major diffrences to be noted. Unlike the randr1.2 proto you
+ * need to create the memory object of the framebuffer yourself with the ttm
+ * buffer object interface. This object needs to be pinned.
+ */
+
+/*
+ * If we pickup an old version of drm.h which doesn't include drm_mode.h
+ * we should redefine defines. This is so that builds doesn't breaks with
+ * new libdrm on old kernels.
+ */
+#ifndef _DRM_MODE_H
+
+#define DRM_DISPLAY_INFO_LEN 32
+#define DRM_CONNECTOR_NAME_LEN 32
+#define DRM_DISPLAY_MODE_LEN 32
+#define DRM_PROP_NAME_LEN 32
+
+#define DRM_MODE_TYPE_BUILTIN (1<<0)
+#define DRM_MODE_TYPE_CLOCK_C ((1<<1) | DRM_MODE_TYPE_BUILTIN)
+#define DRM_MODE_TYPE_CRTC_C ((1<<2) | DRM_MODE_TYPE_BUILTIN)
+#define DRM_MODE_TYPE_PREFERRED (1<<3)
+#define DRM_MODE_TYPE_DEFAULT (1<<4)
+#define DRM_MODE_TYPE_USERDEF (1<<5)
+#define DRM_MODE_TYPE_DRIVER (1<<6)
+
+/* Video mode flags */
+/* bit compatible with the xorg definitions. */
+#define DRM_MODE_FLAG_PHSYNC (1<<0)
+#define DRM_MODE_FLAG_NHSYNC (1<<1)
+#define DRM_MODE_FLAG_PVSYNC (1<<2)
+#define DRM_MODE_FLAG_NVSYNC (1<<3)
+#define DRM_MODE_FLAG_INTERLACE (1<<4)
+#define DRM_MODE_FLAG_DBLSCAN (1<<5)
+#define DRM_MODE_FLAG_CSYNC (1<<6)
+#define DRM_MODE_FLAG_PCSYNC (1<<7)
+#define DRM_MODE_FLAG_NCSYNC (1<<8)
+#define DRM_MODE_FLAG_HSKEW (1<<9) /* hskew provided */
+#define DRM_MODE_FLAG_BCAST (1<<10)
+#define DRM_MODE_FLAG_PIXMUX (1<<11)
+#define DRM_MODE_FLAG_DBLCLK (1<<12)
+#define DRM_MODE_FLAG_CLKDIV2 (1<<13)
+#define DRM_MODE_FLAG_3D_MASK (0x1f<<14)
+#define DRM_MODE_FLAG_3D_NONE (0<<14)
+#define DRM_MODE_FLAG_3D_FRAME_PACKING (1<<14)
+#define DRM_MODE_FLAG_3D_FIELD_ALTERNATIVE (2<<14)
+#define DRM_MODE_FLAG_3D_LINE_ALTERNATIVE (3<<14)
+#define DRM_MODE_FLAG_3D_SIDE_BY_SIDE_FULL (4<<14)
+#define DRM_MODE_FLAG_3D_L_DEPTH (5<<14)
+#define DRM_MODE_FLAG_3D_L_DEPTH_GFX_GFX_DEPTH (6<<14)
+#define DRM_MODE_FLAG_3D_TOP_AND_BOTTOM (7<<14)
+#define DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF (8<<14)
+
+/* DPMS flags */
+/* bit compatible with the xorg definitions. */
+#define DRM_MODE_DPMS_ON 0
+#define DRM_MODE_DPMS_STANDBY 1
+#define DRM_MODE_DPMS_SUSPEND 2
+#define DRM_MODE_DPMS_OFF 3
+
+/* Scaling mode options */
+#define DRM_MODE_SCALE_NON_GPU 0
+#define DRM_MODE_SCALE_FULLSCREEN 1
+#define DRM_MODE_SCALE_NO_SCALE 2
+#define DRM_MODE_SCALE_ASPECT 3
+
+/* Dithering mode options */
+#define DRM_MODE_DITHERING_OFF 0
+#define DRM_MODE_DITHERING_ON 1
+
+#define DRM_MODE_ENCODER_NONE 0
+#define DRM_MODE_ENCODER_DAC 1
+#define DRM_MODE_ENCODER_TMDS 2
+#define DRM_MODE_ENCODER_LVDS 3
+#define DRM_MODE_ENCODER_TVDAC 4
+#define DRM_MODE_ENCODER_VIRTUAL 5
+#define DRM_MODE_ENCODER_DSI 6
+#define DRM_MODE_ENCODER_DPMST 7
+#define DRM_MODE_ENCODER_DPI 8
+
+#define DRM_MODE_SUBCONNECTOR_Automatic 0
+#define DRM_MODE_SUBCONNECTOR_Unknown 0
+#define DRM_MODE_SUBCONNECTOR_DVID 3
+#define DRM_MODE_SUBCONNECTOR_DVIA 4
+#define DRM_MODE_SUBCONNECTOR_Composite 5
+#define DRM_MODE_SUBCONNECTOR_SVIDEO 6
+#define DRM_MODE_SUBCONNECTOR_Component 8
+#define DRM_MODE_SUBCONNECTOR_SCART 9
+
+#define DRM_MODE_CONNECTOR_Unknown 0
+#define DRM_MODE_CONNECTOR_VGA 1
+#define DRM_MODE_CONNECTOR_DVII 2
+#define DRM_MODE_CONNECTOR_DVID 3
+#define DRM_MODE_CONNECTOR_DVIA 4
+#define DRM_MODE_CONNECTOR_Composite 5
+#define DRM_MODE_CONNECTOR_SVIDEO 6
+#define DRM_MODE_CONNECTOR_LVDS 7
+#define DRM_MODE_CONNECTOR_Component 8
+#define DRM_MODE_CONNECTOR_9PinDIN 9
+#define DRM_MODE_CONNECTOR_DisplayPort 10
+#define DRM_MODE_CONNECTOR_HDMIA 11
+#define DRM_MODE_CONNECTOR_HDMIB 12
+#define DRM_MODE_CONNECTOR_TV 13
+#define DRM_MODE_CONNECTOR_eDP 14
+#define DRM_MODE_CONNECTOR_VIRTUAL 15
+#define DRM_MODE_CONNECTOR_DSI 16
+#define DRM_MODE_CONNECTOR_DPI 17
+
+#define DRM_MODE_PROP_PENDING (1<<0)
+#define DRM_MODE_PROP_RANGE (1<<1)
+#define DRM_MODE_PROP_IMMUTABLE (1<<2)
+#define DRM_MODE_PROP_ENUM (1<<3) /* enumerated type with text strings */
+#define DRM_MODE_PROP_BLOB (1<<4)
+
+#define DRM_MODE_CURSOR_BO (1<<0)
+#define DRM_MODE_CURSOR_MOVE (1<<1)
+
+#endif /* _DRM_MODE_H */
+
+
+/*
+ * Feature defines
+ *
+ * Just because these are defined doesn't mean that the kernel
+ * can do that feature, its just for new code vs old libdrm.
+ */
+#define DRM_MODE_FEATURE_KMS 1
+#define DRM_MODE_FEATURE_DIRTYFB 1
+
+
+typedef struct _drmModeRes {
+
+ int count_fbs;
+ uint32_t *fbs;
+
+ int count_crtcs;
+ uint32_t *crtcs;
+
+ int count_connectors;
+ uint32_t *connectors;
+
+ int count_encoders;
+ uint32_t *encoders;
+
+ uint32_t min_width, max_width;
+ uint32_t min_height, max_height;
+} drmModeRes, *drmModeResPtr;
+
+typedef struct _drmModeModeInfo {
+ uint32_t clock;
+ uint16_t hdisplay, hsync_start, hsync_end, htotal, hskew;
+ uint16_t vdisplay, vsync_start, vsync_end, vtotal, vscan;
+
+ uint32_t vrefresh;
+
+ uint32_t flags;
+ uint32_t type;
+ char name[DRM_DISPLAY_MODE_LEN];
+} drmModeModeInfo, *drmModeModeInfoPtr;
+
+typedef struct _drmModeFB {
+ uint32_t fb_id;
+ uint32_t width, height;
+ uint32_t pitch;
+ uint32_t bpp;
+ uint32_t depth;
+ /* driver specific handle */
+ uint32_t handle;
+} drmModeFB, *drmModeFBPtr;
+
+typedef struct drm_clip_rect drmModeClip, *drmModeClipPtr;
+
+typedef struct _drmModePropertyBlob {
+ uint32_t id;
+ uint32_t length;
+ void *data;
+} drmModePropertyBlobRes, *drmModePropertyBlobPtr;
+
+typedef struct _drmModeProperty {
+ uint32_t prop_id;
+ uint32_t flags;
+ char name[DRM_PROP_NAME_LEN];
+ int count_values;
+ uint64_t *values; /* store the blob lengths */
+ int count_enums;
+ struct drm_mode_property_enum *enums;
+ int count_blobs;
+ uint32_t *blob_ids; /* store the blob IDs */
+} drmModePropertyRes, *drmModePropertyPtr;
+
+static __inline int drm_property_type_is(drmModePropertyPtr property,
+ uint32_t type)
+{
+ /* instanceof for props.. handles extended type vs original types: */
+ if (property->flags & DRM_MODE_PROP_EXTENDED_TYPE)
+ return (property->flags & DRM_MODE_PROP_EXTENDED_TYPE) == type;
+ return property->flags & type;
+}
+
+typedef struct _drmModeCrtc {
+ uint32_t crtc_id;
+ uint32_t buffer_id; /**< FB id to connect to 0 = disconnect */
+
+ uint32_t x, y; /**< Position on the framebuffer */
+ uint32_t width, height;
+ int mode_valid;
+ drmModeModeInfo mode;
+
+ int gamma_size; /**< Number of gamma stops */
+
+} drmModeCrtc, *drmModeCrtcPtr;
+
+typedef struct _drmModeEncoder {
+ uint32_t encoder_id;
+ uint32_t encoder_type;
+ uint32_t crtc_id;
+ uint32_t possible_crtcs;
+ uint32_t possible_clones;
+} drmModeEncoder, *drmModeEncoderPtr;
+
+typedef enum {
+ DRM_MODE_CONNECTED = 1,
+ DRM_MODE_DISCONNECTED = 2,
+ DRM_MODE_UNKNOWNCONNECTION = 3
+} drmModeConnection;
+
+typedef enum {
+ DRM_MODE_SUBPIXEL_UNKNOWN = 1,
+ DRM_MODE_SUBPIXEL_HORIZONTAL_RGB = 2,
+ DRM_MODE_SUBPIXEL_HORIZONTAL_BGR = 3,
+ DRM_MODE_SUBPIXEL_VERTICAL_RGB = 4,
+ DRM_MODE_SUBPIXEL_VERTICAL_BGR = 5,
+ DRM_MODE_SUBPIXEL_NONE = 6
+} drmModeSubPixel;
+
+typedef struct _drmModeConnector {
+ uint32_t connector_id;
+ uint32_t encoder_id; /**< Encoder currently connected to */
+ uint32_t connector_type;
+ uint32_t connector_type_id;
+ drmModeConnection connection;
+ uint32_t mmWidth, mmHeight; /**< HxW in millimeters */
+ drmModeSubPixel subpixel;
+
+ int count_modes;
+ drmModeModeInfoPtr modes;
+
+ int count_props;
+ uint32_t *props; /**< List of property ids */
+ uint64_t *prop_values; /**< List of property values */
+
+ int count_encoders;
+ uint32_t *encoders; /**< List of encoder ids */
+} drmModeConnector, *drmModeConnectorPtr;
+
+#define DRM_PLANE_TYPE_OVERLAY 0
+#define DRM_PLANE_TYPE_PRIMARY 1
+#define DRM_PLANE_TYPE_CURSOR 2
+
+typedef struct _drmModeObjectProperties {
+ uint32_t count_props;
+ uint32_t *props;
+ uint64_t *prop_values;
+} drmModeObjectProperties, *drmModeObjectPropertiesPtr;
+
+typedef struct _drmModePlane {
+ uint32_t count_formats;
+ uint32_t *formats;
+ uint32_t plane_id;
+
+ uint32_t crtc_id;
+ uint32_t fb_id;
+
+ uint32_t crtc_x, crtc_y;
+ uint32_t x, y;
+
+ uint32_t possible_crtcs;
+ uint32_t gamma_size;
+} drmModePlane, *drmModePlanePtr;
+
+typedef struct _drmModePlaneRes {
+ uint32_t count_planes;
+ uint32_t *planes;
+} drmModePlaneRes, *drmModePlaneResPtr;
+
+extern void drmModeFreeModeInfo( drmModeModeInfoPtr ptr );
+extern void drmModeFreeResources( drmModeResPtr ptr );
+extern void drmModeFreeFB( drmModeFBPtr ptr );
+extern void drmModeFreeCrtc( drmModeCrtcPtr ptr );
+extern void drmModeFreeConnector( drmModeConnectorPtr ptr );
+extern void drmModeFreeEncoder( drmModeEncoderPtr ptr );
+extern void drmModeFreePlane( drmModePlanePtr ptr );
+extern void drmModeFreePlaneResources(drmModePlaneResPtr ptr);
+
+/**
+ * Retrives all of the resources associated with a card.
+ */
+extern drmModeResPtr drmModeGetResources(int fd);
+
+/*
+ * FrameBuffer manipulation.
+ */
+
+/**
+ * Retrive information about framebuffer bufferId
+ */
+extern drmModeFBPtr drmModeGetFB(int fd, uint32_t bufferId);
+
+/**
+ * Creates a new framebuffer with an buffer object as its scanout buffer.
+ */
+extern int drmModeAddFB(int fd, uint32_t width, uint32_t height, uint8_t depth,
+ uint8_t bpp, uint32_t pitch, uint32_t bo_handle,
+ uint32_t *buf_id);
+/* ...with a specific pixel format */
+extern int drmModeAddFB2(int fd, uint32_t width, uint32_t height,
+ uint32_t pixel_format, const uint32_t bo_handles[4],
+ const uint32_t pitches[4], const uint32_t offsets[4],
+ uint32_t *buf_id, uint32_t flags);
+
+/* ...with format modifiers */
+int drmModeAddFB2WithModifiers(int fd, uint32_t width, uint32_t height,
+ uint32_t pixel_format, const uint32_t bo_handles[4],
+ const uint32_t pitches[4], const uint32_t offsets[4],
+ const uint64_t modifier[4], uint32_t *buf_id,
+ uint32_t flags);
+
+/**
+ * Destroies the given framebuffer.
+ */
+extern int drmModeRmFB(int fd, uint32_t bufferId);
+
+/**
+ * Mark a region of a framebuffer as dirty.
+ */
+extern int drmModeDirtyFB(int fd, uint32_t bufferId,
+ drmModeClipPtr clips, uint32_t num_clips);
+
+
+/*
+ * Crtc functions
+ */
+
+/**
+ * Retrive information about the ctrt crtcId
+ */
+extern drmModeCrtcPtr drmModeGetCrtc(int fd, uint32_t crtcId);
+
+/**
+ * Set the mode on a crtc crtcId with the given mode modeId.
+ */
+int drmModeSetCrtc(int fd, uint32_t crtcId, uint32_t bufferId,
+ uint32_t x, uint32_t y, uint32_t *connectors, int count,
+ drmModeModeInfoPtr mode);
+
+/*
+ * Cursor functions
+ */
+
+/**
+ * Set the cursor on crtc
+ */
+int drmModeSetCursor(int fd, uint32_t crtcId, uint32_t bo_handle, uint32_t width, uint32_t height);
+
+int drmModeSetCursor2(int fd, uint32_t crtcId, uint32_t bo_handle, uint32_t width, uint32_t height, int32_t hot_x, int32_t hot_y);
+/**
+ * Move the cursor on crtc
+ */
+int drmModeMoveCursor(int fd, uint32_t crtcId, int x, int y);
+
+/**
+ * Encoder functions
+ */
+drmModeEncoderPtr drmModeGetEncoder(int fd, uint32_t encoder_id);
+
+/*
+ * Connector manipulation
+ */
+
+/**
+ * Retrieve all information about the connector connectorId. This will do a
+ * forced probe on the connector to retrieve remote information such as EDIDs
+ * from the display device.
+ */
+extern drmModeConnectorPtr drmModeGetConnector(int fd,
+ uint32_t connectorId);
+
+/**
+ * Retrieve current information, i.e the currently active mode and encoder,
+ * about the connector connectorId. This will not do any probing on the
+ * connector or remote device, and only reports what is currently known.
+ * For the complete set of modes and encoders associated with the connector
+ * use drmModeGetConnector() which will do a probe to determine any display
+ * link changes first.
+ */
+extern drmModeConnectorPtr drmModeGetConnectorCurrent(int fd,
+ uint32_t connector_id);
+
+/**
+ * Attaches the given mode to an connector.
+ */
+extern int drmModeAttachMode(int fd, uint32_t connectorId, drmModeModeInfoPtr mode_info);
+
+/**
+ * Detaches a mode from the connector
+ * must be unused, by the given mode.
+ */
+extern int drmModeDetachMode(int fd, uint32_t connectorId, drmModeModeInfoPtr mode_info);
+
+extern drmModePropertyPtr drmModeGetProperty(int fd, uint32_t propertyId);
+extern void drmModeFreeProperty(drmModePropertyPtr ptr);
+
+extern drmModePropertyBlobPtr drmModeGetPropertyBlob(int fd, uint32_t blob_id);
+extern void drmModeFreePropertyBlob(drmModePropertyBlobPtr ptr);
+extern int drmModeConnectorSetProperty(int fd, uint32_t connector_id, uint32_t property_id,
+ uint64_t value);
+extern int drmCheckModesettingSupported(const char *busid);
+
+extern int drmModeCrtcSetGamma(int fd, uint32_t crtc_id, uint32_t size,
+ uint16_t *red, uint16_t *green, uint16_t *blue);
+extern int drmModeCrtcGetGamma(int fd, uint32_t crtc_id, uint32_t size,
+ uint16_t *red, uint16_t *green, uint16_t *blue);
+extern int drmModePageFlip(int fd, uint32_t crtc_id, uint32_t fb_id,
+ uint32_t flags, void *user_data);
+extern int drmModePageFlipTarget(int fd, uint32_t crtc_id, uint32_t fb_id,
+ uint32_t flags, void *user_data,
+ uint32_t target_vblank);
+
+extern drmModePlaneResPtr drmModeGetPlaneResources(int fd);
+extern drmModePlanePtr drmModeGetPlane(int fd, uint32_t plane_id);
+extern int drmModeSetPlane(int fd, uint32_t plane_id, uint32_t crtc_id,
+ uint32_t fb_id, uint32_t flags,
+ int32_t crtc_x, int32_t crtc_y,
+ uint32_t crtc_w, uint32_t crtc_h,
+ uint32_t src_x, uint32_t src_y,
+ uint32_t src_w, uint32_t src_h);
+
+extern drmModeObjectPropertiesPtr drmModeObjectGetProperties(int fd,
+ uint32_t object_id,
+ uint32_t object_type);
+extern void drmModeFreeObjectProperties(drmModeObjectPropertiesPtr ptr);
+extern int drmModeObjectSetProperty(int fd, uint32_t object_id,
+ uint32_t object_type, uint32_t property_id,
+ uint64_t value);
+
+
+typedef struct _drmModeAtomicReq drmModeAtomicReq, *drmModeAtomicReqPtr;
+
+extern drmModeAtomicReqPtr drmModeAtomicAlloc(void);
+extern drmModeAtomicReqPtr drmModeAtomicDuplicate(drmModeAtomicReqPtr req);
+extern int drmModeAtomicMerge(drmModeAtomicReqPtr base,
+ drmModeAtomicReqPtr augment);
+extern void drmModeAtomicFree(drmModeAtomicReqPtr req);
+extern int drmModeAtomicGetCursor(drmModeAtomicReqPtr req);
+extern void drmModeAtomicSetCursor(drmModeAtomicReqPtr req, int cursor);
+extern int drmModeAtomicAddProperty(drmModeAtomicReqPtr req,
+ uint32_t object_id,
+ uint32_t property_id,
+ uint64_t value);
+extern int drmModeAtomicCommit(int fd,
+ drmModeAtomicReqPtr req,
+ uint32_t flags,
+ void *user_data);
+
+extern int drmModeCreatePropertyBlob(int fd, const void *data, size_t size,
+ uint32_t *id);
+extern int drmModeDestroyPropertyBlob(int fd, uint32_t id);
+
+/*
+ * DRM mode lease APIs. These create and manage new drm_masters with
+ * access to a subset of the available DRM resources
+ */
+
+extern int drmModeCreateLease(int fd, const uint32_t *objects, int num_objects, int flags, uint32_t *lessee_id);
+
+typedef struct drmModeLesseeList {
+ uint32_t count;
+ uint32_t lessees[0];
+} drmModeLesseeListRes, *drmModeLesseeListPtr;
+
+extern drmModeLesseeListPtr drmModeListLessees(int fd);
+
+typedef struct drmModeObjectList {
+ uint32_t count;
+ uint32_t objects[0];
+} drmModeObjectListRes, *drmModeObjectListPtr;
+
+extern drmModeObjectListPtr drmModeGetLease(int fd);
+
+extern int drmModeRevokeLease(int fd, uint32_t lessee_id);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java b/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java
index d5ab61e20..4dd09ebbd 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java
@@ -213,7 +213,7 @@ public class EGLDisplayUtil {
case NativeWindowFactory.TYPE_ANDROID:
eglPlatform = EGLExt.EGL_PLATFORM_ANDROID_KHR;
break;
- case NativeWindowFactory.TYPE_EGL_GBM:
+ case NativeWindowFactory.TYPE_DRM_GBM:
eglPlatform = EGLExt.EGL_PLATFORM_GBM_KHR; // same EGLExt.EGL_PLATFORM_GBM_MESA;
break;
case NativeWindowFactory.TYPE_WAYLAND:
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java
index 8c9656354..eda2610a4 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java
@@ -49,10 +49,13 @@ import com.jogamp.nativewindow.AbstractGraphicsScreen;
import com.jogamp.nativewindow.DefaultGraphicsScreen;
import com.jogamp.nativewindow.MutableSurface;
import com.jogamp.nativewindow.NativeSurface;
+import com.jogamp.nativewindow.NativeWindowException;
import com.jogamp.nativewindow.NativeWindowFactory;
import com.jogamp.nativewindow.ProxySurface;
import com.jogamp.nativewindow.UpstreamSurfaceHook;
+import com.jogamp.nativewindow.UpstreamSurfaceHookMutableSize;
import com.jogamp.nativewindow.VisualIDHolder;
+import com.jogamp.nativewindow.VisualIDHolder.VIDType;
import com.jogamp.opengl.GL;
import com.jogamp.opengl.GLCapabilities;
import com.jogamp.opengl.GLCapabilitiesChooser;
@@ -64,6 +67,9 @@ import com.jogamp.opengl.GLException;
import com.jogamp.opengl.GLProfile;
import jogamp.common.os.PlatformPropsImpl;
+import jogamp.nativewindow.drm.DRMLib;
+import jogamp.nativewindow.drm.DRMUtil;
+import jogamp.nativewindow.drm.GBMDummyUpstreamSurfaceHook;
import jogamp.opengl.Debug;
import jogamp.opengl.GLContextImpl;
import jogamp.opengl.GLContextImpl.MappedGLVersion;
@@ -100,6 +106,7 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
private static GLDynamicLookupHelper eglGLnDynamicLookupHelper = null;
private static boolean isANGLE = false;
private static boolean hasX11 = false;
+ private static boolean isDRM_GBM = false;
private static String defaultConnection = null;
private static EGLGraphicsDevice defaultDevice = null;
private static EGLFeatures defaultDeviceEGLFeatures = null;
@@ -205,6 +212,12 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
} else {
hasX11 = false;
}
+ if(NativeWindowFactory.TYPE_DRM_GBM == nwt) {
+ isDRM_GBM = true;
+ } else {
+ isDRM_GBM = false;
+ }
+
defaultConnection = NativeWindowFactory.getDefaultDisplayConnection(nwt);
/**
@@ -346,7 +359,13 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
// Note: defaultDevice.open() triggers eglInitialize(..) which crashed on Windows w/ Chrome/ANGLE, FF/ANGLE!
// Hence opening will happen later, eventually
- defaultDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(EGL.EGL_DEFAULT_DISPLAY, defaultConnection, AbstractGraphicsDevice.DEFAULT_UNIT);
+ final long nativeDisplayID;
+ if( isDRM_GBM ) { // Bug 1402 related and in case surfaceless is n/a
+ nativeDisplayID = DRMLib.gbm_create_device(DRMUtil.getDrmFd());
+ } else {
+ nativeDisplayID = EGL.EGL_DEFAULT_DISPLAY;
+ }
+ defaultDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(nativeDisplayID, defaultConnection, AbstractGraphicsDevice.DEFAULT_UNIT);
// Init shared resources off thread
// Will be released via ShutdownHook
@@ -379,6 +398,9 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
}
if(null != defaultDevice) {
+ if( isDRM_GBM ) { // Bug 1402 related and in case surfaceless is n/a
+ DRMLib.gbm_device_destroy(defaultDevice.getNativeDisplayID());
+ }
defaultDevice.close();
defaultDevice = null;
}
@@ -690,7 +712,7 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
System.err.println("EGLDrawableFactory.MapGLVersions: "+profileString+" ( "+majorVersion+" ), "+
"mapsADeviceToDefaultDevice "+mapsADeviceToDefaultDevice[0]+
" (useDefaultDevice "+useDefaultDevice+", defaultDeviceHasPBuffer "+defaultDeviceHasPBuffer+", hasDesktopFactory "+(null != desktopFactory)+
- ", isEGLGraphicsDevice "+(adevice instanceof EGLGraphicsDevice)+")");
+ ", isEGLGraphicsDevice "+(adevice instanceof EGLGraphicsDevice)+"), isDRM_GBM "+isDRM_GBM);
}
if( mapsADeviceToDefaultDevice[0] ) {
@@ -700,13 +722,16 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
final boolean defaultNoSurfacelessCtx = GLRendererQuirks.existStickyDeviceQuirk(defaultDevice, GLRendererQuirks.NoSurfacelessCtx);
boolean success = false;
final boolean hasKHRSurfacelessTried;
- if( defaultDeviceEGLFeatures.hasKHRSurfaceless && !defaultNoSurfacelessCtx ) {
+ if( defaultDeviceEGLFeatures.hasKHRSurfaceless && !defaultNoSurfacelessCtx
+ && ( !isDRM_GBM || isDRM_GBM && useDefaultDevice ) )
+ {
+ // Includes mapping DRM_GBM EGL device to EGL default shared resources (default behavior), surfaceless.
hasKHRSurfacelessTried = true;
final AbstractGraphicsDevice zdevice = useDefaultDevice ? defaultDevice : adevice; // reuse
final EGLSurface zeroSurface = createSurfacelessImpl(zdevice, false, reqCapsAny, reqCapsAny, null, 64, 64);
resEGLDevice[0] = (EGLGraphicsDevice) zeroSurface.getGraphicsConfiguration().getScreen().getDevice();
if ( DEBUG_SHAREDCTX ) {
- System.err.println("EGLDrawableFactory-MapGLVersions.0: "+resEGLDevice[0]);
+ System.err.println("EGLDrawableFactory.MapGLVersions.0: "+resEGLDevice[0]);
}
EGLDrawable zeroDrawable = null;
EGLContext context = null;
@@ -730,12 +755,12 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
setNoSurfacelessCtxQuirk(context);
}
} else if ( DEBUG_SHAREDCTX ) {
- System.err.println("EGLDrawableFactory-MapGLVersions.0: NOT_CURRENT: "+resEGLDevice[0]+", "+context);
+ System.err.println("EGLDrawableFactory.MapGLVersions.0: NOT_CURRENT: "+resEGLDevice[0]+", "+context);
}
} catch (final Throwable t) {
hasException = true;
if ( DEBUG_SHAREDCTX ) {
- System.err.println("EGLDrawableFactory-MapGLVersions.0: INFO: context create/makeCurrent failed");
+ System.err.println("EGLDrawableFactory.MapGLVersions.0: INFO: context create/makeCurrent failed");
t.printStackTrace();
}
} finally {
@@ -744,7 +769,7 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
context.destroy();
} catch (final GLException gle) {
if ( DEBUG_SHAREDCTX ) {
- System.err.println("EGLDrawableFactory-MapGLVersions.0: INFO: destroy caught exception:");
+ System.err.println("EGLDrawableFactory.MapGLVersions.0: INFO: destroy caught exception:");
gle.printStackTrace();
}
}
@@ -777,13 +802,26 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
ProxySurface upstreamSurface = null; // X11, GLX, ..
ProxySurface downstreamSurface = null; // EGL
try {
- if( useDefaultDevice && defaultDeviceHasPBuffer ) {
+ if( useDefaultDevice && isDRM_GBM ) {
+ // Map DRM_GBM EGL device to EGL default shared resources (default behavior), using a GBM dummy surface
+ resEGLDevice[0] = defaultDevice; // reuse
+ eglFeatures = defaultDeviceEGLFeatures;
+ if ( DEBUG_SHAREDCTX ) {
+ System.err.println("EGLDrawableFactory.MapGLVersions.1: "+resEGLDevice[0]);
+ System.err.println("EGLDrawableFactory.MapGLVersions.1: "+eglFeatures);
+ }
+ downstreamSurface = createDummySurfaceImpl(resEGLDevice[0], false, reqCapsAny, reqCapsAny, null, 64, 64);
+ if( null != downstreamSurface ) {
+ downstreamSurface.createNotify();
+ surface = downstreamSurface;
+ }
+ } else if( useDefaultDevice && defaultDeviceHasPBuffer ) {
// Map any non EGL device to EGL default shared resources (default behavior), using a pbuffer surface
resEGLDevice[0] = defaultDevice; // reuse
eglFeatures = defaultDeviceEGLFeatures;
if ( DEBUG_SHAREDCTX ) {
- System.err.println("EGLDrawableFactory-MapGLVersions.1: "+resEGLDevice[0]);
- System.err.println("EGLDrawableFactory-MapGLVersions.1: "+eglFeatures);
+ System.err.println("EGLDrawableFactory.MapGLVersions.2: "+resEGLDevice[0]);
+ System.err.println("EGLDrawableFactory.MapGLVersions.2: "+eglFeatures);
}
downstreamSurface = createDummySurfaceImpl(resEGLDevice[0], false, reqCapsPBuffer, reqCapsPBuffer, null, 64, 64);
@@ -791,9 +829,8 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
downstreamSurface.createNotify();
surface = downstreamSurface;
}
- } else if( adevice != defaultDevice ) {
+ } else if( !useDefaultDevice && !isDRM_GBM ) {
// Create a true mapping of given device to EGL
- // FIXME !!!! EGL-GBM
upstreamSurface = desktopFactory.createDummySurface(adevice, reqCapsAny, null, 64, 64); // X11, WGL, .. dummy window
if(null != upstreamSurface) {
upstreamSurface.createNotify();
@@ -801,8 +838,8 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
resEGLDevice[0].open();
eglFeatures = new EGLFeatures(resEGLDevice[0]);
if ( DEBUG_SHAREDCTX ) {
- System.err.println("EGLDrawableFactory-MapGLVersions.2: "+resEGLDevice[0]);
- System.err.println("EGLDrawableFactory-MapGLVersions.2: "+eglFeatures);
+ System.err.println("EGLDrawableFactory.MapGLVersions.3: "+resEGLDevice[0]);
+ System.err.println("EGLDrawableFactory.MapGLVersions.3: "+eglFeatures);
}
surface = upstreamSurface;
}
@@ -835,15 +872,15 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
setNoSurfacelessCtxQuirk(context);
}
} else if ( DEBUG_SHAREDCTX ) {
- System.err.println("EGLDrawableFactory-MapGLVersions.12: NULL VERSION: "+resEGLDevice[0]+", "+context.getGLVersion());
+ System.err.println("EGLDrawableFactory.MapGLVersions.123: NULL VERSION: "+resEGLDevice[0]+", "+context.getGLVersion());
}
} else if ( DEBUG_SHAREDCTX ) {
- System.err.println("EGLDrawableFactory-MapGLVersions.12: NOT_CURRENT: "+resEGLDevice[0]+", "+context);
+ System.err.println("EGLDrawableFactory.MapGLVersions.123: NOT_CURRENT: "+resEGLDevice[0]+", "+context);
}
}
} catch (final Throwable t) {
if ( DEBUG_SHAREDCTX ) {
- System.err.println("EGLDrawableFactory-MapGLVersions.12: INFO: context create/makeCurrent failed");
+ System.err.println("EGLDrawableFactory.MapGLVersions.123: INFO: context create/makeCurrent failed");
t.printStackTrace();
}
success = false;
@@ -853,7 +890,7 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
context.destroy();
} catch (final GLException gle) {
if ( DEBUG_SHAREDCTX ) {
- System.err.println("EGLDrawableFactory-MapGLVersions.12: INFO: destroy caught exception:");
+ System.err.println("EGLDrawableFactory.MapGLVersions.123: INFO: destroy caught exception:");
gle.printStackTrace();
}
}
@@ -915,11 +952,25 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
* switching the API via 'eglBindAPI(EGL_OpenGL_API)' the latter 'eglCreateContext(..)' fails w/ EGL_BAD_ACCESS.
* Hence we require both: OpenGL API support _and_ 'EGL_KHR_create_context'.
*
- * Using EGL_GBM, i.e. EGLExt.EGL_PLATFORM_GBM_KHR, we get an unsatisfied linkage error using desktop GL !!
+ * TODO Bug 1401: Mesa 18.3.6 issues using EGL_PLATFORM_GBM_KHR and OpenGL Desktop Profile
+ * Using EGL_GBM with OpenGL results in an unsatisfied linkage error using desktop GL, see:
+ *
+ * java.lang.UnsatisfiedLinkError: 'int jogamp.opengl.gl4.GL4bcImpl.dispatch_glGetError1(long)'
+ * at jogamp.opengl.gl4.GL4bcImpl.dispatch_glGetError1(Native Method)
+ * at jogamp.opengl.gl4.GL4bcImpl.glGetError(GL4bcImpl.java:648)
+ * at jogamp.opengl.GLContextImpl.setGLFunctionAvailability(GLContextImpl.java:2186)
+ * at jogamp.opengl.GLContextImpl.createContextARBVersions(GLContextImpl.java:1427)
+ * at jogamp.opengl.GLContextImpl.createContextARBMapVersionsAvailable(GLContextImpl.java:1366)
+ * at jogamp.opengl.GLContextImpl.mapGLVersions(GLContextImpl.java:1223)
+ * at jogamp.opengl.GLContextImpl.createContextARB(GLContextImpl.java:968)
+ * at jogamp.opengl.egl.EGLContext.createImpl(EGLContext.java:318)
+ * at jogamp.opengl.GLContextImpl.makeCurrentWithinLock(GLContextImpl.java:769)
+ * at jogamp.opengl.GLContextImpl.makeCurrent(GLContextImpl.java:652)
+ * at jogamp.opengl.GLContextImpl.makeCurrent(GLContextImpl.java:590)
+ * at jogamp.opengl.egl.EGLDrawableFactory$SharedResourceImplementation.mapAvailableEGLESConfig(EGLDrawableFactory.java:858)
*/
return null != eglGLnDynamicLookupHelper &&
- defaultDeviceEGLFeatures.hasGLAPI && defaultDeviceEGLFeatures.hasKHRCreateContext &&
- false; // hack
+ defaultDeviceEGLFeatures.hasGLAPI && defaultDeviceEGLFeatures.hasKHRCreateContext && !isDRM_GBM;
}
/**
@@ -1051,7 +1102,7 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
private final EGLGraphicsConfiguration evalConfig(final boolean[] ownDevice, final AbstractGraphicsDevice deviceReq, final boolean createNewDevice,
final GLCapabilitiesImmutable capsChosen, final GLCapabilitiesImmutable capsRequested,
- final GLCapabilitiesChooser chooser) {
+ final GLCapabilitiesChooser chooser, final int nativeVisualID) {
final EGLGraphicsDevice device;
if( createNewDevice || ! (deviceReq instanceof EGLGraphicsDevice) ) {
device = EGLDisplayUtil.eglCreateEGLGraphicsDevice(deviceReq);
@@ -1062,7 +1113,8 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
ownDevice[0] = false;
}
final DefaultGraphicsScreen screen = new DefaultGraphicsScreen(device, 0);
- final EGLGraphicsConfiguration config = EGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capsChosen, capsRequested, chooser, screen, VisualIDHolder.VID_UNDEFINED, false);
+ final EGLGraphicsConfiguration config = EGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(
+ capsChosen, capsRequested, chooser, screen, nativeVisualID, false);
if(null == config) {
throw new GLException("Choosing GraphicsConfiguration failed w/ "+capsChosen+" on "+screen);
}
@@ -1071,26 +1123,42 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
@Override
protected final EGLSurface createMutableSurfaceImpl(final AbstractGraphicsDevice deviceReq, final boolean createNewDevice,
- final GLCapabilitiesImmutable capsChosen, final GLCapabilitiesImmutable capsRequested,
- final GLCapabilitiesChooser chooser, final UpstreamSurfaceHook upstreamHook) {
+ final GLCapabilitiesImmutable capsChosen, final GLCapabilitiesImmutable capsRequested,
+ final GLCapabilitiesChooser chooser,
+ final UpstreamSurfaceHook upstreamHook) {
+ return createMutableSurfaceImpl2(deviceReq, createNewDevice, capsChosen, capsRequested, chooser, VisualIDHolder.VID_UNDEFINED, upstreamHook);
+ }
+ private final EGLSurface createMutableSurfaceImpl2(final AbstractGraphicsDevice deviceReq, final boolean createNewDevice,
+ final GLCapabilitiesImmutable capsChosen, final GLCapabilitiesImmutable capsRequested,
+ final GLCapabilitiesChooser chooser, final int nativeVisualID,
+ final UpstreamSurfaceHook upstreamHook) {
final boolean[] ownDevice = { false };
- final EGLGraphicsConfiguration config = evalConfig(ownDevice, deviceReq, createNewDevice, capsChosen, capsRequested, chooser);
+ final EGLGraphicsConfiguration config = evalConfig(ownDevice, deviceReq, createNewDevice, capsChosen, capsRequested, chooser, nativeVisualID);
return EGLSurface.createWrapped(config, 0, upstreamHook, ownDevice[0]);
}
@Override
public final EGLSurface createDummySurfaceImpl(final AbstractGraphicsDevice deviceReq, final boolean createNewDevice,
- GLCapabilitiesImmutable chosenCaps, final GLCapabilitiesImmutable requestedCaps, final GLCapabilitiesChooser chooser, final int width, final int height) {
- chosenCaps = GLGraphicsConfigurationUtil.fixGLPBufferGLCapabilities(chosenCaps); // complete validation in EGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(..) above
- return createMutableSurfaceImpl(deviceReq, createNewDevice, chosenCaps, requestedCaps, chooser, new EGLDummyUpstreamSurfaceHook(width, height));
+ GLCapabilitiesImmutable chosenCaps, final GLCapabilitiesImmutable requestedCaps, final GLCapabilitiesChooser chooser, final int width, final int height) {
+ final UpstreamSurfaceHook ush;
+ final int nativeVisualID;
+ if( isDRM_GBM ) {
+ ush = new GBMDummyUpstreamSurfaceHook(width, height);
+ nativeVisualID = DRMUtil.GBM_FORMAT_XRGB8888;
+ } else {
+ ush = new EGLDummyUpstreamSurfaceHook(width, height);
+ chosenCaps = GLGraphicsConfigurationUtil.fixGLPBufferGLCapabilities(chosenCaps); // complete validation in EGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(..) above
+ nativeVisualID = VisualIDHolder.VID_UNDEFINED;
+ }
+ return createMutableSurfaceImpl2(deviceReq, createNewDevice, chosenCaps, requestedCaps, chooser, nativeVisualID, ush);
}
@Override
public final EGLSurface createSurfacelessImpl(final AbstractGraphicsDevice deviceReq, final boolean createNewDevice,
- GLCapabilitiesImmutable chosenCaps, final GLCapabilitiesImmutable requestedCaps, final GLCapabilitiesChooser chooser, final int width, final int height) {
+ GLCapabilitiesImmutable chosenCaps, final GLCapabilitiesImmutable requestedCaps, final GLCapabilitiesChooser chooser, final int width, final int height) {
chosenCaps = GLGraphicsConfigurationUtil.fixOnscreenGLCapabilities(chosenCaps);
final boolean[] ownDevice = { false };
- final EGLGraphicsConfiguration config = evalConfig(ownDevice, deviceReq, createNewDevice, chosenCaps, requestedCaps, chooser);
+ final EGLGraphicsConfiguration config = evalConfig(ownDevice, deviceReq, createNewDevice, chosenCaps, requestedCaps, chooser, VisualIDHolder.VID_UNDEFINED);
return EGLSurface.createSurfaceless(config, new GenericUpstreamSurfacelessHook(width, height), ownDevice[0]);
}
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java
index 7e54152bf..5fd0535ad 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java
@@ -113,15 +113,22 @@ public class EGLGraphicsConfiguration extends MutableGraphicsConfiguration imple
void updateGraphicsConfiguration() {
final CapabilitiesImmutable capsChosen = getChosenCapabilities();
- final EGLGraphicsConfiguration newConfig = (EGLGraphicsConfiguration)
- GraphicsConfigurationFactory.getFactory(getScreen().getDevice(), capsChosen).chooseGraphicsConfiguration(
- capsChosen, getRequestedCapabilities(), chooser, getScreen(), VisualIDHolder.VID_UNDEFINED);
- if(null!=newConfig) {
- // FIXME: setScreen( ... );
- setChosenCapabilities(newConfig.getChosenCapabilities());
- if(DEBUG) {
- System.err.println("updateGraphicsConfiguration(1): "+this);
+ if( VisualIDHolder.VID_UNDEFINED == capsChosen.getVisualID(VIDType.NATIVE) ) {
+ final EGLGraphicsConfiguration newConfig = (EGLGraphicsConfiguration)
+ GraphicsConfigurationFactory.getFactory(getScreen().getDevice(), capsChosen).chooseGraphicsConfiguration(
+ capsChosen, getRequestedCapabilities(), chooser, getScreen(), VisualIDHolder.VID_UNDEFINED);
+ if(null!=newConfig) {
+ // FIXME: setScreen( ... );
+ setChosenCapabilities(newConfig.getChosenCapabilities());
+ if(DEBUG) {
+ System.err.println("EGLGraphicsConfiguration.updateGraphicsConfiguration updated: "+this);
+ }
+ } else {
+ throw new GLException("No native VisualID pre-chosen and update failed: "+this);
}
+ } else if (DEBUG) {
+ System.err.println("EGLGraphicsConfiguration.updateGraphicsConfiguration kept:"+this);
+
}
}
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java
index 929be16e3..1d9a9732d 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java
@@ -219,6 +219,18 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
return availableCaps;
}
+ /**
+ * Called mainly by {@link #chooseGraphicsConfigurationImpl(CapabilitiesImmutable, CapabilitiesImmutable, CapabilitiesChooser, AbstractGraphicsScreen, int)}
+ * @param capsChosen the intermediate chosen capabilities to be refined by this implementation, may be equal to capsRequested
+ * @param capsReq the original requested capabilities
+ * @param chooser the choosing implementation
+ * @param absScreen the referring Screen
+ * @param nativeVisualID if not {@link VisualIDHolder#VID_UNDEFINED} it reflects a pre-chosen visualID of the native platform's windowing system.
+ * @param forceTransparentFlag
+ * @return the complete GraphicsConfiguration
+ * @see #chooseGraphicsConfigurationImpl(CapabilitiesImmutable, CapabilitiesImmutable, CapabilitiesChooser, AbstractGraphicsScreen, int)
+ * @see GraphicsConfigurationFactory#chooseGraphicsConfiguration(CapabilitiesImmutable, CapabilitiesImmutable, CapabilitiesChooser, AbstractGraphicsScreen, int)
+ */
public static EGLGraphicsConfiguration chooseGraphicsConfigurationStatic(GLCapabilitiesImmutable capsChosen,
final GLCapabilitiesImmutable capsReq,
final GLCapabilitiesChooser chooser,
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/GraphicsConfigurationFactory.java b/src/nativewindow/classes/com/jogamp/nativewindow/GraphicsConfigurationFactory.java
index 929af054e..5214dbf3d 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/GraphicsConfigurationFactory.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/GraphicsConfigurationFactory.java
@@ -427,6 +427,24 @@ public abstract class GraphicsConfigurationFactory {
}
}
+ /**
+ * Called by {@link #chooseGraphicsConfiguration(CapabilitiesImmutable, CapabilitiesImmutable, CapabilitiesChooser, AbstractGraphicsScreen, int)}
+ * post argument validation within {@link AbstractGraphicsDevice#lock()}ed segment.
+ *
+ * @param capsChosen the intermediate chosen capabilities to be refined by this implementation, may be equal to capsRequested
+ * @param capsRequested the original requested capabilities
+ * @param chooser the choosing implementation
+ * @param screen the referring Screen
+ * @param nativeVisualID if not {@link VisualIDHolder#VID_UNDEFINED} it reflects a pre-chosen visualID of the native platform's windowing system.
+ * @return the complete GraphicsConfiguration
+ *
+ * @throws IllegalArgumentException if the data type of the passed
+ * AbstractGraphicsDevice is not supported by this
+ * NativeWindowFactory.
+ * @throws NativeWindowException if any window system-specific errors caused
+ * the selection of the graphics configuration to fail.
+ * @see #chooseGraphicsConfiguration(CapabilitiesImmutable, CapabilitiesImmutable, CapabilitiesChooser, AbstractGraphicsScreen, int)
+ */
protected abstract AbstractGraphicsConfiguration
chooseGraphicsConfigurationImpl(CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested,
CapabilitiesChooser chooser, AbstractGraphicsScreen screen, int nativeVisualID)
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/NativeWindowFactory.java b/src/nativewindow/classes/com/jogamp/nativewindow/NativeWindowFactory.java
index a41e9c349..d4249d404 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/NativeWindowFactory.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/NativeWindowFactory.java
@@ -86,8 +86,8 @@ public abstract class NativeWindowFactory {
/** Wayland/EGL type, as retrieved with {@link #getNativeWindowType(boolean)}. String is canonical via {@link String#intern()}.*/
public static final String TYPE_WAYLAND = ".wayland";
- /** GBM/EGL type, as retrieved with {@link #getNativeWindowType(boolean)}. String is canonical via {@link String#intern()}.*/
- public static final String TYPE_EGL_GBM = ".egl.gbm";
+ /** DRM/GBM type, as retrieved with {@link #getNativeWindowType(boolean)}. String is canonical via {@link String#intern()}.*/
+ public static final String TYPE_DRM_GBM = ".egl.gbm"; // We leave the sub-package name as .egl.gbm for NEWT as it uses EGL
/** OpenKODE/EGL type, as retrieved with {@link #getNativeWindowType(boolean)}. String is canonical via {@link String#intern()}.*/
public static final String TYPE_EGL = ".egl";
@@ -128,6 +128,8 @@ public abstract class NativeWindowFactory {
private static final String JAWTUtilClassName = "jogamp.nativewindow.jawt.JAWTUtil" ;
/** {@link jogamp.nativewindow.x11.X11Util} implements {@link ToolkitProperties}. */
private static final String X11UtilClassName = "jogamp.nativewindow.x11.X11Util";
+ /** {@link jogamp.nativewindow.drm.DRMUtil} implements {@link ToolkitProperties}. */
+ private static final String DRMUtilClassName = "jogamp.nativewindow.drm.DRMUtil";
/** {@link jogamp.nativewindow.macosx.OSXUtil} implements {@link ToolkitProperties}. */
private static final String OSXUtilClassName = "jogamp.nativewindow.macosx.OSXUtil";
/** {@link jogamp.nativewindow.ios.IOSUtil} implements {@link ToolkitProperties}. */
@@ -181,7 +183,7 @@ public abstract class NativeWindowFactory {
return TYPE_WAYLAND;
}
if( guessGBM(false) ) {
- return TYPE_EGL_GBM;
+ return TYPE_DRM_GBM;
}
if( BcmVCArtifacts.guessVCIVUsed(false) ) {
return TYPE_BCM_VC_IV;
@@ -259,6 +261,9 @@ public abstract class NativeWindowFactory {
case TYPE_X11:
clazzName = X11UtilClassName;
break;
+ case TYPE_DRM_GBM:
+ clazzName = DRMUtilClassName;
+ break;
case TYPE_WINDOWS:
clazzName = GDIClassName;
break;
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/VisualIDHolder.java b/src/nativewindow/classes/com/jogamp/nativewindow/VisualIDHolder.java
index 69bfe50f8..62b73d230 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/VisualIDHolder.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/VisualIDHolder.java
@@ -40,13 +40,13 @@ import java.util.Comparator;
public interface VisualIDHolder {
public enum VIDType {
- // Generic Values
+ /** Generic Values */
INTRINSIC(0), NATIVE(1),
- // EGL Values
+ /** EGL Values */
EGL_CONFIG(10),
- // X11 Values
+ /** X11 Values */
X11_XVISUAL(20), X11_FBCONFIG(21),
- // Windows Values
+ /** Windows Values */
WIN32_PFD(30);
public final int id;
diff --git a/src/nativewindow/classes/jogamp/nativewindow/drm/DRMUtil.java b/src/nativewindow/classes/jogamp/nativewindow/drm/DRMUtil.java
new file mode 100644
index 000000000..176ebccb0
--- /dev/null
+++ b/src/nativewindow/classes/jogamp/nativewindow/drm/DRMUtil.java
@@ -0,0 +1,154 @@
+/**
+ * Copyright 2019 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package jogamp.nativewindow.drm;
+
+import com.jogamp.nativewindow.NativeWindowException;
+import com.jogamp.nativewindow.NativeWindowFactory;
+
+import jogamp.nativewindow.Debug;
+import jogamp.nativewindow.NWJNILibLoader;
+import jogamp.nativewindow.ToolkitProperties;
+
+import com.jogamp.common.ExceptionUtils;
+
+/**
+ * DRM and GBM utility
+ */
+public class DRMUtil implements ToolkitProperties {
+ /* pp */ static final boolean DEBUG = Debug.debug("DRMUtil");
+
+ /** FIXME: Add support for other OS implementing DRM/GBM, e.g. FreeBSD, OpenBSD, ..? */
+ private static final String dri0Linux = "/dev/dri/card0";
+
+ private static volatile boolean isInit = false;
+ /** DRM file descriptor, valid if >= 0 */
+ private static int drmFd = -1;
+
+ /**
+ * Called by {@link NativeWindowFactory#initSingleton()}
+ * @see ToolkitProperties
+ */
+ public static void initSingleton() {
+ if(!isInit) {
+ synchronized(DRMUtil.class) {
+ if(!isInit) {
+ isInit = true;
+ if(DEBUG) {
+ System.out.println("DRMUtil.initSingleton()");
+ }
+ if(!NWJNILibLoader.loadNativeWindow("drm")) {
+ throw new NativeWindowException("NativeWindow DRM native library load error.");
+ }
+ if( initialize0(DEBUG) ) {
+ drmFd = DRMLib.drmOpenFile(dri0Linux);
+ }
+ if(DEBUG) {
+ System.err.println("DRMUtil.initSingleton(): OK "+(0 <= drmFd)+", drmFd "+drmFd+"]");
+ if( 0 <= drmFd ) {
+ final DrmMode d = DrmMode.create(drmFd, true);
+ d.print(System.err);
+ d.destroy();
+ }
+ // Thread.dumpStack();
+ }
+ }
+ }
+ }
+ }
+
+ /** Return the global DRM file descriptor */
+ public static int getDrmFd() { return drmFd; }
+
+ /**
+ * Cleanup resources.
+ * <p>
+ * Called by {@link NativeWindowFactory#shutdown()}
+ * </p>
+ * @see ToolkitProperties
+ */
+ public static void shutdown() {
+ if(isInit) {
+ synchronized(DRMUtil.class) {
+ if(isInit) {
+ final boolean isJVMShuttingDown = NativeWindowFactory.isJVMShuttingDown() ;
+ if( DEBUG ) {
+ System.err.println("DRMUtil.Display: Shutdown (JVM shutdown: "+isJVMShuttingDown+")");
+ if(DEBUG) {
+ ExceptionUtils.dumpStack(System.err);
+ }
+ }
+
+ // Only at JVM shutdown time, since AWT impl. seems to
+ // dislike closing of X11 Display's (w/ ATI driver).
+ if( isJVMShuttingDown ) {
+ if( 0 <= drmFd ) {
+ DRMLib.drmClose(drmFd);
+ drmFd = -1;
+ }
+ isInit = false;
+ shutdown0();
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Called by {@link NativeWindowFactory#initSingleton()}
+ * @see ToolkitProperties
+ */
+ public static final boolean requiresToolkitLock() {
+ return true;
+ }
+
+ /**
+ * Called by {@link NativeWindowFactory#initSingleton()}
+ * @see ToolkitProperties
+ */
+ public static final boolean hasThreadingIssues() {
+ return false;
+ }
+
+ 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) );
+ }
+ /** [31:0] x:R:G:B 8:8:8:8 little endian */
+ public static final int GBM_FORMAT_XRGB8888 = fourcc_code('X', 'R', '2', '4');
+ /** [31:0] A:R:G:B 8:8:8:8 little endian */
+ public static final int GBM_FORMAT_ARGB8888 = fourcc_code('A', 'R', '2', '4');
+
+ private DRMUtil() {}
+
+ private static final String getCurrentThreadName() { return Thread.currentThread().getName(); } // Callback for JNI
+ private static final void dumpStack() { ExceptionUtils.dumpStack(System.err); } // Callback for JNI
+
+ private static native boolean initialize0(boolean debug);
+ private static native void shutdown0();
+}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/drm/DrmMode.java b/src/nativewindow/classes/jogamp/nativewindow/drm/DrmMode.java
new file mode 100644
index 000000000..44b2a1327
--- /dev/null
+++ b/src/nativewindow/classes/jogamp/nativewindow/drm/DrmMode.java
@@ -0,0 +1,304 @@
+/**
+ * Copyright 2019 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+package jogamp.nativewindow.drm;
+
+import java.io.PrintStream;
+import java.nio.IntBuffer;
+import java.util.ArrayList;
+import java.util.List;
+
+import com.jogamp.nativewindow.NativeWindowException;
+
+import jogamp.nativewindow.drm.DRMLib;
+import jogamp.nativewindow.drm.drmModeConnector;
+import jogamp.nativewindow.drm.drmModeEncoder;
+import jogamp.nativewindow.drm.drmModeModeInfo;
+import jogamp.nativewindow.drm.drmModeRes;
+
+/**
+ * Describing a DRM adapter's connected {@link drmModeConnector}
+ * and it's {@link drmModeModeInfo}, {@link drmModeEncoder} and CRT index.
+ */
+public class DrmMode {
+ /** DRM file descriptor, valid if >= 0 */
+ public final int drmFd;
+ /** Number of connected {@link drmModeConnector}s and hence length of all arrays within this instance. */
+ public final int count;
+ /** Connected {@link drmModeConnector}, multiple outputs supported. Array can be of length zero if none is connected. */
+ private final drmModeConnector[] connectors;
+ /** Selected current mode {@link drmModeModeInfo}. Array index matches the {@link #connectors}. */
+ private final drmModeModeInfo[] modes;
+ /** Selected {@link drmModeEncoder}. Array index matches the {@link #connectors}. */
+ private final drmModeEncoder[] encoder;
+ /** Selected CRT IDs. Array index matches the {@link #connectors}. */
+ private final int[] crtc_ids;
+ /** Selected CRT indices. Array index matches the {@link #connectors}. */
+ private final int[] crtc_indices;
+ /** boolean indicating that instance data is valid reflecting native DRM data and has not been {@link #destroy()}ed. */
+ private volatile boolean valid;
+
+ private DrmMode(final int drmFd, final int count) {
+ this.drmFd = drmFd;
+ this.count = count;
+ this.connectors = new drmModeConnector[count];
+ this.modes = new drmModeModeInfo[count];
+ this.encoder = new drmModeEncoder[count];
+ this.crtc_ids = new int[count];
+ this.crtc_indices = new int[count];
+ this.valid = false;
+ }
+
+ public void print(final PrintStream out) {
+ for(int i=0; i<count; i++) {
+ print(out, i);
+ }
+ }
+ public void print(final PrintStream out, final int connectorIdx) {
+ final drmModeConnector c = connectors[connectorIdx];
+ out.printf("Connector[%d]: id[con 0x%x, enc 0x%x], type %d[id 0x%x], connection %d, dim %dx%x mm, modes %d, encoders %d\n",
+ connectorIdx, c.getConnector_id(), c.getEncoder_id(),
+ c.getConnector_type(), c.getConnector_type_id(), c.getConnection(), c.getMmWidth(), c.getMmHeight(),
+ c.getCount_modes(), c.getCount_encoders());
+ final drmModeModeInfo m = modes[connectorIdx];
+ System.err.printf( "Connector[%d].Mode: clock %d, %dx%d @ %d Hz, type %d, name <%s>\n",
+ connectorIdx, m.getClock(), m.getHdisplay(), m.getVdisplay(), m.getVrefresh(),
+ m.getType(), m.getNameAsString());
+ final drmModeEncoder e = encoder[connectorIdx];
+ System.err.printf( "Connector[%d].Encoder: id 0x%x, type %d, crtc_id 0x%x, possible[crtcs %d, clones %d]\n",
+ connectorIdx, e.getEncoder_id(), e.getEncoder_type(), e.getCrtc_id(),
+ e.getPossible_crtcs(), e.getPossible_clones());
+ }
+
+ /**
+ * Collecting all connected {@link drmModeConnector}
+ * and it's {@link drmModeModeInfo}, {@link drmModeEncoder} and CRT index.
+ *
+ * @param drmFd the DRM file descriptor
+ * @param preferNativeMode chose {@link DRMLib#DRM_MODE_TYPE_PREFERRED}
+ */
+ public static DrmMode create(final int drmFd, final boolean preferNativeMode) {
+ final drmModeRes resources = DRMLib.drmModeGetResources(drmFd);
+ if( null == resources ) {
+ throw new NativeWindowException("drmModeGetResources failed");
+ }
+ DrmMode res = null;
+ try {
+ {
+ final List<drmModeConnector> _connectors = new ArrayList<drmModeConnector>();
+ final IntBuffer _connectorIDs = resources.getConnectors();
+ if(DRMUtil.DEBUG) {
+ for(int i=0; i<_connectorIDs.limit(); i++) {
+ final drmModeConnector c = DRMLib.drmModeGetConnector(drmFd, _connectorIDs.get(i));
+ final boolean chosen = DRMLib.DRM_MODE_CONNECTED == c.getConnection();
+ System.err.printf("Connector %d/%d chosen %b,: id[con 0x%x, enc 0x%x], type %d[id 0x%x], connection %d, dim %dx%x mm, modes %d, encoders %d\n",
+ i, _connectorIDs.limit(), chosen, c.getConnector_id(), c.getEncoder_id(),
+ c.getConnector_type(), c.getConnector_type_id(), c.getConnection(), c.getMmWidth(), c.getMmHeight(),
+ c.getCount_modes(), c.getCount_encoders());
+ DRMLib.drmModeFreeConnector(c);
+ }
+ }
+ drmModeConnector con = null;
+ for(int i=0; i<_connectorIDs.limit(); i++) {
+ con = DRMLib.drmModeGetConnector(drmFd, _connectorIDs.get(i));
+ if( DRMLib.DRM_MODE_CONNECTED == con.getConnection() ) {
+ _connectors.add(con);
+ } else {
+ DRMLib.drmModeFreeConnector(con);
+ con = null;
+ }
+ }
+ res = new DrmMode(drmFd, _connectors.size());
+ _connectors.toArray(res.connectors);
+ }
+ for(int k=0; k<res.count; k++) {
+ final drmModeModeInfo _modes[] = res.connectors[k].getModes(0, new drmModeModeInfo[res.connectors[k].getCount_modes()]);
+ drmModeModeInfo _mode = null;
+ {
+ int maxArea = 0;
+ int j=0;
+ for(int i=0; i<_modes.length; i++) {
+ final drmModeModeInfo m = _modes[i];
+ final int area = m.getHdisplay() * m.getVdisplay();
+ if( preferNativeMode && m.getType() == DRMLib.DRM_MODE_TYPE_PREFERRED ) {
+ _mode = m;
+ maxArea = Integer.MAX_VALUE;
+ j = i;
+ // only continue loop for DEBUG verbosity
+ } else if( area > maxArea ) {
+ _mode = m;
+ maxArea = area;
+ j = i;
+ }
+ if( DRMUtil.DEBUG ) {
+ System.err.printf( "Connector[%d].Mode %d/%d (max-chosen %d): clock %d, %dx%d @ %d Hz, type %d, name <%s>\n",
+ k, i, _modes.length, j,
+ m.getClock(), m.getHdisplay(), m.getVdisplay(), m.getVrefresh(),
+ m.getType(), m.getNameAsString());
+ }
+ }
+ }
+ if( null == _mode ) {
+ throw new NativeWindowException("could not find mode");
+ }
+ res.modes[k] = _mode;
+ }
+ {
+ final IntBuffer encoderIDs = resources.getEncoders();
+ for(int k=0; k<res.count; k++) {
+ if( DRMUtil.DEBUG ) {
+ for (int i = 0; i < encoderIDs.limit(); i++) {
+ final drmModeEncoder e = DRMLib.drmModeGetEncoder(drmFd, encoderIDs.get(i));
+ final boolean chosen = e.getEncoder_id() == res.connectors[k].getEncoder_id();
+ System.err.printf( "Connector[%d].Encoder %d/%d chosen %b: id 0x%x, type %d, crtc_id 0x%x, possible[crtcs %d, clones %d]\n",
+ k, i, encoderIDs.limit(), chosen,
+ e.getEncoder_id(), e.getEncoder_type(), e.getCrtc_id(),
+ e.getPossible_crtcs(), e.getPossible_clones());
+ DRMLib.drmModeFreeEncoder(e);
+ }
+ }
+ drmModeEncoder e = null;
+ for (int i = 0; i < encoderIDs.limit(); i++) {
+ e = DRMLib.drmModeGetEncoder(drmFd, encoderIDs.get(i));
+ if( e.getEncoder_id() == res.connectors[k].getEncoder_id() ) {
+ break;
+ } else {
+ DRMLib.drmModeFreeEncoder(e);
+ e = null;
+ }
+ }
+ if( null == e ) {
+ throw new NativeWindowException("could not find encoder");
+ }
+ res.encoder[k] = e;
+ }
+ }
+ {
+ final IntBuffer crtcs = resources.getCrtcs();
+ for(int k=0; k<res.count; k++) {
+ int idx = -1;
+ for(int i=0; i<crtcs.limit(); i++) {
+ if( crtcs.get(i) == res.encoder[k].getCrtc_id() ) {
+ idx = i;
+ break;
+ }
+ }
+ if( 0 > idx ) {
+ throw new NativeWindowException("could not find crtc index");
+ }
+ res.crtc_ids[k] = crtcs.get(idx);
+ res.crtc_indices[k] = idx;
+ }
+ }
+ } catch (final Throwable t) {
+ if( null != res ) {
+ res.destroy();
+ res = null;
+ }
+ throw t;
+ } finally {
+ DRMLib.drmModeFreeResources(resources);
+ }
+ res.valid = true;
+ return res;
+ }
+
+ /**
+ * Returns whether instance data is valid reflecting native DRM data and has not been {@link #destroy()}ed.
+ */
+ public final boolean isValid() {
+ return valid;
+ }
+ private final void checkValid() {
+ if( !valid ) {
+ throw new IllegalStateException("Instance is invalid");
+ }
+ }
+
+
+ /**
+ * Frees all native DRM resources collected by one of the static methods like {@link #create(int, boolean)}.
+ * <p>
+ * Method should be issued before shutting down or releasing the {@link #drmFd} via {@link DRMLib#drmClose(int)}.
+ * </p>
+ */
+ public final void destroy() {
+ if( valid ) {
+ synchronized( this ) {
+ if( valid ) {
+ valid = false;
+ for(int i=0; i<count; i++) {
+ if( null != encoder[i] ) {
+ DRMLib.drmModeFreeEncoder(encoder[i]);
+ }
+ if( null != connectors[i]) {
+ DRMLib.drmModeFreeConnector(connectors[i]);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns an array for each connected {@link drmModeConnector}s.
+ * <p>
+ * Returned array length is zero if no {@link drmModeConnector} is connected.
+ * </p>
+ * @throws IllegalStateException if instance is not {@link #isValid()}.
+ */
+ public final drmModeConnector[] getConnectors() throws IllegalStateException
+ { checkValid(); return connectors; }
+
+ /**
+ * Returns an array of {@link drmModeModeInfo} for each connected {@link #getConnectors()}'s current mode.
+ * @throws IllegalStateException if instance is not {@link #isValid()}.
+ */
+ public final drmModeModeInfo[] getModes() throws IllegalStateException
+ { checkValid(); return modes; }
+
+ /**
+ * Returns an array of {@link drmModeEncoder} for each connected {@link #getConnectors()}.
+ * @throws IllegalStateException if instance is not {@link #isValid()}.
+ */
+ public final drmModeEncoder[] getEncoder() throws IllegalStateException
+ { checkValid(); return encoder; }
+
+ /**
+ * Returns an array of selected CRT IDs for each connected {@link #getConnectors()}.
+ * @throws IllegalStateException if instance is not {@link #isValid()}.
+ */
+ public final int[] getCrtcIDs() throws IllegalStateException
+ { checkValid(); return crtc_ids; }
+
+ /**
+ * Returns an array of selected CRT indices for each connected {@link #getConnectors()}.
+ * @throws IllegalStateException if instance is not {@link #isValid()}.
+ */
+ public final int[] getCrtcIndices() throws IllegalStateException
+ { checkValid(); return crtc_indices; }
+} \ No newline at end of file
diff --git a/src/nativewindow/classes/jogamp/nativewindow/drm/GBMDummyUpstreamSurfaceHook.java b/src/nativewindow/classes/jogamp/nativewindow/drm/GBMDummyUpstreamSurfaceHook.java
new file mode 100644
index 000000000..c237e6802
--- /dev/null
+++ b/src/nativewindow/classes/jogamp/nativewindow/drm/GBMDummyUpstreamSurfaceHook.java
@@ -0,0 +1,105 @@
+/**
+ * Copyright 2019 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+package jogamp.nativewindow.drm;
+
+import com.jogamp.nativewindow.AbstractGraphicsDevice;
+import com.jogamp.nativewindow.NativeSurface;
+import com.jogamp.nativewindow.NativeWindowException;
+import com.jogamp.nativewindow.ProxySurface;
+import com.jogamp.nativewindow.UpstreamSurfaceHook;
+
+import com.jogamp.nativewindow.UpstreamSurfaceHookMutableSize;
+
+public class GBMDummyUpstreamSurfaceHook extends UpstreamSurfaceHookMutableSize {
+ private long gbmDevice = 0;
+
+ /**
+ * @param width the initial width as returned by {@link NativeSurface#getSurfaceWidth()} via {@link UpstreamSurfaceHook#getSurfaceWidth(ProxySurface)},
+ * not the actual dummy surface width.
+ * The latter is platform specific and small
+ * @param height the initial height as returned by {@link NativeSurface#getSurfaceHeight()} via {@link UpstreamSurfaceHook#getSurfaceHeight(ProxySurface)},
+ * not the actual dummy surface height,
+ * The latter is platform specific and small
+ */
+ public GBMDummyUpstreamSurfaceHook(final int width, final int height) {
+ super(width, height);
+ }
+
+ @Override
+ public final void create(final ProxySurface s) {
+ final AbstractGraphicsDevice gd = s.getGraphicsConfiguration().getScreen().getDevice();
+ final int visualID = DRMUtil.GBM_FORMAT_XRGB8888;
+ gd.lock();
+ try {
+ if( 0 == s.getSurfaceHandle() ) {
+ gbmDevice = DRMLib.gbm_create_device(DRMUtil.getDrmFd());
+ if(0 == gbmDevice) {
+ throw new NativeWindowException("Creating dummy GBM device failed");
+ }
+
+ final long gbmSurface = DRMLib.gbm_surface_create(gbmDevice, 64, 64, visualID,
+ DRMLib.GBM_BO_USE_SCANOUT | DRMLib.GBM_BO_USE_RENDERING);
+ if(0 == gbmSurface) {
+ throw new NativeWindowException("Creating dummy GBM surface failed");
+ }
+ s.setSurfaceHandle(gbmSurface);
+
+ s.addUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE );
+ }
+ s.addUpstreamOptionBits( ProxySurface.OPT_UPSTREAM_WINDOW_INVISIBLE );
+ } finally {
+ gd.unlock();
+ }
+ }
+
+ @Override
+ public final void destroy(final ProxySurface s) {
+ if( s.containsUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE ) ) {
+ final AbstractGraphicsDevice gd = s.getGraphicsConfiguration().getScreen().getDevice();
+ final long gbmSurface = s.getSurfaceHandle();
+ if( 0 == gbmDevice ) {
+ throw new InternalError("GBM device handle is null");
+ }
+ if( 0 == gbmSurface ) {
+ throw new InternalError("Owns upstream surface, but has no GBM surface: "+s);
+ }
+ gd.lock();
+ try {
+ DRMLib.gbm_surface_destroy(gbmSurface);
+ s.setSurfaceHandle(0);
+
+ DRMLib.gbm_device_destroy(gbmDevice);
+ gbmDevice = 0;
+
+ s.clearUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE );
+ } finally {
+ gd.unlock();
+ }
+ }
+ }
+}
diff --git a/src/nativewindow/native/JVM_JNI8.c b/src/nativewindow/native/JVM_JNI8.c
index a7b4e5d90..4cdeaeb43 100644
--- a/src/nativewindow/native/JVM_JNI8.c
+++ b/src/nativewindow/native/JVM_JNI8.c
@@ -36,12 +36,14 @@ JNIEXPORT jint JNICALL JNI_OnLoad_nativewindow_x11(JavaVM *vm, void *reserved) {
JNIEXPORT jint JNICALL JNI_OnLoad_nativewindow_win32(JavaVM *vm, void *reserved) { return JNI_VERSION_1_8; }
JNIEXPORT jint JNICALL JNI_OnLoad_nativewindow_macosx(JavaVM *vm, void *reserved) { return JNI_VERSION_1_8; }
JNIEXPORT jint JNICALL JNI_OnLoad_nativewindow_ios(JavaVM *vm, void *reserved) { return JNI_VERSION_1_8; }
+JNIEXPORT jint JNICALL JNI_OnLoad_nativewindow_drm(JavaVM *vm, void *reserved) { return JNI_VERSION_1_8; }
JNIEXPORT void JNICALL JNI_OnUnload_nativewindow_awt(JavaVM *vm, void *reserved) { }
JNIEXPORT void JNICALL JNI_OnUnload_nativewindow_x11(JavaVM *vm, void *reserved) { }
JNIEXPORT void JNICALL JNI_OnUnload_nativewindow_win32(JavaVM *vm, void *reserved) { }
JNIEXPORT void JNICALL JNI_OnUnload_nativewindow_macosx(JavaVM *vm, void *reserved) { }
JNIEXPORT void JNICALL JNI_OnUnload_nativewindow_ios(JavaVM *vm, void *reserved) { }
+JNIEXPORT void JNICALL JNI_OnUnload_nativewindow_drm(JavaVM *vm, void *reserved) { }
#endif /* defined (JNI_VERSION_1_8) */
diff --git a/src/nativewindow/native/drm/DRMmisc.c b/src/nativewindow/native/drm/DRMmisc.c
new file mode 100644
index 000000000..1bd8e1eaf
--- /dev/null
+++ b/src/nativewindow/native/drm/DRMmisc.c
@@ -0,0 +1,89 @@
+/**
+ * Copyright 2019 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+#include "NativewindowCommon.h"
+
+#include "jogamp_nativewindow_drm_DRMLib.h"
+#include "jogamp_nativewindow_drm_DRMUtil.h"
+
+#include <fcntl.h>
+
+/** Remove memcpy GLIBC > 2.4 dependencies */
+#include <glibc-compat-symbols.h>
+
+// #define VERBOSE_ON 1
+
+#ifdef VERBOSE_ON
+ #define DBG_PRINT(args...) fprintf(stderr, args);
+#else
+ #define DBG_PRINT(args...)
+#endif
+
+static int _initialized = 0;
+
+JNIEXPORT jboolean JNICALL
+Java_jogamp_nativewindow_drm_DRMUtil_initialize0(JNIEnv *env, jclass clazz, jboolean debug) {
+ if( 0 == _initialized ) {
+ _initialized=1;
+ if(JNI_TRUE == debug) {
+ fprintf(stderr, "Info: NativeWindow native init passed\n");
+ }
+ }
+ return JNI_TRUE;
+}
+
+JNIEXPORT void JNICALL
+Java_jogamp_nativewindow_drm_DRMUtil_shutdown0(JNIEnv *env, jclass _unused) {
+ // NOP
+}
+
+/* Java->C glue code:
+ * Java package: jogamp.nativewindow.drm.DRMLib
+ * Java method: int drmOpenFile(java.lang.String filename)
+ * C function: int drmOpenFile(const char *filename)
+ */
+JNIEXPORT jint JNICALL
+Java_jogamp_nativewindow_drm_DRMLib_drmOpenFile(JNIEnv *env, jclass _unused, jstring filename) {
+ const char* _strchars_filename = NULL;
+ int _res;
+ if ( NULL != filename ) {
+ _strchars_filename = (*env)->GetStringUTFChars(env, filename, (jboolean*)NULL);
+ if ( NULL == _strchars_filename ) {
+ (*env)->ThrowNew(env, (*env)->FindClass(env, "java/lang/OutOfMemoryError"),
+ "Failed to get UTF-8 chars for argument \"filename\" in native dispatcher for \"drmOpenFile\"");
+ return 0;
+ }
+ }
+ _res = (int) open((const char * ) _strchars_filename, O_RDWR);
+ if ( NULL != filename ) {
+ (*env)->ReleaseStringUTFChars(env, filename, _strchars_filename);
+ }
+ return _res;
+}
+
+
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);
}
diff --git a/src/newt/native/drm_gbm.c b/src/newt/native/drm_gbm.c
new file mode 100644
index 000000000..93b02dbe7
--- /dev/null
+++ b/src/newt/native/drm_gbm.c
@@ -0,0 +1,83 @@
+/**
+ * Copyright 2019 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+#include "drm_gbm.h"
+
+static jmethodID sizeChangedID = NULL;
+static jmethodID positionChangedID = NULL;
+static jmethodID visibleChangedID = NULL;
+static jmethodID windowDestroyNotifyID = NULL;
+
+/**
+ * Display
+ */
+
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_egl_gbm_DisplayDriver_initIDs
+ (JNIEnv *env, jclass clazz)
+{
+ DBG_PRINT( "EGL_GBM.Display initIDs ok\n" );
+ return JNI_TRUE;
+}
+
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_egl_gbm_DisplayDriver_DispatchMessages0
+ (JNIEnv *env, jclass clazz)
+{
+}
+
+/**
+ * Screen
+ */
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_egl_gbm_ScreenDriver_initIDs
+ (JNIEnv *env, jclass clazz)
+{
+ DBG_PRINT( "EGL_GBM.Screen initIDs ok\n" );
+ return JNI_TRUE;
+}
+
+/**
+ * Window
+ */
+
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_egl_gbm_WindowDriver_initIDs
+ (JNIEnv *env, jclass clazz)
+{
+ sizeChangedID = (*env)->GetMethodID(env, clazz, "sizeChanged", "(ZIIZ)V");
+ positionChangedID = (*env)->GetMethodID(env, clazz, "positionChanged", "(ZII)V");
+ visibleChangedID = (*env)->GetMethodID(env, clazz, "visibleChanged", "(Z)V");
+ windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "(Z)Z");
+ if (sizeChangedID == NULL ||
+ positionChangedID == NULL ||
+ visibleChangedID == NULL ||
+ windowDestroyNotifyID == NULL) {
+ DBG_PRINT( "initIDs failed\n" );
+ return JNI_FALSE;
+ }
+ DBG_PRINT( "EGL_GBM.Window initIDs ok\n" );
+ return JNI_TRUE;
+}
+
diff --git a/src/newt/native/egl_gbm.h b/src/newt/native/drm_gbm.h
index ae7c9121f..3fac0f59b 100644
--- a/src/newt/native/egl_gbm.h
+++ b/src/newt/native/drm_gbm.h
@@ -42,7 +42,7 @@
#define WEAK __attribute__((weak))
-#define VERBOSE_ON 1
+// #define VERBOSE_ON 1
#ifdef VERBOSE_ON
#define DBG_PRINT(...) fprintf(stderr, __VA_ARGS__); fflush(stderr)
@@ -51,12 +51,3 @@
#endif
#define ERR_PRINT(...) fprintf(stderr, __VA_ARGS__); fflush(stderr)
-typedef struct {
- int fd; // drmClose
- drmModeConnector *connector; // drmModeFreeConnector
- drmModeEncoder *encoder; // drmModeFreeEncoder
- int crtc_index;
-
- drmModeModeInfo *current_mode;
-} DRM_HANDLE;
-
diff --git a/src/newt/native/drm_gbm_legacy.c b/src/newt/native/drm_gbm_legacy.c
new file mode 100644
index 000000000..8cc1c3c15
--- /dev/null
+++ b/src/newt/native/drm_gbm_legacy.c
@@ -0,0 +1,306 @@
+/**
+ * Copyright 2019 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+#include "drm_gbm.h"
+
+WEAK uint64_t
+gbm_bo_get_modifier(struct gbm_bo *bo);
+
+WEAK int
+gbm_bo_get_plane_count(struct gbm_bo *bo);
+
+WEAK uint32_t
+gbm_bo_get_stride_for_plane(struct gbm_bo *bo, int plane);
+
+WEAK uint32_t
+gbm_bo_get_offset(struct gbm_bo *bo, int plane);
+
+typedef struct {
+ struct gbm_bo *bo;
+ uint32_t fb_id;
+ uint32_t x, y;
+} DRM_FB;
+
+static void page_flip_handler(int fd, unsigned int frame,
+ unsigned int sec, unsigned int usec, void *data)
+{
+ /* suppress 'unused parameter' warnings */
+ (void)fd, (void)frame, (void)sec, (void)usec;
+
+ int *waiting_for_flip = data;
+ *waiting_for_flip = 0;
+}
+
+static drmEventContext drm_event_ctx = {
+ .version = DRM_EVENT_CONTEXT_VERSION,
+ .page_flip_handler = page_flip_handler,
+ };
+
+static void drm_fb_destroy_callback(struct gbm_bo *bo, void *data)
+{
+ struct gbm_device * gbmDev = gbm_bo_get_device(bo);
+ int drm_fd = gbm_device_get_fd(gbmDev);
+ DRM_FB *fb = data;
+
+ if (fb->fb_id) {
+ drmModeRmFB(drm_fd, fb->fb_id);
+ fb->fb_id = 0;
+ fb->bo = NULL;
+ }
+
+ free(fb);
+}
+
+static DRM_FB * drm_fb_get_from_bo2(int drmFd, struct gbm_bo *bo)
+{
+ DRM_FB *fb = gbm_bo_get_user_data(bo);
+ uint32_t width, height, format,
+ strides[4] = {0}, handles[4] = {0},
+ offsets[4] = {0}, flags = 0;
+ int ret = -1;
+
+ if (fb) {
+ return fb;
+ }
+
+ fb = calloc(1, sizeof *fb);
+ fb->bo = bo;
+
+ width = gbm_bo_get_width(bo);
+ height = gbm_bo_get_height(bo);
+ format = gbm_bo_get_format(bo);
+
+ if (gbm_bo_get_modifier && gbm_bo_get_plane_count &&
+ gbm_bo_get_stride_for_plane && gbm_bo_get_offset) {
+
+ uint64_t modifiers[4] = {0};
+ modifiers[0] = gbm_bo_get_modifier(bo);
+ const int num_planes = gbm_bo_get_plane_count(bo);
+ for (int i = 0; i < num_planes; i++) {
+ strides[i] = gbm_bo_get_stride_for_plane(bo, i);
+ handles[i] = gbm_bo_get_handle(bo).u32;
+ offsets[i] = gbm_bo_get_offset(bo, i);
+ modifiers[i] = modifiers[0];
+ }
+
+ if (modifiers[0]) {
+ flags = DRM_MODE_FB_MODIFIERS;
+ DBG_PRINT("Using modifier %" PRIx64 "\n", modifiers[0]);
+ }
+
+ ret = drmModeAddFB2WithModifiers(drmFd, width, height,
+ format, handles, strides, offsets,
+ modifiers, &fb->fb_id, flags);
+ if(ret) {
+ ERR_PRINT("drmModeAddFB2WithModifiers failed!\n");
+ } else {
+ DBG_PRINT("drmModeAddFB2WithModifiers OK!\n");
+ }
+ }
+
+ if (ret) {
+ memcpy(handles, (uint32_t [4]){gbm_bo_get_handle(bo).u32,0,0,0}, 16);
+ memcpy(strides, (uint32_t [4]){gbm_bo_get_stride(bo),0,0,0}, 16);
+ memset(offsets, 0, 16);
+ ret = drmModeAddFB2(drmFd, width, height, format,
+ handles, strides, offsets, &fb->fb_id, 0);
+ if(ret) {
+ ERR_PRINT("drmModeAddFB2 failed!\n");
+ } else {
+ DBG_PRINT("drmModeAddFB2 OK!\n");
+ }
+ }
+
+ if (ret) {
+ ERR_PRINT("failed to create fb: %s\n", strerror(errno));
+ free(fb);
+ return NULL;
+ }
+
+ gbm_bo_set_user_data(bo, fb, drm_fb_destroy_callback);
+
+ return fb;
+}
+
+static DRM_FB * drm_fb_get_from_bo(int drmFd, struct gbm_bo *bo)
+{
+ DRM_FB *fb = gbm_bo_get_user_data(bo);
+ uint32_t width, height, stride, handle;
+ int ret;
+
+ if (fb) {
+ return fb;
+ }
+
+ fb = calloc(1, sizeof *fb);
+ fb->bo = bo;
+
+ width = gbm_bo_get_width(bo);
+ height = gbm_bo_get_height(bo);
+ stride = gbm_bo_get_stride(bo);
+ handle = gbm_bo_get_handle(bo).u32;
+
+ ret = drmModeAddFB(drmFd, width, height, 24, 32, stride, handle, &fb->fb_id);
+ if (ret) {
+ ERR_PRINT("failed to create fb: %s\n", strerror(errno));
+ free(fb);
+ return NULL;
+ } else {
+ DBG_PRINT("drmModeAddFB OK!\n");
+ }
+
+ gbm_bo_set_user_data(bo, fb, drm_fb_destroy_callback);
+
+ return fb;
+}
+
+JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_egl_gbm_WindowDriver_FirstSwapSurface0
+ (JNIEnv *env, jobject obj, jint drmFd, jint jcrtc_id, jint jx, jint jy,
+ jint jconnector_id, jobject jmode, jint jmode_byte_offset, jlong jgbmSurface)
+{
+ uint32_t crtc_id = (uint32_t)jcrtc_id;
+ uint32_t connector_id = (uint32_t)jconnector_id;
+ drmModeModeInfo *drmMode = NULL;
+ struct gbm_surface *gbmSurface = (struct gbm_surface *) (intptr_t) jgbmSurface;
+ struct gbm_bo *nextBO = NULL;
+ DRM_FB *fb = NULL;
+ int ret;
+
+ if ( NULL != jmode ) {
+ const char * c1 = (const char *) (*env)->GetDirectBufferAddress(env, jmode);
+ drmMode = (drmModeModeInfo *) (intptr_t) ( c1 + jmode_byte_offset );
+ }
+ nextBO = gbm_surface_lock_front_buffer(gbmSurface);
+ fb = drm_fb_get_from_bo(drmFd, nextBO);
+ if (!fb) {
+ ERR_PRINT("Failed to get a new framebuffer BO (0)\n");
+ return 0;
+ }
+ fb->x = (uint32_t)jx;
+ fb->y = (uint32_t)jy;
+ /**
+ * Set Mode
+ *
+ * Fails with x/y != 0: -28 No space left on device
+ * drmModeSetCrtc.0 failed to set mode: fd 26, crtc_id 0x27, fb_id 0x54, pos 10/10, conn_id 0x4d, curMode 1920x1080: -28 No space left on device
+ */
+ ret = drmModeSetCrtc(drmFd, crtc_id, fb->fb_id, fb->x, fb->y,
+ &connector_id, 1, drmMode);
+ if (ret) {
+ ERR_PRINT("drmModeSetCrtc.0 failed to set mode: fd %d, crtc_id 0x%x, fb_id 0x%x, pos %d/%d, conn_id 0x%x, curMode %s: %d %s\n",
+ drmFd, crtc_id, fb->fb_id, jx, jy, connector_id, drmMode->name, ret, strerror(errno));
+ return 0;
+ }
+ DBG_PRINT( "EGL_GBM.Window FirstSwapSurface0 nextBO %p, fd %d, crtc_id 0x%x, fb_id 0x%x, pos %d/%d, conn_id 0x%x, curMode %s\n",
+ nextBO, drmFd, crtc_id, fb->fb_id, jx, jy, connector_id, drmMode->name);
+ return (jlong) (intptr_t) nextBO;
+}
+
+JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_egl_gbm_WindowDriver_NextSwapSurface0
+ (JNIEnv *env, jobject obj, jint drmFd, jint jcrtc_id, jint jx, jint jy,
+ jint jconnector_id, jobject jmode, jint jmode_byte_offset, jlong jgbmSurface, jlong jlastBO)
+{
+ uint32_t crtc_id = (uint32_t)jcrtc_id;
+ uint32_t x = (uint32_t)jx;
+ uint32_t y = (uint32_t)jy;
+ uint32_t connector_id = (uint32_t)jconnector_id;
+ drmModeModeInfo *drmMode = NULL;
+ struct gbm_surface *gbmSurface = (struct gbm_surface *) (intptr_t) jgbmSurface;
+ struct gbm_bo *lastBO = (struct gbm_bo*) (intptr_t) jlastBO, *nextBO = NULL;
+ DRM_FB *fbNext = NULL;
+ int ret, waiting_for_flip = 1;
+ fd_set fds;
+
+ if ( NULL != jmode ) {
+ const char * c1 = (const char *) (*env)->GetDirectBufferAddress(env, jmode);
+ drmMode = (drmModeModeInfo *) (intptr_t) ( c1 + jmode_byte_offset );
+ }
+ nextBO = gbm_surface_lock_front_buffer(gbmSurface);
+ fbNext = drm_fb_get_from_bo(drmFd, nextBO);
+ if (!fbNext) {
+ ERR_PRINT("Failed to get a new framebuffer BO (1)\n");
+ return 0;
+ }
+ if( fbNext->x != x || fbNext->y != y ) {
+ // position changed, hard drmModeSetCrtc(..) w/o vsync
+ fbNext->x = x;
+ fbNext->y = y;
+
+ /**
+ * Set Mode
+ *
+ * Fails with x/y != 0: -28 No space left on device
+ * drmModeSetCrtc.0 failed to set mode: fd 26, crtc_id 0x27, fb_id 0x54, pos 10/10, conn_id 0x4d, curMode 1920x1080: -28 No space left on device
+ */
+ ret = drmModeSetCrtc(drmFd, crtc_id, fbNext->fb_id, fbNext->x, fbNext->y,
+ &connector_id, 1, drmMode);
+
+ if (ret) {
+ ERR_PRINT("drmModeSetCrtc.1 failed to set mode: fd %d, crtc_id 0x%x, fb_id 0x%x, pos %d/%d, conn_id 0x%x, curMode %s: %d %s\n",
+ drmFd, crtc_id, fbNext->fb_id, jx, jy, connector_id, drmMode->name, ret, strerror(errno));
+ return 0;
+ }
+ } else {
+ // same position, use vsync
+ ret = drmModePageFlip(drmFd, crtc_id, fbNext->fb_id,
+ DRM_MODE_PAGE_FLIP_EVENT, &waiting_for_flip);
+ if (ret) {
+ ERR_PRINT("drmModePageFlip.1 failed to queue page flip: fd %d, crtc_id 0x%x, fb_id 0x%x, conn_id 0x%x, curMode %s: %p -> %p: %d %s\n",
+ drmFd, crtc_id, fbNext->fb_id, connector_id, drmMode->name, lastBO, nextBO, ret, strerror(errno));
+ return 0;
+ }
+
+ while (waiting_for_flip) {
+ FD_ZERO(&fds);
+ FD_SET(0, &fds);
+ FD_SET(drmFd, &fds);
+
+ ret = select(drmFd + 1, &fds, NULL, NULL, NULL);
+ if (ret < 0) {
+ ERR_PRINT("drm.select: select err: %s\n", strerror(errno));
+ return ret;
+ } else if (ret == 0) {
+ ERR_PRINT("drm.select: select timeout!\n");
+ return -1;
+ } else if (FD_ISSET(0, &fds)) {
+ ERR_PRINT("drm.select: user interrupted!\n");
+ return 0;
+ }
+ drmHandleEvent(drmFd, &drm_event_ctx);
+ }
+ }
+
+ /* release last buffer to render on again: */
+ if( NULL != lastBO ) {
+ gbm_surface_release_buffer(gbmSurface, lastBO);
+ }
+
+ DBG_PRINT( "EGL_GBM.Window NextSwapSurface0 %p -> %p\n", lastBO, nextBO);
+ return (jlong) (intptr_t) nextBO;
+}
+
diff --git a/src/newt/native/egl_gbm.c b/src/newt/native/egl_gbm.c
deleted file mode 100644
index afbab9ef2..000000000
--- a/src/newt/native/egl_gbm.c
+++ /dev/null
@@ -1,353 +0,0 @@
-#include "egl_gbm.h"
-
-static jmethodID notifyScreenModeID = NULL;
-
-static jmethodID sizeChangedID = NULL;
-static jmethodID positionChangedID = NULL;
-static jmethodID visibleChangedID = NULL;
-static jmethodID windowDestroyNotifyID = NULL;
-
-/**
- * Display
- */
-
-static void freeDrm(DRM_HANDLE *drm) {
- if( NULL != drm ) {
- if( NULL != drm->encoder ) {
- drmModeFreeEncoder(drm->encoder);
- drm->encoder = NULL;
- }
- if( NULL != drm->connector ) {
- drmModeFreeConnector(drm->connector);
- drm->connector = NULL;
- }
- if( 0 <= drm->fd ) {
- drmClose(drm->fd);
- drm->fd = -1;
- }
- free(drm);
- }
-}
-
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_egl_gbm_DisplayDriver_initIDs
- (JNIEnv *env, jclass clazz)
-{
- DBG_PRINT( "EGL_GBM.Display initIDs ok\n" );
- return JNI_TRUE;
-}
-
-JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_egl_gbm_DisplayDriver_initDrm
- (JNIEnv *env, jclass clazz, jboolean verbose)
-{
- static const char *linux_dri_card0 = "/dev/dri/card0";
- static const char *modules[] = {
- "i915", "radeon", "nouveau", "vmwgfx", "omapdrm", "exynos", "msm"
- };
- int module_count = sizeof(modules) / sizeof(const char*);
- const char * module_used = NULL;
- int ret, i, j, area;
- DRM_HANDLE *drm = calloc(1, sizeof(DRM_HANDLE));
- drmModeRes *resources = NULL;
-
-#ifdef VERBOSE_ON
- verbose = JNI_TRUE;
-#endif
-
- if( verbose ) {
- ERR_PRINT( "EGL_GBM.Display initDrm start\n");
- }
-
- drm->fd = -1;
-
-#if 1
- // try linux_dri_card0 first
- drm->fd = open(linux_dri_card0, O_RDWR);
- ERR_PRINT("EGL_GBM.Display trying to open '%s': success %d\n",
- linux_dri_card0, 0<=drm->fd);
-#endif
-
- // try drm modules
- for (i = 0; 0>drm->fd && i < module_count; i++) {
- if( verbose ) {
- ERR_PRINT("EGL_GBM.Display trying to load module[%d/%d] %s...",
- i, module_count, modules[i]);
- }
- drm->fd = drmOpen(modules[i], NULL);
- if (drm->fd < 0) {
- if( verbose ) {
- ERR_PRINT("failed.\n");
- }
- } else {
- if( verbose ) {
- ERR_PRINT("success.\n");
- }
- module_used = modules[i];
- }
- }
- if (drm->fd < 0) {
- ERR_PRINT("EGL_GBM.Display could not open drm device\n");
- goto error;
- }
-
-#if 1
- ret = drmSetMaster(drm->fd);
- if(ret) {
- //drmDropMaster(int fd);
- DBG_PRINT( "EGL_GBM.Display drmSetMaster fd %d: FAILED: %d %s\n",
- drm->fd, ret, strerror(errno));
- } else {
- DBG_PRINT( "EGL_GBM.Display drmSetMaster fd %d: OK\n", drm->fd);
- }
-#endif
-
- resources = drmModeGetResources(drm->fd);
- if ( NULL == resources ) {
- ERR_PRINT("EGL_GBM.Display drmModeGetResources failed on module %s: %s\n",
- module_used, strerror(errno));
- goto error;
- }
-
- if( verbose ) {
- for (i = 0; i < resources->count_connectors; i++) {
- drmModeConnector * c = drmModeGetConnector(drm->fd, resources->connectors[i]);
- int chosen = DRM_MODE_CONNECTED == c->connection;
- ERR_PRINT( "EGL_GBM.Display Connector %d/%d chosen %d: id[con 0x%x, enc 0x%x], type %d[id 0x%x], connection %d, dim %dx%x mm, modes %d, encoders %d\n",
- i, resources->count_connectors, chosen,
- c->connector_id, c->encoder_id, c->connector_type, c->connector_type_id,
- c->connection, c->mmWidth, c->mmHeight, c->count_modes, c->count_encoders);
- drmModeFreeConnector(c);
- }
- }
- /* find a connected connector: */
- for (i = 0; i < resources->count_connectors; i++) {
- drm->connector = drmModeGetConnector(drm->fd, resources->connectors[i]);
- if( DRM_MODE_CONNECTED == drm->connector->connection ) {
- break;
- } else {
- drmModeFreeConnector(drm->connector);
- drm->connector = NULL;
- }
- }
- if( i >= resources->count_connectors ) {
- /* we could be fancy and listen for hotplug events and wait for
- * a connector..
- */
- ERR_PRINT("EGL_GBM.Display no connected connector (connector count %d, module %s)!\n",
- resources->count_connectors, module_used);
- goto error;
- }
-
- /* find highest resolution mode: */
- for (i = 0, j = -1, area = 0; i < drm->connector->count_modes; i++) {
- drmModeModeInfo *current_mode = &drm->connector->modes[i];
- int current_area = current_mode->hdisplay * current_mode->vdisplay;
- if (current_area > area) {
- drm->current_mode = current_mode;
- area = current_area;
- j = i;
- }
- if( verbose ) {
- ERR_PRINT( "EGL_GBM.Display Mode %d/%d (max-chosen %d): clock %d, %dx%d @ %d Hz, type %d, name <%s>\n",
- i, drm->connector->count_modes, j,
- current_mode->clock, current_mode->hdisplay, current_mode->vdisplay, current_mode->vrefresh,
- current_mode->type, current_mode->name);
- }
- }
- if ( NULL == drm->current_mode ) {
- ERR_PRINT("EGL_GBM.Display could not find mode (module %s)!\n", module_used);
- goto error;
- }
-
- if( verbose ) {
- for (i = 0; i < resources->count_encoders; i++) {
- drmModeEncoder * e = drmModeGetEncoder(drm->fd, resources->encoders[i]);
- int chosen = e->encoder_id == drm->connector->encoder_id;
- ERR_PRINT( "EGL_GBM.Display Encoder %d/%d chosen %d: id 0x%x, type %d, crtc_id 0x%x, possible[crtcs %d, clones %d]\n",
- i, resources->count_encoders, chosen,
- e->encoder_id, e->encoder_type, e->crtc_id,
- e->possible_crtcs, e->possible_clones);
- drmModeFreeEncoder(e);
- }
- }
- /* find encoder: */
- for (i = 0; i < resources->count_encoders; i++) {
- drm->encoder = drmModeGetEncoder(drm->fd, resources->encoders[i]);
- if( drm->encoder->encoder_id == drm->connector->encoder_id ) {
- break;
- } else {
- drmModeFreeEncoder(drm->encoder);
- drm->encoder = NULL;
- }
- }
- if ( i >= resources->count_encoders ) {
- ERR_PRINT("EGL_GBM.Display no encoder (module %s)!\n", module_used);
- goto error;
- }
- for (i = 0; i < resources->count_crtcs; i++) {
- if (resources->crtcs[i] == drm->encoder->crtc_id) {
- drm->crtc_index = i;
- break;
- }
- }
-
- drmModeFreeResources(resources);
- resources = NULL;
-
- if( verbose ) {
- DBG_PRINT( "EGL_GBM.Display initDrm end.X0 OK: fd %d, enc_id 0x%x, crtc_id 0x%x, conn_id 0x%x, curMode %s\n",
- drm->fd, drm->encoder->encoder_id, drm->encoder->crtc_id, drm->connector->connector_id, drm->current_mode->name);
- }
-
- // drm->crtc_id = encoder->crtc_id;
- // drm->connector_id = connector->connector_id;
- return (jlong) (intptr_t) drm;
-
-error:
- if( verbose ) {
- DBG_PRINT( "EGL_GBM.Display initDrm end.X2 ERROR\n");
- }
- drmModeFreeResources(resources);
- resources = NULL;
- freeDrm(drm);
- return 0;
-}
-
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_egl_gbm_DisplayDriver_freeDrm
- (JNIEnv *env, jclass clazz, jlong jdrm) {
- freeDrm( (DRM_HANDLE*) (intptr_t) jdrm );
-}
-
-JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_egl_gbm_DisplayDriver_OpenGBMDisplay0
- (JNIEnv *env, jclass clazz, jlong jdrm)
-{
- DRM_HANDLE *drm = (DRM_HANDLE*) (intptr_t) jdrm;
- struct gbm_device * dev = gbm_create_device(drm->fd);
- DBG_PRINT( "EGL_GBM.Display OpenGBMDisplay0 handle %p\n", dev);
- return (jlong) (intptr_t) dev;
-}
-
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_egl_gbm_DisplayDriver_CloseGBMDisplay0
- (JNIEnv *env, jclass clazz, jlong jgbm)
-{
- struct gbm_device * dev = (struct gbm_device *) (intptr_t) jgbm;
- DBG_PRINT( "EGL_GBM.Display CloseGBMDisplay0 handle %p\n", dev);
- gbm_device_destroy(dev);
-}
-
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_egl_gbm_DisplayDriver_DispatchMessages0
- (JNIEnv *env, jclass clazz)
-{
-}
-
-/**
- * Screen
- */
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_egl_gbm_ScreenDriver_initIDs
- (JNIEnv *env, jclass clazz)
-{
- notifyScreenModeID = (*env)->GetMethodID(env, clazz, "notifyScreenMode", "(III)V");
- if (notifyScreenModeID == NULL) {
- DBG_PRINT( "EGL_GBM.Screen initIDs FALSE\n" );
- return JNI_FALSE;
- }
- DBG_PRINT( "EGL_GBM.Screen initIDs ok\n" );
- return JNI_TRUE;
-}
-
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_egl_gbm_ScreenDriver_initNative
- (JNIEnv *env, jobject obj, jlong jdrm)
-{
- DRM_HANDLE *drm = (DRM_HANDLE*) (intptr_t) jdrm;
- uint32_t screen_width = 0;
- uint32_t screen_height = 0;
- uint32_t screen_vrefresh = 0;
- int32_t success = 0;
-
- if( NULL != drm ) {
- /**
- connector.modes.hdisplay; // width
- connector.modes.vdisplay; // height
- connector.modes.flags; // flags
- encoder.crtc_id; // crt_idx
- */
- screen_width = drm->current_mode->hdisplay;
- screen_height = drm->current_mode->vdisplay;
- screen_vrefresh = drm->current_mode->vrefresh;
-
- DBG_PRINT( "EGL_GBM.Screen initNative ok %dx%d @ %d\n", screen_width, screen_height, screen_vrefresh );
- (*env)->CallVoidMethod(env, obj, notifyScreenModeID, (jint) screen_width, (jint) screen_height, (jint) screen_vrefresh);
- } else {
- DBG_PRINT( "BCM.Screen initNative failed\n" );
- }
-}
-
-/**
- * Window
- */
-
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_egl_gbm_WindowDriver_initIDs
- (JNIEnv *env, jclass clazz)
-{
- sizeChangedID = (*env)->GetMethodID(env, clazz, "sizeChanged", "(ZIIZ)V");
- positionChangedID = (*env)->GetMethodID(env, clazz, "positionChanged", "(ZII)V");
- visibleChangedID = (*env)->GetMethodID(env, clazz, "visibleChanged", "(Z)V");
- windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "(Z)Z");
- if (sizeChangedID == NULL ||
- positionChangedID == NULL ||
- visibleChangedID == NULL ||
- windowDestroyNotifyID == NULL) {
- DBG_PRINT( "initIDs failed\n" );
- return JNI_FALSE;
- }
- DBG_PRINT( "EGL_GBM.Window initIDs ok\n" );
- return JNI_TRUE;
-}
-
-#ifndef DRM_FORMAT_MOD_LINEAR
- #define DRM_FORMAT_MOD_LINEAR 0
-#endif
-
-WEAK struct gbm_surface *
-gbm_surface_create_with_modifiers(struct gbm_device *gbm,
- uint32_t width, uint32_t height,
- uint32_t format,
- const uint64_t *modifiers,
- const unsigned int count);
-
-JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_egl_gbm_WindowDriver_CreateWindow0
- (JNIEnv *env, jobject obj, jlong jdrm, jlong jgbm, jint x, jint y, jint width, jint height, jint visual_id)
-{
- DRM_HANDLE *drm = (DRM_HANDLE*) (intptr_t) jdrm;
- struct gbm_device *dev = (struct gbm_device *) (intptr_t) jgbm;
- uint64_t modifier = DRM_FORMAT_MOD_LINEAR;
- struct gbm_surface *surface = NULL;
-
- if( gbm_surface_create_with_modifiers ) {
- surface = gbm_surface_create_with_modifiers(dev, width, height, visual_id, &modifier, 1);
- }
- if( NULL == surface ) {
- if( gbm_surface_create_with_modifiers ) {
- DBG_PRINT( "EGL_GBM.Window CreateWindow0 gbm_surface_create_with_modifiers failed\n");
- }
- surface = gbm_surface_create(dev, width, height, visual_id, GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
- }
- if ( NULL == surface ) {
- DBG_PRINT( "EGL_GBM.Window CreateWindow0 gbm_surface_create failed\n");
- return 0;
- }
-
- // Done in Java code ..
- // (*env)->CallVoidMethod(env, obj, visibleChangedID, JNI_TRUE);
-
- DBG_PRINT( "EGL_GBM.Window CreateWindow0 handle %p\n", surface);
- return (jlong) (intptr_t) surface;
-}
-
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_egl_gbm_WindowDriver_CloseWindow0
- (JNIEnv *env, jobject obj, jlong display, jlong window)
-{
- struct gbm_surface *surface = (struct gbm_surface *) (intptr_t) window;
- DBG_PRINT( "EGL_GBM.Window CloseWindow0 handle %p\n", surface);
- gbm_surface_destroy(surface);
-}
-
diff --git a/src/newt/native/egl_gbm_drmflip.c b/src/newt/native/egl_gbm_drmflip.c
deleted file mode 100644
index 4dda026a0..000000000
--- a/src/newt/native/egl_gbm_drmflip.c
+++ /dev/null
@@ -1,230 +0,0 @@
-#include "egl_gbm.h"
-
-#include <EGL/egl.h>
-
-WEAK uint64_t
-gbm_bo_get_modifier(struct gbm_bo *bo);
-
-WEAK int
-gbm_bo_get_plane_count(struct gbm_bo *bo);
-
-WEAK uint32_t
-gbm_bo_get_stride_for_plane(struct gbm_bo *bo, int plane);
-
-WEAK uint32_t
-gbm_bo_get_offset(struct gbm_bo *bo, int plane);
-
-typedef struct {
- struct gbm_bo *bo;
- uint32_t fb_id;
-} DRM_FB;
-
-static void page_flip_handler(int fd, unsigned int frame,
- unsigned int sec, unsigned int usec, void *data)
-{
- /* suppress 'unused parameter' warnings */
- (void)fd, (void)frame, (void)sec, (void)usec;
-
- int *waiting_for_flip = data;
- *waiting_for_flip = 0;
-}
-
-static drmEventContext drm_event_ctx = {
- .version = 2,
- .page_flip_handler = page_flip_handler,
- };
-
-static void drm_fb_destroy_callback(struct gbm_bo *bo, void *data)
-{
- struct gbm_device * gbmDev = gbm_bo_get_device(bo);
- int drm_fd = gbm_device_get_fd(gbmDev);
- DRM_FB *fb = data;
-
- if (fb->fb_id)
- drmModeRmFB(drm_fd, fb->fb_id);
-
- free(fb);
-}
-
-static DRM_FB * drm_fb_get_from_bo(struct gbm_bo *bo)
-{
- struct gbm_device * gbmDev = gbm_bo_get_device(bo);
- int drm_fd = gbm_device_get_fd(gbmDev);
- DRM_FB *fb = gbm_bo_get_user_data(bo);
- uint32_t width, height, format,
- strides[4] = {0}, handles[4] = {0},
- offsets[4] = {0}, flags = 0;
- int ret = -1;
-
- if (fb)
- return fb;
-
- fb = calloc(1, sizeof *fb);
- fb->bo = bo;
-
- width = gbm_bo_get_width(bo);
- height = gbm_bo_get_height(bo);
- format = gbm_bo_get_format(bo);
-
- if (gbm_bo_get_modifier && gbm_bo_get_plane_count &&
- gbm_bo_get_stride_for_plane && gbm_bo_get_offset) {
-
- uint64_t modifiers[4] = {0};
- modifiers[0] = gbm_bo_get_modifier(bo);
- const int num_planes = gbm_bo_get_plane_count(bo);
- for (int i = 0; i < num_planes; i++) {
- strides[i] = gbm_bo_get_stride_for_plane(bo, i);
- handles[i] = gbm_bo_get_handle(bo).u32;
- offsets[i] = gbm_bo_get_offset(bo, i);
- modifiers[i] = modifiers[0];
- }
-
- if (modifiers[0]) {
- flags = DRM_MODE_FB_MODIFIERS;
- DBG_PRINT("Using modifier %" PRIx64 "\n", modifiers[0]);
- }
-
- ret = drmModeAddFB2WithModifiers(drm_fd, width, height,
- format, handles, strides, offsets,
- modifiers, &fb->fb_id, flags);
- if(ret) {
- ERR_PRINT("drmModeAddFB2WithModifiers failed!\n");
- } else {
- ERR_PRINT("drmModeAddFB2WithModifiers OK!\n");
- }
- }
-
- if (ret) {
- memcpy(handles, (uint32_t [4]){gbm_bo_get_handle(bo).u32,0,0,0}, 16);
- memcpy(strides, (uint32_t [4]){gbm_bo_get_stride(bo),0,0,0}, 16);
- memset(offsets, 0, 16);
- ret = drmModeAddFB2(drm_fd, width, height, format,
- handles, strides, offsets, &fb->fb_id, 0);
- if(ret) {
- ERR_PRINT("drmModeAddFB2 failed!\n");
- } else {
- ERR_PRINT("drmModeAddFB2 OK!\n");
- }
- }
-
- if (ret) {
- ERR_PRINT("failed to create fb: %s\n", strerror(errno));
- free(fb);
- return NULL;
- }
-
- gbm_bo_set_user_data(bo, fb, drm_fb_destroy_callback);
-
- return fb;
-}
-
-JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_egl_gbm_WindowDriver_FirstSwapSurface0
- (JNIEnv *env, jobject obj, jlong jdrm, jlong jgbmSurface, jlong jeglDisplay, jlong jeglSurface)
-{
- DRM_HANDLE *drm = (DRM_HANDLE*) (intptr_t) jdrm;
- struct gbm_surface *gbmSurface = (struct gbm_surface *) (intptr_t) jgbmSurface;
- EGLDisplay eglDisplay = (EGLDisplay) (intptr_t) jeglDisplay;
- EGLSurface eglSurface = (EGLSurface) (intptr_t) jeglSurface;
- struct gbm_bo *nextBO = NULL;
- DRM_FB *fb = NULL;
- int ret;
-
- if ( EGL_TRUE != eglSwapBuffers(eglDisplay, eglSurface) ) {
- EGLint err = eglGetError();
- ERR_PRINT("Failed eglSwapBuffers, err 0x%x\n", err);
- return 0;
- }
- nextBO = gbm_surface_lock_front_buffer(gbmSurface);
- fb = drm_fb_get_from_bo(nextBO);
- if (!fb) {
- ERR_PRINT("Failed to get a new framebuffer BO\n");
- return 0;
- }
- /* set mode: */
- ret = drmModeSetCrtc(drm->fd, drm->encoder->crtc_id, fb->fb_id, 0, 0,
- &drm->connector->connector_id, 1, drm->current_mode);
- /**
- int drmModeSetCrtc(int fd, uint32_t crtcId, uint32_t bufferId,
- uint32_t x, uint32_t y, uint32_t *connectors, int count,
- drmModeModeInfoPtr mode);
- */
-
- if (ret) {
- ERR_PRINT("drmModeSetCrtc failed to set mode: fd %d, enc_id 0x%x, crtc_id 0x%x, fb_id 0x%x, conn_id 0x%x, curMode %s: %d %s\n",
- drm->fd, drm->encoder->encoder_id, drm->encoder->crtc_id, fb->fb_id,
- drm->connector->connector_id, drm->current_mode->name, ret, strerror(errno));
- return 0;
- }
- DBG_PRINT( "EGL_GBM.Window FirstSwapSurface0 nextBO %p, fd %d, enc_id 0x%x, crtc_id 0x%x, fb_id 0x%x, conn_id 0x%x, curMode %s\n",
- nextBO,
- drm->fd, drm->encoder->encoder_id, drm->encoder->crtc_id, fb->fb_id,
- drm->connector->connector_id, drm->current_mode->name);
- return (jlong) (intptr_t) nextBO;
-}
-
-JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_egl_gbm_WindowDriver_NextSwapSurface0
- (JNIEnv *env, jobject obj, jlong jdrm, jlong jgbmSurface, jlong jlastBO, jlong jeglDisplay, jlong jeglSurface)
-{
- DRM_HANDLE *drm = (DRM_HANDLE*) (intptr_t) jdrm;
- struct gbm_surface *gbmSurface = (struct gbm_surface *) (intptr_t) jgbmSurface;
- struct gbm_bo *lastBO = (struct gbm_bo*) (intptr_t) jlastBO, *nextBO = NULL;
- EGLDisplay eglDisplay = (EGLDisplay) (intptr_t) jeglDisplay;
- EGLSurface eglSurface = (EGLSurface) (intptr_t) jeglSurface;
- DRM_FB *fb = NULL;
- int ret, waiting_for_flip = 1;
- fd_set fds;
-
- if ( EGL_TRUE != eglSwapBuffers(eglDisplay, eglSurface) ) {
- EGLint err = eglGetError();
- ERR_PRINT("Failed eglSwapBuffers, err 0x%x\n", err);
- return 0;
- }
- nextBO = gbm_surface_lock_front_buffer(gbmSurface);
- fb = drm_fb_get_from_bo(nextBO);
- if (!fb) {
- ERR_PRINT("Failed to get a new framebuffer BO\n");
- return 0;
- }
-
- /**
- * Here you could also update drm plane layers if you want
- * hw composition
- */
- ret = drmModePageFlip(drm->fd, drm->encoder->crtc_id, fb->fb_id,
- DRM_MODE_PAGE_FLIP_EVENT, &waiting_for_flip);
- if (ret) {
- ERR_PRINT("drmModePageFlip failed to queue page flip: fd %d, enc_id 0x%x, crtc_id 0x%x, fb_id 0x%x, conn_id 0x%x, curMode %s: %p -> %p: %d %s\n",
- drm->fd, drm->encoder->encoder_id, drm->encoder->crtc_id, fb->fb_id,
- drm->connector->connector_id, drm->current_mode->name,
- lastBO, nextBO, ret, strerror(errno));
- return 0;
- }
-
- while (waiting_for_flip) {
- FD_ZERO(&fds);
- FD_SET(0, &fds);
- FD_SET(drm->fd, &fds);
-
- ret = select(drm->fd + 1, &fds, NULL, NULL, NULL);
- if (ret < 0) {
- ERR_PRINT("select err: %s\n", strerror(errno));
- return ret;
- } else if (ret == 0) {
- ERR_PRINT("select timeout!\n");
- return -1;
- } else if (FD_ISSET(0, &fds)) {
- ERR_PRINT("user interrupted!\n");
- return 0;
- }
- drmHandleEvent(drm->fd, &drm_event_ctx);
- }
-
- /* release last buffer to render on again: */
- if( NULL != lastBO ) {
- gbm_surface_release_buffer(gbmSurface, lastBO);
- }
-
- DBG_PRINT( "EGL_GBM.Window NextSwapSurface0 %p -> %p\n", lastBO, nextBO);
- return (jlong) (intptr_t) nextBO;
-}
-