blob: 7da3dd24b5984481eaadafcb5f4b736d47245092 [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/ui/scenic/lib/scheduling/delegating_frame_scheduler.h"
#include "src/lib/fxl/logging.h"
#include "src/ui/scenic/lib/scheduling/id.h"
namespace scheduling {
DelegatingFrameScheduler::DelegatingFrameScheduler(
std::shared_ptr<FrameScheduler> frame_scheduler) {
if (frame_scheduler) {
SetFrameScheduler(frame_scheduler);
}
}
void DelegatingFrameScheduler::SetFrameRenderer(fxl::WeakPtr<FrameRenderer> frame_renderer) {
CallWhenFrameSchedulerAvailable(
[frame_renderer = frame_renderer](FrameScheduler* frame_scheduler) {
frame_scheduler->SetFrameRenderer(frame_renderer);
});
};
void DelegatingFrameScheduler::AddSessionUpdater(fxl::WeakPtr<SessionUpdater> session_updater) {
CallWhenFrameSchedulerAvailable(
[session_updater = session_updater](FrameScheduler* frame_scheduler) {
frame_scheduler->AddSessionUpdater(session_updater);
});
};
void DelegatingFrameScheduler::SetRenderContinuously(bool render_continuously) {
CallWhenFrameSchedulerAvailable([render_continuously](FrameScheduler* frame_scheduler) {
frame_scheduler->SetRenderContinuously(render_continuously);
});
}
PresentId DelegatingFrameScheduler::RegisterPresent(
SessionId session_id, std::variant<OnPresentedCallback, Present2Info> present_information,
std::vector<zx::event> release_fences, PresentId present_id) {
// Assuming we never have several levels of delegating frame schedulers |present_id| should never
// be set.
FX_CHECK(present_id == kInvalidPresentId);
present_id = scheduling::GetNextPresentId();
CallWhenFrameSchedulerAvailable([session_id, present_information = std::move(present_information),
release_fences = std::move(release_fences),
present_id](FrameScheduler* frame_scheduler) mutable {
frame_scheduler->RegisterPresent(session_id, std::move(present_information),
std::move(release_fences), present_id);
});
return present_id;
}
void DelegatingFrameScheduler::SetOnUpdateFailedCallbackForSession(
SessionId session_id, FrameScheduler::OnSessionUpdateFailedCallback update_failed_callback) {
CallWhenFrameSchedulerAvailable([session_id, callback = std::move(update_failed_callback)](
FrameScheduler* frame_scheduler) mutable {
frame_scheduler->SetOnUpdateFailedCallbackForSession(session_id, std::move(callback));
});
}
void DelegatingFrameScheduler::ScheduleUpdateForSession(zx::time presentation_time,
SchedulingIdPair id_pair) {
CallWhenFrameSchedulerAvailable([presentation_time, id_pair](FrameScheduler* frame_scheduler) {
frame_scheduler->ScheduleUpdateForSession(presentation_time, id_pair);
});
}
void DelegatingFrameScheduler::GetFuturePresentationInfos(
zx::duration requested_prediction_span, GetFuturePresentationInfosCallback callback) {
FX_DCHECK(callback);
CallWhenFrameSchedulerAvailable([requested_prediction_span, callback = std::move(callback)](
FrameScheduler* frame_scheduler) mutable {
frame_scheduler->GetFuturePresentationInfos(requested_prediction_span, std::move(callback));
});
}
void DelegatingFrameScheduler::SetOnFramePresentedCallbackForSession(
SessionId session, OnFramePresentedCallback callback) {
if (callback) {
CallWhenFrameSchedulerAvailable(
[session, callback = std::move(callback)](FrameScheduler* frame_scheduler) mutable {
frame_scheduler->SetOnFramePresentedCallbackForSession(session, std::move(callback));
});
}
}
void DelegatingFrameScheduler::RemoveSession(SessionId session_id) {
CallWhenFrameSchedulerAvailable([session_id](FrameScheduler* frame_scheduler) {
frame_scheduler->RemoveSession(session_id);
});
}
void DelegatingFrameScheduler::CallWhenFrameSchedulerAvailable(
OnFrameSchedulerAvailableCallback callback) {
if (frame_scheduler_) {
callback(frame_scheduler_.get());
} else {
call_when_frame_scheduler_available_callbacks_.push_back(std::move(callback));
}
}
void DelegatingFrameScheduler::SetFrameScheduler(
const std::shared_ptr<FrameScheduler>& frame_scheduler) {
if (frame_scheduler_) {
FX_LOGS(ERROR) << "DelegatingFrameScheduler can only be set once.";
return;
}
if (!frame_scheduler) {
FX_LOGS(ERROR) << "DelegatingFrameScheduler cannot be set to a null value.";
return;
}
frame_scheduler_ = frame_scheduler;
for (auto& callback : call_when_frame_scheduler_available_callbacks_) {
callback(frame_scheduler_.get());
}
call_when_frame_scheduler_available_callbacks_.clear();
}
} // namespace scheduling