Skia performance when loading a "larger" amount of images

Hey, I am currently evaluating gamma/skia for a potential future project, where I need to load a larger amount of images. Up to certain point the performance in skia is fine but then it suddenly caves.

The machine I am testing on:

  • Wind 10 Pro x64

  • vvvv gamma 2020.1.7

  • vvvv beta 40 with latest DX11

  • Core I7-8700

  • 32GB Ram

  • GTX 1070-Ti with 8GB of Memory

The gamma test patch looks like this (renderer fullscreen on second monitor 2560x1600@60Hz):

The latest tests were made with pngs with a resolution of 512x512px.
Up to 84 images the patch is running at 60 FPS on my machine.

With 85 images it goes down to about 13 FPS. The memory usage only slightly increases and timings in gamma also don’t change significantly, but GPU usage makes a big jump. In my earlier tests with different images (jpgs 354x388px) there was also a big difference in CPU usage.

I also tried in beta/DX11 (again renderer in fullscreen on second monitor 2560x1600@60Hz):

BetaDX11

It was possible to load about 20 times the amount without taking a massive performance hit.

Attached you’ll find the two test patches. I also included the patch that was used to create the test images,
only use it if you have no history of photosensitive epilepsy.

Perftest.zip (11.9 KB)

3 Likes

I can confirm this, I also get a transition from stable 60 fps to 11 fps when I just load one more picture.

interesting thread, wonder if you cache whole group would it make it better ;)
anyways i guess it uses some bitmap draw method
i would assume you need some gl canvas or something like that…

Doesn’t make a difference and the patch as is, is really only for testing. Once you want to have something animated the cache doesn’t really make sense this way.

Reading through this and that I assume images in VL.Skia aren’t GPU-accelerated and it also uses the GPU resource cache with a default size of 96MB.
Depending on what else is going on in the renderer this number corresponds pretty much to the number/size of images I can load before performance goes down.

“As a first workaround” I’d like to increase the cache size using GRContext.SetResourceCacheLimits
Is there a way to access the GRcontext?

And maybe could something like this be done in VL.Skia s.o.t.r.:

using (var surface = SKSurface.Create(grContext, false, imageInfo, 1, GRSurfaceOrigin.TopLeft))
{
    surface.Canvas.DrawImage(rasterImg, 0, 0);
    surface.Canvas.Flush();
    var textureImage = surface.Snapshot()); //This should be texture backed
}

sauce

@robotanton/@elias I guess.

1 Like

Humpty Bumpty

Here’s is a quick hack showing how to access the GRContext
PlayWithGRContext.vl (7.5 KB)

Thanks a lot. The current default GPU ResourceCacheLimit is indeed 96MB. Setting it to a higher value solves the problem. I’d suggest to set a more sensible default in the future and to add the info to the documentation and help patches. Also a convenience node for setting would be nice.SkiaPerf

3 Likes

Very good find Björn! Since you invested a lot of time in it already - what default would you suggest? And is there a known drawback when increasing the default?

So I’d suggest some sort of skia config node which can be connected upstream to the renderer - modeled as record and describing those special configuration properties. @gregsn any thoughts on this?

Concerning drawbacks, as far as I understood the RessourceCache reserves/uses the set amount of memory in Ram AND VRam when images are not GPU-backed. Systems with integrated graphics that already use shared system Ram might more easily run into problems when setting the limit too high.

Maybe there is a possibility to gauge the system specs and set the limits accordingly?

But I really recommend reading through this thread those people are far more knowledgeable.

cool THX solved also here a lot of problems - but is this also possible to make it available in gamma1.8preview - I have problems with AzureKinect and gamma2.0preview - whatever is easier to fix ;)

Ah ok you’re also running into the Xenko->Stride rename issue turning all 2020.1 libs using a C# project internally unusable for 2020.2 and vice versa :/

In any case, here is the same patch saved in a way that it should work for both 2020.1 and 2020.2
PlayWithGRContext.vl (7.3 KB)

also this might be useful: Performance issue with image · Issue #3043 · AvaloniaUI/Avalonia · GitHub

This solved my Skia performance issue in 2021.3.1. Is there already a convenience node for this job? We tried adding all dll functions manually. Especially “GRContext” was hard to find, since the dll has a new name in the latest version.

Out of the box skia is unable to use more than 100MB VRAM atm. lol Did nobody try this with more than one bigger texture? Maybe the elementa performance issues is also caused by this?

The default resource limit has been increased to 512 MB (from 96 MB) in 2021.4 previews. A GRContext is now held per thread (and not per renderer), therefor the patch I posted here will no longer make any sense and will crash for sure. Instead you’ll find a new node called GRContext which will give access to the Skia graphics context on the current thread as well as allow to configure the resource cache limit.

3 Likes

I think I ran into the 512MB limit. how do I set the new resource cache limit in preview 381?
How do I connect it to the renderer?

grcontext

You don’t have to connect it to the renderer. Just set it like so for example:

image

CacheLimit.vl (8.0 KB)

@Elias what happens when a renderer is inside a Foreach [Reactive] (triggered by a MultimediaTimer), does it get its “own” context that needs to be set inside the region?

1 Like

Yes - a graphics context is held per thread. You’ll need to be very careful when passing Skia objects from one such thread to another - Skia is not built for that and you’ll most certainly experience crashes.

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.