/// <summary> /// Initialize RPi Broadcom VideoCore IV API. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private static void KhronosApi_PlatformInit_Rpi(object sender, EglEventArgs e) { if (Bcm.IsAvailable) { Bcm.bcm_host_init(); } }
/// <summary> /// Releases all resources used by the <see cref="VideoCoreWindow"/> object. /// </summary> /// <param name="disposing"> /// </param> protected virtual void Dispose(bool disposing) { if (disposing) { if (_ElementHandle != 0) { uint updateHandle = Bcm.vc_dispmanx_update_start(0); Bcm.vc_dispmanx_element_remove(updateHandle, _ElementHandle); Bcm.vc_dispmanx_update_submit_sync(updateHandle); _ElementHandle = 0; } if (_DispManxDisplay != 0) { Bcm.vc_dispmanx_display_close(_DispManxDisplay); _DispManxDisplay = 0; } if (_NativeWindowLock != null) { _NativeWindowLock.Dispose(); _NativeWindowLock = null; } } }
/// <summary> /// Construct a fullscreen window. /// </summary> public VideoCoreWindow() { try { int width, height; KhronosApi.LogComment("Creating VideoCore IV native window"); if (Bcm.graphics_get_display_size(0 /* LCD */, out width, out height) < 0) { throw new InvalidOperationException("unable to get BCM display size"); } Bcm.VC_RECT_T dstRect = new Bcm.VC_RECT_T(0, 0, width, height); Bcm.VC_RECT_T srcRect = new Bcm.VC_RECT_T(0, 0, width << 16, height << 16); if ((_DispManxDisplay = Bcm.vc_dispmanx_display_open(0 /* LCD */)) == 0) { throw new InvalidOperationException("unable to open DispManX display"); } // Update - Add element uint updateHandle = Bcm.vc_dispmanx_update_start(0); _ElementHandle = Bcm.vc_dispmanx_element_add(updateHandle, _DispManxDisplay, 0, dstRect, 0, srcRect, 0, IntPtr.Zero, IntPtr.Zero, Bcm.DISPMANX_TRANSFORM_T.DISPMANX_NO_ROTATE); Bcm.vc_dispmanx_update_submit_sync(updateHandle); // Native window _NativeWindow = new EGL_DISPMANX_WINDOW_T(); _NativeWindow.element = _ElementHandle; _NativeWindow.width = width; _NativeWindow.height = height; // Keep native window pinned _NativeWindowLock = new MemoryLock(_NativeWindow); KhronosApi.LogComment("VideoCore IV Native Window is 0x{0}", _NativeWindowLock.Address.ToString("X")); } catch { Dispose(); throw; } }
/// <summary> /// Initialize OpenGL namespace static environment. This method shall be called before any other classes methods. /// </summary> public static void Initialize() { if (_Initialized == true) { return; // Already initialized } _Initialized = true; // Before linking procedures, append ANGLE directory in path string assemblyPath = Path.GetDirectoryName(Assembly.GetAssembly(typeof(Egl)).Location); string anglePath = null; switch (Platform.CurrentPlatformId) { case Platform.Id.WindowsNT: #if DEBUG if (IntPtr.Size == 8) { anglePath = Path.Combine(assemblyPath, @"ANGLE\winrt10d\x64"); } else { anglePath = Path.Combine(assemblyPath, @"ANGLE\winrt10d\x86"); } #else if (IntPtr.Size == 8) { anglePath = Path.Combine(assemblyPath, @"ANGLE\winrt10\x64"); } else { anglePath = Path.Combine(assemblyPath, @"ANGLE\winrt10\x86"); } #endif break; case Platform.Id.Linux: // Note: on RPi libEGL.so depends on libGLESv2.so, so it's required to pre-load the shared library GetProcAddressX11.Instance.GetLibraryHandle("libGLESv2.so"); break; } // Include ANGLE path, if any if (anglePath != null && Directory.Exists(anglePath)) { OpenGL.GetProcAddress.GetProcAddressOS.AddLibraryDirectory(Path.Combine(assemblyPath, anglePath)); } // Load procedures string platformLibrary = GetPlatformLibrary(); try { LogComment("Querying EGL from {0}", platformLibrary); BindAPI <Egl>(platformLibrary, OpenGL.GetProcAddress.GetProcAddressOS); LogComment("EGL availability: {0}", IsAvailable); } catch (Exception exception) { /* Fail-safe (it may fail due Egl access) */ LogComment("EGL not available:\n{0}", exception.ToString()); } // Support for BCM VideoCore API if (IsAvailable && Bcm.IsAvailable) { // This need to be executed before any EGL/GL routine Bcm.bcm_host_init(); } #if DEBUG string envEglInit = Environment.GetEnvironmentVariable("EGL_INIT"); if (envEglInit != null && envEglInit == "NO") { return; } #endif // Get EGL information if (IsAvailable) { IntPtr eglDisplay = GetDisplay(new IntPtr(DEFAULT_DISPLAY)); try { if (Initialize(eglDisplay, null, null) == false) { throw new InvalidOperationException("unable to initialize EGL"); } // Query EGL version string eglVersionString = QueryString(eglDisplay, VERSION); _CurrentVersion = KhronosVersion.Parse(eglVersionString, KhronosVersion.ApiEgl); // Query EGL vendor _Vendor = QueryString(eglDisplay, VENDOR); // Client APIs if (_CurrentVersion >= Version_120) { string clientApisString = QueryString(eglDisplay, CLIENT_APIS); _AvailableApis = System.Text.RegularExpressions.Regex.Split(clientApisString, " "); } } finally { Terminate(eglDisplay); } } }