blob: 82fd6a24bc301a138557defb27fbf342d2020ad9 [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.
#ifndef SRC_GRAPHICS_DISPLAY_DRIVERS_FAKE_SYSMEM_PROXY_DEVICE_H_
#define SRC_GRAPHICS_DISPLAY_DRIVERS_FAKE_SYSMEM_PROXY_DEVICE_H_
#include <fuchsia/hardware/platform/device/c/banjo.h>
#include <fuchsia/hardware/platform/device/cpp/banjo.h>
#include <fuchsia/hardware/sysmem/c/banjo.h>
#include <fuchsia/hardware/sysmem/cpp/banjo.h>
#include <fuchsia/sysmem/llcpp/fidl.h>
#include <fuchsia/sysmem2/llcpp/fidl.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/ddk/debug.h>
#include <lib/ddk/device.h>
#include <lib/ddk/driver.h>
#include <lib/inspect/cpp/inspect.h>
#include <lib/zx/bti.h>
#include <lib/zx/channel.h>
#include <limits>
#include <map>
#include <memory>
#include <unordered_set>
#include <ddktl/device.h>
#include <fbl/vector.h>
#include <region-alloc/region-alloc.h>
namespace sysmem_driver {
class Driver;
} // namespace sysmem_driver
namespace display {
class SysmemProxyDevice;
using DdkDeviceType2 = ddk::Device<SysmemProxyDevice, ddk::Messageable, ddk::Unbindable>;
// SysmemProxyDevice is a replacement for sysmem_driver::Device, intended for use in tests. Instead
// of instantiating a separate/hermetic Sysmem, SysmemProxyDevice connects to the allocator made
// available via the test-component's environment (i.e. "/svc/fuchsia.sysmem.Allocator"). This is
// useful for testing use-cases where multiple components must share the same allocator to negotiate
// which memory to use. For example, consider a scenario where Scenic wishes to use Vulkan for
// image compositing, and then wishes to display the resulting image on the screen. In order to do
// so, it must allocate an image which is acceptable both to Vulkan and the display driver.
class SysmemProxyDevice final : public DdkDeviceType2,
public ddk::SysmemProtocol<SysmemProxyDevice, ddk::base_protocol> {
public:
SysmemProxyDevice(zx_device_t* parent_device, sysmem_driver::Driver* parent_driver);
zx_status_t Bind();
//
// The rest of the methods are only valid to call after Bind().
//
// SysmemProtocol implementation.
zx_status_t SysmemConnect(zx::channel allocator_request);
zx_status_t SysmemRegisterHeap(uint64_t heap, zx::channel heap_connection);
zx_status_t SysmemRegisterSecureMem(zx::channel tee_connection);
zx_status_t SysmemUnregisterSecureMem();
// Ddk mixin implementations.
zx_status_t DdkMessage(fidl_incoming_msg_t* msg, fidl_txn_t* txn);
// Quits the async loop and joins with all spawned threads. Note: this doesn't tear down
// connections already made via SysmemConnect(). This is because these connections are made by
// passing the channel handle to an external Sysmem service, after which SysmemProxyDevice has no
// further knowledge of the connection.
void DdkUnbind(ddk::UnbindTxn txn);
void DdkRelease() { delete this; }
zx_status_t Connect(zx_handle_t allocator_request);
const sysmem_protocol_t* proto() const { return &in_proc_sysmem_protocol_; }
const zx_device_t* device() const { return zxdev_; }
async_dispatcher_t* dispatcher() { return loop_.dispatcher(); }
private:
sysmem_driver::Driver* parent_driver_ = nullptr;
inspect::Inspector inspector_;
async::Loop loop_;
thrd_t loop_thrd_;
ddk::PDevProtocolClient pdev_;
// In-proc sysmem interface. Essentially an in-proc version of
// fuchsia.sysmem.DriverConnector.
sysmem_protocol_t in_proc_sysmem_protocol_;
};
} // namespace display
#endif // SRC_GRAPHICS_DISPLAY_DRIVERS_FAKE_SYSMEM_PROXY_DEVICE_H_