Project

General

Profile

Actions

Feature #1033

open

Preload icons

Added by Hammel about 1 year ago. Updated about 1 year ago.

Status:
In Progress
Priority:
Normal
Assignee:
Target version:
Start date:
10 Sep 2023
Due date:
% Done:

20%

Estimated time:
Severity:
02 - High

Description

do_carousel_drawing() loads images as it needs them. This can bog down moving through the list.

To fix this, readDB() should read the image at the time the db is being created. It should also scale the icons.

To help speed up start time, only the first 50 (or 100 or whatever) should be loaded. The rest will be loaded in the background with a g_idle_add() function.

This will simplify musicfe.c:do_carousel_drawing() by removing the image load section and thus speed up processing.

References:
  1. https://www.baeldung.com/linux/gui
  2. https://www.cs.nmsu.edu/~joshagam/archive/cs574/3-dri.html
  3. https://unix.stackexchange.com/a/733390
  4. https://www.khronos.org/opengl/wiki/Platform_specifics:_Linux
  5. https://dri.freedesktop.org/wiki/
  6. https://en.wikipedia.org/wiki/Direct_Rendering_Manager
  7. https://en.wikipedia.org/wiki/Direct_Rendering_Infrastructure
Actions #1

Updated by Hammel about 1 year ago

  • Severity changed from 04 - Low to 02 - High
Actions #2

Updated by Hammel about 1 year ago

  • Description updated (diff)
Actions #3

Updated by Hammel about 1 year ago

This isn't as easy at it seems. Consider

  1. If there are 1000's of images, that could take 100's of MB of memory to pre-allocate the images.
  2. If we only allocate a few, which few do we allocate?
    1. What if the user searches for albums/artists - do we redo the preallocations? Won't that just slow things down too?

The way it works now is that 5 images are selected with 2 on either side of the active selection. Those five are loaded each time. It's relatively fast but could benefit from 2D acceleration (re: OpenGL again).

A short term alternative would be to cache the images and only load new ones on either end as the carousel spins. And don't allow the user to hit next/prev too fast - disable key presses while drawing. That may give the appearance of better performance.

For more help with OpenGL/etc, see the Adding OpenGL to Cairo issue. In particular, this discussion suggests that an X program can just create an empty window and provide the size and offsets to DispmanX to do the rendering. DispmanX will be displayed above the X window, which means you could interleave the two windows.

Actions #4

Updated by Hammel about 1 year ago

Side note: The cover art database is made up of png files because the genid3db.sh outputs them as png files. So I only need a PNG loader

Actions #5

Updated by Hammel about 1 year ago

  • Description updated (diff)
Actions #6

Updated by Hammel about 1 year ago

Another side note: All HDMI connected boards have /dev/dri/card0. The RPi LCD and TFT displays do not have this device file. /dev/dri/card0 is the DRM interface. The reason it's missing on RPi LCD and TFT's is because either firstboot or lcdshow removes the dtoverlays for vc4-fkms-v3d*.

Actions #7

Updated by Hammel about 1 year ago

  • Severity changed from 02 - High to 03 - Medium
Actions #8

Updated by Hammel about 1 year ago

  • Status changed from New to In Progress
  • % Done changed from 0 to 10

MusicFE is the initial target for this, since it has the simplest interface to update. There is a branch of in my sandbox called "feature/rm1033" for this work.

So the following links are the best to learn how to do this.

Also: This forum post gives the details of the current state of display graphics on Raspberry Pi.

The triangle.c demo is actually just about all I want. The init_ogl() function is what maps OpenGL surfaces to DispmanX, then OpenGL commands are used to transpose images on the display. When DispManX is retired fully (on 32bit builds, which is all Pibox is using right now) the transition should be simple since it's just the mapping function that will need updating (and the exit function, come to think of it).

The trick in the init_ogl() is to use the size of the GTK+ window where the musicfe carousel is displayed instead of the full display. For experimentation, initially I'll use the full display just to make sure the code is working and keyboard input works.

The first thing to do is duplicate the triangle code and initialize it running with a timer, just to see it work inside of musicfe.

Actions #9

Updated by Hammel about 1 year ago

  • Severity changed from 03 - Medium to 02 - High
Actions #10

Updated by Hammel about 1 year ago

Code is ported and ready to test. If I understand this correctly, the EGL will be displayed under the X, but I think that only works if I set the layer the EGL should be on with DispmanX.

Actions #11

Updated by Hammel about 1 year ago

  • % Done changed from 10 to 20

That code didn't work for some reason. It didn't crash anything, but nothing displayed. So I switched to the clouds demo. This was even simpler code and it integrated easily into musicfe. I'm able to animate a cloud using DispmanX over the Cairo-based carousel. The difference between the two is that the former wrapped OpenGL in with DispmanX while the latter was strictly DispmanX.

I also read the forum post for the current state of graphics on Raspberry Pi. Since I rely on omxplayer, I'm required to stick to 32bit builds. And since I'm required to do that, it doesn't really hurt me to stick to using DispmanX. I did try the OpenGL code but as mentioned, it didn't work (might have been missing drivers?).

For now, I'm going to convert to using dispmanX and a Plex-style interface instead of the carousel. I will leave the Cairo-base carousel as a build option, however, should I decide to use this on non-Raspberry Pi hardware. I should also mirror the userland repo in case that goes away for some reason.

Actions #12

Updated by Hammel about 1 year ago

Need a step-by-step plan for this.

  1. Update demo to accept GTK+ window size and offset instead of using full screen.
  2. Refactor do_carousel_drawing()
    1. Get 5 images
      1. Only parse JSON data.
      2. pointer to data struct array
    2. Allocate Cairo images vs DispmanX resources
    3. Compute scaling and positioning
    4. Draw Cairo vs DispmanX
  3. Free/cleanup data struct array
Actions #13

Updated by Hammel about 1 year ago

Some things I'm learning while working on that plan.

  • dispmanx has no native file loading.
  • Each image in the carousel is a dispmanx resource
  • Only create 1 new resource, no matter the direction the carousel moves
    • vc_dispmanx_element_change_source() can swap sources, just remember are we moving down or up in the carousel.

This would really be better done with OpenGL but I couldn't get that to integrate - maybe I need to make sure I'm linking against -lbrcmGLESv2 -lbrcmEGL? But OpenGL doesn't load PNG files natively either.

Actions #14

Updated by Hammel about 1 year ago

  • Priority changed from Immediate to Normal

It's unclear if doing this brings any added value right now.

Moving back down the priority list. I'll revisit later, if necessary.

Actions

Also available in: Atom PDF