Forum Discussion

renojim's avatar
renojim
Community Streaming Expert
14 years ago

There's a bug here somplace

I don't know what to make of this other than there appears to be a bug in the Roku 2 firmware. It's pretty hard to explain, so I'm just going to give the code to reproduce it.


Function BuildText(text as String) as Object
color = &heba0dfff
font = CreateObject("roFontRegistry").GetDefaultFont(20,true,false)
width = font.GetOneLineWidth(text,640)
height = font.GetOneLineHeight()
bm = CreateObject("roBitmap",{width:width,height:height,AlphaEnable:true})
bm.DrawText(text,0,0,color,font)
REM bm2 = CreateObject("roBitmap",{width:width,height:height,AlphaEnable:true})
REM bm2.DrawScaledObject(0,0,1,1,bm)
return bm
End Function

Sub RunUserInterface()
screen=CreateObject("roScreen")
screen.SetAlphaEnable(true)
screen.Clear(&hFF)
screen.Finish()
compositor=CreateObject("roCompositor")
compositor.SetDrawTo(screen, &hFF)

bm = BuildText("This is some text")
bmRgn = CreateObject("roRegion",bm,0,0,bm.GetWidth(),bm.GetHeight())
sprite = compositor.NewSprite(100,100,bmRgn)
compositor.Draw()
screen.Finish()
sleep(5000)

print "exiting"
End Sub

Run this on a Roku 1 and it works as expected. On a Roku 2, all I get are blocks of color where the characters should be. However, it gets more interesting. If the REMs are removed on the two lines and either bm or bm2 is returned the string is displayed properly. And, to add to the confusion, if the BuildText function is included inline the text is displayed properly with or without the two bm2 lines.

Another interesting Roku 2 issue I've noticed is that DrawText is about 10 times faster on a Roku 1. I thought the Roku 2 was supposed to be faster? :?

I should point out that I'm on beta firmware, so maybe that's the issue. I don't have any way to test this on the release firmware.

-JT

9 Replies

  • I noticed the same recently. I've found that the Roku 2 really favors the roRegion for drawing objects and text. Wrap the bitmap in a full size region, and see if you get better results.

    In addition to this issue, I've also found that on the Roku 2, drawing a bitmap onto another (bitmap or region) with AlphaEnable set to true will cause the alpha to get pushed all the way through, so overlays cause the bitmap you're overlaying to become transparent as well. The only way I've found around that so far is to composite everything on a separate bitmap, then draw that bitmap onto the final canvas with AlphaEnable turned off, which is incredibly frustrating, as the double draw reduces the framerate from 60 down to 30 fps.
  • Found your problem. You aren't calling bm.finish().

    Void Finish()
    Realize the bitmap by finishing all queued draw calls. Until Finish() is called, prior graphics operations may not be user visible. For example, they may be in the graphics display pipeline, or in a server queue. Finish() is synchronous, it does not return until all graphic operations are complete.

    The second bitmap creationis most likely causing some barrier to be crossed that causes the bitmap to coalesce operations and write it's actions.
  • renojim's avatar
    renojim
    Community Streaming Expert
    Interesting. I guess I've been relying on screen.Finish() to finish everything and it always seemed to do just that. It's always strange when things work differently on a Roku 1 vs. 2. Looks like I'm going to have to add a bunch of finish()'s to my code.

    There's still the issue of why DrawText is so much slower on a Roku 2.

    Thanks!
    -JT
  • "renojim" wrote:

    There's still the issue of why DrawText is so much slower on a Roku 2.


    We've found the Roku2 to be slower in general. Then again, we basically re-made everything roCompositor does in pure BrightScript. With a highly optimized processing loop (lots of GOTOs to skip loops and sub-loops where we can detect it) and all direct calls to DrawRect on the base roScreen, we're achieving 60 fps on Roku1, but the Roku2 can't keep up.

    We're just not moving into porting stuff to using roCompositor and sprites to test the difference, hopefully having collision detection handled by the component is much faster than doing it ourselves. It's possible that the Roku2 is slower in select areas, and we happen to be using them heavily.
  • "kbenson" wrote:
    "renojim" wrote:

    There's still the issue of why DrawText is so much slower on a Roku 2.


    We've found the Roku2 to be slower in general. Then again, we basically re-made everything roCompositor does in pure BrightScript. With a highly optimized processing loop (lots of GOTOs to skip loops and sub-loops where we can detect it) and all direct calls to DrawRect on the base roScreen, we're achieving 60 fps on Roku1, but the Roku2 can't keep up.

    We're just not moving into porting stuff to using roCompositor and sprites to test the difference, hopefully having collision detection handled by the component is much faster than doing it ourselves. It's possible that the Roku2 is slower in select areas, and we happen to be using them heavily.

    If roCompositor supported scaling, I'd try going that route myself, but it's just too limited in that respect. I'm actually having the opposite problem, though. I can get 60fps on Roku 2, but get about 3 fps with the same code on Roku 1. Granted, I'm drawing/compositing custom bitmaps on demand (due to serious memory limitations when it comes to caching bitmaps), so it's probably a different part of the processor being used in my scenario.
  • renojim's avatar
    renojim
    Community Streaming Expert
    I think part of my frustration is that I develop on one box, say a Roku 2, and then run the same code on a Roku 1 and the timing is significantly different. Even sleep() is different on the two boxes. I hate to not support both devices given the number of Roku 1s out there. Why limit your potential sales?

    -JT
  • destruk's avatar
    destruk
    Streaming Star
    The best method is most likely to check the firmware revision when your code starts and then refer to that variable to execute your routines for the roku that is running the code, or release two versions - one with a requirement of roku2.
    When drawing on a canvas, roku2 is faster to swap layers of already-drawn information than to clear/redraw the layer. Luckily that also works for Roku1 so you don't notice much difference using the same routine.
  • "renojim" wrote:

    Run this on a Roku 1 and it works as expected. On a Roku 2, all I get are blocks of color where the characters should be. However, it gets more interesting. If the REMs are removed on the two lines and either bm or bm2 is returned the string is displayed properly. And, to add to the confusion, if the BuildText function is included inline the text is displayed properly with or without the two bm2 lines.


    Thanks for reporting this.

    Engineering's Response:

    A fix has been integrated into the next (4.7) firmware release. The cause of the bug is the roFont gets destroyed when the function is exited and before the DrawText command was committed. The extra Finish() call worked around the bug by committing the DrawText call before the roFont was destroyed. In 4.7, this Finish() call will be unnecessary now that the bug has been fixed.


    Further:

    On Roku2, the 2D API attempts to minimize round-trips to the GPU by queuing up draw calls as much as possible. The draw calls are committed when a state change would alter any draws currently in the queue. For example, changing the alpha setting would force all draw calls to be completed with the current alpha setting.

    Unfortunately, another comment that suggested adding a bunch of finish calls would adversely impact performance. A finish call requires a round-trip and the point is to minimize them. .


    Hope that helps.

    - Joel
  • "RokuJoel" wrote:
    Further:

    On Roku2, the 2D API attempts to minimize round-trips to the GPU by queuing up draw calls as much as possible. The draw calls are committed when a state change would alter any draws currently in the queue. For example, changing the alpha setting would force all draw calls to be completed with the current alpha setting.

    Unfortunately, another comment that suggested adding a bunch of finish calls would adversely impact performance. A finish call requires a round-trip and the point is to minimize them. .


    Hope that helps.

    - Joel

    Will this address the issue where alpha gets pushed all the way through the bitmap, regardless of what was drawn to it prior to an alpha overlay? I'm really struggling with working around this in any realistically performant way.