Opentk/Source/OpenTK/Platform/Linux/LinuxFactory.cs

147 lines
4.9 KiB
C#
Raw Normal View History

2014-06-23 20:22:04 +00:00
#region License
//
// LinuxFactory.cs
//
// Author:
// Stefanos A. <stapostol@gmail.com>
//
// Copyright (c) 2006-2014 Stefanos Apostolopoulos
//
// 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.
//
#endregion
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using OpenTK.Graphics;
using OpenTK.Input;
2014-06-24 17:27:38 +00:00
using OpenTK.Platform.Egl;
2014-06-23 20:22:04 +00:00
namespace OpenTK.Platform.Linux
{
2014-06-24 17:27:38 +00:00
using Egl = OpenTK.Platform.Egl.Egl;
2014-06-23 20:22:04 +00:00
// Linux KMS platform
class LinuxFactory : PlatformFactoryBase
{
int fd;
2014-06-24 17:27:38 +00:00
GbmDevice gbm_device;
2014-06-23 20:22:04 +00:00
IntPtr display;
2014-06-24 17:27:38 +00:00
IJoystickDriver2 JoystickDriver;
IDisplayDeviceDriver DisplayDriver;
2014-06-23 20:22:04 +00:00
public LinuxFactory()
2014-06-24 17:27:38 +00:00
{
SetupEgl();
}
#region Private Members
void SetupEgl()
2014-06-23 20:22:04 +00:00
{
// Todo: support multi-GPU systems
string gpu = "/dev/dri/card0";
2014-06-24 17:27:38 +00:00
fd = Libc.open(gpu, OpenFlags.ReadWrite | OpenFlags.CloseOnExec);
2014-06-23 20:22:04 +00:00
if (fd < 0)
{
2014-06-24 17:27:38 +00:00
throw new NotSupportedException("[KMS] No KMS-capable GPU available");
2014-06-23 20:22:04 +00:00
}
2014-06-24 17:27:38 +00:00
Debug.Print("[KMS] GPU '{0}' opened as fd:{1}", gpu, fd);
2014-06-23 20:22:04 +00:00
IntPtr dev = Gbm.CreateDevice(fd);
if (dev == IntPtr.Zero)
{
2014-06-24 17:27:38 +00:00
throw new NotSupportedException("[KMS] Failed to create GBM device");
2014-06-23 20:22:04 +00:00
}
2014-06-24 17:27:38 +00:00
gbm_device = (GbmDevice)Marshal.PtrToStructure(dev, typeof(GbmDevice));
Debug.Print("[KMS] GBM {0:x} created successfully", dev);
2014-06-23 20:22:04 +00:00
2014-06-24 17:27:38 +00:00
display = Egl.GetDisplay(dev);
2014-06-23 20:22:04 +00:00
if (display == IntPtr.Zero)
{
2014-06-24 17:27:38 +00:00
throw new NotSupportedException("[KMS] Failed to create EGL display");
2014-06-23 20:22:04 +00:00
}
2014-06-24 17:27:38 +00:00
Debug.Print("[KMS] EGL display {0:x} created successfully", display);
2014-06-23 20:22:04 +00:00
int major, minor;
2014-06-24 17:27:38 +00:00
if (!Egl.Initialize(display, out major, out minor))
2014-06-23 20:22:04 +00:00
{
2014-06-24 17:27:38 +00:00
int error = Egl.GetError();
throw new NotSupportedException("[KMS] Failed to initialize EGL display. Error code: " + error);
2014-06-23 20:22:04 +00:00
}
2014-06-24 17:27:38 +00:00
Debug.Print("[KMS] EGL {0}.{1} initialized successfully on display {2:x}", major, minor, display);
2014-06-23 20:22:04 +00:00
}
2014-06-24 17:27:38 +00:00
#endregion
#region IPlatformFactory Members
public override INativeWindow CreateNativeWindow(int x, int y, int width, int height, string title, GraphicsMode mode, GameWindowFlags options, DisplayDevice display_device)
2014-06-23 20:22:04 +00:00
{
2014-06-24 17:27:38 +00:00
return new LinuxNativeWindow(display, gbm_device, width, height, title, mode, options, display_device);
2014-06-23 20:22:04 +00:00
}
public override IDisplayDeviceDriver CreateDisplayDeviceDriver()
{
2014-06-24 17:27:38 +00:00
lock (this)
{
DisplayDriver = DisplayDriver ?? new LinuxDisplayDriver(fd);
return DisplayDriver;
}
2014-06-23 20:22:04 +00:00
}
public override IGraphicsContext CreateGLContext(GraphicsMode mode, IWindowInfo window, IGraphicsContext shareContext, bool directRendering, int major, int minor, GraphicsContextFlags flags)
{
2014-06-24 17:27:38 +00:00
return new EglUnixContext(mode, (EglWindowInfo)window, shareContext, major, minor, flags);
2014-06-23 20:22:04 +00:00
}
public override GraphicsContext.GetCurrentContextDelegate CreateGetCurrentGraphicsContext()
{
2014-06-24 17:27:38 +00:00
return (GraphicsContext.GetCurrentContextDelegate)delegate
{
return new ContextHandle(Egl.GetCurrentContext());
};
2014-06-23 20:22:04 +00:00
}
public override IKeyboardDriver2 CreateKeyboardDriver()
{
throw new NotImplementedException();
}
public override IMouseDriver2 CreateMouseDriver()
{
throw new NotImplementedException();
}
public override IJoystickDriver2 CreateJoystickDriver()
{
2014-06-24 17:27:38 +00:00
lock (this)
{
JoystickDriver = JoystickDriver ?? new LinuxJoystick();
return JoystickDriver;
}
2014-06-23 20:22:04 +00:00
}
2014-06-24 17:27:38 +00:00
#endregion
2014-06-23 20:22:04 +00:00
}
}