mirror of
https://github.com/niri-wm/niri.git
synced 2026-06-21 02:01:55 +07:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 88b74f4a3a | |||
| b94b0c7fa4 |
Generated
+2
-2
@@ -3005,7 +3005,7 @@ checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7"
|
||||
[[package]]
|
||||
name = "smithay"
|
||||
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 = [
|
||||
"appendlist",
|
||||
"bitflags 2.4.2",
|
||||
@@ -3077,7 +3077,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "smithay-drm-extras"
|
||||
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 = [
|
||||
"drm",
|
||||
"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 }
|
||||
|
||||
[workspace.dependencies.smithay]
|
||||
git = "https://github.com/Smithay/smithay.git"
|
||||
git = "https://github.com/YaLTeR/smithay.git"
|
||||
rev = "0c06b7889b72e4392d89fab91f2d2cf4f272db83"
|
||||
# path = "../smithay"
|
||||
default-features = false
|
||||
|
||||
[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"
|
||||
|
||||
[package]
|
||||
|
||||
+9
-3
@@ -55,6 +55,7 @@ use self::workspace::{compute_working_area, Column, ColumnWidth, OutputId, Works
|
||||
use crate::animation::Animation;
|
||||
use crate::niri::WindowOffscreenId;
|
||||
use crate::niri_render_elements;
|
||||
use crate::render_helpers::nearest_integer_scale::NearestIntegerScale;
|
||||
use crate::render_helpers::renderer::NiriRenderer;
|
||||
use crate::utils::output_size;
|
||||
|
||||
@@ -65,7 +66,7 @@ pub mod workspace;
|
||||
|
||||
niri_render_elements! {
|
||||
LayoutElementRenderElement => {
|
||||
Wayland = WaylandSurfaceRenderElement<R>,
|
||||
Wayland = NearestIntegerScale<WaylandSurfaceRenderElement<R>>,
|
||||
SolidColor = SolidColorRenderElement,
|
||||
}
|
||||
}
|
||||
@@ -238,12 +239,17 @@ impl LayoutElement for Window {
|
||||
scale: Scale<f64>,
|
||||
) -> Vec<LayoutElementRenderElement<R>> {
|
||||
let buf_pos = location - self.geometry().loc;
|
||||
self.render_elements(
|
||||
let elements: Vec<WaylandSurfaceRenderElement<R>> = self.render_elements(
|
||||
renderer,
|
||||
buf_pos.to_physical_precise_round(scale),
|
||||
scale,
|
||||
1.,
|
||||
)
|
||||
);
|
||||
elements
|
||||
.into_iter()
|
||||
.map(NearestIntegerScale::from)
|
||||
.map(LayoutElementRenderElement::from)
|
||||
.collect()
|
||||
}
|
||||
|
||||
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 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| {
|
||||
Some(RelocateRenderElement::from_element(
|
||||
CropRenderElement::from_element(
|
||||
elem,
|
||||
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),
|
||||
Relocate::Relative,
|
||||
@@ -645,7 +651,10 @@ impl<W: LayoutElement> Monitor<W> {
|
||||
CropRenderElement::from_element(
|
||||
elem,
|
||||
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),
|
||||
Relocate::Relative,
|
||||
|
||||
+45
-26
@@ -101,6 +101,7 @@ use crate::ipc::server::IpcServer;
|
||||
use crate::layout::{Layout, MonitorRenderElement};
|
||||
use crate::protocols::foreign_toplevel::{self, ForeignToplevelManagerState};
|
||||
use crate::pw_utils::{Cast, PipeWire};
|
||||
use crate::render_helpers::nearest_integer_scale::NearestIntegerScale;
|
||||
use crate::render_helpers::renderer::NiriRenderer;
|
||||
use crate::render_helpers::{render_to_texture, render_to_vec};
|
||||
use crate::screenshot_ui::{ScreenshotUi, ScreenshotUiRenderElement};
|
||||
@@ -1693,14 +1694,20 @@ impl Niri {
|
||||
let pointer_pos =
|
||||
(pointer_pos - hotspot.to_f64()).to_physical_precise_round(output_scale);
|
||||
|
||||
let pointer_elements = render_elements_from_surface_tree(
|
||||
renderer,
|
||||
&surface,
|
||||
pointer_pos,
|
||||
output_scale,
|
||||
1.,
|
||||
Kind::Cursor,
|
||||
);
|
||||
let pointer_elements: Vec<WaylandSurfaceRenderElement<_>> =
|
||||
render_elements_from_surface_tree(
|
||||
renderer,
|
||||
&surface,
|
||||
pointer_pos,
|
||||
output_scale,
|
||||
1.,
|
||||
Kind::Cursor,
|
||||
);
|
||||
let pointer_elements = pointer_elements
|
||||
.into_iter()
|
||||
.map(NearestIntegerScale::from)
|
||||
.map(OutputRenderElements::from)
|
||||
.collect();
|
||||
|
||||
(pointer_elements, pointer_pos)
|
||||
}
|
||||
@@ -1740,14 +1747,20 @@ impl Niri {
|
||||
};
|
||||
|
||||
if let Some(dnd_icon) = &self.dnd_icon {
|
||||
pointer_elements.extend(render_elements_from_surface_tree(
|
||||
renderer,
|
||||
dnd_icon,
|
||||
pointer_pos,
|
||||
output_scale,
|
||||
1.,
|
||||
Kind::Unspecified,
|
||||
));
|
||||
let dnd_elements: Vec<WaylandSurfaceRenderElement<_>> =
|
||||
render_elements_from_surface_tree(
|
||||
renderer,
|
||||
dnd_icon,
|
||||
pointer_pos,
|
||||
output_scale,
|
||||
1.,
|
||||
Kind::Unspecified,
|
||||
);
|
||||
let dnd_elements = dnd_elements
|
||||
.into_iter()
|
||||
.map(NearestIntegerScale::from)
|
||||
.map(OutputRenderElements::from);
|
||||
pointer_elements.extend(dnd_elements);
|
||||
}
|
||||
|
||||
pointer_elements
|
||||
@@ -1923,14 +1936,20 @@ impl Niri {
|
||||
if self.is_locked() {
|
||||
let state = self.output_state.get(output).unwrap();
|
||||
if let Some(surface) = state.lock_surface.as_ref() {
|
||||
elements.extend(render_elements_from_surface_tree(
|
||||
renderer,
|
||||
surface.wl_surface(),
|
||||
(0, 0),
|
||||
output_scale,
|
||||
1.,
|
||||
Kind::Unspecified,
|
||||
));
|
||||
let lock_elements: Vec<WaylandSurfaceRenderElement<_>> =
|
||||
render_elements_from_surface_tree(
|
||||
renderer,
|
||||
surface.wl_surface(),
|
||||
(0, 0),
|
||||
output_scale,
|
||||
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.
|
||||
@@ -2688,7 +2707,7 @@ impl Niri {
|
||||
scale,
|
||||
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)?;
|
||||
|
||||
self.save_screenshot(size, pixels)
|
||||
@@ -2945,7 +2964,7 @@ impl ClientData for ClientState {
|
||||
niri_render_elements! {
|
||||
OutputRenderElements => {
|
||||
Monitor = MonitorRenderElement<R>,
|
||||
Wayland = WaylandSurfaceRenderElement<R>,
|
||||
Wayland = NearestIntegerScale<WaylandSurfaceRenderElement<R>>,
|
||||
NamedPointer = MemoryRenderBufferRenderElement<R>,
|
||||
SolidColor = SolidColorRenderElement,
|
||||
ScreenshotUi = ScreenshotUiRenderElement,
|
||||
|
||||
@@ -6,6 +6,7 @@ use smithay::backend::renderer::sync::SyncPoint;
|
||||
use smithay::backend::renderer::{Bind, ExportMem, Frame, Offscreen, Renderer};
|
||||
use smithay::utils::{Physical, Rectangle, Scale, Size, Transform};
|
||||
|
||||
pub mod nearest_integer_scale;
|
||||
pub mod offscreen;
|
||||
pub mod primary_gpu_texture;
|
||||
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