| // 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. |
| |
| #include "buffer_collection_token.h" |
| |
| #include <lib/ddk/trace/event.h> |
| #include <lib/zx/channel.h> |
| #include <zircon/errors.h> |
| #include <zircon/types.h> |
| |
| #include "device.h" |
| #include "node.h" |
| #include "node_properties.h" |
| |
| namespace sysmem_driver { |
| |
| BufferCollectionToken::~BufferCollectionToken() { |
| TRACE_DURATION("gfx", "BufferCollectionToken::~BufferCollectionToken", "this", this, |
| "logical_buffer_collection", &logical_buffer_collection()); |
| |
| // zx_koid_t values are never re-used during lifetime of running system, so |
| // it's fine that the channel is already closed (no possibility of re-use |
| // of value in the tracked set of values). |
| |
| // It's fine if server_koid() is ZX_KOID_INVALID - no effect in that case. |
| parent_device()->UntrackToken(this); |
| } |
| |
| void BufferCollectionToken::CloseServerBinding(zx_status_t epitaph) { |
| if (server_binding_.has_value()) { |
| if (last_seen_version_ == ConnectionVersion::kVersion1) { |
| server_binding_->Close(epitaph); |
| } else { |
| server_binding_->Close(ZX_ERR_INTERNAL); |
| } |
| } |
| server_binding_ = {}; |
| parent_device()->UntrackToken(this); |
| } |
| |
| // static |
| BufferCollectionToken& BufferCollectionToken::EmplaceInTree( |
| fbl::RefPtr<LogicalBufferCollection> logical_buffer_collection, |
| NodeProperties* new_node_properties, const TokenServerEnd& server_end) { |
| auto token = fbl::AdoptRef(new BufferCollectionToken(std::move(logical_buffer_collection), |
| new_node_properties, server_end)); |
| auto token_ptr = token.get(); |
| new_node_properties->SetNode(token); |
| return *token_ptr; |
| } |
| |
| void BufferCollectionToken::Bind(TokenServerEnd token_server_end) { |
| Node::Bind(TakeNodeServerEnd(std::move(token_server_end))); |
| } |
| |
| void BufferCollectionToken::BindInternalV1(zx::channel token_request, |
| ErrorHandlerWrapper error_handler_wrapper) { |
| ZX_PANIC("BufferCollectionToken never serves V1 alone - only combined V1 and V2"); |
| } |
| |
| void BufferCollectionToken::BindInternalV2(zx::channel token_request, |
| ErrorHandlerWrapper error_handler_wrapper) { |
| ZX_PANIC("BufferCollectionToken never serves V2 alone - only combined V1 and V2"); |
| } |
| |
| void BufferCollectionToken::BindInternalCombinedV1AndV2(zx::channel token_request, |
| ErrorHandlerWrapper error_handler_wrapper) { |
| server_.emplace(*this); |
| server_binding_ = |
| fidl::BindServer(parent_device()->dispatcher(), |
| TokenServerEndCombinedV1AndV2(std::move(token_request)), &server_.value(), |
| [error_handler_wrapper = std::move(error_handler_wrapper)]( |
| BufferCollectionToken::CombinedTokenServer* token, fidl::UnbindInfo info, |
| TokenServerEndCombinedV1AndV2 channel) { error_handler_wrapper(info); }); |
| } |
| |
| void BufferCollectionToken::CombinedTokenServer::DuplicateSyncV1( |
| DuplicateSyncV1Request& request, DuplicateSyncV1Completer::Sync& completer) { |
| TRACE_DURATION("gfx", "BufferCollectionToken::CombinedTokenServer::DuplicateSyncV1", "this", this, |
| "logical_buffer_collection", &parent_.logical_buffer_collection()); |
| parent_.last_seen_version_ = ConnectionVersion::kVersion1; |
| if (parent_.is_done_) { |
| // Probably a Close() followed by DuplicateSync(), which is illegal and |
| // causes the whole LogicalBufferCollection to fail. |
| parent_.FailSync(FROM_HERE, ConnectionVersion::kVersion1, completer, ZX_ERR_BAD_STATE, |
| "BufferCollectionToken::DuplicateSync() attempted when is_done_"); |
| return; |
| } |
| std::vector<fidl::ClientEnd<fuchsia_sysmem::BufferCollectionToken>> new_tokens; |
| |
| for (auto& rights_attenuation_mask : request.rights_attenuation_masks()) { |
| if (rights_attenuation_mask == 0) { |
| parent_.FailSync(FROM_HERE, ConnectionVersion::kVersion1, completer, ZX_ERR_INVALID_ARGS, |
| "DuplicateSync() rights_attenuation_mask 0 not permitted"); |
| return; |
| } |
| } |
| |
| for (auto& rights_attenuation_mask : request.rights_attenuation_masks()) { |
| auto token_endpoints = fidl::CreateEndpoints<fuchsia_sysmem::BufferCollectionToken>(); |
| if (!token_endpoints.is_ok()) { |
| parent_.FailSync(FROM_HERE, ConnectionVersion::kVersion1, completer, |
| token_endpoints.status_value(), |
| "BufferCollectionToken::DuplicateSync() failed to create token channel."); |
| return; |
| } |
| |
| NodeProperties* new_node_properties = |
| parent_.node_properties().NewChild(&parent_.logical_buffer_collection()); |
| if (rights_attenuation_mask != ZX_RIGHT_SAME_RIGHTS) { |
| new_node_properties->rights_attenuation_mask() &= |
| safe_cast<uint32_t>(rights_attenuation_mask); |
| } |
| parent_.logical_buffer_collection().CreateBufferCollectionTokenV1( |
| parent_.shared_logical_buffer_collection(), new_node_properties, |
| std::move(token_endpoints->server)); |
| new_tokens.push_back(std::move(token_endpoints->client)); |
| } |
| |
| fuchsia_sysmem2_internal::CombinedBufferCollectionTokenDuplicateSyncV1Response response; |
| response.tokens() = std::move(new_tokens); |
| completer.Reply(std::move(response)); |
| } |
| |
| void BufferCollectionToken::CombinedTokenServer::DuplicateSyncV2( |
| DuplicateSyncV2Request& request, DuplicateSyncV2Completer::Sync& completer) { |
| TRACE_DURATION("gfx", "BufferCollectionToken::CombiendTokenServer::DuplicateSyncV2", "this", this, |
| "logical_buffer_collection", &parent_.logical_buffer_collection()); |
| parent_.last_seen_version_ = ConnectionVersion::kVersion2; |
| if (parent_.is_done_) { |
| // Probably a Close() followed by DuplicateSync(), which is illegal and |
| // causes the whole LogicalBufferCollection to fail. |
| parent_.FailSync(FROM_HERE, ConnectionVersion::kVersion2, completer, ZX_ERR_BAD_STATE, |
| "DuplicateSync() attempted when is_done_"); |
| return; |
| } |
| if (!request.rights_attenuation_masks().has_value()) { |
| parent_.FailSync(FROM_HERE, ConnectionVersion::kVersion2, completer, ZX_ERR_BAD_STATE, |
| "DuplicateSync() requires rights_attenuation_masks set"); |
| return; |
| } |
| |
| for (auto& rights_attenuation_mask : *request.rights_attenuation_masks()) { |
| if (rights_attenuation_mask == 0) { |
| parent_.FailSync(FROM_HERE, ConnectionVersion::kVersion2, completer, ZX_ERR_INVALID_ARGS, |
| "DuplicateSync() rights_attenuation_mask 0 not permitted"); |
| return; |
| } |
| } |
| |
| std::vector<fidl::ClientEnd<fuchsia_sysmem2::BufferCollectionToken>> new_tokens; |
| for (auto& rights_attenuation_mask : request.rights_attenuation_masks().value()) { |
| auto token_endpoints = fidl::CreateEndpoints<fuchsia_sysmem2::BufferCollectionToken>(); |
| if (!token_endpoints.is_ok()) { |
| parent_.FailSync(FROM_HERE, ConnectionVersion::kVersion2, completer, |
| token_endpoints.status_value(), |
| "BufferCollectionToken::DuplicateSync() failed to create token channel."); |
| return; |
| } |
| |
| NodeProperties* new_node_properties = |
| parent_.node_properties().NewChild(&parent_.logical_buffer_collection()); |
| if (rights_attenuation_mask != ZX_RIGHT_SAME_RIGHTS) { |
| new_node_properties->rights_attenuation_mask() &= |
| safe_cast<uint32_t>(rights_attenuation_mask); |
| } |
| parent_.logical_buffer_collection().CreateBufferCollectionTokenV2( |
| parent_.shared_logical_buffer_collection(), new_node_properties, |
| std::move(token_endpoints->server)); |
| new_tokens.push_back(std::move(token_endpoints->client)); |
| } |
| |
| fuchsia_sysmem2_internal::CombinedBufferCollectionTokenDuplicateSyncV2Response response; |
| response.tokens() = std::move(new_tokens); |
| completer.Reply(std::move(response)); |
| } |
| |
| template <typename Completer> |
| bool BufferCollectionToken::CommonDuplicateStage1(uint32_t rights_attenuation_mask, |
| ConnectionVersion version, Completer& completer, |
| NodeProperties** out_node_properties) { |
| if (is_done_) { |
| // Probably a Close() followed by Duplicate(), which is illegal and |
| // causes the whole LogicalBufferCollection to fail. |
| FailSync(FROM_HERE, version, completer, ZX_ERR_BAD_STATE, |
| "BufferCollectionToken::Duplicate() attempted when is_done_"); |
| return false; |
| } |
| NodeProperties* new_node_properties = node_properties().NewChild(&logical_buffer_collection()); |
| if (rights_attenuation_mask == 0) { |
| logical_buffer_collection().LogClientError( |
| FROM_HERE, &node_properties(), |
| "rights_attenuation_mask of 0 is DEPRECATED - use ZX_RIGHT_SAME_RIGHTS instead."); |
| rights_attenuation_mask = ZX_RIGHT_SAME_RIGHTS; |
| } |
| if (rights_attenuation_mask != ZX_RIGHT_SAME_RIGHTS) { |
| new_node_properties->rights_attenuation_mask() &= rights_attenuation_mask; |
| } |
| *out_node_properties = new_node_properties; |
| return true; |
| } |
| |
| void BufferCollectionToken::CombinedTokenServer::DuplicateV1( |
| DuplicateV1Request& request, DuplicateV1Completer::Sync& completer) { |
| TRACE_DURATION("gfx", "BufferCollectionToken::DuplicateV1", "this", this, |
| "logical_buffer_collection", &parent_.logical_buffer_collection()); |
| parent_.last_seen_version_ = ConnectionVersion::kVersion1; |
| NodeProperties* new_node_properties; |
| if (!parent_.CommonDuplicateStage1(request.rights_attenuation_mask(), |
| ConnectionVersion::kVersion1, completer, |
| &new_node_properties)) { |
| return; |
| } |
| parent_.logical_buffer_collection().CreateBufferCollectionTokenV1( |
| parent_.shared_logical_buffer_collection(), new_node_properties, |
| std::move(request.token_request())); |
| } |
| |
| void BufferCollectionToken::CombinedTokenServer::DuplicateV2( |
| DuplicateV2Request& request, DuplicateV2Completer::Sync& completer) { |
| TRACE_DURATION("gfx", "BufferCollectionToken::DuplicateV2", "this", this, |
| "logical_buffer_collection", &parent_.logical_buffer_collection()); |
| parent_.last_seen_version_ = ConnectionVersion::kVersion2; |
| if (!request.rights_attenuation_mask().has_value()) { |
| parent_.FailSync(FROM_HERE, ConnectionVersion::kVersion2, completer, ZX_ERR_BAD_STATE, |
| "Duplicate() requires rights_attenuation_mask set"); |
| return; |
| } |
| if (!request.token_request().has_value()) { |
| parent_.FailSync(FROM_HERE, ConnectionVersion::kVersion2, completer, ZX_ERR_BAD_STATE, |
| "Duplicate() requires token_request set"); |
| return; |
| } |
| NodeProperties* new_node_properties; |
| if (!parent_.CommonDuplicateStage1(request.rights_attenuation_mask().value(), |
| ConnectionVersion::kVersion2, completer, |
| &new_node_properties)) { |
| return; |
| } |
| parent_.logical_buffer_collection().CreateBufferCollectionTokenV2( |
| parent_.shared_logical_buffer_collection(), new_node_properties, |
| std::move(request.token_request().value())); |
| } |
| |
| void BufferCollectionToken::CombinedTokenServer::SyncV1(SyncV1Completer::Sync& completer) { |
| parent_.last_seen_version_ = ConnectionVersion::kVersion1; |
| parent_.SyncImpl(ConnectionVersion::kVersion1, completer); |
| } |
| |
| void BufferCollectionToken::CombinedTokenServer::SyncV2(SyncV2Completer::Sync& completer) { |
| parent_.last_seen_version_ = ConnectionVersion::kVersion2; |
| parent_.SyncImpl(ConnectionVersion::kVersion2, completer); |
| } |
| |
| void BufferCollectionToken::CombinedTokenServer::DeprecatedSyncV1( |
| DeprecatedSyncV1Completer::Sync& completer) { |
| parent_.last_seen_version_ = ConnectionVersion::kVersion1; |
| parent_.SyncImpl(ConnectionVersion::kVersion1, completer); |
| } |
| |
| // Clean token close without causing LogicalBufferCollection failure. |
| void BufferCollectionToken::CombinedTokenServer::CloseV1(CloseV1Completer::Sync& completer) { |
| parent_.last_seen_version_ = ConnectionVersion::kVersion1; |
| parent_.TokenReleaseImpl(ConnectionVersion::kVersion1, completer); |
| } |
| |
| void BufferCollectionToken::CombinedTokenServer::ReleaseV2(ReleaseV2Completer::Sync& completer) { |
| parent_.last_seen_version_ = ConnectionVersion::kVersion2; |
| parent_.TokenReleaseImpl(ConnectionVersion::kVersion2, completer); |
| } |
| |
| void BufferCollectionToken::CombinedTokenServer::DeprecatedCloseV1( |
| DeprecatedCloseV1Completer::Sync& completer) { |
| parent_.last_seen_version_ = ConnectionVersion::kVersion1; |
| parent_.TokenReleaseImpl(ConnectionVersion::kVersion1, completer); |
| } |
| |
| void BufferCollectionToken::OnServerKoid() { |
| ZX_DEBUG_ASSERT(has_server_koid()); |
| parent_device()->TrackToken(this); |
| if (parent_device()->TryRemoveKoidFromUnfoundTokenList(server_koid())) { |
| set_unfound_node(); |
| // LogicalBufferCollection will print an error, since it might have useful client information. |
| } |
| } |
| |
| bool BufferCollectionToken::is_done() { return is_done_; } |
| |
| void BufferCollectionToken::SetBufferCollectionRequest( |
| CollectionServerEnd buffer_collection_request) { |
| if (is_done_ || buffer_collection_request_.has_value()) { |
| FailAsync(FROM_HERE, ZX_ERR_BAD_STATE, |
| "BufferCollectionToken::SetBufferCollectionRequest() attempted " |
| "when already is_done_ || buffer_collection_request_"); |
| return; |
| } |
| ZX_DEBUG_ASSERT(!buffer_collection_request_); |
| buffer_collection_request_ = std::move(buffer_collection_request); |
| } |
| |
| std::optional<CollectionServerEnd> BufferCollectionToken::TakeBufferCollectionRequest() { |
| return std::exchange(buffer_collection_request_, std::nullopt); |
| } |
| |
| void BufferCollectionToken::CombinedTokenServer::SetNameV1(SetNameV1Request& request, |
| SetNameV1Completer::Sync& completer) { |
| parent_.last_seen_version_ = ConnectionVersion::kVersion1; |
| parent_.SetNameImplV1(request, completer); |
| } |
| |
| void BufferCollectionToken::CombinedTokenServer::SetNameV2(SetNameV2Request& request, |
| SetNameV2Completer::Sync& completer) { |
| parent_.last_seen_version_ = ConnectionVersion::kVersion2; |
| parent_.SetNameImplV2(request, completer); |
| } |
| |
| void BufferCollectionToken::CombinedTokenServer::DeprecatedSetNameV1( |
| DeprecatedSetNameV1Request& request, DeprecatedSetNameV1Completer::Sync& completer) { |
| parent_.last_seen_version_ = ConnectionVersion::kVersion1; |
| parent_.SetNameImplV1(request, completer); |
| } |
| |
| void BufferCollectionToken::CombinedTokenServer::SetDebugClientInfoV1( |
| SetDebugClientInfoV1Request& request, SetDebugClientInfoV1Completer::Sync& completer) { |
| parent_.last_seen_version_ = ConnectionVersion::kVersion1; |
| parent_.SetDebugClientInfoImplV1(request, completer); |
| } |
| |
| void BufferCollectionToken::CombinedTokenServer::SetDebugClientInfoV2( |
| SetDebugClientInfoV2Request& request, SetDebugClientInfoV2Completer::Sync& completer) { |
| parent_.last_seen_version_ = ConnectionVersion::kVersion2; |
| parent_.SetDebugClientInfoImplV2(request, completer); |
| } |
| |
| void BufferCollectionToken::CombinedTokenServer::DeprecatedSetDebugClientInfoV1( |
| DeprecatedSetDebugClientInfoV1Request& request, |
| DeprecatedSetDebugClientInfoV1Completer::Sync& completer) { |
| parent_.last_seen_version_ = ConnectionVersion::kVersion1; |
| parent_.SetDebugClientInfoImplV1(request, completer); |
| } |
| |
| void BufferCollectionToken::CombinedTokenServer::SetDebugTimeoutLogDeadlineV1( |
| SetDebugTimeoutLogDeadlineV1Request& request, |
| SetDebugTimeoutLogDeadlineV1Completer::Sync& completer) { |
| parent_.last_seen_version_ = ConnectionVersion::kVersion1; |
| parent_.SetDebugTimeoutLogDeadlineImplV1(request, completer); |
| } |
| |
| void BufferCollectionToken::CombinedTokenServer::SetDebugTimeoutLogDeadlineV2( |
| SetDebugTimeoutLogDeadlineV2Request& request, |
| SetDebugTimeoutLogDeadlineV2Completer::Sync& completer) { |
| parent_.last_seen_version_ = ConnectionVersion::kVersion2; |
| parent_.SetDebugTimeoutLogDeadlineImplV2(request, completer); |
| } |
| |
| void BufferCollectionToken::CombinedTokenServer::DeprecatedSetDebugTimeoutLogDeadlineV1( |
| DeprecatedSetDebugTimeoutLogDeadlineV1Request& request, |
| DeprecatedSetDebugTimeoutLogDeadlineV1Completer::Sync& completer) { |
| parent_.last_seen_version_ = ConnectionVersion::kVersion1; |
| parent_.SetDebugTimeoutLogDeadlineImplV1(request, completer); |
| } |
| |
| void BufferCollectionToken::CombinedTokenServer::SetDispensableV1( |
| SetDispensableV1Completer::Sync& completer) { |
| parent_.last_seen_version_ = ConnectionVersion::kVersion1; |
| parent_.SetDispensableInternal(); |
| } |
| |
| void BufferCollectionToken::CombinedTokenServer::SetDispensableV2( |
| SetDispensableV2Completer::Sync& completer) { |
| parent_.last_seen_version_ = ConnectionVersion::kVersion2; |
| parent_.SetDispensableInternal(); |
| } |
| |
| void BufferCollectionToken::CombinedTokenServer::handle_unknown_method( |
| fidl::UnknownMethodMetadata<fuchsia_sysmem2_internal::CombinedBufferCollectionToken> metadata, |
| fidl::UnknownMethodCompleter::Sync& completer) { |
| parent_.FailSync(FROM_HERE, parent_.last_seen_version_, completer, ZX_ERR_NOT_SUPPORTED, |
| "token unknown method - ordinal: %" PRIx64, metadata.method_ordinal); |
| } |
| |
| void BufferCollectionToken::SetDispensableInternal() { |
| if (node_properties().error_propagation_mode() < |
| ErrorPropagationMode::kPropagateBeforeAllocation) { |
| node_properties().error_propagation_mode() = ErrorPropagationMode::kPropagateBeforeAllocation; |
| } |
| } |
| |
| template <typename Completer> |
| bool BufferCollectionToken::CommonCreateBufferCollectionTokenGroupStage1( |
| ConnectionVersion version, Completer& completer, NodeProperties** out_node_properties) { |
| if (is_done_) { |
| // Probably a Close() followed by Duplicate(), which is illegal and |
| // causes the whole LogicalBufferCollection to fail. |
| FailSync(FROM_HERE, version, completer, ZX_ERR_BAD_STATE, |
| "BufferCollectionToken::CreateBufferCollectionTokenGroup() attempted when is_done_"); |
| return false; |
| } |
| NodeProperties* new_node_properties = node_properties().NewChild(&logical_buffer_collection()); |
| *out_node_properties = new_node_properties; |
| return true; |
| } |
| |
| void BufferCollectionToken::CombinedTokenServer::CreateBufferCollectionTokenGroupV1( |
| CreateBufferCollectionTokenGroupV1Request& request, |
| CreateBufferCollectionTokenGroupV1Completer::Sync& completer) { |
| TRACE_DURATION("gfx", "BufferCollectionTokenGroup::CreateBufferCollectionTokenGroupV1", "this", |
| this, "logical_buffer_collection", &parent_.logical_buffer_collection()); |
| parent_.last_seen_version_ = ConnectionVersion::kVersion1; |
| NodeProperties* new_node_properties; |
| if (!parent_.CommonCreateBufferCollectionTokenGroupStage1(ConnectionVersion::kVersion1, completer, |
| &new_node_properties)) { |
| return; |
| } |
| parent_.logical_buffer_collection().CreateBufferCollectionTokenGroupV1( |
| parent_.shared_logical_buffer_collection(), new_node_properties, |
| std::move(request.group_request())); |
| } |
| |
| void BufferCollectionToken::CombinedTokenServer::CreateBufferCollectionTokenGroupV2( |
| CreateBufferCollectionTokenGroupV2Request& request, |
| CreateBufferCollectionTokenGroupV2Completer::Sync& completer) { |
| TRACE_DURATION("gfx", "BufferCollectionTokenGroup::CreateBufferCollectionTokenGroupV2", "this", |
| this, "logical_buffer_collection", &parent_.logical_buffer_collection()); |
| parent_.last_seen_version_ = ConnectionVersion::kVersion2; |
| if (!request.group_request().has_value()) { |
| parent_.FailSync(FROM_HERE, ConnectionVersion::kVersion2, completer, ZX_ERR_BAD_STATE, |
| "CreateBufferCollectionTokenGroup() requires group_request set"); |
| return; |
| } |
| NodeProperties* new_node_properties; |
| if (!parent_.CommonCreateBufferCollectionTokenGroupStage1(ConnectionVersion::kVersion2, completer, |
| &new_node_properties)) { |
| return; |
| } |
| parent_.logical_buffer_collection().CreateBufferCollectionTokenGroupV2( |
| parent_.shared_logical_buffer_collection(), new_node_properties, |
| std::move(request.group_request().value())); |
| } |
| |
| void BufferCollectionToken::CombinedTokenServer::SetVerboseLoggingV1( |
| SetVerboseLoggingV1Completer::Sync& completer) { |
| parent_.last_seen_version_ = ConnectionVersion::kVersion1; |
| parent_.SetVerboseLoggingImpl(ConnectionVersion::kVersion1, completer); |
| } |
| |
| void BufferCollectionToken::CombinedTokenServer::SetVerboseLoggingV2( |
| SetVerboseLoggingV2Completer::Sync& completer) { |
| parent_.last_seen_version_ = ConnectionVersion::kVersion2; |
| parent_.SetVerboseLoggingImpl(ConnectionVersion::kVersion2, completer); |
| } |
| |
| void BufferCollectionToken::CombinedTokenServer::GetNodeRefV1( |
| GetNodeRefV1Completer::Sync& completer) { |
| parent_.last_seen_version_ = ConnectionVersion::kVersion1; |
| parent_.GetNodeRefImplV1(completer); |
| } |
| |
| void BufferCollectionToken::CombinedTokenServer::GetNodeRefV2( |
| GetNodeRefV2Completer::Sync& completer) { |
| parent_.last_seen_version_ = ConnectionVersion::kVersion2; |
| parent_.GetNodeRefImplV2< |
| GetNodeRefV2Completer::Sync, |
| fuchsia_sysmem2_internal::CombinedBufferCollectionTokenGetNodeRefV2Response>(completer); |
| } |
| |
| void BufferCollectionToken::CombinedTokenServer::IsAlternateForV1( |
| IsAlternateForV1Request& request, IsAlternateForV1Completer::Sync& completer) { |
| parent_.last_seen_version_ = ConnectionVersion::kVersion1; |
| parent_.IsAlternateForImplV1< |
| IsAlternateForV1Request, IsAlternateForV1Completer::Sync, |
| fuchsia_sysmem2_internal::CombinedBufferCollectionTokenIsAlternateForV1Response>(request, |
| completer); |
| } |
| |
| void BufferCollectionToken::CombinedTokenServer::IsAlternateForV2( |
| IsAlternateForV2Request& request, IsAlternateForV2Completer::Sync& completer) { |
| parent_.last_seen_version_ = ConnectionVersion::kVersion2; |
| parent_.IsAlternateForImplV2< |
| IsAlternateForV2Request, IsAlternateForV2Completer::Sync, |
| fuchsia_sysmem2_internal::CombinedBufferCollectionTokenIsAlternateForV2Response>(request, |
| completer); |
| } |
| |
| void BufferCollectionToken::CombinedTokenServer::GetBufferCollectionIdV2( |
| GetBufferCollectionIdV2Completer::Sync& completer) { |
| parent_.last_seen_version_ = ConnectionVersion::kVersion2; |
| parent_.GetBufferCollectionIdImplV2< |
| GetBufferCollectionIdV2Completer::Sync, |
| fuchsia_sysmem2_internal::CombinedBufferCollectionTokenGetBufferCollectionIdV2Response>( |
| completer); |
| } |
| |
| void BufferCollectionToken::CombinedTokenServer::SetWeakV2(SetWeakV2Completer::Sync& completer) { |
| parent_.last_seen_version_ = ConnectionVersion::kVersion2; |
| parent_.SetWeakImplV2(completer); |
| } |
| |
| void BufferCollectionToken::CombinedTokenServer::SetWeakOkV2( |
| SetWeakOkV2Request& request, SetWeakOkV2Completer::Sync& completer) { |
| parent_.last_seen_version_ = ConnectionVersion::kVersion2; |
| parent_.SetWeakOkImplV2(request, completer); |
| } |
| |
| BufferCollectionToken::BufferCollectionToken( |
| fbl::RefPtr<LogicalBufferCollection> logical_buffer_collection_param, |
| NodeProperties* new_node_properties, const TokenServerEnd& server_end) |
| : Node(std::move(logical_buffer_collection_param), new_node_properties, |
| GetUnownedChannel(server_end)), |
| LoggingMixin("BufferCollectionToken") { |
| TRACE_DURATION("gfx", "BufferCollectionToken::BufferCollectionToken", "this", this, |
| "logical_buffer_collection", &logical_buffer_collection()); |
| inspect_node_ = |
| logical_buffer_collection().inspect_node().CreateChild(CreateUniqueName("token-")); |
| if (create_status() != ZX_OK) { |
| // Node::Node() failed and maybe !has_server_koid(). |
| return; |
| } |
| // Node::Node filled this out (or didn't and status() reflected that, which was already checked |
| // above). |
| ZX_DEBUG_ASSERT(has_server_koid()); |
| OnServerKoid(); |
| } |
| |
| void BufferCollectionToken::FailAsync(Location location, zx_status_t status, const char* format, |
| ...) { |
| va_list args; |
| va_start(args, format); |
| vLog(true, location.file(), location.line(), logging_prefix(), "fail", format, args); |
| va_end(args); |
| |
| // Idempotent, so only close once. |
| if (!server_binding_.has_value()) { |
| return; |
| } |
| |
| async_failure_result_ = status; |
| |
| server_binding_->Close(status); |
| server_binding_ = {}; |
| } |
| |
| bool BufferCollectionToken::ReadyForAllocation() { return false; } |
| |
| void BufferCollectionToken::OnBuffersAllocated(const AllocationResult& allocation_result) { |
| ZX_PANIC("Unexpected call to BufferCollectionToken::OnBuffersAllocated()"); |
| } |
| |
| BufferCollectionToken* BufferCollectionToken::buffer_collection_token() { return this; } |
| |
| const BufferCollectionToken* BufferCollectionToken::buffer_collection_token() const { return this; } |
| |
| BufferCollection* BufferCollectionToken::buffer_collection() { return nullptr; } |
| |
| const BufferCollection* BufferCollectionToken::buffer_collection() const { return nullptr; } |
| |
| BufferCollectionTokenGroup* BufferCollectionToken::buffer_collection_token_group() { |
| return nullptr; |
| } |
| |
| const BufferCollectionTokenGroup* BufferCollectionToken::buffer_collection_token_group() const { |
| return nullptr; |
| } |
| |
| OrphanedNode* BufferCollectionToken::orphaned_node() { return nullptr; } |
| |
| const OrphanedNode* BufferCollectionToken::orphaned_node() const { return nullptr; } |
| |
| bool BufferCollectionToken::is_connected_type() const { return true; } |
| |
| bool BufferCollectionToken::is_currently_connected() const { return server_binding_.has_value(); } |
| |
| const char* BufferCollectionToken::node_type_string() const { return "token"; } |
| |
| ConnectionVersion BufferCollectionToken::connection_version() const { |
| if (!server_binding_.has_value()) { |
| return ConnectionVersion::kNoConnection; |
| } |
| return last_seen_version_; |
| } |
| |
| } // namespace sysmem_driver |