OpenGL performance on laptop's external monitor - performance

I'm writing a small viewer application on Windows using C++ and OpenGL (Glfw).
I've struggled to get a consistent framerate # 60fps with no or almost no drop frames and so far so good. But, the application must be able to run on different monitors, ie either on the laptop's own display or an external one. I'm running on a Lenovo P50 and a full HD external monitor.
Running in duplicate mode everything is fine, while in extended mode using the external display I get many drop frames. I have tested this on other systems as well and it's the same pattern: the external monitor in extended mode is having a lot of frame drops.
Is this as expected?

Related

Qt/OpenGL: drawing into non-exposed windows

I am using gitlab-ci-runner to automatically test a desktop Qt/OpenGL application on every commit. On Windows 8, the application is executed by a system service installed with gitlab-ci-runner, hence it is run "hidden", i.e. on no visible desktop. All the UI modules initialize and run anyway, except the OpenGL module, which never gets an "expose" event; if I try to draw into the OpenGL context without the window being exposed I get the error:
QOpenGLContext::swapBuffers() called with non-exposed window, behavior is undefined
I have found out that it is rather difficult and not recommended to execute a Windows GUI application from a service on a running desktop session (see How can a Windows service execute a GUI application?).
Now, I don't need the user to see the application, I just need the OpenGL part to work correctly. Is there a way I can "pretend" to expose a window somehow, or is there any other way to get this to run correctly from a system service?
Is there a way I can "pretend" to expose a window somehow, or is there any other way to get this to run correctly from a system service?
Two problems you're running into:
If a window is not exposed all pixels rendered to will fail the pixel ownership test and rendering turns into a NoOp for all the pixels. The workaround for that is using wither a PBuffer or (recommended) a framebuffer object. Neither will immediately work with a on screen window, so you'll have to change some code.
In Windows processes started as a service usually don't get access to the graphics hardware, so you're limited to the capabilities of the software GDI OpenGL fallback (limited to OpenGL-1.1, hence no support for FBOs or PBuffers).
If you need GPU acceleration you can either invest into some grid computing GPU hardware (well, actually every GPU could do it, but the drivers disallow it for consumer grade stuff) to get a working OpenGL accelerated context. Or you can migrate to Linux, use a GPU supported by KMS/DRI/DRM and completely circumvent any graphics system. There's no official guide on how to do that, but it's on my (lengthy) ToDo list writing such a tutorial.
If you can live without GPU acceleration, drop a Windows build of Mesa with the softpipe renderer beside your program's .exe; the Windows Mesa softpipe build comes as a opengl32.dll fully API and ABI compatible with the standard opengl32.dll, but is independent of any graphics driver. It gives you OpenGL-3.3 support including FBOs and PBuffers.

VB6 with Images behaving strange, Any Expert?

I am facing really strange problem in my vb6 Application. It is working fine on every other machines but when I run it on my client's machine, Images do not show properly.
This is how problem looks like
Specifications:
Windows 8 Pro (6.2 Build 9200) 32 Bit
Processor Architecture 64 Bit
Core 2 Duo T9600 2.80 Ghz
Dell Latitude 6400.
I have deployed the same application on many other machines and tested on different resolutions with different Operating systems. Everywhere it is working prefect. but not working properly on client's Machine.
Without more information it is hard to be sure, but here is a guess:
Starting in Windows 7, if the system notices you have a monitor with excessive resolution it automatically chooses a high DPI setting.
If your program is not DPI-aware then one of several forms of appcompat are applied (based on the version of Windows, some system options, and application characteristics). Depending on which remediation is attempted by Windows, bitmap graphics can end up scaled and pixelated or not scaled and show as "smaller than expected."
Just to add fuel to the fire, people often try to do UI layout using ScaleMode = vbPixels and/or manual conversions and rely on a fixed ratio between these virtual pixels and actual screen metrics. Hard-coding 15 Twips/Pixel (1440/96) is very common because 96 DPI VGA (and VGA-derivative) square-pixeled screens were in use for a long time.
This fallacy can cause such a program to size controls improperly even when others get resized by the DPI remediation.
You might try reading though High DPI for information on this subject.
In the case of something like a Form backdrop image you either need several bitmaps of varying sizes from which you choose at runtime or else you'll need to scale the image yourself.

How to use DirectX 9 with multi- GPU on windows7

I‘ve got multiple nVidia GPU Cards (Q2000) on a Windows 7 system,without SLI, only one monitor.
Now what I'm trying to do is make a Direct3D9 device runing on a specific GPU.
I can use the [Adapter] parameter in IDirect3D9::CreateDevice to choose a GPU, but unless I connect a second monitor on that GPU card, it will not work (if I've only got one desktop on Windows).
If I click the "Detect" button in Resolution Control Panel, it can make a "fake" desktop on the side of my primary desktop, and CreateDevice(1, ...) works well - but this is not what I want.
For OpenGL, it's easy because the WGL_NV_gpu_affinity, It can make a OpenGL device runs on the second GPU with only one monitor connected, one desktop on windows.
I wonder if there is any API can use for Directx 9 work as "WGL_NV_gpu_affinity".
Any hint will be very appreciated. Thanks in advance!
IDirect3D9::CreateDevice uses at 1st parametr "Adapter", which not GPU, just monitor adapter

Enable/Disable multiple monitors via Win32 API or NVidia API?

I'm trying to write a small utility that will enable/disable monitors under Windows 7 with my nVidia graphics card. (ie. "Extend the desktop onto this monitor", etc)
The reason is that my nVidia Geforce GTX 480 has three outputs (2x DVI, 1x Mini-HDMI) but only allows two to be active at any given time so I need to enable/disable monitors when I want to switch to my TV (HDMI) display.
The Win32 API function EnumDisplayDevices isn't working because it doesn't show disabled monitors.
nVidia provides an API (NVAPI) and has functions to enumerate all monitors (even disabled ones) and you can enable a monitor but you can't disable a monitor. (I'm referring to NvAPI_CreateDisplayFromUnAttachedDisplay)
UltraMon seems to have figured out how to perform this but I can't find any information.
I think that if 2 out of three displays are already connected, the 3rd one will not be detected.
the card will stop listening for a new hardware.
you have to manually take out the cable , and then insert a new one in a different port.
unless there is a way to "eject" the connection, similar to a usb storage device.

What causes poor network performance when playing audio or video in Windows Vista and newer?

The software in question is a native C++/MFC application that receives a large amount of data over UDP and then processes the data for display, sound output, and writing to disk among other things. I first encountered the problem when the application's CHM help document was launched from its help menu and then I clicked around the help document while gathering data from the hardware. To replicate this, an AutoHotkey script was used to rapidly click around in the help document while the application was running. As soon as any sound occurred on the system, I started getting errors.
If I have the sound card completely disabled, everything processes fine with no errors, though sound output is obviously disabled. However, if I have sound playing (in this application, a different application or even just the beep from a message box) I get thousands of dropped packets (we know this because each packet is timestamped). As a second test, I didn't use my application at all and just used Wireshark to monitor incoming packets from the hardware. Sure enough, whenever a sound played in Windows, we had dropped packets. In fact, sound doesn't even have to be actively playing to cause the error. If I simply create a buffer (using DirectSound8) and never start playing, I still get these errors.
This occurs on multiple PCs with multiple combinations of network cards (both fiber optic and RJ45) and sound cards (both integrated and separate cards). I've also tried different driver versions for each NIC and sound card. All tests have been on Windows 7 32bit. Since my application uses DirectSound for audio, I've tried different CooperativeLevels (normal operation is DSSCL_PRIORITY) with no success.
At this point, I'm pretty convinced it has nothing to do with my application and was wondering if anyone had any idea what could be causing this problem before I started dealing with the hardware vendors and/or Microsoft.
It turns out that this behavior is by design. Windows Vista and later implemented something called the Multimedia Class Scheduler service (MMCSS) that is intended to make all multimedia playback as smooth as possible. Since multimedia playback relies on hardware interrupts to ensure smooth playback, any competing interrupts will cause problems. One of the major hardware interrupt sources is network traffic. Because of this, Microsoft decided to throttle the network traffic when a program was running under MMCSS.
I guess this was a big deal back in 2007 when Vista came out, but I missed it. There was an article by Mark Russinovich (thanks ypnos) describing MMCSS. It seems that the my entire problem boiled down to this:
Because the standard Ethernet frame
size is about 1500 bytes, a limit of
10,000 packets per second equals a
maximum throughput of roughly 15MB/s.
100Mb networks can handle at most
12MB/s, so if your system is on a
100Mb network, you typically won’t see
any slowdown. However, if you have a
1Gb network infrastructure and both
the sending system and your Vista
receiving system have 1Gb network
adapters, you’ll see throughput drop
to roughly 15%. Further, there’s an
unfortunate bug in the NDIS throttling
code that magnifies throttling if you
have multiple NICs. If you have a
system with both wireless and wired
adapters, for instance, NDIS will
process at most 8000 packets per
second, and with three adapters it
will process a maximum of 6000 packets
per second. 6000 packets per second
equals 9MB/s, a limit that’s visible
even on 100Mb networks.
I haven't verified that the multiple adapter bug still exists in Windows 7 or Vista SP1, but it is something to look for if you are running into problems.
From the comments on Russinovich's post, I found that Vista SP1 introduced some registry settings that allowed one to adjust how MMCSS affects Windows. Specifically the NetworkThrottlingIndex key.
The solution to my issue was to completely disable network throttling by setting the HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Multimedia\SystemProfile\NetworkThrottlingIndex key to 0xFFFFFFFF and then rebooting. This completely disables the network throttling portion of MMCSS. I had tried simply upping the value to 70, but it didn't stop causing errors until I completely disabled it.
Thus far I have not seen any adverse effects on other multimedia applications (nor the video capture and audio output portions of my own application) from this change. I will report back here if that changes.
It is known that Microsoft built some weird anti-feature into the Windows Vista kernel that will degrade I/O performance preventatively to make sure that multimedia applications (windows media player, directX) get 100% responsiveness. I don't know if that also means packet loss with UDP. Read this lame justification for the method: http://blogs.technet.com/b/markrussinovich/archive/2007/08/27/1833290.aspx
One of the comments there summarizes this quite well: "Seems to me Microsoft tried to 'fix' something that wasn't broken."

Resources