blob: f6a49aa5323dc0f9dd1d2852cc13a047ab18019a [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/intel-display/testing/fake-buffer-collection.h"
#include <fidl/fuchsia.images2/cpp/fidl.h>
#include <fidl/fuchsia.sysmem2/cpp/fidl.h>
#include <fidl/fuchsia.sysmem2/cpp/wire_test_base.h>
#include <lib/image-format/image_format.h>
#include <zircon/assert.h>
#include <cstddef>
#include <cstdint>
#include <cinttypes>
#include <fbl/algorithm.h>
#include <gtest/gtest.h>
namespace intel_display {
FakeBufferCollection::FakeBufferCollection(const FakeBufferCollectionConfig& config)
: config_(config) {}
FakeBufferCollection::~FakeBufferCollection() = default;
void FakeBufferCollection::SetConstraints(SetConstraintsRequestView request,
SetConstraintsCompleter::Sync& _completer) {
if (!request->has_constraints()) {
return;
}
fuchsia_sysmem2::wire::BufferMemoryConstraints& buffer_memory_constraints =
request->constraints().buffer_memory_constraints();
if (!config_.cpu_domain_supported) {
ZX_ASSERT(!buffer_memory_constraints.has_cpu_domain_supported() ||
!buffer_memory_constraints.cpu_domain_supported());
}
if (!config_.ram_domain_supported) {
ZX_ASSERT(!buffer_memory_constraints.has_ram_domain_supported() ||
!buffer_memory_constraints.ram_domain_supported());
}
if (!config_.inaccessible_domain_supported) {
ZX_ASSERT(!buffer_memory_constraints.has_inaccessible_domain_supported() ||
!buffer_memory_constraints.inaccessible_domain_supported());
}
constraints_ = fidl::ToNatural(request->constraints());
}
void FakeBufferCollection::CheckAllBuffersAllocated(
CheckAllBuffersAllocatedCompleter::Sync& completer) {
completer.Reply(fit::ok());
}
void FakeBufferCollection::WaitForAllBuffersAllocated(
WaitForAllBuffersAllocatedCompleter::Sync& completer) {
ZX_ASSERT(HasConstraints());
fidl::WireTableBuilder<fuchsia_sysmem2::wire::BufferCollectionInfo> info =
fuchsia_sysmem2::wire::BufferCollectionInfo::Builder(arena_);
std::vector<fuchsia_sysmem2::ImageFormatConstraints>& image_format_constraints_vector =
*constraints_.image_format_constraints();
auto image_format_constraints_it =
std::find_if(image_format_constraints_vector.begin(), image_format_constraints_vector.end(),
[&](const fuchsia_sysmem2::ImageFormatConstraints& c) {
return c.pixel_format_modifier() == config_.format_modifier;
});
ZX_ASSERT_MSG(image_format_constraints_it != image_format_constraints_vector.end(),
"Failed to find image format constraints with `format_modifier` 0x%" PRIx64,
static_cast<uint64_t>(config_.format_modifier));
fuchsia_sysmem2::ImageFormatConstraints& image_format_constraints = *image_format_constraints_it;
image_format_constraints.bytes_per_row_divisor(config_.bytes_per_row_divisor);
info.settings(fuchsia_sysmem2::wire::SingleBufferSettings::Builder(arena_)
.image_format_constraints(fidl::ToWire(arena_, image_format_constraints))
.Build());
int64_t width = config_.width_fallback_px;
int64_t height = config_.height_fallback_px;
const std::optional<fuchsia_math::SizeU>& required_min_size =
image_format_constraints.required_min_size();
if (required_min_size.has_value()) {
width = required_min_size->width();
height = required_min_size->height();
}
int64_t bytes_per_pixel = ImageFormatStrideBytesPerWidthPixel(
PixelFormatAndModifierFromConstraints(image_format_constraints));
int64_t bytes_per_row = fbl::round_up(static_cast<size_t>(width * bytes_per_pixel),
static_cast<uint32_t>(config_.bytes_per_row_divisor));
int64_t bytes_per_image = bytes_per_row * height;
zx::vmo vmo;
zx_status_t create_status = zx::vmo::create(bytes_per_image, 0, &vmo);
ZX_ASSERT(create_status == ZX_OK);
info.buffers(std::vector{fuchsia_sysmem2::wire::VmoBuffer::Builder(arena_)
.vmo(std::move(vmo))
.vmo_usable_start(0)
.Build()});
auto response =
fuchsia_sysmem2::wire::BufferCollectionWaitForAllBuffersAllocatedResponse::Builder(arena_)
.buffer_collection_info(info.Build())
.Build();
completer.Reply(fit::ok(&response));
}
void FakeBufferCollection::NotImplemented_(const std::string& name,
fidl::CompleterBase& completer) {
ZX_PANIC("Not implemented: %s", name.c_str());
}
} // namespace intel_display