From db6f4cdb7f379713979b930e8e1fa1a813ebecc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Tue, 25 Feb 2025 18:56:13 +0400 Subject: [PATCH] refactor(server)!: drop support for pixelOrder MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Dealing with multiple formats is sufficiently annoying, there isn't much need for awkward image layout. This was done for efficiency reason for bitmap encoding, but bitmap is really inefficient anyway and very few servers will actually provide bottom to top images (except with GL/GPU textures, but this is not in scope yet). Signed-off-by: Marc-André Lureau --- crates/ironrdp-bench/benches/bench.rs | 2 -- crates/ironrdp-server/src/display.rs | 8 ------ crates/ironrdp-server/src/encoder/bitmap.rs | 31 ++++++--------------- crates/ironrdp-server/src/encoder/mod.rs | 30 +++++--------------- crates/ironrdp/examples/server.rs | 5 ++-- 5 files changed, 17 insertions(+), 59 deletions(-) diff --git a/crates/ironrdp-bench/benches/bench.rs b/crates/ironrdp-bench/benches/bench.rs index 428493c5..5781a6e4 100644 --- a/crates/ironrdp-bench/benches/bench.rs +++ b/crates/ironrdp-bench/benches/bench.rs @@ -16,7 +16,6 @@ pub fn rfx_enc_tile_bench(c: &mut Criterion) { height: NonZero::new(64).unwrap(), format: ironrdp_server::PixelFormat::ARgb32, data: vec![0; 64 * 64 * 4], - order: ironrdp_server::PixelOrder::BottomToTop, stride: 64 * 4, }; c.bench_function("rfx_enc_tile", |b| b.iter(|| rfx_enc_tile(&bitmap, &quant, algo, 0, 0))); @@ -32,7 +31,6 @@ pub fn rfx_enc_bench(c: &mut Criterion) { height: NonZero::new(2048).unwrap(), format: ironrdp_server::PixelFormat::ARgb32, data: vec![0; 2048 * 2048 * 4], - order: ironrdp_server::PixelOrder::BottomToTop, stride: 64 * 4, }; c.bench_function("rfx_enc", |b| b.iter(|| rfx_enc(&bitmap, &quant, algo))); diff --git a/crates/ironrdp-server/src/display.rs b/crates/ironrdp-server/src/display.rs index 1f825e5e..9d4879e6 100644 --- a/crates/ironrdp-server/src/display.rs +++ b/crates/ironrdp-server/src/display.rs @@ -24,12 +24,6 @@ pub enum DisplayUpdate { DefaultPointer, } -#[derive(Debug, Clone, Copy, PartialEq)] -pub enum PixelOrder { - TopToBottom, - BottomToTop, -} - #[derive(Clone)] pub struct RGBAPointer { pub width: u16, @@ -73,7 +67,6 @@ pub struct BitmapUpdate { pub width: NonZeroU16, pub height: NonZeroU16, pub format: PixelFormat, - pub order: PixelOrder, pub data: Vec, pub stride: usize, } @@ -86,7 +79,6 @@ impl core::fmt::Debug for BitmapUpdate { .field("width", &self.width) .field("height", &self.height) .field("format", &self.format) - .field("order", &self.order) .finish() } } diff --git a/crates/ironrdp-server/src/encoder/bitmap.rs b/crates/ironrdp-server/src/encoder/bitmap.rs index c502cdf3..1476f29c 100644 --- a/crates/ironrdp-server/src/encoder/bitmap.rs +++ b/crates/ironrdp-server/src/encoder/bitmap.rs @@ -4,7 +4,7 @@ use ironrdp_graphics::rdp6::{ABgrChannels, ARgbChannels, BgrAChannels, BitmapStr use ironrdp_pdu::bitmap::{self, BitmapData, BitmapUpdateData, Compression}; use ironrdp_pdu::geometry::InclusiveRectangle; -use crate::{BitmapUpdate, PixelOrder}; +use crate::BitmapUpdate; // PERF: we could also remove the need for this buffer pub(crate) struct BitmapEncoder { @@ -43,20 +43,14 @@ impl BitmapEncoder { let encoder = BitmapStreamEncoder::new(usize::from(bitmap.width.get()), height); - let len = match bitmap.order { - PixelOrder::BottomToTop => { - Self::encode_slice(encoder, bitmap.format, &chunk[..row_len], self.buffer.as_mut_slice()) - } + let len = { + let pixels = chunk + .chunks(bitmap.stride) + .map(|row| &row[..row_len]) + .rev() + .flat_map(|row| row.chunks(bytes_per_pixel)); - PixelOrder::TopToBottom => { - let pixels = chunk - .chunks(bitmap.stride) - .map(|row| &row[..row_len]) - .rev() - .flat_map(|row| row.chunks(bytes_per_pixel)); - - Self::encode_iter(encoder, bitmap.format, pixels, self.buffer.as_mut_slice()) - } + Self::encode_iter(encoder, bitmap.format, pixels, self.buffer.as_mut_slice()) }; let data = BitmapData { @@ -84,15 +78,6 @@ impl BitmapEncoder { Ok(cursor.pos()) } - fn encode_slice(mut encoder: BitmapStreamEncoder, format: PixelFormat, src: &[u8], dst: &mut [u8]) -> usize { - match format { - PixelFormat::ARgb32 | PixelFormat::XRgb32 => encoder.encode_bitmap::(src, dst, true).unwrap(), - PixelFormat::RgbA32 | PixelFormat::RgbX32 => encoder.encode_bitmap::(src, dst, true).unwrap(), - PixelFormat::ABgr32 | PixelFormat::XBgr32 => encoder.encode_bitmap::(src, dst, true).unwrap(), - PixelFormat::BgrA32 | PixelFormat::BgrX32 => encoder.encode_bitmap::(src, dst, true).unwrap(), - } - } - fn encode_iter<'a, P>(mut encoder: BitmapStreamEncoder, format: PixelFormat, src: P, dst: &mut [u8]) -> usize where P: Iterator + Clone, diff --git a/crates/ironrdp-server/src/encoder/mod.rs b/crates/ironrdp-server/src/encoder/mod.rs index 9fa7f29a..6ac4079e 100644 --- a/crates/ironrdp-server/src/encoder/mod.rs +++ b/crates/ironrdp-server/src/encoder/mod.rs @@ -1,7 +1,7 @@ mod bitmap; pub(crate) mod rfx; -use core::{cmp, mem}; +use core::cmp; use anyhow::{Context, Result}; use ironrdp_core::{Encode, WriteCursor}; @@ -14,7 +14,7 @@ use ironrdp_pdu::surface_commands::{ExtendedBitmapDataPdu, SurfaceBitsPdu, Surfa use self::bitmap::BitmapEncoder; use self::rfx::RfxEncoder; use super::BitmapUpdate; -use crate::{ColorPointer, PixelOrder, RGBAPointer}; +use crate::{ColorPointer, RGBAPointer}; #[derive(Debug, Copy, Clone, PartialEq, Eq)] #[repr(u8)] @@ -201,28 +201,12 @@ impl UpdateEncoder { self.set_surface(bitmap, codec_id, &buffer[..len]) } - fn none_update(&mut self, mut bitmap: BitmapUpdate) -> Result> { + fn none_update(&mut self, bitmap: BitmapUpdate) -> Result> { let stride = usize::from(bitmap.format.bytes_per_pixel()) * usize::from(bitmap.width.get()); - let data = match bitmap.order { - PixelOrder::BottomToTop => { - if stride == bitmap.stride { - mem::take(&mut bitmap.data) - } else { - let mut data = Vec::with_capacity(stride * usize::from(bitmap.height.get())); - for row in bitmap.data.chunks(bitmap.stride) { - data.extend_from_slice(&row[..stride]); - } - data - } - } - PixelOrder::TopToBottom => { - let mut data = Vec::with_capacity(stride * usize::from(bitmap.height.get())); - for row in bitmap.data.chunks(bitmap.stride).rev() { - data.extend_from_slice(&row[..stride]); - } - data - } - }; + let mut data = Vec::with_capacity(stride * usize::from(bitmap.height.get())); + for row in bitmap.data.chunks(bitmap.stride).rev() { + data.extend_from_slice(&row[..stride]); + } self.set_surface(bitmap, CodecId::None as u8, &data) } diff --git a/crates/ironrdp/examples/server.rs b/crates/ironrdp/examples/server.rs index 7d0453ce..c881e122 100644 --- a/crates/ironrdp/examples/server.rs +++ b/crates/ironrdp/examples/server.rs @@ -20,8 +20,8 @@ use ironrdp::server::tokio::sync::mpsc::UnboundedSender; use ironrdp::server::tokio::time::{self, sleep, Duration}; use ironrdp::server::{ tokio, BitmapUpdate, CliprdrServerFactory, Credentials, DisplayUpdate, KeyboardEvent, MouseEvent, PixelFormat, - PixelOrder, RdpServer, RdpServerDisplay, RdpServerDisplayUpdates, RdpServerInputHandler, ServerEvent, - ServerEventSender, SoundServerFactory, TlsIdentityCtx, + RdpServer, RdpServerDisplay, RdpServerDisplayUpdates, RdpServerInputHandler, ServerEvent, ServerEventSender, + SoundServerFactory, TlsIdentityCtx, }; use ironrdp_cliprdr_native::StubCliprdrBackend; use rand::prelude::*; @@ -183,7 +183,6 @@ impl RdpServerDisplayUpdates for DisplayUpdates { width, height, format: PixelFormat::BgrA32, - order: PixelOrder::TopToBottom, data, stride: usize::from(width.get()).checked_mul(4).unwrap(), };