Chromium Code Reviews| Index: device/vr/openvr/openvr_device.cc |
| diff --git a/device/vr/openvr/openvr_device.cc b/device/vr/openvr/openvr_device.cc |
| index f129d977e0a77510ee14f763cf9f171dcea8b523..60adc91802baa60f84e2bdae3419118c566d7cf4 100644 |
| --- a/device/vr/openvr/openvr_device.cc |
| +++ b/device/vr/openvr/openvr_device.cc |
| @@ -76,14 +76,21 @@ std::vector<float> HmdMatrix34ToWebVRTransformMatrix( |
| namespace device { |
| -OpenVRDevice::OpenVRDevice() {} |
| +OpenVRDevice::OpenVRDevice() : weak_ptr_factory_(this) {} |
| OpenVRDevice::~OpenVRDevice() {} |
| void OpenVRDevice::CreateVRDisplayInfo( |
| const base::Callback<void(mojom::VRDisplayInfoPtr)>& on_created) { |
| - vr::EVRInitError init_error; |
| + // Initialize init_error with success. |
| + vr::EVRInitError init_error = vr::VRInitError_None; |
| + |
| + // vr_system here could be used as openvr device initialization or update |
| + // device info. |
| auto vr_system = |
|
nhu
2017/04/25 00:52:19
In https://codereview.chromium.org/2825203004/, we
|
| - vr::VR_Init(&init_error, vr::EVRApplicationType::VRApplication_Scene); |
| + render_loop_ == nullptr |
| + ? vr::VR_Init(&init_error, |
| + vr::EVRApplicationType::VRApplication_Scene) |
| + : render_loop_->GetVRSystem(); |
| if (init_error != vr::VRInitError_None) { |
| LOG(ERROR) << vr::VR_GetVRInitErrorAsEnglishDescription(init_error); |
| @@ -91,6 +98,12 @@ void OpenVRDevice::CreateVRDisplayInfo( |
| return; |
| } |
| + if (vr_system == nullptr) { |
| + LOG(ERROR) << "OpenVRRenderLoop failed to return valid IVRSystem pointer"; |
| + on_created.Run(nullptr); |
| + return; |
| + } |
| + |
| mojom::VRDisplayInfoPtr device = mojom::VRDisplayInfo::New(); |
| device->index = id(); |
| device->displayName = |
| @@ -147,7 +160,14 @@ void OpenVRDevice::CreateVRDisplayInfo( |
| device->stageParameters->sizeZ = 0.0f; |
| } |
| - render_loop_ = std::make_unique<OpenVRRenderLoop>(vr_system); |
| + // If it is first initialization, OpenVRRenderLoop instance need to be |
| + // careated and callback need to be registed. |
| + if (!render_loop_) { |
| + render_loop_ = std::make_unique<OpenVRRenderLoop>(vr_system); |
| + |
| + render_loop_->RegistPollingEventCallback(base::Bind( |
| + &OpenVRDevice::OnPollingEvent, weak_ptr_factory_.GetWeakPtr())); |
| + } |
| on_created.Run(std::move(device)); |
| } |
| @@ -179,6 +199,23 @@ void OpenVRDevice::UpdateLayerBounds(int16_t frame_index, |
| // We don't support presentation currently, so don't do anything. |
| } |
| +// TODO(shaobo): OnConnect and OnDisconnect need to be added to VrDisplayClient |
| +// in vr_service.mojom |
| +void OpenVRDevice::OnPollingEvent(OpenVRDevice::VREvent event) { |
| + switch (event) { |
| + case OpenVRDevice::VREvent::CONNECTED: |
| + case OpenVRDevice::VREvent::DISCONNECTED: |
| + break; |
| + |
| + case OpenVRDevice::VREvent::CHANGED: |
| + OnChanged(); |
| + break; |
| + |
| + default: |
| + break; |
| + } |
| +} |
| + |
| void OpenVRDevice::GetVRVSyncProvider(mojom::VRVSyncProviderRequest request) { |
| render_loop_->Bind(std::move(request)); |
| } |
| @@ -238,11 +275,73 @@ device::mojom::VRPosePtr OpenVRDevice::OpenVRRenderLoop::getPose() { |
| return std::move(pose); |
| } |
| +// TODO(shaobo) : Expose pointer directly will increase the risk that behaviour |
| +// out of OpenVRRenderLoop will affect OpenVRRenderLoop. Need to fix it. |
| +vr::IVRSystem* OpenVRDevice::OpenVRRenderLoop::GetVRSystem() { |
| + return vr_system_; |
| +} |
| + |
| +// Only deal with event which will cause displayInfo changed now. |
| +void OpenVRDevice::OpenVRRenderLoop::PollEvents() { |
| + if (!vr_system_ || on_polling_event_.is_null()) |
| + return; |
| + |
| + vr::VREvent_t event; |
| + bool is_changed = false; |
| + while (vr_system_->PollNextEvent(&event, sizeof(event))) { |
| + if (event.trackedDeviceIndex != vr::k_unTrackedDeviceIndex_Hmd && |
| + event.trackedDeviceIndex != vr::k_unTrackedDeviceIndexInvalid) { |
| + continue; |
| + } |
| + |
| + switch (event.eventType) { |
| + case vr::VREvent_TrackedDeviceActivated: |
| + on_polling_event_.Run(OpenVRDevice::VREvent::CONNECTED); |
| + break; |
| + |
| + case vr::VREvent_TrackedDeviceDeactivated: |
| + on_polling_event_.Run(OpenVRDevice::VREvent::DISCONNECTED); |
| + break; |
| + |
| + case vr::VREvent_TrackedDeviceUpdated: |
| + case vr::VREvent_IpdChanged: |
| + case vr::VREvent_ChaperoneDataHasChanged: |
| + case vr::VREvent_ChaperoneSettingsHaveChanged: |
| + case vr::VREvent_ChaperoneUniverseHasChanged: |
| + is_changed = true; |
| + break; |
| + |
| + default: |
| + break; |
| + } |
| + } |
| + |
| + if (is_changed) { |
| + on_polling_event_.Run(OpenVRDevice::VREvent::CHANGED); |
| + } |
| +} |
| + |
| +// Regist a callback function to deal with system event. |
| +void OpenVRDevice::OpenVRRenderLoop::RegistPollingEventCallback( |
| + const base::Callback<void(OpenVRDevice::VREvent)>& onPollingEvent) { |
| + if (onPollingEvent.is_null()) |
| + return; |
| + |
| + on_polling_event_ = onPollingEvent; |
| +} |
| + |
| +void OpenVRDevice::OpenVRRenderLoop::UnregistPollingEventCallback() { |
| + on_polling_event_.Reset(); |
| +} |
| + |
| void OpenVRDevice::OpenVRRenderLoop::GetVSync( |
| const mojom::VRVSyncProvider::GetVSyncCallback& callback) { |
| static int16_t next_frame = 0; |
| int16_t frame = next_frame++; |
| + // VSync could be used as a signal to poll event. |
| + PollEvents(); |
| + |
| // TODO(BillOrr): Give real values when VSync loop is hooked up. This is the |
| // presentation time for the frame. Just returning a default value for now |
| // since we don't have VSync hooked up. |