From d52192a2ba920994e2068da3fb38f1cabaf62e93 Mon Sep 17 00:00:00 2001 From: Ottatop Date: Fri, 29 Mar 2024 11:57:35 -0500 Subject: [PATCH] Default back to linear scaling and add config options to set --- api/lua/examples/default/default_config.lua | 12 +++- api/lua/pinnacle-api-dev-1.rockspec | 1 + api/lua/pinnacle.lua | 6 +- api/lua/pinnacle/grpc/protobuf.lua | 1 + api/lua/pinnacle/render.lua | 69 +++++++++++++++++++ .../pinnacle/render/v0alpha1/render.proto | 35 ++++++++++ api/rust/src/lib.rs | 7 ++ api/rust/src/render.rs | 52 ++++++++++++++ pinnacle-api-defs/build.rs | 1 + pinnacle-api-defs/src/lib.rs | 6 ++ src/api.rs | 68 ++++++++++++++++++ src/backend.rs | 59 +++++++++++++++- src/backend/udev.rs | 60 +++++++--------- src/backend/winit.rs | 39 ++++++----- src/config.rs | 7 +- 15 files changed, 360 insertions(+), 63 deletions(-) create mode 100644 api/lua/pinnacle/render.lua create mode 100644 api/protocol/pinnacle/render/v0alpha1/render.proto create mode 100644 api/rust/src/render.rs diff --git a/api/lua/examples/default/default_config.lua b/api/lua/examples/default/default_config.lua index a29c6a0..8f48216 100644 --- a/api/lua/examples/default/default_config.lua +++ b/api/lua/examples/default/default_config.lua @@ -92,16 +92,24 @@ require("pinnacle").setup(function(Pinnacle) end end - Input.keybind({ mod_key }, "=", function() + Input.keybind({ mod_key, "shift" }, "=", function() Output.get_focused():increase_scale(0.25) layout_outputs_in_line() end) - Input.keybind({ mod_key }, "-", function() + Input.keybind({ mod_key, "shift" }, "-", function() Output.get_focused():decrease_scale(0.25) layout_outputs_in_line() end) + Input.keybind({ mod_key }, "u", function() + Pinnacle.render.set_upscale_filter("nearest_neighbor") + end) + + Input.keybind({ mod_key }, "d", function() + Pinnacle.render.set_upscale_filter("bilinear") + end) + -------------------- -- Tags -- -------------------- diff --git a/api/lua/pinnacle-api-dev-1.rockspec b/api/lua/pinnacle-api-dev-1.rockspec index ddc22c6..62698c0 100644 --- a/api/lua/pinnacle-api-dev-1.rockspec +++ b/api/lua/pinnacle-api-dev-1.rockspec @@ -28,5 +28,6 @@ build = { ["pinnacle.util"] = "pinnacle/util.lua", ["pinnacle.signal"] = "pinnacle/signal.lua", ["pinnacle.layout"] = "pinnacle/layout.lua", + ["pinnacle.render"] = "pinnacle/render.lua", }, } diff --git a/api/lua/pinnacle.lua b/api/lua/pinnacle.lua index 115c08b..907aeda 100644 --- a/api/lua/pinnacle.lua +++ b/api/lua/pinnacle.lua @@ -6,7 +6,7 @@ local client = require("pinnacle.grpc.client") ---The entry point to configuration. --- ----This module contains one function: `setup`, which is how you'll access all the ways to configure Pinnacle. +---This module contains the `setup` function, which is how you'll access all the ways to configure Pinnacle. ---@class Pinnacle local pinnacle = { ---@type Input @@ -23,6 +23,8 @@ local pinnacle = { util = require("pinnacle.util"), ---@type Layout layout = require("pinnacle.layout"), + ---@type Render + render = require("pinnacle.render"), } ---Quit Pinnacle. @@ -50,6 +52,8 @@ end function pinnacle.setup(config_fn) require("pinnacle.grpc.protobuf").build_protos() + -- This function ensures a config won't run forever if Pinnacle is killed + -- and doesn't kill configs on drop. client.loop:wrap(function() while true do require("cqueues").sleep(60) diff --git a/api/lua/pinnacle/grpc/protobuf.lua b/api/lua/pinnacle/grpc/protobuf.lua index a6b6bef..f7a5939 100644 --- a/api/lua/pinnacle/grpc/protobuf.lua +++ b/api/lua/pinnacle/grpc/protobuf.lua @@ -19,6 +19,7 @@ function protobuf.build_protos() PINNACLE_PROTO_DIR .. "/pinnacle/window/" .. version .. "/window.proto", PINNACLE_PROTO_DIR .. "/pinnacle/signal/" .. version .. "/signal.proto", PINNACLE_PROTO_DIR .. "/pinnacle/layout/" .. version .. "/layout.proto", + PINNACLE_PROTO_DIR .. "/pinnacle/render/" .. version .. "/render.proto", PINNACLE_PROTO_DIR .. "/google/protobuf/empty.proto", } diff --git a/api/lua/pinnacle/render.lua b/api/lua/pinnacle/render.lua new file mode 100644 index 0000000..d1bb445 --- /dev/null +++ b/api/lua/pinnacle/render.lua @@ -0,0 +1,69 @@ +-- This Source Code Form is subject to the terms of the Mozilla Public +-- License, v. 2.0. If a copy of the MPL was not distributed with this +-- file, You can obtain one at https://mozilla.org/MPL/2.0/. + +local client = require("pinnacle.grpc.client") + +---The protobuf absolute path prefix +local prefix = "pinnacle.render." .. client.version .. "." +local service = prefix .. "RenderService" + +---@type table +---@enum (key) RenderServiceMethod +local rpc_types = { + SetUpscaleFilter = {}, + SetDownscaleFilter = {}, +} + +---Build GrpcRequestParams +---@param method RenderServiceMethod +---@param data table +---@return GrpcRequestParams +local function build_grpc_request_params(method, data) + local req_type = rpc_types[method].request_type + local resp_type = rpc_types[method].response_type + + ---@type GrpcRequestParams + return { + service = service, + method = method, + request_type = req_type and prefix .. req_type or prefix .. method .. "Request", + response_type = resp_type and prefix .. resp_type, + data = data, + } +end + +---Rendering management. +--- +---@class Render +local render = {} + +---@alias ScalingFilter +---| "bilinear" +---| "nearest_neighbor" + +---@type table +local filter_name_to_filter_value = { + bilinear = 1, + nearest_neighbor = 2, +} + +---Set the upscale filter the renderer will use to upscale buffers. +--- +---@param filter ScalingFilter +function render.set_upscale_filter(filter) + client.unary_request( + build_grpc_request_params("SetUpscaleFilter", { filter = filter_name_to_filter_value[filter] }) + ) +end + +---Set the downscale filter the renderer will use to downscale buffers. +--- +---@param filter ScalingFilter +function render.set_downscale_filter(filter) + client.unary_request( + build_grpc_request_params("SetDownscaleFilter", { filter = filter_name_to_filter_value[filter] }) + ) +end + +return render diff --git a/api/protocol/pinnacle/render/v0alpha1/render.proto b/api/protocol/pinnacle/render/v0alpha1/render.proto new file mode 100644 index 0000000..a5df5f0 --- /dev/null +++ b/api/protocol/pinnacle/render/v0alpha1/render.proto @@ -0,0 +1,35 @@ +syntax = "proto2"; + +package pinnacle.render.v0alpha1; + +import "google/protobuf/empty.proto"; + +// The filtering method. +enum Filter { + FILTER_UNSPECIFIED = 0; + // Bilinear filtering. + // + // This will cause up- and downscaling to be blurry. + FILTER_BILINEAR = 1; + // Nearest neighbor filtering. + // + // This will cause edges to become pixelated when scaling. + FILTER_NEAREST_NEIGHBOR = 2; +} + +message SetUpscaleFilterRequest { + // The filter that will be used. + optional Filter filter = 1; +} + +message SetDownscaleFilterRequest { + // The filter that will be used. + optional Filter filter = 1; +} + +service RenderService { + // Set the upscaling filter the renderer will use when upscaling buffers. + rpc SetUpscaleFilter(SetUpscaleFilterRequest) returns (google.protobuf.Empty); + // Set the downscaling filter the renderer will use when downscaling buffers. + rpc SetDownscaleFilter(SetDownscaleFilterRequest) returns (google.protobuf.Empty); +} diff --git a/api/rust/src/lib.rs b/api/rust/src/lib.rs index 350b167..7fe6175 100644 --- a/api/rust/src/lib.rs +++ b/api/rust/src/lib.rs @@ -88,6 +88,7 @@ use layout::Layout; use output::Output; use pinnacle::Pinnacle; use process::Process; +use render::Render; use signal::SignalState; use tag::Tag; use tokio::sync::{ @@ -104,6 +105,7 @@ pub mod layout; pub mod output; pub mod pinnacle; pub mod process; +pub mod render; pub mod signal; pub mod tag; pub mod util; @@ -121,6 +123,7 @@ static OUTPUT: OnceLock = OnceLock::new(); static TAG: OnceLock = OnceLock::new(); static SIGNAL: OnceLock> = OnceLock::new(); static LAYOUT: OnceLock = OnceLock::new(); +static RENDER: OnceLock = OnceLock::new(); /// A struct containing static references to all of the configuration structs. #[derive(Debug, Clone, Copy)] @@ -139,6 +142,8 @@ pub struct ApiModules { pub tag: &'static Tag, /// The [`Layout`] struct pub layout: &'static Layout, + /// The [`Render`] struct + pub render: &'static Render, } /// Connects to Pinnacle and builds the configuration structs. @@ -166,6 +171,7 @@ pub async fn connect( let tag = TAG.get_or_init(|| Tag::new(channel.clone())); let output = OUTPUT.get_or_init(|| Output::new(channel.clone())); let layout = LAYOUT.get_or_init(|| Layout::new(channel.clone())); + let render = RENDER.get_or_init(|| Render::new(channel.clone())); SIGNAL .set(RwLock::new(SignalState::new( @@ -182,6 +188,7 @@ pub async fn connect( output, tag, layout, + render, }; Ok((modules, fut_recv)) diff --git a/api/rust/src/render.rs b/api/rust/src/render.rs new file mode 100644 index 0000000..e288108 --- /dev/null +++ b/api/rust/src/render.rs @@ -0,0 +1,52 @@ +//! Rendering management. + +use pinnacle_api_defs::pinnacle::render::v0alpha1::{ + render_service_client::RenderServiceClient, SetDownscaleFilterRequest, SetUpscaleFilterRequest, +}; +use tonic::transport::Channel; + +use crate::block_on_tokio; + +/// A struct that allows you to manage rendering. +#[derive(Debug, Clone)] +pub struct Render { + client: RenderServiceClient, +} + +/// What filter to use when scaling. +pub enum ScalingFilter { + /// Use a bilinear filter. + /// + /// This will make up- and downscaling blurry. + Bilinear, + /// Use a nearest neighbor filter. + /// + /// This will cause scaling to look pixelated. + NearestNeighbor, +} + +impl Render { + pub(crate) fn new(channel: Channel) -> Self { + Self { + client: RenderServiceClient::new(channel), + } + } + + /// Set the upscaling filter that will be used for rendering. + pub fn set_upscale_filter(&self, filter: ScalingFilter) { + let mut client = self.client.clone(); + block_on_tokio(client.set_upscale_filter(SetUpscaleFilterRequest { + filter: Some(filter as i32), + })) + .unwrap(); + } + + /// Set the downscaling filter that will be used for rendering. + pub fn set_downscale_filter(&self, filter: ScalingFilter) { + let mut client = self.client.clone(); + block_on_tokio(client.set_downscale_filter(SetDownscaleFilterRequest { + filter: Some(filter as i32), + })) + .unwrap(); + } +} diff --git a/pinnacle-api-defs/build.rs b/pinnacle-api-defs/build.rs index adae15b..a7122ff 100644 --- a/pinnacle-api-defs/build.rs +++ b/pinnacle-api-defs/build.rs @@ -15,6 +15,7 @@ fn main() { formatcp!("../api/protocol/pinnacle/window/{VERSION}/window.proto"), formatcp!("../api/protocol/pinnacle/signal/{VERSION}/signal.proto"), formatcp!("../api/protocol/pinnacle/layout/{VERSION}/layout.proto"), + formatcp!("../api/protocol/pinnacle/render/{VERSION}/render.proto"), ]; let descriptor_path = PathBuf::from(std::env::var("OUT_DIR").unwrap()).join("pinnacle.bin"); diff --git a/pinnacle-api-defs/src/lib.rs b/pinnacle-api-defs/src/lib.rs index 30ef083..7d0a999 100644 --- a/pinnacle-api-defs/src/lib.rs +++ b/pinnacle-api-defs/src/lib.rs @@ -74,6 +74,12 @@ pub mod pinnacle { tonic::include_proto!("pinnacle.layout.v0alpha1"); } } + + pub mod render { + pub mod v0alpha1 { + tonic::include_proto!("pinnacle.render.v0alpha1"); + } + } } pub const FILE_DESCRIPTOR_SET: &[u8] = tonic::include_file_descriptor_set!("pinnacle"); diff --git a/src/api.rs b/src/api.rs index aa12f3d..9035769 100644 --- a/src/api.rs +++ b/src/api.rs @@ -20,6 +20,9 @@ use pinnacle_api_defs::pinnacle::{ }, }, process::v0alpha1::{process_service_server, SetEnvRequest, SpawnRequest, SpawnResponse}, + render::v0alpha1::{ + render_service_server, Filter, SetDownscaleFilterRequest, SetUpscaleFilterRequest, + }, tag::{ self, v0alpha1::{ @@ -30,6 +33,7 @@ use pinnacle_api_defs::pinnacle::{ v0alpha1::{pinnacle_service_server, PingRequest, PingResponse, QuitRequest, SetOrToggle}, }; use smithay::{ + backend::renderer::TextureFilter, desktop::layer_map_for_output, input::keyboard::XkbConfig, output::Scale, @@ -46,6 +50,7 @@ use tonic::{Request, Response, Status, Streaming}; use tracing::{debug, error, warn}; use crate::{ + backend::BackendData, config::ConnectorSavedState, input::ModifierMask, output::OutputName, @@ -1135,3 +1140,66 @@ impl output_service_server::OutputService for OutputService { .await } } + +pub struct RenderService { + sender: StateFnSender, +} + +impl RenderService { + pub fn new(sender: StateFnSender) -> Self { + Self { sender } + } +} + +#[tonic::async_trait] +impl render_service_server::RenderService for RenderService { + async fn set_upscale_filter( + &self, + request: Request, + ) -> Result, Status> { + let request = request.into_inner(); + if let Filter::Unspecified = request.filter() { + return Err(Status::invalid_argument("unspecified filter")); + } + + let filter = match request.filter() { + Filter::Bilinear => TextureFilter::Linear, + Filter::NearestNeighbor => TextureFilter::Nearest, + _ => unreachable!(), + }; + + run_unary_no_response(&self.sender, move |state| { + state.backend.set_upscale_filter(filter); + for output in state.space.outputs().cloned().collect::>() { + state.backend.reset_buffers(&output); + state.schedule_render(&output); + } + }) + .await + } + + async fn set_downscale_filter( + &self, + request: Request, + ) -> Result, Status> { + let request = request.into_inner(); + if let Filter::Unspecified = request.filter() { + return Err(Status::invalid_argument("unspecified filter")); + } + + let filter = match request.filter() { + Filter::Bilinear => TextureFilter::Linear, + Filter::NearestNeighbor => TextureFilter::Nearest, + _ => unreachable!(), + }; + + run_unary_no_response(&self.sender, move |state| { + state.backend.set_downscale_filter(filter); + for output in state.space.outputs().cloned().collect::>() { + state.backend.reset_buffers(&output); + state.schedule_render(&output); + } + }) + .await + } +} diff --git a/src/backend.rs b/src/backend.rs index cbecc7d..591f943 100644 --- a/src/backend.rs +++ b/src/backend.rs @@ -10,7 +10,7 @@ use smithay::{ default_primary_scanout_output_compare, utils::select_dmabuf_feedback, RenderElementStates, }, - ImportDma, + ImportDma, Renderer, TextureFilter, }, }, delegate_dmabuf, @@ -26,6 +26,7 @@ use smithay::{ fractional_scale::with_fractional_scale, }, }; +use tracing::error; use crate::{ state::{State, SurfaceDmabufFeedback}, @@ -51,6 +52,32 @@ pub enum Backend { } impl Backend { + pub fn set_upscale_filter(&mut self, filter: TextureFilter) { + match self { + Backend::Winit(winit) => { + if let Err(err) = winit.backend.renderer().upscale_filter(filter) { + error!("Failed to set winit upscale filter: {err}"); + } + } + Backend::Udev(udev) => udev.upscale_filter = filter, + #[cfg(feature = "testing")] + Backend::Dummy(_) => (), + } + } + + pub fn set_downscale_filter(&mut self, filter: TextureFilter) { + match self { + Backend::Winit(winit) => { + if let Err(err) = winit.backend.renderer().downscale_filter(filter) { + error!("Failed to set winit upscale filter: {err}"); + } + } + Backend::Udev(udev) => udev.downscale_filter = filter, + #[cfg(feature = "testing")] + Backend::Dummy(_) => (), + } + } + pub fn seat_name(&self) -> String { match self { Backend::Winit(winit) => winit.seat_name(), @@ -86,7 +113,6 @@ impl Backend { } } -/// A trait defining common methods for each available backend: winit and tty-udev pub trait BackendData: 'static { fn seat_name(&self) -> String; fn reset_buffers(&mut self, output: &Output); @@ -95,6 +121,35 @@ pub trait BackendData: 'static { fn early_import(&mut self, surface: &WlSurface); } +impl BackendData for Backend { + fn seat_name(&self) -> String { + match self { + Backend::Winit(winit) => winit.seat_name(), + Backend::Udev(udev) => udev.seat_name(), + #[cfg(feature = "testing")] + Backend::Dummy(dummy) => dummy.seat_name(), + } + } + + fn reset_buffers(&mut self, output: &Output) { + match self { + Backend::Winit(winit) => winit.reset_buffers(output), + Backend::Udev(udev) => udev.reset_buffers(output), + #[cfg(feature = "testing")] + Backend::Dummy(dummy) => dummy.reset_buffers(output), + } + } + + fn early_import(&mut self, surface: &WlSurface) { + match self { + Backend::Winit(winit) => winit.early_import(surface), + Backend::Udev(udev) => udev.early_import(surface), + #[cfg(feature = "testing")] + Backend::Dummy(dummy) => dummy.early_import(surface), + } + } +} + /// Update surface primary scanout outputs and send frames and dmabuf feedback to visible windows /// and layers. pub fn post_repaint( diff --git a/src/backend/udev.rs b/src/backend/udev.rs index fc81514..2ff0e2c 100644 --- a/src/backend/udev.rs +++ b/src/backend/udev.rs @@ -29,9 +29,9 @@ use smithay::{ renderer::{ damage, element::{texture::TextureBuffer, RenderElement, RenderElementStates}, - gles::{GlesRenderer, GlesTexture}, + gles::GlesRenderer, multigpu::{gbm::GbmGlesBackend, GpuManager, MultiRenderer, MultiTexture}, - Bind, ExportMem, ImportDma, ImportEgl, ImportMemWl, Offscreen, Renderer, TextureFilter, + Bind, ImportDma, ImportEgl, ImportMemWl, Renderer, TextureFilter, }, session::{ self, @@ -52,10 +52,7 @@ use smithay::{ reexports::{ ash::vk::ExtPhysicalDeviceDrmFn, calloop::{EventLoop, Idle, LoopHandle, RegistrationToken}, - drm::{ - control::{connector, crtc, ModeTypeFlags}, - Device, - }, + drm::control::{connector, crtc, ModeTypeFlags}, input::Libinput, rustix::fs::OFlags, wayland_protocols::wp::{ @@ -122,6 +119,9 @@ pub struct Udev { pointer_images: Vec<(xcursor::parser::Image, TextureBuffer)>, pointer_element: PointerElement, pointer_image: crate::cursor::Cursor, + + pub(super) upscale_filter: TextureFilter, + pub(super) downscale_filter: TextureFilter, } impl Backend { @@ -320,6 +320,9 @@ pub fn setup_udev( pointer_image: crate::cursor::Cursor::load(), pointer_images: Vec::new(), pointer_element: PointerElement::default(), + + upscale_filter: TextureFilter::Linear, + downscale_filter: TextureFilter::Linear, }; let display_handle = display.handle(); @@ -721,14 +724,14 @@ struct SurfaceCompositorRenderResult { /// Render a frame with the given elements. /// /// This frame needs to be queued for scanout afterwards. -fn render_frame( +fn render_frame( compositor: &mut GbmDrmCompositor, renderer: &mut R, elements: &[E], clear_color: [f32; 4], ) -> Result where - R: Renderer + Bind + Bind + Offscreen + ExportMem, + R: Renderer + Bind, ::TextureId: 'static, ::Error: Into, E: RenderElement, @@ -942,30 +945,12 @@ impl State { }; let compositor = { - let driver = match device.drm.get_driver() { - Ok(driver) => driver, - Err(err) => { - warn!("Failed to query drm driver: {}", err); - return; - } - }; - let mut planes = surface.planes().clone(); - // Using an overlay plane on a nvidia card breaks - if driver - .name() - .to_string_lossy() - .to_lowercase() - .contains("nvidia") - || driver - .description() - .to_string_lossy() - .to_lowercase() - .contains("nvidia") - { - planes.overlay = vec![]; - } + // INFO: We are disabling overlay planes because it seems that any elements on + // | overlay planes don't get up/downscaled according to the set filter; + // | it always defaults to linear. + planes.overlay.clear(); match DrmCompositor::new( &output, @@ -1238,9 +1223,11 @@ impl State { assert!(matches!(surface.render_state, RenderState::Scheduled(_))); // TODO get scale from the rendersurface when supporting HiDPI - let frame = udev - .pointer_image - .get_image(1 /*scale*/, self.clock.now().into()); + let frame = udev.pointer_image.get_image( + 1, + // output.current_scale().integer_scale() as u32, + self.clock.now().into(), + ); let render_node = surface.render_node; let primary_gpu = udev.primary_gpu; @@ -1253,9 +1240,8 @@ impl State { } .expect("failed to create MultiRenderer"); - // TODO: set from config - let _ = renderer.upscale_filter(TextureFilter::Nearest); - let _ = renderer.downscale_filter(TextureFilter::Nearest); + let _ = renderer.upscale_filter(udev.upscale_filter); + let _ = renderer.downscale_filter(udev.downscale_filter); let pointer_images = &mut udev.pointer_images; let pointer_image = pointer_images @@ -1360,7 +1346,7 @@ fn render_surface( Some(pointer_image), ); - let res = render_frame::<_, _, GlesTexture>( + let res = render_frame( &mut surface.compositor, renderer, &output_render_elements, diff --git a/src/backend/winit.rs b/src/backend/winit.rs index 5d9ace9..d033e9c 100644 --- a/src/backend/winit.rs +++ b/src/backend/winit.rs @@ -8,13 +8,13 @@ use smithay::{ renderer::{ damage::{self, OutputDamageTracker}, gles::{GlesRenderer, GlesTexture}, - ImportDma, ImportEgl, ImportMemWl, Renderer, TextureFilter, + ImportDma, ImportEgl, ImportMemWl, }, winit::{self, WinitEvent, WinitGraphicsBackend}, }, - desktop::utils::send_frames_surface_tree, + desktop::{layer_map_for_output, utils::send_frames_surface_tree}, input::pointer::CursorImageStatus, - output::{Output, Subpixel}, + output::{Output, Scale, Subpixel}, reexports::{ calloop::{ timer::{TimeoutAction, Timer}, @@ -30,6 +30,7 @@ use smithay::{ utils::{IsAlive, Transform}, wayland::dmabuf::{DmabufFeedback, DmabufFeedbackBuilder, DmabufGlobal, DmabufState}, }; +use tracing::error; use crate::{ render::{pointer::PointerElement, take_presentation_feedback}, @@ -88,14 +89,6 @@ pub fn setup_winit( Err(err) => anyhow::bail!("Failed to init winit backend: {err}"), }; - // TODO: set from config - winit_backend - .renderer() - .upscale_filter(TextureFilter::Nearest)?; - winit_backend - .renderer() - .downscale_filter(TextureFilter::Nearest)?; - let mode = smithay::output::Mode { size: winit_backend.window_size(), refresh: 144_000, @@ -206,7 +199,7 @@ pub fn setup_winit( true, |_| {}, ) { - tracing::error!("Failed to start XWayland: {err}"); + error!("Failed to start XWayland: {err}"); } let insert_ret = @@ -214,17 +207,25 @@ pub fn setup_winit( .loop_handle .insert_source(Timer::immediate(), move |_instant, _metadata, state| { let status = winit_evt_loop.dispatch_new_events(|event| match event { - WinitEvent::Resized { - size, - scale_factor: _, - } => { + WinitEvent::Resized { size, scale_factor } => { let mode = smithay::output::Mode { size, refresh: 144_000, }; - state.resize_output(&output, mode); + output.change_current_state( + Some(mode), + None, + Some(Scale::Fractional(scale_factor)), + None, + ); + layer_map_for_output(&output).arrange(); + state.request_layout(&output); + } + WinitEvent::Focus(focused) => { + if focused { + state.backend.winit_mut().reset_buffers(&output); + } } - WinitEvent::Focus(_) => {} WinitEvent::Input(input_evt) => { state.process_input_event(input_evt); } @@ -315,7 +316,7 @@ impl State { let has_rendered = render_output_result.damage.is_some(); if let Some(damage) = render_output_result.damage { if let Err(err) = winit.backend.submit(Some(&damage)) { - tracing::warn!("{}", err); + error!("{}", err); } } diff --git a/src/config.rs b/src/config.rs index fd4e632..890ddff 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,7 +1,7 @@ use crate::{ api::{ layout::LayoutService, signal::SignalService, window::WindowService, InputService, - OutputService, PinnacleService, ProcessService, TagService, + OutputService, PinnacleService, ProcessService, RenderService, TagService, }, input::ModifierMask, output::OutputName, @@ -20,6 +20,7 @@ use pinnacle_api_defs::pinnacle::{ layout::v0alpha1::layout_service_server::LayoutServiceServer, output::v0alpha1::output_service_server::OutputServiceServer, process::v0alpha1::process_service_server::ProcessServiceServer, + render::v0alpha1::render_service_server::RenderServiceServer, signal::v0alpha1::signal_service_server::SignalServiceServer, tag::v0alpha1::tag_service_server::TagServiceServer, v0alpha1::pinnacle_service_server::PinnacleServiceServer, @@ -479,6 +480,7 @@ impl State { let window_service = WindowService::new(grpc_sender.clone()); let signal_service = SignalService::new(grpc_sender.clone()); let layout_service = LayoutService::new(grpc_sender.clone()); + let render_service = RenderService::new(grpc_sender.clone()); let refl_service = tonic_reflection::server::Builder::configure() .register_encoded_file_descriptor_set(pinnacle_api_defs::FILE_DESCRIPTOR_SET) @@ -498,7 +500,8 @@ impl State { .add_service(OutputServiceServer::new(output_service)) .add_service(WindowServiceServer::new(window_service)) .add_service(SignalServiceServer::new(signal_service)) - .add_service(LayoutServiceServer::new(layout_service)); + .add_service(LayoutServiceServer::new(layout_service)) + .add_service(RenderServiceServer::new(render_service)); match self.xdisplay.as_ref() { Some(_) => {