private void DisplayAsTexture(DirectXResource res)
        {
            if (res.Texture2D == null)
            {
                Core.LogWarning("DisplayAsTexture failed as Texture2D == null");
                return;
            }

            res.GetDx().RunOnContext(ctx =>
            {
                ctx.CopyResource(res.Texture2D, _sharedResource);
                ctx.Flush();
            }, "CopyToUI");

            if (_d3dimage.TryLock(TimeSpan.FromMilliseconds(1500)))
            {
                _d3dimage.AddDirtyRect(new Int32Rect(0, 0, res.Texture2D.Description.Width, res.Texture2D.Description.Height));
                _d3dimage.Unlock();
            }
            else
            {
                Core.LogWarning("Failed to Lock DirectXPresenter/d3dimage");
            }

            if (Source != _d3dimage)
            {
                Core.LogInfo("Assigning new D3DImage");
                Source = _d3dimage;
            }
        }
        private void DownloadAndDisplayAsBitmap(DirectXResource res)
        {
            int width  = res.Texture2D.Description.Width;
            int height = res.Texture2D.Description.Height;
            var dx     = res.GetDx();

            PrepareSoftwareImage(width, height, PixelFormats.Bgra32);

            if (_cpuTexture == null ||
                _cpuTexture.Texture2D == null ||
                _cpuTexture.Texture2D.Description.Width != width ||
                _cpuTexture.Texture2D.Description.Height != height ||
                _cpuTextureOwner != dx)
            {
                _cpuTexture?.Dispose();
                _cpuTextureOwner = dx;
                _cpuTexture      = dx.Pool.Get("uiCpu", DirectXResource.Desc(width, height, SharpDX.DXGI.Format.B8G8R8A8_UNorm, BindFlags.None, ResourceUsage.Staging, ResourceOptionFlags.None, CpuAccessFlags.Read));
            }

            DataBox db = new DataBox();

            dx.RunOnContext(ctx =>
            {
                ctx.CopyResource(res.Texture2D, _cpuTexture.Texture2D);
                ctx.Flush();
                db = ctx.MapSubresource(_cpuTexture.Texture2D, 0, MapMode.Read, MapFlags.None);
            }, "Download for ui");

            if (db.SlicePitch > 0)
            {
                _softwareImage.WritePixels(new Int32Rect(0, 0, width, height), db.DataPointer, db.SlicePitch, db.RowPitch);
            }
            dx.RunOnContext(ctx => ctx.UnmapSubresource(_cpuTexture.Texture2D, 0), "Unmap for ui");

            if (Source != _softwareImage)
            {
                Source = _softwareImage;
            }
        }
        private void OpenSharedResourceIfNeeded(DirectXResource res)
        {
            try
            {
                bool reinit = false;
                _occludedCounter++;

                if (_occludedCounter % 1 == 0) // every 200 ms
                {
                    var  state         = _device?.CheckDeviceState(_windowHandle) ?? DeviceState.Ok;
                    bool occludedState = state == DeviceState.PresentOccluded; // happens when windows is locked; then we could get black screen in preview d3dImage

                    reinit = _occludedState && !occludedState;                 // reinit if change from bad -> good
                    if (reinit)
                    {
                        Core.LogInfo("occluded -> normal");

                        if (_windowStateManager.IsMinimized())
                        {
                            _windowStateManager.IsMinimizedChanged += OnwindowStateManagerIsMinimizedChanged;
                        }
                        else
                        {
                            _ = ReinitSurfacesWithDelay();
                        }
                    }

                    if (!_occludedState && occludedState)
                    {
                        Core.LogInfo("normal -> occluded");
                    }

                    _occludedState = occludedState;
                }

                if (_sharedResource == null ||
                    _sharedResource.Description.Width != res.Texture2D.Description.Width ||
                    _sharedResource.Description.Height != res.Texture2D.Description.Height ||
                    _sharedResourceOwner != res.GetDx() ||
                    _reinitSurfaces)
                {
                    Core.LogInfo("Initing DX Presenter surface");
                    Source          = null;
                    _reinitSurfaces = false;

                    _surfaceD9?.Dispose();
                    _sharedResource?.Dispose();

                    _surfaceD9           = null;
                    _sharedResource      = null;
                    _sharedResourceOwner = null;


                    IntPtr handle = IntPtr.Zero;
                    _surfaceD9 = Surface.CreateRenderTarget(_device, res.Texture2D.Description.Width, res.Texture2D.Description.Height, Format.A8R8G8B8, MultisampleType.None, 0, true, ref handle);
                    if (handle == IntPtr.Zero)
                    {
                        Core.LogWarning("DirectX 9 Device failed to create Surface. Reinit Devices");
                        _device?.Dispose();
                        _direct3d?.Dispose();
                        _device   = null;
                        _direct3d = null;
                        InitDx9();
                        _surfaceD9 = Surface.CreateRenderTarget(_device, res.Texture2D.Description.Width, res.Texture2D.Description.Height, Format.A8R8G8B8, MultisampleType.None, 0, true, ref handle);

                        if (handle == IntPtr.Zero)
                        {
                            Core.LogWarning("DirectX 9 Device failed to create Surface after recreation.");
                        }
                    }
                    _sharedResource      = res.GetDx().Device.OpenSharedResource <Texture2D>(handle);
                    _sharedResourceOwner = res.GetDx();

                    _d3dimage = new D3DImage();
                    _d3dimage.Lock();
                    _d3dimage.SetBackBuffer(D3DResourceType.IDirect3DSurface9, _surfaceD9.NativePointer);
                    _d3dimage.Unlock();

                    Core.LogInfo("Inited DX Presenter surface");
                }
            }
            catch (Exception e)
            {
                Core.LogError(e, "Failed to open shared resource");
            }
        }