
TheEndless
Channel Surfer
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
08-03-2010
01:02 PM
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
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)
Instant Watch Browser (NetflixIWB), Aquarium Screensaver (AQUARIUM), Clever Clocks Screensaver (CLEVERCLOCKS), iTunes Podcasts (ITPC), My Channels (MYCHANNELS)
9 REPLIES 9
renojim
Community Streaming Expert
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
08-03-2010
02:19 PM
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
-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.
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.
kbenson
Visitor
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
08-03-2010
04:57 PM
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.
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!
Check out Reversi! in the channel store!
kbenson
Visitor
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
08-04-2010
12:44 AM
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):
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.
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!
Check out Reversi! in the channel store!

TheEndless
Channel Surfer
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
08-04-2010
01:45 PM
Re: roImageCanvas Performance Tips?
Great information, kbenson. Thanks! I am actually doing something similar, but I'm curious about this comment:
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.
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)
Instant Watch Browser (NetflixIWB), Aquarium Screensaver (AQUARIUM), Clever Clocks Screensaver (CLEVERCLOCKS), iTunes Podcasts (ITPC), My Channels (MYCHANNELS)
kbenson
Visitor
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
08-04-2010
07:43 PM
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).
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!
Check out Reversi! in the channel store!

TheEndless
Channel Surfer
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
09-10-2010
09:19 AM
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)
Instant Watch Browser (NetflixIWB), Aquarium Screensaver (AQUARIUM), Clever Clocks Screensaver (CLEVERCLOCKS), iTunes Podcasts (ITPC), My Channels (MYCHANNELS)

RokuKevin
Visitor
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
09-10-2010
09:29 AM
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
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

TheEndless
Channel Surfer
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
09-10-2010
09:37 AM
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)
Instant Watch Browser (NetflixIWB), Aquarium Screensaver (AQUARIUM), Clever Clocks Screensaver (CLEVERCLOCKS), iTunes Podcasts (ITPC), My Channels (MYCHANNELS)
kbenson
Visitor
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
09-10-2010
10:03 AM
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.
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!
Check out Reversi! in the channel store!