1 // Copyright 2016 The Fuchsia Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #pragma once 6 7 #include <semaphore.h> 8 #include <stdlib.h> 9 10 #include <ddk/protocol/display/controller.h> 11 #include <fbl/unique_ptr.h> 12 #include <zircon/pixelformat.h> 13 #include <zircon/compiler.h> 14 15 #include "device.h" 16 #include "ring.h" 17 #include "virtio_gpu.h" 18 19 namespace virtio { 20 21 class Ring; 22 23 class GpuDevice : public Device { 24 public: 25 GpuDevice(zx_device_t* device, zx::bti bti, fbl::unique_ptr<Backend> backend); 26 virtual ~GpuDevice(); 27 28 zx_status_t Init() override; 29 30 void IrqRingUpdate() override; 31 void IrqConfigChange() override; 32 pmode()33 const virtio_gpu_resp_display_info::virtio_gpu_display_one* pmode() const { return &pmode_; } 34 35 void Flush(); 36 tag()37 const char* tag() const override { return "virtio-gpu"; }; 38 39 private: 40 // DDK driver hooks 41 static void virtio_gpu_set_display_controller_interface( 42 void* ctx, const display_controller_interface_t* intf); 43 static zx_status_t virtio_gpu_import_vmo_image( 44 void* ctx, image_t* image, zx_handle_t vmo, size_t offset); 45 static void virtio_gpu_release_image(void* ctx, image_t* image); 46 static uint32_t virtio_gpu_check_configuration( 47 void* ctx, const display_config_t** display_configs, size_t display_count, 48 uint32_t** layer_cfg_results, size_t* layer_cfg_result_count); 49 static void virtio_gpu_apply_configuration( 50 void* ctx, const display_config_t** display_configs, size_t display_count); 51 static uint32_t virtio_gpu_compute_linear_stride( 52 void* ctx, uint32_t width, zx_pixel_format_t format); 53 static zx_status_t virtio_gpu_allocate_vmo(void* ctx, uint64_t size, zx_handle_t* vmo_out); 54 55 56 // Internal routines 57 template <typename RequestType, typename ResponseType> 58 void send_command_response(const RequestType* cmd, ResponseType** res); 59 60 zx_status_t get_display_info(); 61 zx_status_t allocate_2d_resource(uint32_t* resource_id, uint32_t width, uint32_t height); 62 zx_status_t attach_backing(uint32_t resource_id, zx_paddr_t ptr, size_t buf_len); 63 zx_status_t set_scanout(uint32_t scanout_id, uint32_t resource_id, uint32_t width, uint32_t height); 64 zx_status_t flush_resource(uint32_t resource_id, uint32_t width, uint32_t height); 65 zx_status_t transfer_to_host_2d(uint32_t resource_id, uint32_t width, uint32_t height); 66 67 zx_status_t virtio_gpu_start(); 68 thrd_t start_thread_ = {}; 69 70 // the main virtio ring 71 Ring vring_ = {this}; 72 73 // display protocol ops 74 display_controller_impl_protocol_ops_t display_proto_ops_ = {}; 75 76 // gpu op 77 io_buffer_t gpu_req_; 78 79 // A saved copy of the display 80 virtio_gpu_resp_display_info::virtio_gpu_display_one pmode_ = {}; 81 int pmode_id_ = -1; 82 83 uint32_t next_resource_id_ = 1; 84 85 fbl::Mutex request_lock_; 86 sem_t request_sem_; 87 sem_t response_sem_; 88 89 // Flush thread 90 void virtio_gpu_flusher(); 91 thrd_t flush_thread_ = {}; 92 fbl::Mutex flush_lock_; 93 cnd_t flush_cond_ = {}; 94 bool flush_pending_ = false; 95 96 display_controller_interface_t dc_intf_; 97 98 struct imported_image* current_fb_; 99 struct imported_image* displayed_fb_; 100 101 zx_pixel_format_t supported_formats_ = ZX_PIXEL_FORMAT_RGB_x888; 102 }; 103 104 } // namespace virtio 105