Beispiel #1
0
        private bool PollReadable(int timeoutMs)
        {
            LibC.PollFd fd = new LibC.PollFd();
            fd.fd     = _drmFd;
            fd.events = LibC.POLLIN | LibC.POLLPRI;
            LibC.PollFd[] fds = new LibC.PollFd[] { fd };
            int           rc  = LibC.Poll(fds, timeoutMs);

            return(rc > 0);
        }
Beispiel #2
0
        public override void EnterMessageLoop(bool runInBackground)
        {
            bool running = true;

            SizeChanged?.Invoke(this, _width, _height);
            Activated?.Invoke(this);

            IntPtr bo         = Gbm.SurfaceLockFrontBuffer(_gbmSurface);
            uint   fb         = GetFbForBo(bo);
            IntPtr connectors = System.Runtime.InteropServices.Marshal.AllocHGlobal(sizeof(uint));

            System.Runtime.InteropServices.Marshal.WriteInt32(connectors, (int)_drmConnectorId);
            int rc = Drm.ModeSetCrtc(_drmFd, _drmEncoderCrtcId, fb, 0, 0, connectors, 1, ref _drmMode);

            System.Runtime.InteropServices.Marshal.FreeHGlobal(connectors);
            if (rc != 0)
            {
                throw new Exception("Failed to create DRM Mode");
            }

            while (running)
            {
                LibEvdev.HandleEvents();
                Render?.Invoke(this);

                IntPtr prevBo = bo;
                bo = Gbm.SurfaceLockFrontBuffer(_gbmSurface);
                fb = GetFbForBo(bo);

                Drm.ModePageFlip(_drmFd, _drmEncoderCrtcId, fb, Drm.MODE_PAGE_FLIP_EVENT, IntPtr.Zero);

                LibC.PollFd fd = new LibC.PollFd();
                fd.fd     = _drmFd;
                fd.events = LibC.POLLIN | LibC.POLLPRI;
                LibC.PollFd[] fds = new LibC.PollFd[] { fd };
                LibC.Poll(fds, -1);
                Drm.EventContext evctx = new Drm.EventContext();
                evctx.version = 2;
                Drm.HandleEvent(_drmFd, ref evctx);

                if (prevBo != IntPtr.Zero)
                {
                    Gbm.SurfaceReleaseBuffer(_gbmSurface, prevBo);
                }
            }
        }
Beispiel #3
0
        public GbmDisplay(string drmDevice)
        {
            _close = false;

            IntPtr udev = LibUdev.New();

            _drmFd = LibC.Open(drmDevice, LibC.O_RDWR);

            if (_drmFd == -1)
            {
                IntPtr udevMonitor = LibUdev.MonitorNewFromNetlink(udev, "udev");

                LibUdev.MonitorFilterAddMatchSubsystemDevtype(udevMonitor, "drm", null);
                LibUdev.MonitorEnableReceiving(udevMonitor);

                int udevMonitorFd = LibUdev.MonitorGetFd(udevMonitor);

                LibC.PollFd fd = new LibC.PollFd();
                fd.fd     = udevMonitorFd;
                fd.events = LibC.POLLIN | LibC.POLLPRI;
                LibC.PollFd[] fds = { fd };
                while (_drmFd == -1)
                {
                    int rc = LibC.Poll(fds, -1);
                    if (rc > 0)
                    {
                        IntPtr device = LibUdev.MonitorReceiveDevice(udevMonitor);

                        if (device == IntPtr.Zero)
                        {
                            break;
                        }

                        IntPtr deviceAction = LibUdev.DeviceGetAction(device);
                        IntPtr deviceName   = LibUdev.DeviceGetDevnode(device);

                        string devAction = System.Runtime.InteropServices.Marshal.PtrToStringAnsi(deviceAction);

                        if (devAction == "add")
                        {
                            _drmFd = LibC.Open(drmDevice, LibC.O_RDWR);
                        }

                        LibUdev.DeviceUnref(device);
                    }
                }

                LibUdev.MonitorUnref(udevMonitor);
            }

            LibUdev.Unref(udev);

            IntPtr resourcesPtr = Drm.ModeGetResources(_drmFd);

            Drm.ModeRes resources = System.Runtime.InteropServices.Marshal.PtrToStructure <Drm.ModeRes>(resourcesPtr);

            for (int i = 0; i < resources.countConnectors; ++i)
            {
                uint              connectorId  = (uint)System.Runtime.InteropServices.Marshal.ReadInt32(resources.connectors, i * sizeof(uint));
                IntPtr            connectorPtr = Drm.ModeGetConnector(_drmFd, connectorId);
                Drm.ModeConnector connector    = System.Runtime.InteropServices.Marshal.PtrToStructure <Drm.ModeConnector>(connectorPtr);
                if (connector.connection == Drm.MODE_CONNECTED)
                {
                    _drmConnectorId = connector.connectorId;

                    int SizeOfDrmModeModeInfo = System.Runtime.InteropServices.Marshal.SizeOf <Drm.ModeModeInfo>();
                    int area = 0;
                    for (int j = 0; j < connector.countModes; ++j)
                    {
                        Drm.ModeModeInfo drmMode = System.Runtime.InteropServices.Marshal.PtrToStructure <Drm.ModeModeInfo>(IntPtr.Add(connector.modes, j * SizeOfDrmModeModeInfo));
                        if ((drmMode.type & Drm.MODE_TYPE_PREFERRED) != 0)
                        {
                            int modeArea = drmMode.hdisplay * drmMode.vdisplay;
                            if (modeArea > area)
                            {
                                _drmMode = drmMode;
                                _width   = drmMode.hdisplay;
                                _height  = drmMode.vdisplay;
                                area     = modeArea;
                            }
                        }
                    }

                    for (int j = 0; j < resources.countEncoders; ++j)
                    {
                        uint            encoderId  = (uint)System.Runtime.InteropServices.Marshal.ReadInt32(resources.encoders, j * sizeof(uint));
                        IntPtr          encoderPtr = Drm.ModeGetEncoder(_drmFd, encoderId);
                        Drm.ModeEncoder encoder    = System.Runtime.InteropServices.Marshal.PtrToStructure <Drm.ModeEncoder>(encoderPtr);
                        for (int k = 0; k < resources.countCrtcs; ++k)
                        {
                            uint crtcMask = (uint)(1 << k);
                            if ((encoder.possibleCrtcs & crtcMask) != 0)
                            {
                                uint crtcId = (uint)System.Runtime.InteropServices.Marshal.ReadInt32(resources.crtcs, k * sizeof(uint));
                                _drmEncoderCrtcId = crtcId;
                            }
                        }

                        Drm.ModeFreeEncoder(encoderPtr);
                    }

                    break;
                }

                Drm.ModeFreeConnector(connectorPtr);
            }

            Drm.ModeFreeResources(resourcesPtr);

            Drm.SetClientCap(_drmFd, Drm.CLIENT_CAP_UNIVERSAL_PLANES, 1);

            _gbmDevice  = Gbm.CreateDevice(_drmFd);
            _gbmSurface = Gbm.SurfaceCreate(_gbmDevice, (uint)_width, (uint)_height, Drm.FORMAT_ARGB8888, Gbm.BO_USE_SCANOUT | Gbm.BO_USE_RENDERING);

            _gbmBoToDrmFb = new Dictionary <IntPtr, uint>();
        }