Bug 418086

Summary: Okular starts over rendering preview of page when scrolling
Product: [Applications] okular Reporter: postix <postix>
Component: generalAssignee: Okular developers <okular-devel>
Status: RESOLVED FIXED    
Severity: normal CC: aacid, nate, postix
Priority: NOR    
Version: 1.9.2   
Target Milestone: ---   
Platform: Other   
OS: Linux   
Latest Commit: Version Fixed In: 19.12.3
Attachments: Screen recording

Description postix 2020-02-23 11:44:18 UTC
Created attachment 126334 [details]
Screen recording

SUMMARY

When I opened a PDF (21 MB) with huge images, which took some time to render, I noticed that the preview first starts to be generated after the actual page has been rendered completely. 

This could probably be done in a second thread simultaneously or the preview could make use of the already rendered page.

However, it seems that, as long as the preview rendering did not finish, the preview is rendered from the very beginning whenever the user scrolls a little bit in the PDF -- a few pixel or a scroll event seem to be enough.

Please take a look at the screen recording. The preview starts rendering at T = 30 s.

SOFTWARE/OS VERSIONS
Operating System: Manjaro Linux 
KDE Plasma Version: 5.17.5
KDE Frameworks Version: 5.67.0
Qt Version: 5.14.1
Kernel Version: 5.5.2-1-MANJARO
OS Type: 64-bit
Processors: 4 × Intel® Core™ i7-7500U CPU @ 2.70GHz
Memory: 15,4 GiB

Additional Information:
RAM usage: Greedy
Rendering: Anti-Aliasing, Hinting, Transparency Effects
Comment 1 Albert Astals Cid 2020-02-23 11:57:15 UTC
Can we have such a file?
Comment 2 postix 2020-02-23 12:03:59 UTC
I uploaded the PDF and send you a link to your mail address.
Comment 3 Albert Astals Cid 2020-02-23 18:07:49 UTC
ok, i can see this and i know what's wrong, need to think how to fix it.
Comment 4 Albert Astals Cid 2020-02-23 23:20:57 UTC
In case you know how to compile from git proposed solution at https://invent.kde.org/kde/okular/-/merge_requests/125
Comment 5 postix 2020-02-24 12:39:01 UTC
(In reply to Albert Astals Cid from comment #4)
> In case you know how to compile from git proposed solution at
> https://invent.kde.org/kde/okular/-/merge_requests/125

I tried it as follows:

git clone https://github.com/KDE/okular.git
cd okular
git fetch "https://invent.kde.org/aacid/okular.git" "fix_unneeeded_rerendering"
git checkout -b "aacid/okular-fix_unneeeded_rerendering" FETCH_HEAD
git fetch origin
git checkout "origin/release/19.12"
git merge --no-ff "aacid/okular-fix_unneeeded_rerendering"

mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=debug -DCMAKE_INSTALL_PREFIX=~/.local
make -j4
./shell/okular

Then I loaded the problematic PDF, which opened at page 6 as Okular seems to use the settings of the package installed Okular.

Result: 
1) Okular first rendered slowy the very big images on page 6
2) Then it rendered the rest very quickly
3) It started rendering the previews

Unfortunately, moving the viewport still resulted in re-rendering of 3). :-(

Or maybe I am doing something wrong here.
Comment 6 postix 2020-02-24 14:07:29 UTC
OT: Side note, with the debug build as desribed above and the problematic PDF, I see the following in the terminal output:

Bogus memory allocation size
Bogus memory allocation size
Bogus memory allocation size
(~20x more)

Is that something to fix? The RAM does actually not fill up, it just throws those errors.
Comment 7 Albert Astals Cid 2020-02-24 18:01:12 UTC
(In reply to Postix from comment #5)
> (In reply to Albert Astals Cid from comment #4)
> > In case you know how to compile from git proposed solution at
> > https://invent.kde.org/kde/okular/-/merge_requests/125
> 
> I tried it as follows:
> 
> git clone https://github.com/KDE/okular.git
> cd okular
> git fetch "https://invent.kde.org/aacid/okular.git"
> "fix_unneeeded_rerendering"
> git checkout -b "aacid/okular-fix_unneeeded_rerendering" FETCH_HEAD
> git fetch origin
> git checkout "origin/release/19.12"
> git merge --no-ff "aacid/okular-fix_unneeeded_rerendering"
> 
> mkdir build && cd build
> cmake .. -DCMAKE_BUILD_TYPE=debug -DCMAKE_INSTALL_PREFIX=~/.local
> make -j4
> ./shell/okular
> 
> Then I loaded the problematic PDF, which opened at page 6 as Okular seems to
> use the settings of the package installed Okular.
> 
> Result: 
> 1) Okular first rendered slowy the very big images on page 6
> 2) Then it rendered the rest very quickly
> 3) It started rendering the previews
> 
> Unfortunately, moving the viewport still resulted in re-rendering of 3). :-(
> 
> Or maybe I am doing something wrong here.

Yes you are, please see the end of https://okular.kde.org/download.php
Comment 8 postix 2020-02-24 19:09:28 UTC
(In reply to Albert Astals Cid from comment #7)
> Yes you are, please see the end of https://okular.kde.org/download.php

If I try to execute ~/.local/bin/okular it only writes a memory dump. :-/

source build/prefix.sh; ./build/okular seems to still load the wrong libraries and settings.

I am afraid someone else has to evaluate it until I find the time to find the error on my side.
Comment 9 Albert Astals Cid 2020-03-02 21:20:42 UTC
Git commit 81c005710cdbb23f9ed9ebcc4aee4db69d33434d by Albert Astals Cid.
Committed on 02/03/2020 at 21:06.
Pushed by aacid into branch 'release/19.12'.

Fix re-rendering of images when using partial updates

Partial updates trigger when the page is taking "too much" to render (>
500 ms).

When this happens we store a pixmap for the page, this meant that
Page::hasPixmap returned true, so when moving the viewport around we
would think that that page was already rendered, and thus needed no
rendering so we didn't add it to the list of requested pixmaps.

Then on document when seeing the new list of requested pixmaps we would
go and check and say "oh there's one request going on that we don't want
anymore, let's cancel it", so we would cancel the page that we actually
wanted (and clear the partial pixmap)

Then on the next scroll we would realize we did not have that page
pixmap and then request it again which since it's the current page would
immediately stop all other renders and start this one.

Then we would get a temporary pixmap and the loop of cancellations and
requesting again would keep happening as long as the user moved the
viewport.

We fix that my making hasPixmap return false if the pixmap we have is a
partial one, because that's what the function meant "forever" until we
recently introduced partial updates so all the calls to hasPixmap
actually mean "hasNonPartialPixmap"

M  +6    -0    core/page.cpp
M  +2    -1    core/page.h
M  +1    -0    core/page_p.h

https://invent.kde.org/kde/okular/commit/81c005710cdbb23f9ed9ebcc4aee4db69d33434d