Merge pull request #94 from mahkoh/jorth/fix-screencopies
video: unify output rendering
This commit is contained in:
commit
439befcf78
13 changed files with 132 additions and 48 deletions
|
|
@ -380,22 +380,16 @@ impl MetalConnector {
|
||||||
if let Some(node) = self.state.root.outputs.get(&self.connector_id) {
|
if let Some(node) = self.state.root.outputs.get(&self.connector_id) {
|
||||||
let mut rr = self.render_result.borrow_mut();
|
let mut rr = self.render_result.borrow_mut();
|
||||||
let render_fb = buffer.render_fb();
|
let render_fb = buffer.render_fb();
|
||||||
render_fb.render_node(
|
self.state.present_output(
|
||||||
&*node,
|
&node,
|
||||||
&self.state,
|
&render_fb,
|
||||||
Some(node.global.pos.get()),
|
&buffer.render_tex,
|
||||||
Some(&mut rr),
|
&mut rr,
|
||||||
node.preferred_scale.get(),
|
|
||||||
!self.cursor_enabled.get(),
|
!self.cursor_enabled.get(),
|
||||||
);
|
);
|
||||||
if let Some(tex) = &buffer.dev_tex {
|
if let Some(tex) = &buffer.dev_tex {
|
||||||
buffer.dev_fb.copy_texture(tex, 0, 0);
|
buffer.dev_fb.copy_texture(tex, 0, 0);
|
||||||
}
|
}
|
||||||
for fr in rr.frame_requests.drain(..) {
|
|
||||||
fr.send_done();
|
|
||||||
let _ = fr.client.remove_obj(&*fr);
|
|
||||||
}
|
|
||||||
node.perform_screencopies(&*render_fb, &buffer.render_tex);
|
|
||||||
}
|
}
|
||||||
changes.change_object(plane.id, |c| {
|
changes.change_object(plane.id, |c| {
|
||||||
c.change(plane.fb_id, buffer.drm.id().0 as _);
|
c.change(plane.fb_id, buffer.drm.id().0 as _);
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,6 @@ use {
|
||||||
collections::VecDeque,
|
collections::VecDeque,
|
||||||
error::Error,
|
error::Error,
|
||||||
future::pending,
|
future::pending,
|
||||||
ops::DerefMut,
|
|
||||||
rc::Rc,
|
rc::Rc,
|
||||||
},
|
},
|
||||||
thiserror::Error,
|
thiserror::Error,
|
||||||
|
|
@ -733,21 +732,13 @@ impl XBackend {
|
||||||
image.last_serial.set(serial);
|
image.last_serial.set(serial);
|
||||||
|
|
||||||
if let Some(node) = self.state.root.outputs.get(&output.id) {
|
if let Some(node) = self.state.root.outputs.get(&output.id) {
|
||||||
let mut rr = self.render_result.borrow_mut();
|
self.state.present_output(
|
||||||
let fb = image.fb.get();
|
&node,
|
||||||
fb.render_node(
|
&image.fb.get(),
|
||||||
&*node,
|
&image.tex.get(),
|
||||||
&self.state,
|
&mut self.render_result.borrow_mut(),
|
||||||
Some(node.global.pos.get()),
|
|
||||||
Some(rr.deref_mut()),
|
|
||||||
node.preferred_scale.get(),
|
|
||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
for fr in rr.frame_requests.drain(..) {
|
|
||||||
fr.send_done();
|
|
||||||
let _ = fr.client.remove_obj(&*fr);
|
|
||||||
}
|
|
||||||
node.perform_screencopies(&*fb, &image.tex.get());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let pp = PresentPixmap {
|
let pp = PresentPixmap {
|
||||||
|
|
|
||||||
|
|
@ -392,7 +392,6 @@ fn create_dummy_output(state: &Rc<State>) {
|
||||||
scroll: Default::default(),
|
scroll: Default::default(),
|
||||||
pointer_positions: Default::default(),
|
pointer_positions: Default::default(),
|
||||||
lock_surface: Default::default(),
|
lock_surface: Default::default(),
|
||||||
preferred_scale: Cell::new(Scale::from_int(1)),
|
|
||||||
hardware_cursor: Default::default(),
|
hardware_cursor: Default::default(),
|
||||||
update_render_data_scheduled: Cell::new(false),
|
update_render_data_scheduled: Cell::new(false),
|
||||||
screencasts: Default::default(),
|
screencasts: Default::default(),
|
||||||
|
|
|
||||||
|
|
@ -717,7 +717,7 @@ impl ConfigProxyHandler {
|
||||||
fn handle_connector_get_scale(&self, connector: Connector) -> Result<(), CphError> {
|
fn handle_connector_get_scale(&self, connector: Connector) -> Result<(), CphError> {
|
||||||
let connector = self.get_output(connector)?;
|
let connector = self.get_output(connector)?;
|
||||||
self.respond(Response::ConnectorGetScale {
|
self.respond(Response::ConnectorGetScale {
|
||||||
scale: connector.node.preferred_scale.get().to_f64(),
|
scale: connector.node.global.preferred_scale.get().to_f64(),
|
||||||
});
|
});
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -149,7 +149,12 @@ impl JayScreencast {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn copy_texture(&self, on: &OutputNode, texture: &Rc<dyn GfxTexture>) {
|
pub fn copy_texture(
|
||||||
|
&self,
|
||||||
|
on: &OutputNode,
|
||||||
|
texture: &Rc<dyn GfxTexture>,
|
||||||
|
render_hardware_cursors: bool,
|
||||||
|
) {
|
||||||
if !self.running.get() {
|
if !self.running.get() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -165,7 +170,15 @@ impl JayScreencast {
|
||||||
let mut buffer = self.buffers.borrow_mut();
|
let mut buffer = self.buffers.borrow_mut();
|
||||||
for (idx, buffer) in buffer.deref_mut().iter_mut().enumerate() {
|
for (idx, buffer) in buffer.deref_mut().iter_mut().enumerate() {
|
||||||
if buffer.free {
|
if buffer.free {
|
||||||
buffer.fb.copy_texture(texture, 0, 0);
|
self.client.state.perform_screencopy(
|
||||||
|
texture,
|
||||||
|
&buffer.fb,
|
||||||
|
on.global.preferred_scale.get(),
|
||||||
|
on.global.pos.get(),
|
||||||
|
render_hardware_cursors,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
);
|
||||||
self.client.event(Ready {
|
self.client.event(Ready {
|
||||||
self_id: self.id,
|
self_id: self.id,
|
||||||
idx: idx as _,
|
idx: idx as _,
|
||||||
|
|
|
||||||
|
|
@ -74,6 +74,7 @@ pub struct WlOutputGlobal {
|
||||||
pub pending_captures: LinkedList<Rc<ZwlrScreencopyFrameV1>>,
|
pub pending_captures: LinkedList<Rc<ZwlrScreencopyFrameV1>>,
|
||||||
pub destroyed: Cell<bool>,
|
pub destroyed: Cell<bool>,
|
||||||
pub legacy_scale: Cell<u32>,
|
pub legacy_scale: Cell<u32>,
|
||||||
|
pub preferred_scale: Cell<crate::scale::Scale>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Eq, PartialEq)]
|
#[derive(Eq, PartialEq)]
|
||||||
|
|
@ -120,6 +121,7 @@ impl WlOutputGlobal {
|
||||||
pending_captures: Default::default(),
|
pending_captures: Default::default(),
|
||||||
destroyed: Cell::new(false),
|
destroyed: Cell::new(false),
|
||||||
legacy_scale: Cell::new(1),
|
legacy_scale: Cell::new(1),
|
||||||
|
preferred_scale: Cell::new(crate::scale::Scale::from_int(1)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -200,7 +202,12 @@ impl WlOutputGlobal {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn perform_screencopies(&self, fb: &dyn GfxFramebuffer, tex: &Rc<dyn GfxTexture>) {
|
pub fn perform_screencopies(
|
||||||
|
&self,
|
||||||
|
fb: &dyn GfxFramebuffer,
|
||||||
|
tex: &Rc<dyn GfxTexture>,
|
||||||
|
render_hardware_cursors: bool,
|
||||||
|
) {
|
||||||
if self.pending_captures.is_empty() {
|
if self.pending_captures.is_empty() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -276,7 +283,15 @@ impl WlOutputGlobal {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
fb.copy_texture(tex, -capture.rect.x1(), -capture.rect.y1());
|
self.state.perform_screencopy(
|
||||||
|
tex,
|
||||||
|
&fb,
|
||||||
|
self.preferred_scale.get(),
|
||||||
|
self.pos.get(),
|
||||||
|
render_hardware_cursors,
|
||||||
|
-capture.rect.x1(),
|
||||||
|
-capture.rect.y1(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
if capture.with_damage.get() {
|
if capture.with_damage.get() {
|
||||||
capture.send_damage();
|
capture.send_damage();
|
||||||
|
|
|
||||||
|
|
@ -265,7 +265,7 @@ impl WlSeatGlobal {
|
||||||
for output in self.state.root.outputs.lock().values() {
|
for output in self.state.root.outputs.lock().values() {
|
||||||
if let Some(hc) = output.hardware_cursor.get() {
|
if let Some(hc) = output.hardware_cursor.get() {
|
||||||
let render = render | output.hardware_cursor_needs_render.take();
|
let render = render | output.hardware_cursor_needs_render.take();
|
||||||
let scale = output.preferred_scale.get();
|
let scale = output.global.preferred_scale.get();
|
||||||
let extents = cursor.extents_at_scale(scale);
|
let extents = cursor.extents_at_scale(scale);
|
||||||
if render {
|
if render {
|
||||||
let (max_width, max_height) = hc.max_size();
|
let (max_width, max_height) = hc.max_size();
|
||||||
|
|
|
||||||
|
|
@ -438,7 +438,7 @@ impl WlSurface {
|
||||||
}
|
}
|
||||||
output.global.send_enter(self);
|
output.global.send_enter(self);
|
||||||
old.global.send_leave(self);
|
old.global.send_leave(self);
|
||||||
if old.preferred_scale.get() != output.preferred_scale.get() {
|
if old.global.preferred_scale.get() != output.global.preferred_scale.get() {
|
||||||
self.on_scale_change();
|
self.on_scale_change();
|
||||||
}
|
}
|
||||||
let children = self.children.borrow_mut();
|
let children = self.children.borrow_mut();
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ impl WpFractionalScaleV1 {
|
||||||
pub fn send_preferred_scale(&self) {
|
pub fn send_preferred_scale(&self) {
|
||||||
self.client.event(PreferredScale {
|
self.client.event(PreferredScale {
|
||||||
self_id: self.id,
|
self_id: self.id,
|
||||||
scale: self.surface.output.get().preferred_scale.get().0,
|
scale: self.surface.output.get().global.preferred_scale.get().0,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -139,7 +139,7 @@ impl Renderer<'_> {
|
||||||
let c = theme.colors.attention_requested_background.get();
|
let c = theme.colors.attention_requested_background.get();
|
||||||
self.base
|
self.base
|
||||||
.fill_boxes2(&rd.attention_requested_workspaces, &c, x, y);
|
.fill_boxes2(&rd.attention_requested_workspaces, &c, x, y);
|
||||||
let scale = output.preferred_scale.get();
|
let scale = output.global.preferred_scale.get();
|
||||||
for title in &rd.titles {
|
for title in &rd.titles {
|
||||||
let (x, y) = self.base.scale_point(x + title.tex_x, y + title.tex_y);
|
let (x, y) = self.base.scale_point(x + title.tex_x, y + title.tex_y);
|
||||||
self.base
|
self.base
|
||||||
|
|
|
||||||
72
src/state.rs
72
src/state.rs
|
|
@ -13,8 +13,9 @@ use {
|
||||||
cursor::{Cursor, ServerCursors},
|
cursor::{Cursor, ServerCursors},
|
||||||
dbus::Dbus,
|
dbus::Dbus,
|
||||||
drm_feedback::DrmFeedback,
|
drm_feedback::DrmFeedback,
|
||||||
|
fixed::Fixed,
|
||||||
forker::ForkerProxy,
|
forker::ForkerProxy,
|
||||||
gfx_api::{GfxContext, GfxError},
|
gfx_api::{GfxContext, GfxError, GfxFramebuffer, GfxTexture},
|
||||||
gfx_apis::create_gfx_context,
|
gfx_apis::create_gfx_context,
|
||||||
globals::{Globals, GlobalsError, WaylandGlobal},
|
globals::{Globals, GlobalsError, WaylandGlobal},
|
||||||
ifs::{
|
ifs::{
|
||||||
|
|
@ -36,8 +37,9 @@ use {
|
||||||
leaks::Tracker,
|
leaks::Tracker,
|
||||||
logger::Logger,
|
logger::Logger,
|
||||||
rect::Rect,
|
rect::Rect,
|
||||||
|
renderer::{renderer_base::RendererBase, RenderResult, Renderer},
|
||||||
scale::Scale,
|
scale::Scale,
|
||||||
theme::Theme,
|
theme::{Color, Theme},
|
||||||
tree::{
|
tree::{
|
||||||
ContainerNode, ContainerSplit, Direction, DisplayNode, FloatNode, Node, NodeIds,
|
ContainerNode, ContainerSplit, Direction, DisplayNode, FloatNode, Node, NodeIds,
|
||||||
NodeVisitorBase, OutputNode, PlaceholderNode, ToplevelNode, WorkspaceNode,
|
NodeVisitorBase, OutputNode, PlaceholderNode, ToplevelNode, WorkspaceNode,
|
||||||
|
|
@ -730,4 +732,70 @@ impl State {
|
||||||
f(tester);
|
f(tester);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn present_output(
|
||||||
|
&self,
|
||||||
|
output: &OutputNode,
|
||||||
|
fb: &Rc<dyn GfxFramebuffer>,
|
||||||
|
tex: &Rc<dyn GfxTexture>,
|
||||||
|
rr: &mut RenderResult,
|
||||||
|
render_hw_cursor: bool,
|
||||||
|
) {
|
||||||
|
fb.render_node(
|
||||||
|
output,
|
||||||
|
self,
|
||||||
|
Some(output.global.pos.get()),
|
||||||
|
Some(rr),
|
||||||
|
output.global.preferred_scale.get(),
|
||||||
|
render_hw_cursor,
|
||||||
|
);
|
||||||
|
for fr in rr.frame_requests.drain(..) {
|
||||||
|
fr.send_done();
|
||||||
|
let _ = fr.client.remove_obj(&*fr);
|
||||||
|
}
|
||||||
|
output.perform_screencopies(&**fb, tex, !render_hw_cursor);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn perform_screencopy(
|
||||||
|
&self,
|
||||||
|
src: &Rc<dyn GfxTexture>,
|
||||||
|
target: &Rc<dyn GfxFramebuffer>,
|
||||||
|
scale: Scale,
|
||||||
|
position: Rect,
|
||||||
|
render_hardware_cursors: bool,
|
||||||
|
x_off: i32,
|
||||||
|
y_off: i32,
|
||||||
|
) {
|
||||||
|
let mut ops = target.take_render_ops();
|
||||||
|
let (width, height) = target.size();
|
||||||
|
let mut renderer = Renderer {
|
||||||
|
base: RendererBase {
|
||||||
|
ops: &mut ops,
|
||||||
|
scaled: scale != 1,
|
||||||
|
scale,
|
||||||
|
scalef: scale.to_f64(),
|
||||||
|
},
|
||||||
|
state: self,
|
||||||
|
result: None,
|
||||||
|
logical_extents: position.at_point(0, 0),
|
||||||
|
physical_extents: Rect::new_sized(0, 0, width, height).unwrap(),
|
||||||
|
};
|
||||||
|
renderer
|
||||||
|
.base
|
||||||
|
.render_texture(src, x_off, y_off, None, None, scale, None);
|
||||||
|
if render_hardware_cursors {
|
||||||
|
for seat in self.globals.lock_seats().values() {
|
||||||
|
if let Some(cursor) = seat.get_cursor() {
|
||||||
|
let (mut x, mut y) = seat.get_position();
|
||||||
|
if seat.hardware_cursor() {
|
||||||
|
x = x + x_off - Fixed::from_int(position.x1());
|
||||||
|
y = y + y_off - Fixed::from_int(position.y1());
|
||||||
|
cursor.render(&mut renderer, x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let clear = target.format().has_alpha.then_some(&Color::TRANSPARENT);
|
||||||
|
target.render(ops, clear);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ use {
|
||||||
crate::{
|
crate::{
|
||||||
backend::{Connector, ConnectorEvent, ConnectorId, MonitorInfo},
|
backend::{Connector, ConnectorEvent, ConnectorId, MonitorInfo},
|
||||||
ifs::wl_output::WlOutputGlobal,
|
ifs::wl_output::WlOutputGlobal,
|
||||||
scale::Scale,
|
|
||||||
state::{ConnectorData, OutputData, State},
|
state::{ConnectorData, OutputData, State},
|
||||||
tree::{OutputNode, OutputRenderData},
|
tree::{OutputNode, OutputRenderData},
|
||||||
utils::{asyncevent::AsyncEvent, clonecell::CloneCell},
|
utils::{asyncevent::AsyncEvent, clonecell::CloneCell},
|
||||||
|
|
@ -124,14 +123,13 @@ impl ConnectorHandler {
|
||||||
scroll: Default::default(),
|
scroll: Default::default(),
|
||||||
pointer_positions: Default::default(),
|
pointer_positions: Default::default(),
|
||||||
lock_surface: Default::default(),
|
lock_surface: Default::default(),
|
||||||
preferred_scale: Cell::new(Scale::from_int(1)),
|
|
||||||
hardware_cursor: Default::default(),
|
hardware_cursor: Default::default(),
|
||||||
jay_outputs: Default::default(),
|
jay_outputs: Default::default(),
|
||||||
screencasts: Default::default(),
|
screencasts: Default::default(),
|
||||||
update_render_data_scheduled: Cell::new(false),
|
update_render_data_scheduled: Cell::new(false),
|
||||||
hardware_cursor_needs_render: Cell::new(false),
|
hardware_cursor_needs_render: Cell::new(false),
|
||||||
});
|
});
|
||||||
self.state.add_output_scale(on.preferred_scale.get());
|
self.state.add_output_scale(on.global.preferred_scale.get());
|
||||||
let mode = info.initial_mode;
|
let mode = info.initial_mode;
|
||||||
let output_data = Rc::new(OutputData {
|
let output_data = Rc::new(OutputData {
|
||||||
connector: self.data.clone(),
|
connector: self.data.clone(),
|
||||||
|
|
@ -278,7 +276,8 @@ impl ConnectorHandler {
|
||||||
if let Some(dev) = &self.data.drm_dev {
|
if let Some(dev) = &self.data.drm_dev {
|
||||||
dev.connectors.remove(&self.id);
|
dev.connectors.remove(&self.id);
|
||||||
}
|
}
|
||||||
self.state.remove_output_scale(on.preferred_scale.get());
|
self.state
|
||||||
|
.remove_output_scale(on.global.preferred_scale.get());
|
||||||
let _ = self.state.remove_global(&*global);
|
let _ = self.state.remove_global(&*global);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,6 @@ pub struct OutputNode {
|
||||||
pub scroll: Scroller,
|
pub scroll: Scroller,
|
||||||
pub pointer_positions: CopyHashMap<SeatId, (i32, i32)>,
|
pub pointer_positions: CopyHashMap<SeatId, (i32, i32)>,
|
||||||
pub lock_surface: CloneCell<Option<Rc<ExtSessionLockSurfaceV1>>>,
|
pub lock_surface: CloneCell<Option<Rc<ExtSessionLockSurfaceV1>>>,
|
||||||
pub preferred_scale: Cell<Scale>,
|
|
||||||
pub hardware_cursor: CloneCell<Option<Rc<dyn HardwareCursor>>>,
|
pub hardware_cursor: CloneCell<Option<Rc<dyn HardwareCursor>>>,
|
||||||
pub hardware_cursor_needs_render: Cell<bool>,
|
pub hardware_cursor_needs_render: Cell<bool>,
|
||||||
pub update_render_data_scheduled: Cell<bool>,
|
pub update_render_data_scheduled: Cell<bool>,
|
||||||
|
|
@ -79,15 +78,21 @@ pub async fn output_render_data(state: Rc<State>) {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OutputNode {
|
impl OutputNode {
|
||||||
pub fn perform_screencopies(&self, fb: &dyn GfxFramebuffer, tex: &Rc<dyn GfxTexture>) {
|
pub fn perform_screencopies(
|
||||||
|
&self,
|
||||||
|
fb: &dyn GfxFramebuffer,
|
||||||
|
tex: &Rc<dyn GfxTexture>,
|
||||||
|
render_hardware_cursor: bool,
|
||||||
|
) {
|
||||||
if let Some(workspace) = self.workspace.get() {
|
if let Some(workspace) = self.workspace.get() {
|
||||||
if !workspace.capture.get() {
|
if !workspace.capture.get() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.global.perform_screencopies(fb, tex);
|
self.global
|
||||||
|
.perform_screencopies(fb, tex, render_hardware_cursor);
|
||||||
for sc in self.screencasts.lock().values() {
|
for sc in self.screencasts.lock().values() {
|
||||||
sc.copy_texture(self, tex);
|
sc.copy_texture(self, tex, render_hardware_cursor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -111,7 +116,7 @@ impl OutputNode {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_preferred_scale(self: &Rc<Self>, scale: Scale) {
|
pub fn set_preferred_scale(self: &Rc<Self>, scale: Scale) {
|
||||||
let old_scale = self.preferred_scale.replace(scale);
|
let old_scale = self.global.preferred_scale.replace(scale);
|
||||||
if scale == old_scale {
|
if scale == old_scale {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -152,7 +157,7 @@ impl OutputNode {
|
||||||
let font = self.state.theme.font.borrow_mut();
|
let font = self.state.theme.font.borrow_mut();
|
||||||
let theme = &self.state.theme;
|
let theme = &self.state.theme;
|
||||||
let th = theme.sizes.title_height.get();
|
let th = theme.sizes.title_height.get();
|
||||||
let scale = self.preferred_scale.get();
|
let scale = self.global.preferred_scale.get();
|
||||||
let scale = if scale != 1 {
|
let scale = if scale != 1 {
|
||||||
Some(scale.to_f64())
|
Some(scale.to_f64())
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -410,7 +415,7 @@ impl OutputNode {
|
||||||
let mode = self.global.mode.get();
|
let mode = self.global.mode.get();
|
||||||
let mut width = mode.width;
|
let mut width = mode.width;
|
||||||
let mut height = mode.height;
|
let mut height = mode.height;
|
||||||
let scale = self.preferred_scale.get();
|
let scale = self.global.preferred_scale.get();
|
||||||
if scale != 1 {
|
if scale != 1 {
|
||||||
let scale = scale.to_f64();
|
let scale = scale.to_f64();
|
||||||
width = (width as f64 / scale).round() as _;
|
width = (width as f64 / scale).round() as _;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue