protected override void Dispose(bool manual)
 {
     if (manual)
     {
         // Reset the scanout region
         LinuxWindowInfo wnd = WindowInfo as LinuxWindowInfo;
         if (wnd != null)
         {
             unsafe
             {
                 int      connector_id = wnd.DisplayDevice.pConnector->connector_id;
                 ModeInfo mode         = wnd.DisplayDevice.OriginalMode;
                 Drm.ModeSetCrtc(fd,
                                 wnd.DisplayDevice.pCrtc->crtc_id,
                                 wnd.DisplayDevice.pCrtc->buffer_id,
                                 wnd.DisplayDevice.pCrtc->x,
                                 wnd.DisplayDevice.pCrtc->y,
                                 &connector_id,
                                 1,
                                 &mode);
             }
         }
     }
     base.Dispose(manual);
 }
        private void SetScanoutRegion(int buffer)
        {
            LinuxWindowInfo wnd = WindowInfo as LinuxWindowInfo;

            if (wnd == null)
            {
                throw new InvalidOperationException();
            }

            unsafe
            {
                ModeInfo *mode         = wnd.DisplayDevice.pConnector->modes;
                int       connector_id = wnd.DisplayDevice.pConnector->connector_id;
                int       crtc_id      = wnd.DisplayDevice.Id;

                int x = 0;
                int y = 0;
                int connector_count = 1;
                int ret             = Drm.ModeSetCrtc(fd, crtc_id, buffer, x, y,
                                                      &connector_id, connector_count, mode);

                if (ret != 0)
                {
                    Debug.Print("[KMS] Drm.ModeSetCrtc{0}, {1}, {2}, {3}, {4:x}, {5}, {6:x}) failed. Error: {7}",
                                fd, crtc_id, buffer, x, y, (IntPtr)connector_id, connector_count, (IntPtr)mode, ret);
                }
            }
        }
        public LinuxNativeWindow(IntPtr display, IntPtr gbm, int fd,
            int x, int y, int width, int height, string title,
            GraphicsMode mode, GameWindowFlags options,
            DisplayDevice display_device)
        {
            Debug.Print("[KMS] Creating window on display {0:x}", display);

            Title = title;

            display_device = display_device ?? DisplayDevice.Default;
            if (display_device == null)
            {
                throw new NotSupportedException("[KMS] Driver does not currently support headless systems");
            }

            window = new LinuxWindowInfo(display, fd, gbm, display_device.Id as LinuxDisplay);

            // Note: we only support fullscreen windows on KMS.
            // We implicitly override the requested width and height
            // by the width and height of the DisplayDevice, if any.
            width = display_device.Width;
            height = display_device.Height;
            bounds = new Rectangle(0, 0, width, height);
            client_size = bounds.Size;

            if (!mode.Index.HasValue)
            {
                mode = new EglGraphicsMode().SelectGraphicsMode(window, mode, 0);
            }
            Debug.Print("[KMS] Selected EGL mode {0}", mode);

            SurfaceFormat format = GetSurfaceFormat(display, mode);
            SurfaceFlags usage = SurfaceFlags.Rendering | SurfaceFlags.Scanout;
            if (!Gbm.IsFormatSupported(gbm, format, usage))
            {
                Debug.Print("[KMS] Failed to find suitable surface format, using XRGB8888");
                format = SurfaceFormat.XRGB8888;
            }

            Debug.Print("[KMS] Creating GBM surface on {0:x} with {1}x{2} {3} [{4}]",
                gbm, width, height, format, usage);
            IntPtr gbm_surface =  Gbm.CreateSurface(gbm,
                    width, height, format, usage);
            if (gbm_surface == IntPtr.Zero)
            {
                throw new NotSupportedException("[KMS] Failed to create GBM surface for rendering");
            }

            window.Handle = gbm_surface;
                Debug.Print("[KMS] Created GBM surface {0:x}", window.Handle);

            window.CreateWindowSurface(mode.Index.Value);
            Debug.Print("[KMS] Created EGL surface {0:x}", window.Surface);

            cursor_default = CreateCursor(gbm, Cursors.Default);
            cursor_empty = CreateCursor(gbm, Cursors.Empty);
            Cursor = MouseCursor.Default;
            exists = true;
        }
        public LinuxGraphicsContext(GraphicsMode mode, LinuxWindowInfo window, IGraphicsContext sharedContext,
            int major, int minor, GraphicsContextFlags flags)
            : base(mode, window, sharedContext, major, minor, flags)
        {
            if (mode.Buffers < 1)
                throw new ArgumentException();
            fd = window.FD;

            PageFlip = HandlePageFlip;
            PageFlipPtr = Marshal.GetFunctionPointerForDelegate(PageFlip);
        }
        public LinuxGraphicsContext(GraphicsMode mode, LinuxWindowInfo window, IGraphicsContext sharedContext,
                                    int major, int minor, GraphicsContextFlags flags)
            : base(mode, window, sharedContext, major, minor, flags)
        {
            if (mode.Buffers < 1)
            {
                throw new ArgumentException();
            }
            fd = window.FD;

            PageFlip    = HandlePageFlip;
            PageFlipPtr = Marshal.GetFunctionPointerForDelegate(PageFlip);
        }
        private void QueueFlip(int buffer)
        {
            LinuxWindowInfo wnd = WindowInfo as LinuxWindowInfo;

            if (wnd == null)
            {
                throw new InvalidOperationException();
            }

            unsafe
            {
                int ret = Drm.ModePageFlip(fd, wnd.DisplayDevice.Id, buffer,
                                           PageFlipFlags.FlipEvent, IntPtr.Zero);

                if (ret < 0)
                {
                    Debug.Print("[KMS] Failed to enqueue framebuffer flip. Error: {0}", ret);
                }

                is_flip_queued = true;
            }
        }
Exemple #7
0
        public LinuxNativeWindow(IntPtr display, IntPtr gbm, int fd,
                                 int x, int y, int width, int height, string title,
                                 GraphicsMode mode, GameWindowFlags options,
                                 DisplayDevice display_device)
        {
            Debug.Print("[KMS] Creating window on display {0:x}", display);

            Title = title;

            display_device = display_device ?? DisplayDevice.Default;
            if (display_device == null)
            {
                throw new NotSupportedException("[KMS] Driver does not currently support headless systems");
            }

            window = new LinuxWindowInfo(display, fd, gbm, display_device.Id as LinuxDisplay);

            // Note: we only support fullscreen windows on KMS.
            // We implicitly override the requested width and height
            // by the width and height of the DisplayDevice, if any.
            width       = display_device.Width;
            height      = display_device.Height;
            bounds      = new Rectangle(0, 0, width, height);
            client_size = bounds.Size;

            if (!mode.Index.HasValue)
            {
                mode = new EglGraphicsMode().SelectGraphicsMode(window, mode, 0);
            }
            Debug.Print("[KMS] Selected EGL mode {0}", mode);

            SurfaceFormat format = GetSurfaceFormat(display, mode);
            SurfaceFlags  usage  = SurfaceFlags.Rendering | SurfaceFlags.Scanout;

            if (!Gbm.IsFormatSupported(gbm, format, usage))
            {
                Debug.Print("[KMS] Failed to find suitable surface format, using XRGB8888");
                format = SurfaceFormat.XRGB8888;
            }

            Debug.Print("[KMS] Creating GBM surface on {0:x} with {1}x{2} {3} [{4}]",
                        gbm, width, height, format, usage);
            IntPtr gbm_surface = Gbm.CreateSurface(gbm,
                                                   width, height, format, usage);

            if (gbm_surface == IntPtr.Zero)
            {
                throw new NotSupportedException("[KMS] Failed to create GBM surface for rendering");
            }

            window.Handle = gbm_surface;
            Debug.Print("[KMS] Created GBM surface {0:x}", window.Handle);

            window.CreateWindowSurface(mode.Index.Value);
            Debug.Print("[KMS] Created EGL surface {0:x}", window.Surface);

            cursor_default = CreateCursor(gbm, Cursors.Default);
            cursor_empty   = CreateCursor(gbm, Cursors.Empty);
            Cursor         = MouseCursor.Default;
            exists         = true;
        }