blob: e4483b02555a4b2c6421567bbc89d537c60cd77a [file] [log] [blame]
// Copyright 2021 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/coordinator/display-info.h"
#include <lib/driver/logging/cpp/logger.h>
#include <lib/fit/result.h>
#include <lib/zx/result.h>
#include <lib/zx/time.h>
#include <zircon/assert.h>
#include <zircon/device/audio.h>
#include <zircon/errors.h>
#include <zircon/syscalls.h>
#include <zircon/time.h>
#include <cinttypes>
#include <cstddef>
#include <cstring>
#include <utility>
#include <fbl/alloc_checker.h>
#include <fbl/string_printf.h>
#include "src/graphics/display/drivers/coordinator/added-display-info.h"
#include "src/graphics/display/lib/api-types/cpp/display-id.h"
#include "src/graphics/display/lib/api-types/cpp/mode-and-id.h"
namespace display_coordinator {
DisplayInfo::DisplayInfo(display::DisplayId display_id,
fbl::Vector<display::PixelFormat> pixel_formats,
fbl::Vector<display::ModeAndId> preferred_modes)
: IdMappable(display_id),
preferred_modes(std::move(preferred_modes)),
pixel_formats(std::move(pixel_formats)) {
ZX_DEBUG_ASSERT(display_id != display::kInvalidDisplayId);
}
DisplayInfo::~DisplayInfo() = default;
void DisplayInfo::InitializeInspect(inspect::Node* parent_node) {
node = parent_node->CreateChild(fbl::StringPrintf("display-%" PRIu64, id().value()).c_str());
for (const display::ModeAndId& mode_and_id : preferred_modes) {
auto child = node.CreateChild(
fbl::StringPrintf("preferred-mode-%" PRIu16, mode_and_id.id().value()).c_str());
child.CreateDouble("vsync-hz", mode_and_id.mode().refresh_rate_millihertz() / 1000.0,
&properties);
child.CreateInt("width-pixels", mode_and_id.mode().active_area().width(), &properties);
child.CreateInt("height-pixels", mode_and_id.mode().active_area().height(), &properties);
properties.emplace(std::move(child));
}
}
// static
zx::result<std::unique_ptr<DisplayInfo>> DisplayInfo::Create(AddedDisplayInfo added_display_info) {
ZX_DEBUG_ASSERT(added_display_info.display_id != display::kInvalidDisplayId);
display::DisplayId display_id = added_display_info.display_id;
fbl::Vector<display::Mode> preferred_modes = std::move(added_display_info.preferred_modes);
if (preferred_modes.is_empty()) {
fdf::error("Failed to create DisplayInfo: The display doesn't provide valid preferred modes.");
return zx::error(ZX_ERR_INVALID_ARGS);
}
fbl::AllocChecker alloc_checker;
fbl::Vector<display::ModeAndId> preferred_modes_and_ids;
preferred_modes_and_ids.reserve(preferred_modes.size(), &alloc_checker);
if (!alloc_checker.check()) {
fdf::error("Failed to allocate preferred modes and ids");
return zx::error(ZX_ERR_NO_MEMORY);
}
// TODO(https://fxbug.dev/316631158): This assumes preferred modes have
// `ModeId`s from 1 to `preferred_modes.size()`. The mapping between `ModeId`
// and `Mode` should be made available to the display engine driver.
for (uint16_t i = 0; i < preferred_modes.size(); ++i) {
ZX_DEBUG_ASSERT_MSG(preferred_modes_and_ids.size() < preferred_modes.size(),
"The push_back() below was not supposed to allocate memory, but it might");
preferred_modes_and_ids.push_back({{
.id = display::ModeId(i + 1),
.mode = preferred_modes[i],
}},
&alloc_checker);
ZX_DEBUG_ASSERT_MSG(alloc_checker.check(),
"The push_back() above failed to allocate memory; "
"it was not supposed to allocate at all");
}
auto display_info = fbl::make_unique_checked<DisplayInfo>(
&alloc_checker, display_id, std::move(added_display_info.pixel_formats),
std::move(preferred_modes_and_ids));
if (!alloc_checker.check()) {
fdf::error("Failed to allocate DisplayInfo for display ID: {}", display_id.value());
return zx::error(ZX_ERR_NO_MEMORY);
}
return zx::ok(std::move(display_info));
}
// TODO(https://fxbug.dev/439019150): Provide display panel metadata when
// it's available.
int DisplayInfo::GetHorizontalSizeMm() const { return 0; }
int DisplayInfo::GetVerticalSizeMm() const { return 0; }
std::string_view DisplayInfo::GetManufacturerName() const { return {}; }
std::string DisplayInfo::GetMonitorName() const { return {}; }
std::string DisplayInfo::GetMonitorSerial() const { return {}; }
} // namespace display_coordinator