@@ -73,6 +73,10 @@ pub fn init_wasm_log(log_level: &str) {
7373pub struct BitmapFrame {
7474 top : u16 ,
7575 left : u16 ,
76+ dirty_x : u16 ,
77+ dirty_y : u16 ,
78+ dirty_width : u16 ,
79+ dirty_height : u16 ,
7680 image_data : ImageData ,
7781}
7882
@@ -88,6 +92,26 @@ impl BitmapFrame {
8892 self . left
8993 }
9094
95+ #[ wasm_bindgen( getter) ]
96+ pub fn dirty_x ( & self ) -> u16 {
97+ self . dirty_x
98+ }
99+
100+ #[ wasm_bindgen( getter) ]
101+ pub fn dirty_y ( & self ) -> u16 {
102+ self . dirty_y
103+ }
104+
105+ #[ wasm_bindgen( getter) ]
106+ pub fn dirty_width ( & self ) -> u16 {
107+ self . dirty_width
108+ }
109+
110+ #[ wasm_bindgen( getter) ]
111+ pub fn dirty_height ( & self ) -> u16 {
112+ self . dirty_height
113+ }
114+
91115 #[ wasm_bindgen( getter) ]
92116 pub fn image_data ( & self ) -> ImageData {
93117 self . image_data . clone ( ) // TODO(isaiah): can we remove this clone?
@@ -204,9 +228,14 @@ impl FastPathProcessor {
204228 match output {
205229 ActiveStageOutput :: GraphicsUpdate ( updated_region) => {
206230 // Apply the updated region to the canvas.
207- let ( image_location, image_data) =
208- extract_partial_image ( & self . image , updated_region) ;
209- self . apply_image_to_canvas ( image_data, image_location, cb_context, draw_cb) ?;
231+ self . apply_image_to_canvas (
232+ self . image . data ( ) ,
233+ updated_region,
234+ cb_context,
235+ draw_cb,
236+ self . image . width ( ) ,
237+ self . image . height ( ) ,
238+ ) ?;
210239 }
211240 ActiveStageOutput :: ResponseFrame ( frame) => {
212241 // Send the response frame back to the server.
@@ -280,18 +309,30 @@ impl FastPathProcessor {
280309
281310 fn apply_image_to_canvas (
282311 & self ,
283- image_data : Vec < u8 > ,
312+ image_data : & [ u8 ] ,
284313 image_location : InclusiveRectangle ,
285314 cb_context : & JsValue ,
286315 callback : & js_sys:: Function ,
316+ image_width : u16 ,
317+ image_height : u16 ,
287318 ) -> Result < ( ) , JsValue > {
288- let top = image_location. top ;
289- let left = image_location. left ;
319+ let image_data = create_image_data_from_image_and_region (
320+ image_data,
321+ InclusiveRectangle {
322+ left : 0 ,
323+ top : 0 ,
324+ right : image_width - 1 ,
325+ bottom : image_height - 1 ,
326+ } ,
327+ ) ?;
290328
291- let image_data = create_image_data_from_image_and_region ( & image_data, image_location) ?;
292329 let bitmap_frame = BitmapFrame {
293- top,
294- left,
330+ top : 0 ,
331+ left : 0 ,
332+ dirty_x : image_location. left ,
333+ dirty_y : image_location. top ,
334+ dirty_width : image_location. width ( ) ,
335+ dirty_height : image_location. height ( ) ,
295336 image_data,
296337 } ;
297338
@@ -302,86 +343,3 @@ impl FastPathProcessor {
302343 Ok ( ( ) )
303344 }
304345}
305-
306- /// Taken from https://github.com/Devolutions/IronRDP/blob/35839459aa58c5c42cd686b39b63a7944285c0de/crates/ironrdp-web/src/image.rs#L6
307- pub fn extract_partial_image (
308- image : & DecodedImage ,
309- region : InclusiveRectangle ,
310- ) -> ( InclusiveRectangle , Vec < u8 > ) {
311- // PERF: needs actual benchmark to find a better heuristic
312- if region. height ( ) > 64 || region. width ( ) > 512 {
313- extract_whole_rows ( image, region)
314- } else {
315- extract_smallest_rectangle ( image, region)
316- }
317- }
318-
319- /// Faster for low-height and smaller images
320- ///
321- /// https://github.com/Devolutions/IronRDP/blob/35839459aa58c5c42cd686b39b63a7944285c0de/crates/ironrdp-web/src/image.rs#L16
322- fn extract_smallest_rectangle (
323- image : & DecodedImage ,
324- region : InclusiveRectangle ,
325- ) -> ( InclusiveRectangle , Vec < u8 > ) {
326- let pixel_size = usize:: from ( image. pixel_format ( ) . bytes_per_pixel ( ) ) ;
327-
328- let image_width = usize:: from ( image. width ( ) ) ;
329- let image_stride = image_width * pixel_size;
330-
331- let region_top = usize:: from ( region. top ) ;
332- let region_left = usize:: from ( region. left ) ;
333- let region_width = usize:: from ( region. width ( ) ) ;
334- let region_height = usize:: from ( region. height ( ) ) ;
335- let region_stride = region_width * pixel_size;
336-
337- let dst_buf_size = region_width * region_height * pixel_size;
338- let mut dst = vec ! [ 0 ; dst_buf_size] ;
339-
340- let src = image. data ( ) ;
341-
342- for row in 0 ..region_height {
343- let src_begin = image_stride * ( region_top + row) + region_left * pixel_size;
344- let src_end = src_begin + region_stride;
345- let src_slice = & src[ src_begin..src_end] ;
346-
347- let target_begin = region_stride * row;
348- let target_end = target_begin + region_stride;
349- let target_slice = & mut dst[ target_begin..target_end] ;
350-
351- target_slice. copy_from_slice ( src_slice) ;
352- }
353-
354- ( region, dst)
355- }
356-
357- /// Faster for high-height and bigger images
358- ///
359- /// https://github.com/Devolutions/IronRDP/blob/35839459aa58c5c42cd686b39b63a7944285c0de/crates/ironrdp-web/src/image.rs#L49
360- fn extract_whole_rows (
361- image : & DecodedImage ,
362- region : InclusiveRectangle ,
363- ) -> ( InclusiveRectangle , Vec < u8 > ) {
364- let pixel_size = usize:: from ( image. pixel_format ( ) . bytes_per_pixel ( ) ) ;
365-
366- let image_width = usize:: from ( image. width ( ) ) ;
367- let image_stride = image_width * pixel_size;
368-
369- let region_top = usize:: from ( region. top ) ;
370- let region_bottom = usize:: from ( region. bottom ) ;
371-
372- let src = image. data ( ) ;
373-
374- let src_begin = region_top * image_stride;
375- let src_end = ( region_bottom + 1 ) * image_stride;
376-
377- let dst = src[ src_begin..src_end] . to_vec ( ) ;
378-
379- let wider_region = InclusiveRectangle {
380- left : 0 ,
381- top : region. top ,
382- right : image. width ( ) - 1 ,
383- bottom : region. bottom ,
384- } ;
385-
386- ( wider_region, dst)
387- }
0 commit comments