Bug 362856 - HiDPI: Wrong render resolution with display scaling
Summary: HiDPI: Wrong render resolution with display scaling
Status: RESOLVED FIXED
Alias: None
Product: okular
Classification: Applications
Component: general (show other bugs)
Version: unspecified
Platform: Other Linux
: NOR normal
Target Milestone: ---
Assignee: Okular developers
URL:
Keywords:
: 372899 374207 385200 386215 (view as bug list)
Depends on:
Blocks:
 
Reported: 2016-05-09 16:33 UTC by Yi Yang
Modified: 2017-10-26 17:20 UTC (History)
34 users (show)

See Also:
Latest Commit:
Version Fixed In:
Sentry Crash Report:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Yi Yang 2016-05-09 16:33:33 UTC
KDE 5 includes a new feature, "scale display", for better support for high resolution screens. To enable it, go to settings > Display and Monitor > Display Configuration > Scale Display.

I use a 4K screen and I enabled 1.5x scale display.

I noticed that all PDFs are rendered in a way that looks extremely bad. A closer look reveals that the PDF is somehow rendered in a way, so that the rendered bitmap consists of 2x2 regions of the same color. In other words, Okular rendered PDFs with 1/2 of actual resolution.

I tried to dive into the source code. Apparently, the render resolution is decided  then sent to the PDF module via a PixmapRequest. Therefore, I guess this is not only a PDF problem, but a global one, hence the general component instead of PDF backend in this bug report.

The geometry sent in PixmapRequest comes from uncroppedWidth() & uncroppedHeight(), which in turn come from m_uncroppedGeometry. The calculation of m_uncroppedGeometry looks somewhat magical, which is where I stop looking at the code and decide to write a bug report instead...

The KDE5 Scale display feature is the most possible cause of this problem. However, I'll happily give you more information if that's needed for diagnosing this bug. 

Reproducible: Always

Steps to Reproduce:
1. Enable KDE 5 scale display.
2. Open Okular, open a PDF.
3. Look at how text is rendered (other things are also affected, but text is more important and ubiquitous)

Actual Results:  
Okular renders at half of actual resolution, then scale the result, producing poor results.

Expected Results:  
Okular renders at actual resolution.
Comment 1 Luigi Toscano 2016-05-09 16:36:20 UTC
You set [Frameworks] in the topic, is this the Frameworks version of Okular? What happens with the supported version (kdelibs4)?
Comment 2 Albert Astals Cid 2016-05-09 22:41:58 UTC
There's no such thing called KDE 5
Comment 3 Yi Yang 2016-05-10 12:50:01 UTC
To be honest, your terminology change from KDE 3 to KDE SC 4 to {Insert a myriad names here} 5 is absolutely terrible. I have no idea how to even call it.

And, yes, i checked and it is Plasma 5. I didn't know systemsettings is part of Plasma instead of kdelibs or KF. It's kind of counterintuitive. Why should I, as a user instead of a KF/Plasma/Kdelibs developer, know about this though? :|
Comment 4 Yi Yang 2016-05-10 12:53:12 UTC
Luigi, yes, I am using the Frameworks version of Okular. To be sure this bug is still around I even git pull'ed and compiled it again. So to be precise I'm reporting the newest version of frameworks branch is still having this resolution problem.

I will try the kdelibs4 version of Okular and report back. I don't remenber my KDE SC 4 comes with "scale display" option though. Maybe I need a full system upgrade or something.
Comment 5 Albert Astals Cid 2016-05-10 22:17:12 UTC
> To be honest, your terminology change from KDE 3 to KDE SC 4 to {Insert a myriad names here} 5 is absolutely terrible. I have no idea how to even call it.

Call what? Okular? You call it Okular :)

> Why should I, as a user instead of a KF/Plasma/Kdelibs developer, know about this though? :|
You should not, just don't call it KDE5, call it Okular or Plasma or systemsettings.

> I will try the kdelibs4 version of Okular and report back. I don't remenber my KDE SC 4 comes with "scale display" option though. Maybe I need a full system upgrade or something.
Okular is independent on the desktop you use, you can use Okular based on kdelibs4 just fine on Plasma 5, in fact, it's the recommended thing to do.
Comment 6 Yi Yang 2016-05-11 03:08:50 UTC
Every application is, in principle, independent of the desktop environment I use.

However, when I'm reporting a bug, I'm trying to include information about my DE. I think this makes sense. In principle they are independent. But when you have a bug, you are no longer so sure.

Anyway, I'll definitely try KDE Plasma 4 + KDElibs4/Okular & KDE Plasma 5 + KDElibs4/Okular some time later and report back. Last night (as in GMT+8 timezone) I had less free time than expected, so sorry no experiment results for now.
Comment 7 Yi Yang 2016-05-12 03:41:54 UTC
OK. I tried KDE Plasma 4 + Kdelibs4/Okular. There were no render resolution problem.

That said, there were no "scale display" option in systemsettings in this setup. So this might indeed be the difference.
Comment 8 Yi Yang 2016-05-12 17:54:34 UTC
OK, I digged the source code a bit more.

The DPI calculation code at core/utils.cpp line 63-81 returned (93.6, 93.6), while my actual DPI, as reported by Xorg.log, is (187, 189). Apparently QScreen::physicalDotsPerInchX() and QScreen::physicalDotsPerInchY() are returning something not quite physical, when Plasma 5 "scale display" gets enabled.
Comment 9 Luigi Toscano 2016-05-12 18:04:05 UTC
David, any idea?
Comment 10 Yi Yang 2016-05-17 16:27:53 UTC
A wild guess: the environment variable QT_AUTO_SCREEN_SCALE_FACTOR or QT_SCALE_FACTOR is used by Plasma 5 "scale display" functionality.
Comment 11 Yi Yang 2016-05-22 14:45:54 UTC
By reading more documents and doing more experiments, things are now clear.

Qt 5.6 introduces a new option, called "High DPI Scaling", which is both controllable form environment variables and application-wise options (Qt::AA_EnableHighDpiScaling and Qt::AA_DisbleHighDpiScaling). This gives us solution A: temporarily force Qt::AA_DisbleHighDpiScaling. This solution does uglify menus and icons, though.

The more complex solution B needs more code refactoring. The key is to realize that you are using "device-independent geometry" while the pixmap inside QPixmap are using real physical values. You need to get this magical value from QScreen::devicePixelRatio() and set them to QPixmap::setDevicePixelRatio(). This step might be simplified by "Qt::AA_UseHighDpiPixmaps". I'm not sure, the documentation here isn't clear.

But the even harder part is you need to rewrite the image rotation and cropping code, since now you are cropping the image to (widget size * devicePixelRatio()). It's a bit tricky and many code in different locations made the assumption that widget size = the pixmap size in it, which no longer holds and thus broken code is scattered everywhere.
Comment 12 Yi Yang 2016-05-22 14:47:00 UTC
Relevant documentations:
relevant flags: http://doc.qt.io/qt-5/qt.html
QScreen and QPixmap with their new addition in Qt 5.5 or 5.6:
http://doc.qt.io/qt-5/qscreen.html
http://doc.qt.io/qt-5/qpixmap.html
Comment 13 Yi Yang 2016-06-19 16:11:37 UTC
Hi all,

I upgraded to Plasma 5.6 today. It seems to be handling hi-res screens in a new way (by handling font DPI better it seems), so that the "scale display" option is no longer needed in most common cases. Therefore, even if the Okular bug still exists, its severity becomes even lower.

I'm not sure if this means this bug should be closed. I leave that to your decision. But I think it's my duty to report on the progress. Thank you for all your hard work, people ;)
Comment 14 Antoine Poliakov 2016-07-11 13:05:47 UTC
Hi, I'm experiencing the same bug, with Qt 5.7, Plasma 5.7, Frameworks 5.23.
I confirm the problem is not specific to PDFs, but happens with all document/image rendering in okular. The content appears as though it is rendered in a buffer sized according to the number of *logical pixels* in the viewport - which is less than *physical pixels* in the case of hidpi displays with QT_AUTO_SCREEN_SCALE_FACTOR=1. When this buffers gets displayed, it's scaled with nearest interpolation, producing ugly large square pixels.
Comment 15 Aleix Pol 2016-10-29 12:52:41 UTC
I can reproduce, launching with `QT_SCALE_FACTOR=2 okular` on a regular screen reproduces.
Comment 16 Albert Astals Cid 2016-11-25 23:39:04 UTC
*** Bug 372899 has been marked as a duplicate of this bug. ***
Comment 17 Michael K. 2016-12-17 20:12:14 UTC
Same problem here.

- 5K monitor
- QT_SCREEN_SCALE_FACTORS=2
- QT_AUTO_SCREEN_SCALE_FACTOR=0
- xdpyinfo | grep resolution
  resolution:    215x215 dots per inch

I have just upgraded to the new release of KF5/plasma which includes KF5-based okular. Documents look as if they were rendered at lower resolution and then upscaled. The irony is that the kdelibs4-based okular rendered documents properly -- at native resolution -- as it was not aware of scaling. (the UI elements were half-sized though, which was a bit annoying)

This seems to affect every backend. (I've tried PDF, ePub and Mobi)
Comment 18 Michael K. 2016-12-17 20:50:44 UTC
Unsetting the above env variables (QT_...) restores old (kdelibs4-based) behavior/rendering.
Comment 19 Antoine Poliakov 2016-12-26 18:14:11 UTC
Not sure if this helps, but Gwenview has the exact same issue, and apparently there's a 5 line patch that fixes is, here: https://bugs.kde.org/show_bug.cgi?id=373178#c1
Since it the same issue and (from the outside) the Gwenview and Okular seem similar, maybe the same fix may be applied ?
Comment 20 Albert Astals Cid 2016-12-28 11:38:30 UTC
*** Bug 374207 has been marked as a duplicate of this bug. ***
Comment 21 Christoph Cullmann 2017-01-08 14:39:05 UTC
I did take a look, IMHO the problem (beside the missing 

   // These attributes must be set before a Q(Gui)Application is constructed.
+    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
+    QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);

calls) is that the generators render the stuff in a QImage but that has not set the right scale factor nor dimensions.

During writing our company PDF helper viewer (https://github.com/AbsInt/FirstAid), I run into the same issue with libpoppler and altered our rendering code to:

            /**
             * we render in too high resolution and then set the right ratio
             */
            cachedPage = new QImage(page->renderToImage(resX() * devicePixelRatio(), resY() * devicePixelRatio(), -1, -1, -1, -1, Poppler::Page::Rotate0));
            cachedPage->setDevicePixelRatio(devicePixelRatio());

This did the trick, unfortunately Okular is more complex than our toy program therefore I am not that sure where to adjust that :/
Comment 22 Alexey Shiklomanov 2017-01-11 15:58:47 UTC
Can confirm this bug on latest version of KDE Plasma and Okular on Arch Linux (main repositories, not AUR git versions).

While this is getting fixed by the developers, just wanted to point out that a hacky temporary solution is to adjust the Okular `.desktop` files with the QT_SCREEN_SCALE_FACTORS environment variable. I used a command like:

sed -i 's/Exec=okular/Exec=QT_SCREEN_SCALE_FACTORS=1 okular/g' /usr/share/applications/*okular*

...to adjust all of them at once. Definitely not a permanent solution, but I found it to be a convenient fix that doesn't require rebuilding Okular.
Comment 23 Antoine Poliakov 2017-01-11 16:21:10 UTC
Interesting, I have the same version (current arch linux) as Alexey, and QT_SCREEN_SCALE_FACTORS=1 has no visible effect for me.

QT_SCREEN_SCALE_FACTORS=1 QT_AUTO_SCREEN_SCALE_FACTOR=1 okular

does the same pixelated render as

QT_AUTO_SCREEN_SCALE_FACTOR=1 okular

On the other hand, running

QT_SCREEN_SCALE_FACTORS=1 QT_AUTO_SCREEN_SCALE_FACTOR=0 okular

renders the document correctly, same as

QT_AUTO_SCREEN_SCALE_FACTOR=0 okular

but of course then the menu, toolbars and controls in general are all wrong (on a hidpi screen).
Comment 24 Michael K. 2017-01-11 16:27:17 UTC
Here is the script that I am using (also on Arch Linux):

#!/bin/sh
unset QT_SCREEN_SCALE_FACTORS
unset QT_AUTO_SCREEN_SCALE_FACTOR
okular "$*"
Comment 25 Willie Koomson 2017-02-08 00:37:49 UTC
(In reply to Alexey Shiklomanov from comment #22)
> Can confirm this bug on latest version of KDE Plasma and Okular on Arch
> Linux (main repositories, not AUR git versions).
> 
> While this is getting fixed by the developers, just wanted to point out that
> a hacky temporary solution is to adjust the Okular `.desktop` files with the
> QT_SCREEN_SCALE_FACTORS environment variable. I used a command like:
> 
> sed -i 's/Exec=okular/Exec=QT_SCREEN_SCALE_FACTORS=1 okular/g'
> /usr/share/applications/*okular*
> 
> ...to adjust all of them at once. Definitely not a permanent solution, but I
> found it to be a convenient fix that doesn't require rebuilding Okular.

Modifying the environment variable QT_SCREEN_SCALE_FACTORS=1 in the desktop file also works for me. Am on Arch Linux, kde5, repo version, and i was having the same issue as the others
Comment 26 e.ekmecic 2017-04-21 14:05:41 UTC
I've found that setting XServer DPI manually fixes these fractional scaling problems.
On my 2560x1440 display I use a DPI of 144 (i.e. a scaling factor of 1.5x), which caused problems in regular Qt programs, the lockscreen, shutdown/logout/suspend dialog, Okular etc.

To fix this, added "-dpi 144" to ServerArguments in my sddm.conf and set display scaling back to 1.0x.
This makes KDE and all Qt programs scale flawlessly but GTK programs (i.e. Firefox) remain unscaled which is an acceptable tradeoff for me.
Comment 27 Giuseppe Ghibò 2017-04-25 13:43:41 UTC
I'm using the DPI forced to 282 but I get this problems too when using QT_AUTO_SCREEN_SCALE_FACTOR=1 which I use as default; forcing QT_AUTO_SCREEN_SCALE_FACTOR=0 before calling okular of course doesn't cause the loss of resolution but in that case fonts menus and especially widgets (scroll bars) aren't scaled properly.
Comment 28 LuHe 2017-05-27 10:54:37 UTC
I'm going to be working on this as part of my Google Summer of Code 2017 project, more details can be found here: https://summerofcode.withgoogle.com/projects/#4835460277862400 and https://drive.google.com/open?id=0BwXqDXwyptm8eEo5bjdZRzZTQkk
Comment 29 LuHe 2017-05-27 10:56:22 UTC
I'm going to be working on this as part of my Google Summer of Code 2017 project, more details can be found here: https://summerofcode.withgoogle.com/projects/#4835460277862400 and https://drive.google.com/open?id=0BwXqDXwyptm8eEo5bjdZRzZTQkk
Comment 30 Oskar Kirmis 2017-06-11 16:52:24 UTC
I am having the same issue as in #374207 (which has been marked as a dup) with okular but the behavior is quiete strange:

 - ScaleFactor=1.0, start okular -> ok
 - Scale up to 1.5, start okular -> ok, correctly scaled up and looking sharp
 - Log out, log in again, start okular -> blurry

Hope it helps tracking down the bug.
Comment 31 Christoph Feck 2017-09-29 12:04:38 UTC
*** Bug 385200 has been marked as a duplicate of this bug. ***
Comment 32 null 2017-09-29 12:20:30 UTC
See https://phabricator.kde.org/D6268 to track progress.
Comment 33 Nate Graham 2017-10-15 02:39:52 UTC
HiDPI support landed today with https://cgit.kde.org/okular.git/commit/?id=ecc1141e0293e1a30e0f8787d86dcc6309ffb0c0
Comment 34 Nate Graham 2017-10-26 17:20:51 UTC
*** Bug 386215 has been marked as a duplicate of this bug. ***