• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2020 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 use std::collections::BTreeMap;
6 
7 use crate::virtio::queue::DescriptorChain;
8 use crate::virtio::video::command::QueueType;
9 use crate::virtio::video::device::{AsyncCmdResponse, AsyncCmdTag};
10 use crate::virtio::video::error::VideoError;
11 use crate::virtio::video::protocol;
12 use crate::virtio::video::response::CmdResponse;
13 
14 /// AsyncCmdDescMap is a BTreeMap which stores descriptor chains in which asynchronous
15 /// responses will be written.
16 #[derive(Default)]
17 pub struct AsyncCmdDescMap(BTreeMap<AsyncCmdTag, DescriptorChain>);
18 
19 impl AsyncCmdDescMap {
insert(&mut self, tag: AsyncCmdTag, descriptor_chain: DescriptorChain)20     pub fn insert(&mut self, tag: AsyncCmdTag, descriptor_chain: DescriptorChain) {
21         self.0.insert(tag, descriptor_chain);
22     }
23 
remove(&mut self, tag: &AsyncCmdTag) -> Option<DescriptorChain>24     pub fn remove(&mut self, tag: &AsyncCmdTag) -> Option<DescriptorChain> {
25         self.0.remove(tag)
26     }
27 
28     /// Returns a list of `AsyncCmdResponse`s to cancel pending commands that target
29     /// stream `target_stream_id`.
30     /// If `target_queue_type` is specified, then only create the requests for the specified queue.
31     /// Otherwise, create the requests for both input and output queue.
32     /// If `processing_tag` is specified, a cancellation request for that tag will
33     /// not be created.
create_cancellation_responses( &self, target_stream_id: &u32, target_queue_type: Option<QueueType>, processing_tag: Option<AsyncCmdTag>, ) -> Vec<AsyncCmdResponse>34     pub fn create_cancellation_responses(
35         &self,
36         target_stream_id: &u32,
37         target_queue_type: Option<QueueType>,
38         processing_tag: Option<AsyncCmdTag>,
39     ) -> Vec<AsyncCmdResponse> {
40         let mut responses = vec![];
41         for tag in self.0.keys().filter(|&&k| Some(k) != processing_tag) {
42             match tag {
43                 AsyncCmdTag::Queue {
44                     stream_id,
45                     queue_type,
46                     ..
47                 } if stream_id == target_stream_id
48                     && target_queue_type.as_ref().unwrap_or(&queue_type) == queue_type =>
49                 {
50                     responses.push(AsyncCmdResponse::from_response(
51                         tag.clone(),
52                         CmdResponse::ResourceQueue {
53                             timestamp: 0,
54                             flags: protocol::VIRTIO_VIDEO_BUFFER_FLAG_ERR,
55                             size: 0,
56                         },
57                     ));
58                 }
59                 AsyncCmdTag::Drain { stream_id } if stream_id == target_stream_id => {
60                     // TODO(b/1518105): Use more appropriate error code if a new protocol supports
61                     // one.
62                     responses.push(AsyncCmdResponse::from_error(
63                         tag.clone(),
64                         VideoError::InvalidOperation,
65                     ));
66                 }
67                 AsyncCmdTag::Clear {
68                     stream_id,
69                     queue_type,
70                 } if stream_id == target_stream_id
71                     && target_queue_type.as_ref().unwrap_or(&queue_type) == queue_type =>
72                 {
73                     // TODO(b/1518105): Use more appropriate error code if a new protocol supports
74                     // one.
75                     responses.push(AsyncCmdResponse::from_error(
76                         tag.clone(),
77                         VideoError::InvalidOperation,
78                     ));
79                 }
80                 _ => {
81                     // Keep commands for other streams.
82                 }
83             }
84         }
85         responses
86     }
87 }
88