我使用了SharpD2D1来在屏幕上显示图像。
我使用了SharpDX的示例创建SwapChain用于在屏幕上显示。
public static D2D.RenderTarget Target { get; private set; }
public readonly Device device;
public bool isFormClosed = false;
private readonly DXGI.Factory factory;
private readonly Texture2D backBuffer;
private readonly D2D.Factory factory2D;
private readonly DXGI.SwapChain swapChain;
private readonly RenderTargetView backBufferView;
public DXMagager() {
Width = Screen.PrimaryScreen.Bounds.Width;
Height = Screen.PrimaryScreen.Bounds.Height;
Left = Top = 0;
var desc = new DXGI.SwapChainDescription() {
BufferCount = 1,
ModeDescription = new DXGI.ModeDescription(Width, Height, new DXGI.Rational(300, 1), DXGI.Format.R8G8B8A8_UNorm),
IsWindowed = true,
OutputHandle = Handle,
SampleDescription = new DXGI.SampleDescription(1, 0),
SwapEffect = DXGI.SwapEffect.Discard,
Usage = DXGI.Usage.RenderTargetOutput
};
Device.CreateWithSwapChain(D3D.DriverType.Hardware, DeviceCreationFlags.BgraSupport, new[] { D3D.FeatureLevel.Level_10_0 }, desc, out device, out swapChain);
factory = swapChain.GetParent<DXGI.Factory>();
factory.MakeWindowAssociation(Handle, DXGI.WindowAssociationFlags.IgnoreAll);
backBuffer = Resource.FromSwapChain<Texture2D>(swapChain, 0);
backBufferView = new RenderTargetView(device, backBuffer);
factory2D = new D2D.Factory();
using (var surface = backBuffer.QueryInterface<DXGI.Surface>()) {
Target = new D2D.RenderTarget(factory2D, surface, new D2D.RenderTargetProperties(new D2D.PixelFormat(DXGI.Format.Unknown, D2D.AlphaMode.Premultiplied)));
}
Target.AntialiasMode = D2D.AntialiasMode.PerPrimitive;
}
public void Run() {
device.ImmediateContext.Rasterizer.SetViewport(0, 0, Width, Height);
device.ImmediateContext.OutputMerger.SetTargets(backBufferView);
using (var loop = new RenderLoop(this)) {
while (loop.NextFrame()) {
BeginDraw();
if (!isFormClosed) {
Draw();
}
EndDraw();
}
}
backBufferView.Dispose();
backBuffer.Dispose();
device.Dispose();
Target.Dispose();
swapChain.Dispose();
factory.Dispose();
}
之后我用这样的方式加载了100张Bitmap来绘制:
MemUsed = width * height * 4;
IntPtr intPtr = Marshal.AllocHGlobal(MemUsed);
unsafe {
slide.ReadRegion(level, x, y, width, height, (void*)intPtr); // 这句是加载一种格式的图片到intPtr,可以理解为Stream
}
BitmapProperties props = new BitmapProperties(new PixelFormat(Format.B8G8R8A8_UNorm, SharpDX.Direct2D1.AlphaMode.Ignore));
DataPointer pointer = new DataPointer(intPtr, MemUsed);
Bitmap = new Bitmap(DXMagager.Target, new Size2(width, height), pointer, width * 4, props);
Marshal.FreeHGlobal(intPtr); // 释放预分配的内存
但是我发现,如果把这100张Bitmap全部Dispose之后直接关闭DX窗口,那么其内存不会被释放。但如果不直接关闭DX窗口,那么过一段时间内存会被自动释放掉。请问这里到底发生了什么呢?
附SharpDX中对Dispose的解释:http://sharpdx.org/wiki/usage/