Roku Developer Program

Join our online forum to talk to Roku developers and fellow channel creators. Ask questions, share tips with the community, and find helpful resources.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
TheEndless
Channel Surfer

roImageCanvas Performance Tips?

Can you (Roku, other developers, etc) provide any tips on using the roImageCanvas efficiently to allow for smooth animation? The sliding covers in the Netflix UI are so fluid that there's no doubt the box can do it, but I'm struggling to even get simple text to scroll across the screen without looking jumpy. I've tried breaking the background layer into multiple sections, which definitely has a noticeable effect when displaying a graphical background (598 pixels high appears to be the cutoff before there's a significant performance hit), but that doesn't seem to make any difference if it's a flat color. With a very simple animated object, I can get a fairly reliable refresh rate of 100ms, but that plummets as soon as I add additional elements.

Any tips or tricks would be greatly appreciated! Thanks in advance!
TheEndless
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
9 REPLIES 9
renojim
Community Streaming Expert

Re: roImageCanvas Performance Tips?

I'd like to know the answer to this as well. As you can see from this thread, the roImageCanvas performance took a big hit with the release of the 687 firmware.

-JT
Roku Community Streaming Expert

Help others find this answer and click "Accept as Solution."
If you appreciate my answer, maybe give me a Kudo.

I am not a Roku employee.
0 Kudos
kbenson
Visitor

Re: roImageCanvas Performance Tips?

We've been experimenting with the ImageCanvas extensively over the last month or two for our contest entry, and are also running into performance problems. I believe Roku has stated that the grid layout they are using isn't available in the SDK yet, and it's probably using a special component (written in C/C++) to achieve it's performance. It's obvious at this point the purpose for the ImageCanvas is to do static image display. Hopefully it can be altered to work at least passably for animation, or a separate component can be added to provide animation capabilities, as there's quite a lot of potential there.

In my testing, I found that time to add items to a layer goes up quite a bit as items are added. What takes 100ms when there's 3-4 items turns into 2-4 seconds when there's 60 items. Also troubling is that there's no guarantee that when the script returns from the show() method on the canvas, there seems to be no requirement that the image has actually been displayed yet (but future events seem to be blocked until the display completes).

We have a few thoughts about how to enhance performance, such as running multiple canvases, but we haven't done ANY testing on that yet, and that may or may not help in your specific case. I'll update our findings here after we do some testing, which will either be tonight or Thursday night.

P.S. After the contest is over, we'll be releasing (open sourcing) a BRS library to provide arbitrarily colored and sized drawing primitives, lines, ellipses, rectangles, etc in border or solid mode, with transparency level control. I imagine the accompanying info on how we achieved it will be of interest to many here.
-- GandK Labs
Check out Reversi! in the channel store!
0 Kudos
kbenson
Visitor

Re: roImageCanvas Performance Tips?

Yes, you can get back initial canvas performance through using multiple canvas items. This method may work best if your previously placed items are static and should be behind any newer items. If there are multiple dynamic layers between multiple static layers, more than two canvas items may be the route to go.

In short, you can create a canvas, load as much as you want on it, and when you want better performance, create a new canvas, and add items to it. Upon creating the new canvas, you want to first display any older canvases you have, in order of creation (or whatever z-order you see fit), and then display the new canvas. The important thing to note is that you need to sleep between the show methods on each canvas (otherwise the previous show() method doesn't finish). In my testing, I showed 11 milliseconds to be sufficient between show commands (10 ms didn't work), but I have by canvas show method wrapped in a class, so there may be some additional delay imposed from that. I suspect 20 ms would be fine in all cases.

The following pseudo-code should illustrate how I tested this (the actual code uses some classes I created that make my life easier, but explaining this harder, so pseudo code is probably the best choice here):


canvas = new canvas
cavas.port(new port)

nextlayer=0
for i=1 to 50
' draw random image to canvas at random location
nextlayer = nextlayer +1
canvas.setlayer(nextlayer, random_image_random_location())
end for
canvas.show()

canvas_stack = []
while true
msg = wait on canvas event
if type(msg) = canvas event
' if we get a play button, start a new canvas to get better performance
if buttonpress = play
canvas_stack.push(canvas)
for each c in canvas_stack
c.show()
sleep(20)
end for
canvas = new canvas
canvas.port(original canvas port)
end if

' draw random image to canvas at random location
nextlayer = nextlayer +1
canvas.setlayer(nextlayer, random_image_random_location())
canvas.show()

end if
end while


What you see with this is that after about 30-60 images on a canvas, it starts to really lag as you add more images, to the point where it can take 2-3 seconds to actually display it, instead of the 100 ms you generally see for new blank canvas items. Pressing the play button after noticing this will throw the current canvas onto the stack so it can be redisplayed at will, and reassigns a new canvas to the current canvas var.

Note: I'm re-showing all the canvas objects when creating a new one, but since I'm strictly advancing the layer I could omit this, but I included it to show that it does work with the delay I mentioned.
-- GandK Labs
Check out Reversi! in the channel store!
0 Kudos
TheEndless
Channel Surfer

Re: roImageCanvas Performance Tips?

Great information, kbenson. Thanks! I am actually doing something similar, but I'm curious about this comment:
Note: I'm re-showing all the canvas objects when creating a new one, but since I'm strictly advancing the layer I could omit this, but I included it to show that it does work with the delay I mentioned.

If you don't do the Show() for the canvases beneath, don't you get "smearing" in the case of an animated element on the top canvas? In my experience, if you don't have a background on the current canvas, an animated element just gets redrawn on top of what's already on the screen. I suspect a Show() on the canvas beneath would eliminate that, but probably also has some measurable performance hit associated with it.
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
kbenson
Visitor

Re: roImageCanvas Performance Tips?

Yes, I believe I would get smearing if I was animating, but my example was simply adding images to new layers, so everything added was never moved. I was just pointing out that for my example I didn't need to call show, but I was anyway for clarity.

Thanks for bringing it up though, as it helps clarify an aspect of ImageCanvas that some may not be familiar with, which is that using it without setting a background image or color results in leftover artifacts if you change a layer from it's previous settings (it doesn't "un-draw", it just redisplays everything you've told it do draw).
-- GandK Labs
Check out Reversi! in the channel store!
0 Kudos
TheEndless
Channel Surfer

Re: roImageCanvas Performance Tips?

"TheEndless" wrote:
The sliding covers in the Netflix UI are so fluid that there's no doubt the box can do it, but I'm struggling to even get simple text to scroll across the screen without looking jumpy.

I discovered something the other day that may explain how the Netflix UI achieves the performance it does. I had a custom screensaver with a transparent PNG drawn in "Source" CompositionMode. On the ordinary Roku screens, this drew correctly with the black background that I expected when painting on an roImageCanvas. When the screensaver popped up while in the Netflix UI, however, I could see right through the transparency to the Netflix screen beneath. This would lead me to believe that the Netflix UI is actually using the video plane for it's rendering. There'd be some very very interesting possibilities if that level or access to the video plane were exposed through a future SDK release!
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
RokuKevin
Visitor

Re: roImageCanvas Performance Tips?

TheEndless,

Yes, you are correct that the grid component uses the video plane to improve its performance. That trick is not currently available to the image canvas or explicitly through the SDK.

If you can set SetRequireAllImagesToDraw() to false, you will notice a speedup in the v2.7 SDK on the image canvas.

--Kevin
0 Kudos
TheEndless
Channel Surfer

Re: roImageCanvas Performance Tips?

"RokuKevin" wrote:
TheEndless,

Yes, you are correct that the grid component uses the video plane to improve its performance. That trick is not currently available to the image canvas or explicitly through the SDK.

If you can set SetRequireAllImagesToDraw() to false, you will notice a speedup in the v2.7 SDK on the image canvas.

--Kevin

Good to know! I use SetRequireAllImagesToDraw(false) everywhere it makes sense now, so I might immediately see a benefit once 2.7 is released! Any timeframe on that (sorry, you had to see that coming!)?
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
kbenson
Visitor

Re: roImageCanvas Performance Tips?

You know, I was talking to my teammate the other day, and thinking that if I only had a component to do compress/uncompress (inflate/deflate, actually) for me, I could make a real canvas out a a full size PNG by actually just setting bits in the data section of the PNG, using deflate to compress it (required), and write it out. It wouldn't necessarily be faster than a simple canvas, but at least we would have O(1) time for actions no matter how complex the canvas got. Zlib supports this...

Not to mention there are numerous other uses for built in compression support. The main problem is zip bombs, but if you can only write to tmp:/, I don't see that being a problem for the box, just the app.
-- GandK Labs
Check out Reversi! in the channel store!
0 Kudos