Win32 Bitmap如何渲染比像素更快?

6 c++ winapi msdn

与SetPixelV或其他功能相比,Win32位图(很多)绘制得更快.如果最终计算机将为位图绘制像素,这是如何工作的?

Yak*_*ont 5

假设你有一个像素.该像素具有颜色分量AB和C.您要绘制的表面具有颜色分量XY和Z.

所以首先你需要检查它们是否匹配.如果它们不匹配,则成本会上升.假设他们匹配.

接下来,你需要做边界检查 - 调用者是否给你一些愚蠢的东西?一些比较,添加和乘法.

接下来,您需要找到像素的位置.这是一些乘法和补充.

现在,您必须访问源数据和目标数据并进行编写.


如果您一次使用扫描线,几乎所有上述开销都可以完成一次.您可以计算扫描线的哪个部分落入边界,只需要比执行一个像素更多的开销.您可以找到扫描线在目标中写入的位置,而且只需要比一个像素更多的开销.您可以使用与一个像素相同的开销检查色彩空间转换.

最大的区别在于,您不是复制一个像素,而是复制一个块.

事实上,计算机非常擅长复制事物.某些CPU上有内置指令,有些内存系统可以在不涉及CPU的情况下执行此操作(CPU表示"将X复制到Y",然后可以执行其他操作;内存到内存带宽可能高于内存 - 到CPU到存储器).即使您通过CPU进行往返,也可以使用SIMD指令同时处理2,4,8,16甚至更多单位的数据,只要您以相同的方式处理它们即可有限的指令集.

在某些情况下,你甚至可以将工作卸载到GPU上 - 如果源和目标扫描线都在GPU上,你可以说"你用GPU,你可以处理它",GPU更专业于做那种任务.

优化的第一位 - 每个扫描线只需要检查一次而不是每个像素一次 - 可以轻松地为您提供2倍到10倍的加速.第二个 - 更有效率的blitting - 另外4倍到20倍更快.在GPU上执行所有操作可以快2到100倍.

最后一件事是实际调用函数的开销.通常这是次要的; 但是当调用SetPixel 100万次(1000 x 1000图像或适度大小的屏幕)时,它会加起来.

对于具有200万像素的HD显示器,每秒60次是每秒操纵1.2亿像素.如果你想跟上屏幕的话,3 GHz机器上的单线程程序只能运行每个像素大约25条指令,并假设没有其他事情发生(这是不太可能的).在4k显示器上,每个像素最多可以显示6条指令.

有了这么多像素,你可以削掉每一条指令.


乘数无处不在.我已经为每个像素的操作编写了一些转换,这些操作已经显示出令人印象深刻的加速,然而,同样适用于CPU到GPU的负载,并且看到SIMD给出了令人印象深刻的加速.