On Windows 7 onwards how do you ensure layered windows via the WS_EX_LAYERED window style do not incur a performance hit of copying data back from the GPU to CPU for hit testing?
From what I have read this optimisation only seems possible if the full window region lets mouse hits pass right through, or fully blocks them. But how do you specifically ensure this behaviour in both of these cases?
Related
I've have found a problem running unity(ver. 2019.4.34f1 and 2021.2.8f1) on my MacBook m1 chip. Whenever I run Playmode while having Scene and Game tab open at the same time I get only around 30fps which is very strange running on m1 chip. But When I closed the Scene tab and ONLY having the Game tab open, the fps jump to 400fps+.
I have:
installed mono, .Net Arm64
Default Unity Configuration
Is there a way to resolve this issue?
I suspect this has to do with a default setting on a LapTop to save power. Try changing the interaction mode under Edit/Preferences/General.
Interaction Mode Specifies how long the Editor can idle before it
updates. After one frame finishes, the Editor waits up to the
specified amount of time before the next frame begins.
This allows you to throttle Editor performance, and reduce consumption
of CPU resources and power.
For example, if you want to test the Editor’s performance, set this
property to No Throttling. If you want to conserve power (for example,
to prolong battery life on a laptop computer), set this property to
one of the throttled modes.
In throttled modes, the Editor stops idling if you interact with it
(for example, by panning in the Scene view).
Note: In Play mode, Unity ignores any throttling that you apply using
this preference. The editor updates as fast as possible unless you
enable the VSync option in the Game view, or set
Application.targetFrameRate to a value other than –1.
Unity Docs
The documentation for the DXGI 1.5 flag DXGI_PRESENT_ALLOW_TEARING is somewhat sparse. The MSDN article on variable refresh rate displays has the following to say about when to use the flag:
"Support for variable refresh rate displays is achieved by setting certain flags when creating and presenting the swap chain."
"It is recommended to always pass this tearing flag when using sync interval 0 if CheckFeatureSupport reports that tearing is supported and the app is in a windowed mode - including border-less fullscreen mode."
These descriptions make it clear that apps should use this flag if they want to support variable refresh rate in windowed mode, but don't go into very much detail on how exactly a program will behave differently if the flag is enabled or disabled. I have several relevant questions:
Is this flag always required to get variable refresh for windowed swap chains, or can the system ever inject support automatically like it does for fullscreen applications (e.g., when "enabled for windowed and fullscreen mode" is enabled in the Nvidia control panel)?
Can the system use this flag to allow multiple swap chains running at different refresh rates to co-exist without tearing or stuttering on the same display? E.g., a 120hz monitor playing back a 30hz video and a 24hz video at the same time without tearing or stuttering.
Can this flag be used to produce actual tearing on monitors that don't support variable refresh rate?
If this flag is always useful when running on compatible hardware in windowed mode with presentInterval = 0, then why can't the system enable it automatically under those circumstances?
I am using BitBlt heavily in my project. I create a number of threads and in each thread I capture the screen by BitBlt. It works great and as expected for now except the following problem.
The problem happens when the user clicks on a running program or for example already opened explorer on the taskbar. You know when you click on the running program on the taskbar, it either minimizes or appears on the screen. The issue that I am talking about happens just in this transition. At that moment, something like an interrupt, all threads stop capturing the screen for a fraction of a second and then they continue capturing. The same thing happen when you move down or up the thing on the volume control window. Could you please shed some light why this is happening and how I can prevent this happening?
Thanks.
Jay
It could be a scheduling issue. When you activate an app, it gets a small, momentary boost in its priority (so that it can seem responsive in the UI). This boost might last about as long as the animation and momentarily pre-empt your screen capture threads.
It's also possible that the desktop manager is serializing stuff, and your bitblts are simply stalled until the animation is over. Even if you've turned Aero off, I believe the desktop window manager may still be in compositing mode, which has the effect Hans Passant was describing in the comments.
If you're trying to make a video from the screen, I think it's going to be impossible to rely on GDI. I strongly suggest reading about the Desktop Window Manager. For example, this caveat directly applies to what you're trying to do:
Avoid reading from or writing to a display DC. Although supported by DWM, we do not recommend it because of decreased performance.
When you use GDI to try to read the screen, DWM has to stop what it's doing, possibly render a fresh copy of the desktop to video memory, and to copy data from video memory back to system memory. It's possible that the DWM treats these as lower-priority requests than an animation in progress, so by the time it responds to the BitBlt, the animation is over.
This question suggests that DirectShow with a screen capture filter might be the way to go.
On my system, this is a problem if you have a 3D application with running, which takes some time to redraw, and drag any window over it. It causes a very jerky movement. This also happens if you drag a dialog from the 3D app over its 3D window. The application actually gets a redraw message (WM_PAINT?) which causes it to do a full redraw. Shouldn't the background window be cached by Windows as a bitmap or something?
I've pasted the NVIDIA system information dump below, note that I have 2 GPUs. Don't know if that's significant, but we're seeing this problem on another machine in the office, which also has 2 GPUs and Windows 7. Other machines which have 1 GPU don't have this problem.
Found out what the issue was. I was running Windows Vista Basic color scheme, instead of Aero. In basic, Windows probably only has one buffer for the whole screen, so whenever a window is moved, any window it overlaps must be redrawn. In Aero, each windows' "buffer" is cached to enable gpu accelerated blending (for the transparent parts of the window). So in Aero, there's no redraw of underlying windows as a result of dragging another window across it.
I am programmatically animating a window to make it bounce around the desktop, using MoveWindow.
It's leaving a temporary ghosting effect of the previous portion of the desktop the window that
it occupied.
How does one prevent this happening ?
That's somewhat inevitable on older versions of Windows. The processes whose windows you overlap need time to update the part of the window that got revealed when you moved your window. Do check that your program isn't burning 100% core with taskmgr.exe, that would make it much more noticeable.
A real solution for this problem requires Aero, available on Vista and up.