xbmc / Official-Kodi-Remote-iOS

Full-featured remote control for XBMC Media Center. It features library browsing, now playing informations and a direct remote control.
Other
221 stars 104 forks source link

Rework pre-scaling / caching of images #1176

Open wutschel opened 13 hours ago

wutschel commented 13 hours ago

While analyzing memory consumption I also found some more interesting facts on the behaviour when caching pre-scaled images.

Memory impact of color space creation and scaling

If an image dimension is not changed (image and target resolution are identical), high memory consumption is driven by creating a new color space via CGColorSpaceCreateDeviceRGB(). If, in case of identical target/image resolution, no new color space is created, e.g. when the correct color space is already given, the memory consumption is far less (hundreds of MBs less for about 400 thumbs). But, once rescaling to a different resolution is done, this does not matter anymore. The memory consumption is always high in this case. Nothing I can do about it as far as I can see.

Pre-scaling done only half-way

What I realized, after working in-depth / reviewing the implementation, is, that thumb images are not really fully scaled to the target resolution, which would require content fill method to be taken into account at this stage. In fact, the image's aspect ratio is kept, and the thumbs are only scaled half-way to meet to minimum resolution requirements. Examples:

This will cause some scaling still do be processed by UIImageView, if target and image have different aspect ratios. My assumption is that this might cause some of the stuttering reported by users. It also causes the memory and flash consumption to be higher than desired as, in case of mismatching aspect ratios, always more pixels are kept as required.

Impact of UIImageView scaling

I reworked the pre-scaling, which also allows to remove doubled code, and to reduce the flash size of the image cache. But there are (slight) differences in image quality when doing all scaling in advance (using CGContextDrawImage(...)), which removes the scaling part of UIImageView. Obviously the CG scaling results in smoother results (more interpolation, less aliasing), whereas the UI scaling at first glance results in a sharper image.

When improving UIImageView's the scaling method by setting

imageview.layer.minificationFilter = kCAFilterTrilinear;
imageview.layer.magnificationFilter = kCAFilterTrilinear;

this visual differences become less prominent. I take this as sign that the standard UI scaling shows some ringing or undesired granularity, and not more details. Still I prefer the UI trilinear scaling over what CG scaling achieves. But to reduce the load and stutter via scrolling the pre-scaling is needed, and using trilinear UI scaling is counter productive.

Screenshots: Bildschirmfoto-2024-10-27-um-11-19-09

Edit: To put the above zoomed images into full context: https://ibb.co/30czCwP

kambala-decapitator commented 10 hours ago

honestly, I don't see any difference in the images at all =)

wutschel commented 8 hours ago

honestly, I don't see any difference in the images at all =)

There is -- subtle, but visible. Just open full size image (click the link, and then enlarge to full resolution). I know our testers :)