Skip to content

Commit

Permalink
Add probe new added render node
Browse files Browse the repository at this point in the history
If it is sancout buffer with certain resolution,
use the ivshm node to allocate buffer

Tracked-On: OAM-122966
Signed-off-by: He, Yue <[email protected]>
  • Loading branch information
yhe39 committed Sep 4, 2024
1 parent 485e908 commit 15e5fa1
Show file tree
Hide file tree
Showing 3 changed files with 161 additions and 8 deletions.
163 changes: 156 additions & 7 deletions cros_gralloc/cros_gralloc_driver.cc
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@
// DRM Card nodes start at 0
#define DRM_CARD_NODE_START 0

#define IVSH_WIDTH 1920
#define IVSH_HEIGHT 1080

class cros_gralloc_driver_preloader
{
public:
Expand Down Expand Up @@ -109,6 +112,103 @@ cros_gralloc_driver *cros_gralloc_driver::get_instance()
close(fd); \
}

int32_t cros_gralloc_driver::reload()
{
int fd;
drmVersionPtr version;
char const *str = "%s/renderD%d";
const char *undesired[2] = { "vgem", nullptr };
uint32_t min_node = 128;
uint32_t max_node = (min_node + drv_num + 2);
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;

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_loge("Open ivshmem node fail\n");
return -ENODEV;
}

fd = open(node, O_RDWR, 0);
free(node);

if (fd < 0) {
return -ENODEV;
}

version = drmGetVersion(fd);
if (!version) {
close(fd);
return -ENODEV;
}

if (strcmp(version->name, "virtio_gpu")) {
drv_loge("New added node is not ivshmem node\n");
close(fd);
drmFreeVersion(version);
return -ENODEV;
}

drv_ivshmem_ = drv_create(fd);
if (!drv_ivshmem_) {
drv_loge("Failed to create driver for ivshmem device\n");
close(fd);
return -ENODEV;
}
gpu_grp_type = THREE_GPU_IGPU_VIRTIO_IVSHMEM;

if (drv_ivshmem_) {
if (drv_init(drv_ivshmem_, gpu_grp_type)) {
drv_loge("Failed to init ivshmem driver\n");
DRV_DESTROY(drv_ivshmem_)
return -ENODEV;
}
}
}

return 0;
}

cros_gralloc_driver::cros_gralloc_driver()
{
/*
Expand All @@ -134,6 +234,7 @@ cros_gralloc_driver::cros_gralloc_driver()
char *node_name[render_num] = {};
int availabe_node = 0;
int virtio_node_idx = -1;
int ivshm_node_idx = -1;
int renderer_idx = -1;
int video_idx = -1;
uint32_t gpu_grp_type = 0;
Expand All @@ -149,6 +250,10 @@ cros_gralloc_driver::cros_gralloc_driver()
DRV_DESTROY(drv_kms_)
DRV_DESTROY(drv_render_)

if (drv_ivshmem_) {
DRV_DESTROY(drv_ivshmem_)
}

for (uint32_t i = min_render_node; i < max_render_node; i++) {
if (asprintf(&node, render_nodes_fmt, DRM_DIR_NAME, i) < 0)
continue;
Expand Down Expand Up @@ -177,7 +282,10 @@ cros_gralloc_driver::cros_gralloc_driver()
continue;

if (!strcmp(version->name, "virtio_gpu")) {
virtio_node_idx = availabe_node;
if (virtio_node_idx == -1)
virtio_node_idx = availabe_node;
else
ivshm_node_idx = availabe_node;
}

if (!strcmp(version->name, "i915")) {
Expand All @@ -201,6 +309,8 @@ cros_gralloc_driver::cros_gralloc_driver()
drmFreeVersion(version);
}

drv_num = availabe_node;

if (availabe_node > 0) {
switch (availabe_node) {
// only have one render node, is GVT-d/BM/VirtIO
Expand Down Expand Up @@ -262,6 +372,15 @@ cros_gralloc_driver::cros_gralloc_driver()
drv_kms_ = drv_render_;
}

if (ivshm_node_idx != -1) {
if (!(drv_ivshmem_ = drv_create(node_fd[ivshm_node_idx]))) {
drv_loge("Failed to create driver for the ivshm device with card id %d\n",
ivshm_node_idx);
close(node_fd[ivshm_node_idx]);
} else
gpu_grp_type = THREE_GPU_IGPU_VIRTIO_IVSHMEM;
}

// Init drv
DRV_INIT(drv_render_, gpu_grp_type, renderer_idx)
if (video_idx != renderer_idx)
Expand All @@ -282,11 +401,14 @@ cros_gralloc_driver::cros_gralloc_driver()
drv_logi("virtio ivshmem device or no blob\n");
}
}
if (ivshm_node_idx != -1) {
DRV_INIT(drv_ivshmem_, gpu_grp_type, ivshm_node_idx)
}
}

for (int i = 0; i < availabe_node; i++) {
free(node_name[i]);
if ((i != renderer_idx) && (i != video_idx) && (i != virtio_node_idx)) {
if ((i != renderer_idx) && (i != video_idx) && (i != virtio_node_idx) && (i != ivshm_node_idx)) {
close(node_fd[i]);
}
}
Expand Down Expand Up @@ -331,7 +453,14 @@ bool cros_gralloc_driver::get_resolved_format_and_use_flags(
struct combination *combo;

struct driver *drv = is_video_format(descriptor) ? drv_video_ : drv_render_;
if ((descriptor->use_flags & BO_USE_SCANOUT) && !(is_video_format(descriptor)))
if (!drv_ivshmem_) {
if (reload()) {
}
}
if (drv_ivshmem_ && (descriptor->use_flags & BO_USE_SCANOUT) &&
(descriptor->width == IVSH_WIDTH) && (descriptor->height == IVSH_HEIGHT)) {
drv = drv_ivshmem_;
} else if ((descriptor->use_flags & BO_USE_SCANOUT) && !(is_video_format(descriptor)))
drv = drv_kms_;

if (mt8183_camera_quirk_ && (descriptor->use_flags & BO_USE_CAMERA_READ) &&
Expand Down Expand Up @@ -377,7 +506,14 @@ bool cros_gralloc_driver::is_supported(const struct cros_gralloc_buffer_descript
uint32_t resolved_format;
uint64_t resolved_use_flags;
struct driver *drv = is_video_format(descriptor) ? drv_video_ : drv_render_;
if ((descriptor->use_flags & BO_USE_SCANOUT) && !(is_video_format(descriptor)))
if (!drv_ivshmem_) {
if (reload()) {
}
}
if (drv_ivshmem_ && (descriptor->use_flags & BO_USE_SCANOUT) &&
(descriptor->width == IVSH_WIDTH) && (descriptor->height == IVSH_HEIGHT)) {
drv = drv_ivshmem_;
} else if ((descriptor->use_flags & BO_USE_SCANOUT) && !(is_video_format(descriptor)))
drv = drv_kms_;
uint32_t max_texture_size = drv_get_max_texture_2d_size(drv);
if (!get_resolved_format_and_use_flags(descriptor, &resolved_format, &resolved_use_flags))
Expand Down Expand Up @@ -428,9 +564,15 @@ int32_t cros_gralloc_driver::allocate(const struct cros_gralloc_buffer_descripto
struct driver *drv;

drv = is_video_format(descriptor) ? drv_video_ : drv_render_;
if ((descriptor->use_flags & BO_USE_SCANOUT) && (!is_video_format(descriptor))) {
drv = drv_kms_;
if (!drv_ivshmem_) {
if (reload()) {
}
}
if (drv_ivshmem_ && (descriptor->use_flags & BO_USE_SCANOUT) &&
(descriptor->width == IVSH_WIDTH) && (descriptor->height == IVSH_HEIGHT)) {
drv = drv_ivshmem_;
} else if ((descriptor->use_flags & BO_USE_SCANOUT) && !(is_video_format(descriptor)))
drv = drv_kms_;

if (!get_resolved_format_and_use_flags(descriptor, &resolved_format, &resolved_use_flags)) {
ALOGE("Failed to resolve format and use_flags.");
Expand Down Expand Up @@ -585,7 +727,14 @@ int32_t cros_gralloc_driver::retain(buffer_handle_t handle)
.use_flags = hnd->use_flags,
};
drv = is_video_format(&descriptor) ? drv_video_ : drv_render_;
if ((hnd->use_flags & BO_USE_SCANOUT) && (!is_video_format(&descriptor)))
if (!drv_ivshmem_) {
if (reload()) {
}
}
if (drv_ivshmem_ && (hnd->use_flags & BO_USE_SCANOUT) &&
(hnd->width == IVSH_WIDTH) && (hnd->height == IVSH_HEIGHT)) {
drv = drv_ivshmem_;
} else if ((hnd->use_flags & BO_USE_SCANOUT) && !(is_video_format(&descriptor)))
drv = drv_kms_;

auto hnd_it = handles_.find(hnd);
Expand Down
3 changes: 3 additions & 0 deletions cros_gralloc/cros_gralloc_driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ class cros_gralloc_driver
~cros_gralloc_driver();
bool is_initialized();
bool is_video_format(const struct cros_gralloc_buffer_descriptor *descriptor);
int32_t reload();
cros_gralloc_buffer *get_buffer(cros_gralloc_handle_t hnd);
bool
get_resolved_format_and_use_flags(const struct cros_gralloc_buffer_descriptor *descriptor,
Expand Down Expand Up @@ -90,6 +91,8 @@ class cros_gralloc_driver
struct driver *drv_video_ = nullptr;
// the drv_kms_ is used to allocate scanout non-video buffer.
struct driver *drv_kms_ = nullptr;
struct driver *drv_ivshmem_ = nullptr;
int32_t drv_num = 0;
std::mutex mutex_;
std::unordered_map<uint32_t, std::unique_ptr<cros_gralloc_buffer>> buffers_;
std::unordered_map<cros_gralloc_handle_t, cros_gralloc_imported_handle_info> handles_;
Expand Down
3 changes: 2 additions & 1 deletion drv_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,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 {
Expand Down

0 comments on commit 15e5fa1

Please sign in to comment.