Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
google
GitHub Repository: google/crosvm
Path: blob/main/devices/src/virtio/video/device.rs
5394 views
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 {
22
id: u32,
23
},
24
/// Signals that processing of a given buffer has completed. Used for cases where the guest CPU
25
/// may access the buffer, in which case it cannot be handed over to the guest until operations
26
/// on it have completed.
27
BufferBarrier {
28
id: u32,
29
},
30
Kill,
31
}
32
33
/// A tag for commands being processed asynchronously in the back-end device.
34
///
35
/// TODO(b/149720783): Remove this enum by using async primitives.
36
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Debug)]
37
pub enum AsyncCmdTag {
38
Queue {
39
stream_id: u32,
40
queue_type: QueueType,
41
resource_id: u32,
42
},
43
Drain {
44
stream_id: u32,
45
},
46
Clear {
47
stream_id: u32,
48
queue_type: QueueType,
49
},
50
// Used exclusively by the encoder.
51
#[cfg(feature = "video-encoder")]
52
GetParams {
53
stream_id: u32,
54
queue_type: QueueType,
55
},
56
}
57
58
/// A return value when a command from the guest is processed.
59
#[derive(Debug)]
60
pub enum VideoCmdResponseType {
61
/// The response for a synchronous command. This can be returned to the guest immediately via
62
/// command virtqueue.
63
Sync(response::CmdResponse),
64
/// The tag for an asynchronous command that the back-end device will complete.
65
/// Once the command is completed, its result will be sent with the same tag.
66
/// This can be seen as a poor man's future pattern.
67
Async(AsyncCmdTag),
68
}
69
70
/// A response for an asynchronous command that was enqueued through `process_cmd` before.
71
/// The `tag` must be same as the one returned when the command was enqueued.
72
#[derive(Debug)]
73
pub struct AsyncCmdResponse {
74
pub tag: AsyncCmdTag,
75
pub response: VideoResult<response::CmdResponse>,
76
}
77
78
impl AsyncCmdResponse {
79
pub fn from_response(tag: AsyncCmdTag, response: response::CmdResponse) -> Self {
80
Self {
81
tag,
82
response: Ok(response),
83
}
84
}
85
86
pub fn from_error(tag: AsyncCmdTag, error: VideoError) -> Self {
87
Self {
88
tag,
89
response: Err(error),
90
}
91
}
92
}
93
94
/// A return value when processing a event the back-end device sent.
95
#[derive(Debug)]
96
pub enum VideoEvtResponseType {
97
/// The responses for an asynchronous command.
98
AsyncCmd(AsyncCmdResponse),
99
/// The event that happened in the back-end device.
100
Event(VideoEvt),
101
}
102
103
pub trait Device {
104
/// Processes a virtio-video command.
105
/// If the command expects a synchronous response, it returns a response as
106
/// `VideoCmdResponseType::Sync`. Otherwise, it returns a name of the descriptor chain that
107
/// will be used when a response is prepared. Implementations of this method is passed a
108
/// WaitContext object which can be used to add or remove descriptors to wait on. It is
109
/// expected that only Token::Event items would be added. When a Token::Event event arrives,
110
/// process_event() will be invoked.
111
///
112
/// TODO(b/149720783): Make this an async function.
113
fn process_cmd(
114
&mut self,
115
cmd: VideoCmd,
116
wait_ctx: &WaitContext<Token>,
117
) -> (
118
VideoCmdResponseType,
119
Option<(u32, Vec<VideoEvtResponseType>)>,
120
);
121
122
/// Processes an available `Token::Event` event and returns a list of `VideoEvtResponseType`
123
/// responses. It returns None if an invalid event comes.
124
/// For responses to be sent via command queue, the return type is
125
/// `VideoEvtResponseType::AsyncCmd`. For responses to be sent via event queue, the return
126
/// type is `VideoEvtResponseType::Event`.
127
///
128
/// TODO(b/149720783): Make this an async function.
129
fn process_event(
130
&mut self,
131
desc_map: &mut AsyncCmdDescMap,
132
stream_id: u32,
133
wait_ctx: &WaitContext<Token>,
134
) -> Option<Vec<VideoEvtResponseType>>;
135
136
/// Processes a `Token::BufferBarrier` event and returns a list of `VideoEvtResponseType`
137
/// responses. Only needs to be implemented for devices that adds `Token::BufferBarrier` tokens
138
/// to the wait context.
139
fn process_buffer_barrier(
140
&mut self,
141
_stream_id: u32,
142
_wait_ctx: &WaitContext<Token>,
143
) -> Option<Vec<VideoEvtResponseType>> {
144
None
145
}
146
}
147
148