Request to Move to Background

Introduction

When your application receives a request to move to the background, it must release the foreground. The request is in the form of the system message RELEASE_FOREGROUND. For more information, see Multicore Processing and the ProcUI Library.

Releasing the Foreground

After your application has received the message, it must perform the following.

  1. Stop all graphics owned by your application.
  2. Stop all audio owned by your application.
  3. Stop using all other foreground-only resources.
  4. Save all relevant states of your application.
  5. Make any other optional-but-useful calls.
  6. Release the foreground.

When your application is prepared to move to the background, you must call the OSReleaseForeground OS function on each and all cores. All cores synchronize inside the kernel on this call to have the foreground switch take place.

Finalize all Rendering Operations

While a process transitions to the background (i.e., it is in the "RELEASING" state), it may continue to use GX2 and MEM1 as normal. However, it should complete all drawing activity, display its final frame, and release all MEM1 resources before doing its final transition to the background state. Prior to releasing the foreground, the main graphics core (the one which called GX2Init) must call GX2DrawDone after all rendering is complete. This guarantees that all command buffer data has been dispatched to the GPU and completed. There are two ways to perform this using the ProcUI system:

  1. If ProcUIProcessMessages returns PROCUI_STATUS_RELEASING:
    1. Render any last transition frames.
    2. Call GX2SetTVEnable(TRUE) if a frame was rendered to the TV.
    3. Call GX2SetDRCEnable(TRUE) if a frame was rendered to the DRC.
    4. Call GX2DrawDone just prior to calling ProcUIDrawDoneRelease
    5. Call ProcUIProcessMessages
  2. Register a PROCUI_MESSAGE_RELEASE callback using ProcUIRegisterCallback that performs the following.
    1. Finalize and swap the current frame.
    2. Call GX2SetTVEnable(TRUE) if a frame was rendered to the TV.
    3. Call GX2SetDRCEnable(TRUE) if a frame was rendered to the DRC.
    4. Call GX2DrawDone
    5. Call ProcUIDrawDoneRelease

In addition to guaranteeing that the main core's command buffer has been flushed, all display list generation on the other threads/cores must also stop. Therefore the application must call GX2EndDisplayList in all other rendering threads/cores if a display list is being generated prior to switching to the background. While in the background state, no further GX2 operations should be performed until the main core has reentered the foreground. After the main core switches to the background, other threads/cores may partially overrun their time slice. To avoid overrunning and writing new GX2 commands on these cores, stop all threads that issue GX2 commands prior to calling GX2DrawDone in the above sequence.

Stop the Threads on Which a GX2 Command is Issued to Avoid an Overrun

After performing a process switch using the ProcUIProcessMessages function, threads overrun slightly, except the thread that called ProcUIProcessMessages. To avoid the overrun when calling ProcUIProcessMessages, stop the thread on which a GX2 command is issued.

For example, if you have an asynchronous thread for loading that also creates a display list, you must use a mutex or other exclusive locking construct to lock the place where the display list is created and the place where ProcUIProcessMessages is called.

Call GX2SetTVEnable and GX2SetDRCEnable Before Switching Processes

The GX2SetTVEnable and GX2SetDRCEnable functions sets a flag after the last frame is cleared that instructs the system that the application allowed rendering to occur. When a process releases the foreground, GX2 can store the last frame that the application displayed. The flag that these functions set determines whether the frame is stored.

The last frame is not stored unless the GX2SetTVEnable or the GX2SetDRCEnable function is called with TRUE as the argument, which sets the flag.

In addition, under the current implementation, at each process switch, this flag is cleared after the last frame is stored. Although the black screen is cleared when the application acquires the foreground, the application must pass TRUE to these functions every time.

To simplify your implementation:

Mutex Locking When Moving to Background

When a user presses the HOME Button during gameplay, the game moves to the background. Some games continue to run in the background. For example, an online game might communicate in the background to maintain its connection. Only Core 2 is available in the background. Core 0 and Core 1 are not available.

If the game moves to the background with a thread on Core 0 or Core 1, and the thread leaves a mutex locked:

Stop Using All Foreground-only Resources

See Foreground Resources for a list of all foreground-only resources.

Optional Calls

Optionally, call OSSetScreenCapturePermission to enable/disable the ability for the system to save a screen capture.

Release the Foreground

Call OSReleaseForeground from all three cores.

Foreground Swapping

To switch which process is in the foreground, two transitions occur:

The more complex transition of the two is switching from the foreground to the background.

A foreground switch is cooperative with both the current and next foreground processes. First, the current foreground process will receive a message from the system message queue to release the foreground. When the process responds to this message it will allow the next foreground process to acquire the foreground. A process does not have the foreground taken away without its knowledge and a background process cannot force itself into the foreground.

Switching From Foreground to Background

To switch which process is in the foreground, the current foreground process must first release the foreground before the next foreground process can move to the foreground.

If not using ProcUI, to begin this process, the current foreground process receives a message from the system message queue with RELEASE_FORGROUND set.

If using ProcUI, at every frame, the current foreground process should call ProcUIProcessMessages. This function will handle any system messages, call PROCUI_MESSAGE_RELEASE callbacks as appropriate, and block while in the background.

After the RELEASE_FORGROUND message is received, or in the PROCUI_MESSAGE_RELEASE callbacks, the process must:

  1. Stop using any foreground-only resources (graphics, audio, etc.)
    NOTE:
    Save any data from MEM1 or the foreground bucket that cannot be readily recreated because these memory regions are cleared on a foreground switch.

    ProcUI provides functions to save MEM1 and/or the foreground bucket automatically.
  2. Call OSReleaseForeground from all three cores

Process Switching and Effect on Controllers

When a process releases the foreground, the controller states as used by WPAD and KPAD are saved, and when the foreground is again acquired, WPAD and KPAD try to restore these states. This is helpful because the controller setup may change in the other process, for example, turning on or off DPD or MPLS.

Here are some issues to consider after a process switch:

Reasons for Foreground Release

There are only a few reasons for a process to receive the RELEASE_FOREGROUND message:

File System and Network Subsystem Calls

What happens when a game is in the middle of a file system (FS) or network (NET) API call during the switch from foreground to background modes? Consider two cases:

IMPORTANT:
Because inflight API completion time depends on when the user chooses to return to playing the game, the game must not use real-time timeout logic to check for inflight API completion.

See Also

Application Lifecycle
Foreground State
Background State
Request to Move to the Foreground
Transition Messages
Multicore Processing on the Wii U
Creating an Application

Revision History

2014/01/23 Terminology fix.
2013/08/08 Created


CONFIDENTIAL