2 * buffer manager for libtbm-vigs
4 * Copyright (c) 2013 Samsung Electronics Co., Ltd. All rights reserved.
7 * Stanislav Vorobiov <s.vorobiov@samsung.com>
8 * Jinhyung Jo <jinhyung.jo@samsung.com>
9 * Sangho Park <sangho1206.park@samsung.com>
10 * YeongKyoon Lee <yeongkyoon.lee@samsung.com>
12 * Permission is hereby granted, free of charge, to any person obtaining a copy
13 * of this software and associated documentation files (the "Software"), to deal
14 * in the Software without restriction, including without limitation the rights
15 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16 * copies of the Software, and to permit persons to whom the Software is
17 * furnished to do so, subject to the following conditions:
19 * The above copyright notice and this permission notice shall be included in
20 * all copies or substantial portions of the Software.
22 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
46 #include <hal-common.h>
47 #include <hal-tbm-types.h>
48 #include <hal-tbm-interface.h>
49 #include "tbm_backend_log.h"
51 #define STRERR_BUFSIZE 128
53 #define VIGS_DRM_NAME "vigs"
55 /* global singleton drm_dev. this is shared with yagl. */
56 struct vigs_drm_device *g_drm_dev = NULL;
58 static uint32_t tbm_bufmgr_vigs_color_format_list[] = {
59 HAL_TBM_FORMAT_RGB888,
60 HAL_TBM_FORMAT_ARGB8888,
61 HAL_TBM_FORMAT_RGBA8888,
62 HAL_TBM_FORMAT_XRGB8888,
63 HAL_TBM_FORMAT_XBGR8888,
66 HAL_TBM_FORMAT_YUV420,
69 typedef struct _tbm_vigs_bufmgr tbm_vigs_bufmgr;
70 typedef struct _tbm_vigs_bo tbm_vigs_bo;
72 /* tbm buffor object for vigs */
74 struct vigs_drm_surface *sfc;
76 tbm_vigs_bufmgr *bufmgr_data;
79 /* tbm bufmgr private for vigs */
80 struct _tbm_vigs_bufmgr {
84 struct vigs_drm_device *drm_dev;
88 _tbm_vigs_open_drm(void)
92 fd = drmOpen(VIGS_DRM_NAME, NULL);
94 TBM_BACKEND_ERR("open vigs drm device failed");
102 _get_name(int fd, unsigned int gem)
104 struct drm_gem_flink arg = {0,};
107 if (drmIoctl(fd, DRM_IOCTL_GEM_FLINK, &arg)) {
108 TBM_BACKEND_ERR("fail to DRM_IOCTL_GEM_FLINK gem:%d", gem);
112 return (unsigned int)arg.name;
115 static hal_tbm_bo_handle
116 get_tbm_bo_handle(struct vigs_drm_surface *sfc, int device)
118 hal_tbm_bo_handle bo_handle;
120 struct vigs_drm_gem *gem = &sfc->gem;
121 char buf[STRERR_BUFSIZE];
123 memset(&bo_handle, 0, sizeof(bo_handle));
126 case HAL_TBM_DEVICE_DEFAULT:
127 case HAL_TBM_DEVICE_2D:
128 bo_handle.u32 = gem->handle;
130 case HAL_TBM_DEVICE_CPU:
131 ret = vigs_drm_gem_map(gem, 1);
134 bo_handle.ptr = gem->vaddr;
136 TBM_BACKEND_ERR("vigs_drm_gem_map failed: %s", strerror_r(errno, buf, STRERR_BUFSIZE));
139 case HAL_TBM_DEVICE_3D:
140 bo_handle.ptr = (void *)sfc;
142 case HAL_TBM_DEVICE_MM:
143 TBM_BACKEND_ERR("HAL_TBM_DEVICE_MM not supported");
146 TBM_BACKEND_ERR("%d not supported", device);
153 static hal_tbm_bufmgr_capability
154 tbm_vigs_bufmgr_get_capabilities(hal_tbm_bufmgr *bufmgr, hal_tbm_error *error)
156 hal_tbm_bufmgr_capability capabilities = HAL_TBM_BUFMGR_CAPABILITY_NONE;
158 capabilities = HAL_TBM_BUFMGR_CAPABILITY_SHARE_KEY | HAL_TBM_BUFMGR_CAPABILITY_SHARE_FD;
161 *error = HAL_TBM_ERROR_NONE;
167 tbm_vigs_bufmgr_get_supported_formats(hal_tbm_bufmgr *bufmgr,
168 uint32_t **formats, uint32_t *num)
170 tbm_vigs_bufmgr *bufmgr_data = (tbm_vigs_bufmgr *)bufmgr;
171 uint32_t *color_formats;
174 return HAL_TBM_ERROR_INVALID_PARAMETER;
176 color_formats = (uint32_t *) calloc(1, sizeof(tbm_bufmgr_vigs_color_format_list));
178 return HAL_TBM_ERROR_OUT_OF_MEMORY;
180 memcpy(color_formats, tbm_bufmgr_vigs_color_format_list, sizeof(tbm_bufmgr_vigs_color_format_list));
182 *formats = color_formats;
183 *num = sizeof(tbm_bufmgr_vigs_color_format_list) / sizeof(tbm_bufmgr_vigs_color_format_list[0]);
185 return HAL_TBM_ERROR_NONE;
189 tbm_vigs_bufmgr_get_plane_data(hal_tbm_bufmgr *bufmgr,
190 hal_tbm_format format, int plane_idx, int width,
191 int height, uint32_t * size, uint32_t * offset,
192 uint32_t * pitch, int *bo_idx)
194 tbm_vigs_bufmgr *bufmgr_data = (tbm_vigs_bufmgr *)bufmgr;
201 TBM_BACKEND_RETURN_VAL_IF_FAIL(bufmgr_data != NULL, HAL_TBM_ERROR_INVALID_PARAMETER);
204 case HAL_TBM_FORMAT_RGB888:
205 *size = width * height * 3;
209 return HAL_TBM_ERROR_NONE;
210 case HAL_TBM_FORMAT_XRGB8888:
211 case HAL_TBM_FORMAT_XBGR8888:
212 case HAL_TBM_FORMAT_ARGB8888:
213 case HAL_TBM_FORMAT_RGBA8888:
214 *size = width * height * 4;
218 return HAL_TBM_ERROR_NONE;
219 case HAL_TBM_FORMAT_NV21:
220 if (plane_idx == 0) {
221 *size = width * height;
225 } else if (plane_idx == 1) {
226 *size = width * (height >> 1);
227 *offset = width * height;
231 return HAL_TBM_ERROR_INVALID_PARAMETER;
233 return HAL_TBM_ERROR_NONE;
234 case HAL_TBM_FORMAT_NV61:
235 if (plane_idx == 0) {
236 *size = width * height;
240 } else if (plane_idx == 1) {
241 *size = width * height;
242 *offset = width * height;
246 return HAL_TBM_ERROR_INVALID_PARAMETER;
248 return HAL_TBM_ERROR_NONE;
249 case HAL_TBM_FORMAT_YUV420:
250 if (plane_idx == 0) {
251 *size = width * height;
255 } else if (plane_idx == 1) {
256 *size = (width * height) >> 2;
257 *offset = width * height;
260 } else if (plane_idx == 2) {
261 *size = (width * height) >> 2;
262 *offset = (width * height) + (width * height >> 2);
266 return HAL_TBM_ERROR_INVALID_PARAMETER;
268 return HAL_TBM_ERROR_NONE;
270 return HAL_TBM_ERROR_INVALID_PARAMETER;
275 tbm_vigs_bufmgr_alloc_bo(hal_tbm_bufmgr *bufmgr, unsigned int size,
276 hal_tbm_bo_memory_type flags, hal_tbm_error *error)
278 tbm_vigs_bufmgr *bufmgr_data = (tbm_vigs_bufmgr *)bufmgr;
279 tbm_vigs_bo *bo_data;
280 struct vigs_drm_device *drm_dev;
281 struct vigs_drm_surface *sfc;
282 uint32_t width = 2048, height;
284 char buf[STRERR_BUFSIZE];
286 if (bufmgr_data == NULL || bufmgr_data->drm_dev == NULL) {
287 TBM_BACKEND_ERR("bufmgr_data is null\n");
289 *error = HAL_TBM_ERROR_INVALID_PARAMETER;
293 drm_dev = bufmgr_data->drm_dev;
295 height = ((uint32_t) size + (width * 4) - 1) / (width * 4);
297 ret = vigs_drm_surface_create(drm_dev, width, height, width * 4, vigs_drm_surface_bgra8888, 0, &sfc);
299 TBM_BACKEND_ERR("vigs_drm_suface_create failed: %s", strerror_r(errno, buf, STRERR_BUFSIZE));
301 *error = HAL_TBM_ERROR_INVALID_PARAMETER;
305 bo_data = calloc(1, sizeof(struct _tbm_vigs_bo));
307 TBM_BACKEND_ERR("fail to allocate the bo_data private\n");
308 vigs_drm_gem_unref(&sfc->gem);
310 *error = HAL_TBM_ERROR_OUT_OF_MEMORY;
313 bo_data->bufmgr_data = bufmgr_data;
316 ret = vigs_drm_gem_get_name(&sfc->gem);
318 TBM_BACKEND_ERR("vigs_drm_gem_get_name failed: %s", strerror_r(errno, buf, STRERR_BUFSIZE));
319 vigs_drm_gem_unref(&sfc->gem);
322 *error = HAL_TBM_ERROR_INVALID_OPERATION;
326 if (drmHashInsert(bufmgr_data->hash_bos, bo_data->sfc->gem.name, (void *)bo_data) < 0)
327 TBM_BACKEND_ERR("Cannot insert bo_data to Hash(%d)\n", bo_data->sfc->gem.name);
329 TBM_BACKEND_DBG("size = %d, flags = 0x%X", size, flags);
332 *error = HAL_TBM_ERROR_NONE;
334 return (hal_tbm_bo *)bo_data;
338 tbm_vigs_bufmgr_alloc_bo_with_format(hal_tbm_bufmgr *bufmgr, int format, int bo_idx,
339 int width, int height, int cpp, hal_tbm_bo_memory_type flags, hal_tbm_error *error)
341 tbm_vigs_bufmgr *bufmgr_data = (tbm_vigs_bufmgr *)bufmgr;
342 tbm_vigs_bo *bo_data;
343 struct vigs_drm_device *drm_dev;
344 struct vigs_drm_surface *sfc;
346 char buf[STRERR_BUFSIZE];
348 if (bufmgr_data == NULL || bufmgr_data->drm_dev == NULL) {
349 TBM_BACKEND_ERR("bufmgr_data is null\n");
351 *error = HAL_TBM_ERROR_INVALID_PARAMETER;
356 TBM_BACKEND_ERR("Not supported bo idx");
358 *error = HAL_TBM_ERROR_INVALID_PARAMETER;
362 drm_dev = bufmgr_data->drm_dev;
365 case HAL_TBM_FORMAT_RGB888:
366 ret = vigs_drm_surface_create(drm_dev, width, height, width * 3, vigs_drm_surface_bgra8888, 0, &sfc);
368 case HAL_TBM_FORMAT_XRGB8888:
369 case HAL_TBM_FORMAT_XBGR8888:
370 ret = vigs_drm_surface_create(drm_dev, width, height, width * 4, vigs_drm_surface_bgra8888, 0, &sfc);
372 case HAL_TBM_FORMAT_ARGB8888:
373 case HAL_TBM_FORMAT_RGBA8888:
374 ret = vigs_drm_surface_create(drm_dev, width, height, width * 4, vigs_drm_surface_bgra8888, 0, &sfc);
376 case HAL_TBM_FORMAT_NV21:
377 ret = vigs_drm_surface_create(drm_dev, width, height * 3 >> 1, width, vigs_drm_surface_bgra8888, 0, &sfc);
379 case HAL_TBM_FORMAT_NV61:
380 ret = vigs_drm_surface_create(drm_dev, width, height * 2, width, vigs_drm_surface_bgra8888, 0, &sfc);
382 case HAL_TBM_FORMAT_YUV420:
383 ret = vigs_drm_surface_create(drm_dev, width >> 2, height * 3 >> 1, width, vigs_drm_surface_bgra8888, 0, &sfc);
386 TBM_BACKEND_ERR("Not supported format");
388 *error = HAL_TBM_ERROR_INVALID_PARAMETER;
393 TBM_BACKEND_ERR("vigs_drm_suface_create failed: %s", strerror_r(errno, buf, STRERR_BUFSIZE));
395 *error = HAL_TBM_ERROR_INVALID_PARAMETER;
399 bo_data = calloc(1, sizeof(struct _tbm_vigs_bo));
401 TBM_BACKEND_ERR("fail to allocate the bo_data private\n");
402 vigs_drm_gem_unref(&sfc->gem);
404 *error = HAL_TBM_ERROR_OUT_OF_MEMORY;
407 bo_data->bufmgr_data = bufmgr_data;
410 ret = vigs_drm_gem_get_name(&sfc->gem);
412 TBM_BACKEND_ERR("vigs_drm_gem_get_name failed: %s", strerror_r(errno, buf, STRERR_BUFSIZE));
413 vigs_drm_gem_unref(&sfc->gem);
416 *error = HAL_TBM_ERROR_INVALID_OPERATION;
420 if (drmHashInsert(bufmgr_data->hash_bos, bo_data->sfc->gem.name, (void *)bo_data) < 0)
421 TBM_BACKEND_ERR("Cannot insert bo_data to Hash(%d)\n", bo_data->sfc->gem.name);
423 TBM_BACKEND_DBG("width = %d, height = %d, format = %x, flags = 0x%X bo_idx = %d",
424 width, height, format, flags, bo_idx);
427 *error = HAL_TBM_ERROR_NONE;
429 return (hal_tbm_bo *)bo_data;
433 tbm_vigs_bufmgr_import_fd(hal_tbm_bufmgr *bufmgr, hal_tbm_fd key, hal_tbm_error *error)
435 tbm_vigs_bufmgr *bufmgr_data = (tbm_vigs_bufmgr *)bufmgr;
436 tbm_vigs_bo *bo_data;
437 struct vigs_drm_device *drm_dev;
438 struct vigs_drm_surface *sfc;
440 char buf[STRERR_BUFSIZE];
441 struct drm_prime_handle arg = {0, };
445 if (bufmgr_data == NULL || bufmgr_data->drm_dev == NULL) {
446 TBM_BACKEND_ERR("bufmgr_data is null\n");
448 *error = HAL_TBM_ERROR_INVALID_PARAMETER;
452 drm_dev = bufmgr_data->drm_dev;
455 if (drmIoctl(bufmgr_data->drm_dev->fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &arg)) {
456 TBM_BACKEND_ERR("Cannot get gem handle from fd:%d (%s)\n",
457 arg.fd, strerror_r(errno, buf, STRERR_BUFSIZE));
459 *error = HAL_TBM_ERROR_INVALID_OPERATION;
464 name = _get_name(bufmgr_data->drm_dev->fd, gem);
466 TBM_BACKEND_ERR("Cannot get name from gem:%d, fd:%d (%s)\n",
467 gem, key, strerror_r(errno, buf, STRERR_BUFSIZE));
469 *error = HAL_TBM_ERROR_INVALID_OPERATION;
473 ret = drmHashLookup(bufmgr_data->hash_bos, name, (void **)&bo_data);
475 if (gem == bo_data->sfc->gem.handle) {
477 *error = HAL_TBM_ERROR_NONE;
478 return (hal_tbm_bo *)bo_data;
482 ret = vigs_drm_prime_import_fd(drm_dev, key, &sfc);
484 TBM_BACKEND_ERR("vigs_drm_prime_import_fd failed for key %d: %s",
485 key, strerror_r(errno, buf, STRERR_BUFSIZE));
487 *error = HAL_TBM_ERROR_INVALID_OPERATION;
491 bo_data = calloc(1, sizeof(struct _tbm_vigs_bo));
493 TBM_BACKEND_ERR("fail to allocate the bo_data private\n");
494 vigs_drm_gem_unref(&sfc->gem);
496 *error = HAL_TBM_ERROR_OUT_OF_MEMORY;
499 bo_data->bufmgr_data = bufmgr_data;
502 ret = vigs_drm_gem_get_name(&sfc->gem);
504 TBM_BACKEND_ERR("vigs_drm_gem_get_name failed: %s", strerror_r(errno, buf, STRERR_BUFSIZE));
505 vigs_drm_gem_unref(&sfc->gem);
508 *error = HAL_TBM_ERROR_INVALID_OPERATION;
512 if (drmHashInsert(bufmgr_data->hash_bos, bo_data->sfc->gem.name, (void *)bo_data) < 0)
513 TBM_BACKEND_ERR("Cannot insert bo_data to Hash(%d)\n", bo_data->sfc->gem.name);
515 TBM_BACKEND_DBG("bo_data = %p, key = %u handle = %u", bo_data, key, sfc->gem.handle);
518 *error = HAL_TBM_ERROR_NONE;
520 return (hal_tbm_bo *)bo_data;
524 tbm_vigs_bufmgr_import_key(hal_tbm_bufmgr *bufmgr, hal_tbm_key key, hal_tbm_error *error)
526 tbm_vigs_bufmgr *bufmgr_data = (tbm_vigs_bufmgr *)bufmgr;
527 tbm_vigs_bo *bo_data;
528 struct vigs_drm_device *drm_dev;
530 struct vigs_drm_surface *sfc;
531 char buf[STRERR_BUFSIZE];
533 if (bufmgr_data == NULL || bufmgr_data->drm_dev == NULL) {
534 TBM_BACKEND_ERR("bufmgr_data is null\n");
536 *error = HAL_TBM_ERROR_INVALID_PARAMETER;
540 drm_dev = bufmgr_data->drm_dev;
542 ret = drmHashLookup(bufmgr_data->hash_bos, key, (void **)&bo_data);
545 *error = HAL_TBM_ERROR_NONE;
546 return (hal_tbm_bo *)bo_data;
549 ret = vigs_drm_surface_open(drm_dev, key, &sfc);
551 TBM_BACKEND_ERR("vigs_drm_surface_open failed for key %u: %s",
552 key, strerror_r(errno, buf, STRERR_BUFSIZE));
554 *error = HAL_TBM_ERROR_INVALID_OPERATION;
558 bo_data = calloc(1, sizeof(struct _tbm_vigs_bo));
560 TBM_BACKEND_ERR("fail to allocate the bo_data private\n");
561 vigs_drm_gem_unref(&sfc->gem);
563 *error = HAL_TBM_ERROR_OUT_OF_MEMORY;
566 bo_data->bufmgr_data = bufmgr_data;
569 ret = vigs_drm_gem_get_name(&sfc->gem);
571 TBM_BACKEND_ERR("vigs_drm_gem_get_name failed: %s", strerror_r(errno, buf, STRERR_BUFSIZE));
572 vigs_drm_gem_unref(&sfc->gem);
575 *error = HAL_TBM_ERROR_INVALID_OPERATION;
579 if (drmHashInsert(bufmgr_data->hash_bos, bo_data->sfc->gem.name, (void *)bo_data) < 0)
580 TBM_BACKEND_ERR("Cannot insert bo_data to Hash(%d)\n", bo_data->sfc->gem.name);
582 TBM_BACKEND_DBG("bo_data = %p, key = %u handle = %u", bo_data, key, sfc->gem.handle);
585 *error = HAL_TBM_ERROR_NONE;
587 return (hal_tbm_bo *)bo_data;
591 tbm_vigs_bo_free(hal_tbm_bo *bo)
593 tbm_vigs_bo *bo_data = (tbm_vigs_bo *)bo;
595 struct vigs_drm_surface *sfc;
596 tbm_vigs_bufmgr *bufmgr_data;
602 bufmgr_data = bo_data->bufmgr_data;
606 TBM_BACKEND_DBG("bo_data = %p", bo_data);
610 /* delete bo from hash */
611 ret = drmHashLookup(bufmgr_data->hash_bos, bo_data->sfc->gem.name,
614 drmHashDelete(bufmgr_data->hash_bos, bo_data->sfc->gem.name);
616 TBM_BACKEND_ERR("Cannot find bo_data to Hash(%d), ret=%d\n", bo_data->sfc->gem.name, ret);
618 vigs_drm_gem_unref(&sfc->gem);
624 tbm_vigs_bo_get_size(hal_tbm_bo *bo, hal_tbm_error *error)
626 tbm_vigs_bo *bo_data = (tbm_vigs_bo *)bo;
627 struct vigs_drm_surface *sfc;
629 if (!bo_data || !bo_data->sfc) {
631 *error = HAL_TBM_ERROR_INVALID_PARAMETER;
635 TBM_BACKEND_DBG("bo_data = %p", bo_data);
640 *error = HAL_TBM_ERROR_NONE;
642 return sfc->gem.size;
645 static hal_tbm_bo_memory_type
646 tbm_vigs_bo_get_memory_type(hal_tbm_bo *bo, hal_tbm_error *error)
648 tbm_vigs_bo *bo_data = (tbm_vigs_bo *)bo;
650 if (!bo_data || !bo_data->sfc) {
652 *error = HAL_TBM_ERROR_INVALID_PARAMETER;
653 return HAL_TBM_BO_DEFAULT;
657 *error = HAL_TBM_ERROR_NONE;
659 return HAL_TBM_BO_DEFAULT;
662 static hal_tbm_bo_handle
663 tbm_vigs_bo_get_handle(hal_tbm_bo *bo, hal_tbm_bo_device_type device, hal_tbm_error *error)
665 tbm_vigs_bo *bo_data = (tbm_vigs_bo *)bo;
666 struct vigs_drm_surface *sfc;
667 hal_tbm_bo_handle handle;
669 if (!bo_data || !bo_data->sfc) {
671 *error = HAL_TBM_ERROR_INVALID_PARAMETER;
672 return (hal_tbm_bo_handle) NULL;
677 TBM_BACKEND_DBG("bo_data = %p, device = %d", bo_data, device);
679 handle = get_tbm_bo_handle(sfc, device);
682 *error = HAL_TBM_ERROR_INVALID_PARAMETER;
687 *error = HAL_TBM_ERROR_NONE;
692 static hal_tbm_bo_handle
693 tbm_vigs_bo_map(hal_tbm_bo *bo, hal_tbm_bo_device_type device,
694 hal_tbm_bo_access_option opt, hal_tbm_error *error)
696 tbm_vigs_bo *bo_data = (tbm_vigs_bo *)bo;
697 struct vigs_drm_surface *sfc;
698 hal_tbm_bo_handle handle;
701 if (!bo_data || !bo_data->sfc) {
703 *error = HAL_TBM_ERROR_INVALID_PARAMETER;
704 return (hal_tbm_bo_handle) NULL;
709 TBM_BACKEND_DBG("bo_data = %p, device = %d, opt = %d", bo_data, device, opt);
711 handle = get_tbm_bo_handle(sfc, device);
714 *error = HAL_TBM_ERROR_INVALID_PARAMETER;
718 if ((opt & HAL_TBM_OPTION_READ) != 0)
719 saf |= VIGS_DRM_SAF_READ;
721 if ((opt & HAL_TBM_OPTION_WRITE) != 0)
722 saf |= VIGS_DRM_SAF_WRITE;
724 vigs_drm_surface_start_access(sfc, saf);
727 *error = HAL_TBM_ERROR_NONE;
733 tbm_vigs_bo_unmap(hal_tbm_bo *bo)
735 tbm_vigs_bo *bo_data = (tbm_vigs_bo *)bo;
736 struct vigs_drm_surface *sfc;
738 if (!bo_data || !bo_data->sfc)
739 return HAL_TBM_ERROR_INVALID_PARAMETER;
743 TBM_BACKEND_DBG("bo_data = %p", bo_data);
745 vigs_drm_surface_end_access(sfc, 1);
747 return HAL_TBM_ERROR_NONE;
751 tbm_vigs_bo_lock(hal_tbm_bo *bo, hal_tbm_bo_device_type device,
752 hal_tbm_bo_access_option opt)
754 tbm_vigs_bo *bo_data = (tbm_vigs_bo *)bo;
756 if (!bo_data || !bo_data->sfc)
757 return HAL_TBM_ERROR_INVALID_PARAMETER;
759 TBM_BACKEND_DBG("bo_data = %p", bo_data);
761 return HAL_TBM_ERROR_NONE;
765 tbm_vigs_bo_unlock(hal_tbm_bo *bo)
767 tbm_vigs_bo *bo_data = (tbm_vigs_bo *)bo;
769 if (!bo_data || !bo_data->sfc)
770 return HAL_TBM_ERROR_INVALID_PARAMETER;
772 TBM_BACKEND_DBG("bo_data = %p", bo_data);
774 return HAL_TBM_ERROR_NONE;
778 tbm_vigs_bo_export_fd(hal_tbm_bo *bo, hal_tbm_error *error)
780 tbm_vigs_bo *bo_data = (tbm_vigs_bo *)bo;
781 tbm_vigs_bufmgr *bufmgr_data;
782 struct vigs_drm_surface *sfc;
783 struct vigs_drm_device *drm_dev;
785 char buf[STRERR_BUFSIZE];
787 if (!bo_data || !bo_data->sfc) {
789 *error = HAL_TBM_ERROR_INVALID_PARAMETER;
793 bufmgr_data = bo_data->bufmgr_data;
794 if (!bufmgr_data || !bufmgr_data->drm_dev) {
796 *error = HAL_TBM_ERROR_INVALID_PARAMETER;
800 drm_dev = bufmgr_data->drm_dev;
803 ret = vigs_drm_prime_export_fd(drm_dev, sfc, &fd);
805 TBM_BACKEND_ERR("vigs_drm_prime_export_fd failed: %s", strerror_r(errno, buf, STRERR_BUFSIZE));
807 *error = HAL_TBM_ERROR_INVALID_OPERATION;
811 TBM_BACKEND_DBG(" bo_data:%p, gem:%d(%d)\n", bo_data, sfc->gem);
814 *error = HAL_TBM_ERROR_NONE;
816 return (hal_tbm_fd)fd;
820 tbm_vigs_bo_export_key(hal_tbm_bo *bo, hal_tbm_error *error)
822 tbm_vigs_bo *bo_data = (tbm_vigs_bo *)bo;
823 struct vigs_drm_surface *sfc;
825 char buf[STRERR_BUFSIZE];
827 if (!bo_data || !bo_data->sfc) {
829 *error = HAL_TBM_ERROR_INVALID_PARAMETER;
835 ret = vigs_drm_gem_get_name(&sfc->gem);
837 TBM_BACKEND_ERR("vigs_drm_gem_get_name failed: %s", strerror_r(errno, buf, STRERR_BUFSIZE));
839 *error = HAL_TBM_ERROR_INVALID_OPERATION;
843 TBM_BACKEND_DBG(" bo_data:%p, gem:%d(%d)\n", bo_data, sfc->gem);
846 *error = HAL_TBM_ERROR_NONE;
848 return (hal_tbm_key)sfc->gem.name;
851 _tbm_vigs_bufmgr_deinitialize(tbm_vigs_bufmgr *bufmgr_data)
853 if (bufmgr_data->drm_dev)
854 vigs_drm_device_destroy(bufmgr_data->drm_dev);
860 _tbm_vigs_bufmgr_initailize(tbm_vigs_bufmgr *bufmgr_data)
862 struct vigs_drm_device *drm_dev = NULL;
863 char buf[STRERR_BUFSIZE];
866 ret = vigs_drm_device_create(bufmgr_data->fd, &drm_dev);
868 TBM_BACKEND_ERR("vigs_drm_device_create failed: %s", strerror_r(errno, buf, STRERR_BUFSIZE));
869 vigs_drm_device_destroy(drm_dev);
871 return HAL_TBM_ERROR_INVALID_OPERATION;
874 bufmgr_data->drm_dev = drm_dev;
877 return HAL_TBM_ERROR_NONE;
881 _tbm_vigs_authenticated_drm_fd_handler(hal_tbm_fd auth_fd, void *user_data)
883 tbm_vigs_bufmgr *bufmgr_data = (tbm_vigs_bufmgr *) user_data;
886 TBM_BACKEND_RETURN_VAL_IF_FAIL(bufmgr_data != NULL, HAL_TBM_ERROR_INVALID_PARAMETER);
888 bufmgr_data->fd = auth_fd;
889 TBM_BACKEND_INFO("Get the authenticated drm_fd(%d)!\n", bufmgr_data->fd);
891 ret = _tbm_vigs_bufmgr_initailize(bufmgr_data);
892 if (ret != HAL_TBM_ERROR_NONE) {
893 TBM_BACKEND_ERR("_tbm_vigs_bufmgr_initailize failed.");
897 return HAL_TBM_ERROR_NONE;
901 hal_backend_tbm_vigs_exit(void *data)
903 hal_tbm_backend_data *backend_data = (hal_tbm_backend_data *)data;
904 tbm_vigs_bufmgr *bufmgr_data;
908 TBM_BACKEND_DBG("enter");
910 TBM_BACKEND_RETURN_VAL_IF_FAIL(backend_data != NULL, -1);
912 bufmgr_data = (tbm_vigs_bufmgr *)backend_data->bufmgr;
913 TBM_BACKEND_RETURN_VAL_IF_FAIL(bufmgr_data != NULL, -1);
915 if (bufmgr_data->hash_bos) {
916 while (drmHashFirst(bufmgr_data->hash_bos, &key, &value) > 0) {
918 drmHashDelete(bufmgr_data->hash_bos, key);
921 drmHashDestroy(bufmgr_data->hash_bos);
922 bufmgr_data->hash_bos = NULL;
925 if (backend_data->bufmgr_funcs)
926 free(backend_data->bufmgr_funcs);
927 if (backend_data->bo_funcs)
928 free(backend_data->bo_funcs);
930 _tbm_vigs_bufmgr_deinitialize(bufmgr_data);
932 if (bufmgr_data->fd >= 0)
933 close(bufmgr_data->fd);
935 free(backend_data->bufmgr);
938 return HAL_TBM_ERROR_NONE;
942 hal_backend_tbm_vigs_init(void **data)
944 hal_tbm_backend_data *backend_data = NULL;
945 hal_tbm_bufmgr_funcs *bufmgr_funcs = NULL;
946 hal_tbm_bo_funcs *bo_funcs = NULL;
947 tbm_vigs_bufmgr *bufmgr_data = NULL;
951 TBM_BACKEND_DBG("enter");
953 /* allocate a hal_tbm_backend_data */
954 backend_data = calloc(1, sizeof(struct _hal_tbm_backend_data));
956 TBM_BACKEND_ERR("fail to alloc backend_data!\n");
960 *data = backend_data;
962 /* allocate a hal_tbm_bufmgr */
963 bufmgr_data = calloc(1, sizeof(struct _tbm_vigs_bufmgr));
965 TBM_BACKEND_ERR("fail to alloc bufmgr_data!\n");
966 goto fail_alloc_bufmgr_data;
968 backend_data->bufmgr = (hal_tbm_bufmgr *)bufmgr_data;
970 bufmgr_data->fd = -1;
973 drm_fd = _tbm_vigs_open_drm();
975 TBM_BACKEND_ERR("fail to open drm!\n");
979 // set true when backend has a drm_device.
980 backend_data->has_drm_device = 1;
982 // check if drm_fd is master_drm_fd.
983 if (drmIsMaster(drm_fd)) {
984 // drm_fd is a master_drm_fd.
985 backend_data->drm_info.drm_fd = drm_fd;
986 backend_data->drm_info.is_master = 1;
988 bufmgr_data->fd = drm_fd;
989 TBM_BACKEND_INFO("Get the master drm_fd(%d)!\n", bufmgr_data->fd);
991 ret = _tbm_vigs_bufmgr_initailize(bufmgr_data);
992 if (ret != HAL_TBM_ERROR_NONE) {
993 TBM_BACKEND_ERR("_tbm_vigs_bufmgr_initailize failed.");
994 goto fail_create_vigs_drm_device;
997 // drm_fd is not a master_drm_fd.
998 // request authenticated fd
1000 backend_data->drm_info.drm_fd = -1;
1001 backend_data->drm_info.is_master = 0;
1002 backend_data->drm_info.auth_drm_fd_func = _tbm_vigs_authenticated_drm_fd_handler;
1003 backend_data->drm_info.user_data = bufmgr_data;
1005 TBM_BACKEND_INFO("A backend requests an authenticated drm_fd.\n");
1008 bufmgr_data->hash_bos = drmHashCreate();
1010 /* alloc and register bufmgr_funcs */
1011 bufmgr_funcs = calloc(1, sizeof(struct _hal_tbm_bufmgr_funcs));
1012 if (!bufmgr_funcs) {
1013 TBM_BACKEND_ERR("fail to alloc bufmgr_funcs!\n");
1014 goto fail_alloc_bufmgr_funcs;
1016 backend_data->bufmgr_funcs = bufmgr_funcs;
1018 bufmgr_funcs->bufmgr_get_capabilities = tbm_vigs_bufmgr_get_capabilities;
1019 bufmgr_funcs->bufmgr_get_supported_formats = tbm_vigs_bufmgr_get_supported_formats;
1020 bufmgr_funcs->bufmgr_get_plane_data = tbm_vigs_bufmgr_get_plane_data;
1021 bufmgr_funcs->bufmgr_alloc_bo = tbm_vigs_bufmgr_alloc_bo;
1022 bufmgr_funcs->bufmgr_alloc_bo_with_format = tbm_vigs_bufmgr_alloc_bo_with_format;
1023 bufmgr_funcs->bufmgr_import_fd = tbm_vigs_bufmgr_import_fd;
1024 bufmgr_funcs->bufmgr_import_key = tbm_vigs_bufmgr_import_key;
1026 /* alloc and register bo_funcs */
1027 bo_funcs = calloc(1, sizeof(struct _hal_tbm_bo_funcs));
1029 TBM_BACKEND_ERR("fail to alloc bo_funcs!\n");
1030 goto fail_alloc_bo_funcs;
1032 backend_data->bo_funcs = bo_funcs;
1034 bo_funcs->bo_free = tbm_vigs_bo_free;
1035 bo_funcs->bo_get_size = tbm_vigs_bo_get_size;
1036 bo_funcs->bo_get_memory_types = tbm_vigs_bo_get_memory_type;
1037 bo_funcs->bo_get_handle = tbm_vigs_bo_get_handle;
1038 bo_funcs->bo_map = tbm_vigs_bo_map;
1039 bo_funcs->bo_unmap = tbm_vigs_bo_unmap;
1040 bo_funcs->bo_lock = tbm_vigs_bo_lock;
1041 bo_funcs->bo_unlock = tbm_vigs_bo_unlock;
1042 bo_funcs->bo_export_fd = tbm_vigs_bo_export_fd;
1043 bo_funcs->bo_export_key = tbm_vigs_bo_export_key;
1045 TBM_BACKEND_DBG("drm_fd:%d\n", bufmgr_data->fd);
1047 return HAL_TBM_ERROR_NONE;
1049 fail_alloc_bo_funcs:
1051 fail_alloc_bufmgr_funcs:
1052 drmHashDestroy(bufmgr_data->hash_bos);
1053 _tbm_vigs_bufmgr_deinitialize(bufmgr_data);
1054 fail_create_vigs_drm_device:
1055 if (bufmgr_data->fd >= 0)
1056 close(bufmgr_data->fd);
1059 fail_alloc_bufmgr_data:
1068 hal_backend hal_backend_tbm_data = {
1071 HAL_ABI_VERSION_TIZEN_6_5,
1072 hal_backend_tbm_vigs_init,
1073 hal_backend_tbm_vigs_exit
1076 struct vigs_drm_device *
1077 libhal_backend_tbm_vigs_get_drm_dev(void)