| // Copyright 2016 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #pragma once |
| |
| #include <semaphore.h> |
| #include <stdlib.h> |
| |
| #include <ddk/protocol/display-controller.h> |
| #include <fbl/unique_ptr.h> |
| #include <zircon/pixelformat.h> |
| #include <zircon/compiler.h> |
| |
| #include "device.h" |
| #include "ring.h" |
| #include "virtio_gpu.h" |
| |
| namespace virtio { |
| |
| class Ring; |
| |
| class GpuDevice : public Device { |
| public: |
| GpuDevice(zx_device_t* device, zx::bti bti, fbl::unique_ptr<Backend> backend); |
| virtual ~GpuDevice(); |
| |
| zx_status_t Init() override; |
| |
| void IrqRingUpdate() override; |
| void IrqConfigChange() override; |
| |
| const virtio_gpu_resp_display_info::virtio_gpu_display_one* pmode() const { return &pmode_; } |
| |
| void Flush(); |
| |
| const char* tag() const override { return "virtio-gpu"; }; |
| |
| private: |
| // DDK driver hooks |
| static void virtio_gpu_set_display_controller_interface( |
| void* ctx, const display_controller_interface_t* intf); |
| static zx_status_t virtio_gpu_import_vmo_image( |
| void* ctx, image_t* image, zx_handle_t vmo, size_t offset); |
| static void virtio_gpu_release_image(void* ctx, image_t* image); |
| static uint32_t virtio_gpu_check_configuration( |
| void* ctx, const display_config_t** display_configs, size_t display_count, |
| uint32_t** layer_cfg_results, size_t* layer_cfg_result_count); |
| static void virtio_gpu_apply_configuration( |
| void* ctx, const display_config_t** display_configs, size_t display_count); |
| static uint32_t virtio_gpu_compute_linear_stride( |
| void* ctx, uint32_t width, zx_pixel_format_t format); |
| static zx_status_t virtio_gpu_allocate_vmo(void* ctx, uint64_t size, zx_handle_t* vmo_out); |
| |
| |
| // Internal routines |
| template <typename RequestType, typename ResponseType> |
| void send_command_response(const RequestType* cmd, ResponseType** res); |
| |
| zx_status_t get_display_info(); |
| zx_status_t allocate_2d_resource(uint32_t* resource_id, uint32_t width, uint32_t height); |
| zx_status_t attach_backing(uint32_t resource_id, zx_paddr_t ptr, size_t buf_len); |
| zx_status_t set_scanout(uint32_t scanout_id, uint32_t resource_id, uint32_t width, uint32_t height); |
| zx_status_t flush_resource(uint32_t resource_id, uint32_t width, uint32_t height); |
| zx_status_t transfer_to_host_2d(uint32_t resource_id, uint32_t width, uint32_t height); |
| |
| zx_status_t virtio_gpu_start(); |
| thrd_t start_thread_ = {}; |
| |
| // the main virtio ring |
| Ring vring_ = {this}; |
| |
| // display protocol ops |
| display_controller_protocol_ops_t display_proto_ops_ = {}; |
| |
| // gpu op |
| io_buffer_t gpu_req_; |
| |
| // A saved copy of the display |
| virtio_gpu_resp_display_info::virtio_gpu_display_one pmode_ = {}; |
| int pmode_id_ = -1; |
| |
| uint32_t next_resource_id_ = 1; |
| |
| fbl::Mutex request_lock_; |
| sem_t request_sem_; |
| sem_t response_sem_; |
| |
| // Flush thread |
| void virtio_gpu_flusher(); |
| thrd_t flush_thread_ = {}; |
| fbl::Mutex flush_lock_; |
| cnd_t flush_cond_ = {}; |
| bool flush_pending_ = false; |
| |
| display_controller_interface_t dc_intf_; |
| |
| struct imported_image* current_fb_; |
| struct imported_image* displayed_fb_; |
| |
| zx_pixel_format_t supported_formats_ = ZX_PIXEL_FORMAT_RGB_x888; |
| }; |
| |
| } // namespace virtio |