mirror of
https://codeberg.org/waydeer/layer-shika.git
synced 2025-12-02 21:15:55 +00:00
refactor: remove dependency on primary output for egl context management system
This commit is contained in:
parent
4fb4d87125
commit
5a1c551efb
6 changed files with 166 additions and 206 deletions
|
|
@ -1,208 +1,57 @@
|
||||||
use super::context::EGLContext;
|
use super::context::EGLContext;
|
||||||
|
use super::render_context_manager::RenderContextManager;
|
||||||
use crate::errors::{EGLError, LayerShikaError, Result};
|
use crate::errors::{EGLError, LayerShikaError, Result};
|
||||||
use glutin::{
|
use glutin::{
|
||||||
api::egl::{
|
api::egl::{config::Config, display::Display, surface::Surface},
|
||||||
config::Config,
|
|
||||||
context::{NotCurrentContext, PossiblyCurrentContext},
|
|
||||||
display::Display,
|
|
||||||
surface::Surface,
|
|
||||||
},
|
|
||||||
config::ConfigTemplateBuilder,
|
|
||||||
context::ContextAttributesBuilder,
|
context::ContextAttributesBuilder,
|
||||||
prelude::*,
|
prelude::*,
|
||||||
surface::{SurfaceAttributesBuilder, WindowSurface},
|
surface::{SurfaceAttributesBuilder, WindowSurface},
|
||||||
};
|
};
|
||||||
use log::{debug, info};
|
use log::info;
|
||||||
use raw_window_handle::{
|
use raw_window_handle::{RawWindowHandle, WaylandWindowHandle};
|
||||||
RawDisplayHandle, RawWindowHandle, WaylandDisplayHandle, WaylandWindowHandle,
|
|
||||||
};
|
|
||||||
use slint::PhysicalSize;
|
use slint::PhysicalSize;
|
||||||
use std::{cell::RefCell, ffi::c_void, num::NonZeroU32, ptr::NonNull, rc::Rc};
|
use std::{ffi::c_void, num::NonZeroU32, ptr::NonNull, rc::Rc};
|
||||||
use wayland_client::backend::ObjectId;
|
use wayland_client::backend::ObjectId;
|
||||||
|
|
||||||
pub struct RenderContextFactory {
|
pub struct RenderContextFactory {
|
||||||
shared_state: RefCell<Option<SharedRenderState>>,
|
manager: Rc<RenderContextManager>,
|
||||||
}
|
|
||||||
|
|
||||||
struct SharedRenderState {
|
|
||||||
display: Display,
|
|
||||||
config: Config,
|
|
||||||
primary_context: PossiblyCurrentContext,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RenderContextFactory {
|
impl RenderContextFactory {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn new() -> Rc<Self> {
|
pub fn new(manager: Rc<RenderContextManager>) -> Rc<Self> {
|
||||||
Rc::new(Self {
|
Rc::new(Self { manager })
|
||||||
shared_state: RefCell::new(None),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_context(
|
pub fn create_context(&self, surface_id: &ObjectId, size: PhysicalSize) -> Result<EGLContext> {
|
||||||
&self,
|
info!("Creating shared EGL context from root context manager");
|
||||||
display_id: &ObjectId,
|
|
||||||
surface_id: &ObjectId,
|
|
||||||
size: PhysicalSize,
|
|
||||||
) -> Result<EGLContext> {
|
|
||||||
let mut state = self.shared_state.borrow_mut();
|
|
||||||
|
|
||||||
if state.is_none() {
|
let context_attributes =
|
||||||
info!("Creating primary EGL context (will be shared with subsequent contexts)");
|
ContextAttributesBuilder::default().with_sharing(self.manager.root_context());
|
||||||
let new_state = self.create_primary_context(display_id, surface_id, size)?;
|
|
||||||
*state = Some(new_state);
|
let not_current = unsafe {
|
||||||
|
self.manager
|
||||||
|
.display()
|
||||||
|
.create_context(self.manager.config(), &context_attributes.build(None))
|
||||||
}
|
}
|
||||||
|
|
||||||
let Some(shared_state) = state.as_ref() else {
|
|
||||||
return Err(LayerShikaError::InvalidInput {
|
|
||||||
message: "Shared state initialization failed".into(),
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
if shared_state.primary_context.is_current() {
|
|
||||||
debug!("Creating shared context while primary is current");
|
|
||||||
self.create_shared_context_from_current(
|
|
||||||
&shared_state.display,
|
|
||||||
&shared_state.config,
|
|
||||||
&shared_state.primary_context,
|
|
||||||
surface_id,
|
|
||||||
size,
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
debug!("Creating shared context (primary not current)");
|
|
||||||
self.create_shared_context(
|
|
||||||
&shared_state.display,
|
|
||||||
&shared_state.config,
|
|
||||||
&shared_state.primary_context,
|
|
||||||
surface_id,
|
|
||||||
size,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(clippy::unused_self)]
|
|
||||||
fn create_primary_context(
|
|
||||||
&self,
|
|
||||||
display_id: &ObjectId,
|
|
||||||
surface_id: &ObjectId,
|
|
||||||
size: PhysicalSize,
|
|
||||||
) -> Result<SharedRenderState> {
|
|
||||||
let display_handle = create_wayland_display_handle(display_id)?;
|
|
||||||
let display = unsafe { Display::new(display_handle) }
|
|
||||||
.map_err(|e| EGLError::DisplayCreation { source: e.into() })?;
|
|
||||||
|
|
||||||
let config_template = ConfigTemplateBuilder::default();
|
|
||||||
let config = select_config(&display, config_template)?;
|
|
||||||
|
|
||||||
let context_attributes = ContextAttributesBuilder::default();
|
|
||||||
let not_current = create_context(&display, &config, context_attributes)?;
|
|
||||||
|
|
||||||
let surface_handle = create_surface_handle(surface_id)?;
|
|
||||||
let surface = create_surface(&display, &config, surface_handle, size)?;
|
|
||||||
|
|
||||||
let primary_context = not_current
|
|
||||||
.make_current(&surface)
|
|
||||||
.map_err(|e| EGLError::MakeCurrent { source: e.into() })?;
|
|
||||||
|
|
||||||
info!("Primary EGL context created successfully");
|
|
||||||
|
|
||||||
Ok(SharedRenderState {
|
|
||||||
display,
|
|
||||||
config,
|
|
||||||
primary_context,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(clippy::unused_self)]
|
|
||||||
fn create_shared_context(
|
|
||||||
&self,
|
|
||||||
display: &Display,
|
|
||||||
config: &Config,
|
|
||||||
share_context: &PossiblyCurrentContext,
|
|
||||||
surface_id: &ObjectId,
|
|
||||||
size: PhysicalSize,
|
|
||||||
) -> Result<EGLContext> {
|
|
||||||
let context_attributes = ContextAttributesBuilder::default().with_sharing(share_context);
|
|
||||||
|
|
||||||
let not_current =
|
|
||||||
unsafe { display.create_context(config, &context_attributes.build(None)) }
|
|
||||||
.map_err(|e| EGLError::ContextCreation { source: e.into() })?;
|
.map_err(|e| EGLError::ContextCreation { source: e.into() })?;
|
||||||
|
|
||||||
let surface_handle = create_surface_handle(surface_id)?;
|
let surface_handle = create_surface_handle(surface_id)?;
|
||||||
let surface = create_surface(display, config, surface_handle, size)?;
|
let surface = create_surface(
|
||||||
|
self.manager.display(),
|
||||||
|
self.manager.config(),
|
||||||
|
surface_handle,
|
||||||
|
size,
|
||||||
|
)?;
|
||||||
|
|
||||||
let context = not_current
|
let context = not_current
|
||||||
.make_current(&surface)
|
.make_current(&surface)
|
||||||
.map_err(|e| EGLError::MakeCurrent { source: e.into() })?;
|
.map_err(|e| EGLError::MakeCurrent { source: e.into() })?;
|
||||||
|
|
||||||
info!("Shared EGL context created successfully");
|
info!("Shared EGL context created successfully from root manager");
|
||||||
|
|
||||||
Ok(EGLContext::from_raw(surface, context))
|
Ok(EGLContext::from_raw(surface, context))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::unused_self)]
|
|
||||||
fn create_shared_context_from_current(
|
|
||||||
&self,
|
|
||||||
display: &Display,
|
|
||||||
config: &Config,
|
|
||||||
share_context: &PossiblyCurrentContext,
|
|
||||||
surface_id: &ObjectId,
|
|
||||||
size: PhysicalSize,
|
|
||||||
) -> Result<EGLContext> {
|
|
||||||
let context_attributes = ContextAttributesBuilder::default().with_sharing(share_context);
|
|
||||||
|
|
||||||
let not_current =
|
|
||||||
unsafe { display.create_context(config, &context_attributes.build(None)) }
|
|
||||||
.map_err(|e| EGLError::ContextCreation { source: e.into() })?;
|
|
||||||
|
|
||||||
let surface_handle = create_surface_handle(surface_id)?;
|
|
||||||
let surface = create_surface(display, config, surface_handle, size)?;
|
|
||||||
|
|
||||||
let context = not_current
|
|
||||||
.make_current(&surface)
|
|
||||||
.map_err(|e| EGLError::MakeCurrent { source: e.into() })?;
|
|
||||||
|
|
||||||
info!("Shared EGL context created successfully (from current)");
|
|
||||||
|
|
||||||
Ok(EGLContext::from_raw(surface, context))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for RenderContextFactory {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self {
|
|
||||||
shared_state: RefCell::new(None),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn create_wayland_display_handle(display_id: &ObjectId) -> Result<RawDisplayHandle> {
|
|
||||||
let display = NonNull::new(display_id.as_ptr().cast::<c_void>()).ok_or_else(|| {
|
|
||||||
LayerShikaError::InvalidInput {
|
|
||||||
message: "Failed to create NonNull pointer for display".into(),
|
|
||||||
}
|
|
||||||
})?;
|
|
||||||
let handle = WaylandDisplayHandle::new(display);
|
|
||||||
Ok(RawDisplayHandle::Wayland(handle))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn select_config(
|
|
||||||
glutin_display: &Display,
|
|
||||||
config_template: ConfigTemplateBuilder,
|
|
||||||
) -> Result<Config> {
|
|
||||||
let mut configs = unsafe { glutin_display.find_configs(config_template.build()) }
|
|
||||||
.map_err(|e| EGLError::ConfigSelection { source: e.into() })?;
|
|
||||||
configs
|
|
||||||
.next()
|
|
||||||
.ok_or_else(|| EGLError::NoCompatibleConfig.into())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn create_context(
|
|
||||||
glutin_display: &Display,
|
|
||||||
config: &Config,
|
|
||||||
context_attributes: ContextAttributesBuilder,
|
|
||||||
) -> Result<NotCurrentContext> {
|
|
||||||
unsafe { glutin_display.create_context(config, &context_attributes.build(None)) }
|
|
||||||
.map_err(|e| EGLError::ContextCreation { source: e.into() }.into())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_surface_handle(surface_id: &ObjectId) -> Result<RawWindowHandle> {
|
fn create_surface_handle(surface_id: &ObjectId) -> Result<RawWindowHandle> {
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,3 @@
|
||||||
pub mod context;
|
pub mod context;
|
||||||
pub mod context_factory;
|
pub mod context_factory;
|
||||||
|
pub mod render_context_manager;
|
||||||
|
|
|
||||||
113
crates/adapters/src/rendering/egl/render_context_manager.rs
Normal file
113
crates/adapters/src/rendering/egl/render_context_manager.rs
Normal file
|
|
@ -0,0 +1,113 @@
|
||||||
|
use crate::errors::{EGLError, LayerShikaError, Result};
|
||||||
|
use glutin::{
|
||||||
|
api::egl::{config::Config, context::PossiblyCurrentContext, display::Display},
|
||||||
|
config::ConfigTemplateBuilder,
|
||||||
|
context::ContextAttributesBuilder,
|
||||||
|
prelude::*,
|
||||||
|
};
|
||||||
|
use log::{info, warn};
|
||||||
|
use raw_window_handle::{RawDisplayHandle, WaylandDisplayHandle};
|
||||||
|
use std::{ffi::c_void, ptr::NonNull, rc::Rc};
|
||||||
|
use wayland_client::backend::ObjectId;
|
||||||
|
|
||||||
|
pub struct RenderContextManager {
|
||||||
|
display: Display,
|
||||||
|
config: Config,
|
||||||
|
root_context: PossiblyCurrentContext,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RenderContextManager {
|
||||||
|
pub fn new(display_id: &ObjectId) -> Result<Rc<Self>> {
|
||||||
|
info!("Initializing RenderContextManager with independent root context");
|
||||||
|
|
||||||
|
let display_handle = create_wayland_display_handle(display_id)?;
|
||||||
|
let display = unsafe { Display::new(display_handle) }
|
||||||
|
.map_err(|e| EGLError::DisplayCreation { source: e.into() })?;
|
||||||
|
|
||||||
|
let config_template = ConfigTemplateBuilder::default();
|
||||||
|
let config = select_config(&display, config_template)?;
|
||||||
|
|
||||||
|
let root_context = Self::create_root_context(&display, &config)?;
|
||||||
|
|
||||||
|
info!("RenderContextManager initialized successfully");
|
||||||
|
|
||||||
|
Ok(Rc::new(Self {
|
||||||
|
display,
|
||||||
|
config,
|
||||||
|
root_context,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_root_context(display: &Display, config: &Config) -> Result<PossiblyCurrentContext> {
|
||||||
|
if let Ok(context) = Self::try_create_surfaceless_context(display, config) {
|
||||||
|
info!("Created surfaceless root EGL context");
|
||||||
|
return Ok(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
warn!(
|
||||||
|
"Surfaceless context not available, using workaround with make_current_surfaceless anyway"
|
||||||
|
);
|
||||||
|
Self::create_surfaceless_fallback(display, config)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn try_create_surfaceless_context(
|
||||||
|
display: &Display,
|
||||||
|
config: &Config,
|
||||||
|
) -> Result<PossiblyCurrentContext> {
|
||||||
|
let context_attributes = ContextAttributesBuilder::default();
|
||||||
|
let not_current =
|
||||||
|
unsafe { display.create_context(config, &context_attributes.build(None)) }
|
||||||
|
.map_err(|e| EGLError::ContextCreation { source: e.into() })?;
|
||||||
|
|
||||||
|
not_current
|
||||||
|
.make_current_surfaceless()
|
||||||
|
.map_err(|e| EGLError::MakeCurrent { source: e.into() }.into())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_surfaceless_fallback(
|
||||||
|
display: &Display,
|
||||||
|
config: &Config,
|
||||||
|
) -> Result<PossiblyCurrentContext> {
|
||||||
|
let context_attributes = ContextAttributesBuilder::default();
|
||||||
|
let not_current =
|
||||||
|
unsafe { display.create_context(config, &context_attributes.build(None)) }
|
||||||
|
.map_err(|e| EGLError::ContextCreation { source: e.into() })?;
|
||||||
|
|
||||||
|
not_current
|
||||||
|
.make_current_surfaceless()
|
||||||
|
.map_err(|e| EGLError::MakeCurrent { source: e.into() }.into())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn display(&self) -> &Display {
|
||||||
|
&self.display
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn config(&self) -> &Config {
|
||||||
|
&self.config
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn root_context(&self) -> &PossiblyCurrentContext {
|
||||||
|
&self.root_context
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_wayland_display_handle(display_id: &ObjectId) -> Result<RawDisplayHandle> {
|
||||||
|
let display = NonNull::new(display_id.as_ptr().cast::<c_void>()).ok_or_else(|| {
|
||||||
|
LayerShikaError::InvalidInput {
|
||||||
|
message: "Failed to create NonNull pointer for display".into(),
|
||||||
|
}
|
||||||
|
})?;
|
||||||
|
let handle = WaylandDisplayHandle::new(display);
|
||||||
|
Ok(RawDisplayHandle::Wayland(handle))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn select_config(
|
||||||
|
glutin_display: &Display,
|
||||||
|
config_template: ConfigTemplateBuilder,
|
||||||
|
) -> Result<Config> {
|
||||||
|
let mut configs = unsafe { glutin_display.find_configs(config_template.build()) }
|
||||||
|
.map_err(|e| EGLError::ConfigSelection { source: e.into() })?;
|
||||||
|
configs
|
||||||
|
.next()
|
||||||
|
.ok_or_else(|| EGLError::NoCompatibleConfig.into())
|
||||||
|
}
|
||||||
|
|
@ -1,10 +1,14 @@
|
||||||
use crate::{bind_globals, errors::LayerShikaError};
|
use crate::{
|
||||||
|
bind_globals, errors::LayerShikaError,
|
||||||
|
rendering::egl::render_context_manager::RenderContextManager,
|
||||||
|
};
|
||||||
use log::info;
|
use log::info;
|
||||||
use smithay_client_toolkit::reexports::protocols_wlr::layer_shell::v1::client::zwlr_layer_shell_v1::ZwlrLayerShellV1;
|
use smithay_client_toolkit::reexports::protocols_wlr::layer_shell::v1::client::zwlr_layer_shell_v1::ZwlrLayerShellV1;
|
||||||
|
use std::rc::Rc;
|
||||||
use wayland_client::{
|
use wayland_client::{
|
||||||
globals::registry_queue_init,
|
globals::registry_queue_init,
|
||||||
protocol::{wl_compositor::WlCompositor, wl_output::WlOutput, wl_seat::WlSeat},
|
protocol::{wl_compositor::WlCompositor, wl_output::WlOutput, wl_seat::WlSeat},
|
||||||
Connection, QueueHandle,
|
Connection, Proxy, QueueHandle,
|
||||||
};
|
};
|
||||||
use wayland_protocols::wp::fractional_scale::v1::client::wp_fractional_scale_manager_v1::WpFractionalScaleManagerV1;
|
use wayland_protocols::wp::fractional_scale::v1::client::wp_fractional_scale_manager_v1::WpFractionalScaleManagerV1;
|
||||||
use wayland_protocols::wp::viewporter::client::wp_viewporter::WpViewporter;
|
use wayland_protocols::wp::viewporter::client::wp_viewporter::WpViewporter;
|
||||||
|
|
@ -20,6 +24,7 @@ pub struct GlobalContext {
|
||||||
pub xdg_wm_base: Option<XdgWmBase>,
|
pub xdg_wm_base: Option<XdgWmBase>,
|
||||||
pub fractional_scale_manager: Option<WpFractionalScaleManagerV1>,
|
pub fractional_scale_manager: Option<WpFractionalScaleManagerV1>,
|
||||||
pub viewporter: Option<WpViewporter>,
|
pub viewporter: Option<WpViewporter>,
|
||||||
|
pub render_context_manager: Rc<RenderContextManager>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GlobalContext {
|
impl GlobalContext {
|
||||||
|
|
@ -100,6 +105,9 @@ impl GlobalContext {
|
||||||
info!("Viewporter protocol not available");
|
info!("Viewporter protocol not available");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let render_context_manager =
|
||||||
|
RenderContextManager::new(&connection.display().id())?;
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
compositor,
|
compositor,
|
||||||
outputs,
|
outputs,
|
||||||
|
|
@ -108,6 +116,7 @@ impl GlobalContext {
|
||||||
xdg_wm_base,
|
xdg_wm_base,
|
||||||
fractional_scale_manager,
|
fractional_scale_manager,
|
||||||
viewporter,
|
viewporter,
|
||||||
|
render_context_manager,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ use std::rc::Rc;
|
||||||
use wayland_client::{
|
use wayland_client::{
|
||||||
Connection, EventQueue, Proxy, QueueHandle,
|
Connection, EventQueue, Proxy, QueueHandle,
|
||||||
backend::ObjectId,
|
backend::ObjectId,
|
||||||
protocol::{wl_display::WlDisplay, wl_pointer::WlPointer, wl_surface::WlSurface},
|
protocol::{wl_pointer::WlPointer, wl_surface::WlSurface},
|
||||||
};
|
};
|
||||||
|
|
||||||
type PopupManagersAndSurfaces = (Vec<Rc<PopupManager>>, Vec<Rc<ZwlrLayerSurfaceV1>>);
|
type PopupManagersAndSurfaces = (Vec<Rc<PopupManager>>, Vec<Rc<ZwlrLayerSurfaceV1>>);
|
||||||
|
|
@ -55,8 +55,6 @@ pub struct WaylandWindowingSystem {
|
||||||
connection: Rc<Connection>,
|
connection: Rc<Connection>,
|
||||||
event_queue: EventQueue<AppState>,
|
event_queue: EventQueue<AppState>,
|
||||||
event_loop: EventLoop<'static, AppState>,
|
event_loop: EventLoop<'static, AppState>,
|
||||||
#[allow(dead_code)]
|
|
||||||
render_factory: Rc<RenderContextFactory>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WaylandWindowingSystem {
|
impl WaylandWindowingSystem {
|
||||||
|
|
@ -66,15 +64,13 @@ impl WaylandWindowingSystem {
|
||||||
let event_loop =
|
let event_loop =
|
||||||
EventLoop::try_new().map_err(|e| EventLoopError::Creation { source: e })?;
|
EventLoop::try_new().map_err(|e| EventLoopError::Creation { source: e })?;
|
||||||
|
|
||||||
let render_factory = RenderContextFactory::new();
|
let state = Self::init_state(config, &connection, &mut event_queue)?;
|
||||||
let state = Self::init_state(config, &connection, &mut event_queue, &render_factory)?;
|
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
state,
|
state,
|
||||||
connection,
|
connection,
|
||||||
event_queue,
|
event_queue,
|
||||||
event_loop,
|
event_loop,
|
||||||
render_factory,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -101,7 +97,6 @@ impl WaylandWindowingSystem {
|
||||||
event_queue: &mut EventQueue<AppState>,
|
event_queue: &mut EventQueue<AppState>,
|
||||||
pointer: &Rc<WlPointer>,
|
pointer: &Rc<WlPointer>,
|
||||||
layer_surface_config: &LayerSurfaceConfig,
|
layer_surface_config: &LayerSurfaceConfig,
|
||||||
render_factory: &Rc<RenderContextFactory>,
|
|
||||||
) -> Result<Vec<OutputSetup>> {
|
) -> Result<Vec<OutputSetup>> {
|
||||||
let mut setups = Vec::new();
|
let mut setups = Vec::new();
|
||||||
|
|
||||||
|
|
@ -132,8 +127,10 @@ impl WaylandWindowingSystem {
|
||||||
let surface_ctx = SurfaceCtx::setup(&setup_params, layer_surface_config);
|
let surface_ctx = SurfaceCtx::setup(&setup_params, layer_surface_config);
|
||||||
let main_surface_id = surface_ctx.surface.id();
|
let main_surface_id = surface_ctx.surface.id();
|
||||||
|
|
||||||
let window =
|
let render_factory =
|
||||||
Self::initialize_renderer(&surface_ctx.surface, &connection.display(), config, render_factory)?;
|
RenderContextFactory::new(Rc::clone(&global_ctx.render_context_manager));
|
||||||
|
|
||||||
|
let window = Self::initialize_renderer(&surface_ctx.surface, config, &render_factory)?;
|
||||||
|
|
||||||
let mut builder = WindowStateBuilder::new()
|
let mut builder = WindowStateBuilder::new()
|
||||||
.with_component_definition(config.component_definition.clone())
|
.with_component_definition(config.component_definition.clone())
|
||||||
|
|
@ -222,7 +219,6 @@ impl WaylandWindowingSystem {
|
||||||
config: &WaylandWindowConfig,
|
config: &WaylandWindowConfig,
|
||||||
connection: &Connection,
|
connection: &Connection,
|
||||||
event_queue: &mut EventQueue<AppState>,
|
event_queue: &mut EventQueue<AppState>,
|
||||||
render_factory: &Rc<RenderContextFactory>,
|
|
||||||
) -> Result<AppState> {
|
) -> Result<AppState> {
|
||||||
let global_ctx = GlobalContext::initialize(connection, &event_queue.handle())?;
|
let global_ctx = GlobalContext::initialize(connection, &event_queue.handle())?;
|
||||||
let layer_surface_config = Self::create_layer_surface_config(config);
|
let layer_surface_config = Self::create_layer_surface_config(config);
|
||||||
|
|
@ -235,15 +231,17 @@ impl WaylandWindowingSystem {
|
||||||
Rc::clone(&shared_serial),
|
Rc::clone(&shared_serial),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let render_factory =
|
||||||
|
RenderContextFactory::new(Rc::clone(&global_ctx.render_context_manager));
|
||||||
|
|
||||||
let popup_context = PopupContext::new(
|
let popup_context = PopupContext::new(
|
||||||
global_ctx.compositor.clone(),
|
global_ctx.compositor.clone(),
|
||||||
global_ctx.xdg_wm_base.clone(),
|
global_ctx.xdg_wm_base.clone(),
|
||||||
global_ctx.seat.clone(),
|
global_ctx.seat.clone(),
|
||||||
global_ctx.fractional_scale_manager.clone(),
|
global_ctx.fractional_scale_manager.clone(),
|
||||||
global_ctx.viewporter.clone(),
|
global_ctx.viewporter.clone(),
|
||||||
connection.display(),
|
|
||||||
Rc::new(connection.clone()),
|
Rc::new(connection.clone()),
|
||||||
Rc::clone(render_factory),
|
Rc::clone(&render_factory),
|
||||||
);
|
);
|
||||||
|
|
||||||
let setups = Self::create_output_setups(
|
let setups = Self::create_output_setups(
|
||||||
|
|
@ -253,7 +251,6 @@ impl WaylandWindowingSystem {
|
||||||
event_queue,
|
event_queue,
|
||||||
&pointer,
|
&pointer,
|
||||||
&layer_surface_config,
|
&layer_surface_config,
|
||||||
render_factory,
|
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let platform = Self::setup_platform(&setups)?;
|
let platform = Self::setup_platform(&setups)?;
|
||||||
|
|
@ -327,17 +324,12 @@ impl WaylandWindowingSystem {
|
||||||
|
|
||||||
fn initialize_renderer(
|
fn initialize_renderer(
|
||||||
surface: &Rc<WlSurface>,
|
surface: &Rc<WlSurface>,
|
||||||
display: &WlDisplay,
|
|
||||||
config: &WaylandWindowConfig,
|
config: &WaylandWindowConfig,
|
||||||
render_factory: &Rc<RenderContextFactory>,
|
render_factory: &Rc<RenderContextFactory>,
|
||||||
) -> Result<Rc<FemtoVGWindow>> {
|
) -> Result<Rc<FemtoVGWindow>> {
|
||||||
let init_size = PhysicalSize::new(1, 1);
|
let init_size = PhysicalSize::new(1, 1);
|
||||||
|
|
||||||
let context = render_factory.create_context(
|
let context = render_factory.create_context(&surface.id(), init_size)?;
|
||||||
&display.id(),
|
|
||||||
&surface.id(),
|
|
||||||
init_size,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
let renderer = FemtoVGRenderer::new(context)
|
let renderer = FemtoVGRenderer::new(context)
|
||||||
.map_err(|e| LayerShikaError::FemtoVGRendererCreation { source: e })?;
|
.map_err(|e| LayerShikaError::FemtoVGRendererCreation { source: e })?;
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ use std::collections::HashMap;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use wayland_client::{
|
use wayland_client::{
|
||||||
backend::ObjectId,
|
backend::ObjectId,
|
||||||
protocol::{wl_compositor::WlCompositor, wl_display::WlDisplay, wl_seat::WlSeat, wl_surface::WlSurface},
|
protocol::{wl_compositor::WlCompositor, wl_seat::WlSeat, wl_surface::WlSurface},
|
||||||
Connection, Proxy, QueueHandle,
|
Connection, Proxy, QueueHandle,
|
||||||
};
|
};
|
||||||
use wayland_protocols::wp::fractional_scale::v1::client::wp_fractional_scale_manager_v1::WpFractionalScaleManagerV1;
|
use wayland_protocols::wp::fractional_scale::v1::client::wp_fractional_scale_manager_v1::WpFractionalScaleManagerV1;
|
||||||
|
|
@ -73,7 +73,6 @@ pub struct PopupContext {
|
||||||
seat: WlSeat,
|
seat: WlSeat,
|
||||||
fractional_scale_manager: Option<WpFractionalScaleManagerV1>,
|
fractional_scale_manager: Option<WpFractionalScaleManagerV1>,
|
||||||
viewporter: Option<WpViewporter>,
|
viewporter: Option<WpViewporter>,
|
||||||
display: WlDisplay,
|
|
||||||
render_factory: Rc<RenderContextFactory>,
|
render_factory: Rc<RenderContextFactory>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -86,7 +85,6 @@ impl PopupContext {
|
||||||
seat: WlSeat,
|
seat: WlSeat,
|
||||||
fractional_scale_manager: Option<WpFractionalScaleManagerV1>,
|
fractional_scale_manager: Option<WpFractionalScaleManagerV1>,
|
||||||
viewporter: Option<WpViewporter>,
|
viewporter: Option<WpViewporter>,
|
||||||
display: WlDisplay,
|
|
||||||
_connection: Rc<Connection>,
|
_connection: Rc<Connection>,
|
||||||
render_factory: Rc<RenderContextFactory>,
|
render_factory: Rc<RenderContextFactory>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
|
@ -96,7 +94,6 @@ impl PopupContext {
|
||||||
seat,
|
seat,
|
||||||
fractional_scale_manager,
|
fractional_scale_manager,
|
||||||
viewporter,
|
viewporter,
|
||||||
display,
|
|
||||||
render_factory,
|
render_factory,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -332,11 +329,10 @@ impl PopupManager {
|
||||||
popup_surface.surface.commit();
|
popup_surface.surface.commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
let context = self.context.render_factory.create_context(
|
let context = self
|
||||||
&self.context.display.id(),
|
.context
|
||||||
&popup_surface.surface.id(),
|
.render_factory
|
||||||
popup_size,
|
.create_context(&popup_surface.surface.id(), popup_size)?;
|
||||||
)?;
|
|
||||||
|
|
||||||
let renderer = FemtoVGRenderer::new(context)
|
let renderer = FemtoVGRenderer::new(context)
|
||||||
.map_err(|e| LayerShikaError::FemtoVGRendererCreation { source: e })?;
|
.map_err(|e| LayerShikaError::FemtoVGRendererCreation { source: e })?;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue