internal DrmModeInfo(ref drmModeModeInfo info) { Mode = info; fixed(void *pName = info.name) Name = Marshal.PtrToStringAnsi(new IntPtr(pName)); }
void Init(DrmCard card, DrmResources resources, DrmConnector connector, DrmModeInfo modeInfo) { FbDestroyDelegate = FbDestroyCallback; _card = card; uint GetCrtc() { if (resources.Encoders.TryGetValue(connector.EncoderId, out var encoder)) { // Not sure why that should work return(encoder.Encoder.crtc_id); } else { foreach (var encId in connector.EncoderIds) { if (resources.Encoders.TryGetValue(encId, out encoder) && encoder.PossibleCrtcs.Count > 0) { return(encoder.PossibleCrtcs.First().crtc_id); } } throw new InvalidOperationException("Unable to find CRTC matching the desired mode"); } } _crtcId = GetCrtc(); var device = gbm_create_device(card.Fd); _gbmTargetSurface = gbm_surface_create(device, modeInfo.Resolution.Width, modeInfo.Resolution.Height, GbmColorFormats.GBM_FORMAT_XRGB8888, GbmBoFlags.GBM_BO_USE_SCANOUT | GbmBoFlags.GBM_BO_USE_RENDERING); if (_gbmTargetSurface == null) { throw new InvalidOperationException("Unable to create GBM surface"); } _eglDisplay = new EglDisplay(new EglInterface(eglGetProcAddress), 0x31D7, device, null); _eglSurface = _eglDisplay.CreateWindowSurface(_gbmTargetSurface); EglContext CreateContext(EglContext share) { var offSurf = gbm_surface_create(device, 1, 1, GbmColorFormats.GBM_FORMAT_XRGB8888, GbmBoFlags.GBM_BO_USE_RENDERING); if (offSurf == null) { throw new InvalidOperationException("Unable to create 1x1 sized GBM surface"); } return(_eglDisplay.CreateContext(share, _eglDisplay.CreateWindowSurface(offSurf))); } _immediateContext = CreateContext(null); _deferredContext = CreateContext(_immediateContext); _immediateContext.MakeCurrent(_eglSurface); _eglDisplay.GlInterface.ClearColor(0, 0, 0, 0); _eglDisplay.GlInterface.Clear(GlConsts.GL_COLOR_BUFFER_BIT | GlConsts.GL_STENCIL_BUFFER_BIT); _eglSurface.SwapBuffers(); var bo = gbm_surface_lock_front_buffer(_gbmTargetSurface); var fbId = GetFbIdForBo(bo); var connectorId = connector.Id; var mode = modeInfo.Mode; var res = drmModeSetCrtc(_card.Fd, _crtcId, fbId, 0, 0, &connectorId, 1, &mode); if (res != 0) { throw new Win32Exception(res, "drmModeSetCrtc failed"); } _mode = mode; _currentBo = bo; // Go trough two cycles of buffer swapping (there are render artifacts otherwise) for (var c = 0; c < 2; c++) { using (CreateGlRenderTarget().BeginDraw()) { _eglDisplay.GlInterface.ClearColor(0, 0, 0, 0); _eglDisplay.GlInterface.Clear(GlConsts.GL_COLOR_BUFFER_BIT | GlConsts.GL_STENCIL_BUFFER_BIT); } } }