// Copyright 2018 The Chromium OS Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. //! This module defines the protocol between `virtio-wayland` and `virtio-gpu` for sharing resources //! that are backed by file descriptors. use std::fmt; use std::fs::File; use msg_on_socket_derive::MsgOnSocket; use msg_socket::{MsgError, MsgReceiver, MsgSender, MsgSocket}; #[derive(Debug, MsgOnSocket)] pub enum ResourceRequest { GetResource { id: u32 }, } #[derive(MsgOnSocket, Clone)] pub struct PlaneInfo { pub offset: u32, pub stride: u32, } const RESOURE_PLANE_NUM: usize = 4; #[derive(MsgOnSocket)] pub struct ResourceInfo { pub file: File, pub planes: [PlaneInfo; RESOURE_PLANE_NUM], } #[derive(MsgOnSocket)] pub enum ResourceResponse { Resource(ResourceInfo), Invalid, } pub type ResourceRequestSocket = MsgSocket; pub type ResourceResponseSocket = MsgSocket; pub fn pair() -> std::io::Result<(ResourceRequestSocket, ResourceResponseSocket)> { msg_socket::pair() } #[derive(Debug)] pub enum ResourceBridgeError { InvalidResource(u32), SendFailure(u32, MsgError), RecieveFailure(u32, MsgError), } impl fmt::Display for ResourceBridgeError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { ResourceBridgeError::InvalidResource(id) => { write!(f, "attempt to send non-existent gpu resource for id {}", id) } ResourceBridgeError::SendFailure(id, e) => write!( f, "failed to send a resource bridge request for id {}: {}", id, e ), ResourceBridgeError::RecieveFailure(id, e) => write!( f, "error receiving resource bridge response for id {}: {}", id, e ), } } } impl std::error::Error for ResourceBridgeError {} pub fn get_resource_info( sock: &ResourceRequestSocket, id: u32, ) -> std::result::Result { if let Err(e) = sock.send(&ResourceRequest::GetResource { id }) { return Err(ResourceBridgeError::SendFailure(id, e)); } match sock.recv() { Ok(ResourceResponse::Resource(info)) => Ok(info), Ok(ResourceResponse::Invalid) => Err(ResourceBridgeError::InvalidResource(id)), Err(e) => Err(ResourceBridgeError::RecieveFailure(id, e)), } }