From e0a5abf7df32def09795447bc28207d19a4a1387 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Mon, 13 May 2019 20:06:46 +0200 Subject: [PATCH] Implement Window's GL context for Glutin --- ports/glutin/context.rs | 60 ++++++++++++++++++++++++++++++- ports/glutin/headed_window.rs | 68 ++++++++++++++++++++++++++++++----- 2 files changed, 119 insertions(+), 9 deletions(-) diff --git a/ports/glutin/context.rs b/ports/glutin/context.rs index 5e5e86cb461..4328f9e47ea 100644 --- a/ports/glutin/context.rs +++ b/ports/glutin/context.rs @@ -2,7 +2,10 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -use glutin::{WindowedContext, NotCurrent, PossiblyCurrent}; +use glutin::os::ContextTraitExt; +use glutin::{NotCurrent, PossiblyCurrent, WindowedContext}; +use servo_media::player::context::GlContext as RawContext; +use std::os::raw; pub enum GlContext { Current(WindowedContext), @@ -71,4 +74,59 @@ impl GlContext { GlContext::None => unreachable!(), }; } + pub fn raw_context(&self) -> RawContext { + match self { + GlContext::Current(c) => { + let raw_handle = unsafe { c.raw_handle() }; + + #[cfg(any( + target_os = "linux", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "netbsd", + target_os = "openbsd" + ))] + { + use glutin::os::unix::RawHandle; + + return match raw_handle { + RawHandle::Egl(handle) => RawContext::Egl(handle as usize), + RawHandle::Glx(handle) => RawContext::Glx(handle as usize), + }; + } + + #[cfg(not(any( + target_os = "linux", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "netbsd", + target_os = "openbsd" + )))] + unimplemented!() + } + GlContext::NotCurrent(_) => { + error!("Context is not current."); + RawContext::Unknown + } + GlContext::None => unreachable!(), + } + } + pub fn egl_display(&self) -> Option<*const raw::c_void> { + match self { + GlContext::Current(c) => unsafe { c.get_egl_display() }, + GlContext::NotCurrent(_) => { + error!("Context is not current."); + None + }, + GlContext::None => unreachable!(), + } + } + + pub fn get_api(&self) -> glutin::Api { + match self { + GlContext::Current(c) => c.get_api(), + GlContext::NotCurrent(c) => c.get_api(), + GlContext::None => unreachable!(), + } + } } diff --git a/ports/glutin/headed_window.rs b/ports/glutin/headed_window.rs index b409304c93b..1e1801c2d49 100644 --- a/ports/glutin/headed_window.rs +++ b/ports/glutin/headed_window.rs @@ -13,9 +13,9 @@ use gleam::gl; use glutin::dpi::{LogicalPosition, LogicalSize, PhysicalSize}; #[cfg(target_os = "macos")] use glutin::os::macos::{ActivationPolicy, WindowBuilderExt}; +use glutin::Api; #[cfg(any(target_os = "linux", target_os = "windows"))] use glutin::Icon; -use glutin::Api; use glutin::{ElementState, KeyboardInput, MouseButton, MouseScrollDelta, TouchPhase}; #[cfg(any(target_os = "linux", target_os = "windows"))] use image; @@ -30,7 +30,7 @@ use servo::style_traits::DevicePixel; use servo::webrender_api::{ DeviceIntPoint, DeviceIntRect, DeviceIntSize, FramebufferIntSize, ScrollLocation, }; -use servo_media::player::context as MediaPlayerCtxt; +use servo_media::player::context::{GlApi, GlContext as PlayerGLContext, NativeDisplay}; use std::cell::{Cell, RefCell}; use std::mem; use std::rc::Rc; @@ -526,16 +526,68 @@ impl WindowMethods for Window { self.gl_context.borrow_mut().make_current(); } - fn get_gl_context(&self) -> MediaPlayerCtxt::GlContext { - MediaPlayerCtxt::GlContext::Unknown + fn get_gl_context(&self) -> PlayerGLContext { + self.gl_context.borrow().raw_context() } - fn get_native_display(&self) -> MediaPlayerCtxt::NativeDisplay { - MediaPlayerCtxt::NativeDisplay::Unknown + fn get_native_display(&self) -> NativeDisplay { + #[cfg(any( + target_os = "linux", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "netbsd", + target_os = "openbsd" + ))] + let native_display = { + if let Some(display) = self.gl_context.borrow().egl_display() { + NativeDisplay::Egl(display as usize) + } else { + use glutin::os::unix::WindowExt; + + if let Some(display) = self.gl_context.borrow().window().get_wayland_display() { + NativeDisplay::Wayland(display as usize) + } else if let Some(display) = self.gl_context.borrow().window().get_xlib_display() { + NativeDisplay::X11(display as usize) + } else { + NativeDisplay::Unknown + } + } + }; + + #[cfg(not(any( + target_os = "linux", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "netbsd", + target_os = "openbsd" + )))] + let native_display = NativeDisplay::Unknown; + + native_display } - fn get_gl_api(&self) -> MediaPlayerCtxt::GlApi { - MediaPlayerCtxt::GlApi::None + fn get_gl_api(&self) -> GlApi { + let api = self.gl_context.borrow().get_api(); + + let version = self.gl.get_string(gl::VERSION); + let version = version.trim_start_matches("OpenGL ES "); + let mut values = version.split(&['.', ' '][..]); + let major = values + .next() + .and_then(|v| v.parse::().ok()) + .unwrap_or(1); + let minor = values + .next() + .and_then(|v| v.parse::().ok()) + .unwrap_or(20); + + match api { + glutin::Api::OpenGl if major >= 3 && minor >= 2 => GlApi::OpenGL3, + glutin::Api::OpenGl => GlApi::OpenGL, + glutin::Api::OpenGlEs if major > 1 => GlApi::Gles2, + glutin::Api::OpenGlEs => GlApi::Gles1, + _ => GlApi::None, + } } }