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: 
kbenson
Visitor

roImageCanvas feature request (yet another)

To the Roku devs, the following two capabilities would be greatly appreciated
1. The ability to composite the canvas without showing it. That is, a show() method that just does the heavy lifting, so I can later do a very speedy actual displaying of the canvas.
2. The ability to block until the canvas is actual updated/displayed. The show() method returns after a fairly standard time interval, but depending on how heavily the canvas is utilized, the actual screen update may take several more seconds. Calls to screen components with quicker update intervals may cause screen components to display out of order. Actually, it just occurred to be you may have that behavior on purpose to facilitate message handling. In that case, sending a message that the canvas has finished displaying would be useful.

Additionally, if you don't already have plans on how to speed up roImageCanvas, I have a suggestion, allow contiguous sets of layers to be tagged as "static." This would allow the roImageCanvas to composite and cache those layers into a single image to be used on future calls to show(), which I imagine could greatly speed up compositing the canvas elements.

E.g.
1. Set layer 0 to background image
2. Build display in layers 1-10
3. set layers 1-10 as static, telling the canvas that you won't be changing them
4. Display something dynamic on layer 11

This would allow layers 1-10 to be composited into a single image, and that image then used in the show operation. Instead of each additional canvas change having to composite with the previous 11 layers (including 0), it composites with 0, 1-10 as a single image, and the new item. Changing anything in layers 1-10 could incur a fairly large performance/time penalty, as it re-caches them all.

This is fairly analogous to the multiple canvas object approach currently being used by myself and a few other developers, but less confusing and more determinate, since manual sleep for arbitrary times isn't needed.
-- GandK Labs
Check out Reversi! in the channel store!
0 Kudos
8 REPLIES 8
TheEndless
Channel Surfer

Re: roImageCanvas feature request (yet another)

"kbenson" wrote:
2. Build display in layers 1-10
3. set layers 1-10 as static, telling the canvas that you won't be changing them

I'm not sure, but I think you can already accomplish this by adding an array of elements to a single layer, instead of adding 10 separate layers. This is how I composite all of my background layers:

background = [
screenBG,
section1AlphaOverlay,
section2AlphaOverlay,
section3AlphaOverlay
]
canvas.SetLayer( 0, background )

I assumed it would cache the whole layer as a single image if done this way, but I might be wrong.
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
renojim
Community Streaming Expert

Re: roImageCanvas feature request (yet another)

I agree that something needs to be done. I could probably live with the slow speed or find ways to work around it, but the idea of sleeping random amounts of time after a show() is just ridiculous. I've just been getting frustrated as I think I've found the magic number to sleep only to have it work 9 times out of 10 and then the 10th time my update just seems to get totally discarded. A blocking show() or some other way to force an update is desperately needed.

-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 feature request (yet another)

"TheEndless" wrote:

I'm not sure, but I think you can already accomplish this by adding an array of elements to a single layer, instead of adding 10 separate layers. This is how I composite all of my background layers:


Hmm, I don't think I've tested that specific case for performance. I'll have to do that, and compare to using a separate canvas.

"renojim" wrote:

A blocking show() or some other way to force an update is desperately needed.


Indeed. Although I can understand if they would prefer to send an event on completion instead, as it fits well with their current model and then the system isn't prevented from handling other events (such as HTTP events) during this period. While it's probably a bit harder to code for, it's the best route IMHO.
-- GandK Labs
Check out Reversi! in the channel store!
0 Kudos
kbenson
Visitor

Re: roImageCanvas feature request (yet another)

"kbenson" wrote:
"TheEndless" wrote:

I'm not sure, but I think you can already accomplish this by adding an array of elements to a single layer, instead of adding 10 separate layers. This is how I composite all of my background layers:

Hmm, I don't think I've tested that specific case for performance. I'll have to do that, and compare to using a separate canvas.


Unfortunately, I'm not seeing any speedup when using a single layer with many images in it compared to a layer per image. with 40 randomly sized and colored triangles, all with separate files located in tmp:/, I see zero performance difference. That is to say, I can count to 4 between the call to setLayer() and the image actually showing on the screen when there's that many images already displayed.

What's more, I've determined that if you call allowupdates(false), add items to teh canvas, then call allowupdates(true), show(), allowupdates(false), nothing is displayed. That is, since show is non-blocking, and allowupdates is a state changing method, it can set the state of the canvas back to non-updating before anything displays. This means if you want the default state of the canvas to be non-updating, you need to wait an arbitrary amount of time after calls to show() (because it takes different amounts depending on what's displayed) to ensure the updates have happened, and THEN set the display state to non-updating.

We REALLY need an event denoting image canvas has finished compositing images. Preferably with a blocking show-like method (or an optional argument to make show() block) to boot, so people can pick their poison.
-- GandK Labs
Check out Reversi! in the channel store!
0 Kudos
TheEndless
Channel Surfer

Re: roImageCanvas feature request (yet another)

I don't know if it makes a difference in your implementation, but based on some testing I did today, SetLayer() appears to block after a canvas has been shown. Have you tried calling Show() first, then setting your layers? Setting multiple layers like this causes some flickering, but it doesn't if you set a single layer with your array of data. I never call Show() except on the initial draw, because calling SetLayer() updates the screen immediately.
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 feature request (yet another)

That's actually not the behavior I see at all. I suspect it might be some canvas settings you've toggled, which I'd be interested in knowing.

What I'm seeing is that if I loop 40 times and within each loop assign an image to display on a unique layer with setLayer(), whether I've previously called show() or not, it finishes that loop LONG before the images actually display. What I do see is that the images display in clumps, and at first I'll get 2-4 showing, then another 10 or so, and finally the rest, 6+ seconds from starting the loop. It takes ~2 seconds is the sum of the per iteration create PNG and call setlayer time, so it's ~4 seconds to display the images, which is the same amount of time it takes to hand an array of images (as ImageCanvas items) as a single call to setlayer (~4 seconds). If it was blocking, the loop should take 6 seconds to complete, but it takes slightly less than 2.

I see no difference whether I call show() in each iteration or at the end, and whether I've called it before
-- GandK Labs
Check out Reversi! in the channel store!
0 Kudos
TheEndless
Channel Surfer

Re: roImageCanvas feature request (yet another)

I suppose I should clarify. On my relatively complex canvas, wrapping a call to SetLayer() in an roTimespan, I'm seeing it take upwards of 150-200ms, whereas a call to show takes 2ms, which would suggest that SetLayer() is blocking to some extent.
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 feature request (yet another)

Ah, yes. The setLayer() call does tend to take a bit longer the more items are on the canvas, but I still find it returns long before the image actually displays.
-- GandK Labs
Check out Reversi! in the channel store!
0 Kudos
Need Assistance?
Welcome to the Roku Community! Feel free to search our Community for answers or post your question to get help.

Become a Roku Streaming Expert!

Share your expertise, help fellow streamers, and unlock exclusive rewards as part of the Roku Community. Learn more.