blob: 30f4694c3dbd8cb60b04d507a23cb95ac406d140 [file] [log] [blame]
// Copyright 2019 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_DEVICES_SYSMEM_DRIVERS_SYSMEM_BUFFER_COLLECTION_TOKEN_H_
#define SRC_DEVICES_SYSMEM_DRIVERS_SYSMEM_BUFFER_COLLECTION_TOKEN_H_
#include <fuchsia/sysmem/c/fidl.h>
#include <fuchsia/sysmem/llcpp/fidl.h>
#include <lib/fidl-async-2/fidl_server.h>
#include <lib/fidl-async-2/simple_binding.h>
#include "logging.h"
#include "logical_buffer_collection.h"
#include "node.h"
namespace sysmem_driver {
class BufferCollectionToken;
class BufferCollectionToken : public Node,
public fidl::WireInterface<fuchsia_sysmem::BufferCollectionToken>,
public LoggingMixin {
public:
~BufferCollectionToken() override;
// The returned reference is owned by new_node_properties, which in turn is owned by
// logical_buffer_collection->root_.
static BufferCollectionToken& EmplaceInTree(
Device* parent_device, fbl::RefPtr<LogicalBufferCollection> logical_buffer_collection,
NodeProperties* new_node_properties);
void SetErrorHandler(fit::function<void(zx_status_t)> error_handler) {
error_handler_ = std::move(error_handler);
}
void Bind(fidl::ServerEnd<fuchsia_sysmem::BufferCollectionToken> token_request);
void Duplicate(
uint32_t rights_attenuation_mask,
fidl::ServerEnd<fuchsia_sysmem::BufferCollectionToken> buffer_collection_token_request,
DuplicateCompleter::Sync& completer) override;
void Sync(SyncCompleter::Sync&) override;
void Close(CloseCompleter::Sync&) override;
void SetName(uint32_t priority, fidl::StringView name, SetNameCompleter::Sync&) override;
void SetDebugClientInfo(fidl::StringView, uint64_t id,
SetDebugClientInfoCompleter::Sync&) override;
void SetDebugTimeoutLogDeadline(int64_t deadline,
SetDebugTimeoutLogDeadlineCompleter::Sync&) override;
void SetDispensable(SetDispensableCompleter::Sync& completer) override;
void SetDebugClientInfoInternal(std::string name, uint64_t id);
void SetServerKoid(zx_koid_t server_koid);
zx_koid_t server_koid();
void SetDispensableInternal();
bool is_done();
bool was_unfound_token() const { return was_unfound_token_; }
void SetBufferCollectionRequest(zx::channel buffer_collection_request);
zx::channel TakeBufferCollectionRequest();
void CloseChannel(zx_status_t epitaph);
// Node interface
bool ReadyForAllocation() override;
void OnBuffersAllocated(const AllocationResult& allocation_result) override;
void Fail(zx_status_t epitaph) override;
BufferCollectionToken* buffer_collection_token() override;
const BufferCollectionToken* buffer_collection_token() const override;
BufferCollection* buffer_collection() override;
const BufferCollection* buffer_collection() const override;
OrphanedNode* orphaned_node() override;
const OrphanedNode* orphaned_node() const override;
bool is_connected() const override;
private:
friend class FidlServer;
BufferCollectionToken(Device* parent_device, fbl::RefPtr<LogicalBufferCollection> parent,
NodeProperties* new_node_properties);
void FailAsync(Location location, zx_status_t status, const char* format, ...);
template <typename Completer>
void FailSync(Location location, Completer& completer, zx_status_t status, const char* format,
...);
Device* parent_device_ = nullptr;
// Cached from parent_.
TableSet& table_set_;
std::optional<zx_status_t> async_failure_result_;
fit::function<void(zx_status_t)> error_handler_;
zx_koid_t server_koid_ = ZX_KOID_INVALID;
// Becomes true on the first Close() or BindSharedCollection(). This being
// true means a channel close is not fatal to the LogicalBufferCollection.
// However, if the client sends a redundant Close(), that is fatal to the
// BufferCollectionToken and fatal to the LogicalBufferCollection.
bool is_done_ = false;
bool was_unfound_token_ = false;
std::optional<fidl::ServerBindingRef<fuchsia_sysmem::BufferCollectionToken>> server_binding_;
// This is set up to once during
// LogicalBufferCollection::BindSharedCollection(), and essentially curries
// the buffer_collection_request past the processing of any remaining
// inbound messages on the BufferCollectionToken before starting to serve
// the BufferCollection that the token was exchanged for. This way, inbound
// Duplicate() messages in the BufferCollectionToken are seen before any
// BufferCollection::SetConstraints() (which might otherwise try to allocate
// buffers too soon before all tokens are gone).
zx::channel buffer_collection_request_;
inspect::Node inspect_node_;
inspect::UintProperty debug_id_property_;
inspect::StringProperty debug_name_property_;
inspect::ValueList properties_;
};
} // namespace sysmem_driver
#endif // SRC_DEVICES_SYSMEM_DRIVERS_SYSMEM_BUFFER_COLLECTION_TOKEN_H_