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:
Martin Robinson 2025-02-18 15:50:41 +01:00 committed by GitHub
parent 73507f58e6
commit f34f2d9d0a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
18 changed files with 514 additions and 470 deletions

View file

@ -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()
}
}