DocumentView class in an embedded device.

Asked by Michael Klank

I use your DocumentView class in an embedded device with limited memory. If the PDF document is to big, it runs out of memory. Do you have any suggestions to solve this problem. I.e. to have not all pages rendered in the list or so?

Question information

Language:
English Edit question
Status:
Answered
For:
qpdfview Edit question
Assignee:
No assignee Edit question
Last query:
Last reply:
Revision history for this message
Adam Reichold (adamreichold) said :
#1

Hello Michael,

As a hobbyist programmer with no experience in embedded development, please have a bucket of salt ready before reading this...

The program obviously was not designed with really (meaning less than small desktop systems) limited memory use in mind, e.g. always carrying around a separate QGraphicsView for thumbnails in case the user wants to see those and the thumbnail items having all the data of the page items present even though they don't use most of it. So you might have a hard time with this. (Removing everything connected to the thumbnails may be one simpler step to reduce memory requirements by a constant factor. But that is probably not really what you need.) (Same goes for outline and properties if you don't need them. All of this could probably be done using preprocessor directives.)

The problem with the page items themselves is probably not so much the rendering since this is done on demand anyway and its memory requirements are more or less (but not strictly because of the threading) fixed to image buffers for the visible pages which are released after they are painted. At least if the cache size (PageItem::setCacheSize) is zero and prefetch (Document::setPrefetch) is disabled.

The problem is more that the document view assumes to have all page positions and sizes (i.e. bounding rectangles) available at once. This is used extensively to determine layout and visibility, e.g. in DocumentView::prepareScene, ::prepareView and ::on_verticalScrollBar_valueChanged... I doubt that the design is flexible enough to fundamentally change this. Just loading the meta-data of a few pages at once and layouting them is probably just not possible with the current design. Sorry for this. (Again, you could try to get a constant factor reduction by stripping unused parts from PageItem like annotations and such but the memory scaling will be the same...)

A long-term solution might be to use QGraphicsGridLayout to do the layout dynamically for a few pages only but this will be quite a lot of work. Sorry for not being able to be more helpful at the moment. Of course, we can continue to discuss this if you decide on attacking this in some way or the other.

Best regards, Adam.

Revision history for this message
Adam Reichold (adamreichold) said :
#2

By the way, the default page cache size is 32 MB which strikes me a quite generous. :-) So make sure to call PageItem::setCacheSize(cacheSizeInByteAndPossibilyZero) before using the document view... (Another memory usage problem is that the program will always rendering whole pages and not just the visible parts, so even the temporary buffers can be quite large at high resolutions and scale factors and the cache will only be useful if is able to contain at least one page (page width * page height * (dpi/27 * scale)^2 * depth).)

Revision history for this message
Adam Reichold (adamreichold) said :
#3

Doh! My first sentence should have begun with "As I am a hobbyist programmer...". No insult intended. ;-)

Revision history for this message
Michael Klank (michael-klank) said :
#4

Hello Adam,

thanks for your answer. This is no problem. So I want to adapt this problem if you want.
May be I can find a solution which fits for almost all targets.

"A long-term solution might be to use QGraphicsGridLayout to do the layout dynamically for a few pages only but this will be quite a lot of work."

I think this is the biggest task and the main problem. So I try to find a solution.

Thanks!

Revision history for this message
Adam Reichold (adamreichold) said :
#5

If you are diving into this, you might want to consider joining the "qpdfview" team at "https://launchpad.net/~qpdfview" to use its mailing list for future discussions.

Revision history for this message
Adam Reichold (adamreichold) said :
#6

After thinking about this some more, are you absolutely sure that the memory usage of the PageItem classes themselves in contrast to the temporary image buffers PageItem::m_image or the memory usage of the SplashOutputDev used by the poppler-qt4 frontend is the actual problem?

(One user reported that certain documents drive the SplashOutputDev to consume several hundred megabytes of memory leading to enormous memory consumption of both qpdfview and Okular whereas Evince was fine since it uses the CairoOutputDev...)

You should be able to find this out if you replace lines 807 to 817 in pageitem.cpp by something like
"image = QImage(1, 1, QImage::Format_ARGB32); image.fill(Qt::white);" in a current version qpdfview's trunk to suppress rendering.

Can you help with this problem?

Provide an answer of your own, or ask Michael Klank for more information if necessary.

To post a message you must log in.