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 use base::AsRawDescriptor; 6 use base::Event; 7 use base::RawDescriptor; 8 use base::VolatileSlice; 9 use vm_control::gpu::DisplayParameters; 10 11 use crate::DisplayT; 12 use crate::GpuDisplayError; 13 use crate::GpuDisplayFramebuffer; 14 use crate::GpuDisplayResult; 15 use crate::GpuDisplaySurface; 16 use crate::SurfaceType; 17 use crate::SysDisplayT; 18 19 #[allow(dead_code)] 20 struct Buffer { 21 width: u32, 22 _height: u32, 23 bytes_per_pixel: u32, 24 bytes: Vec<u8>, 25 } 26 27 impl Drop for Buffer { drop(&mut self)28 fn drop(&mut self) {} 29 } 30 31 impl Buffer { as_volatile_slice(&mut self) -> VolatileSlice32 fn as_volatile_slice(&mut self) -> VolatileSlice { 33 VolatileSlice::new(self.bytes.as_mut_slice()) 34 } 35 stride(&self) -> usize36 fn stride(&self) -> usize { 37 (self.bytes_per_pixel as usize) * (self.width as usize) 38 } 39 bytes_per_pixel(&self) -> usize40 fn bytes_per_pixel(&self) -> usize { 41 self.bytes_per_pixel as usize 42 } 43 } 44 45 struct StubSurface { 46 width: u32, 47 height: u32, 48 buffer: Option<Buffer>, 49 } 50 51 impl StubSurface { 52 /// Gets the buffer at buffer_index, allocating it if necessary. lazily_allocate_buffer(&mut self) -> Option<&mut Buffer>53 fn lazily_allocate_buffer(&mut self) -> Option<&mut Buffer> { 54 if self.buffer.is_none() { 55 // XRGB8888 56 let bytes_per_pixel = 4; 57 let bytes_total = (self.width as u64) * (self.height as u64) * (bytes_per_pixel as u64); 58 59 self.buffer = Some(Buffer { 60 width: self.width, 61 _height: self.height, 62 bytes_per_pixel, 63 bytes: vec![0; bytes_total as usize], 64 }); 65 } 66 67 self.buffer.as_mut() 68 } 69 } 70 71 impl GpuDisplaySurface for StubSurface { framebuffer(&mut self) -> Option<GpuDisplayFramebuffer>72 fn framebuffer(&mut self) -> Option<GpuDisplayFramebuffer> { 73 let framebuffer = self.lazily_allocate_buffer()?; 74 let framebuffer_stride = framebuffer.stride() as u32; 75 let framebuffer_bytes_per_pixel = framebuffer.bytes_per_pixel() as u32; 76 Some(GpuDisplayFramebuffer::new( 77 framebuffer.as_volatile_slice(), 78 framebuffer_stride, 79 framebuffer_bytes_per_pixel, 80 )) 81 } 82 } 83 84 impl Drop for StubSurface { drop(&mut self)85 fn drop(&mut self) {} 86 } 87 88 pub struct DisplayStub { 89 /// This event is never triggered and is used solely to fulfill AsRawDescriptor. 90 event: Event, 91 } 92 93 impl DisplayStub { new() -> GpuDisplayResult<DisplayStub>94 pub fn new() -> GpuDisplayResult<DisplayStub> { 95 let event = Event::new().map_err(|_| GpuDisplayError::CreateEvent)?; 96 97 Ok(DisplayStub { event }) 98 } 99 } 100 101 impl DisplayT for DisplayStub { create_surface( &mut self, parent_surface_id: Option<u32>, _surface_id: u32, _scanout_id: Option<u32>, display_params: &DisplayParameters, _surf_type: SurfaceType, ) -> GpuDisplayResult<Box<dyn GpuDisplaySurface>>102 fn create_surface( 103 &mut self, 104 parent_surface_id: Option<u32>, 105 _surface_id: u32, 106 _scanout_id: Option<u32>, 107 display_params: &DisplayParameters, 108 _surf_type: SurfaceType, 109 ) -> GpuDisplayResult<Box<dyn GpuDisplaySurface>> { 110 if parent_surface_id.is_some() { 111 return Err(GpuDisplayError::Unsupported); 112 } 113 114 let (width, height) = display_params.get_virtual_display_size(); 115 Ok(Box::new(StubSurface { 116 width, 117 height, 118 buffer: None, 119 })) 120 } 121 } 122 123 impl SysDisplayT for DisplayStub {} 124 125 impl AsRawDescriptor for DisplayStub { as_raw_descriptor(&self) -> RawDescriptor126 fn as_raw_descriptor(&self) -> RawDescriptor { 127 self.event.as_raw_descriptor() 128 } 129 } 130