// Copyright 2020 The ChromiumOS Authors1// Use of this source code is governed by a BSD-style license that can be2// found in the LICENSE file.34//! Definition of the trait `Device` that each backend video device must implement.56use base::EventToken;7use base::WaitContext;89use crate::virtio::video::async_cmd_desc_map::AsyncCmdDescMap;10use crate::virtio::video::command::QueueType;11use crate::virtio::video::command::VideoCmd;12use crate::virtio::video::error::*;13use crate::virtio::video::event::VideoEvt;14use crate::virtio::video::response;1516#[derive(EventToken, Debug)]17pub enum Token {18CmdQueue,19EventQueue,20Event {21id: u32,22},23/// Signals that processing of a given buffer has completed. Used for cases where the guest CPU24/// may access the buffer, in which case it cannot be handed over to the guest until operations25/// on it have completed.26BufferBarrier {27id: u32,28},29Kill,30}3132/// A tag for commands being processed asynchronously in the back-end device.33///34/// TODO(b/149720783): Remove this enum by using async primitives.35#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Debug)]36pub enum AsyncCmdTag {37Queue {38stream_id: u32,39queue_type: QueueType,40resource_id: u32,41},42Drain {43stream_id: u32,44},45Clear {46stream_id: u32,47queue_type: QueueType,48},49// Used exclusively by the encoder.50#[cfg(feature = "video-encoder")]51GetParams {52stream_id: u32,53queue_type: QueueType,54},55}5657/// A return value when a command from the guest is processed.58#[derive(Debug)]59pub enum VideoCmdResponseType {60/// The response for a synchronous command. This can be returned to the guest immediately via61/// command virtqueue.62Sync(response::CmdResponse),63/// The tag for an asynchronous command that the back-end device will complete.64/// Once the command is completed, its result will be sent with the same tag.65/// This can be seen as a poor man's future pattern.66Async(AsyncCmdTag),67}6869/// A response for an asynchronous command that was enqueued through `process_cmd` before.70/// The `tag` must be same as the one returned when the command was enqueued.71#[derive(Debug)]72pub struct AsyncCmdResponse {73pub tag: AsyncCmdTag,74pub response: VideoResult<response::CmdResponse>,75}7677impl AsyncCmdResponse {78pub fn from_response(tag: AsyncCmdTag, response: response::CmdResponse) -> Self {79Self {80tag,81response: Ok(response),82}83}8485pub fn from_error(tag: AsyncCmdTag, error: VideoError) -> Self {86Self {87tag,88response: Err(error),89}90}91}9293/// A return value when processing a event the back-end device sent.94#[derive(Debug)]95pub enum VideoEvtResponseType {96/// The responses for an asynchronous command.97AsyncCmd(AsyncCmdResponse),98/// The event that happened in the back-end device.99Event(VideoEvt),100}101102pub trait Device {103/// Processes a virtio-video command.104/// If the command expects a synchronous response, it returns a response as105/// `VideoCmdResponseType::Sync`. Otherwise, it returns a name of the descriptor chain that106/// will be used when a response is prepared. Implementations of this method is passed a107/// WaitContext object which can be used to add or remove descriptors to wait on. It is108/// expected that only Token::Event items would be added. When a Token::Event event arrives,109/// process_event() will be invoked.110///111/// TODO(b/149720783): Make this an async function.112fn process_cmd(113&mut self,114cmd: VideoCmd,115wait_ctx: &WaitContext<Token>,116) -> (117VideoCmdResponseType,118Option<(u32, Vec<VideoEvtResponseType>)>,119);120121/// Processes an available `Token::Event` event and returns a list of `VideoEvtResponseType`122/// responses. It returns None if an invalid event comes.123/// For responses to be sent via command queue, the return type is124/// `VideoEvtResponseType::AsyncCmd`. For responses to be sent via event queue, the return125/// type is `VideoEvtResponseType::Event`.126///127/// TODO(b/149720783): Make this an async function.128fn process_event(129&mut self,130desc_map: &mut AsyncCmdDescMap,131stream_id: u32,132wait_ctx: &WaitContext<Token>,133) -> Option<Vec<VideoEvtResponseType>>;134135/// Processes a `Token::BufferBarrier` event and returns a list of `VideoEvtResponseType`136/// responses. Only needs to be implemented for devices that adds `Token::BufferBarrier` tokens137/// to the wait context.138fn process_buffer_barrier(139&mut self,140_stream_id: u32,141_wait_ctx: &WaitContext<Token>,142) -> Option<Vec<VideoEvtResponseType>> {143None144}145}146147148