blob: 6eb9de6fa7a0219a0f65e049fb5dd974c4c5f99a [file] [log] [blame]
// 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.
#ifndef SRC_GRAPHICS_DRIVERS_VIRTIO_GPU_H_
#define SRC_GRAPHICS_DRIVERS_VIRTIO_GPU_H_
#include <fuchsia/hardware/display/controller/c/banjo.h>
#include <fuchsia/hardware/display/controller/cpp/banjo.h>
#include <fuchsia/hardware/sysmem/c/banjo.h>
#include <lib/virtio/device.h>
#include <lib/virtio/ring.h>
#include <semaphore.h>
#include <stdlib.h>
#include <zircon/compiler.h>
#include <zircon/pixelformat.h>
#include <memory>
#include <ddktl/device.h>
#include "virtio_gpu.h"
namespace virtio {
class Ring;
class GpuDevice;
using DeviceType = ddk::Device<GpuDevice, ddk::GetProtocolable>;
class GpuDevice : public Device,
public DeviceType,
public ddk::DisplayControllerImplProtocol<GpuDevice, ddk::base_protocol> {
public:
GpuDevice(zx_device_t* device, zx::bti bti, std::unique_ptr<Backend> backend);
virtual ~GpuDevice();
zx_status_t Init() override;
zx_status_t DdkGetProtocol(uint32_t proto_id, void* out);
void DdkRelease() { virtio::Device::Release(); }
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"; }
zx_status_t GetVmoAndStride(image_t* image, zx_unowned_handle_t handle, uint32_t index,
zx::vmo* vmo_out, size_t* offset_out, uint32_t* pixel_size_out,
uint32_t* row_bytes_out);
void DisplayControllerImplSetDisplayControllerInterface(
const display_controller_interface_protocol_t* intf);
zx_status_t DisplayControllerImplImportVmoImage(image_t* image, zx::vmo vmo, size_t offset);
zx_status_t DisplayControllerImplImportImage(image_t* image, zx_unowned_handle_t collection,
uint32_t index);
void DisplayControllerImplReleaseImage(image_t* image);
uint32_t DisplayControllerImplCheckConfiguration(const display_config_t** display_config_list,
size_t display_config_count,
uint32_t** out_layer_cfg_result_list,
size_t* layer_cfg_result_count);
void DisplayControllerImplApplyConfiguration(const display_config_t** display_config_list,
size_t display_config_count);
void DisplayControllerImplSetEld(uint64_t display_id, const uint8_t* raw_eld_list,
size_t raw_eld_count) {} // No ELD required for non-HDA systems.
zx_status_t DisplayControllerImplGetSysmemConnection(zx::channel sysmem_handle);
zx_status_t DisplayControllerImplSetBufferCollectionConstraints(const image_t* config,
zx_unowned_handle_t collection);
zx_status_t DisplayControllerImplGetSingleBufferFramebuffer(zx::vmo* out_vmo,
uint32_t* out_stride);
private:
// Internal routines
template <typename RequestType, typename ResponseType>
void send_command_response(const RequestType* cmd, ResponseType** res);
zx_status_t Import(zx::vmo vmo, image_t* image, size_t offset, uint32_t pixel_size,
uint32_t row_bytes);
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};
// 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_protocol_t dc_intf_ = {};
sysmem_protocol_t sysmem_ = {};
struct imported_image* current_fb_ = nullptr;
struct imported_image* displayed_fb_ = nullptr;
zx_pixel_format_t supported_formats_ = ZX_PIXEL_FORMAT_RGB_x888;
};
} // namespace virtio
#endif // SRC_GRAPHICS_DRIVERS_VIRTIO_GPU_H_