不安全的C#和2D渲染的指针是好是坏?
我正在编写一个包装DirectX 9并提供简化的界面来执行2D像素级绘制的Ccontrol。 .NET要求我将此代码包装在不安全的代码块中,并使用allow unsafe code选项进行编译。
我要锁定整个表面,然后返回一个指向内存锁定区域的指针。然后,我可以使用"简单"指针算法直接写入像素数据。我已经对性能进行了测试,发现与已知的其他"安全"方法相比,速度有了显着提高。
这是在C.NET应用程序中处理单个像素的最快方法吗?有没有更好,更安全的方法?如果有一种不需要指针操作的同样快速的方法,那么我倾向于使用它。
(我知道这是2008年,我们都应该使用DirectX 3D,OpenGL等,但是此控件仅用于2D像素渲染,而根本不需要3D渲染。)
解决方案
回答
我最近的任务是为我们的一个瘦客户端应用程序(C#)创建一个简单的直方图控件。我正在分析的图像约为1200x1200,我必须走相同的路线。我可以使它绘制一次而没有问题,但是控件需要重新设置大小。我试图避免这种情况,但是我必须了解原始内存本身。
我并不是说使用标准的.NET类是不可能的,但是最终我还是无法使它正常工作。
回答
使用不安全的指针是在C语言中进行直接内存操作的最快方法(肯定比使用元帅包装函数要快)。
出于好奇,我们尝试执行哪种2D绘图操作?
我之所以问是因为锁定DirectX曲面以进行像素级操作会挫败我们希望从使用DirectX获得的大多数硬件加速优势。此外,在终端服务(远程桌面)上使用DirectX设备时,初始化将失败,因此该控件在该情况下将无法使用(这可能对我们没有影响)。
DirectX在绘制大三角形和变换图像(将纹理映射到四边形)时将是一个巨大的胜利,但是在单像素操作下,DirectX并不能真正实现如此出色的效果。
留在.NET领域,一种替代方法是使用LockBits并保持Bitmap对象作为表面,并通过返回的BitmapData对象中的不安全指针直接访问像素。
回答
是的,这可能是最快的方法。
几年前,我不得不比较两个1024x1024像素级别的图像; get-pixel方法花费了2分钟,不安全的扫描花费了0.01秒。
回答
我还使用不安全来加速这种性质的事情。至少可以说,性能的改善是惊人的。这里的重点是,只要我们知道自己在做什么,不安全就可以关闭一堆我们可能不需要的东西。
此外,签出DirectDraw。它是DirectX的2D图形组件。真的很快。