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), false, 0x31D7, device, null); _platformGl = new EglPlatformOpenGlInterface(_eglDisplay); _eglSurface = _platformGl.CreateWindowSurface(_gbmTargetSurface); _deferredContext = _platformGl.PrimaryEglContext; using (_deferredContext.MakeCurrent(_eglSurface)) { _deferredContext.GlInterface.ClearColor(0, 0, 0, 0); _deferredContext.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()) { _deferredContext.GlInterface.ClearColor(0, 0, 0, 0); _deferredContext.GlInterface.Clear(GlConsts.GL_COLOR_BUFFER_BIT | GlConsts.GL_STENCIL_BUFFER_BIT); } } }
public override IGlPlatformSurfaceRenderTarget CreateGlRenderTarget() => new GlRenderTarget(_egl, _info, _egl.CreateWindowSurface(_info.Handle));