blob: 6aad7bc91e50bd60157ce8994a57cf745d9e7ef2 [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-controller-banjo.h"
#include <fidl/fuchsia.hardware.display.engine/cpp/wire.h>
#include <fidl/fuchsia.hardware.display.types/cpp/wire.h>
#include <fidl/fuchsia.sysmem/cpp/wire.h>
#include <fuchsia/hardware/display/controller/c/banjo.h>
#include <lib/zx/channel.h>
#include <lib/zx/result.h>
#include <zircon/assert.h>
#include <zircon/errors.h>
#include <zircon/types.h>
#include <cstdint>
#include <utility>
#include <fbl/alloc_checker.h>
#include <fbl/vector.h>
#include "src/graphics/display/drivers/virtio-guest/v1/display-coordinator-events-banjo.h"
#include "src/graphics/display/lib/api-types-cpp/display-id.h"
#include "src/graphics/display/lib/api-types-cpp/driver-buffer-collection-id.h"
#include "src/graphics/display/lib/api-types-cpp/driver-capture-image-id.h"
#include "src/graphics/display/lib/api-types-cpp/driver-image-id.h"
#include "src/graphics/display/lib/api-types-cpp/image-buffer-usage.h"
#include "src/graphics/display/lib/api-types-cpp/image-metadata.h"
namespace virtio_display {
DisplayControllerBanjo::DisplayControllerBanjo(DisplayEngine* engine,
DisplayCoordinatorEventsBanjo* coordinator_events)
: engine_(*engine), coordinator_events_(*coordinator_events) {
ZX_DEBUG_ASSERT(engine != nullptr);
ZX_DEBUG_ASSERT(coordinator_events != nullptr);
}
DisplayControllerBanjo::~DisplayControllerBanjo() = default;
void DisplayControllerBanjo::DisplayControllerImplSetDisplayControllerInterface(
const display_controller_interface_protocol_t* display_controller_interface) {
ZX_DEBUG_ASSERT(display_controller_interface);
coordinator_events_.SetDisplayControllerInterface(display_controller_interface);
if (display_controller_interface != nullptr) {
engine_.OnCoordinatorConnected();
}
}
void DisplayControllerBanjo::DisplayControllerImplResetDisplayControllerInterface() {
coordinator_events_.SetDisplayControllerInterface(nullptr);
}
zx_status_t DisplayControllerBanjo::DisplayControllerImplImportBufferCollection(
uint64_t banjo_driver_buffer_collection_id, zx::channel banjo_buffer_collection_token) {
const display::DriverBufferCollectionId driver_buffer_collection_id =
display::ToDriverBufferCollectionId(banjo_driver_buffer_collection_id);
fidl::ClientEnd<fuchsia_sysmem::BufferCollectionToken> buffer_collection_token(
std::move(banjo_buffer_collection_token));
zx::result<> result = engine_.ImportBufferCollection(driver_buffer_collection_id,
std::move(buffer_collection_token));
return result.status_value();
}
zx_status_t DisplayControllerBanjo::DisplayControllerImplReleaseBufferCollection(
uint64_t banjo_driver_buffer_collection_id) {
const display::DriverBufferCollectionId driver_buffer_collection_id =
display::ToDriverBufferCollectionId(banjo_driver_buffer_collection_id);
zx::result<> result = engine_.ReleaseBufferCollection(driver_buffer_collection_id);
return result.status_value();
}
zx_status_t DisplayControllerBanjo::DisplayControllerImplImportImage(
const image_metadata_t* banjo_image_metadata, uint64_t banjo_driver_buffer_collection_id,
uint32_t index, uint64_t* out_image_handle) {
const display::ImageMetadata image_metadata(*banjo_image_metadata);
const display::DriverBufferCollectionId driver_buffer_collection_id =
display::ToDriverBufferCollectionId(banjo_driver_buffer_collection_id);
zx::result<display::DriverImageId> result =
engine_.ImportImage(image_metadata, driver_buffer_collection_id, index);
if (result.is_error()) {
return result.error_value();
}
*out_image_handle = display::ToBanjoDriverImageId(result.value());
return ZX_OK;
}
zx_status_t DisplayControllerBanjo::DisplayControllerImplImportImageForCapture(
uint64_t banjo_driver_buffer_collection_id, uint32_t index, uint64_t* out_capture_handle) {
const display::DriverBufferCollectionId driver_buffer_collection_id =
display::ToDriverBufferCollectionId(banjo_driver_buffer_collection_id);
zx::result<display::DriverCaptureImageId> result =
engine_.ImportImageForCapture(driver_buffer_collection_id, index);
if (result.is_error()) {
return result.error_value();
}
*out_capture_handle = display::ToBanjoDriverCaptureImageId(result.value());
return ZX_OK;
}
void DisplayControllerBanjo::DisplayControllerImplReleaseImage(uint64_t banjo_image_handle) {
const display::DriverImageId driver_image_id = display::ToDriverImageId(banjo_image_handle);
engine_.ReleaseImage(driver_image_id);
}
config_check_result_t DisplayControllerBanjo::DisplayControllerImplCheckConfiguration(
const display_config_t** banjo_display_configs, size_t banjo_display_configs_count,
client_composition_opcode_t* out_client_composition_opcodes_list,
size_t out_client_composition_opcodes_size, size_t* out_client_composition_opcodes_actual) {
cpp20::span<const display_config_t*> display_configs(banjo_display_configs,
banjo_display_configs_count);
cpp20::span<client_composition_opcode_t> out_client_composition_opcodes(
out_client_composition_opcodes_list, out_client_composition_opcodes_size);
return engine_.CheckConfiguration(display_configs, out_client_composition_opcodes,
out_client_composition_opcodes_actual);
}
void DisplayControllerBanjo::DisplayControllerImplApplyConfiguration(
const display_config_t** banjo_display_configs, size_t banjo_display_configs_count,
const config_stamp_t* banjo_config_stamp) {
cpp20::span<const display_config_t*> display_configs(banjo_display_configs,
banjo_display_configs_count);
return engine_.ApplyConfiguration(display_configs, banjo_config_stamp);
}
void DisplayControllerBanjo::DisplayControllerImplSetEld(uint64_t banjo_display_id,
const uint8_t* raw_eld_list,
size_t raw_eld_count) {
const display::DisplayId display_id = display::ToDisplayId(banjo_display_id);
const cpp20::span<const uint8_t> raw_eld(raw_eld_list, raw_eld_count);
engine_.SetEld(display_id, raw_eld);
}
zx_status_t DisplayControllerBanjo::DisplayControllerImplSetBufferCollectionConstraints(
const image_buffer_usage_t* banjo_image_buffer_usage,
uint64_t banjo_driver_buffer_collection_id) {
display::ImageBufferUsage image_buffer_usage =
display::ToImageBufferUsage(*banjo_image_buffer_usage);
const display::DriverBufferCollectionId driver_buffer_collection_id =
display::ToDriverBufferCollectionId(banjo_driver_buffer_collection_id);
zx::result<> result =
engine_.SetBufferCollectionConstraints(image_buffer_usage, driver_buffer_collection_id);
return result.status_value();
}
zx_status_t DisplayControllerBanjo::DisplayControllerImplSetDisplayPower(uint64_t banjo_display_id,
bool power_on) {
const display::DisplayId display_id = display::ToDisplayId(banjo_display_id);
zx::result<> result = engine_.SetDisplayPower(display_id, power_on);
return result.status_value();
}
bool DisplayControllerBanjo::DisplayControllerImplIsCaptureSupported() {
return engine_.IsCaptureSupported();
}
zx_status_t DisplayControllerBanjo::DisplayControllerImplStartCapture(
uint64_t banjo_capture_handle) {
const display::DriverCaptureImageId capture_image_id =
display::ToDriverCaptureImageId(banjo_capture_handle);
zx::result<> result = engine_.StartCapture(capture_image_id);
return result.status_value();
}
zx_status_t DisplayControllerBanjo::DisplayControllerImplReleaseCapture(
uint64_t banjo_capture_handle) {
const display::DriverCaptureImageId capture_image_id =
display::ToDriverCaptureImageId(banjo_capture_handle);
zx::result<> result = engine_.ReleaseCapture(capture_image_id);
return result.status_value();
}
bool DisplayControllerBanjo::DisplayControllerImplIsCaptureCompleted() {
return engine_.IsCaptureCompleted();
}
zx_status_t DisplayControllerBanjo::DisplayControllerImplSetMinimumRgb(uint8_t minimum_rgb) {
zx::result<> result = engine_.SetMinimumRgb(minimum_rgb);
return result.status_value();
}
zx_status_t DisplayControllerBanjo::DdkGetProtocol(uint32_t proto_id, void* out) {
auto* proto = static_cast<ddk::AnyProtocol*>(out);
proto->ctx = this;
if (proto_id == ZX_PROTOCOL_DISPLAY_CONTROLLER_IMPL) {
proto->ops = &display_controller_impl_protocol_ops_;
return ZX_OK;
}
return ZX_ERR_NOT_SUPPORTED;
}
} // namespace virtio_display