blob: 4cf98ee8200865e73cf35672c1640ab0dfcbf49b [file] [log] [blame] [edit]
// 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/graphics/display/lib/api-protocols/cpp/display-engine-events-fidl.h"
#include <fidl/fuchsia.hardware.display.engine/cpp/driver/wire.h>
#include <fidl/fuchsia.images2/cpp/wire.h>
#include <lib/stdcompat/span.h>
#include <lib/zx/time.h>
#include <zircon/assert.h>
#include <zircon/time.h>
#include <algorithm>
#include <array>
#include <cstdint>
#include <sdk/lib/driver/logging/cpp/logger.h>
#include "src/graphics/display/lib/api-types/cpp/display-id.h"
#include "src/graphics/display/lib/api-types/cpp/driver-config-stamp.h"
#include "src/graphics/display/lib/api-types/cpp/mode-and-id.h"
#include "src/graphics/display/lib/api-types/cpp/pixel-format.h"
namespace display {
DisplayEngineEventsFidl::DisplayEngineEventsFidl() = default;
DisplayEngineEventsFidl::~DisplayEngineEventsFidl() = default;
void DisplayEngineEventsFidl::SetListener(
fdf::ClientEnd<fuchsia_hardware_display_engine::EngineListener> client_end) {
if (client_end.is_valid()) {
fidl_client_ =
fdf::WireSyncClient<fuchsia_hardware_display_engine::EngineListener>(std::move(client_end));
} else {
fidl_client_ = fdf::WireSyncClient<fuchsia_hardware_display_engine::EngineListener>();
}
}
namespace {
// Used for all FIDL calls coming from this client.
constexpr fdf_arena_tag_t kArenaTag = 'DISP';
} // namespace
void DisplayEngineEventsFidl::OnDisplayAdded(
display::DisplayId display_id, cpp20::span<const display::ModeAndId> preferred_modes,
cpp20::span<const display::PixelFormat> pixel_formats) {
ZX_DEBUG_ASSERT(preferred_modes.size() <= kMaxPreferredModes);
ZX_DEBUG_ASSERT(pixel_formats.size() <= kMaxPixelFormats);
if (!fidl_client_.is_valid()) {
FDF_LOG(WARNING, "OnDisplayAdded() emitted with invalid event listener; event dropped");
return;
}
std::array<fuchsia_hardware_display_types::wire::Mode, kMaxPreferredModes>
fidl_preferred_modes_buffer;
for (size_t i = 0; i < preferred_modes.size(); ++i) {
fidl_preferred_modes_buffer[i] = preferred_modes[i].mode().ToFidl();
}
std::array<fuchsia_images2::wire::PixelFormat, kMaxPixelFormats> fidl_pixel_formats_buffer;
for (size_t i = 0; i < pixel_formats.size(); ++i) {
fidl_pixel_formats_buffer[i] = pixel_formats[i].ToFidl();
}
fuchsia_hardware_display_engine::wire::RawDisplayInfo fidl_display_info = {
.display_id = display_id.ToFidl(),
.preferred_modes = fidl::VectorView<fuchsia_hardware_display_types::wire::Mode>::FromExternal(
fidl_preferred_modes_buffer.data(), preferred_modes.size()),
.edid_bytes = {},
.pixel_formats = fidl::VectorView<fuchsia_images2::wire::PixelFormat>::FromExternal(
fidl_pixel_formats_buffer.data(), pixel_formats.size()),
};
// TODO(https://fxbug.dev/430058446): Eliminate the per-call dynamic memory
// allocation caused by fdf::Arena creation.
fdf::Arena arena(kArenaTag);
fidl::OneWayStatus fidl_transport_status =
fidl_client_.buffer(arena)->OnDisplayAdded(std::move(fidl_display_info));
if (!fidl_transport_status.ok()) {
FDF_LOG(ERROR, "FIDL error calling OnDisplayAdded: %s",
fidl_transport_status.error().FormatDescription().c_str());
}
}
void DisplayEngineEventsFidl::OnDisplayRemoved(display::DisplayId display_id) {
if (!fidl_client_.is_valid()) {
FDF_LOG(WARNING, "OnDisplayRemoved() emitted with invalid event listener; event dropped");
return;
}
// TODO(https://fxbug.dev/430058446): Eliminate the per-call dynamic memory
// allocation caused by fdf::Arena creation.
fdf::Arena arena(kArenaTag);
fidl::OneWayStatus fidl_transport_status =
fidl_client_.buffer(arena)->OnDisplayRemoved(display_id.ToFidl());
if (!fidl_transport_status.ok()) {
FDF_LOG(ERROR, "FIDL error calling OnDisplayRemoved: %s",
fidl_transport_status.error().FormatDescription().c_str());
}
}
void DisplayEngineEventsFidl::OnDisplayVsync(display::DisplayId display_id,
zx::time_monotonic timestamp,
display::DriverConfigStamp config_stamp) {
if (!fidl_client_.is_valid()) {
FDF_LOG(WARNING, "OnDisplayVsync() emitted with invalid event listener; event dropped");
return;
}
// TODO(https://fxbug.dev/430058446): Eliminate the per-call dynamic memory
// allocation caused by fdf::Arena creation.
fdf::Arena arena(kArenaTag);
fidl::OneWayStatus fidl_transport_status = fidl_client_.buffer(arena)->OnDisplayVsync(
display_id.ToFidl(), timestamp, config_stamp.ToFidl());
if (!fidl_transport_status.ok()) {
FDF_LOG(ERROR, "FIDL error calling OnDisplayVsync: %s",
fidl_transport_status.error().FormatDescription().c_str());
}
}
void DisplayEngineEventsFidl::OnCaptureComplete() {
if (!fidl_client_.is_valid()) {
FDF_LOG(WARNING, "OnCaptureComplete() emitted with invalid event listener; event dropped");
return;
}
// TODO(https://fxbug.dev/430058446): Eliminate the per-call dynamic memory
// allocation caused by fdf::Arena creation.
fdf::Arena arena(kArenaTag);
fidl::OneWayStatus fidl_transport_status = fidl_client_.buffer(arena)->OnCaptureComplete();
if (!fidl_transport_status.ok()) {
FDF_LOG(ERROR, "FIDL error calling OnCaptureComplete: %s",
fidl_transport_status.error().FormatDescription().c_str());
}
}
} // namespace display