1 // Copyright 2022 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 use std::rc::Rc; 6 7 use log::error; 8 9 use crate::bindings; 10 use crate::buffer::Buffer; 11 use crate::buffer::BufferType; 12 use crate::display::Display; 13 use crate::va_check; 14 use crate::Config; 15 use crate::EncCodedBuffer; 16 use crate::Surface; 17 use crate::SurfaceMemoryDescriptor; 18 use crate::VaError; 19 20 /// A VA context for a particular [`Display`]. 21 pub struct Context { 22 display: Rc<Display>, 23 id: bindings::VAContextID, 24 } 25 26 impl Context { 27 /// Creates a Context by wrapping around a `vaCreateContext` call. This is just a helper for 28 /// [`Display::create_context`]. new<D: SurfaceMemoryDescriptor>( display: Rc<Display>, config: &Config, coded_width: u32, coded_height: u32, surfaces: Option<&Vec<Surface<D>>>, progressive: bool, ) -> Result<Rc<Self>, VaError>29 pub(crate) fn new<D: SurfaceMemoryDescriptor>( 30 display: Rc<Display>, 31 config: &Config, 32 coded_width: u32, 33 coded_height: u32, 34 surfaces: Option<&Vec<Surface<D>>>, 35 progressive: bool, 36 ) -> Result<Rc<Self>, VaError> { 37 let mut context_id = 0; 38 let flags = if progressive { 39 bindings::VA_PROGRESSIVE as i32 40 } else { 41 0 42 }; 43 44 let mut render_targets = match surfaces { 45 Some(surfaces) => Surface::as_id_vec(surfaces), 46 None => Default::default(), 47 }; 48 49 // Safe because `self` represents a valid VADisplay and render_targets 50 // and ntargets are properly initialized. Note that render_targets==NULL 51 // is valid so long as ntargets==0. 52 va_check(unsafe { 53 bindings::vaCreateContext( 54 display.handle(), 55 config.id(), 56 coded_width as i32, 57 coded_height as i32, 58 flags, 59 render_targets.as_mut_ptr(), 60 render_targets.len() as i32, 61 &mut context_id, 62 ) 63 })?; 64 65 Ok(Rc::new(Self { 66 display, 67 id: context_id, 68 })) 69 } 70 71 /// Returns a shared reference to the [`Display`] used by this context. display(&self) -> &Rc<Display>72 pub fn display(&self) -> &Rc<Display> { 73 &self.display 74 } 75 76 /// Returns the ID of this context. id(&self) -> bindings::VAContextID77 pub(crate) fn id(&self) -> bindings::VAContextID { 78 self.id 79 } 80 81 /// Create a new buffer of type `type_`. create_buffer(self: &Rc<Self>, type_: BufferType) -> Result<Buffer, VaError>82 pub fn create_buffer(self: &Rc<Self>, type_: BufferType) -> Result<Buffer, VaError> { 83 Buffer::new(Rc::clone(self), type_) 84 } 85 86 /// Create a new buffer of type `type_`. create_enc_coded(self: &Rc<Self>, size: usize) -> Result<EncCodedBuffer, VaError>87 pub fn create_enc_coded(self: &Rc<Self>, size: usize) -> Result<EncCodedBuffer, VaError> { 88 EncCodedBuffer::new(Rc::clone(self), size) 89 } 90 } 91 92 impl Drop for Context { drop(&mut self)93 fn drop(&mut self) { 94 // Safe because `self` represents a valid VAContext. 95 let status = 96 va_check(unsafe { bindings::vaDestroyContext(self.display.handle(), self.id) }); 97 98 if status.is_err() { 99 error!("vaDestroyContext failed: {}", status.unwrap_err()); 100 } 101 } 102 } 103