// Copyright 2018 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

//! Implementation for the transport agnostic virtio-gpu protocol, including display and rendering.

use std::cell::RefCell;
use std::collections::btree_map::Entry;
use std::collections::BTreeMap as Map;
use std::os::unix::io::AsRawFd;
use std::rc::Rc;
use std::usize;

use data_model::*;

use msg_socket::{MsgReceiver, MsgSender};
use sys_util::{error, GuestAddress, GuestMemory};

use gpu_buffer::{Buffer, Device, Flags, Format};
use gpu_display::*;
use gpu_renderer::{
    format_fourcc as renderer_fourcc, Box3, Context as RendererContext, Image as RendererImage,
    Renderer, Resource as GpuRendererResource, ResourceCreateArgs,
};

use super::protocol::{
    GpuResponse, GpuResponsePlaneInfo, VIRTIO_GPU_CAPSET_VIRGL, VIRTIO_GPU_CAPSET_VIRGL2,
};
use crate::virtio::resource_bridge::*;

const DEFAULT_WIDTH: u32 = 1280;
const DEFAULT_HEIGHT: u32 = 1024;

/// Trait for virtio-gpu resources allocated by the guest.
trait VirglResource {
    /// The width in pixels of this resource.
    fn width(&self) -> u32;

    /// The height in pixels of this resource.
    fn height(&self) -> u32;

    /// Associates the backing for this resource with the given guest memory.
    fn attach_guest_backing(&mut self, mem: &GuestMemory, vecs: Vec<(GuestAddress, usize)>);

    /// Removes associated memory for this resource previously made with `attach_guest_backing`.
    fn detach_guest_backing(&mut self);

    /// Returns the GPU `Buffer` for this resource, if it has one.
    fn buffer(&self) -> Option<&Buffer> {
        None
    }

    /// Returns the renderer's concrete `GpuRendererResource` for this resource, if it has one.
    fn gpu_renderer_resource(&mut self) -> Option<&mut GpuRendererResource> {
        None
    }

    /// Returns an import ID for this resource onto the given display, if successful.
    fn import_to_display(&mut self, _display: &Rc<RefCell<GpuDisplay>>) -> Option<u32> {
        None
    }

    /// Copies the given rectangle of pixels from guest memory, using the backing specified from a
    /// call to `attach_guest_backing`.
    fn write_from_guest_memory(
        &mut self,
        x: u32,
        y: u32,
        width: u32,
        height: u32,
        src_offset: u64,
        mem: &GuestMemory,
    );

    /// Reads from the given rectangle of pixels in the resource to the `dst` slice of memory.
    fn read_to_volatile(&mut self, x: u32, y: u32, width: u32, height: u32, dst: VolatileSlice);
}

impl VirglResource for GpuRendererResource {
    fn width(&self) -> u32 {
        match self.get_info() {
            Ok(info) => info.width,
            Err(_) => 0,
        }
    }
    fn height(&self) -> u32 {
        match self.get_info() {
            Ok(info) => info.height,
            Err(_) => 0,
        }
    }

    fn attach_guest_backing(&mut self, mem: &GuestMemory, vecs: Vec<(GuestAddress, usize)>) {
        if let Err(e) = self.attach_backing(&vecs[..], mem) {
            error!("failed to attach backing to resource: {}", e);
        }
    }

    fn detach_guest_backing(&mut self) {
        self.detach_backing();
    }

    fn gpu_renderer_resource(&mut self) -> Option<&mut GpuRendererResource> {
        Some(self)
    }

    fn write_from_guest_memory(
        &mut self,
        x: u32,
        y: u32,
        width: u32,
        height: u32,
        src_offset: u64,
        _mem: &GuestMemory,
    ) {
        let res = self.transfer_write(
            None,
            0,
            0,
            0,
            Box3 {
                x,
                y,
                z: 0,
                w: width,
                h: height,
                d: 0,
            },
            src_offset,
        );
        if let Err(e) = res {
            error!(
                "failed to write to resource (x={} y={} w={} h={}, src_offset={}): {}",
                x, y, width, height, src_offset, e
            );
        }
    }

    fn read_to_volatile(&mut self, x: u32, y: u32, width: u32, height: u32, dst: VolatileSlice) {
        let res = GpuRendererResource::read_to_volatile(
            self,
            None,
            0,
            0,
            0,
            Box3 {
                x,
                y,
                z: 0,
                w: width,
                h: height,
                d: 0,
            },
            0,
            dst,
        );
        if let Err(e) = res {
            error!("failed to read from resource: {}", e);
        }
    }
}

/// A buffer backed with a `gpu_buffer::Buffer`.
struct BackedBuffer {
    display_import: Option<(Rc<RefCell<GpuDisplay>>, u32)>,
    backing: Vec<(GuestAddress, usize)>,
    buffer: Buffer,
    gpu_renderer_resource: Option<GpuRendererResource>,
    _image: Option<RendererImage>,
}

impl BackedBuffer {
    fn new_renderer_registered(
        buffer: Buffer,
        gpu_renderer_resource: GpuRendererResource,
        image: RendererImage,
    ) -> BackedBuffer {
        BackedBuffer {
            display_import: None,
            backing: Vec::new(),
            buffer,
            gpu_renderer_resource: Some(gpu_renderer_resource),
            _image: Some(image),
        }
    }
}

impl From<Buffer> for BackedBuffer {
    fn from(buffer: Buffer) -> BackedBuffer {
        BackedBuffer {
            display_import: None,
            backing: Vec::new(),
            buffer,
            gpu_renderer_resource: None,
            _image: None,
        }
    }
}

impl VirglResource for BackedBuffer {
    fn width(&self) -> u32 {
        self.buffer.width()
    }

    fn height(&self) -> u32 {
        self.buffer.height()
    }

    fn attach_guest_backing(&mut self, mem: &GuestMemory, vecs: Vec<(GuestAddress, usize)>) {
        self.backing = vecs.clone();
        if let Some(ref mut resource) = self.gpu_renderer_resource {
            if let Err(e) = resource.attach_backing(&vecs[..], mem) {
                error!("failed to attach backing to BackBuffer resource: {}", e);
            }
        }
    }

    fn detach_guest_backing(&mut self) {
        if let Some(ref mut resource) = self.gpu_renderer_resource {
            resource.detach_backing();
        }
        self.backing.clear();
    }

    fn gpu_renderer_resource(&mut self) -> Option<&mut GpuRendererResource> {
        self.gpu_renderer_resource.as_mut()
    }

    fn buffer(&self) -> Option<&Buffer> {
        Some(&self.buffer)
    }

    fn import_to_display(&mut self, display: &Rc<RefCell<GpuDisplay>>) -> Option<u32> {
        if let Some((ref self_display, import)) = self.display_import {
            if Rc::ptr_eq(&self_display, display) {
                return Some(import);
            }
        }
        let dmabuf = match self.buffer.export_plane_fd(0) {
            Ok(dmabuf) => dmabuf,
            Err(e) => {
                error!("failed to get dmabuf for scanout: {}", e);
                return None;
            }
        };

        match display.borrow_mut().import_dmabuf(
            dmabuf.as_raw_fd(),
            0, /* offset */
            self.buffer.stride(),
            self.buffer.format_modifier(),
            self.buffer.width(),
            self.buffer.height(),
            self.buffer.format().into(),
        ) {
            Ok(import_id) => {
                self.display_import = Some((display.clone(), import_id));
                Some(import_id)
            }
            Err(e) => {
                error!("failed to import dmabuf for display: {}", e);
                None
            }
        }
    }

    fn write_from_guest_memory(
        &mut self,
        x: u32,
        y: u32,
        width: u32,
        height: u32,
        src_offset: u64,
        mem: &GuestMemory,
    ) {
        if src_offset >= usize::MAX as u64 {
            error!(
                "failed to write to resource with given offset: {}",
                src_offset
            );
            return;
        }
        let res = self.buffer.write_from_sg(
            x,
            y,
            width,
            height,
            0, // plane
            src_offset as usize,
            self.backing
                .iter()
                .map(|&(addr, len)| mem.get_slice(addr.offset(), len as u64).unwrap_or_default()),
        );
        if let Err(e) = res {
            error!("failed to write to resource from guest memory: {}", e)
        }
    }

    fn read_to_volatile(&mut self, x: u32, y: u32, width: u32, height: u32, dst: VolatileSlice) {
        if let Err(e) = self.buffer.read_to_volatile(x, y, width, height, 0, dst) {
            error!("failed to copy resource: {}", e);
        }
    }
}

/// The virtio-gpu backend state tracker.
///
/// Commands from the virtio-gpu protocol can be submitted here using the methods, and they will be
/// realized on the hardware. Most methods return a `GpuResponse` that indicate the success,
/// failure, or requested data for the given command.
pub struct Backend {
    display: Rc<RefCell<GpuDisplay>>,
    device: Device,
    renderer: Renderer,
    resources: Map<u32, Box<dyn VirglResource>>,
    contexts: Map<u32, RendererContext>,
    scanout_surface: Option<u32>,
    cursor_surface: Option<u32>,
    scanout_resource: u32,
    cursor_resource: u32,
}

impl Backend {
    /// Creates a new backend for virtio-gpu that realizes all commands using the given `device` for
    /// allocating buffers, `display` for showing the results, and `renderer` for submitting
    /// rendering commands.
    pub fn new(device: Device, display: GpuDisplay, renderer: Renderer) -> Backend {
        Backend {
            display: Rc::new(RefCell::new(display)),
            device,
            renderer,
            resources: Default::default(),
            contexts: Default::default(),
            scanout_surface: None,
            cursor_surface: None,
            scanout_resource: 0,
            cursor_resource: 0,
        }
    }

    /// Gets a reference to the display passed into `new`.
    pub fn display(&self) -> &Rc<RefCell<GpuDisplay>> {
        &self.display
    }

    /// Processes the internal `display` events and returns `true` if the main display was closed.
    pub fn process_display(&mut self) -> bool {
        let mut display = self.display.borrow_mut();
        display.dispatch_events();
        self.scanout_surface
            .map(|s| display.close_requested(s))
            .unwrap_or(false)
    }

    pub fn process_resource_bridge(&self, resource_bridge: &ResourceResponseSocket) {
        let request = match resource_bridge.recv() {
            Ok(msg) => msg,
            Err(e) => {
                error!("error receiving resource bridge request: {}", e);
                return;
            }
        };

        let response = match request {
            ResourceRequest::GetResource { id } => self
                .resources
                .get(&id)
                .and_then(|resource| resource.buffer())
                .and_then(|buffer| buffer.export_plane_fd(0).ok())
                .map(|fd| ResourceResponse::Resource(fd))
                .unwrap_or(ResourceResponse::Invalid),
        };

        if let Err(e) = resource_bridge.send(&response) {
            error!("error sending resource bridge request: {}", e);
        }
    }

    /// Gets the list of supported display resolutions as a slice of `(width, height)` tuples.
    pub fn display_info(&self) -> &[(u32, u32)] {
        &[(DEFAULT_WIDTH, DEFAULT_HEIGHT)]
    }

    /// Creates a 2D resource with the given properties and associated it with the given id.
    pub fn create_resource_2d(
        &mut self,
        id: u32,
        width: u32,
        height: u32,
        fourcc: u32,
    ) -> GpuResponse {
        if id == 0 {
            return GpuResponse::ErrInvalidResourceId;
        }
        match self.resources.entry(id) {
            Entry::Vacant(slot) => {
                let res = self.device.create_buffer(
                    width,
                    height,
                    Format::from(fourcc),
                    Flags::empty().use_scanout(true).use_linear(true),
                );
                match res {
                    Ok(res) => {
                        slot.insert(Box::from(BackedBuffer::from(res)));
                        GpuResponse::OkNoData
                    }
                    Err(_) => {
                        error!("failed to create renderer resource {}", fourcc);
                        GpuResponse::ErrUnspec
                    }
                }
            }
            Entry::Occupied(_) => GpuResponse::ErrInvalidResourceId,
        }
    }

    /// Removes the guest's reference count for the given resource id.
    pub fn unref_resource(&mut self, id: u32) -> GpuResponse {
        match self.resources.remove(&id) {
            Some(_) => GpuResponse::OkNoData,
            None => GpuResponse::ErrInvalidResourceId,
        }
    }

    /// Sets the given resource id as the source of scanout to the display.
    pub fn set_scanout(&mut self, id: u32) -> GpuResponse {
        let mut display = self.display.borrow_mut();
        if id == 0 {
            if let Some(surface) = self.scanout_surface.take() {
                display.release_surface(surface);
            }
            self.scanout_resource = 0;
            if let Some(surface) = self.cursor_surface.take() {
                display.release_surface(surface);
            }
            self.cursor_resource = 0;
            GpuResponse::OkNoData
        } else if self.resources.get_mut(&id).is_some() {
            self.scanout_resource = id;

            if self.scanout_surface.is_none() {
                match display.create_surface(None, DEFAULT_WIDTH, DEFAULT_HEIGHT) {
                    Ok(surface) => self.scanout_surface = Some(surface),
                    Err(e) => error!("failed to create display surface: {}", e),
                }
            }
            GpuResponse::OkNoData
        } else {
            GpuResponse::ErrInvalidResourceId
        }
    }

    fn flush_resource_to_surface(
        &mut self,
        resource_id: u32,
        surface_id: u32,
        x: u32,
        y: u32,
        width: u32,
        height: u32,
    ) -> GpuResponse {
        let resource = match self.resources.get_mut(&resource_id) {
            Some(r) => r,
            None => return GpuResponse::ErrInvalidResourceId,
        };

        if let Some(import_id) = resource.import_to_display(&self.display) {
            self.display.borrow_mut().flip_to(surface_id, import_id);
            return GpuResponse::OkNoData;
        }

        // Import failed, fall back to a copy.
        let display = self.display.borrow_mut();
        // Prevent overwriting a buffer that is currently being used by the compositor.
        if display.next_buffer_in_use(surface_id) {
            return GpuResponse::OkNoData;
        }
        let fb = match display.framebuffer_memory(surface_id) {
            Some(fb) => fb,
            None => {
                error!("failed to access framebuffer for surface {}", surface_id);
                return GpuResponse::ErrUnspec;
            }
        };

        resource.read_to_volatile(x, y, width, height, fb);
        display.flip(surface_id);

        GpuResponse::OkNoData
    }

    /// Flushes the given rectangle of pixels of the given resource to the display.
    pub fn flush_resource(
        &mut self,
        id: u32,
        x: u32,
        y: u32,
        width: u32,
        height: u32,
    ) -> GpuResponse {
        if id == 0 {
            return GpuResponse::OkNoData;
        }

        let mut response = GpuResponse::OkNoData;

        if id == self.scanout_resource {
            if let Some(surface_id) = self.scanout_surface {
                response = self.flush_resource_to_surface(id, surface_id, x, y, width, height);
            }
        }

        if response != GpuResponse::OkNoData {
            return response;
        }

        if id == self.cursor_resource {
            if let Some(surface_id) = self.cursor_surface {
                response = self.flush_resource_to_surface(id, surface_id, x, y, width, height);
            }
        }

        response
    }

    /// Copes the given rectangle of pixels of the given resource's backing memory to the host side
    /// resource.
    pub fn transfer_to_resource_2d(
        &mut self,
        id: u32,
        x: u32,
        y: u32,
        width: u32,
        height: u32,
        src_offset: u64,
        mem: &GuestMemory,
    ) -> GpuResponse {
        match self.resources.get_mut(&id) {
            Some(res) => {
                res.write_from_guest_memory(x, y, width, height, src_offset, mem);
                GpuResponse::OkNoData
            }
            None => GpuResponse::ErrInvalidResourceId,
        }
    }

    /// Attaches backing memory to the given resource, represented by a `Vec` of `(address, size)`
    /// tuples in the guest's physical address space.
    pub fn attach_backing(
        &mut self,
        id: u32,
        mem: &GuestMemory,
        vecs: Vec<(GuestAddress, usize)>,
    ) -> GpuResponse {
        match self.resources.get_mut(&id) {
            Some(resource) => {
                resource.attach_guest_backing(mem, vecs);
                GpuResponse::OkNoData
            }
            None => GpuResponse::ErrInvalidResourceId,
        }
    }

    /// Detaches any backing memory from the given resource, if there is any.
    pub fn detach_backing(&mut self, id: u32) -> GpuResponse {
        match self.resources.get_mut(&id) {
            Some(resource) => {
                resource.detach_guest_backing();
                GpuResponse::OkNoData
            }
            None => GpuResponse::ErrInvalidResourceId,
        }
    }

    /// Updates the cursor's memory to the given id, and sets its position to the given coordinates.
    pub fn update_cursor(&mut self, id: u32, x: u32, y: u32) -> GpuResponse {
        if id == 0 {
            if let Some(surface) = self.cursor_surface.take() {
                self.display.borrow_mut().release_surface(surface);
            }
            self.cursor_resource = 0;
            GpuResponse::OkNoData
        } else if let Some(resource) = self.resources.get_mut(&id) {
            self.cursor_resource = id;
            if self.cursor_surface.is_none() {
                match self.display.borrow_mut().create_surface(
                    self.scanout_surface,
                    resource.width(),
                    resource.height(),
                ) {
                    Ok(surface) => self.cursor_surface = Some(surface),
                    Err(e) => {
                        error!("failed to create cursor surface: {}", e);
                        return GpuResponse::ErrUnspec;
                    }
                }
            }

            let cursor_surface = self.cursor_surface.unwrap();
            self.display.borrow_mut().set_position(cursor_surface, x, y);

            // Gets the resource's pixels into the display by importing the buffer.
            if let Some(import_id) = resource.import_to_display(&self.display) {
                self.display.borrow_mut().flip_to(cursor_surface, import_id);
                return GpuResponse::OkNoData;
            }

            // Importing failed, so try copying the pixels into the surface's slower shared memory
            // framebuffer.
            if let Some(buffer) = resource.buffer() {
                if let Some(fb) = self.display.borrow_mut().framebuffer_memory(cursor_surface) {
                    if let Err(e) =
                        buffer.read_to_volatile(0, 0, buffer.width(), buffer.height(), 0, fb)
                    {
                        error!("failed to copy resource to cursor: {}", e);
                        return GpuResponse::ErrInvalidParameter;
                    }
                }
                self.display.borrow_mut().flip(cursor_surface);
            }
            GpuResponse::OkNoData
        } else {
            GpuResponse::ErrInvalidResourceId
        }
    }

    /// Moves the cursor's position to the given coordinates.
    pub fn move_cursor(&mut self, x: u32, y: u32) -> GpuResponse {
        if let Some(cursor_surface) = self.cursor_surface {
            if let Some(scanout_surface) = self.scanout_surface {
                let display = self.display.borrow_mut();
                display.set_position(cursor_surface, x, y);
                display.commit(scanout_surface);
            }
        }
        GpuResponse::OkNoData
    }

    /// Gets the renderer's capset information associated with `index`.
    pub fn get_capset_info(&self, index: u32) -> GpuResponse {
        let id = match index {
            0 => VIRTIO_GPU_CAPSET_VIRGL,
            1 => VIRTIO_GPU_CAPSET_VIRGL2,
            _ => return GpuResponse::ErrInvalidParameter,
        };
        let (version, size) = self.renderer.get_cap_set_info(id);
        GpuResponse::OkCapsetInfo { id, version, size }
    }

    /// Gets the capset of `version` associated with `id`.
    pub fn get_capset(&self, id: u32, version: u32) -> GpuResponse {
        GpuResponse::OkCapset(self.renderer.get_cap_set(id, version))
    }

    /// Creates a fresh renderer context with the given `id`.
    pub fn create_renderer_context(&mut self, id: u32) -> GpuResponse {
        if id == 0 {
            return GpuResponse::ErrInvalidContextId;
        }
        match self.contexts.entry(id) {
            Entry::Occupied(_) => GpuResponse::ErrInvalidContextId,
            Entry::Vacant(slot) => match self.renderer.create_context(id) {
                Ok(ctx) => {
                    slot.insert(ctx);
                    GpuResponse::OkNoData
                }
                Err(e) => {
                    error!("failed to create renderer ctx: {}", e);
                    GpuResponse::ErrUnspec
                }
            },
        }
    }

    /// Destorys the renderer context associated with `id`.
    pub fn destroy_renderer_context(&mut self, id: u32) -> GpuResponse {
        match self.contexts.remove(&id) {
            Some(_) => GpuResponse::OkNoData,
            None => GpuResponse::ErrInvalidContextId,
        }
    }

    /// Attaches the indicated resource to the given context.
    pub fn context_attach_resource(&mut self, ctx_id: u32, res_id: u32) -> GpuResponse {
        match (
            self.contexts.get_mut(&ctx_id),
            self.resources
                .get_mut(&res_id)
                .and_then(|res| res.gpu_renderer_resource()),
        ) {
            (Some(ctx), Some(res)) => {
                ctx.attach(res);
                GpuResponse::OkNoData
            }
            (None, _) => GpuResponse::ErrInvalidContextId,
            (_, None) => GpuResponse::ErrInvalidResourceId,
        }
    }

    /// detaches the indicated resource to the given context.
    pub fn context_detach_resource(&mut self, ctx_id: u32, res_id: u32) -> GpuResponse {
        match (
            self.contexts.get_mut(&ctx_id),
            self.resources
                .get_mut(&res_id)
                .and_then(|res| res.gpu_renderer_resource()),
        ) {
            (Some(ctx), Some(res)) => {
                ctx.detach(res);
                GpuResponse::OkNoData
            }
            (None, _) => GpuResponse::ErrInvalidContextId,
            (_, None) => GpuResponse::ErrInvalidResourceId,
        }
    }

    pub fn validate_args_as_fourcc(args: ResourceCreateArgs) -> Option<u32> {
        if args.depth == 1 && args.array_size == 1 && args.last_level == 0 && args.nr_samples == 0 {
            renderer_fourcc(args.format)
        } else {
            None
        }
    }

    /// Creates a 3D resource with the given properties and associated it with the given id.
    pub fn resource_create_3d(
        &mut self,
        id: u32,
        target: u32,
        format: u32,
        bind: u32,
        width: u32,
        height: u32,
        depth: u32,
        array_size: u32,
        last_level: u32,
        nr_samples: u32,
        flags: u32,
    ) -> GpuResponse {
        if id == 0 {
            return GpuResponse::ErrInvalidResourceId;
        }

        let create_args = ResourceCreateArgs {
            handle: id,
            target,
            format,
            bind,
            width,
            height,
            depth,
            array_size,
            last_level,
            nr_samples,
            flags,
        };

        match self.resources.entry(id) {
            Entry::Occupied(_) => GpuResponse::ErrInvalidResourceId,
            Entry::Vacant(slot) => match Backend::validate_args_as_fourcc(create_args) {
                Some(fourcc) => {
                    let buffer = match self.device.create_buffer(
                        width,
                        height,
                        Format::from(fourcc),
                        Flags::empty().use_scanout(true).use_rendering(true),
                    ) {
                        Ok(buffer) => buffer,
                        Err(e) => {
                            error!("failed to create buffer for 3d resource {}: {}", format, e);
                            return GpuResponse::ErrUnspec;
                        }
                    };

                    let dma_buf_fd = match buffer.export_plane_fd(0) {
                        Ok(dma_buf_fd) => dma_buf_fd,
                        Err(e) => {
                            error!("failed to export plane fd: {}", e);
                            return GpuResponse::ErrUnspec;
                        }
                    };

                    let image = match self.renderer.image_from_dmabuf(
                        fourcc,
                        width,
                        height,
                        dma_buf_fd.as_raw_fd(),
                        buffer.plane_offset(0),
                        buffer.plane_stride(0),
                    ) {
                        Ok(image) => image,
                        Err(e) => {
                            error!("failed to create egl image: {}", e);
                            return GpuResponse::ErrUnspec;
                        }
                    };

                    let res = self.renderer.import_resource(create_args, &image);
                    match res {
                        Ok(res) => {
                            let format_modifier = buffer.format_modifier();
                            let mut plane_info = Vec::with_capacity(buffer.num_planes());
                            for plane_index in 0..buffer.num_planes() {
                                plane_info.push(GpuResponsePlaneInfo {
                                    stride: buffer.plane_stride(plane_index),
                                    offset: buffer.plane_offset(plane_index),
                                });
                            }
                            let backed = BackedBuffer::new_renderer_registered(buffer, res, image);
                            slot.insert(Box::new(backed));
                            GpuResponse::OkResourcePlaneInfo {
                                format_modifier,
                                plane_info,
                            }
                        }
                        Err(e) => {
                            error!("failed to import renderer resource: {}", e);
                            GpuResponse::ErrUnspec
                        }
                    }
                }
                None => {
                    let res = self.renderer.create_resource(create_args);
                    match res {
                        Ok(res) => {
                            slot.insert(Box::new(res));
                            GpuResponse::OkNoData
                        }
                        Err(e) => {
                            error!("failed to create renderer resource: {}", e);
                            GpuResponse::ErrUnspec
                        }
                    }
                }
            },
        }
    }

    /// Copes the given 3D rectangle of pixels of the given resource's backing memory to the host
    /// side resource.
    pub fn transfer_to_resource_3d(
        &mut self,
        ctx_id: u32,
        res_id: u32,
        x: u32,
        y: u32,
        z: u32,
        width: u32,
        height: u32,
        depth: u32,
        level: u32,
        stride: u32,
        layer_stride: u32,
        offset: u64,
    ) -> GpuResponse {
        let ctx = match ctx_id {
            0 => None,
            id => match self.contexts.get(&id) {
                None => return GpuResponse::ErrInvalidContextId,
                ctx => ctx,
            },
        };
        match self.resources.get_mut(&res_id) {
            Some(res) => match res.gpu_renderer_resource() {
                Some(res) => {
                    let transfer_box = Box3 {
                        x,
                        y,
                        z,
                        w: width,
                        h: height,
                        d: depth,
                    };
                    let res =
                        res.transfer_write(ctx, level, stride, layer_stride, transfer_box, offset);
                    match res {
                        Ok(_) => GpuResponse::OkNoData,
                        Err(e) => {
                            error!("failed to transfer to host: {}", e);
                            GpuResponse::ErrUnspec
                        }
                    }
                }
                None => GpuResponse::ErrInvalidResourceId,
            },
            None => GpuResponse::ErrInvalidResourceId,
        }
    }

    /// Copes the given rectangle of pixels from the resource to the given resource's backing
    /// memory.
    pub fn transfer_from_resource_3d(
        &mut self,
        ctx_id: u32,
        res_id: u32,
        x: u32,
        y: u32,
        z: u32,
        width: u32,
        height: u32,
        depth: u32,
        level: u32,
        stride: u32,
        layer_stride: u32,
        offset: u64,
    ) -> GpuResponse {
        let ctx = match ctx_id {
            0 => None,
            id => match self.contexts.get(&id) {
                None => return GpuResponse::ErrInvalidContextId,
                ctx => ctx,
            },
        };
        match self.resources.get_mut(&res_id) {
            Some(res) => match res.gpu_renderer_resource() {
                Some(res) => {
                    let transfer_box = Box3 {
                        x,
                        y,
                        z,
                        w: width,
                        h: height,
                        d: depth,
                    };
                    let res =
                        res.transfer_read(ctx, level, stride, layer_stride, transfer_box, offset);
                    match res {
                        Ok(_) => GpuResponse::OkNoData,
                        Err(e) => {
                            error!("failed to transfer from host: {}", e);
                            GpuResponse::ErrUnspec
                        }
                    }
                }
                None => GpuResponse::ErrInvalidResourceId,
            },
            None => GpuResponse::ErrInvalidResourceId,
        }
    }

    /// Submits a command buffer to the given rendering context.
    pub fn submit_command(&mut self, ctx_id: u32, commands: &mut [u8]) -> GpuResponse {
        match self.contexts.get_mut(&ctx_id) {
            Some(ctx) => match ctx.submit(&mut commands[..]) {
                Ok(_) => GpuResponse::OkNoData,
                Err(e) => {
                    error!("failed to submit command buffer: {}", e);
                    GpuResponse::ErrUnspec
                }
            },
            None => GpuResponse::ErrInvalidContextId,
        }
    }

    pub fn create_fence(&mut self, ctx_id: u32, fence_id: u32) -> GpuResponse {
        // There is a mismatch of ordering that is intentional.
        // This create_fence matches the other functions in Backend, yet
        // the renderer matches the virgl interface.
        match self.renderer.create_fence(fence_id, ctx_id) {
            Ok(_) => GpuResponse::OkNoData,
            Err(e) => {
                error!("failed to create fence: {}", e);
                GpuResponse::ErrUnspec
            }
        }
    }

    pub fn fence_poll(&mut self) -> u32 {
        self.renderer.poll()
    }

    pub fn force_ctx_0(&mut self) {
        self.renderer.force_ctx_0();
    }
}
