blob: ffcf1faf7932f9cf2b02e181db5a0e898d249e10 [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/devices/lib/sysmem/sysmem.h"
#include <fidl/fuchsia.sysmem/cpp/hlcpp_conversion.h>
#include <fidl/fuchsia.sysmem2/cpp/hlcpp_conversion.h>
#include <lib/sysmem-version/sysmem-version.h>
namespace sysmem {
fuchsia_sysmem::wire::PixelFormat banjo_to_fidl(const pixel_format_t& source) {
return {
.type = static_cast<fuchsia_sysmem::wire::PixelFormatType>(source.type),
.has_format_modifier = source.has_format_modifier,
.format_modifier =
{
.value = source.has_format_modifier ? source.format_modifier.value
: fuchsia_sysmem::wire::kFormatModifierNone,
},
};
}
image_format_2_t fidl_to_banjo(const fuchsia_sysmem::wire::ImageFormat2& source) {
return {
.pixel_format =
{
.type = static_cast<pixel_format_type_t>(source.pixel_format.type),
.has_format_modifier = source.pixel_format.has_format_modifier,
.format_modifier =
{
.value = source.pixel_format.has_format_modifier
? source.pixel_format.format_modifier.value
: fuchsia_sysmem::wire::kFormatModifierNone,
},
},
.coded_width = source.coded_width,
.coded_height = source.coded_height,
.bytes_per_row = source.bytes_per_row,
.display_width = source.display_width,
.display_height = source.display_height,
.layers = source.layers,
.color_space = {static_cast<color_space_type_t>(source.color_space.type)},
.has_pixel_aspect_ratio = source.has_pixel_aspect_ratio,
.pixel_aspect_ratio_width = source.pixel_aspect_ratio_width,
.pixel_aspect_ratio_height = source.pixel_aspect_ratio_height,
};
}
fuchsia_sysmem::wire::ImageFormat2 banjo_to_fidl(const image_format_2_t& source) {
return {
.pixel_format = banjo_to_fidl(source.pixel_format),
.coded_width = source.coded_width,
.coded_height = source.coded_height,
.bytes_per_row = source.bytes_per_row,
.display_width = source.display_width,
.display_height = source.display_height,
.layers = source.layers,
.color_space =
{
.type = static_cast<fuchsia_sysmem::wire::ColorSpaceType>(source.color_space.type),
},
.has_pixel_aspect_ratio = source.has_pixel_aspect_ratio,
.pixel_aspect_ratio_width = source.pixel_aspect_ratio_width,
.pixel_aspect_ratio_height = source.pixel_aspect_ratio_height,
};
}
buffer_collection_info_2_t fidl_to_banjo(const fuchsia::sysmem::BufferCollectionInfo_2& source) {
buffer_collection_info_2_t destination = {
.buffer_count = source.buffer_count,
.settings =
{
.buffer_settings =
{
.size_bytes = source.settings.buffer_settings.size_bytes,
.is_physically_contiguous =
source.settings.buffer_settings.is_physically_contiguous,
.is_secure = source.settings.buffer_settings.is_secure,
.coherency_domain = static_cast<coherency_domain_t>(
source.settings.buffer_settings.coherency_domain),
.heap = static_cast<heap_type_t>(source.settings.buffer_settings.heap),
},
.has_image_format_constraints = source.settings.has_image_format_constraints,
},
};
if (source.settings.has_image_format_constraints) {
const fuchsia::sysmem::ImageFormatConstraints& image_format_constraints =
source.settings.image_format_constraints;
destination.settings.image_format_constraints = {
.pixel_format =
{
.type =
static_cast<pixel_format_type_t>(image_format_constraints.pixel_format.type),
.has_format_modifier = image_format_constraints.pixel_format.has_format_modifier,
.format_modifier =
{.value = image_format_constraints.pixel_format.has_format_modifier
? image_format_constraints.pixel_format.format_modifier.value
: fuchsia_sysmem::wire::kFormatModifierNone},
},
.color_spaces_count = image_format_constraints.color_spaces_count,
.min_coded_width = image_format_constraints.min_coded_width,
.max_coded_width = image_format_constraints.max_coded_width,
.min_coded_height = image_format_constraints.min_coded_height,
.max_coded_height = image_format_constraints.max_coded_height,
.min_bytes_per_row = image_format_constraints.min_bytes_per_row,
.max_bytes_per_row = image_format_constraints.max_bytes_per_row,
.max_coded_width_times_coded_height =
image_format_constraints.max_coded_width_times_coded_height,
.layers = image_format_constraints.layers,
.coded_width_divisor = image_format_constraints.coded_width_divisor,
.coded_height_divisor = image_format_constraints.coded_height_divisor,
.bytes_per_row_divisor = image_format_constraints.bytes_per_row_divisor,
.start_offset_divisor = image_format_constraints.start_offset_divisor,
.display_width_divisor = image_format_constraints.display_width_divisor,
.display_height_divisor = image_format_constraints.display_height_divisor,
.required_min_coded_width = image_format_constraints.required_min_coded_width,
.required_max_coded_width = image_format_constraints.required_max_coded_width,
.required_min_coded_height = image_format_constraints.required_min_coded_height,
.required_max_coded_height = image_format_constraints.required_max_coded_height,
.required_min_bytes_per_row = image_format_constraints.required_min_bytes_per_row,
.required_max_bytes_per_row = image_format_constraints.required_max_bytes_per_row,
};
for (size_t i = 0; i < image_format_constraints.color_spaces_count; i++) {
destination.settings.image_format_constraints.color_space[i].type =
static_cast<color_space_type_t>(image_format_constraints.color_space[i].type);
}
}
for (size_t i = 0; i < source.buffer_count; i++) {
destination.buffers[i].vmo = source.buffers[i].vmo.get();
destination.buffers[i].vmo_usable_start = source.buffers[i].vmo_usable_start;
}
return destination;
}
buffer_collection_info_2_t fidl_to_banjo(const fuchsia::sysmem2::BufferCollectionInfo& source) {
// we don't actually use the dup'ed vmo handles for anything (see below)
auto v1_result =
sysmem::V1MoveFromV2BufferCollectionInfo(fidl::HLCPPToNatural(fidl::Clone(source)));
ZX_ASSERT(v1_result.is_ok());
auto v1_natural = std::move(v1_result.value());
auto v1 = fidl::NaturalToHLCPP(std::move(v1_natural));
// the semantics of fidl_to_banjo are that the source handle values are directly placed in the
// returned buffer_collection_info_2_t
for (uint32_t i = 0; i < v1.buffer_count; ++i) {
// we temporarily let v1 believe it owns the lifetimes of the vmos, even though source actually
// owns the lifetimes of the vmos - this also closes the un-needed vmo handles dup'ed above
v1.buffers[i].vmo.reset(source.buffers()[i].vmo().get());
}
// result gets raw zx_handle_t values from source
auto result = fidl_to_banjo(v1);
// the lifetimes of the vmos are actually owned by source not v1, so release v1's vmo handles and
// intentionally ignore the released handle value as they're still owned by source; this ends the
// lifetime shenanigans, aside from the fact that fidl_to_banjo is returning a banjo struct with
// handle lifetimes controlled by source, but ... it's a banjo struct, so ... it is what it is.
for (uint32_t i = 0; i < v1.buffer_count; ++i) {
(void)v1.buffers[i].vmo.release();
}
return result;
}
} // namespace sysmem