Skip to content

Commit

Permalink
wip: fix buffer offset
Browse files Browse the repository at this point in the history
  • Loading branch information
cmeissl committed Feb 24, 2024
1 parent 5386601 commit 4ad5199
Show file tree
Hide file tree
Showing 8 changed files with 167 additions and 74 deletions.
34 changes: 34 additions & 0 deletions anvil/src/shell/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,10 +151,44 @@ impl<BackendData: Backend> CompositorHandler for AnvilState<BackendData> {
}
if let Some(window) = self.window_for_surface(&root) {
window.0.on_commit();

if &root == surface {
let buffer_offset = with_states(surface, |states| {
states
.cached_state
.current::<SurfaceAttributes>()
.buffer_delta
.take()
});

if let Some(buffer_offset) = buffer_offset {
let current_loc = self.space.element_location(&window).unwrap();
self.space.map_element(window, current_loc + buffer_offset, false);
}
}
}
}
self.popups.commit(surface);

if let Some(dnd_icon) = self.dnd_icon.as_mut().and_then(|icon| {
if &icon.surface == surface {
Some(icon)
} else {
None
}
}) {
with_states(surface, |states| {
let buffer_delta = states
.cached_state
.current::<SurfaceAttributes>()
.buffer_delta
.take()
.unwrap_or_default();
tracing::trace!(offset = ?dnd_icon.offset, ?buffer_delta, "moving dnd offset");
dnd_icon.offset += buffer_delta;
});
}

ensure_initial_configure(surface, &self.space, &mut self.popups)
}
}
Expand Down
39 changes: 30 additions & 9 deletions anvil/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use smithay::{
},
input::{
keyboard::{Keysym, LedState, XkbConfig},
pointer::{CursorImageStatus, PointerHandle},
pointer::{CursorImageAttributes, CursorImageStatus, PointerHandle},
Seat, SeatHandler, SeatState,
},
output::Output,
Expand All @@ -41,7 +41,7 @@ use smithay::{
Display, DisplayHandle, Resource,
},
},
utils::{Clock, Monotonic, Rectangle},
utils::{Clock, Logical, Monotonic, Point, Rectangle},
wayland::{
compositor::{get_parent, with_states, CompositorClientState, CompositorState},
dmabuf::DmabufFeedback,
Expand All @@ -59,11 +59,11 @@ use smithay::{
security_context::{
SecurityContext, SecurityContextHandler, SecurityContextListenerSource, SecurityContextState,
},
selection::data_device::{
set_data_device_focus, ClientDndGrabHandler, DataDeviceHandler, DataDeviceState,
ServerDndGrabHandler,
},
selection::{
data_device::{
set_data_device_focus, ClientDndGrabHandler, DataDeviceHandler, DataDeviceState,
ServerDndGrabHandler,
},
primary_selection::{set_primary_focus, PrimarySelectionHandler, PrimarySelectionState},
wlr_data_control::{DataControlHandler, DataControlState},
SelectionHandler,
Expand Down Expand Up @@ -96,7 +96,7 @@ use crate::{
#[cfg(feature = "xwayland")]
use smithay::{
delegate_xwayland_keyboard_grab,
utils::{Point, Size},
utils::Size,
wayland::selection::{SelectionSource, SelectionTarget},
wayland::xwayland_keyboard_grab::{XWaylandKeyboardGrabHandler, XWaylandKeyboardGrabState},
xwayland::{X11Wm, XWayland, XWaylandEvent},
Expand Down Expand Up @@ -148,7 +148,7 @@ pub struct AnvilState<BackendData: Backend + 'static> {
pub presentation_state: PresentationState,
pub fractional_scale_manager_state: FractionalScaleManagerState,

pub dnd_icon: Option<WlSurface>,
pub dnd_icon: Option<DndIcon>,

// input-related fields
pub suppressed_keys: Vec<Keysym>,
Expand All @@ -171,6 +171,12 @@ pub struct AnvilState<BackendData: Backend + 'static> {
pub show_window_preview: bool,
}

#[derive(Debug)]
pub struct DndIcon {
pub surface: WlSurface,
pub offset: Point<i32, Logical>,
}

delegate_compositor!(@<BackendData: Backend + 'static> AnvilState<BackendData>);

impl<BackendData: Backend> DataDeviceHandler for AnvilState<BackendData> {
Expand All @@ -181,7 +187,22 @@ impl<BackendData: Backend> DataDeviceHandler for AnvilState<BackendData> {

impl<BackendData: Backend> ClientDndGrabHandler for AnvilState<BackendData> {
fn started(&mut self, _source: Option<WlDataSource>, icon: Option<WlSurface>, _seat: Seat<Self>) {
self.dnd_icon = icon;
let cursor_status = self.cursor_status.lock().unwrap();
let offset = if let CursorImageStatus::Surface(ref surface) = *cursor_status {
with_states(surface, |states| {
let hotspot = states
.data_map
.get::<Mutex<CursorImageAttributes>>()
.unwrap()
.lock()
.unwrap()
.hotspot;
Point::from((-hotspot.x, -hotspot.y))
})
} else {
(0, 0).into()
};
self.dnd_icon = icon.map(|surface| DndIcon { surface, offset });
}
fn dropped(&mut self, _seat: Seat<Self>) {
self.dnd_icon = None;
Expand Down
29 changes: 20 additions & 9 deletions anvil/src/udev.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use std::{
time::{Duration, Instant},
};

use crate::state::SurfaceDmabufFeedback;
use crate::state::{DndIcon, SurfaceDmabufFeedback};
use crate::{
drawing::*,
render::*,
Expand Down Expand Up @@ -1566,7 +1566,7 @@ fn render_surface<'a>(
pointer_location: Point<f64, Logical>,
pointer_image: &MemoryRenderBuffer,
pointer_element: &mut PointerElement,
dnd_icon: &Option<wl_surface::WlSurface>,
dnd_icon: &Option<DndIcon>,
cursor_status: &mut CursorImageStatus,
clock: &Clock<Monotonic>,
show_window_preview: bool,
Expand All @@ -1590,8 +1590,7 @@ fn render_surface<'a>(
} else {
(0, 0).into()
};
let cursor_pos = pointer_location - output_geometry.loc.to_f64() - cursor_hotspot.to_f64();
let cursor_pos_scaled = cursor_pos.to_physical(scale).to_i32_round();
let cursor_pos = pointer_location - output_geometry.loc.to_f64();

// set cursor
pointer_element.set_buffer(pointer_image.clone());
Expand All @@ -1610,16 +1609,28 @@ fn render_surface<'a>(
pointer_element.set_status(cursor_status.clone());
}

custom_elements.extend(pointer_element.render_elements(renderer, cursor_pos_scaled, scale, 1.0));
custom_elements.extend(
pointer_element.render_elements(
renderer,
(cursor_pos - cursor_hotspot.to_f64())
.to_physical(scale)
.to_i32_round(),
scale,
1.0,
),
);

// draw the dnd icon if applicable
{
if let Some(wl_surface) = dnd_icon.as_ref() {
if wl_surface.alive() {
if let Some(icon) = dnd_icon.as_ref() {
let dnd_icon_pos = (cursor_pos + icon.offset.to_f64())
.to_physical(scale)
.to_i32_round();
if icon.surface.alive() {
custom_elements.extend(AsRenderElements::<UdevRenderer<'a>>::render_elements(
&SurfaceTree::from_surface(wl_surface),
&SurfaceTree::from_surface(&icon.surface),
renderer,
cursor_pos_scaled,
dnd_icon_pos,
scale,
1.0,
));
Expand Down
25 changes: 18 additions & 7 deletions anvil/src/winit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -291,8 +291,7 @@ pub fn run_winit() {
} else {
(0, 0).into()
};
let cursor_pos = state.pointer.current_location() - cursor_hotspot.to_f64();
let cursor_pos_scaled = cursor_pos.to_physical(scale).to_i32_round();
let cursor_pos = state.pointer.current_location();

#[cfg(feature = "debug")]
let mut renderdoc = state.renderdoc.as_mut();
Expand Down Expand Up @@ -324,15 +323,27 @@ pub fn run_winit() {

let mut elements = Vec::<CustomRenderElements<GlesRenderer>>::new();

elements.extend(pointer_element.render_elements(renderer, cursor_pos_scaled, scale, 1.0));
elements.extend(
pointer_element.render_elements(
renderer,
(cursor_pos - cursor_hotspot.to_f64())
.to_physical(scale)
.to_i32_round(),
scale,
1.0,
),
);

// draw the dnd icon if any
if let Some(surface) = dnd_icon {
if surface.alive() {
if let Some(icon) = dnd_icon {
let dnd_icon_pos = (cursor_pos + icon.offset.to_f64())
.to_physical(scale)
.to_i32_round();
if icon.surface.alive() {
elements.extend(AsRenderElements::<GlesRenderer>::render_elements(
&smithay::desktop::space::SurfaceTree::from_surface(surface),
&smithay::desktop::space::SurfaceTree::from_surface(&icon.surface),
renderer,
cursor_pos_scaled,
dnd_icon_pos,
scale,
1.0,
));
Expand Down
30 changes: 18 additions & 12 deletions anvil/src/x11.rs
Original file line number Diff line number Diff line change
Expand Up @@ -360,24 +360,30 @@ pub fn run_x11() {
} else {
(0, 0).into()
};
let cursor_pos = state.pointer.current_location() - cursor_hotspot.to_f64();
let cursor_pos_scaled = cursor_pos.to_physical(scale).to_i32_round();
let cursor_pos = state.pointer.current_location();

pointer_element.set_status(cursor_guard.clone());
elements.extend(pointer_element.render_elements(
&mut backend_data.renderer,
cursor_pos_scaled,
scale,
1.0,
));
elements.extend(
pointer_element.render_elements(
&mut backend_data.renderer,
(cursor_pos - cursor_hotspot.to_f64())
.to_physical(scale)
.to_i32_round(),
scale,
1.0,
),
);

// draw the dnd icon if any
if let Some(surface) = state.dnd_icon.as_ref() {
if surface.alive() {
if let Some(icon) = state.dnd_icon.as_ref() {
let dnd_icon_pos = (cursor_pos + icon.offset.to_f64())
.to_physical(scale)
.to_i32_round();
if icon.surface.alive() {
elements.extend(AsRenderElements::<GlesRenderer>::render_elements(
&smithay::desktop::space::SurfaceTree::from_surface(surface),
&smithay::desktop::space::SurfaceTree::from_surface(&icon.surface),
&mut backend_data.renderer,
cursor_pos_scaled,
dnd_icon_pos,
scale,
1.0,
));
Expand Down
31 changes: 3 additions & 28 deletions src/backend/renderer/utils/wayland.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,13 @@ pub struct RendererSurfaceState {
pub(crate) buffer_dimensions: Option<Size<i32, BufferCoord>>,
pub(crate) buffer_scale: i32,
pub(crate) buffer_transform: Transform,
pub(crate) buffer_delta: Option<Point<i32, Logical>>,
pub(crate) buffer_has_alpha: Option<bool>,
pub(crate) buffer: Option<Buffer>,
pub(crate) damage: DamageBag<i32, BufferCoord>,
pub(crate) renderer_seen: HashMap<(TypeId, usize), CommitCounter>,
pub(crate) textures: HashMap<(TypeId, usize), Box<dyn std::any::Any>>,
pub(crate) surface_view: Option<SurfaceView>,
pub(crate) opaque_regions: Vec<Rectangle<i32, Logical>>,

accumulated_buffer_delta: Point<i32, Logical>,
}

#[derive(Debug)]
Expand Down Expand Up @@ -96,12 +93,6 @@ impl RendererSurfaceState {
#[profiling::function]
pub(crate) fn update_buffer(&mut self, states: &SurfaceData) {
let mut attrs = states.cached_state.current::<SurfaceAttributes>();
self.buffer_delta = attrs.buffer_delta.take();

if let Some(delta) = self.buffer_delta {
self.accumulated_buffer_delta += delta;
}

match attrs.buffer.take() {
Some(BufferAssignment::NewBuffer(buffer)) => {
// new contents
Expand All @@ -126,8 +117,7 @@ impl RendererSurfaceState {
.buffer_dimensions
.unwrap()
.to_logical(self.buffer_scale, self.buffer_transform);
let surface_view =
SurfaceView::from_states(states, surface_size, self.accumulated_buffer_delta);
let surface_view = SurfaceView::from_states(states, surface_size);
self.surface_view = Some(surface_view);

let mut buffer_damage = attrs
Expand Down Expand Up @@ -266,16 +256,6 @@ impl RendererSurfaceState {
self.textures.get(&texture_id).and_then(|e| e.downcast_ref())
}

/// Location of the buffer relative to the previous call of take_accumulated_buffer_delta
///
/// In other words, the x and y, combined with the new surface size define in which directions
/// the surface's size changed since last call to this method.
///
/// Once delta is taken this method returns `None` to avoid processing it several times.
pub fn take_accumulated_buffer_delta(&mut self) -> Point<i32, Logical> {
std::mem::take(&mut self.accumulated_buffer_delta)
}

/// Gets the opaque regions of this surface
pub fn opaque_regions(&self) -> Option<&[Rectangle<i32, Logical>]> {
// If the surface is unmapped there can be no opaque regions
Expand Down Expand Up @@ -359,23 +339,18 @@ pub fn on_commit_buffer_handler<D: 'static>(surface: &WlSurface) {
}

impl SurfaceView {
fn from_states(
states: &SurfaceData,
surface_size: Size<i32, Logical>,
buffer_delta: Point<i32, Logical>,
) -> SurfaceView {
fn from_states(states: &SurfaceData, surface_size: Size<i32, Logical>) -> SurfaceView {
viewporter::ensure_viewport_valid(states, surface_size);
let viewport = states.cached_state.current::<viewporter::ViewportCachedState>();
let src = viewport
.src
.unwrap_or_else(|| Rectangle::from_loc_and_size((0.0, 0.0), surface_size.to_f64()));
let dst = viewport.size().unwrap_or(surface_size);
let mut offset = if states.role == Some("subsurface") {
let offset = if states.role == Some("subsurface") {
states.cached_state.current::<SubsurfaceCachedState>().location
} else {
Default::default()
};
offset += buffer_delta;
SurfaceView { src, dst, offset }
}

Expand Down
Loading

0 comments on commit 4ad5199

Please sign in to comment.