fix: invalidate semantic materials on scene changes
This commit is contained in:
1 parent
ae6ec1c5f5
commit
b3c5821e3b
4 files changed
+55
-19
No files matched your search
+38
-19
@@ -96,11 +96,14 @@ impl SurfaceEffectsState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_role(&self, role: Option<SemanticRole>) {
|
fn set_role(&self, role: Option<SemanticRole>) -> bool {
|
||||||
let mut current = self.role.lock().unwrap();
|
let mut current = self.role.lock().unwrap();
|
||||||
if *current != role {
|
if *current != role {
|
||||||
*current = role;
|
*current = role;
|
||||||
self.generation.fetch_add(1, Ordering::Release);
|
self.generation.fetch_add(1, Ordering::Release);
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -192,7 +195,7 @@ impl Dispatch<FereseEffectsManagerV1, ()> for Ferese {
|
|||||||
|
|
||||||
impl Dispatch<FereseSurfaceEffectsV1, SurfaceEffectsUserData> for Ferese {
|
impl Dispatch<FereseSurfaceEffectsV1, SurfaceEffectsUserData> for Ferese {
|
||||||
fn request(
|
fn request(
|
||||||
_state: &mut Self,
|
state: &mut Self,
|
||||||
_client: &Client,
|
_client: &Client,
|
||||||
_resource: &FereseSurfaceEffectsV1,
|
_resource: &FereseSurfaceEffectsV1,
|
||||||
request: ferese_surface_effects_v1::Request,
|
request: ferese_surface_effects_v1::Request,
|
||||||
@@ -220,10 +223,23 @@ impl Dispatch<FereseSurfaceEffectsV1, SurfaceEffectsUserData> for Ferese {
|
|||||||
WEnum::Value(ferese_surface_effects_v1::Role::Modal) => SemanticRole::Modal,
|
WEnum::Value(ferese_surface_effects_v1::Role::Modal) => SemanticRole::Modal,
|
||||||
WEnum::Unknown(_) | WEnum::Value(_) => return,
|
WEnum::Unknown(_) | WEnum::Value(_) => return,
|
||||||
};
|
};
|
||||||
set_surface_role(&surface, Some(role));
|
if set_surface_role(&surface, Some(role)) {
|
||||||
|
state.invalidate_material_scene();
|
||||||
|
crate::backends::direct::render_all(state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ferese_surface_effects_v1::Request::ClearRole => {
|
||||||
|
if set_surface_role(&surface, None) {
|
||||||
|
state.invalidate_material_scene();
|
||||||
|
crate::backends::direct::render_all(state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ferese_surface_effects_v1::Request::Destroy => {
|
||||||
|
if detach(&surface) {
|
||||||
|
state.invalidate_material_scene();
|
||||||
|
crate::backends::direct::render_all(state);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ferese_surface_effects_v1::Request::ClearRole => set_surface_role(&surface, None),
|
|
||||||
ferese_surface_effects_v1::Request::Destroy => detach(&surface),
|
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -240,21 +256,24 @@ impl Dispatch<FereseSurfaceEffectsV1, SurfaceEffectsUserData> for Ferese {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_surface_role(surface: &WlSurface, role: Option<SemanticRole>) {
|
fn set_surface_role(surface: &WlSurface, role: Option<SemanticRole>) -> bool {
|
||||||
with_states(surface, |states| {
|
with_states(surface, |states| {
|
||||||
if let Some(effects) = states.data_map.get::<SurfaceEffectsState>() {
|
states
|
||||||
effects.set_role(role);
|
.data_map
|
||||||
}
|
.get::<SurfaceEffectsState>()
|
||||||
});
|
.is_some_and(|effects| effects.set_role(role))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn detach(surface: &WlSurface) {
|
fn detach(surface: &WlSurface) -> bool {
|
||||||
with_states(surface, |states| {
|
with_states(surface, |states| {
|
||||||
if let Some(effects) = states.data_map.get::<SurfaceEffectsState>() {
|
let Some(effects) = states.data_map.get::<SurfaceEffectsState>() else {
|
||||||
effects.set_role(None);
|
return false;
|
||||||
effects.attached.store(false, Ordering::Release);
|
};
|
||||||
}
|
let role_changed = effects.set_role(None);
|
||||||
});
|
let was_attached = effects.attached.swap(false, Ordering::AcqRel);
|
||||||
|
role_changed || was_attached
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@@ -264,13 +283,13 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn role_changes_advance_generation_only_when_material_changes() {
|
fn role_changes_advance_generation_only_when_material_changes() {
|
||||||
let effects = SurfaceEffectsState::new();
|
let effects = SurfaceEffectsState::new();
|
||||||
effects.set_role(Some(SemanticRole::Panel));
|
assert!(effects.set_role(Some(SemanticRole::Panel)));
|
||||||
assert_eq!(effects.generation.load(Ordering::Acquire), 1);
|
assert_eq!(effects.generation.load(Ordering::Acquire), 1);
|
||||||
|
|
||||||
effects.set_role(Some(SemanticRole::Panel));
|
assert!(!effects.set_role(Some(SemanticRole::Panel)));
|
||||||
assert_eq!(effects.generation.load(Ordering::Acquire), 1);
|
assert_eq!(effects.generation.load(Ordering::Acquire), 1);
|
||||||
|
|
||||||
effects.set_role(Some(SemanticRole::Popover));
|
assert!(effects.set_role(Some(SemanticRole::Popover)));
|
||||||
assert_eq!(effects.generation.load(Ordering::Acquire), 2);
|
assert_eq!(effects.generation.load(Ordering::Acquire), 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ impl CompositorHandler for Ferese {
|
|||||||
|
|
||||||
fn commit(&mut self, surface: &WlSurface) {
|
fn commit(&mut self, surface: &WlSurface) {
|
||||||
on_commit_buffer_handler::<Self>(surface);
|
on_commit_buffer_handler::<Self>(surface);
|
||||||
|
self.invalidate_material_scene();
|
||||||
if !is_sync_subsurface(surface) {
|
if !is_sync_subsurface(surface) {
|
||||||
let mut root = surface.clone();
|
let mut root = surface.clone();
|
||||||
while let Some(parent) = get_parent(&root) {
|
while let Some(parent) = get_parent(&root) {
|
||||||
|
|||||||
@@ -124,6 +124,7 @@ pub struct Ferese {
|
|||||||
pub(crate) rounded_clip_programs: HashMap<ErasedContextId, crate::winit::RoundedClipPrograms>,
|
pub(crate) rounded_clip_programs: HashMap<ErasedContextId, crate::winit::RoundedClipPrograms>,
|
||||||
pub(crate) material_programs: HashMap<ErasedContextId, crate::winit::MaterialProgram>,
|
pub(crate) material_programs: HashMap<ErasedContextId, crate::winit::MaterialProgram>,
|
||||||
pub(crate) material_buffers: HashMap<WlSurface, crate::winit::MaterialBuffers>,
|
pub(crate) material_buffers: HashMap<WlSurface, crate::winit::MaterialBuffers>,
|
||||||
|
material_scene_generation: u64,
|
||||||
closing_windows: HashMap<WindowId, ClosingAnimation>,
|
closing_windows: HashMap<WindowId, ClosingAnimation>,
|
||||||
viewport_animations: HashMap<WorkspaceId, AnimatedValue>,
|
viewport_animations: HashMap<WorkspaceId, AnimatedValue>,
|
||||||
scrolling_world_x: HashMap<WindowId, (WorkspaceId, AnimatedValue)>,
|
scrolling_world_x: HashMap<WindowId, (WorkspaceId, AnimatedValue)>,
|
||||||
@@ -438,6 +439,7 @@ impl Ferese {
|
|||||||
rounded_clip_programs: HashMap::new(),
|
rounded_clip_programs: HashMap::new(),
|
||||||
material_programs: HashMap::new(),
|
material_programs: HashMap::new(),
|
||||||
material_buffers: HashMap::new(),
|
material_buffers: HashMap::new(),
|
||||||
|
material_scene_generation: 0,
|
||||||
closing_windows: HashMap::new(),
|
closing_windows: HashMap::new(),
|
||||||
viewport_animations: HashMap::new(),
|
viewport_animations: HashMap::new(),
|
||||||
scrolling_world_x: HashMap::new(),
|
scrolling_world_x: HashMap::new(),
|
||||||
@@ -1276,9 +1278,21 @@ impl Ferese {
|
|||||||
}
|
}
|
||||||
self.sync_window_stacking();
|
self.sync_window_stacking();
|
||||||
|
|
||||||
|
if active_animation {
|
||||||
|
self.invalidate_material_scene();
|
||||||
|
}
|
||||||
|
|
||||||
active_animation
|
active_animation
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn invalidate_material_scene(&mut self) {
|
||||||
|
self.material_scene_generation = self.material_scene_generation.wrapping_add(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn material_scene_generation(&self) -> u64 {
|
||||||
|
self.material_scene_generation
|
||||||
|
}
|
||||||
|
|
||||||
pub fn record_client_commit(&mut self, window: &Window) {
|
pub fn record_client_commit(&mut self, window: &Window) {
|
||||||
let Some(id) = self.window_ids.get(window) else {
|
let Some(id) = self.window_ids.get(window) else {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -247,6 +247,7 @@ struct MaterialParameters {
|
|||||||
tint: [f32; 4],
|
tint: [f32; 4],
|
||||||
noise: f32,
|
noise: f32,
|
||||||
generation: u64,
|
generation: u64,
|
||||||
|
scene_generation: u64,
|
||||||
opaque: bool,
|
opaque: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1207,6 +1208,7 @@ fn material_element(
|
|||||||
tint,
|
tint,
|
||||||
noise: material.noise,
|
noise: material.noise,
|
||||||
generation,
|
generation,
|
||||||
|
scene_generation: state.material_scene_generation(),
|
||||||
opaque: material.opacity == 1.0,
|
opaque: material.opacity == 1.0,
|
||||||
};
|
};
|
||||||
let context = renderer.context_id().erased();
|
let context = renderer.context_id().erased();
|
||||||
|
|||||||
Reference in new issue
Block a user