Browse Source

Fixed previewer render scaling

pull/11596/head
Julien Lebosquain 3 years ago
parent
commit
4adf0b68cb
No known key found for this signature in database GPG Key ID: 1833CAD10ACC46FD
  1. 32
      src/Avalonia.Controls/Remote/Server/RemoteServerTopLevelImpl.Framebuffer.cs
  2. 20
      src/Avalonia.Controls/Remote/Server/RemoteServerTopLevelImpl.cs
  3. 6
      src/Avalonia.DesignerSupport/Remote/PreviewerWindowImpl.cs

32
src/Avalonia.Controls/Remote/Server/RemoteServerTopLevelImpl.Framebuffer.cs

@ -19,17 +19,18 @@ namespace Avalonia.Controls.Remote.Server
private sealed class Framebuffer
{
public static Framebuffer Empty { get; } =
new(ProtocolPixelFormat.Rgba8888, default, new Vector(96.0, 96.0));
public static Framebuffer Empty { get; } = new(ProtocolPixelFormat.Rgba8888, default, 1.0);
private readonly double _dpi;
private readonly PixelSize _frameSize;
private readonly object _dataLock = new();
private readonly byte[] _data; // for rendering only
private readonly byte[] _dataCopy; // for messages only
private FrameStatus _status = FrameStatus.NotRendered;
public Framebuffer(ProtocolPixelFormat format, Size clientSize, Vector dpi)
public Framebuffer(ProtocolPixelFormat format, Size clientSize, double renderScaling)
{
var frameSize = PixelSize.FromSizeWithDpi(clientSize, dpi);
var frameSize = PixelSize.FromSize(clientSize, renderScaling);
if (frameSize.Width <= 0 || frameSize.Height <= 0)
frameSize = PixelSize.Empty;
@ -37,10 +38,11 @@ namespace Avalonia.Controls.Remote.Server
var stride = frameSize.Width * bpp;
var dataLength = Math.Max(0, stride * frameSize.Height);
_dpi = renderScaling * 96.0;
_frameSize = frameSize;
Format = format;
FrameSize = frameSize;
ClientSize = clientSize;
Dpi = dpi;
RenderScaling = renderScaling;
(Stride, _data, _dataCopy) = dataLength > 0 ?
(stride, new byte[dataLength], new byte[dataLength]) :
@ -51,9 +53,7 @@ namespace Avalonia.Controls.Remote.Server
public Size ClientSize { get; }
public Vector Dpi { get; }
public PixelSize FrameSize { get; }
public double RenderScaling { get; }
public int Stride { get; }
@ -72,9 +72,9 @@ namespace Avalonia.Controls.Remote.Server
{
return new LockedFramebuffer(
handle.AddrOfPinnedObject(),
FrameSize,
_frameSize,
Stride,
Dpi,
new Vector(_dpi, _dpi),
new PlatformPixelFormat((PixelFormatEnum)Format),
() =>
{
@ -93,7 +93,7 @@ namespace Avalonia.Controls.Remote.Server
}
}
/// <remarks>The returned message must be kept around, as it contains a shared buffer.</remarks>
/// <remarks>The returned message must NOT be kept around, as it contains a shared buffer.</remarks>
public FrameMessage ToMessage(long sequenceId)
{
lock (_dataLock)
@ -104,11 +104,11 @@ namespace Avalonia.Controls.Remote.Server
SequenceId = sequenceId,
Data = _dataCopy,
Format = Format,
Width = FrameSize.Width,
Height = FrameSize.Height,
Width = _frameSize.Width,
Height = _frameSize.Height,
Stride = Stride,
DpiX = Dpi.X,
DpiY = Dpi.Y
DpiX = _dpi,
DpiY = _dpi
};
}
}

20
src/Avalonia.Controls/Remote/Server/RemoteServerTopLevelImpl.cs

@ -29,7 +29,6 @@ namespace Avalonia.Controls.Remote.Server
private long _lastReceivedFrame = -1;
private long _nextFrameNumber = 1;
private ClientViewportAllocatedMessage? _pendingAllocation;
private Vector _dpi = new(96, 96);
private ProtocolPixelFormat? _format;
public RemoteServerTopLevelImpl(IAvaloniaRemoteTransportConnection transport)
@ -119,8 +118,11 @@ namespace Avalonia.Controls.Remote.Server
break;
case ClientRenderInfoMessage renderInfo:
_dpi = new Vector(renderInfo.DpiX, renderInfo.DpiY);
Dispatcher.UIThread.Post(_renderAndSendFrameIfNeeded);
Dispatcher.UIThread.Post(() =>
{
RenderScaling = renderInfo.DpiX / 96.0;
RenderAndSendFrameIfNeeded();
});
break;
case ClientSupportedPixelFormatsMessage supportedFormats:
@ -152,7 +154,7 @@ namespace Avalonia.Controls.Remote.Server
_pendingAllocation = null;
}
_dpi = new Vector(allocation.DpiX, allocation.DpiY);
RenderScaling = allocation.DpiX / 96.0;
ClientSize = new Size(allocation.Width, allocation.Height);
RenderAndSendFrameIfNeeded();
});
@ -258,12 +260,6 @@ namespace Avalonia.Controls.Remote.Server
return null;
}
protected void SetDpi(Vector dpi)
{
_dpi = dpi;
RenderAndSendFrameIfNeeded();
}
protected virtual Size Measure(Size constraint)
{
var l = (Layoutable) InputRoot!;
@ -279,8 +275,8 @@ namespace Avalonia.Controls.Remote.Server
{
if (_format is not { } format)
_framebuffer = Framebuffer.Empty;
else if (_framebuffer.Format != format || _framebuffer.ClientSize != ClientSize || _framebuffer.Dpi != _dpi)
_framebuffer = new Framebuffer(format, ClientSize, _dpi);
else if (_framebuffer.Format != format || _framebuffer.ClientSize != ClientSize || _framebuffer.RenderScaling != RenderScaling)
_framebuffer = new Framebuffer(format, ClientSize, RenderScaling);
return _framebuffer;
}

6
src/Avalonia.DesignerSupport/Remote/PreviewerWindowImpl.cs

@ -53,7 +53,11 @@ namespace Avalonia.DesignerSupport.Remote
// In previewer mode we completely ignore client-side viewport size
if (obj is ClientViewportAllocatedMessage alloc)
{
Dispatcher.UIThread.Post(() => SetDpi(new Vector(alloc.DpiX, alloc.DpiY)));
Dispatcher.UIThread.Post(() =>
{
RenderScaling = alloc.DpiX / 96.0;
RenderAndSendFrameIfNeeded();
});
return;
}
base.OnMessage(transport, obj);

Loading…
Cancel
Save