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