Commit fdce2a68 authored by Will Cassella's avatar Will Cassella Committed by Commit Bot

Move all frame data responsibilities into XRFrameProvider

Previously, frame data management and scheduling responsibilities were
somewhat split between the XR and XRFrameProvider classes. This CL moves
all of those responsibilities into XRFrameProvider, leaving XR with the
more high-level session management responsibilities. It also allows
each session to have a different frame data provider instead of trying
to reuse the same provider for all inline-local sessions (which is
not the way the browser process sees things).

Finally, it makes VROrientationDevice suspend the sensor once all
inline-local sessions have been closed, and resume it once another is
created.

Bug: 1004008, 970854
Change-Id: Ia87ac5883ee179aa964522fc955c36add43d1370
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1849098
Commit-Queue: Will Cassella <cassew@google.com>
Reviewed-by: default avatarKlaus Weidner <klausw@chromium.org>
Reviewed-by: default avatarAlexander Cooper <alcooper@chromium.org>
Cr-Commit-Position: refs/heads/master@{#704769}
parent d91c0253
...@@ -150,6 +150,9 @@ void VROrientationDevice::RequestSession( ...@@ -150,6 +150,9 @@ void VROrientationDevice::RequestSession(
} }
std::move(callback).Run(std::move(session), std::move(controller)); std::move(callback).Run(std::move(session), std::move(controller));
// The sensor may have been suspended, so resume it now.
sensor_->Resume();
} }
void VROrientationDevice::EndMagicWindowSession(VROrientationSession* session) { void VROrientationDevice::EndMagicWindowSession(VROrientationSession* session) {
...@@ -157,10 +160,18 @@ void VROrientationDevice::EndMagicWindowSession(VROrientationSession* session) { ...@@ -157,10 +160,18 @@ void VROrientationDevice::EndMagicWindowSession(VROrientationSession* session) {
[session](const std::unique_ptr<VROrientationSession>& item) { [session](const std::unique_ptr<VROrientationSession>& item) {
return item.get() == session; return item.get() == session;
}); });
// If there are no more magic window sessions, suspend the sensor until we get
// a new one.
if (magic_window_sessions_.empty()) {
sensor_->Suspend();
}
} }
void VROrientationDevice::GetInlineFrameData( void VROrientationDevice::GetInlineFrameData(
mojom::XRFrameDataProvider::GetFrameDataCallback callback) { mojom::XRFrameDataProvider::GetFrameDataCallback callback) {
// Orientation sessions should never be exclusive or presenting.
DCHECK(!HasExclusiveSession());
if (!inline_poses_enabled_) { if (!inline_poses_enabled_) {
std::move(callback).Run(nullptr); std::move(callback).Run(nullptr);
return; return;
......
...@@ -18,10 +18,12 @@ VROrientationSession::VROrientationSession( ...@@ -18,10 +18,12 @@ VROrientationSession::VROrientationSession(
: magic_window_receiver_(this, std::move(magic_window_receiver)), : magic_window_receiver_(this, std::move(magic_window_receiver)),
session_controller_receiver_(this, std::move(session_receiver)), session_controller_receiver_(this, std::move(session_receiver)),
device_(device) { device_(device) {
// Unretained is safe because the receiver will close when we are destroyed, magic_window_receiver_.set_disconnect_handler(
// so we won't receive any more callbacks after that. base::BindOnce(&VROrientationSession::OnMojoConnectionError,
session_controller_receiver_.set_disconnect_handler(base::BindOnce( weak_ptr_factory_.GetWeakPtr()));
&VROrientationSession::OnMojoConnectionError, base::Unretained(this))); session_controller_receiver_.set_disconnect_handler(
base::BindOnce(&VROrientationSession::OnMojoConnectionError,
weak_ptr_factory_.GetWeakPtr()));
} }
VROrientationSession::~VROrientationSession() = default; VROrientationSession::~VROrientationSession() = default;
......
...@@ -56,6 +56,9 @@ class DEVICE_VR_EXPORT VROrientationSession ...@@ -56,6 +56,9 @@ class DEVICE_VR_EXPORT VROrientationSession
mojo::Receiver<mojom::XRSessionController> session_controller_receiver_; mojo::Receiver<mojom::XRSessionController> session_controller_receiver_;
device::VROrientationDevice* device_; device::VROrientationDevice* device_;
bool restrict_frame_data_ = true; bool restrict_frame_data_ = true;
// This must be the last member
base::WeakPtrFactory<VROrientationSession> weak_ptr_factory_{this};
}; };
} // namespace device } // namespace device
......
...@@ -466,17 +466,6 @@ XRFrameProvider* XR::frameProvider() { ...@@ -466,17 +466,6 @@ XRFrameProvider* XR::frameProvider() {
return frame_provider_; return frame_provider_;
} }
bool XR::CanRequestNonImmersiveFrameData() const {
return !!magic_window_provider_;
}
void XR::GetNonImmersiveFrameData(
device::mojom::blink::XRFrameDataRequestOptionsPtr options,
device::mojom::blink::XRFrameDataProvider::GetFrameDataCallback callback) {
DCHECK(CanRequestNonImmersiveFrameData());
magic_window_provider_->GetFrameData(std::move(options), std::move(callback));
}
const device::mojom::blink::XREnvironmentIntegrationProviderAssociatedPtr& const device::mojom::blink::XREnvironmentIntegrationProviderAssociatedPtr&
XR::xrEnvironmentProviderPtr() { XR::xrEnvironmentProviderPtr() {
return environment_provider_; return environment_provider_;
...@@ -936,16 +925,18 @@ void XR::OnRequestSessionReturned( ...@@ -936,16 +925,18 @@ void XR::OnRequestSessionReturned(
std::move(session_ptr->display_info), session_ptr->uses_input_eventing, std::move(session_ptr->display_info), session_ptr->uses_input_eventing,
enabled_features); enabled_features);
frameProvider()->OnSessionStarted(session, std::move(session_ptr));
if (query->mode() == XRSession::kModeImmersiveVR || if (query->mode() == XRSession::kModeImmersiveVR ||
query->mode() == XRSession::kModeImmersiveAR) { query->mode() == XRSession::kModeImmersiveAR) {
frameProvider()->BeginImmersiveSession(session, std::move(session_ptr));
if (environment_integration) { if (environment_integration) {
// See Task Sources spreadsheet for more information: // See Task Sources spreadsheet for more information:
// https://docs.google.com/spreadsheets/d/1b-dus1Ug3A8y0lX0blkmOjJILisUASdj8x9YN_XMwYc/view // https://docs.google.com/spreadsheets/d/1b-dus1Ug3A8y0lX0blkmOjJILisUASdj8x9YN_XMwYc/view
frameProvider()->GetDataProvider()->GetEnvironmentIntegrationProvider( frameProvider()
mojo::MakeRequest(&environment_provider_, ->GetImmersiveDataProvider()
GetExecutionContext()->GetTaskRunner( ->GetEnvironmentIntegrationProvider(mojo::MakeRequest(
TaskType::kMiscPlatformAPI))); &environment_provider_, GetExecutionContext()->GetTaskRunner(
TaskType::kMiscPlatformAPI)));
environment_provider_.set_connection_error_handler(WTF::Bind( environment_provider_.set_connection_error_handler(WTF::Bind(
&XR::OnEnvironmentProviderDisconnect, WrapWeakPersistent(this))); &XR::OnEnvironmentProviderDisconnect, WrapWeakPersistent(this)));
LocalFrame* frame = GetFrame(); LocalFrame* frame = GetFrame();
...@@ -991,14 +982,9 @@ void XR::OnRequestSessionReturned( ...@@ -991,14 +982,9 @@ void XR::OnRequestSessionReturned(
if (query->mode() == XRSession::kModeImmersiveVR && if (query->mode() == XRSession::kModeImmersiveVR &&
session->UsesInputEventing()) { session->UsesInputEventing()) {
frameProvider()->GetDataProvider()->SetInputSourceButtonListener( frameProvider()->GetImmersiveDataProvider()->SetInputSourceButtonListener(
session->GetInputClickListener()); session->GetInputClickListener());
} }
} else {
magic_window_provider_.reset();
magic_window_provider_.Bind(std::move(session_ptr->data_provider));
magic_window_provider_.set_disconnect_handler(WTF::Bind(
&XR::OnMagicWindowProviderDisconnect, WrapWeakPersistent(this)));
} }
UseCounter::Count(ExecutionContext::From(query->GetScriptState()), UseCounter::Count(ExecutionContext::From(query->GetScriptState()),
...@@ -1125,17 +1111,6 @@ void XR::OnEnvironmentProviderDisconnect() { ...@@ -1125,17 +1111,6 @@ void XR::OnEnvironmentProviderDisconnect() {
environment_provider_.reset(); environment_provider_.reset();
} }
// Ends all non-immersive sessions when the magic window provider got
// disconnected.
void XR::OnMagicWindowProviderDisconnect() {
for (auto& session : sessions_) {
if (!session->immersive() && !session->ended()) {
session->ForceEnd();
}
}
magic_window_provider_.reset();
}
void XR::Trace(blink::Visitor* visitor) { void XR::Trace(blink::Visitor* visitor) {
visitor->Trace(frame_provider_); visitor->Trace(frame_provider_);
visitor->Trace(sessions_); visitor->Trace(sessions_);
......
...@@ -59,11 +59,6 @@ class XR final : public EventTargetWithInlineData, ...@@ -59,11 +59,6 @@ class XR final : public EventTargetWithInlineData,
XRFrameProvider* frameProvider(); XRFrameProvider* frameProvider();
bool CanRequestNonImmersiveFrameData() const;
void GetNonImmersiveFrameData(
device::mojom::blink::XRFrameDataRequestOptionsPtr,
device::mojom::blink::XRFrameDataProvider::GetFrameDataCallback);
const device::mojom::blink::XREnvironmentIntegrationProviderAssociatedPtr& const device::mojom::blink::XREnvironmentIntegrationProviderAssociatedPtr&
xrEnvironmentProviderPtr(); xrEnvironmentProviderPtr();
...@@ -283,7 +278,6 @@ class XR final : public EventTargetWithInlineData, ...@@ -283,7 +278,6 @@ class XR final : public EventTargetWithInlineData,
void Dispose(); void Dispose();
void OnEnvironmentProviderDisconnect(); void OnEnvironmentProviderDisconnect();
void OnMagicWindowProviderDisconnect();
// Indicates whether use of requestDevice has already been logged. // Indicates whether use of requestDevice has already been logged.
bool did_log_supports_immersive_ = false; bool did_log_supports_immersive_ = false;
...@@ -302,10 +296,7 @@ class XR final : public EventTargetWithInlineData, ...@@ -302,10 +296,7 @@ class XR final : public EventTargetWithInlineData,
Member<XRFrameProvider> frame_provider_; Member<XRFrameProvider> frame_provider_;
HeapHashSet<WeakMember<XRSession>> sessions_; HeapHashSet<WeakMember<XRSession>> sessions_;
mojo::Remote<device::mojom::blink::VRService> service_; mojo::Remote<device::mojom::blink::VRService> service_;
mojo::Remote<device::mojom::blink::XRFrameDataProvider>
magic_window_provider_;
device::mojom::blink::XREnvironmentIntegrationProviderAssociatedPtr device::mojom::blink::XREnvironmentIntegrationProviderAssociatedPtr
environment_provider_; environment_provider_;
mojo::Receiver<device::mojom::blink::VRServiceClient> receiver_{this}; mojo::Receiver<device::mojom::blink::VRServiceClient> receiver_{this};
......
...@@ -27,9 +27,9 @@ class XRFrameProvider final : public GarbageCollected<XRFrameProvider> { ...@@ -27,9 +27,9 @@ class XRFrameProvider final : public GarbageCollected<XRFrameProvider> {
XRSession* immersive_session() const { return immersive_session_; } XRSession* immersive_session() const { return immersive_session_; }
void BeginImmersiveSession(XRSession* session, void OnSessionStarted(XRSession* session,
device::mojom::blink::XRSessionPtr session_ptr); device::mojom::blink::XRSessionPtr session_ptr);
void OnImmersiveSessionEnded(); void OnSessionEnded(XRSession* session);
void RequestFrame(XRSession*); void RequestFrame(XRSession*);
...@@ -41,7 +41,7 @@ class XRFrameProvider final : public GarbageCollected<XRFrameProvider> { ...@@ -41,7 +41,7 @@ class XRFrameProvider final : public GarbageCollected<XRFrameProvider> {
void Dispose(); void Dispose();
void OnFocusChanged(); void OnFocusChanged();
device::mojom::blink::XRFrameDataProvider* GetDataProvider() { device::mojom::blink::XRFrameDataProvider* GetImmersiveDataProvider() {
return immersive_data_provider_.get(); return immersive_data_provider_.get();
} }
...@@ -49,32 +49,47 @@ class XRFrameProvider final : public GarbageCollected<XRFrameProvider> { ...@@ -49,32 +49,47 @@ class XRFrameProvider final : public GarbageCollected<XRFrameProvider> {
private: private:
void OnImmersiveFrameData(device::mojom::blink::XRFrameDataPtr data); void OnImmersiveFrameData(device::mojom::blink::XRFrameDataPtr data);
void OnNonImmersiveFrameData(device::mojom::blink::XRFrameDataPtr data); void OnNonImmersiveFrameData(XRSession* session,
device::mojom::blink::XRFrameDataPtr data);
// Posts a request to the |XRFrameDataProvider| for the given session for
// frame data. If the given session has no provider, it will be given null
// frame data.
void RequestNonImmersiveFrameData(XRSession* session);
// TODO(https://crbug.com/955819): options should be removed from those // TODO(https://crbug.com/955819): options should be removed from those
// methods as they'll no longer be passed on a per-frame basis. // methods as they'll no longer be passed on a per-frame basis.
void ScheduleImmersiveFrame( void ScheduleImmersiveFrame(
device::mojom::blink::XRFrameDataRequestOptionsPtr options); device::mojom::blink::XRFrameDataRequestOptionsPtr options);
// Schedules an animation frame to service all non-immersive requesting
// sessions. This will be postponed if there is a currently running immmersive
// session.
void ScheduleNonImmersiveFrame( void ScheduleNonImmersiveFrame(
device::mojom::blink::XRFrameDataRequestOptionsPtr options); device::mojom::blink::XRFrameDataRequestOptionsPtr options);
void OnProviderConnectionError(); void OnProviderConnectionError(XRSession* session);
void ProcessScheduledFrame(device::mojom::blink::XRFrameDataPtr frame_data, void ProcessScheduledFrame(device::mojom::blink::XRFrameDataPtr frame_data,
double high_res_now_ms); double high_res_now_ms);
const Member<XR> xr_; const Member<XR> xr_;
// Immersive session state
Member<XRSession> immersive_session_; Member<XRSession> immersive_session_;
Member<XRFrameTransport> frame_transport_; Member<XRFrameTransport> frame_transport_;
// Non-immersive Sessions which have requested a frame update.
HeapVector<Member<XRSession>> requesting_sessions_;
HeapVector<Member<XRSession>> processing_sessions_;
mojo::Remote<device::mojom::blink::XRPresentationProvider>
presentation_provider_;
mojo::Remote<device::mojom::blink::XRFrameDataProvider> mojo::Remote<device::mojom::blink::XRFrameDataProvider>
immersive_data_provider_; immersive_data_provider_;
device::mojom::blink::VRPosePtr frame_pose_; mojo::Remote<device::mojom::blink::XRPresentationProvider>
immersive_presentation_provider_;
device::mojom::blink::VRPosePtr immersive_frame_pose_;
bool is_immersive_frame_position_emulated_ = false;
// Non-immersive session state
HeapHashMap<Member<XRSession>,
mojo::Remote<device::mojom::blink::XRFrameDataProvider>>
non_immersive_data_providers_;
HeapHashMap<Member<XRSession>, device::mojom::blink::VRPosePtr>
requesting_sessions_;
// This frame ID is XR-specific and is used to track when frames arrive at the // This frame ID is XR-specific and is used to track when frames arrive at the
// XR compositor so that it knows which poses to use, when to apply bounds // XR compositor so that it knows which poses to use, when to apply bounds
...@@ -82,12 +97,9 @@ class XRFrameProvider final : public GarbageCollected<XRFrameProvider> { ...@@ -82,12 +97,9 @@ class XRFrameProvider final : public GarbageCollected<XRFrameProvider> {
int16_t frame_id_ = -1; int16_t frame_id_ = -1;
bool pending_immersive_vsync_ = false; bool pending_immersive_vsync_ = false;
bool pending_non_immersive_vsync_ = false; bool pending_non_immersive_vsync_ = false;
bool vsync_connection_failed_ = false;
base::Optional<gpu::MailboxHolder> buffer_mailbox_holder_; base::Optional<gpu::MailboxHolder> buffer_mailbox_holder_;
bool last_has_focus_ = false; bool last_has_focus_ = false;
bool emulated_position_ = false;
}; };
} // namespace blink } // namespace blink
......
...@@ -802,11 +802,8 @@ void XRSession::ForceEnd() { ...@@ -802,11 +802,8 @@ void XRSession::ForceEnd() {
canvas_input_provider_ = nullptr; canvas_input_provider_ = nullptr;
} }
// If this session is the active immersive session, notify the frameProvider // Notify the frame provider that we've ended
// that it's ended. xr_->frameProvider()->OnSessionEnded(this);
if (xr_->frameProvider()->immersive_session() == this) {
xr_->frameProvider()->OnImmersiveSessionEnded();
}
DispatchEvent(*XRSessionEvent::Create(event_type_names::kEnd, this)); DispatchEvent(*XRSessionEvent::Create(event_type_names::kEnd, this));
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment