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