Skip to content

Commit

Permalink
#4319 fix scaled paints
Browse files Browse the repository at this point in the history
there are many different types of scaling..
the ones that matter here are:
* the "scale factor" given to us by the opengl backend, which usually comes from the OS and converts from the GTK window geometry to the actual geometry used on-screen,
* the ratio between the backing's size and the render size, this is normally set using the desktop-scaling option

I have no idea why we need to call glClear only when scaling, but not doing so produces garbage in the window, despite glBlitFramebuffer coming afterwards and covering the same area..
  • Loading branch information
totaam committed Aug 14, 2024
1 parent b2b3c50 commit a6bd395
Showing 1 changed file with 9 additions and 8 deletions.
17 changes: 9 additions & 8 deletions xpra/client/gl/backing.py
Original file line number Diff line number Diff line change
Expand Up @@ -774,8 +774,10 @@ def do_present_fbo(self, context) -> None:
# some backends render to the screen (0), otherws may render elsewhere
# (ie: the GTK backend renders to its own buffer…)
bw, bh = self.size
scale = context.get_scale_factor()
scaling = self.size != self.render_size or scale != 1
ww, wh = self.render_size
xscale = ww / bw * context.get_scale_factor()
yscale = wh / bh * context.get_scale_factor()
scaling = xscale != 1 or yscale != 1
if self.is_double_buffered() or scaling:
# refresh the whole window:
rectangles = [(0, 0, bw, bh), ]
Expand All @@ -790,17 +792,16 @@ def do_present_fbo(self, context) -> None:
self.save_fbo()

# viewport for clearing the whole window:
ww, wh = self.render_size
left, top, right, bottom = self.offsets
if left or top or right or bottom:
if left or top or right or bottom or xscale or yscale:
alpha = 0.0 if self._alpha_enabled else 1.0
glViewport(0, 0, int((left + ww + right) * scale), int((top + wh + bottom) * scale))
glViewport(0, 0, int((left + ww + right) * xscale), int((top + wh + bottom) * yscale))
glClearColor(0.0, 0.0, 0.0, alpha)
glClear(GL_COLOR_BUFFER_BIT)

# from now on, take the offsets and scaling into account:
viewport = int(left * scale), int(top * scale), int(ww * scale), int(wh * scale)
log(f"window viewport for render-size={self.render_size} and offsets={self.offsets} with {scale=}: {viewport}")
viewport = int(left * xscale), int(top * yscale), int(ww * xscale), int(wh * yscale)
log(f"viewport for render-size={self.render_size} and offsets={self.offsets} with {xscale=} / {yscale=}: {viewport}")
glViewport(*viewport)

# Draw FBO texture on screen
Expand All @@ -811,7 +812,7 @@ def do_present_fbo(self, context) -> None:

for x, y, w, h in rectangles:
glBlitFramebuffer(x, y, w, h,
round(x*scale), round(y*scale), round((x+ww)*scale), round((y+wh)*scale),
round(x*xscale), round(y*yscale), round((x+w)*xscale), round((y+h)*yscale),
GL_COLOR_BUFFER_BIT, sampling)

if self.pointer_overlay:
Expand Down

0 comments on commit a6bd395

Please sign in to comment.