Direct2d с WPF через RDP

Я разрабатываю приложение C#, которое использует SharpDx для визуализации карты с помощью Direct2d. Эта карта отображается с D3DImage на хосте WPF. На локальной машине все работает нормально, но когда я пытаюсь подключиться через удаленный рабочий стол, D3DImage теряет свой Backbuffer, и визуализированное изображение не может отображаться с помощью WPF.

Я попытался включить откат программного обеспечения при привязке Backbuffer. В результате приложение успевает отобразить одно изображение, а затем снова теряет резервный буфер. Я также пытался включить аппаратное ускорение при подключении к удаленному рабочему столу с помощью gpedit, но ничего не изменилось.

    public void SetBackBuffer(D3D11.Texture2D texture)
    {
      using (var device = CreateDevice(NativeMethods.GetDesktopWindow()))
      {
        using (var texture9 = GetSharedSurface(device, texture))
        {
          this.surface = texture9.GetSurfaceLevel(0);
        }
      }

      this.Lock();
      this.SetBackBuffer(D3DResourceType.IDirect3DSurface9, this.surface.NativePointer, true);
      this.Unlock();
    }

    private static D3D9.Texture GetSharedSurface(D3D9.Device device, D3D11.Texture2D texture)
    {
      using (var surface = texture.QueryInterface<DXGI.Resource>())
      {
        IntPtr handle = surface.SharedHandle;

        return new D3D9.Texture(
          device,
          texture.Description.Width,
          texture.Description.Height,
          1,
          D3D9.Usage.RenderTarget,
          D3D9.Format.A8R8G8B8, // D3DFMT_A8R8G8B8
          D3D9.Pool.Default,  // D3DPOOL_DEFAULT
          ref handle);
      }
    }

    private static D3D9.DeviceEx CreateDevice(IntPtr handle)
    {
      using (var d3D9Ex = new D3D9.Direct3DEx())
      {
        var present = new D3D9.PresentParameters
        {
          Windowed = true,
          SwapEffect = D3D9.SwapEffect.Discard,
          DeviceWindowHandle = handle,
          PresentationInterval = D3D9.PresentInterval.Immediate,
        };

        const D3D9.CreateFlags CreateFlags = D3D9.CreateFlags.HardwareVertexProcessing | D3D9.CreateFlags.Multithreaded | D3D9.CreateFlags.FpuPreserve;

        return new D3D9.DeviceEx(
          d3D9Ex,
          0, // D3DADAPTER_DEFAULT
          D3D9.DeviceType.Hardware, // D3DDEVTYPE_HAL
          handle,
          CreateFlags,
          present);
      }
    }

Изменить Когда я отключаю аппаратное ускорение с помощью HKEY_CURRENT_USER/SOFTWARE/Microsoft/Avolon.Graphics/DisableHWAcceleration, я получаю ту же проблему на локальном компьютере без RDP.

Edit2 Я попытался создать эталонное устройство или деформирующее устройство с помощью Direct11. Но после небольшого исследования выяснилось, что оба программных устройства не поддерживают SharedSurfaces, которые я использую для создания образа WPF.


person Aiqs    schedule 02.07.2019    source источник


Ответы (1)


Итак, я нашел решение своей проблемы:

Прежде всего, вы должны включить резервное копирование программного обеспечения, когда вы привязываете BackBuffer к вашему D3DImage. Моя проблема заключалась в том, что после одного кадра я получил событие IsFrontBufferAvailableChanged, IsFrontBufferAvailable превратился в false, и я прекратил рендеринг. Но при программном рендеринге вы можете игнорировать эти вещи.

Вот проблема с github, которая помогла мне ее исправить: https://github.com/Sascha-L/WPF-MediaKit/issues/3

person Aiqs    schedule 03.07.2019