mirror of
https://github.com/servo/servo.git
synced 2025-09-30 00:29:14 +01:00
libservo: Expose SoftwareRenderingContext
and WindowRenderingContext
(#35501)
Expose two easy-to-use wrappers around `SurfmanRenderingContext` that make the API simpler to use: - `WindowRenderingContext`: This `RenderingContext` is a newtype around `SurfmanRenderingContext` takes a `raw-window-handle` display and window and creates a full window rendering context. - `SoftwareRenderingContext`: is wraps `SurfmanRenderingContext` and adds a swap chain in order to expose a software GL rendering context. Signed-off-by: Martin Robinson <mrobinson@igalia.com>
This commit is contained in:
parent
73507f58e6
commit
f34f2d9d0a
18 changed files with 514 additions and 470 deletions
|
@ -12,7 +12,7 @@ use std::time::Duration;
|
|||
|
||||
use euclid::{Angle, Length, Point2D, Rotation3D, Scale, Size2D, UnknownUnit, Vector2D, Vector3D};
|
||||
use keyboard_types::{Modifiers, ShortcutMatcher};
|
||||
use log::{debug, info, warn};
|
||||
use log::{debug, info};
|
||||
use raw_window_handle::{HasDisplayHandle, HasWindowHandle};
|
||||
use servo::compositing::windowing::{
|
||||
AnimationState, EmbedderCoordinates, WebRenderDebugOption, WindowMethods,
|
||||
|
@ -22,14 +22,13 @@ use servo::servo_config::pref;
|
|||
use servo::servo_geometry::DeviceIndependentPixel;
|
||||
use servo::webrender_api::units::{DeviceIntPoint, DeviceIntRect, DeviceIntSize, DevicePixel};
|
||||
use servo::webrender_api::ScrollLocation;
|
||||
use servo::webrender_traits::rendering_context::{OffscreenRenderingContext, RenderingContext};
|
||||
use servo::webrender_traits::SurfmanRenderingContext;
|
||||
use servo::{
|
||||
Cursor, InputEvent, Key, KeyState, KeyboardEvent, MouseButton as ServoMouseButton,
|
||||
MouseButtonAction, MouseButtonEvent, MouseMoveEvent, Theme, TouchAction, TouchEvent,
|
||||
TouchEventType, TouchId, WebView, WheelDelta, WheelEvent, WheelMode,
|
||||
MouseButtonAction, MouseButtonEvent, MouseMoveEvent, OffscreenRenderingContext,
|
||||
RenderingContext, Theme, TouchAction, TouchEvent, TouchEventType, TouchId, WebView, WheelDelta,
|
||||
WheelEvent, WheelMode, WindowRenderingContext,
|
||||
};
|
||||
use surfman::{Connection, Context, Device, SurfaceType};
|
||||
use surfman::{Context, Device};
|
||||
use url::Url;
|
||||
use winit::dpi::{LogicalSize, PhysicalPosition, PhysicalSize};
|
||||
use winit::event::{
|
||||
|
@ -69,7 +68,7 @@ pub struct Window {
|
|||
/// The RenderingContext that renders directly onto the Window. This is used as
|
||||
/// the target of egui rendering and also where Servo rendering results are finally
|
||||
/// blitted.
|
||||
window_rendering_context: SurfmanRenderingContext,
|
||||
window_rendering_context: Rc<WindowRenderingContext>,
|
||||
|
||||
/// The `RenderingContext` of Servo itself. This is used to render Servo results
|
||||
/// temporarily until they can be blitted into the egui scene.
|
||||
|
@ -125,32 +124,16 @@ impl Window {
|
|||
let display_handle = event_loop
|
||||
.display_handle()
|
||||
.expect("could not get display handle from window");
|
||||
let connection =
|
||||
Connection::from_display_handle(display_handle).expect("Failed to create connection");
|
||||
let adapter = connection
|
||||
.create_adapter()
|
||||
.expect("Failed to create adapter");
|
||||
let window_handle = winit_window
|
||||
.window_handle()
|
||||
.expect("could not get window handle from window");
|
||||
let native_widget = connection
|
||||
.create_native_widget_from_window_handle(
|
||||
window_handle,
|
||||
winit_size_to_euclid_size(inner_size).to_i32().to_untyped(),
|
||||
)
|
||||
.expect("Failed to create native widget");
|
||||
|
||||
let window_rendering_context = SurfmanRenderingContext::create(&connection, &adapter, None)
|
||||
.expect("Failed to create window RenderingContext");
|
||||
let surface = window_rendering_context
|
||||
.create_surface(SurfaceType::Widget { native_widget })
|
||||
.expect("Failed to create surface");
|
||||
window_rendering_context
|
||||
.bind_surface(surface)
|
||||
.expect("Failed to bind surface");
|
||||
let window_rendering_context = Rc::new(
|
||||
WindowRenderingContext::new(display_handle, window_handle, &inner_size)
|
||||
.expect("Could not create RenderingContext for Window"),
|
||||
);
|
||||
|
||||
// Make sure the gl context is made current.
|
||||
window_rendering_context.make_gl_context_current().unwrap();
|
||||
window_rendering_context.make_current().unwrap();
|
||||
|
||||
let rendering_context_size = Size2D::new(inner_size.width, inner_size.height);
|
||||
let rendering_context =
|
||||
|
@ -633,13 +616,8 @@ impl WindowPortsMethods for Window {
|
|||
WindowEvent::Resized(new_size) => {
|
||||
if self.inner_size.get() != new_size {
|
||||
let rendering_context_size = Size2D::new(new_size.width, new_size.height);
|
||||
if let Err(error) = self
|
||||
.window_rendering_context
|
||||
.resize(rendering_context_size.to_i32())
|
||||
{
|
||||
warn!("Could not resize window RenderingContext: {error:?}");
|
||||
}
|
||||
|
||||
self.window_rendering_context
|
||||
.resize(rendering_context_size.to_i32());
|
||||
self.inner_size.set(new_size);
|
||||
webview.notify_rendering_context_resized();
|
||||
}
|
||||
|
|
|
@ -12,9 +12,8 @@ use euclid::{Box2D, Length, Point2D, Scale, Size2D};
|
|||
use servo::compositing::windowing::{AnimationState, EmbedderCoordinates, WindowMethods};
|
||||
use servo::servo_geometry::DeviceIndependentPixel;
|
||||
use servo::webrender_api::units::{DeviceIntSize, DevicePixel};
|
||||
use servo::webrender_traits::rendering_context::RenderingContext;
|
||||
use servo::webrender_traits::SurfmanRenderingContext;
|
||||
use surfman::Connection;
|
||||
use servo::{RenderingContext, SoftwareRenderingContext};
|
||||
use winit::dpi::PhysicalSize;
|
||||
|
||||
use super::app_state::RunningAppState;
|
||||
use crate::desktop::window_trait::WindowPortsMethods;
|
||||
|
@ -27,30 +26,24 @@ pub struct Window {
|
|||
inner_size: Cell<DeviceIntSize>,
|
||||
screen_size: Size2D<i32, DeviceIndependentPixel>,
|
||||
window_rect: Box2D<i32, DeviceIndependentPixel>,
|
||||
rendering_context: SurfmanRenderingContext,
|
||||
rendering_context: Rc<SoftwareRenderingContext>,
|
||||
}
|
||||
|
||||
impl Window {
|
||||
#[allow(clippy::new_ret_no_self)]
|
||||
pub fn new(servoshell_preferences: &ServoShellPreferences) -> Rc<dyn WindowPortsMethods> {
|
||||
let size = servoshell_preferences.initial_window_size;
|
||||
let connection = Connection::new().expect("Failed to create connection");
|
||||
let adapter = connection
|
||||
.create_software_adapter()
|
||||
.expect("Failed to create adapter");
|
||||
let rendering_context = SurfmanRenderingContext::create(
|
||||
&connection,
|
||||
&adapter,
|
||||
Some(size.to_untyped().to_i32()),
|
||||
)
|
||||
.expect("Failed to create WR surfman");
|
||||
|
||||
let device_pixel_ratio_override = servoshell_preferences.device_pixel_ratio_override;
|
||||
let device_pixel_ratio_override: Option<Scale<f32, DeviceIndependentPixel, DevicePixel>> =
|
||||
device_pixel_ratio_override.map(Scale::new);
|
||||
let hidpi_factor = device_pixel_ratio_override.unwrap_or_else(Scale::identity);
|
||||
|
||||
let inner_size = Cell::new((size.to_f32() * hidpi_factor).to_i32());
|
||||
let inner_size = (size.to_f32() * hidpi_factor).to_i32();
|
||||
let physical_size = PhysicalSize::new(inner_size.width as u32, inner_size.height as u32);
|
||||
let rendering_context =
|
||||
SoftwareRenderingContext::new(physical_size).expect("Failed to create WR surfman");
|
||||
|
||||
let window_rect = Box2D::from_origin_and_size(Point2D::zero(), size.to_i32());
|
||||
|
||||
let screen_size = servoshell_preferences.screen_size_override.map_or_else(
|
||||
|
@ -62,10 +55,10 @@ impl Window {
|
|||
animation_state: Cell::new(AnimationState::Idle),
|
||||
fullscreen: Cell::new(false),
|
||||
device_pixel_ratio_override,
|
||||
inner_size,
|
||||
inner_size: Cell::new(inner_size),
|
||||
screen_size,
|
||||
window_rect,
|
||||
rendering_context,
|
||||
rendering_context: Rc::new(rendering_context),
|
||||
};
|
||||
|
||||
Rc::new(window)
|
||||
|
@ -150,9 +143,7 @@ impl WindowPortsMethods for Window {
|
|||
}
|
||||
|
||||
fn rendering_context(&self) -> Rc<dyn RenderingContext> {
|
||||
// `SurfmanRenderingContext` uses shared ownership internally so cloning it here does
|
||||
// not create a new one really.
|
||||
Rc::new(self.rendering_context.clone())
|
||||
self.rendering_context.clone()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -21,8 +21,7 @@ use servo::base::id::WebViewId;
|
|||
use servo::servo_geometry::DeviceIndependentPixel;
|
||||
use servo::servo_url::ServoUrl;
|
||||
use servo::webrender_api::units::DevicePixel;
|
||||
use servo::webrender_traits::rendering_context::{OffscreenRenderingContext, RenderingContext};
|
||||
use servo::{LoadStatus, WebView};
|
||||
use servo::{LoadStatus, OffscreenRenderingContext, RenderingContext, WebView};
|
||||
use winit::event::{ElementState, MouseButton, WindowEvent};
|
||||
use winit::event_loop::ActiveEventLoop;
|
||||
use winit::window::Window;
|
||||
|
@ -429,7 +428,7 @@ impl Minibrowser {
|
|||
.parent_context()
|
||||
.prepare_for_rendering();
|
||||
self.context.paint(window);
|
||||
let _ = self.rendering_context.parent_context().present();
|
||||
self.rendering_context.parent_context().present();
|
||||
}
|
||||
|
||||
/// Updates the location field from the given [WebViewManager], unless the user has started
|
||||
|
|
|
@ -11,8 +11,7 @@ use euclid::{Length, Scale};
|
|||
use servo::compositing::windowing::WindowMethods;
|
||||
use servo::servo_geometry::DeviceIndependentPixel;
|
||||
use servo::webrender_api::units::{DeviceIntPoint, DeviceIntSize, DevicePixel};
|
||||
use servo::webrender_traits::rendering_context::RenderingContext;
|
||||
use servo::{Cursor, WebView};
|
||||
use servo::{Cursor, RenderingContext, WebView};
|
||||
|
||||
use super::app_state::RunningAppState;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue