In VMWare, BitBlt() sometimes takes a very long time for ONE pixel (400 ms or more)
Asked Answered
C

0

6

Any ideas/workarounds on how to improve my BitBlt() reliability when running it in VMware? I have a timer that measures the time spent:

SmartTimer debugTimer = SmartTimer();
debugTimer.restart();
int ms1 = debugTimer.elapsedTimeMs();
POINT origin = { rect.left, rect.top };
int ms2 = debugTimer.elapsedTimeMs();
ClientToScreen(win_hwnd, &origin);
int ms3 = debugTimer.elapsedTimeMs();
BitBlt(hMemoryDC, 0, 0, (rect.right - rect.left) + 1, (rect.bottom - rect.top) + 1, hScreenDC, origin.x, origin.y, SRCCOPY); // SRCCOPY
int ms4 = debugTimer.elapsedTimeMs();
if (ms1 > 150 || ms2 > 150 || ms3 > 150 || ms4 > 150) {
    logs(std::format("getPixelData took very long: {} {} {} {}", ms1, ms2, ms3, ms4));
}

I have observed in the logs, often it says "0, 0, 0, 420" (or similar) indicating that BitBlt() took a very long time, even in cases where I only BitBlt() one pixel.

I know that for reading one pixel, there is GetPixel(), but for some reason this was very buggy for me when reading from a game. It would at times get pixel value 255, 255, 255 for everything, but when I switched to BitBlt(), the bug stopped happening.

It also seems like BitBlt() is usually very fast, but sometimes it is very slow.

Carmellacarmelle answered 27/11, 2021 at 8:30 Comment(7)
Try disabling the 3D support in VMWare, lately I've found this is very buggy.Kymry
How do you run games in VMware without 3D support? won't the performance be too slow?Carmellacarmelle
Bit block copy between devices? that does not sound like a light operation. Depending what is the origin, the destination, if devices are ready, the size of the rectangle...Radiotherapy
I'm not doing anything between devices. Just a program inside a VM doing bitblt, sometimes 2 VM's simultaneously but they are separate and isolated from each other. Nothing cross-device nor cross-VM. I also noticed that if I click to watch a different VM in VMWare, it will log the message that bitblt took a long time. Similar deal for if I do too much strenuous work on the host machine. I understand doing stuff on the host machine will lower performance somewhat but I would not expect so much lag for a tiny one-pixel bitblt.Carmellacarmelle
@Carmellacarmelle you could try to check how much time your thread actually spent executing by calling GetThreadTimes at the beginning and end and then comparing the change of lpKernelTime & lpUserTime. If the time you get using this method is a lot smaller than the time your SmartTimer reports, then your thread simply got preempted (potentially multiple times) during that code fragment.Sorites
If preemption is the problem you can try to increase the priority of your vm in relation to your host (that depends on which virtualization provider you're using - maybe this) and / or increase the process / thread priority of your BitBlt()-process with SetPriorityClass() / SetThreadPriority()Sorites
Beware though that very high priority levels (especially realtime priority) can result in your vm becoming completely unresponsive until the high-priority thread yields. Required Raymond LinkSorites

© 2022 - 2024 — McMap. All rights reserved.