diff --git a/cros_gralloc/cros_gralloc_driver.cc b/cros_gralloc/cros_gralloc_driver.cc index 84893c86..24301407 100644 --- a/cros_gralloc/cros_gralloc_driver.cc +++ b/cros_gralloc/cros_gralloc_driver.cc @@ -8,6 +8,9 @@ #include #include +#include +#include +#include #include #include @@ -19,6 +22,12 @@ #include "i915_private_android.h" #endif +#define IVSH_WIDTH 1920 +#define IVSH_HEIGHT 1080 + +struct driver *cros_gralloc_driver::drv_ivshmem_ = nullptr; +int32_t cros_gralloc_driver::drv_num = 0; + // drv_render_ aim to open the render node cros_gralloc_driver::cros_gralloc_driver() : drv_render_(nullptr) { @@ -35,6 +44,94 @@ cros_gralloc_driver::~cros_gralloc_driver() drv_render_ = nullptr; close(fd); } + + if (drv_ivshmem_) { + int fd = drv_get_fd(drv_ivshmem_); + drv_destroy(drv_ivshmem_); + drv_ivshmem_ = nullptr; + close(fd); + } + //pthread_join(tid, NULL); +} + +void *cros_gralloc_driver::reload2(void *arg) +{ + int fd; + drmVersionPtr version; + char const *str = "%s/renderD%d"; + const char *undesired[2] = { "vgem", nullptr }; + uint32_t num_nodes = 63; + uint32_t min_node = 128; + uint32_t max_node = (min_node + num_nodes); + uint32_t j; + char *node; + + const int render_num = 10; + const int name_length = 50; + int availabe_node = 0; + uint32_t gpu_grp_type = 0; + bool in_loop = true; + + do { + availabe_node = 0; + for (uint32_t i = min_node; i < max_node; i++) { + if (asprintf(&node, str, DRM_DIR_NAME, i) < 0) + continue; + + fd = open(node, O_RDWR, 0); + free(node); + if (fd < 0) + continue; + + version = drmGetVersion(fd); + if (!version) { + close(fd); + continue; + } + + for (j = 0; j < ARRAY_SIZE(undesired); j++) { + if (undesired[j] && !strcmp(version->name, undesired[j])) { + drmFreeVersion(version); + close(fd); + break; + } + } + + // hit any of undesired render node + if (j < ARRAY_SIZE(undesired)) + continue; + + availabe_node++; + close(fd); + drmFreeVersion(version); + } + + // have the ivshemem node + if ((availabe_node > drv_num) && !drv_ivshmem_) { + drv_num = availabe_node; + if (asprintf(&node, str, DRM_DIR_NAME, (min_node + availabe_node - 1)) < 0) + drv_log("Open ivshmem node fail\n"); + fd = open(node, O_RDWR, 0); + free(node); + drv_ivshmem_ = drv_create(fd); + if (!drv_ivshmem_) { + drv_log("Failed to create driver for ivshmem device\n"); + close(fd); + break; + } + gpu_grp_type = THREE_GPU_IGPU_VIRTIO_IVSHMEM; + + if (drv_ivshmem_) { + if (drv_init(drv_ivshmem_, gpu_grp_type)) { + drv_log("Failed to init ivshmem driver\n"); + break; + } + } + in_loop = false; + } + sleep(1); + } while (in_loop); + pthread_exit(NULL); } int32_t cros_gralloc_driver::init() @@ -72,6 +169,13 @@ int32_t cros_gralloc_driver::init() close(fd); } + if (drv_ivshmem_) { + int fd = drv_get_fd(drv_ivshmem_); + drv_destroy(drv_ivshmem_); + drv_ivshmem_ = nullptr; + close(fd); + } + for (uint32_t i = min_node; i < max_node; i++) { if (asprintf(&node, str, DRM_DIR_NAME, i) < 0) continue; @@ -111,6 +215,7 @@ int32_t cros_gralloc_driver::init() } // open the first render node + drv_num = availabe_node; if (availabe_node > 0) { drv_render_ = drv_create(node_fd[0]); if (!drv_render_) { @@ -124,12 +229,13 @@ int32_t cros_gralloc_driver::init() case 1: if (!drv_render_) goto fail; - gpu_grp_type = (virtio_node_idx != -1)? ONE_GPU_VIRTIO: ONE_GPU_INTEL; + gpu_grp_type = (virtio_node_idx != -1) ? ONE_GPU_VIRTIO : ONE_GPU_INTEL; break; // is SR-IOV or iGPU + dGPU case 2: close(node_fd[1]); if (virtio_node_idx != -1) { + is_sriov_mode = true; gpu_grp_type = TWO_GPU_IGPU_VIRTIO; } else { gpu_grp_type = TWO_GPU_IGPU_DGPU; @@ -137,13 +243,19 @@ int32_t cros_gralloc_driver::init() break; // is SR-IOV + dGPU case 3: + close(node_fd[1]); + is_sriov_mode = true; if (!strcmp(node_name[1], "i915")) { - close(node_fd[1]); - } - if (virtio_node_idx != -1) { - close(node_fd[virtio_node_idx]); + gpu_grp_type = THREE_GPU_IGPU_VIRTIO_DGPU; + } else { + drv_ivshmem_ = drv_create(node_fd[2]); + if (!drv_ivshmem_) { + drv_log("Failed to create driver for ivshmem device\n"); + close(node_fd[2]); + goto fail; + } + gpu_grp_type = THREE_GPU_IGPU_VIRTIO_IVSHMEM; } - gpu_grp_type = THREE_GPU_IGPU_VIRTIO_DGPU; // TO-DO: the 3rd node is i915 or others. break; } @@ -154,11 +266,24 @@ int32_t cros_gralloc_driver::init() goto fail; } } + + if (drv_ivshmem_) { + if (drv_init(drv_ivshmem_, gpu_grp_type)) { + drv_log("Failed to init ivshmem driver\n"); + goto fail; + } + } } if (!drv_render_) return -ENODEV; + if (!drv_ivshmem_) { + pthread_attr_t attr; + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + pthread_create(&tid, &attr, reload2, NULL); + } return 0; fail: @@ -169,6 +294,13 @@ int32_t cros_gralloc_driver::init() drv_render_ = nullptr; } + if (drv_ivshmem_) { + fd = drv_get_fd(drv_ivshmem_); + drv_destroy(drv_ivshmem_); + close(fd); + drv_ivshmem_ = nullptr; + } + return -ENODEV; } @@ -177,7 +309,15 @@ bool cros_gralloc_driver::is_supported(struct cros_gralloc_buffer_descriptor *de struct combination *combo; uint32_t resolved_format; bool supported; - struct driver *drv = drv_render_; + struct driver *drv; + + if (drv_ivshmem_ && (descriptor->use_flags & BO_USE_SCANOUT) && + (descriptor->width == IVSH_WIDTH) && (descriptor->height == IVSH_HEIGHT)) { + drv = drv_ivshmem_; + use_ivshmem = true; + } else { + drv = drv_render_; + } resolved_format = drv_resolve_format(drv, descriptor->drm_format, descriptor->use_flags); combo = drv_get_combination(drv, resolved_format, descriptor->use_flags); @@ -185,9 +325,26 @@ bool cros_gralloc_driver::is_supported(struct cros_gralloc_buffer_descriptor *de supported = (combo != nullptr); if (!supported && (descriptor->use_flags & BO_USE_SCANOUT)) { - descriptor->use_flags &= ~BO_USE_SCANOUT; - combo = drv_get_combination(drv, resolved_format, descriptor->use_flags); + if (is_sriov_mode) { + /* if kmsro is enabled, it is scanout buffer and not used for video, + * don't need remove scanout flag */ + if (!IsSupportedYUVFormat(descriptor->droid_format)) { + combo = drv_get_combination(drv, resolved_format, + (descriptor->use_flags) & + (~BO_USE_SCANOUT)); supported = (combo != nullptr); + } else { + drv = drv_render_; + descriptor->use_flags &= ~BO_USE_SCANOUT; + combo = drv_get_combination(drv, resolved_format, + descriptor->use_flags); + supported = (combo != nullptr); + } + } else { + descriptor->use_flags &= ~BO_USE_SCANOUT; + combo = drv_get_combination(drv, resolved_format, descriptor->use_flags); + supported = (combo != nullptr); + } } return supported; } @@ -230,9 +387,15 @@ int32_t cros_gralloc_driver::allocate(const struct cros_gralloc_buffer_descripto struct bo *bo; struct cros_gralloc_handle *hnd; - struct driver *drv; - drv = drv_render_; + + if (drv_ivshmem_ && (descriptor->use_flags & BO_USE_SCANOUT) && + (descriptor->width == IVSH_WIDTH) && (descriptor->height == IVSH_HEIGHT)) { + use_ivshmem = true; + drv = drv_ivshmem_; + } else { + drv = drv_render_; + } resolved_format = drv_resolve_format(drv, descriptor->drm_format, descriptor->use_flags); use_flags = descriptor->use_flags; @@ -309,7 +472,6 @@ int32_t cros_gralloc_driver::allocate(const struct cros_gralloc_buffer_descripto * native_handle_delete(). */ hnd = static_cast(malloc(num_bytes)); - hnd->from_kms = false; // not used, just set a default value. keep this member to be backward compatible. hnd->base.version = sizeof(hnd->base); hnd->base.numFds = num_fds; hnd->base.numInts = num_ints; @@ -379,7 +541,11 @@ int32_t cros_gralloc_driver::retain(buffer_handle_t handle) return -EINVAL; } - drv = drv_render_; + if (drv_ivshmem_ && use_ivshmem) { + drv = drv_ivshmem_; + } else { + drv = drv_render_; + } auto buffer = get_buffer(hnd); if (buffer) { @@ -641,8 +807,12 @@ int32_t cros_gralloc_driver::get_reserved_region(buffer_handle_t handle, uint32_t cros_gralloc_driver::get_resolved_drm_format(uint32_t drm_format, uint64_t usage) { - struct driver *drv = drv_render_; - + struct driver *drv; + if (drv_ivshmem_ && use_ivshmem) { + drv = drv_ivshmem_; + } else { + drv = drv_render_; + } return drv_resolve_format(drv, drm_format, usage); } diff --git a/cros_gralloc/cros_gralloc_driver.h b/cros_gralloc/cros_gralloc_driver.h index bcd3ba20..5ddf996d 100644 --- a/cros_gralloc/cros_gralloc_driver.h +++ b/cros_gralloc/cros_gralloc_driver.h @@ -53,6 +53,7 @@ class cros_gralloc_driver void for_each_handle(const std::function &function); bool IsSupportedYUVFormat(uint32_t droid_format); + static void *reload2(void *arg); private: cros_gralloc_driver(cros_gralloc_driver const &); @@ -60,6 +61,11 @@ class cros_gralloc_driver cros_gralloc_buffer *get_buffer(cros_gralloc_handle_t hnd); struct driver *drv_render_; + static struct driver *drv_ivshmem_; + bool use_ivshmem = false; + static int32_t drv_num; + bool is_sriov_mode = false; + pthread_t tid; std::mutex mutex_; std::unordered_map buffers_; std::unordered_map> diff --git a/cros_gralloc/cros_gralloc_handle.h b/cros_gralloc/cros_gralloc_handle.h index ae8e6793..4c538996 100644 --- a/cros_gralloc/cros_gralloc_handle.h +++ b/cros_gralloc/cros_gralloc_handle.h @@ -27,7 +27,6 @@ struct cros_gralloc_handle { uint32_t strides[DRV_MAX_PLANES]; uint32_t offsets[DRV_MAX_PLANES]; uint32_t sizes[DRV_MAX_PLANES]; - bool from_kms; uint32_t id; uint32_t width; uint32_t height; diff --git a/drv_priv.h b/drv_priv.h index 5f500906..523f2eeb 100644 --- a/drv_priv.h +++ b/drv_priv.h @@ -54,7 +54,8 @@ enum CIV_GPU_TYPE { ONE_GPU_VIRTIO, TWO_GPU_IGPU_VIRTIO, TWO_GPU_IGPU_DGPU, - THREE_GPU_IGPU_VIRTIO_DGPU + THREE_GPU_IGPU_VIRTIO_DGPU, + THREE_GPU_IGPU_VIRTIO_IVSHMEM }; struct driver {