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