gpu_display/
gpu_display_stub.rs

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
5use base::AsRawDescriptor;
6use base::Event;
7use base::RawDescriptor;
8use base::VolatileSlice;
9use vm_control::gpu::DisplayParameters;
10
11use crate::DisplayT;
12use crate::GpuDisplayError;
13use crate::GpuDisplayFramebuffer;
14use crate::GpuDisplayResult;
15use crate::GpuDisplaySurface;
16use crate::SurfaceType;
17use crate::SysDisplayT;
18
19#[allow(dead_code)]
20struct Buffer {
21    width: u32,
22    _height: u32,
23    bytes_per_pixel: u32,
24    bytes: Vec<u8>,
25}
26
27impl Drop for Buffer {
28    fn drop(&mut self) {}
29}
30
31impl Buffer {
32    fn as_volatile_slice(&mut self) -> VolatileSlice {
33        VolatileSlice::new(self.bytes.as_mut_slice())
34    }
35
36    fn stride(&self) -> usize {
37        (self.bytes_per_pixel as usize) * (self.width as usize)
38    }
39
40    fn bytes_per_pixel(&self) -> usize {
41        self.bytes_per_pixel as usize
42    }
43}
44
45struct StubSurface {
46    width: u32,
47    height: u32,
48    buffer: Option<Buffer>,
49}
50
51impl StubSurface {
52    /// Gets the buffer at buffer_index, allocating it if necessary.
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
71impl GpuDisplaySurface for StubSurface {
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
84impl Drop for StubSurface {
85    fn drop(&mut self) {}
86}
87
88pub struct DisplayStub {
89    /// This event is never triggered and is used solely to fulfill AsRawDescriptor.
90    event: Event,
91}
92
93impl DisplayStub {
94    pub fn new() -> GpuDisplayResult<DisplayStub> {
95        let event = Event::new().map_err(|_| GpuDisplayError::CreateEvent)?;
96
97        Ok(DisplayStub { event })
98    }
99}
100
101impl DisplayT for DisplayStub {
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
123impl SysDisplayT for DisplayStub {}
124
125impl AsRawDescriptor for DisplayStub {
126    fn as_raw_descriptor(&self) -> RawDescriptor {
127        self.event.as_raw_descriptor()
128    }
129}