我在 FMX 中有一个奇怪的错误,它具有指针溢出或特定于硬件的错误的所有特征,我无法追踪。重现它的小应用程序,不要(还)。我在下面有代码片段,但由于我没有设法在一个小应用程序中重现它,它们只是片段。
该应用程序加载一些 PNG 文件,然后根据 PNG 文件中的颜色编码创建内存位图 - 也就是说,它将创建一个足够大以绑定原始文件的所有红色区域的内存位图,并且是最初为空白。有一个与内存位图大小相同的字节数组,它是一个掩码(零,非零),指示该像素是否对应于原始的红色(比如说)区域。用户可以在应用程序中绘画,在临时显示位图上绘画,然后当他们松开鼠标按钮时,该位图会针对字节数组进行扫描以写入内存位图。
跟我到现在?基本上,原始的颜色编码子集,为颜色区域创建的蒙版,子集上的绘画被蒙版。这是一个图表:
这适用于 XP(GDI+ 画布)和 Win7(D2D 画布)和 Win8.1 和大多数 Win10 机器。但是,在两台 Win10 机器上,一台使用 Intel HD 4600,另一台使用 Intel Iris 5000,客户端在执行遮罩和设置像素的步骤后在位图上得到奇怪的伪影。
伪像是明显随机散布在位图上的矩形,要么大(比如 100x20 像素),要么小(比如 10x8)。我还看到了一些截图,其中 UI 的其余部分(如按钮字形)也出现在位图上。以下是一些示例屏幕截图:
在这里,用户已经绘制了深红色区域,并在其他地方绘制了较浅的颜色。这些小斑点矩形出现。
在这里,用户在中间绘制了宽条纹。深红色和浅红色矩形是蒙版并绘制到位图后的伪影示例。
对我来说,这听起来像是我在错误的步幅上写像素之类的。我已经对数组或位图数据访问中的非一错误进行了严格的代码检查,并且我正在使用以下代码来获取或设置位图数据中的像素:
function GetBitmapColor(const M : PBitmapData; const X, Y : Integer) : TAlphaColor;
begin
Result := PixelToAlphaColor(
@PAlphaColorArray(M.Data)[Y * (M.Pitch div PixelFormatBytes[M.PixelFormat]) + X],
M.PixelFormat);
end;
procedure SetBitmapColor(const M : PBitmapData; const X, Y : Integer; const C : TAlphaColor);
begin
AlphaColorToPixel(C,
@PAlphaColorArray(M.Data)[Y * (M.Pitch div PixelFormatBytes[M.PixelFormat]) + X],
M.PixelFormat);
end;
这些基于西雅图文档中用于访问位图数据的示例代码。X 和 Y 在有效范围内(位图大小)的断言都是可以的。虽然这发生在上面给出的操作系统和硬件上,但它不会发生在具有其他卡的相同操作系统(Win10)上——另一个英特尔 HD、Nvidia 等;在 Win10 平板电脑上;在我尝试过的 Win10 VM 上;在我的 Win7 开发机器上;等就缓冲区溢出等而言,使用范围检查进行编译不会给出任何错误,也没有我自己的任何断言检查位图大小的有效 X/Y 坐标。
XE6 和 Seattle 在同一台机器上都会出现该错误。
我无法重现这个。他们正在设置对这台机器的远程访问,但要弄清楚发生了什么仍然很棘手,所以我想知道是否有人以前见过类似的东西,或者有具体的检查方法的具体建议位图指针溢出或类似?