Opened 4 years ago

Last modified 20 months ago

#3356 assigned Feature Request

Add per monitor DPI awareness (Windows 8.1 API)

Reported by: XperiAndri Owned by:
Priority: normal Milestone:
Component: General Version:
Severity: normal Keywords: DPI
Cc: alexmarsev Evaluation:

Description

Please, add per monitor dpi awareness support which was introduced in Windows 8.1 API.
Watch http://channel9.msdn.com/Events/Build/2013/3-017 for reference.

Attachments (1)

0001-Set-Per-Monitor-DPI-Awareness.patch (2.7 KB) - added by nevcairiel 2 years ago.

Download all attachments as: .zip

Change History (29)

comment:1 Changed 4 years ago by thevbm

This as well for reference -> http://virtualdub.org/blog/pivot/entry.php?id=384

But pretty much all that needs to be done is change True to True/PM on this line

https://github.com/mpc-hc/mpc-hc/blob/master/src/mpc-hc/res/mpc-hc.exe.manifest.conf#L39

Last edited 4 years ago by thevbm (previous) (diff)

comment:2 Changed 4 years ago by thevbm

  • Milestone next release deleted
  • Type changed from Bug to Feature Request

comment:3 Changed 4 years ago by xhmikosr

  • Owner set to xhmikosr
  • Status changed from new to assigned

comment:5 Changed 4 years ago by xhmikosr

Yeah, I'm not interested in reading all that. I'll merge my simple patch in the near future. If that works, then ok otherwise someone else will have to read all that crap.

comment:6 Changed 4 years ago by XperiAndri

It won't work.
Because your solution will use old DPI awareness, not "per monitor".

To support Win 8.1 API you need to declare per monitor dpi aware in manifest and handle Windows Message passed to application when its window is moved to the screen with other DPI. And when you handed it you need to set corresponding images to images with suitable resolution (if you want them to look well) and rescale video.

Last edited 4 years ago by XperiAndri (previous) (diff)

comment:7 Changed 4 years ago by xhmikosr

And what exactly you think my solution is?

comment:8 Changed 4 years ago by XperiAndri

As I understood from previous comments you want to add dpiaware to the manifest, isn't it?

comment:9 Changed 4 years ago by xhmikosr

  • Owner xhmikosr deleted

Yeah. Then hope someone else will be interested in this stuff.

comment:10 Changed 3 years ago by xhmikosr

  • Cc alexmarsev added

comment:11 Changed 2 years ago by nevcairiel

Fixing this would be nice. Right now, if you have multiple monitors with different DPI, video is not rendered at "native" resolution.

ie. my setup, on Win 8.1:
Primary screen: 27" 2560x1440 at 100% scale
Secondary screen: 27" 3840x2160 at 150% scale (effectively 2560x1440)

Playing a movie in MPC-HC on the 4K screen results in MPC-HC thinking that my screen is 2560x1440, the video being rendered to 2560x1440, and then Windows doing an upscale to full 4K.

Obviously this destroys a lot of the benefits of rendering video at such high resolutions, especially if you play a native 4K video. It actually gets down-sampled by the Video Renderer, and then upsampled again by Windows.

One fix for this problem is to simply mark MPC-HC as Per-Monitor DPI Aware in the manifest.
The window will be tiny on the 4K screen then, but at the very least video renders in proper high quality, which is the most important part here.

If someone wants to test, a quick patch attached to do just this.

Changed 2 years ago by nevcairiel

comment:12 Changed 20 months ago by alexmarsev

Alternatively we can ditch the manifest entry and call SetProcessDPIAware() based on some new advanced option.

comment:13 follow-up: Changed 20 months ago by nevcairiel

Using the manifest is recommended over the API, and easier, too, don't need to handle backwards compat.

The patch added above should really not break anything, just ensures that it renders at native resolution on every screen. If you run a 4K screen only, it works fine. It just doesn't handle mixed DPI environments. Although someone may complain that MPC-HC is smaller now on their 4K screen (when running a mixed setup like mine), but it would already be small if the 4K screen would be their primary screen, so...

comment:14 follow-up: Changed 20 months ago by XperiAndri

What is the problem to write a logic to handle Per Monitor DPI?
Windows 10 already almost came but this has not done yet. And waiting for 2 years.

If I new C++ enough I would already completed this ticket.

You either interested in this or not.
If this task is not interested to you, it is up to you. But don't tell that implementing Per Monitor DPI is too complex.

Last edited 20 months ago by XperiAndri (previous) (diff)

comment:15 in reply to: ↑ 13 ; follow-up: Changed 20 months ago by alexmarsev

Replying to nevcairiel:
I'm more worried about setups like high-dpi laptop connected to low-dpi external screen. Wouldn't that make mpc-hc look huge on external screen?

comment:16 Changed 20 months ago by XperiAndri

It depends on how you will handle crossing the screen boundary.
In general it must be the same in physical screen size and change in logical size.

Last edited 20 months ago by XperiAndri (previous) (diff)

comment:17 Changed 20 months ago by XperiAndri

Download any Per Monitor DPI sample and play with it

comment:18 in reply to: ↑ 14 Changed 20 months ago by alexmarsev

Replying to XperiAndri:
You are free to not believe me, but implementing per-monitor dpi support in mpc-hc is certainly not trivial. You have to override/hack big chunks of MFC in order to support it properly, because MFC has no per-monitor awareness whatsoever.

comment:19 Changed 20 months ago by clsid2

https://msdn.microsoft.com/en-us/library/dd464659.aspx

The WM_DPICHANGED window notification is sent to per-monitor DPI–aware applications when a window’s position changes such that most of its area intersects a monitor with a DPI that is different from the DPI before the position change.

Then just redraw the window?

comment:20 Changed 20 months ago by XperiAndri

Not exactly.

  1. update layout, i. e. multiply by DPI difference every value on UI. Better to multiply defaults by DPI scale value (%).
  2. swap resources, i. e. images to better quality depending on new DPI

comment:21 follow-up: Changed 20 months ago by alexmarsev

Layout is the problem. We have most of our interface in dialog templates. Even if we bypass MFC completely and recreate(!) dialogs by direct call to CreateDialogIndirect(), it will use system dpi for dialog unit to screen pixel conversion. Unless there's a way to circumvent that, I don't see how we can support per monitor dpi in any sane manner.

comment:22 in reply to: ↑ 15 Changed 20 months ago by nevcairiel

Replying to alexmarsev:

Replying to nevcairiel:
I'm more worried about setups like high-dpi laptop connected to low-dpi external screen. Wouldn't that make mpc-hc look huge on external screen?

Not really, it would make MPC-HC look tiny on the high-dpi laptop, which it would be anyway if there is no "mixed" DPI environment, and look "normal" on the external screen.

comment:23 in reply to: ↑ 21 ; follow-up: Changed 20 months ago by clsid2

Replying to alexmarsev:

Layout is the problem. We have most of our interface in dialog templates. Even if we bypass MFC completely and recreate(!) dialogs by direct call to CreateDialogIndirect(), it will use system dpi for dialog unit to screen pixel conversion. Unless there's a way to circumvent that, I don't see how we can support per monitor dpi in any sane manner.

Don't the API calls return the DPI of the parent screen after nev's patch?

comment:24 in reply to: ↑ 23 Changed 20 months ago by alexmarsev

Replying to clsid2:

Don't the API calls return the DPI of the parent screen after nev's patch?

His patch enables rendering at main display dpi (actually not main, but what Windows decides as "system" dpi) and disables DWM auto-scaling performed on other displays.

comment:25 Changed 20 months ago by alexmarsev

In 4e48e2:

Update Changelog.txt

Refs #3356

comment:26 Changed 20 months ago by alexmarsev

I have a rather hacky way to implement per monitor dpi scaling properly in mind, maybe we will support it somewhere soon.

The way is:
Read dialog template into memory, adjust dialog font size in template header (it is used in DLU calculation together with system dpi), destroy/create dialog window without destroying dialog object as we have data that we want to preserve in it, repeat for every toolbar and panel.

comment:27 Changed 20 months ago by alexmarsev

In 2e378a:

Initial support for per-monitor dpi

Refs #3356

comment:28 Changed 20 months ago by alexmarsev

Current status:

  1. Toolbars, Playlist and Subresync scale alright
  2. Icon autoscaling is currently being worked on
  3. Titlebar and menubar do not scale, it's Windows limitation, unless we draw them ourselves.
  4. Popup menu do not scale, same as (3)
  5. Other panels and dialogs do not scale, they're template-based and need custom hacks. Maybe someone else will be interested in doing them - currently I'm not.
Note: See TracTickets for help on using tickets.