繁体   English   中英

远程桌面到 VM 上的平滑 WPF 动画

[英]Smooth WPF animations on Remote Desktop to VM

所以我试图制作一个与 VSCode 和 Atom 中使用的非常相似的对接库,但是我遇到了一些问题。 基本上,首先,我需要制作一个从宽度 0 开始的框,以增加到屏幕的末尾。 我能够做到这一点:

Rectangle rectangle = new Rectangle();
myCanvas.Children.Add(rectangle);
rectangle.Width = 0;
rectangle.Height = ActualHeight;
rectangle.Fill = new SolidColorBrush(Color.FromArgb(80, 120, 120, 120));
Storyboard sb = new Storyboard();
DoubleAnimation da = new DoubleAnimation(rectangle.Width, ActualWidth, new Duration(TimeSpan.FromMilliseconds(1000)));

Storyboard.SetTargetProperty(da, new PropertyPath("(Rectangle.Width)"));
sb.Children.Add(da);

rectangle.BeginStoryboard(sb);

animation 在我的开发机器上非常流畅,但是当远程桌面进入 VM 时,animation 非常不稳定。 但是,VSCodes 和 Atoms 动画仍然相当不错。 有什么办法可以使这项工作更好吗? 谢谢。

编辑:有没有办法为 Winforms 制作平滑的 animation ?

编辑 2:所以我在这里有这个 Winforms GDI 代码示例:

private void FastTimer_Tick(object sender, EventArgs e)
{
    var x = 1;
    if (solidBrush == IntPtr.Zero)
    {
        solidBrush = CreateSolidBrush(ColorTranslator.ToWin32(Color.FromArgb(120, 120, 120)));
        hDC = CreateGraphics().GetHdc();
    }

    index += x;

    int w = x;
    int h = Height;

    //create memory device context
    var memdc = CreateCompatibleDC(hDC);

    //create bitmap
    var hbitmap = CreateCompatibleBitmap(hDC, index, h);

    ////select bitmap in to memory device context
    var holdbmp = SelectObject(memdc, hbitmap);


    RECT rect = new RECT(new Rectangle(0, 0, w, h));
    FillRect(memdc, ref rect, solidBrush);
    
    AlphaBlend(hDC, index - x, 0, w, h, memdc, 0, 0, w, h, new BLENDFUNCTION(0, 0, 128, 0));
    SelectObject(memdc, holdbmp);
    DeleteObject(hbitmap);
    DeleteDC(memdc);
}

快速定时器核心是这样的(测试中间隔为 1000):

double frequency = Stopwatch.Frequency;
long prevTicks = 0;
while (true)
{
    if (!_enabled)
    {
        return;
    }
    double interval = frequency / Interval;
    long ticks = Stopwatch.GetTimestamp();
    if (ticks >= prevTicks + interval)
    {
        prevTicks = ticks;
        Tick?.Invoke(this, EventArgs.Empty);
    }
}

但是,远程桌面上的动画仍然不稳定。 (我知道 RD 不能使用硬件加速,但我认为 GDI 在兼容机器上是硬件加速的,但我在我的开发机器上没有看到任何 GPU 使用)关于 thatguys 的回答,我该如何让它更快?

这些问题在 WPF 中很常见,并且是由 bitmap 远程处理引起的,请参阅此Microsoft 博客

从 NET 3.5 SP1(包括 NET 4)的发布开始,WPF 使用服务器上的软件光栅器呈现应用程序内容,然后在所有情况下将内容远程作为位图。

由于大量重绘,这对于动画至关重要。 动画通常会同时影响一大片区域,想象一下颜色渐变。 因此,应用程序的很大一部分需要作废并重新绘制。 此外,WPF 中缺乏对遮挡的支持,这也可能加剧问题。

位图由底层 RDC 堆栈高度压缩,并且仅更新更改的区域。 另请注意,WPF 当前没有有效的遮挡支持,因此例如完全隐藏在其他不透明 WPF 元素后面的动画仍将强制失效和 RDP 更新。

您可能不会在本机 Win32 或 MFC 应用程序中遇到此问题的原因是它们使用 GDI 或 GDI+ 来绘制其用户界面控件。

当应用程序使用 GDI(例如许多 Win32 和 Winforms 应用程序)时,只有 GDI 原语被远程。 在许多情况下,这可能比远程传输 WPF 应用程序更有效,因为 WPF 应用程序远程处理位图,这通常会导致比类似的基于 GDI 的应用程序通过线路发送更多内容。 附加数据可能会导致性能下降,具体取决于网络带宽以及更新的大小和频率。

Atom 和 VS Code 是基于 Electron 构建的,它基于铬,而不是 WPF,这就是远程桌面存在很大差异的原因。

在链接的博客中,您可以找到有关如何总体提高远程性能的提示。 除了考虑在远程桌面场景中禁用动画(因为无法保证客户端的带宽或延迟等因素)之外,改进动画的基本部分是:

  • 调整DesiredFrameRate以降低 animation 帧率,进而降低流量
  • 在应用程序的被遮挡区域关闭动画,因为它们也会导致重绘
  • 通过从ProgressBarButtonComboBox等的默认 WPF 控制模板以及您自己的所有非必要动画中删除动画来减少流量
  • 通过简化应用程序的其他区域来提高 RDP 压缩效率,例如用纯色 colors 替换颜色渐变
  • 避免在 bitmap 效果或 3D 视图等软件中渲染缓慢的任何内容
  • 使用诸如Perforator之类的 WPF 性能分析工具来识别经常失效的关键区域以优化它们

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM