Forum Discussion

coolbits's avatar
coolbits
Visitor
12 years ago

Strange behavior - update screen even without swapbuffer

Hi,
I've been working with roScreen along with roCompositor and roSprite objects. I've found a strange behavior with the roCompositors.

It is known that we have to use screen.SwapBuffers() in order to update the changes in the sprites inside a compositor. Here is what I did.

1. Created a screen (myScreen) , a compositor(myCompositor) and two sprites (mySprite1, mySprite2) in the compositor
2. Called the myScreen.SwapBuffer() to display the sprites in the screen
3. removed mySprite1 from the myCompositor ; mySprite1.Remove() and set the variable to invalid mySprite1 = invalid
4. Clear screen; myScreen.Clear(&h00000000)
5. Call the Draw function in compositor; myCompositor.Draw()

The strange behavior is that, when I do the step5, the myCompositor draws the remaining sprite (mySprite2) to the screen (without calling the myScreen.swapbuffers()).

At the bottom line, what I want to do is to spare some memory. That's why I am removing the sprites.
I also noticed that, the removed sprites DO NOT remove until I call the myCompositor.Draw() function as well.


Here is the actual code I've used

Function main()

' r2d2_bitmaps
screen = CreateObject("roScreen")

compositor1 = CreateObject("roCompositor")
compositor1.SetDrawTo(screen,&h00000000)

sp1 = compositor1.NewSprite(10,10,CreateObject("roRegion",CreateObject("roBitmap","pkg:/locale/default/images/image1.png"),100,100,300,300),10)
sp12 = compositor1.NewSprite(100, 100,CreateObject("roRegion",CreateObject("roBitmap","pkg:/locale/default/images/backbox.png"),0,0,228,195),10)

compositor2 = CreateObject("roCompositor")
compositor2.SetDrawTo(screen,&h00000000)

sp2 = compositor2.NewSprite(500,500,CreateObject("roRegion",CreateObject("roBitmap","pkg:/locale/default/images/image2.jpg"),100,100,300,300),10)

compositor1.Draw()
compositor2.Draw()

screen.SwapBuffers()

sleep(20000)
print "Now removing the sprites sp2 and sp12"


sp2.Remove()
sp12.Remove()

sp2 = invalid
sp12 = invalid

screen.SwapBuffers()

print "Check whether sprites are removed from the memory"
screen.Clear(&h00000000)
screen.SwapBuffers()

sleep(10000)

print "Now drawging"

compositor1.Draw()
compositor2.Draw()

print "Check now!"

sleep(10000)

End Function



Thanks for any ideas on this.
Cheers,
Chandana

8 Replies

  • Why would you want to use two compositors in the same part of your program
    That are setdraw to same roscreen. Compositors are containors for sprites.

    When you setdraw to an roscreen. It clears the entire display area. You only need one.
    Just keep adding sprites
    To the same compositor. If you want to use more than one. Then they are both
    Attached to the same roscreen. You can expect that behavior. You can use more
    Than one to create an illusion of stacked screens. But you swap only one
    Compositor in /out of a single roscreen.
    Of the one instance of roscreen. Using an iphone to type this is far more
    Difficult
  • You're also creating a single buffered roScreen, so the compositor is drawing to the front buffer, which could account for the odd behavior. SwapBuffers() is meant to be used with a double-buffered screen, while Finish() should be used for a single-buffered screen.
  • Thank you both for the replies. I think I need to look forward more in to double buffering. But still we need to call the screen.Finish() in order to display the changed contents right? So, in this case, even without calling the finish() function, the remaining sprites get displayed on Draw() function all to the compositor. I think this is still mysterious isn't it?

    I am working on a large project and the things did not get mysterious until this point where I removed the sprites and called the Draw() function.

    Thanks
    Chandana
  • No --there is nothing mysterious about it. Create a compositor
    Add / remove sprites to it. Call the compositors draw or drawall
    Interface. Then call swapbuffers. If you change the content of
    Any bitmaps within the sprite. You just repeat the process
    If you look at the roscreen
    Thread below a submitted a very simple example
    Swapbuffers is used for a double buffered screen however
    It also calls finish and will return immediately if the
    Screen is single buffered
  • Thanks.

    The procedure you described is correct. I agree to that. But can you please answer me to this question.

    Let's say we have a roScreen, roCompositor and roSprites attached correctly.
    Q: Without calling screen.Finish() or screen.SwapBuffers() functions, is there any possibility that sprites attached to a compositor get drawn and visible to the user?

    Thanks,
    Chandana
  • My experience with roku dev is limited but in my own channel
    Development which is also complex, Since I employ a lot of special
    Effects, complex menus, and grids. I have never seen any drawing
    Taking place without specifically telling it to draw.
    Your example appears to wrap a compositor around each sprite
    This is a mistake. You only need one compositor attached to one
    Screen. And create sprites from the one compositor and
    Write to the one screen Any other compositor you may wish
    To use on the one screen should be attached to a bitmap

    This allows you to abstract a complex interface into one
    Composite. Such as a sliding menu system

    The 2d API is primarily for games. So if you are going to
    Develop application interface. You still have to play by
    The same rules you would in game development
  • Finish guarantees that anything you have drawn to a single buffered screen has reached the screen; that is, it's not still in some intermediate pipeline. However there is no guarantee that everything you draw does not appear until you call Finish. There would be no place to store all that undrawn information without a second buffer.

    --Mark
  • Thank you all for the help. 🙂 I figured out how to cope with the problem. I attached a background at the top of the compositor before removing the element. 🙂