blob: f6f08110ff26d62b069a61362793d786e3eff6bc [file] [log] [blame]
// Copyright 2024 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/graphics/display/drivers/virtio-guest/v1/display-coordinator-events-banjo.h"
#include <zircon/assert.h>
#include <zircon/time.h>
#include <cstdint>
#include <fbl/alloc_checker.h>
#include <fbl/auto_lock.h>
#include <fbl/vector.h>
#include "src/graphics/display/lib/api-types-cpp/config-stamp.h"
#include "src/graphics/display/lib/api-types-cpp/display-id.h"
namespace virtio_display {
DisplayCoordinatorEventsBanjo::DisplayCoordinatorEventsBanjo() = default;
DisplayCoordinatorEventsBanjo::~DisplayCoordinatorEventsBanjo() = default;
void DisplayCoordinatorEventsBanjo::SetDisplayControllerInterface(
const display_controller_interface_protocol_t* display_controller_interface) {
fbl::AutoLock event_lock(&event_mutex_);
if (display_controller_interface == nullptr) {
display_controller_interface = {};
return;
}
display_controller_interface_ = *display_controller_interface;
}
void DisplayCoordinatorEventsBanjo::OnDisplaysChanged(
cpp20::span<const added_display_args_t> added_displays,
cpp20::span<const display::DisplayId> removed_display_ids) {
fbl::Vector<uint64_t> banjo_removed_display_ids;
fbl::AllocChecker alloc_checker;
banjo_removed_display_ids.reserve(removed_display_ids.size(), &alloc_checker);
if (!alloc_checker.check()) {
return;
}
for (display::DisplayId removed_display_id : removed_display_ids) {
banjo_removed_display_ids.push_back(display::ToBanjoDisplayId(removed_display_id),
&alloc_checker);
ZX_DEBUG_ASSERT(banjo_removed_display_ids.size() <= removed_display_ids.size());
ZX_DEBUG_ASSERT_MSG(alloc_checker.check(),
"push_back() failed despite having the required capacity reserve()d");
}
fbl::AutoLock event_lock(&event_mutex_);
if (display_controller_interface_.ops == nullptr) {
return;
}
display_controller_interface_on_displays_changed(
&display_controller_interface_, added_displays.data(), added_displays.size(),
banjo_removed_display_ids.data(), banjo_removed_display_ids.size());
}
void DisplayCoordinatorEventsBanjo::OnDisplayVsync(display::DisplayId display_id,
zx::time timestamp,
display::ConfigStamp config_stamp) {
const uint64_t banjo_display_id = display::ToBanjoDisplayId(display_id);
const zx_time_t banjo_timestamp = timestamp.get();
const config_stamp_t banjo_config_stamp = display::ToBanjoConfigStamp(config_stamp);
fbl::AutoLock event_lock(&event_mutex_);
if (display_controller_interface_.ops == nullptr) {
return;
}
display_controller_interface_on_display_vsync(&display_controller_interface_, banjo_display_id,
banjo_timestamp, &banjo_config_stamp);
}
void DisplayCoordinatorEventsBanjo::OnCaptureComplete() {
fbl::AutoLock event_lock(&event_mutex_);
if (display_controller_interface_.ops == nullptr) {
return;
}
display_controller_interface_on_capture_complete(&display_controller_interface_);
}
} // namespace virtio_display