Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
google
GitHub Repository: google/crosvm
Path: blob/main/devices/src/virtio/resource_bridge.rs
5394 views
1
// Copyright 2018 The ChromiumOS Authors
2
// Use of this source code is governed by a BSD-style license that can be
3
// found in the LICENSE file.
4
5
//! This module defines the protocol between `virtio-wayland` and `virtio-gpu` for sharing resources
6
//! that are backed by file descriptors.
7
8
use std::fmt;
9
10
use base::with_as_descriptor;
11
use base::SafeDescriptor;
12
use base::Tube;
13
use base::TubeError;
14
use remain::sorted;
15
use serde::Deserialize;
16
use serde::Serialize;
17
use thiserror::Error;
18
19
#[derive(Debug, Serialize, Deserialize)]
20
pub enum ResourceRequest {
21
GetBuffer { id: u32 },
22
GetFence { seqno: u64 },
23
}
24
25
#[derive(Serialize, Deserialize, Clone, Copy, Default)]
26
pub struct PlaneInfo {
27
pub offset: u32,
28
pub stride: u32,
29
}
30
31
#[derive(Serialize, Deserialize)]
32
pub struct BufferInfo {
33
#[serde(with = "with_as_descriptor")]
34
pub handle: SafeDescriptor,
35
pub planes: [PlaneInfo; RESOURE_PLANE_NUM],
36
pub modifier: u64,
37
/// Whether the buffer can be accessed by the guest CPU.
38
pub guest_cpu_mappable: bool,
39
}
40
41
pub const RESOURE_PLANE_NUM: usize = 4;
42
#[derive(Serialize, Deserialize)]
43
pub enum ResourceInfo {
44
Buffer(BufferInfo),
45
Fence {
46
#[serde(with = "with_as_descriptor")]
47
handle: SafeDescriptor,
48
},
49
}
50
51
#[derive(Serialize, Deserialize)]
52
pub enum ResourceResponse {
53
Resource(ResourceInfo),
54
Invalid,
55
}
56
57
#[sorted]
58
#[derive(Error, Debug)]
59
pub enum ResourceBridgeError {
60
#[error("attempt to send non-existent gpu resource for {0}")]
61
InvalidResource(ResourceRequest),
62
#[error("error receiving resource bridge response for {0}: {1}")]
63
RecieveFailure(ResourceRequest, TubeError),
64
#[error("failed to send a resource bridge request for {0}: {1}")]
65
SendFailure(ResourceRequest, TubeError),
66
}
67
68
impl fmt::Display for ResourceRequest {
69
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
70
match self {
71
ResourceRequest::GetBuffer { id } => write!(f, "Buffer-{id}"),
72
ResourceRequest::GetFence { seqno } => write!(f, "Fence-{seqno}"),
73
}
74
}
75
}
76
77
pub fn get_resource_info(
78
tube: &Tube,
79
request: ResourceRequest,
80
) -> std::result::Result<ResourceInfo, ResourceBridgeError> {
81
if let Err(e) = tube.send(&request) {
82
return Err(ResourceBridgeError::SendFailure(request, e));
83
}
84
85
match tube.recv() {
86
Ok(ResourceResponse::Resource(info)) => Ok(info),
87
Ok(ResourceResponse::Invalid) => Err(ResourceBridgeError::InvalidResource(request)),
88
Err(e) => Err(ResourceBridgeError::RecieveFailure(request, e)),
89
}
90
}
91
92