blob: 19f1ea8eea1df8c676c118120e7cd27e3e026dc0 [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 <fidl/fuchsia.sysmem/cpp/fidl.h>
#include <fidl/fuchsia.sysmem2.internal/cpp/fidl.h>
#include <fidl/fuchsia.sysmem2/cpp/fidl.h>
#include "lib/zx/channel.h"
#include "logging.h"
#include "logical_buffer_collection.h"
#include "node.h"
namespace sysmem_driver {
class BufferCollectionToken;
class BufferCollectionToken : public Node, 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(
fbl::RefPtr<LogicalBufferCollection> logical_buffer_collection,
NodeProperties* new_node_properties, const TokenServerEnd& server_end);
template <class CompleterSync>
void TokenReleaseImpl(ConnectionVersion version, CompleterSync& completer) {
// BufferCollectionToken has one additional error case we want to check, so check before calling
// Node::CloseImpl().
if (buffer_collection_request_) {
FailSync(FROM_HERE, version, completer, ZX_ERR_BAD_STATE,
"BufferCollectionToken::Close()/Release() when buffer_collection_request_");
// We're failing async - no need to try to fail sync.
return;
}
ReleaseImpl(version, completer);
}
void OnServerKoid();
void SetDispensableInternal();
bool is_done();
void SetBufferCollectionRequest(CollectionServerEnd buffer_collection_request);
std::optional<CollectionServerEnd> TakeBufferCollectionRequest();
void CloseServerBinding(zx_status_t epitaph) override;
// Node interface
bool ReadyForAllocation() override;
void OnBuffersAllocated(const AllocationResult& allocation_result) override;
BufferCollectionToken* buffer_collection_token() override;
const BufferCollectionToken* buffer_collection_token() const override;
BufferCollection* buffer_collection() override;
const BufferCollection* buffer_collection() const override;
BufferCollectionTokenGroup* buffer_collection_token_group() override;
const BufferCollectionTokenGroup* buffer_collection_token_group() const override;
OrphanedNode* orphaned_node() override;
const OrphanedNode* orphaned_node() const override;
bool is_connected_type() const override;
bool is_currently_connected() const override;
const char* node_type_string() const override;
ConnectionVersion connection_version() const override;
void Bind(TokenServerEnd server_end);
protected:
void BindInternalV1(zx::channel token_request,
ErrorHandlerWrapper error_handler_wrapper) override;
void BindInternalV2(zx::channel token_request,
ErrorHandlerWrapper error_handler_wrapper) override;
void BindInternalCombinedV1AndV2(zx::channel server_end,
ErrorHandlerWrapper error_handler_wrapper) override;
private:
friend class FidlServer;
// We keep the protocol impl separate to clarify which methods are protocol impl. Sysmem serves
// CombinedBufferCollectionToken which is both a V1 and V2 token at the same time. This allows
// us to keep the V1 and V2 protocols separate from a client's point of view, while also avoiding
// any pointless token version conversions. This happens to make sense for BufferCollectionToken
// V1 and V2 since the token is logically the same in all stateful aspects; this approach being
// used here is not an implicit proposal / promise to use this same approach for any hypothetical
// V3.
struct CombinedTokenServer
: public fidl::Server<fuchsia_sysmem2_internal::CombinedBufferCollectionToken> {
explicit CombinedTokenServer(BufferCollectionToken& parent) : parent_(parent) {}
// V1
//
// FIDL "compose Node" "interface" (identical among BufferCollection, BufferCollectionToken,
// BufferCollectionTokenGroup)
void SyncV1(SyncV1Completer::Sync& completer) override;
void DeprecatedSyncV1(DeprecatedSyncV1Completer::Sync& completer) override;
void CloseV1(CloseV1Completer::Sync& completer) override;
void DeprecatedCloseV1(DeprecatedCloseV1Completer::Sync& completer) override;
void GetNodeRefV1(GetNodeRefV1Completer::Sync& completer) override;
void IsAlternateForV1(IsAlternateForV1Request& request,
IsAlternateForV1Completer::Sync& completer) override;
void SetNameV1(SetNameV1Request& request, SetNameV1Completer::Sync& completer) override;
void DeprecatedSetNameV1(DeprecatedSetNameV1Request& request,
DeprecatedSetNameV1Completer::Sync& completer) override;
void SetDebugClientInfoV1(SetDebugClientInfoV1Request& request,
SetDebugClientInfoV1Completer::Sync& completer) override;
void DeprecatedSetDebugClientInfoV1(
DeprecatedSetDebugClientInfoV1Request& request,
DeprecatedSetDebugClientInfoV1Completer::Sync& completer) override;
void SetDebugTimeoutLogDeadlineV1(
SetDebugTimeoutLogDeadlineV1Request& request,
SetDebugTimeoutLogDeadlineV1Completer::Sync& completer) override;
void DeprecatedSetDebugTimeoutLogDeadlineV1(
DeprecatedSetDebugTimeoutLogDeadlineV1Request& request,
DeprecatedSetDebugTimeoutLogDeadlineV1Completer::Sync& completer) override;
void SetVerboseLoggingV1(SetVerboseLoggingV1Completer::Sync& completer) override;
// fuchsia.sysmem.BufferCollectionToken interface methods (see also "compose Node" methods
// above)
void DuplicateSyncV1(DuplicateSyncV1Request& request,
DuplicateSyncV1Completer::Sync& completer) override;
void DuplicateV1(DuplicateV1Request& request, DuplicateV1Completer::Sync& completer) override;
void CreateBufferCollectionTokenGroupV1(
CreateBufferCollectionTokenGroupV1Request& request,
CreateBufferCollectionTokenGroupV1Completer::Sync& completer) override;
void SetDispensableV1(SetDispensableV1Completer::Sync& completer) override;
// V2
//
// FIDL "compose Node" "interface" (identical among BufferCollection, BufferCollectionToken,
// BufferCollectionTokenGroup)
void SyncV2(SyncV2Completer::Sync& completer) override;
void ReleaseV2(ReleaseV2Completer::Sync& completer) override;
void GetNodeRefV2(GetNodeRefV2Completer::Sync& completer) override;
void IsAlternateForV2(IsAlternateForV2Request& request,
IsAlternateForV2Completer::Sync& completer) override;
void GetBufferCollectionIdV2(GetBufferCollectionIdV2Completer::Sync& completer) override;
void SetWeakV2(SetWeakV2Completer::Sync& completer) override;
void SetWeakOkV2(SetWeakOkV2Request& request, SetWeakOkV2Completer::Sync& completer) override;
void SetNameV2(SetNameV2Request& request, SetNameV2Completer::Sync& completer) override;
void SetDebugClientInfoV2(SetDebugClientInfoV2Request& request,
SetDebugClientInfoV2Completer::Sync& completer) override;
void SetDebugTimeoutLogDeadlineV2(
SetDebugTimeoutLogDeadlineV2Request& request,
SetDebugTimeoutLogDeadlineV2Completer::Sync& completer) override;
void SetVerboseLoggingV2(SetVerboseLoggingV2Completer::Sync& completer) override;
// fuchsia.sysmem.BufferCollectionToken interface methods (see also "compose Node" methods
// above)
void DuplicateSyncV2(DuplicateSyncV2Request& request,
DuplicateSyncV2Completer::Sync& completer) override;
void DuplicateV2(DuplicateV2Request& request, DuplicateV2Completer::Sync& completer) override;
void CreateBufferCollectionTokenGroupV2(
CreateBufferCollectionTokenGroupV2Request& request,
CreateBufferCollectionTokenGroupV2Completer::Sync& completer) override;
void SetDispensableV2(SetDispensableV2Completer::Sync& completer) override;
void handle_unknown_method(
fidl::UnknownMethodMetadata<fuchsia_sysmem2_internal::CombinedBufferCollectionToken>
metadata,
fidl::UnknownMethodCompleter::Sync& completer) override;
BufferCollectionToken& parent_;
};
BufferCollectionToken(fbl::RefPtr<LogicalBufferCollection> parent,
NodeProperties* new_node_properties, const TokenServerEnd& server_end);
void FailAsync(Location location, zx_status_t status, const char* format, ...);
template <typename Completer>
bool CommonDuplicateStage1(uint32_t rights_attenuation_mask, ConnectionVersion version,
Completer& completer, NodeProperties** out_node_properties);
template <typename Completer>
bool CommonCreateBufferCollectionTokenGroupStage1(ConnectionVersion version, Completer& completer,
NodeProperties** out_node_properties);
std::optional<CombinedTokenServer> server_;
std::optional<zx_status_t> async_failure_result_;
std::optional<fidl::ServerBindingRef<fuchsia_sysmem2_internal::CombinedBufferCollectionToken>>
server_binding_;
ConnectionVersion last_seen_version_ = ConnectionVersion::kNoConnection;
// 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)
std::optional<CollectionServerEnd> 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_