1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
|
namespace RealTimeGraphEx.DX2D
{
using System;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Interop;
using SharpDX.Direct3D9;
using System.Threading;
class DX10ImageSource : D3DImage, IDisposable
{
private static int ActiveClients;
private static Direct3DEx D3DContext;
private static DeviceEx D3DDevice;
private Texture RenderTarget;
public DX10ImageSource()
{
this.StartD3D();
DX10ImageSource.ActiveClients++;
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2213:DisposableFieldsShouldBeDisposed", MessageId = "RenderTarget")]
public void Dispose()
{
this.SetRenderTargetDX10(null);
// Here, we have our Dispose call
Disposer.SafeDispose(ref this.RenderTarget);
DX10ImageSource.ActiveClients--;
this.EndD3D();
}
public void InvalidateD3DImage()
{
if (this.RenderTarget != null)
{
base.Lock();
base.AddDirtyRect(new Int32Rect(0, 0, base.PixelWidth, base.PixelHeight));
base.Unlock();
}
}
public void SetRenderTargetDX10(SharpDX.Direct3D10.Texture2D renderTarget)
{
if (this.RenderTarget != null)
{
this.RenderTarget = null;
base.Lock();
base.SetBackBuffer(D3DResourceType.IDirect3DSurface9, IntPtr.Zero);
base.Unlock();
}
if (renderTarget == null)
return;
if (!IsShareable(renderTarget))
{
throw new ArgumentException("Texture must be created with ResourceOptionFlags.Shared");
}
Format format = DX10ImageSource.TranslateFormat(renderTarget);
if (format == Format.Unknown)
{
throw new ArgumentException("Texture format is not compatible with OpenSharedResource");
}
IntPtr handle = GetSharedHandle(renderTarget);
if (handle == IntPtr.Zero)
{
throw new ArgumentNullException("Handle");
}
this.RenderTarget = new Texture(DX10ImageSource.D3DDevice, renderTarget.Description.Width, renderTarget.Description.Height, 1, Usage.RenderTarget, format, Pool.Default, ref handle);
using (Surface surface = this.RenderTarget.GetSurfaceLevel(0))
{
base.Lock();
base.SetBackBuffer(D3DResourceType.IDirect3DSurface9, surface.NativePointer);
base.Unlock();
}
}
private void StartD3D()
{
if (DX10ImageSource.ActiveClients != 0)
{
return;
}
DX10ImageSource.D3DContext = new Direct3DEx();
var presentparams = new PresentParameters();
presentparams.Windowed = true;
presentparams.SwapEffect = SwapEffect.Discard;
presentparams.DeviceWindowHandle = NativeMethods.GetDesktopWindow();
presentparams.PresentationInterval = PresentInterval.Default;
presentparams.MultiSampleQuality = 0; //Set By Roy.
DX10ImageSource.D3DDevice = new DeviceEx(D3DContext, 0, DeviceType.Hardware, IntPtr.Zero, CreateFlags.HardwareVertexProcessing | CreateFlags.Multithreaded | CreateFlags.FpuPreserve, presentparams);
}
private void EndD3D()
{
if (DX10ImageSource.ActiveClients != 0)
{
return;
}
Disposer.SafeDispose(ref this.RenderTarget);
Disposer.SafeDispose(ref DX10ImageSource.D3DDevice);
Disposer.SafeDispose(ref DX10ImageSource.D3DContext);
}
private IntPtr GetSharedHandle(SharpDX.Direct3D10.Texture2D Texture)
{
var resource = Texture.QueryInterface<SharpDX.DXGI.Resource>();
var result = resource.SharedHandle;
resource.Dispose();
return result;
}
private static Format TranslateFormat(SharpDX.Direct3D10.Texture2D Texture)
{
switch (Texture.Description.Format)
{
case SharpDX.DXGI.Format.R10G10B10A2_UNorm:
return SharpDX.Direct3D9.Format.A2B10G10R10;
case SharpDX.DXGI.Format.R16G16B16A16_Float:
return SharpDX.Direct3D9.Format.A16B16G16R16F;
case SharpDX.DXGI.Format.B8G8R8A8_UNorm:
return SharpDX.Direct3D9.Format.A8R8G8B8;
default:
return SharpDX.Direct3D9.Format.Unknown;
}
}
private static bool IsShareable(SharpDX.Direct3D10.Texture2D Texture)
{
return (Texture.Description.OptionFlags & SharpDX.Direct3D10.ResourceOptionFlags.Shared) != 0;
}
}
}
|