GvrLayout

public class GvrLayout

A View that wraps and supports a concrete VR presentation view (usually a SurfaceView).

This class operates as the *root* View of a VR scene. It abstracts a number of VR-related auxiliary tasks, e.g., presenting to an external display, obtaining a handle to the Google VR API wrapper and supporting "asynchronous reprojection"-based low-latency rendering.

The client is responsible for installing a "presentation" view. This is the view to which the VR scene (*not 2D, View-based UI*) should be rendered, and will most often be some deriviative of a SurfaceView, e.g., GLSurfaceView. It is this presentation view that owns the render loop; GvrLayout itself does not perform rendering unless asynchronous reprojection is enabled and supported by the client. A typical setup might look something like:

  • Create the SurfaceView to which the VR scene will be rendered, e.g., surfaceView = new GLSurfaceView(context); surfaceView.setRenderer(renderer);
  • Install the SurfaceView in the GvrLayout, e.g., gvrLayout = new GvrLayout(context); gvrLayout.setPresentationView(surfaceView);
  • Install the GvrLayout in the View hierarchy, e.g., activity.setContentView(gvrLayout);
  • Use the associated GvrApi instance to inform and perform stereo rendering, e.g., gvrApi = gvrLayout.getApi(); nativeOnDrawFrame(gvrApi.getNativeGvrContext());

The GvrLayout must be notified when the activity is paused and resumed. GvrLayout clients are required to call onPause() when the activity pauses and onResume() when the activity resumes. These calls allow GvrLayout to detach and reattach any listeners it uses to monitor for external displays. The GvrLayout should also be explicitly shut down by the client using shutdown(), typically when the activity is being destroyed.

Note: This class is *not* generally thread-safe, and should be used solely on the UI thread unless otherwise noted. The same applies for the GvrApi instance owned by this class and exposed via getGvrApi().

Nested Classes

interface GvrLayout.ExternalSurfaceListener Listener for external Surface events. 

Inherited Constants

Inherited Fields

Public Constructors

GvrLayout(Context context)
Creates a new GvrLayout instance.
GvrLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)
Creates a new GvrLayout instance.

Public Methods

boolean
enableAsyncReprojectionProtected()
Enables asynchronous reprojection with supported for protected buffers.
boolean
enableAsyncReprojectionVideoSurface(GvrLayout.ExternalSurfaceListener listener, Handler handler, boolean useProtectedBuffers)
Enables video Surface with async reprojection.
boolean
enableCardboardTriggerEmulation(Runnable cardboardTriggerListener)
Enables emulation of Cardboard-style touch trigger input when using a Daydream headset.
Surface
getAsyncReprojectionVideoSurface()
Gets the video Surface managed by the reprojection thread.
int
getAsyncReprojectionVideoSurfaceId()
Gets the Surface ID of the video Surface managed by the reprojection thread.
GvrApi
getGvrApi()
Gets the GvrApi object associated with the GvrLayout.
GvrUiLayout
getUiLayout()
Returns the GvrUiLayout associated with this view.
void
onBackPressed()
Optional hook the client can trigger from Activity.onBackPressed().
void
onPause()
This must be called when the parent activity is paused.
void
onResume()
This must be called when the parent activity is resumed.
boolean
setAsyncReprojectionEnabled(boolean enabled)
Enables or disables asynchronous reprojection.
void
setFixedPresentationSurfaceSize(int surfaceWidthPixels, int surfaceHeightPixels)
Updates the pipeline to accommodate a custom, fixed presentation surface size.
void
setPresentationView(View view)
Sets the presentation view to a given View.
void
shutdown()
Shuts down the GvrLayout, freeing associated resources.

Inherited Methods

Public Constructors

public GvrLayout (Context context)

Creates a new GvrLayout instance.

Parameters
context The current Context. This *must* be, or wrap, an Activity instance.
Returns
Throws
IllegalArgumentException if the provided Context is not an Activity context.

public GvrLayout (Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)

Creates a new GvrLayout instance.

Parameters
context The current Context. This *must* be, or wrap, an Activity instance.
attrs The custom AttributeSet.
defStyleAttr The custom style attributes.
defStyleRes The custom style resource.
Returns
Throws
IllegalArgumentException if the provided Context is not an Activity context.

Public Methods

public boolean enableAsyncReprojectionProtected ()

Enables asynchronous reprojection with supported for protected buffers. Applications should stop calling eglSwapBuffers on their native view once this feature is enabled. Will only activate on VR-Ready devices. Once asynchronous reprojection is enabled, it cannot be disabled.

This function must be called before any calls to initializeGl() on the GvrApi instance, and must be called on the UI thread.

Returns
  • true if enabling the feature worked, false otherwise.

public boolean enableAsyncReprojectionVideoSurface (GvrLayout.ExternalSurfaceListener listener, Handler handler, boolean useProtectedBuffers)

Enables video Surface with async reprojection.

Applications should set the Surface as the output buffer for their Media playback. Video rendering will occur on the reprojection thread, and so will not be limited to App framerate.

Note: This will implicitly invoke setAsyncReprojectionEnabled(boolean).

Parameters
listener The GvrLayout.ExternalSurfaceListener to receive callbacks from the video Surface. Cannot be null.
handler The Handler that listener events are posted to. Cannot be null.
useProtectedBuffers Whether to use protected buffers when rendering to the video Surface.
Returns
  • true if setting the feature worked, false otherwise.

public boolean enableCardboardTriggerEmulation (Runnable cardboardTriggerListener)

Enables emulation of Cardboard-style touch trigger input when using a Daydream headset.

A Cardboard viewer supports touch-trigger based input, whereas a Daydream headest supports controller input. Enabling Cardboard trigger emulation will simulate Cardboard-style touch trigger input using app and touchpad button events from a Daydream controller. This allows Cardboard-supporting apps to simply and easily support operation on a Daydream headset. Enabling this emulation will have no effect when the paired viewer is already a Cardboard viewer.

Note: It is not sufficient to enable Cardboard emulation to run a Cardboard app on a Daydream headset. The following adjustments to a regular Cardboard app need also be made:

Note: Enabling trigger emulation will *only* translate controller clicks into trigger events. The client reticle (if present) will continue to tracker the user's head motion, which may be less than intuitive for users accustomed to controller-driven reticle motion in a typical Daydream app.

Parameters
cardboardTriggerListener The callback to execute when a simulated Cardboard trigger event (Daydream controller button press) is detected. Must not be null.
Returns
  • Whether emulation was successfully enabled. This requires that the current phone is Daydream-ready. Once enabled, Emulation cannot be disabled, and redundant calls to this method will be effectively ignored.

public Surface getAsyncReprojectionVideoSurface ()

Gets the video Surface managed by the reprojection thread. Must be called after enableAsyncReprojectionVideoSurface(ExternalSurfaceListener, Handler, boolean) and setAsyncReprojectionEnabled(boolean).

Returns
  • The video Surface. Null if Surface has not yet been initialized.

public int getAsyncReprojectionVideoSurfaceId ()

Gets the Surface ID of the video Surface managed by the reprojection thread. This must be called after enableAsyncReprojectionVideoSurface(ExternalSurfaceListener, Handler, boolean).

To render the video Surface to screen, create a BufferViewport that renders the video texture coordinates to the source buffer, and sets this ID as the external surface ID.

Returns

public GvrApi getGvrApi ()

Gets the GvrApi object associated with the GvrLayout.

Typical usage of the GvrApi object will take place in the presentation View's render loop, as provided via setPresentationView. However, this is not a strict requirement. In either case, it is up to the caller to ensure that the api is used in a thread-safe fashion, as GvrApi itself is not strictly thread-safe.

Once created, the GvrApi instance will remain alive and valid for the duration of GvrLayout's existence.

Note: The returned GvrApi instance is *live* from the moment of creation, and will start head tracking immediately. The caller should pause and/or resume tracking as desired, typically using the Activity pause and resume signals.

Returns

public GvrUiLayout getUiLayout ()

Returns the GvrUiLayout associated with this view.

The UI layout provides the static, 2D UI overlays like the settings gear icon and the stereo divider line. It is attached and initialized by default when the GvrLayout is created.

public void onBackPressed ()

Optional hook the client can trigger from Activity.onBackPressed().

This will invoke the currently configured "close" behavior for the layout. For Daydream-compatible Activities this will quit VR and restore the Android launcher. If the user has configured an override for the close button behavior, that action will be invoked. Otherwise, this call will simply invoke Activity.finish().

public void onPause ()

This must be called when the parent activity is paused.

public void onResume ()

This must be called when the parent activity is resumed.

public boolean setAsyncReprojectionEnabled (boolean enabled)

Enables or disables asynchronous reprojection. Applications should stop calling eglSwapBuffers on their native view once this feature is enabled. Will only activate on VR-Ready devices. Once asynchronous reprojection is enabled, it cannot be disabled.

This function must be called before any calls to initializeGl() on the GvrApi instance, and must be called on the UI thread.

Parameters
enabled true to enable async reprojection, false to disable.
Returns
  • true if setting the feature worked, false otherwise.

public void setFixedPresentationSurfaceSize (int surfaceWidthPixels, int surfaceHeightPixels)

Updates the pipeline to accommodate a custom, fixed presentation surface size.

By default, the renderer assumes that the display size matches the surface size. If that is the case for the client app, this method need never be called. However, in certain cases (e.g., hardware scaling via SurfaceView.setFixedSize()), this will not always hold, in which case the vr pipeline must be informed of the custom surface size, e.g., surfaceView.getHolder().setFixedSize(1280, 720); gvrLayout.setPresentationView(surfaceView); gvrLayout.setFixedPresentationSurfaceSize(1280, 720);

If both surface dimensions are set to 0, it is assumed that the rendering surface dimensions match that of the active display.

Note: A custom surface size will *also* change the recommended render target and screen target sizes. The caller should respond accordingly.

Warning: This method calls into GvrApi, and so should be called on the same thread on which the GvrApi instance is used for rendering (or the caller should otheriwise ensure thread-safe GvrApi access).

Parameters
surfaceWidthPixels The width in pixels of the display surface. May be zero to restore default behavior.
surfaceHeightPixels The height in pixels of the display surface. May be zero to restore default behavior.
Throws
IllegalArgumentException if the dimensions are not simultaneously zero or non-zero.

public void setPresentationView (View view)

Sets the presentation view to a given View. The presentation view will be placed at the bottom of this layout, and will be reparented whenever an appropriate external display is discovered. Any previously presented view will be removed and discarded.

This view should contain the stereo content for consumption through a Cardboard device, and not any mono content.

Reparenting to an external display is only supported on devices with Android APIs > 16. For API 16, the passed in presentationView is always attached to the GvrLayout and never reparented.

Parameters
view a view with stereo VR content

public void shutdown ()

Shuts down the GvrLayout, freeing associated resources.

This should be called when the parent activity is destroyed.

Warning: This will shut down both the GvrApi instance as well as the ERROR(/DisplaySynchronizer) instance. The caller is responsible for ensuring safe interaction with these objects after shutdown.