• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2020 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 //! Definition of the trait `Device` that each backend video device must implement.
6 
7 use base::EventToken;
8 use base::WaitContext;
9 
10 use crate::virtio::video::async_cmd_desc_map::AsyncCmdDescMap;
11 use crate::virtio::video::command::QueueType;
12 use crate::virtio::video::command::VideoCmd;
13 use crate::virtio::video::error::*;
14 use crate::virtio::video::event::VideoEvt;
15 use crate::virtio::video::response;
16 
17 #[derive(EventToken, Debug)]
18 pub enum Token {
19     CmdQueue,
20     EventQueue,
21     Event { id: u32 },
22     Kill,
23     InterruptResample,
24 }
25 
26 /// A tag for commands being processed asynchronously in the back-end device.
27 /// TODO(b/149720783): Remove this enum by using async primitives.
28 #[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Debug)]
29 pub enum AsyncCmdTag {
30     Queue {
31         stream_id: u32,
32         queue_type: QueueType,
33         resource_id: u32,
34     },
35     Drain {
36         stream_id: u32,
37     },
38     Clear {
39         stream_id: u32,
40         queue_type: QueueType,
41     },
42     // Used exclusively by the encoder.
43     #[cfg(feature = "video-encoder")]
44     GetParams {
45         stream_id: u32,
46         queue_type: QueueType,
47     },
48 }
49 
50 /// A return value when a command from the guest is processed.
51 #[derive(Debug)]
52 pub enum VideoCmdResponseType {
53     /// The response for a synchronous command. This can be returned to the guest immediately via
54     /// command virtqueue.
55     Sync(response::CmdResponse),
56     /// The tag for an asynchronous command that the back-end device will complete.
57     /// Once the command is completed, its result will be sent with the same tag.
58     /// This can be seen as a poor man's future pattern.
59     Async(AsyncCmdTag),
60 }
61 
62 /// A response for an asynchronous command that was enqueued through `process_cmd` before.
63 /// The `tag` must be same as the one returned when the command was enqueued.
64 #[derive(Debug)]
65 pub struct AsyncCmdResponse {
66     pub tag: AsyncCmdTag,
67     pub response: VideoResult<response::CmdResponse>,
68 }
69 
70 impl AsyncCmdResponse {
from_response(tag: AsyncCmdTag, response: response::CmdResponse) -> Self71     pub fn from_response(tag: AsyncCmdTag, response: response::CmdResponse) -> Self {
72         Self {
73             tag,
74             response: Ok(response),
75         }
76     }
77 
from_error(tag: AsyncCmdTag, error: VideoError) -> Self78     pub fn from_error(tag: AsyncCmdTag, error: VideoError) -> Self {
79         Self {
80             tag,
81             response: Err(error),
82         }
83     }
84 }
85 
86 /// A return value when processing a event the back-end device sent.
87 #[derive(Debug)]
88 pub enum VideoEvtResponseType {
89     /// The responses for an asynchronous command.
90     AsyncCmd(AsyncCmdResponse),
91     /// The event that happened in the back-end device.
92     Event(VideoEvt),
93 }
94 
95 pub trait Device {
96     /// Processes a virtio-video command.
97     /// If the command expects a synchronous response, it returns a response as `VideoCmdResponseType::Sync`.
98     /// Otherwise, it returns a name of the descriptor chain that will be used when a response is prepared.
99     /// Implementations of this method is passed a WaitContext object which can be used to add or remove
100     /// descriptors to wait on. It is expected that only Token::Event items would be added. When a Token::Event
101     /// event arrives, process_event() will be invoked.
102     /// TODO(b/149720783): Make this an async function.
process_cmd( &mut self, cmd: VideoCmd, wait_ctx: &WaitContext<Token>, ) -> ( VideoCmdResponseType, Option<(u32, Vec<VideoEvtResponseType>)>, )103     fn process_cmd(
104         &mut self,
105         cmd: VideoCmd,
106         wait_ctx: &WaitContext<Token>,
107     ) -> (
108         VideoCmdResponseType,
109         Option<(u32, Vec<VideoEvtResponseType>)>,
110     );
111 
112     /// Processes an available `Token::Event` event and returns a list of `VideoEvtResponseType`
113     /// responses. It returns None if an invalid event comes.
114     /// For responses to be sent via command queue, the return type is `VideoEvtResponseType::AsyncCmd`.
115     /// For responses to be sent via event queue, the return type is `VideoEvtResponseType::Event`.
116     /// TODO(b/149720783): Make this an async function.
process_event( &mut self, desc_map: &mut AsyncCmdDescMap, stream_id: u32, ) -> Option<Vec<VideoEvtResponseType>>117     fn process_event(
118         &mut self,
119         desc_map: &mut AsyncCmdDescMap,
120         stream_id: u32,
121     ) -> Option<Vec<VideoEvtResponseType>>;
122 }
123