• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }
38 
39 pub const RESOURE_PLANE_NUM: usize = 4;
40 #[derive(Serialize, Deserialize)]
41 pub enum ResourceInfo {
42     Buffer(BufferInfo),
43     Fence {
44         #[serde(with = "with_as_descriptor")]
45         handle: SafeDescriptor,
46     },
47 }
48 
49 #[derive(Serialize, Deserialize)]
50 pub enum ResourceResponse {
51     Resource(ResourceInfo),
52     Invalid,
53 }
54 
55 #[sorted]
56 #[derive(Error, Debug)]
57 pub enum ResourceBridgeError {
58     #[error("attempt to send non-existent gpu resource for {0}")]
59     InvalidResource(ResourceRequest),
60     #[error("error receiving resource bridge response for {0}: {1}")]
61     RecieveFailure(ResourceRequest, TubeError),
62     #[error("failed to send a resource bridge request for {0}: {1}")]
63     SendFailure(ResourceRequest, TubeError),
64 }
65 
66 impl fmt::Display for ResourceRequest {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result67     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
68         match self {
69             ResourceRequest::GetBuffer { id } => write!(f, "Buffer-{}", id),
70             ResourceRequest::GetFence { seqno } => write!(f, "Fence-{}", seqno),
71         }
72     }
73 }
74 
get_resource_info( tube: &Tube, request: ResourceRequest, ) -> std::result::Result<ResourceInfo, ResourceBridgeError>75 pub fn get_resource_info(
76     tube: &Tube,
77     request: ResourceRequest,
78 ) -> std::result::Result<ResourceInfo, ResourceBridgeError> {
79     if let Err(e) = tube.send(&request) {
80         return Err(ResourceBridgeError::SendFailure(request, e));
81     }
82 
83     match tube.recv() {
84         Ok(ResourceResponse::Resource(info)) => Ok(info),
85         Ok(ResourceResponse::Invalid) => Err(ResourceBridgeError::InvalidResource(request)),
86         Err(e) => Err(ResourceBridgeError::RecieveFailure(request, e)),
87     }
88 }
89