fuchsia_scenic/
sysmem.rs

1// Copyright 2021 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use anyhow::Error;
6use fidl::endpoints::{create_endpoints, ClientEnd};
7use fsysmem2::BufferCollectionTokenDuplicateRequest;
8use zx::{self as zx, AsHandleRef};
9use {fidl_fuchsia_sysmem2 as fsysmem2, fidl_fuchsia_ui_composition as fland};
10
11// Pair of tokens to be used with Scenic Allocator FIDL protocol.
12pub struct BufferCollectionTokenPair {
13    pub export_token: fland::BufferCollectionExportToken,
14    pub import_token: fland::BufferCollectionImportToken,
15}
16
17impl BufferCollectionTokenPair {
18    pub fn new() -> BufferCollectionTokenPair {
19        let (raw_export_token, raw_import_token) = zx::EventPair::create();
20        BufferCollectionTokenPair {
21            export_token: fland::BufferCollectionExportToken { value: raw_export_token },
22            import_token: fland::BufferCollectionImportToken { value: raw_import_token },
23        }
24    }
25}
26
27/// Given a Scenic `BufferCollectionImportToken`, returns a new version which has been duplicated.
28pub fn duplicate_buffer_collection_import_token(
29    import_token: &fland::BufferCollectionImportToken,
30) -> Result<fland::BufferCollectionImportToken, Error> {
31    let handle = import_token.value.as_handle_ref().duplicate(zx::Rights::SAME_RIGHTS)?;
32    Ok(fland::BufferCollectionImportToken { value: handle.into() })
33}
34
35/// Calls `BufferCollectionToken.Duplicate()` on the provided token, passing the server end of a
36/// newly-instantiated channel.  Then, calls `Sync()` on the provided token, so that the returned
37/// token is safe to use immediately (i.e. the server has acknowledged that the duplication has
38/// occurred).
39pub async fn duplicate_buffer_collection_token(
40    token: &mut fsysmem2::BufferCollectionTokenProxy,
41) -> Result<ClientEnd<fsysmem2::BufferCollectionTokenMarker>, Error> {
42    let (duplicate_token, duplicate_token_server_end) =
43        create_endpoints::<fsysmem2::BufferCollectionTokenMarker>();
44
45    token.duplicate(BufferCollectionTokenDuplicateRequest {
46        rights_attenuation_mask: Some(fidl::Rights::SAME_RIGHTS),
47        token_request: Some(duplicate_token_server_end),
48        ..Default::default()
49    })?;
50    token.sync().await?;
51
52    Ok(duplicate_token)
53}