refactor(server)!: drop support for pixelOrder

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 <marcandre.lureau@redhat.com>
This commit is contained in:
Marc-André Lureau
2025-03-31 18:11:03 +02:00
committed by Benoît Cortier
parent 4e581e0f47
commit db6f4cdb7f
5 changed files with 17 additions and 59 deletions
-2
View File
@@ -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)));
-8
View File
@@ -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<u8>,
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()
}
}
+8 -23
View File
@@ -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::<ARgbChannels>(src, dst, true).unwrap(),
PixelFormat::RgbA32 | PixelFormat::RgbX32 => encoder.encode_bitmap::<RgbAChannels>(src, dst, true).unwrap(),
PixelFormat::ABgr32 | PixelFormat::XBgr32 => encoder.encode_bitmap::<ABgrChannels>(src, dst, true).unwrap(),
PixelFormat::BgrA32 | PixelFormat::BgrX32 => encoder.encode_bitmap::<BgrAChannels>(src, dst, true).unwrap(),
}
}
fn encode_iter<'a, P>(mut encoder: BitmapStreamEncoder, format: PixelFormat, src: P, dst: &mut [u8]) -> usize
where
P: Iterator<Item = &'a [u8]> + Clone,
+7 -23
View File
@@ -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<UpdateFragmenter<'_>> {
fn none_update(&mut self, bitmap: BitmapUpdate) -> Result<UpdateFragmenter<'_>> {
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)
}
+2 -3
View File
@@ -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(),
};