blob: 17fecc523102c098912c9e3fb04263119927beb9 [file] [log] [blame]
// Copyright 2020 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/drivers/misc/goldfish_control/device_local_heap.h"
#include <fuchsia/sysmem2/llcpp/fidl.h>
#include <lib/async-loop/default.h>
#include <lib/async-loop/loop.h>
#include <lib/async/cpp/task.h>
#include <lib/fidl/llcpp/server.h>
#include <lib/fit/function.h>
#include <memory>
#include <ddk/debug.h>
#include <fbl/intrusive_double_list.h>
#include "src/graphics/drivers/misc/goldfish_control/control_device.h"
namespace goldfish {
namespace {
static const char* kTag = "goldfish-device-local-heap";
llcpp::fuchsia::sysmem2::HeapProperties GetHeapProperties() {
auto coherency_domain_support =
std::make_unique<llcpp::fuchsia::sysmem2::CoherencyDomainSupport>();
*coherency_domain_support =
llcpp::fuchsia::sysmem2::CoherencyDomainSupport::Builder(
std::make_unique<llcpp::fuchsia::sysmem2::CoherencyDomainSupport::Frame>())
.set_cpu_supported(std::make_unique<bool>(false))
.set_ram_supported(std::make_unique<bool>(false))
.set_inaccessible_supported(std::make_unique<bool>(true))
.build();
return llcpp::fuchsia::sysmem2::HeapProperties::Builder(
std::make_unique<llcpp::fuchsia::sysmem2::HeapProperties::Frame>())
.set_coherency_domain_support(std::move(coherency_domain_support))
.set_need_clear(std::make_unique<bool>(false))
.build();
}
} // namespace
// static
std::unique_ptr<DeviceLocalHeap> DeviceLocalHeap::Create(Control* control) {
// Using `new` to access a non-public constructor.
return std::unique_ptr<DeviceLocalHeap>(new DeviceLocalHeap(control));
}
DeviceLocalHeap::DeviceLocalHeap(Control* control) : Heap(control, kTag) {}
DeviceLocalHeap::~DeviceLocalHeap() = default;
void DeviceLocalHeap::AllocateVmo(uint64_t size, AllocateVmoCompleter::Sync& completer) {
zx::vmo vmo;
zx_status_t status = zx::vmo::create(size, 0, &vmo);
if (status != ZX_OK) {
zxlogf(ERROR, "[%s] zx::vmo::create() failed - size: %lu status: %d", kTag, size, status);
completer.Reply(status, zx::vmo{});
} else {
completer.Reply(ZX_OK, std::move(vmo));
}
}
void DeviceLocalHeap::CreateResource(::zx::vmo vmo,
llcpp::fuchsia::sysmem2::SingleBufferSettings buffer_settings,
CreateResourceCompleter::Sync& completer) {
uint64_t id = control()->RegisterBufferHandle(vmo);
if (id == ZX_KOID_INVALID) {
completer.Reply(ZX_ERR_INVALID_ARGS, 0u);
} else {
completer.Reply(ZX_OK, id);
}
}
void DeviceLocalHeap::DestroyResource(uint64_t id, DestroyResourceCompleter::Sync& completer) {
control()->FreeBufferHandle(id);
completer.Reply();
}
void DeviceLocalHeap::Bind(zx::channel server_request) {
BindWithHeapProperties(std::move(server_request), GetHeapProperties());
}
} // namespace goldfish