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 SurfacView 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 is 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. 
interface GvrLayout.PresentationListener Interface with which interested parties can listen to presentation behavior. 

Public Constructors

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

Public Methods

void
boolean
enableAsyncReprojectionVideoSurface(GvrLayout.ExternalSurfaceListener listener, Handler handler, boolean useProtectedBuffers)
Surface
int
GvrApi
GvrUiLayout
boolean
void
void
boolean
onTouchEvent(MotionEvent event)
boolean
setAsyncReprojectionEnabled(boolean enabled)
void
setFixedPresentationSurfaceSize(int surfaceWidthPixels, int surfaceHeightPixels)
void
setPresentationView(View view)
void

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 void addPresentationListener (GvrLayout.PresentationListener listener)

Adds a listener to be notified when the layout starts and stops presenting to an external display. If the listener has already been added, the call will be ignored.

Parameters
listener The GvrLayout.PresentationListener to be registered for notifications.

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

Enables the asynchronous reprojection video Surface.

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.

Warning: This must be called before calling {@lint setAsyncReprojectionEnabled()}.

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 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 boolean isPresenting ()

Whether the presentation View is attached to an external display's Presentation.

Returns
  • True if we are presenting, false otherwise.

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 onTouchEvent (MotionEvent event)

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 accomodate 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 and 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 DisplaySynchronizer instance. The caller is responsible for ensuring safe interaction with these objects after shutdown.