mirror of
https://github.com/niri-wm/niri.git
synced 2026-06-23 02:05:33 +07:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 88b74f4a3a | |||
| b94b0c7fa4 |
Generated
+2
-2
@@ -3005,7 +3005,7 @@ checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7"
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "smithay"
|
name = "smithay"
|
||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
source = "git+https://github.com/Smithay/smithay.git#91e61f13501f21d66803efac947bfafed43080c5"
|
source = "git+https://github.com/YaLTeR/smithay.git?rev=0c06b7889b72e4392d89fab91f2d2cf4f272db83#0c06b7889b72e4392d89fab91f2d2cf4f272db83"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"appendlist",
|
"appendlist",
|
||||||
"bitflags 2.4.2",
|
"bitflags 2.4.2",
|
||||||
@@ -3077,7 +3077,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "smithay-drm-extras"
|
name = "smithay-drm-extras"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/Smithay/smithay.git#91e61f13501f21d66803efac947bfafed43080c5"
|
source = "git+https://github.com/YaLTeR/smithay.git?rev=0c06b7889b72e4392d89fab91f2d2cf4f272db83#0c06b7889b72e4392d89fab91f2d2cf4f272db83"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"drm",
|
"drm",
|
||||||
"edid-rs",
|
"edid-rs",
|
||||||
|
|||||||
+4
-2
@@ -19,12 +19,14 @@ tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
|
|||||||
tracy-client = { version = "0.16.5", default-features = false }
|
tracy-client = { version = "0.16.5", default-features = false }
|
||||||
|
|
||||||
[workspace.dependencies.smithay]
|
[workspace.dependencies.smithay]
|
||||||
git = "https://github.com/Smithay/smithay.git"
|
git = "https://github.com/YaLTeR/smithay.git"
|
||||||
|
rev = "0c06b7889b72e4392d89fab91f2d2cf4f272db83"
|
||||||
# path = "../smithay"
|
# path = "../smithay"
|
||||||
default-features = false
|
default-features = false
|
||||||
|
|
||||||
[workspace.dependencies.smithay-drm-extras]
|
[workspace.dependencies.smithay-drm-extras]
|
||||||
git = "https://github.com/Smithay/smithay.git"
|
git = "https://github.com/YaLTeR/smithay.git"
|
||||||
|
rev = "0c06b7889b72e4392d89fab91f2d2cf4f272db83"
|
||||||
# path = "../smithay/smithay-drm-extras"
|
# path = "../smithay/smithay-drm-extras"
|
||||||
|
|
||||||
[package]
|
[package]
|
||||||
|
|||||||
+9
-3
@@ -55,6 +55,7 @@ use self::workspace::{compute_working_area, Column, ColumnWidth, OutputId, Works
|
|||||||
use crate::animation::Animation;
|
use crate::animation::Animation;
|
||||||
use crate::niri::WindowOffscreenId;
|
use crate::niri::WindowOffscreenId;
|
||||||
use crate::niri_render_elements;
|
use crate::niri_render_elements;
|
||||||
|
use crate::render_helpers::nearest_integer_scale::NearestIntegerScale;
|
||||||
use crate::render_helpers::renderer::NiriRenderer;
|
use crate::render_helpers::renderer::NiriRenderer;
|
||||||
use crate::utils::output_size;
|
use crate::utils::output_size;
|
||||||
|
|
||||||
@@ -65,7 +66,7 @@ pub mod workspace;
|
|||||||
|
|
||||||
niri_render_elements! {
|
niri_render_elements! {
|
||||||
LayoutElementRenderElement => {
|
LayoutElementRenderElement => {
|
||||||
Wayland = WaylandSurfaceRenderElement<R>,
|
Wayland = NearestIntegerScale<WaylandSurfaceRenderElement<R>>,
|
||||||
SolidColor = SolidColorRenderElement,
|
SolidColor = SolidColorRenderElement,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -238,12 +239,17 @@ impl LayoutElement for Window {
|
|||||||
scale: Scale<f64>,
|
scale: Scale<f64>,
|
||||||
) -> Vec<LayoutElementRenderElement<R>> {
|
) -> Vec<LayoutElementRenderElement<R>> {
|
||||||
let buf_pos = location - self.geometry().loc;
|
let buf_pos = location - self.geometry().loc;
|
||||||
self.render_elements(
|
let elements: Vec<WaylandSurfaceRenderElement<R>> = self.render_elements(
|
||||||
renderer,
|
renderer,
|
||||||
buf_pos.to_physical_precise_round(scale),
|
buf_pos.to_physical_precise_round(scale),
|
||||||
scale,
|
scale,
|
||||||
1.,
|
1.,
|
||||||
)
|
);
|
||||||
|
elements
|
||||||
|
.into_iter()
|
||||||
|
.map(NearestIntegerScale::from)
|
||||||
|
.map(LayoutElementRenderElement::from)
|
||||||
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn request_size(&self, size: Size<i32, Logical>) {
|
fn request_size(&self, size: Size<i32, Logical>) {
|
||||||
|
|||||||
+11
-2
@@ -629,12 +629,18 @@ impl<W: LayoutElement> Monitor<W> {
|
|||||||
let before = self.workspaces[before_idx].render_elements(renderer);
|
let before = self.workspaces[before_idx].render_elements(renderer);
|
||||||
let after = self.workspaces[after_idx].render_elements(renderer);
|
let after = self.workspaces[after_idx].render_elements(renderer);
|
||||||
|
|
||||||
|
// HACK: crop to infinite bounds for all sides except the side where the workspaces
|
||||||
|
// join, to decrease the chance of cutting a lower-scale surface in the middle of a
|
||||||
|
// pixel, thereby disabling its nearest-neighbor upscaling.
|
||||||
let before = before.into_iter().filter_map(|elem| {
|
let before = before.into_iter().filter_map(|elem| {
|
||||||
Some(RelocateRenderElement::from_element(
|
Some(RelocateRenderElement::from_element(
|
||||||
CropRenderElement::from_element(
|
CropRenderElement::from_element(
|
||||||
elem,
|
elem,
|
||||||
output_scale,
|
output_scale,
|
||||||
Rectangle::from_extemities((0, offset), (size.w, size.h)),
|
Rectangle::from_extemities(
|
||||||
|
(-i32::MAX / 2, -i32::MAX / 2),
|
||||||
|
(i32::MAX / 2, size.h),
|
||||||
|
),
|
||||||
)?,
|
)?,
|
||||||
(0, -offset),
|
(0, -offset),
|
||||||
Relocate::Relative,
|
Relocate::Relative,
|
||||||
@@ -645,7 +651,10 @@ impl<W: LayoutElement> Monitor<W> {
|
|||||||
CropRenderElement::from_element(
|
CropRenderElement::from_element(
|
||||||
elem,
|
elem,
|
||||||
output_scale,
|
output_scale,
|
||||||
Rectangle::from_extemities((0, 0), (size.w, offset)),
|
Rectangle::from_extemities(
|
||||||
|
(-i32::MAX / 2, 0),
|
||||||
|
(i32::MAX / 2, i32::MAX / 2),
|
||||||
|
),
|
||||||
)?,
|
)?,
|
||||||
(0, -offset + size.h),
|
(0, -offset + size.h),
|
||||||
Relocate::Relative,
|
Relocate::Relative,
|
||||||
|
|||||||
+45
-26
@@ -101,6 +101,7 @@ use crate::ipc::server::IpcServer;
|
|||||||
use crate::layout::{Layout, MonitorRenderElement};
|
use crate::layout::{Layout, MonitorRenderElement};
|
||||||
use crate::protocols::foreign_toplevel::{self, ForeignToplevelManagerState};
|
use crate::protocols::foreign_toplevel::{self, ForeignToplevelManagerState};
|
||||||
use crate::pw_utils::{Cast, PipeWire};
|
use crate::pw_utils::{Cast, PipeWire};
|
||||||
|
use crate::render_helpers::nearest_integer_scale::NearestIntegerScale;
|
||||||
use crate::render_helpers::renderer::NiriRenderer;
|
use crate::render_helpers::renderer::NiriRenderer;
|
||||||
use crate::render_helpers::{render_to_texture, render_to_vec};
|
use crate::render_helpers::{render_to_texture, render_to_vec};
|
||||||
use crate::screenshot_ui::{ScreenshotUi, ScreenshotUiRenderElement};
|
use crate::screenshot_ui::{ScreenshotUi, ScreenshotUiRenderElement};
|
||||||
@@ -1693,14 +1694,20 @@ impl Niri {
|
|||||||
let pointer_pos =
|
let pointer_pos =
|
||||||
(pointer_pos - hotspot.to_f64()).to_physical_precise_round(output_scale);
|
(pointer_pos - hotspot.to_f64()).to_physical_precise_round(output_scale);
|
||||||
|
|
||||||
let pointer_elements = render_elements_from_surface_tree(
|
let pointer_elements: Vec<WaylandSurfaceRenderElement<_>> =
|
||||||
renderer,
|
render_elements_from_surface_tree(
|
||||||
&surface,
|
renderer,
|
||||||
pointer_pos,
|
&surface,
|
||||||
output_scale,
|
pointer_pos,
|
||||||
1.,
|
output_scale,
|
||||||
Kind::Cursor,
|
1.,
|
||||||
);
|
Kind::Cursor,
|
||||||
|
);
|
||||||
|
let pointer_elements = pointer_elements
|
||||||
|
.into_iter()
|
||||||
|
.map(NearestIntegerScale::from)
|
||||||
|
.map(OutputRenderElements::from)
|
||||||
|
.collect();
|
||||||
|
|
||||||
(pointer_elements, pointer_pos)
|
(pointer_elements, pointer_pos)
|
||||||
}
|
}
|
||||||
@@ -1740,14 +1747,20 @@ impl Niri {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if let Some(dnd_icon) = &self.dnd_icon {
|
if let Some(dnd_icon) = &self.dnd_icon {
|
||||||
pointer_elements.extend(render_elements_from_surface_tree(
|
let dnd_elements: Vec<WaylandSurfaceRenderElement<_>> =
|
||||||
renderer,
|
render_elements_from_surface_tree(
|
||||||
dnd_icon,
|
renderer,
|
||||||
pointer_pos,
|
dnd_icon,
|
||||||
output_scale,
|
pointer_pos,
|
||||||
1.,
|
output_scale,
|
||||||
Kind::Unspecified,
|
1.,
|
||||||
));
|
Kind::Unspecified,
|
||||||
|
);
|
||||||
|
let dnd_elements = dnd_elements
|
||||||
|
.into_iter()
|
||||||
|
.map(NearestIntegerScale::from)
|
||||||
|
.map(OutputRenderElements::from);
|
||||||
|
pointer_elements.extend(dnd_elements);
|
||||||
}
|
}
|
||||||
|
|
||||||
pointer_elements
|
pointer_elements
|
||||||
@@ -1923,14 +1936,20 @@ impl Niri {
|
|||||||
if self.is_locked() {
|
if self.is_locked() {
|
||||||
let state = self.output_state.get(output).unwrap();
|
let state = self.output_state.get(output).unwrap();
|
||||||
if let Some(surface) = state.lock_surface.as_ref() {
|
if let Some(surface) = state.lock_surface.as_ref() {
|
||||||
elements.extend(render_elements_from_surface_tree(
|
let lock_elements: Vec<WaylandSurfaceRenderElement<_>> =
|
||||||
renderer,
|
render_elements_from_surface_tree(
|
||||||
surface.wl_surface(),
|
renderer,
|
||||||
(0, 0),
|
surface.wl_surface(),
|
||||||
output_scale,
|
(0, 0),
|
||||||
1.,
|
output_scale,
|
||||||
Kind::Unspecified,
|
1.,
|
||||||
));
|
Kind::Unspecified,
|
||||||
|
);
|
||||||
|
let lock_elements = lock_elements
|
||||||
|
.into_iter()
|
||||||
|
.map(NearestIntegerScale::from)
|
||||||
|
.map(OutputRenderElements::from);
|
||||||
|
elements.extend(lock_elements);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw the solid color background.
|
// Draw the solid color background.
|
||||||
@@ -2688,7 +2707,7 @@ impl Niri {
|
|||||||
scale,
|
scale,
|
||||||
1.,
|
1.,
|
||||||
);
|
);
|
||||||
let elements = elements.iter().rev();
|
let elements = elements.iter().map(NearestIntegerScale::from).rev();
|
||||||
let pixels = render_to_vec(renderer, size, scale, Fourcc::Abgr8888, elements)?;
|
let pixels = render_to_vec(renderer, size, scale, Fourcc::Abgr8888, elements)?;
|
||||||
|
|
||||||
self.save_screenshot(size, pixels)
|
self.save_screenshot(size, pixels)
|
||||||
@@ -2945,7 +2964,7 @@ impl ClientData for ClientState {
|
|||||||
niri_render_elements! {
|
niri_render_elements! {
|
||||||
OutputRenderElements => {
|
OutputRenderElements => {
|
||||||
Monitor = MonitorRenderElement<R>,
|
Monitor = MonitorRenderElement<R>,
|
||||||
Wayland = WaylandSurfaceRenderElement<R>,
|
Wayland = NearestIntegerScale<WaylandSurfaceRenderElement<R>>,
|
||||||
NamedPointer = MemoryRenderBufferRenderElement<R>,
|
NamedPointer = MemoryRenderBufferRenderElement<R>,
|
||||||
SolidColor = SolidColorRenderElement,
|
SolidColor = SolidColorRenderElement,
|
||||||
ScreenshotUi = ScreenshotUiRenderElement,
|
ScreenshotUi = ScreenshotUiRenderElement,
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ use smithay::backend::renderer::sync::SyncPoint;
|
|||||||
use smithay::backend::renderer::{Bind, ExportMem, Frame, Offscreen, Renderer};
|
use smithay::backend::renderer::{Bind, ExportMem, Frame, Offscreen, Renderer};
|
||||||
use smithay::utils::{Physical, Rectangle, Scale, Size, Transform};
|
use smithay::utils::{Physical, Rectangle, Scale, Size, Transform};
|
||||||
|
|
||||||
|
pub mod nearest_integer_scale;
|
||||||
pub mod offscreen;
|
pub mod offscreen;
|
||||||
pub mod primary_gpu_texture;
|
pub mod primary_gpu_texture;
|
||||||
pub mod render_elements;
|
pub mod render_elements;
|
||||||
|
|||||||
@@ -0,0 +1,100 @@
|
|||||||
|
use smithay::backend::renderer::element::{Element, Id, Kind, RenderElement, UnderlyingStorage};
|
||||||
|
use smithay::backend::renderer::utils::CommitCounter;
|
||||||
|
use smithay::backend::renderer::{Frame, Renderer, TextureFilter};
|
||||||
|
use smithay::utils::{Buffer, Physical, Rectangle, Scale, Transform};
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct NearestIntegerScale<E: Element>(E);
|
||||||
|
|
||||||
|
impl<E: Element> From<E> for NearestIntegerScale<E> {
|
||||||
|
fn from(value: E) -> Self {
|
||||||
|
Self(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<E: Element> Element for NearestIntegerScale<E> {
|
||||||
|
fn id(&self) -> &Id {
|
||||||
|
self.0.id()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn current_commit(&self) -> CommitCounter {
|
||||||
|
self.0.current_commit()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn geometry(&self, scale: Scale<f64>) -> Rectangle<i32, Physical> {
|
||||||
|
self.0.geometry(scale)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn transform(&self) -> Transform {
|
||||||
|
self.0.transform()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn src(&self) -> Rectangle<f64, Buffer> {
|
||||||
|
self.0.src()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn damage_since(
|
||||||
|
&self,
|
||||||
|
scale: Scale<f64>,
|
||||||
|
commit: Option<CommitCounter>,
|
||||||
|
) -> Vec<Rectangle<i32, Physical>> {
|
||||||
|
self.0.damage_since(scale, commit)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn opaque_regions(&self, scale: Scale<f64>) -> Vec<Rectangle<i32, Physical>> {
|
||||||
|
self.0.opaque_regions(scale)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn alpha(&self) -> f32 {
|
||||||
|
self.0.alpha()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn kind(&self) -> Kind {
|
||||||
|
self.0.kind()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<R: Renderer, E: RenderElement<R>> RenderElement<R> for NearestIntegerScale<E> {
|
||||||
|
fn draw(
|
||||||
|
&self,
|
||||||
|
frame: &mut <R as Renderer>::Frame<'_>,
|
||||||
|
src: Rectangle<f64, Buffer>,
|
||||||
|
dst: Rectangle<i32, Physical>,
|
||||||
|
damage: &[Rectangle<i32, Physical>],
|
||||||
|
) -> Result<(), R::Error> {
|
||||||
|
let mut use_nearest = false;
|
||||||
|
|
||||||
|
// Check that we don't need to interpolate between src pixels.
|
||||||
|
let src_i32 = src.to_i32_down::<i32>();
|
||||||
|
if src_i32.to_f64() == src {
|
||||||
|
// Check that the src is not zero.
|
||||||
|
if !src_i32.size.is_empty() {
|
||||||
|
// Check that the scale factor is an integer.
|
||||||
|
let scale_x = dst.size.w / src_i32.size.w;
|
||||||
|
let scale_y = dst.size.h / src_i32.size.h;
|
||||||
|
if scale_x * src_i32.size.w == dst.size.w && scale_y * src_i32.size.h == dst.size.h
|
||||||
|
{
|
||||||
|
use_nearest = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut prev_filter = TextureFilter::Linear;
|
||||||
|
if use_nearest {
|
||||||
|
prev_filter = frame.upscale_filter();
|
||||||
|
frame.set_upscale_filter(TextureFilter::Nearest);
|
||||||
|
}
|
||||||
|
|
||||||
|
let rv = self.0.draw(frame, src, dst, damage);
|
||||||
|
|
||||||
|
if use_nearest {
|
||||||
|
frame.set_upscale_filter(prev_filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
rv
|
||||||
|
}
|
||||||
|
|
||||||
|
fn underlying_storage(&self, renderer: &mut R) -> Option<UnderlyingStorage> {
|
||||||
|
self.0.underlying_storage(renderer)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user