xpra icon
Bug tracker and wiki

Opened 4 weeks ago

Closed 4 weeks ago

#2884 closed defect (fixed)

auto-refresh failure: cancelled

Reported by: Antoine Martin Owned by: Antoine Martin
Priority: critical Milestone: 4.1
Component: server Version: 3.0.x
Keywords: Cc:

Description

Running a simple xterm with --quality=10, maximize and unmaximize until the lossy picture sticks.

Problem is that the server schedules an auto-refresh but a new damage event comes in and cancels it, without re-scheduling a new auto-refresh for some reason. (without even sending a draw packet?)

Change History (3)

comment:1 Changed 4 weeks ago by Antoine Martin

Status: newassigned

What happens is that the refresh is scheduled, but cancelled by size_notify_clients as the window is resized:

2020-09-23 15:04:29,590 cancel_refresh_timer(new damage 3835x2058)
  File "/usr/bin/xpra", line 10, in <module>
    sys.exit(main(sys.argv[0], sys.argv))
  File "/usr/lib64/python3.7/site-packages/xpra/scripts/main.py", line 123, in main
    return run_mode(script_file, err, options, args, mode, defaults)
  File "/usr/lib64/python3.7/site-packages/xpra/scripts/main.py", line 362, in run_mode
    return do_run_mode(script_file, error_cb, options, args, mode, defaults)
  File "/usr/lib64/python3.7/site-packages/xpra/scripts/main.py", line 512, in do_run_mode
    return run_server(error_cb, options, mode, script_file, args, current_display, progress_cb)
  File "/usr/lib64/python3.7/site-packages/xpra/scripts/server.py", line 344, in run_server
    return do_run_server(error_cb, opts, mode, xpra_file, extra_args, desktop_display, progress_cb)
  File "/usr/lib64/python3.7/site-packages/xpra/scripts/server.py", line 940, in do_run_server
    r = app.run()
  File "/usr/lib64/python3.7/site-packages/xpra/server/server_core.py", line 370, in run
    self.do_run()
  File "/usr/lib64/python3.7/site-packages/xpra/server/gtk_server_base.py", line 111, in do_run
    Gtk.main()
  File "/usr/lib64/python3.7/site-packages/gi/overrides/Gtk.py", line 1630, in main
    return _Gtk_main(*args, **kwargs)
  File "/usr/lib64/python3.7/site-packages/xpra/x11/server.py", line 626, in size_notify_clients
    ss.damage(wid, window, 0, 0, nw, nh)
  File "/usr/lib64/python3.7/site-packages/xpra/server/source/windows_mixin.py", line 575, in damage
    ws.damage(x, y, w, h, damage_options)
  File "/usr/lib64/python3.7/site-packages/xpra/server/window/window_source.py", line 1334, in damage
    self.do_damage(ww, wh, x, y, w, h, options)
  File "/usr/lib64/python3.7/site-packages/xpra/server/window/window_video_source.py", line 568, in do_damage
    super().do_damage(ww, wh, x, y, w, h, options)
  File "/usr/lib64/python3.7/site-packages/xpra/server/window/window_source.py", line 1343, in do_damage
    traceback.print_stack()

And this damage event never sends a screen update either!

Last edited 4 weeks ago by Antoine Martin (previous) (diff)

comment:2 Changed 4 weeks ago by Antoine Martin

This is caused by r17480.
The easy fix would be to take it out, or make it more clever by comparing with the refresh list:

===================================================================
--- xpra/server/window/window_source.py	(revision 27525)
+++ xpra/server/window/window_source.py	(working copy)
@@ -1335,9 +1335,15 @@
 
     def do_damage(self, ww, wh, x, y, w, h, options):
         now = monotonic_time()
-        if self.refresh_timer and (w*h>=ww*wh//4 or w*h>=512*1024):
-            #large enough screen update: cancel refresh timer
-            self.cancel_refresh_timer()
+        if self.refresh_timer and not (options.get("auto_refresh", False) or options.get("quality", 0)>=100):
+            rr = tuple(self.refresh_regions)
+            if rr:
+                #does this screen update intersect the refresh areas?
+                overlap = sum(rect.width*rect.height for rect in rr)
+                if overlap>0:
+                    pct = int(min(100, 100*overlap//(ww*wh)) * (1+self.global_statistics.congestion_value))
+                    sched_delay = max(self.min_auto_refresh_delay, int(self.base_auto_refresh_delay * pct // 100))
+                    self.refresh_target_time = max(self.refresh_target_time, now + sched_delay/1000.0)
 
         delayed = self._damage_delayed
         if delayed:

But we already handle intersections with the video region in window_video_source - so is this needed at all?

comment:3 Changed 4 weeks ago by Antoine Martin

Resolution: fixed
Status: assignedclosed
  • r27532 : don't cancel refresh
  • r27530 : timer_full_refresh was not invalidating the scroll data, so we ended up not sending a screen update at all (zero delta since the last one... which was lossy)
Note: See TracTickets for help on using tickets.