Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f43d13e4 authored by Steven Thomas's avatar Steven Thomas
Browse files

Tie vr flinger to persistent vr mode

Transfer display control to vr flinger when persistent vr mode is
entered, rather than when vr mode is entered. This allows cardboard
apps, which will invoke vr mode but not persistent vr mode, to work as
in N.

This activates vr flinger at device boot for Daydream ready devices,
which fixes an issue where an app would attempt to create a surface
before vr flinger was running, which would hang indefinitely.

The VrManager listener for persistent vr mode is put in vr flinger
instead of surface flinger. This is cleaner since the vr interaction
with the rest of the device is now consolidated in vr flinger.

While testing I encountered a problem where vr flinger was given control
of the display but vsync was turned off, causing vr flinger's post
thread to hang. I changed the vr flinger logic to give control over
vsync and other display settings to the post thread, and took the
opportunity to further simplify and improve vr flinger's thread
interactions.

Bug: 35885165

Test: Manually confirmed that when persistent vr mode is not invoked we
get the N-based render implementation, and when persistent vr mode is
invoked we get vr flinger.

Change-Id: Ieeb8dabc19e799e3179e52971f3b63f5a8f54b3b
parent b0ae9c12
Loading
Loading
Loading
Loading
+28 −0
Original line number Diff line number Diff line
@@ -41,6 +41,28 @@ public:
};


// Must be kept in sync with interface defined in
// IPersistentVrStateCallbacks.aidl.

class IPersistentVrStateCallbacks : public IInterface {
public:
    DECLARE_META_INTERFACE(PersistentVrStateCallbacks)

    virtual void onPersistentVrStateChanged(bool enabled) = 0;
};

enum PersistentVrStateCallbacksTransaction {
    ON_PERSISTENT_VR_STATE_CHANGED = IBinder::FIRST_CALL_TRANSACTION,
};

class BnPersistentVrStateCallbacks
        : public BnInterface<IPersistentVrStateCallbacks> {
public:
    status_t onTransact(uint32_t code, const Parcel& data,
                        Parcel* reply, uint32_t flags = 0) override;
};


// Must be kept in sync with interface defined in IVrManager.aidl.

class IVrManager : public IInterface {
@@ -49,12 +71,18 @@ public:

    virtual void registerListener(const sp<IVrStateCallbacks>& cb) = 0;
    virtual void unregisterListener(const sp<IVrStateCallbacks>& cb) = 0;
    virtual void registerPersistentVrStateListener(
        const sp<IPersistentVrStateCallbacks>& cb) = 0;
    virtual void unregisterPersistentVrStateListener(
        const sp<IPersistentVrStateCallbacks>& cb) = 0;
    virtual bool getVrModeState() = 0;
};

enum VrManagerTransaction {
    REGISTER_LISTENER = IBinder::FIRST_CALL_TRANSACTION,
    UNREGISTER_LISTENER,
    REGISTER_PERSISTENT_VR_STATE_LISTENER,
    UNREGISTER_PERSISTENT_VR_STATE_LISTENER,
    GET_VR_MODE_STATE,
};

+0 −23
Original line number Diff line number Diff line
@@ -248,29 +248,6 @@ int DisplayClient::GetLastFrameEdsTransform(LateLatchOutput* ll_out) {
  return 0;
}

int DisplayClient::EnterVrMode() {
  auto status = InvokeRemoteMethod<DisplayRPC::EnterVrMode>();
  if (!status) {
    ALOGE(
        "DisplayClient::EnterVrMode: Failed to set display service to Vr mode");
    return -status.error();
  }

  return 0;
}

int DisplayClient::ExitVrMode() {
  auto status = InvokeRemoteMethod<DisplayRPC::ExitVrMode>();
  if (!status) {
    ALOGE(
        "DisplayClient::ExitVrMode: Failed to revert display service from Vr "
        "mode");
    return -status.error();
  }

  return 0;
}

std::unique_ptr<DisplaySurfaceClient> DisplayClient::CreateDisplaySurface(
    int width, int height, int format, int usage, int flags) {
  return DisplaySurfaceClient::Create(width, height, format, usage, flags);
+0 −3
Original line number Diff line number Diff line
@@ -105,9 +105,6 @@ class DisplayClient : public pdx::ClientBase<DisplayClient> {
  // Pull the latest eds pose data from the display service renderer
  int GetLastFrameEdsTransform(LateLatchOutput* ll_out);

  int EnterVrMode();
  int ExitVrMode();

  std::unique_ptr<DisplaySurfaceClient> CreateDisplaySurface(
      int width, int height, int format, int usage, int flags);

+0 −4
Original line number Diff line number Diff line
@@ -217,8 +217,6 @@ struct DisplayRPC {
    kOpGetMetadataBuffer,
    kOpCreateVideoMeshSurface,
    kOpVideoMeshSurfaceCreateProducerQueue,
    kOpEnterVrMode,
    kOpExitVrMode,
    kOpSetViewerParams
  };

@@ -245,8 +243,6 @@ struct DisplayRPC {
  PDX_REMOTE_METHOD(VideoMeshSurfaceCreateProducerQueue,
                    kOpVideoMeshSurfaceCreateProducerQueue,
                    LocalChannelHandle(Void));
  PDX_REMOTE_METHOD(EnterVrMode, kOpEnterVrMode, int(Void));
  PDX_REMOTE_METHOD(ExitVrMode, kOpExitVrMode, int(Void));
  PDX_REMOTE_METHOD(SetViewerParams, kOpSetViewerParams,
                    void(const ViewerParams& viewer_params));
};
+50 −0
Original line number Diff line number Diff line
@@ -53,6 +53,40 @@ status_t BnVrStateCallbacks::onTransact(uint32_t code, const Parcel& data,
  return BBinder::onTransact(code, data, reply, flags);
}

// Must be kept in sync with interface defined in
// IPersistentVrStateCallbacks.aidl.

class BpPersistentVrStateCallbacks
    : public BpInterface<IPersistentVrStateCallbacks> {
 public:
  explicit BpPersistentVrStateCallbacks(const sp<IBinder>& impl)
      : BpInterface<IPersistentVrStateCallbacks>(impl) {}

  void onPersistentVrStateChanged(bool enabled) {
    Parcel data, reply;
    data.writeInterfaceToken(
        IPersistentVrStateCallbacks::getInterfaceDescriptor());
    data.writeBool(enabled);
    remote()->transact(ON_PERSISTENT_VR_STATE_CHANGED,
                       data, &reply, IBinder::FLAG_ONEWAY);
  }
};

IMPLEMENT_META_INTERFACE(PersistentVrStateCallbacks,
                         "android.service.vr.IPersistentVrStateCallbacks");

status_t BnPersistentVrStateCallbacks::onTransact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
  switch(code) {
    case ON_PERSISTENT_VR_STATE_CHANGED: {
      CHECK_INTERFACE(IPersistentVrStateCallbacks, data, reply);
      onPersistentVrStateChanged(data.readBool());
      return OK;
    }
  }
  return BBinder::onTransact(code, data, reply, flags);
}

// Must be kept in sync with interface defined in IVrManager.aidl.

class BpVrManager : public BpInterface<IVrManager> {
@@ -74,6 +108,22 @@ class BpVrManager : public BpInterface<IVrManager> {
    remote()->transact(UNREGISTER_LISTENER, data, NULL);
  }

  void registerPersistentVrStateListener(
      const sp<IPersistentVrStateCallbacks>& cb) override {
    Parcel data;
    data.writeInterfaceToken(IVrManager::getInterfaceDescriptor());
    data.writeStrongBinder(IInterface::asBinder(cb));
    remote()->transact(REGISTER_PERSISTENT_VR_STATE_LISTENER, data, NULL);
  }

  void unregisterPersistentVrStateListener(
      const sp<IPersistentVrStateCallbacks>& cb) override {
    Parcel data;
    data.writeInterfaceToken(IVrManager::getInterfaceDescriptor());
    data.writeStrongBinder(IInterface::asBinder(cb));
    remote()->transact(UNREGISTER_PERSISTENT_VR_STATE_LISTENER, data, NULL);
  }

  bool getVrModeState() override {
    Parcel data, reply;
    data.writeInterfaceToken(IVrManager::getInterfaceDescriptor());
Loading