blob: 2c5637748f8098766ea7cdeb85d65a5873230298 [file] [log] [blame]
// Copyright 2025 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/display/vsync_source.h"
#include <lib/component/incoming/cpp/protocol.h>
#include <lib/syslog/cpp/macros.h>
#include <lib/trace/event.h>
#include <lib/zx/channel.h>
#include <zircon/types.h>
namespace display {
VsyncSource::VsyncSource(async_dispatcher_t* dispatcher, DisplayManager& display_manager,
fidl::ServerEnd<fuchsia_ui_display_singleton::VsyncSource> server_end,
std::function<void(fidl::UnbindInfo unbind_info)> close_handler)
: binding_(dispatcher, std::move(server_end), this, std::move(close_handler)),
display_manager_(display_manager) {}
VsyncSource::~VsyncSource() { UpdateVsyncCallbackRegistration(false); }
void VsyncSource::SetVsyncEnabled(SetVsyncEnabledRequest& request,
SetVsyncEnabledCompleter::Sync& completer) {
UpdateVsyncCallbackRegistration(request.enabled());
}
void VsyncSource::OnVsync(zx::time_monotonic timestamp,
display::WireConfigStamp applied_config_stamp) {
TRACE_DURATION("gfx", "VsyncSource::OnVsync");
if (!vsync_enabled())
return;
fuchsia_ui_display_singleton::VsyncSourceOnVsyncRequest values;
values.timestamp(timestamp.get());
auto result = fidl::SendEvent(binding_)->OnVsync(values);
if (result.is_error()) {
auto& error = result.error_value().error();
FX_LOGS(WARNING) << "OnVsync(): error while sending FIDL event: " << error.status() << " "
<< error.status_string();
}
}
void VsyncSource::UpdateVsyncCallbackRegistration(bool enabled) {
// No state change.
if (vsync_enabled() == enabled) {
return;
}
// This would be an issue for multiple display case. Revisit when that functionality is available.
auto* display = display_manager_.default_display();
if (!display) {
FX_LOGS(ERROR) << "No default display found. No vsyncs will be received.";
return;
}
if (enabled) {
callback_id_ = display->AddVsyncCallback(fit::bind_member<&VsyncSource::OnVsync>(this));
} else {
display->RemoveVsyncCallback(callback_id_.value());
callback_id_.reset();
}
}
bool VsyncSource::vsync_enabled() const { return callback_id_.has_value(); }
} // namespace display