Jump to content

[TOPIC: topicViewTemplate]
[GLOBAL: userSmallPhoto]
Photo

Snapshot not restored on applicationResume for Android (4.3)
Started by nikraver Dec 02 2013 06:03 AM

15 replies to this topic
snapshot
[TOPIC CONTROLS]
This topic has been archived. This means that you cannot reply to this topic.
[/TOPIC CONTROLS]
[modOptionsDropdown]
[/modOptionsDropdown]
[reputationFilter]
[TOPIC: post.html]
#1

nikraver

[GLOBAL: userInfoPane.html]
nikraver
  • Observer

  • 12 posts
  • Corona SDK

Hi Guys

 

I'm having some issues with the android version of an app that uses the snapshot object (canvas mode is set to discard). The issue occurs when you exit the app by clicking the home or the task manager button and then returning to it (the snapshot is not being restored from the memory). This is not happening on iOS.

 

Attached are 2 screenshots of the "TrailingPaint" example with the issue.

 

Anybody has any idea how to fix this?

 

 

Attached Files



[TOPIC: post.html]
#2

nikraver

[GLOBAL: userInfoPane.html]
nikraver
  • Observer

  • 12 posts
  • Corona SDK

Apparently this is a "normal" behaviour on android according to http://forums.coronalabs.com/topic/41150-issues-with-snapshots-resuming-on-android/, so the only solution would be to save the snapshot on "applicationSuspend" event and restore it "applicationResume".

 

However when I try to do this, the image is saved but on "applicationResume" I only get a blank screen - no actual code is executed on this event. The test is again on Android.



[TOPIC: post.html]
#3

rbhadani

[GLOBAL: userInfoPane.html]
rbhadani
  • Enthusiast

  • 33 posts
  • Corona SDK

Yup, have tried the following and getting the same result (the base is taken from http://coronalabs.com/blog/2013/11/01/snapshot-canvas-paint-brushes-trailing-object-effects-etc/)


local w = display.viewableContentWidth

local h = display.viewableContentHeight

local snapshot = display.newSnapshot( w,h )

snapshot:translate( w * 0.5, h * 0.5 )

snapshot.canvasMode = "discard"

function listener( event )

    local x,y = event.x - snapshot.x, event.y - snapshot.y

 

    if ( event.phase == "began" or event.phase == "moved" ) then

        local r = display.newRect( 0, 0, w, h )

        r:setFillColor( .05, .05, .05, .05 )

        local o = display.newImage( "brush.png", x, y )

        o:setFillColor( 1 )

        o.alpha = .3

        snapshot.canvas:insert( r )

        snapshot.canvas:insert( o )

        snapshot:invalidate( "canvas" )

    end

end

Runtime:addEventListener( "touch", listener )

 

local function onSystemEvent( event )

    if(event.type=="applicationSuspend") then

        display.save(snapshot,"temp.png",system.TemporaryDirectory)

    elseif(event.type=="applicationResume") then

        print("resume code here - THIS IS WHERE THE BLANK SCREEN HAPPENS, or maybe even on suspend")

    end

end

Runtime:addEventListener( "system", onSystemEvent )



[TOPIC: post.html]
#4

walter

[GLOBAL: userInfoPane.html]
walter
  • Moderator

  • 726 posts
  • Alumni

There are a couple of things to keep in mind:

 

  1. Textures are lost between suspend/resume. Normally, an image is backed by an actual file, so you can regenerate the texture on the GPU.
  2. Snapshots use render-to-texture, so as long as you know how to redraw the objects added to the texture, you can regenerate the texture.
  3. In general, you *can* regenerate the texture of the snapshot. 
    • Now, the reason the code above fails is that the snapshot's canvasMode is set to "discard". This means all objects drawn to the snapshot are discarded (thrown away). 
    • The trick is to set the canvasMode to "append". That way objects are saved off into the snapshot's group (http://docs.coronalabs.com/api/type/SnapshotObject/group.html) instead of just being thrown away. Then in the resume event, you can call snapshot:invalidate() --- with 0 params, so it invalidates the group.


[TOPIC: post.html]
#5

nikraver

[GLOBAL: userInfoPane.html]
nikraver
  • Observer

  • 12 posts
  • Corona SDK

Hey Walter, but if you have large number of objects - for instance used in a painting app, then those objects will take a lot of memory so reconstructing the snapshot is not an option in this scenario. So the actual question is when do I save the image of the snapshot since on the system event .type "applicationSuspend" is not possible/not working?



[TOPIC: post.html]
#6

walter

[GLOBAL: userInfoPane.html]
walter
  • Moderator

  • 726 posts
  • Alumni

How much memory are we talking about? The memory of an object is usually a lot less than the memory consumed by a texture, so what numbers are you seeing?

 

Of course, your other option is to display.save this to a file, but the trick is you have to then load that file into an image and draw that into the snapshot.



[TOPIC: post.html]
#7

nikraver

[GLOBAL: userInfoPane.html]
nikraver
  • Observer

  • 12 posts
  • Corona SDK

At the time that the canvas discard was not available - in the early G2 beta the memory use to go up to 3MB (not texture memory) with a few brush strokes. So keeping the objects in the memory won't do the thing.

 

As for the possible workaround - I managed to save the snapshot in to a png file with the original width / height and was able to restore it - put it back in the snapshot on application resume event (on the simulator), however once I add the following code on android:

 

local function onSystemEvent( event )

    if(event.type=="applicationSuspend"then

        display.save(snapshot,"temp.png",system.TemporaryDirectory)

    elseif(event.type=="applicationResume"then

        print("resume code here - THIS IS WHERE THE BLANK SCREEN HAPPENS, or maybe even on suspend")

    end

end

Runtime:addEventListener( "system", onSystemEvent )

 

I usually get a blank screen on application resume (on android, but it works in the simulator) - This might be a bug.

 

At the moment I'm looking for an alternative when to save the snapshot (other than on application resume).

 

Here is a short video of the application template - 



[TOPIC: post.html]
#8

walter

[GLOBAL: userInfoPane.html]
walter
  • Moderator

  • 726 posts
  • Alumni

How many display objects for that 3 MB?



[TOPIC: post.html]
#9

nikraver

[GLOBAL: userInfoPane.html]
nikraver
  • Observer

  • 12 posts
  • Corona SDK

Around 10.000



[TOPIC: post.html]
#10

tschussler

[GLOBAL: userInfoPane.html]
tschussler
  • Enthusiast

  • 97 posts
  • Corona SDK

@nikraver:

 

We're experiencing this exact same issue.  Were you able to determine a solution that worked to prevent the black screen issue on applicationResume?



[TOPIC: post.html]
#11

Fat Red Couch

[GLOBAL: userInfoPane.html]
Fat Red Couch
  • Enthusiast

  • 34 posts
  • Corona SDK

This bug is still present, for us we're getting it specifically on the Galaxy Tab 10.1. Any updates on this? @nikraver - have you been able to solve this issue or work around it in any way?



[TOPIC: post.html]
#12

nikraver

[GLOBAL: userInfoPane.html]
nikraver
  • Observer

  • 12 posts
  • Corona SDK

No, have tried every possible scenario and the only workaround was to redirect the user to the main menu on applicationResume.

 

Note: The app was rejected on Samsung due to this "workaround"



[TOPIC: post.html]
#13

tschussler

[GLOBAL: userInfoPane.html]
tschussler
  • Enthusiast

  • 97 posts
  • Corona SDK

More information.  We can confirm that calling display.save() on applicationSuspend will result in the application screen rendering black on applicationResume.  This was confirmed on Samsung Galaxy Tab 10.1 running Android 4.0.4 (Tegra 2) and the Tabeo e2 running Android 4.2.2 (Tegra 3).  I'm not sure if this is a chipset issue or not.

 

Since display.save() is effectively the only way to save a snapshot so we can recreate the user experience on resume (when using the discard canvasMode because we have to for performance), we are completely blocked trying to pass the Samsung Seller app certification process.

 

Specifically, Samsung states (as a top 10 reason for app certification failure):

 

Problems in the Background mode

  1. Pause/Resume issues
    • Functions are not resumed when it comes to the Foreground Mode.
    • Not be resumed but executed from start page when it comes to the Foreground Mode from the Background Mode.
                        
  2. Functional issues
                          
    • UI errors are occurred when it comes to the Foreground Mode.  

(http://developer.samsung.com/distribute/app-certification/top-10-failures-and-tips)

 

Currently our options are:

 

1)  Allow the user's data to be corrupted by the suspend/resume process by doing nothing.

2)  Use display.save() and cause the screen to render black

3)  On applicationResume, restart the application.

4)  On applicationResume, restart the module (resulting in user data loss)

 

Options 1-3 will cause the application to get immediately rejected by Samsung.

We're going to try using Option 4 but I'm pessimistic about the results.

 

On January 13th, Walter wrote in this thread  that a fix was coming soon.  We look forward to testing it!

 

Terry



[TOPIC: post.html]
#14

walter

[GLOBAL: userInfoPane.html]
walter
  • Moderator

  • 726 posts
  • Alumni

@tschussler, just a quick correction. That was a different black screen issue that was fixed as explained here (http://forums.coronalabs.com/topic/42581-black-screen-loading-hello-world-sample-app-on-android-20132099/?p=225247). 

 

Also, I searched the bugbase for "display.save" and your Android black screen issue did not come up, which explains why it's not on our radar...



[TOPIC: post.html]
#15

tschussler

[GLOBAL: userInfoPane.html]
tschussler
  • Enthusiast

  • 97 posts
  • Corona SDK

@walter, thanks for the correction.  It was a little challenging to dig up the information that I did and I apologize for any confusion.

 

We just finished creating a reproducible code sample and we're filing a ticket on this issue.  Thanks for you and your team's awesome hard work - we really appreciate it!



[TOPIC: post.html]
#16

tschussler

[GLOBAL: userInfoPane.html]
tschussler
  • Enthusiast

  • 97 posts
  • Corona SDK

OK, for everyone's benefit:

 

You cannot call display.save() during applicationSuspend because the OpenGL context is destroyed by the time your code gets called.  This is a limitation of the Android OS and not Corona's fault.

 

We are testing a workaround approach which involves calling display.save() during user idle time or after user touch events that affect the data we want to save.  Performance might not be acceptable here but we'll give it a whirl and report back our success (or failure) to the community.




[topic_controls]
[/topic_controls]