• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2018 The Chromium OS 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 
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 use std::fs::File;
10 
11 use serde::{Deserialize, Serialize};
12 
13 use base::{with_as_descriptor, Tube, TubeError};
14 
15 #[derive(Debug, Serialize, Deserialize)]
16 pub enum ResourceRequest {
17     GetBuffer { id: u32 },
18     GetFence { seqno: u64 },
19 }
20 
21 #[derive(Serialize, Deserialize, Clone, Copy, Default)]
22 pub struct PlaneInfo {
23     pub offset: u32,
24     pub stride: u32,
25 }
26 
27 #[derive(Serialize, Deserialize)]
28 pub struct BufferInfo {
29     #[serde(with = "with_as_descriptor")]
30     pub file: File,
31     pub planes: [PlaneInfo; RESOURE_PLANE_NUM],
32     pub modifier: u64,
33 }
34 
35 pub const RESOURE_PLANE_NUM: usize = 4;
36 #[derive(Serialize, Deserialize)]
37 pub enum ResourceInfo {
38     Buffer(BufferInfo),
39     Fence {
40         #[serde(with = "with_as_descriptor")]
41         file: File,
42     },
43 }
44 
45 #[derive(Serialize, Deserialize)]
46 pub enum ResourceResponse {
47     Resource(ResourceInfo),
48     Invalid,
49 }
50 
51 #[derive(Debug)]
52 pub enum ResourceBridgeError {
53     InvalidResource(ResourceRequest),
54     SendFailure(ResourceRequest, TubeError),
55     RecieveFailure(ResourceRequest, TubeError),
56 }
57 
58 impl fmt::Display for ResourceRequest {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result59     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
60         match self {
61             ResourceRequest::GetBuffer { id } => write!(f, "Buffer-{}", id),
62             ResourceRequest::GetFence { seqno } => write!(f, "Fence-{}", seqno),
63         }
64     }
65 }
66 
67 impl fmt::Display for ResourceBridgeError {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result68     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
69         match self {
70             ResourceBridgeError::InvalidResource(req) => {
71                 write!(f, "attempt to send non-existent gpu resource for {}", req)
72             }
73             ResourceBridgeError::SendFailure(req, e) => write!(
74                 f,
75                 "failed to send a resource bridge request for {}: {}",
76                 req, e
77             ),
78             ResourceBridgeError::RecieveFailure(req, e) => write!(
79                 f,
80                 "error receiving resource bridge response for {}: {}",
81                 req, e
82             ),
83         }
84     }
85 }
86 
87 impl std::error::Error for ResourceBridgeError {}
88 
get_resource_info( tube: &Tube, request: ResourceRequest, ) -> std::result::Result<ResourceInfo, ResourceBridgeError>89 pub fn get_resource_info(
90     tube: &Tube,
91     request: ResourceRequest,
92 ) -> std::result::Result<ResourceInfo, ResourceBridgeError> {
93     if let Err(e) = tube.send(&request) {
94         return Err(ResourceBridgeError::SendFailure(request, e));
95     }
96 
97     match tube.recv() {
98         Ok(ResourceResponse::Resource(info)) => Ok(info),
99         Ok(ResourceResponse::Invalid) => Err(ResourceBridgeError::InvalidResource(request)),
100         Err(e) => Err(ResourceBridgeError::RecieveFailure(request, e)),
101     }
102 }
103