ProcUIProcessMessages

Syntax

#include <cafe/procui.h>

ProcUIStatus ProcUIProcessMessages(BOOL block);

Parameters

block If TRUE, blocks while in the background until an acquire or exit message is received, and a thread is created on Core 2 to process any other background messages.

If FALSE, ProcUIProcessMessages MUST be called on Core 2 (not recommended).

Return Values

PROCUI_STATUS_FOREGROUND The process is currently in the foreground.
PROCUI_STATUS_BACKGROUND The process is currently in the background. This can only be returned if block is set to FALSE (not recommended).
PROCUI_STATUS_RELEASING The process needs to release the foreground. Upon receiving this, ProcUIDrawDoneRelease should be called to release the foreground.
PROCUI_STATUS_EXIT The process needs to exit. It may be returned in the foreground or the background.

Description

When ProcUIProcessMessages is called at every frame, all system messages are handled automatically. The ProcUIProcessMessages function performs the following:

NOTE:
This function may be called by only one thread.
NOTE:
When ProcUIProcessMessages returns PROCUI_STATUS_RELEASING, you need to call ProcUIDrawDoneRelease before calling ProcUIProcessMessages again. If ProcUIProcessMessages is called again before ProcUIDrawDoneRelease, PROCUI_STATUS_FOREGROUND will be returned.

Pass TRUE to ProcUIProcessMessages

The ProcUIProcessMessages function can perform process switching when TRUE is passed as the argument in blocking mode, or in non-blocking mode. Blocking mode is easier to implement.

If you pass TRUE as the argument, you need to call only the following four functions used by ProcUI:

Pass TRUE to this function unless a reason exists not to.

Before Process Switching To Background

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 when all rendering is complete. This guarantees that all command buffer data has been dispatched to the GPU and completed. There are two ways to do 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. 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, 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 tells 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:

Recovering from a Process Switch

Call GX2SetContextState after returning from a process switch.

Upon reacquiring the foreground state, the application should make few assumptions about what GPU state remains from its previous foreground instance. MEM2 resources remained where they were. Any MEM1 resources will need to be reloaded. Display settings (see GX2DisplayPage) should not require resetting, though it does not hurt to do so.

The application must start the rendering with a context state reset. This means it should begin the frame by calling either GX2ClearColor (or similar APIs, see GX2 Functions Which Disable State Shadowing) or GX2SetContextState. This is mandatory. It is not acceptable to attempt to reset every GX2 state manually, since this may not reset all of the GPU pipeline state.

Do Not Call From

Multiple threads This function is not thread-safe.

See Also

Process Switching and Shutdown Tips
ProcUISubProcessMessages

Revision History

2014/01/20 Terminology fix.
2013/05/08 Automated cleanup pass.
2012/05/04 Initial version.


CONFIDENTIAL