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: 
destruk
Binge Watcher

roScreen back buffer and roku internal screensaver

Roku2
To save time and remain as efficient as possible, I create an roscreen and draw the background image, and then swap buffers to display the background image, and then draw the background image again to the back buffer.
This allows me to simply draw the parts of the screen that change when they need to be updated. This works fine and is fast enough for what I need, however, when the roku screensaver turns on, it forces a clear of the back buffer.
What this creates is every time I swap buffers after waking up the roku from the screensaver, half the frames displayed are without any background image.

Is there a solution to this besides having to draw the entire screen with background every frame, or hack/track timer count when a screensaver could turn on to redraw the entire screen?
Single buffer looks real ugly as you see it clear the data and the draw it a piece at a time every time the content needs to change. btw - single buffer also clears/wipes out the background after the screensaver stops if you use swapbuffers to refresh the screen.
0 Kudos
18 REPLIES 18
RokuJoel
Binge Watcher

Re: roScreen back buffer and roku internal screensaver

If you don't mind, please email me an example project that demonstrates these issue, as I have not encountered it myself, I'll try to see if there is a way to fix it by re-coding, or file a bug if it turns out to be a firmware issue.

- Joel
0 Kudos
RokuJoel
Binge Watcher

Re: roScreen back buffer and roku internal screensaver

I believe I have a good guess as to why you are having trouble like this, you should be constantly drawing and swapping buffers:


While true
msg=port.getmessage() 'no wait time
screen.clear(&h000000FF)
'calculate new positions
'draw bitmap objects
'move sprites
screen.drawall() 'or, screen.draw()
screen.swapbuffers()
end while


remember this is for dynamic games where things are moving on the screen all the time, so you try to draw and swap buffers constantly, like every 1/30 of a second, you don't ever wait to call swap buffers. Even if nothing is moving on the screen for 10 minutes you should keep calling swapbuffers(), and usually you should be redrawing everything on the screen each time through the loop before you call swapbuffers().

- Joel
0 Kudos
renojim
Community Streaming Expert

Re: roScreen back buffer and roku internal screensaver

Is this related to this issue that never got any acknowledgement?
viewtopic.php?f=34&t=50313

-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
destruk
Binge Watcher

Re: roScreen back buffer and roku internal screensaver

It's probably related RenoJim (from what I can tell).

Thanks for the idea Joel. The main issue with redrawing the entire screen and everything on it is that it is too slow. My screen is 1280x720, redrawing everything includes the entire background image, and then it needs to overlay some text which is cycle expensive, and some graphics, as well as pop up thumbnail images for a menu overlaid on that too and a highlight box - so it's drawing a lot. By having it redraw the screen 30 times per second, you don't see the missing background long enough to notice as it's redrawn so quickly - but it really slows down responsiveness with the other stuff it has to do. So rather than having it redraw 921,600 pixels 30 times per second, only having it draw the parts it needs is 329,718 pixels (3 times less work) - and even with the 30x second redraw updates it still engages the screensaver to cause the problem issue if there hasn't been any remote activity. I tried using roImageCanvas and that is even slower than roscreen, but maybe I should be using it anyway to accomodate for the buggy screensaver wiping one of the roscreen buffers for itself?

Another issue it appears the more time spent drawing actually delays the timer for the screensaver to kick in. Even redrawing the screen once every 3 seconds causes a screensaver setting of 5 minutes to actually start around 5 minutes 40 seconds - I'd assume the extra 40 second delay is the combined total time it was burning up while drawing the screen over the 5 minute time period - and I thought the screensaver should be in its own thread oblivious to what the app was doing if not playing video?

Or, a possible 'fix' since the screensaver can turn on at a minimum of 5 minutes of inactivity - have the app time itself and at 4 and a half minutes of no activity have it kill itself to return to the roku home screen. I'll need to run that past them to see if it's acceptable.
0 Kudos
TheEndless
Channel Surfer

Re: roScreen back buffer and roku internal screensaver

I'm not sure about redrawing the screen on every pass, even if you don't have anything new to draw. That seems like a waste of cycles to me, but what about redrawing the background every second. That way, there may be a missing background for up to a second when returning from screensaver, but that's probably an acceptable trade-off for the performance boost you get from not having to repaint the entire screen every time.
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
RokuJoel
Binge Watcher

Re: roScreen back buffer and roku internal screensaver

Here is an excerpt from a game, I've removed all the artificial intelligence logic, the collision detection logic and the code that calculates object positions on the screen and the code for creating and deleting sprites and animating explosions, calculating attack and retreat vectors, and handling input from the remote.

There are two large bitmaps involved, both are 2048 x 720, which scroll on screen at different rates, and 21 animated sprites, plus a variable number of sprite missiles, they all move on the screen nice and fast on both the older model devices and the new devices, in full HD 1280x720 mode. There is no problem with anything missing after returning from the screensaver. As you can see, I'm swapping the buffers constantly:

while true
msg=wait(1, msgport) ' wait for a button press
if animtimer.totalmilliseconds() > 50 then
animtimer.mark()
compositor.animationtick(animtimer.totalmilliseconds())
end if
movex=processRemoteInput(msg)
screen.setalphaenable(false)
big2048oneRegion.offset((movex/2),0,0,0)
screen.drawobject(0,st,big2048oneRegion)
screen.setalphaenable(true)
big2048TwoRegion.Offset(movex,0,0,0)
screen.drawobject(0,epos,big2048TwoRegion)
playsprite.moveto(ps.posx,ps.posy)
for i=0 to maxobjects-1
es[i]=calcluateNewPositions(es[i],ps)
enemyspritearray[i].moveto(int(es.posx),int(es.posy))
next i
compositor.drawall()
screen.SwapBuffers()
end while


It is true, I'm not clearing the screen on each iteration, but I'm drawing each element in layers, first the non-alpha blended background, then the transparent background, both are 2048 x 720 and I draw them each time through the loop.

I think that what I said about "every 1/30 second" is probably inaccurate, but I am drawing them as fast as possible (notwithstanding that I'm using wait() which has a 10ms delay bug), and it works quite well, no problems with screensavers.

Hopefully this structure can be useful to you.

- Joel
0 Kudos
destruk
Binge Watcher

Re: roScreen back buffer and roku internal screensaver

Your code works fine that you posted for what you'd using it for. I'll need to make some changes to my code to test it with alpha set to false and see if it's any faster even though it's technically drawing more pixels 🙂
update - alpha set to false does draw a bit faster. Still working on the clearing background image when the screensaver stops though.
0 Kudos
TheEndless
Channel Surfer

Re: roScreen back buffer and roku internal screensaver

"destruk" wrote:
Your code works fine that you posted for what you'd using it for. I'll need to make some changes to my code to test it with alpha set to false and see if it's any faster even though it's technically drawing more pixels 🙂
update - alpha set to false does draw a bit faster. Still working on the clearing background image when the screensaver stops though.

Enabling alpha is actually slower, because it has to evaluate every pixel to see how it will blend with the pixel it's overlaying.
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
destruk
Binge Watcher

Re: roScreen back buffer and roku internal screensaver

Thanks TheEndless. 🙂 makes perfect sense.
After more investigation/experimentation, what it appears to do is similar to caching to keep the framerate up as high as possible.
I theorize - you create the roscreen, you tell it to draw x graphic at x location, or to draw it as the background image. The roku keeps track of all the filenames of the source images and where they are located on the screen in ram. It only actually redraws anything when it moves - in most cases, to the current buffer.
The screensaver kicks on and the first thing it does is take a snapshot of what is currently on the screen and then disables updates to the screen until the screensaver exits. When it turns on it uses one or both of the available buffers for its own graphics presentation. When the screensaver exits, it eats or disposes of the remote button keypress and restores ONE of the buffers - the one that was visible, rather than both of the buffers. However, the back buffer still has stated locations of all the graphics present on it when the screensaver started. So, this explains why the background image would be missing, and having it redraw the background image doesn't do anything - because roku thinks the background image is still there so refuses to draw the same thing. Maybe what I'll need to end up doing to work around it is to destroy the screen and recreate it after the screensaver turns off.
0 Kudos