Roku Developer Program

Developers and content creators—a complete solution for growing an audience directly.
cancel
Showing results for 
Search instead for 
Did you mean: 
rynop
Level 7

get rid of component poster image flicker?

I want to show a full screen image after the splash screen and I get a strange full screen black then gray background that shows before my full screen image.

I can display a full screen image after splash without flicker by using roImageCanvas but I don't want to use that hack. I require use of a component.

Here is a quick video showing what I am seeing.

Here is my main.brs :
sub Main()
' THIS does NOT cause flicker
'  background = {
'        Color: "#000000"
'    }
'    loadingImage = {
'        Url: "pkg:/images/main-background.png"
'        TargetRect: {
'            x: 0,
'            y: 0,
'            w: 1280,
'            h: 720
'        }
'    }
'    loadingText = {
'        Text: "Loading...",
'        TextAttrs: {
'            Font: "Large",
'            VAlign: "Top"
'        },
'        TargetRect: {
'            x: loadingImage.TargetRect.x,
'            y: loadingImage.TargetRect.y + 25,
'            w: loadingImage.TargetRect.w,
'            h: 30
'        }
'    }
'    canvas = CreateObject( "roImageCanvas" )
'    canvas.SetLayer( 0, [ background, loadingImage, loadingText ] )
'    canvas.Show()  

 showChannelSGScreen()

'  canvas.Hide()
end sub

sub showChannelSGScreen()
 screen = CreateObject("roSGScreen")
 m.port = CreateObject("roMessagePort")
 screen.setMessagePort(m.port)
 scene = screen.CreateScene("ZORenderablesExample")
 screen.show()

 while(true)
   msg = wait(0, m.port)
   msgType = type(msg)

   if msgType = "roSGScreenEvent"
     if msg.isScreenClosed() then return
   end if
 end while

end sub


And my component:
<?xml version = "1.0" encoding = "utf-8" ?> 

<!--********** Copyright 2016 Roku Corp.  All Rights Reserved. **********-->

<component name = "ZORenderablesExample" extends = "Scene" >

 <script type = "text/brightscript" >

   <![CDATA[

   sub init()
   end sub

   ]]>

 </script>

 <children>
       <Poster
           id="mainBackground"
           translation="[0, 0]"
           uri="pkg:/images/main-background.png"
           width="1280"
           height="720"
           visible="true">
           <Label
               id = "loading"
               translation = "[ 0, 244 ]"
               width = "1280"
               height = "720"
               font = "fontSmiley FrustratedmallBoldSystemFont"
               text = "Loading..."
               horizAlign = "center"
               vertAlign = "center"
               visible = "true" />            
       </Poster>

       <!-- Overhang logo -->
       <Poster
           translation="[79, 36]"
           uri="pkg:/images/header-logo.png"
           width="156"
           height="49"
           visible="true" />
 </children>
</component>


I madegithub repo where you can get at my full code

How do I prevent the flicker? Is there a way I can keep the splash screen up until the component and full screen image has completed rendering?

FWIW I am using the newest roku stick (4 core)
0 Kudos
5 Replies
Veeta
Level 7

Re: get rid of component poster image flicker?

I think what you're seeing is a hard-cut (using video editing terms) when one thread is handing over UI ownership to another internal to the device.  I would guess that the main Roku menu has a thread that parses and displays the splash while a VM is loading for the channel.  Once that VM is ready, it hands over control and you see the first cut which momentarily displays something like a black screen.  Then you almost immediately launch scene graph UI, which is another thread separate from the main Brightscript thread for your channel, and there's a second hard cut to your grey (default Scene Graph background color).

I don't think you can avoid these but you can minimize them by use of color backgrounds, preferably black.  First, set up a facade using roImageCanvas, but only set a black background color.
sub Main()
  facade = CreateObject( "roImageCanvas" )
  background = { 
        Color: "#000000"
    }   
  facade.SetLayer( 0, [ background] )
  facade.Show()  
  showChannelSGScreen()
  facade.Hide()
end sub 


Next, make sure you have set a background in your Scene so you hide the default grey before the poster becomes ready to display.

<component name = "ZORenderablesExample" extends = "Scene" >
  <script type = "text/brightscript" >
    <![CDATA[

    sub init() 
    end sub

    ]]>
  </script>

  <children>
    <Rectangle
      id="Background"
      width="1280"
      height="720"
      color="0x000000FF"/>
    <Poster
      id="mainBackground"
      translation="[0, 0]"
...
0 Kudos
rynop
Level 7

Re: get rid of component poster image flicker?

Thanks I will give that a try.  Why does my logo in the upper left show right after the hard cut but not my full screen image? Said another way, after the hard cut from the splash the logo in upper left is over top of the grey background for a good few seconds (see my video attached to 1st post).

How does the Watch ESPN app get around this?  They go splash -> full screen with image with loading label -> app with no flicker.

I do see black flicker between splash and main app on other apps however the time that it is black is MUCH shorter than mine (again see my video for how long mine is, and mine is grey for some reason not black like other apps).

Is it because I'm loading a FHD poster image after splash that mine is grey for so long?
0 Kudos
Veeta
Level 7

Re: get rid of component poster image flicker?

I'm pretty certain you're right.  The logo is small and easy to load into VRAM and display while the large background takes a moment longer to load.  You can use loadStatus field if you want to synchronize these.  Alternatively, it seems that if you set the backgroundURI of your Scene component to the background image rather it being a poster child of the scene, then the firmware waits for the image to be loaded before it fades in the UI.  It's not a seamless transition but it does get a better effect than the flashing.  That may be the best you can do for scene graph loads.

I loaded the WatchESPN channel and I did see a very short flicker between their splash and "loading" screens. Amazon Video channel does the same thing.  That's the first hard cut we're seeing.  Neither of them has the second cut (your "grey") because they're not scene graph apps.  They use the old SDK components which run in the same thread as your roImageCanvas, so no visual overhead of handing off the screen UI to another thread.  
0 Kudos
rynop
Level 7

Re: get rid of component poster image flicker?

Ah ok that makes sense.  Thanks so much for your help!
0 Kudos
rynop
Level 7

Re: get rid of component poster image flicker?

Roku really needs to come up with a better solution to this because everyone that uses scene graph runs into this.  

Keeping the splash up until the scene graph node underneath has finished rendering, then removing the splash over top would be a clean solution IMO.
0 Kudos