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(
}
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) {
......@@ -157,10 +160,18 @@ void VROrientationDevice::EndMagicWindowSession(VROrientationSession* session) {
[session](const std::unique_ptr<VROrientationSession>& item) {
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(
mojom::XRFrameDataProvider::GetFrameDataCallback callback) {
// Orientation sessions should never be exclusive or presenting.
DCHECK(!HasExclusiveSession());
if (!inline_poses_enabled_) {
std::move(callback).Run(nullptr);
return;
......
......@@ -18,10 +18,12 @@ VROrientationSession::VROrientationSession(
: magic_window_receiver_(this, std::move(magic_window_receiver)),
session_controller_receiver_(this, std::move(session_receiver)),
device_(device) {
// Unretained is safe because the receiver will close when we are destroyed,
// so we won't receive any more callbacks after that.
session_controller_receiver_.set_disconnect_handler(base::BindOnce(
&VROrientationSession::OnMojoConnectionError, base::Unretained(this)));
magic_window_receiver_.set_disconnect_handler(
base::BindOnce(&VROrientationSession::OnMojoConnectionError,
weak_ptr_factory_.GetWeakPtr()));
session_controller_receiver_.set_disconnect_handler(
base::BindOnce(&VROrientationSession::OnMojoConnectionError,
weak_ptr_factory_.GetWeakPtr()));
}
VROrientationSession::~VROrientationSession() = default;
......
......@@ -56,6 +56,9 @@ class DEVICE_VR_EXPORT VROrientationSession
mojo::Receiver<mojom::XRSessionController> session_controller_receiver_;
device::VROrientationDevice* device_;
bool restrict_frame_data_ = true;
// This must be the last member
base::WeakPtrFactory<VROrientationSession> weak_ptr_factory_{this};
};
} // namespace device
......
......@@ -466,17 +466,6 @@ XRFrameProvider* XR::frameProvider() {
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&
XR::xrEnvironmentProviderPtr() {
return environment_provider_;
......@@ -936,16 +925,18 @@ void XR::OnRequestSessionReturned(
std::move(session_ptr->display_info), session_ptr->uses_input_eventing,
enabled_features);
frameProvider()->OnSessionStarted(session, std::move(session_ptr));
if (query->mode() == XRSession::kModeImmersiveVR ||
query->mode() == XRSession::kModeImmersiveAR) {
frameProvider()->BeginImmersiveSession(session, std::move(session_ptr));
if (environment_integration) {
// See Task Sources spreadsheet for more information:
// https://docs.google.com/spreadsheets/d/1b-dus1Ug3A8y0lX0blkmOjJILisUASdj8x9YN_XMwYc/view
frameProvider()->GetDataProvider()->GetEnvironmentIntegrationProvider(
mojo::MakeRequest(&environment_provider_,
GetExecutionContext()->GetTaskRunner(
TaskType::kMiscPlatformAPI)));
frameProvider()
->GetImmersiveDataProvider()
->GetEnvironmentIntegrationProvider(mojo::MakeRequest(
&environment_provider_, GetExecutionContext()->GetTaskRunner(
TaskType::kMiscPlatformAPI)));
environment_provider_.set_connection_error_handler(WTF::Bind(
&XR::OnEnvironmentProviderDisconnect, WrapWeakPersistent(this)));
LocalFrame* frame = GetFrame();
......@@ -991,14 +982,9 @@ void XR::OnRequestSessionReturned(
if (query->mode() == XRSession::kModeImmersiveVR &&
session->UsesInputEventing()) {
frameProvider()->GetDataProvider()->SetInputSourceButtonListener(
frameProvider()->GetImmersiveDataProvider()->SetInputSourceButtonListener(
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()),
......@@ -1125,17 +1111,6 @@ void XR::OnEnvironmentProviderDisconnect() {
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) {
visitor->Trace(frame_provider_);
visitor->Trace(sessions_);
......
......@@ -59,11 +59,6 @@ class XR final : public EventTargetWithInlineData,
XRFrameProvider* frameProvider();
bool CanRequestNonImmersiveFrameData() const;
void GetNonImmersiveFrameData(
device::mojom::blink::XRFrameDataRequestOptionsPtr,
device::mojom::blink::XRFrameDataProvider::GetFrameDataCallback);
const device::mojom::blink::XREnvironmentIntegrationProviderAssociatedPtr&
xrEnvironmentProviderPtr();
......@@ -283,7 +278,6 @@ class XR final : public EventTargetWithInlineData,
void Dispose();
void OnEnvironmentProviderDisconnect();
void OnMagicWindowProviderDisconnect();
// Indicates whether use of requestDevice has already been logged.
bool did_log_supports_immersive_ = false;
......@@ -302,10 +296,7 @@ class XR final : public EventTargetWithInlineData,
Member<XRFrameProvider> frame_provider_;
HeapHashSet<WeakMember<XRSession>> sessions_;
mojo::Remote<device::mojom::blink::VRService> service_;
mojo::Remote<device::mojom::blink::XRFrameDataProvider>
magic_window_provider_;
device::mojom::blink::XREnvironmentIntegrationProviderAssociatedPtr
environment_provider_;
mojo::Receiver<device::mojom::blink::VRServiceClient> receiver_{this};
......
......@@ -27,9 +27,9 @@ class XRFrameProvider final : public GarbageCollected<XRFrameProvider> {
XRSession* immersive_session() const { return immersive_session_; }
void BeginImmersiveSession(XRSession* session,
device::mojom::blink::XRSessionPtr session_ptr);
void OnImmersiveSessionEnded();
void OnSessionStarted(XRSession* session,
device::mojom::blink::XRSessionPtr session_ptr);
void OnSessionEnded(XRSession* session);
void RequestFrame(XRSession*);
......@@ -41,7 +41,7 @@ class XRFrameProvider final : public GarbageCollected<XRFrameProvider> {
void Dispose();
void OnFocusChanged();
device::mojom::blink::XRFrameDataProvider* GetDataProvider() {
device::mojom::blink::XRFrameDataProvider* GetImmersiveDataProvider() {
return immersive_data_provider_.get();
}
......@@ -49,32 +49,47 @@ class XRFrameProvider final : public GarbageCollected<XRFrameProvider> {
private:
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
// methods as they'll no longer be passed on a per-frame basis.
void ScheduleImmersiveFrame(
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(
device::mojom::blink::XRFrameDataRequestOptionsPtr options);
void OnProviderConnectionError();
void OnProviderConnectionError(XRSession* session);
void ProcessScheduledFrame(device::mojom::blink::XRFrameDataPtr frame_data,
double high_res_now_ms);
const Member<XR> xr_;
// Immersive session state
Member<XRSession> immersive_session_;
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>
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
// XR compositor so that it knows which poses to use, when to apply bounds
......@@ -82,12 +97,9 @@ class XRFrameProvider final : public GarbageCollected<XRFrameProvider> {
int16_t frame_id_ = -1;
bool pending_immersive_vsync_ = false;
bool pending_non_immersive_vsync_ = false;
bool vsync_connection_failed_ = false;
base::Optional<gpu::MailboxHolder> buffer_mailbox_holder_;
bool last_has_focus_ = false;
bool emulated_position_ = false;
};
} // namespace blink
......
......@@ -802,11 +802,8 @@ void XRSession::ForceEnd() {
canvas_input_provider_ = nullptr;
}
// If this session is the active immersive session, notify the frameProvider
// that it's ended.
if (xr_->frameProvider()->immersive_session() == this) {
xr_->frameProvider()->OnImmersiveSessionEnded();
}
// Notify the frame provider that we've ended
xr_->frameProvider()->OnSessionEnded(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