Roku Developer Program

Developers and content creators—a complete solution for growing an audience directly.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Highlighted
Level 13

Tips for speeding up animation speed (roImageCanvas)

Anyone have any? I notice that if I have one layer that's the slightest bit complicated anything I try to draw on another layer slows to a crawl even if the complicated layer never changes. Anyone have any suggestions?

-JT
0 Kudos
10 Replies
Highlighted
Level 7

Re: Tips for speeding up animation speed (roImageCanvas)

Take a look at this thread from last week: viewtopic.php?f=34&t=30944

One of the biggest factors I've found is the size of the image being drawn in a single layer. There's a surprising speed difference between drawing an image that is 600 pixels high vs. an image that's 598 pixels high, so I've found in many cases, you get better refresh rates if you break larger images into multiple layers. kbenson also had some interesting suggestions for using multiple canvases.
My Channels: http://roku.permanence.com - Twitter: @TheEndlessDev
Instant Watch Browser (NetflixIWB), Aquarium Screensaver (AQUARIUM), Clever Clocks Screensaver (CLEVERCLOCKS), iTunes Podcasts (ITPC), My Channels (MYCHANNELS)
0 Kudos
Highlighted
Level 7

Re: Tips for speeding up animation speed (roImageCanvas)

Yeah, we've had really good results so far with multiple canvas items, and calling show on them in order. Here's a few tips:

1) Every time you create a new roImageCanvas object, the other ones will need to redraw everything the next time you call show() on them, so pre-initialize as many as you think you'll need.
2) Once you've got a canvas set up with all the images you want displayed on it, called show(), and given it time to actually do all the compositing, subsequent calls to show() without changing the canvas are quick compared to adding new images and calling how. To the degree that it only takes 15-50 ms (manual sleep!) to call show on a previously shown image canvas.

So, if you have an animation that isn't too complex, you could conceivably create a set of canvas objects, one for each frame, and after calling show on them all initially, you could call show on them in order later for a quick animation.

P.S. If you don't sleep manually between canvas item show() calls, the display order gets all messed up. You could conceivably make use of this to make sure a splash screen is displayed while doing the initial show() on all the objects so they display fast later in the animation.
-- GandK Labs
Check out Reversi! in the channel store!
0 Kudos
Highlighted
Level 13

Re: Tips for speeding up animation speed (roImageCanvas)

Thanks guys. It looks like I have some experimenting to do. I had read that thread, but I didn't look at it too closely. At the time I didn't see the point of multiple canvasses when you could have multiple layers, but I'll have to try it for myself.

Thanks again!
-JT
0 Kudos
Highlighted
Level 7

Re: Tips for speeding up animation speed (roImageCanvas)

"renojim" wrote:
At the time I didn't see the point of multiple canvasses when you could have multiple layers, but I'll have to try it for myself.


Yeah, it's a dirty hack to get around poor performance with multiple items on a canvas. It would be great if Roku could improve canvas performance, but I'm not sure how feasible that is with the hardware and the canvas's current main purpose. Hopefully there's some optimizations they can make to greatly speed up adding layers with lots of images already on the canvas. I could live with the ~100ms update time if it was somewhat constant, and didn't turn into 4000ms when lots of images were already present on that canvas.

P.S. I just realized I haven't tested whether there's a difference in delays with multiple images if they are overlapping or not. I guess I know what I'll be testing tonight...
-- GandK Labs
Check out Reversi! in the channel store!
0 Kudos
Highlighted
Level 7

Re: Tips for speeding up animation speed (roImageCanvas)

"kbenson" wrote:
P.S. I just realized I haven't tested whether there's a difference in delays with multiple images if they are overlapping or not. I guess I know what I'll be testing tonight...

I've actually done some testing with this myself, and found the difference to be negligible. I'm curious to see if you get the same results. I suspect you will, based on my other testing.

One test in particular that reveals a lot about how the canvas works, you may be interested in trying...
Draw a full screen image in one go and time it. Then draw the same image in three sections (to the same layer) with the appropriately different TargetRects and SourceRects, so you're essentially drawing the exact same data, from the exact same file, to the screen. I was surprised at the results.
My Channels: http://roku.permanence.com - Twitter: @TheEndlessDev
Instant Watch Browser (NetflixIWB), Aquarium Screensaver (AQUARIUM), Clever Clocks Screensaver (CLEVERCLOCKS), iTunes Podcasts (ITPC), My Channels (MYCHANNELS)
0 Kudos
Highlighted
Level 7

Re: Tips for speeding up animation speed (roImageCanvas)

"TheEndless" wrote:
One test in particular that reveals a lot about how the canvas works, you may be interested in trying...
Draw a full screen image in one go and time it. Then draw the same image in three sections (to the same layer) with the appropriately different TargetRects and SourceRects, so you're essentially drawing the exact same data, from the exact same file, to the screen. I was surprised at the results.


I haven't tested yet, but are you scaling? We've found that if you can get away with smaller source images, it's much quicker.

Also, if you haven't already, take a two pixel PNG with different colors for each pixel, and scale that up. You get interpolation between the color differences. Easy, super small way to do color gradients.
-- GandK Labs
Check out Reversi! in the channel store!
0 Kudos
Highlighted
Level 7

Re: Tips for speeding up animation speed (roImageCanvas)

"kbenson" wrote:
"TheEndless" wrote:
One test in particular that reveals a lot about how the canvas works, you may be interested in trying...
Draw a full screen image in one go and time it. Then draw the same image in three sections (to the same layer) with the appropriately different TargetRects and SourceRects, so you're essentially drawing the exact same data, from the exact same file, to the screen. I was surprised at the results.


I haven't tested yet, but are you scaling? We've found that if you can get away with smaller source images, it's much quicker.

Also, if you haven't already, take a two pixel PNG with different colors for each pixel, and scale that up. You get interpolation between the color differences. Easy, super small way to do color gradients.

I'm not scaling, but I get the same performance result whether I paint the full image three times (squashed vertically), or I paint different SourceRects of the image. I mentioned in another post that the cutoff seems to be around 598 pixels. I got significantly different paint times painting the image at 598 pixels high than I did at 599 pixels. Very strange...

In the end, I just cut my background image into 3 separate images, and paint them each on the "background" layer. I get the same visual results as having a single image, with much better performance. I haven't actually tested to see if cutting them down further will make a difference, because I basically needed a refresh under a second for updates to my onscreen timer, but I'd be willing to bet that it does.

The gradient thing is awesome! I might just use that!
My Channels: http://roku.permanence.com - Twitter: @TheEndlessDev
Instant Watch Browser (NetflixIWB), Aquarium Screensaver (AQUARIUM), Clever Clocks Screensaver (CLEVERCLOCKS), iTunes Podcasts (ITPC), My Channels (MYCHANNELS)
0 Kudos
Highlighted
Level 13

Re: Tips for speeding up animation speed (roImageCanvas)

"kbenson" wrote:
Are you using multiple canvas objects? From what I remember, I haven't had any problems with this on a single canvas, but multiple canvas items require you to call .show() on the back ones first (with a small delay between them), otherwise the back canvas can't refresh and wipe out any drawing that happened on top of it.

I copied this from greubel's thead since I didn't want to hijack it.

I tried this for an animation, but calling .show() on the back one causes a sort of flashing as the object I'm trying to move across the screen disappears completely during the small delay and then reappears when I call .show() on its canvas. Is this as good as I can expect, or am I missing something? Also, it looks like the box isn't too happy about me calling show() on two different canvases 100 times a second - when I press Home it takes a few seconds for the main screen to appear.

I did lots of experimenting last night, but I wasn't real happy with anything I tried and several things I tried had really strange results. The best compromise I found was to have a background canvas and another canvas where the animation takes place. Then when I want to move the object across the screen, I redraw it in the background color at its old position and at the same time draw it at its new position. This only works because my animation is really simple, my background is mostly empty, and the few places where the moving image crosses over something on the background I can handle pretty easily. It mostly works, but there are still strange things happening on these canvasses. If I don't put enough of a delay in the loop it looks like some updates get discarded leaving artifacts on the screen. Pressing a button on the remote sometimes has the same effect.

That gradient idea sounds pretty cool. I'm going to have to use that someplace. Thanks for sharing!

-JT
0 Kudos
Highlighted
Level 13

Re: Tips for speeding up animation speed (roImageCanvas)

I've discovered another problem with the multiple canvas approach. It looks like when the box comes out of screensaver only the topmost canvas gets redrawn. Has anyone else seen this?

-JT
0 Kudos