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 <tbm_backend.h>
47 #include <tbm_drm_helper.h>
50 #define STRERR_BUFSIZE 128
52 #define VIGS_DRM_NAME "vigs"
54 /* global singleton drm_dev. this is shared with yagl. */
55 struct vigs_drm_device *g_drm_dev = NULL;
57 static uint32_t tbm_bufmgr_vigs_color_format_list[] = {
68 typedef struct _tbm_bufmgr_vigs *tbm_bufmgr_vigs;
69 typedef struct _tbm_bo_vigs *tbm_bo_vigs;
71 /* tbm buffor object for vigs */
73 struct vigs_drm_surface *sfc;
75 tbm_bufmgr_vigs bufmgr_vigs;
78 /* tbm bufmgr private for vigs */
79 struct _tbm_bufmgr_vigs {
80 struct vigs_drm_device *drm_dev;
83 tbm_backend_bufmgr_func *bufmgr_func;
84 tbm_backend_bo_func *bo_func;
89 static int _tbm_vigs_open_drm(void)
93 fd = drmOpen(VIGS_DRM_NAME, NULL);
95 TBM_ERR("open vigs drm device failed");
103 _get_name(int fd, unsigned int gem)
105 struct drm_gem_flink arg = {0,};
108 if (drmIoctl(fd, DRM_IOCTL_GEM_FLINK, &arg)) {
109 TBM_ERR("fail to DRM_IOCTL_GEM_FLINK gem:%d", gem);
113 return (unsigned int)arg.name;
116 static tbm_bo_handle get_tbm_bo_handle(struct vigs_drm_surface *sfc, int device)
118 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 TBM_DEVICE_DEFAULT:
128 bo_handle.u32 = gem->handle;
131 ret = vigs_drm_gem_map(gem, 1);
134 bo_handle.ptr = gem->vaddr;
136 TBM_ERR("vigs_drm_gem_map failed: %s", strerror_r(errno, buf, STRERR_BUFSIZE));
140 bo_handle.ptr = (void *)sfc;
143 TBM_ERR("TBM_DEVICE_MM not supported");
146 TBM_ERR("%d not supported", device);
153 static tbm_bufmgr_capability
154 tbm_vigs_bufmgr_get_capabilities(tbm_backend_bufmgr_data *bufmgr_data, tbm_error_e *error)
156 tbm_bufmgr_capability capabilities = TBM_BUFMGR_CAPABILITY_NONE;
158 capabilities = TBM_BUFMGR_CAPABILITY_SHARE_KEY|TBM_BUFMGR_CAPABILITY_SHARE_FD;
161 *error = TBM_ERROR_NONE;
167 tbm_vigs_bufmgr_bind_native_display(tbm_backend_bufmgr_data *bufmgr_data, tbm_native_display *native_display)
169 tbm_bufmgr_vigs bufmgr_vigs = (tbm_bufmgr_vigs)bufmgr_data;
170 struct vigs_drm_device *drm_dev;
174 if (bufmgr_vigs == NULL || bufmgr_vigs->drm_dev == NULL) {
175 TBM_ERR("bufmgr_data is null\n");
176 return TBM_ERROR_INVALID_PARAMETER;
179 drm_dev = bufmgr_vigs->drm_dev;
181 device_name = drmGetDeviceNameFromFd(drm_dev->fd);
183 TBM_ERR("drmGetDeviceNameFromFd failed");
184 return TBM_ERROR_INVALID_OPERATION;
187 ret = tbm_drm_helper_wl_auth_server_init(native_display, drm_dev->fd, device_name, 0);
189 TBM_ERR("tbm_drm_helper_wl_auth_server_init failed");
191 return TBM_ERROR_INVALID_OPERATION;
196 return TBM_ERROR_NONE;
200 tbm_vigs_bufmgr_get_supported_formats(tbm_backend_bufmgr_data *bufmgr_data,
201 uint32_t **formats, uint32_t *num)
203 tbm_bufmgr_vigs bufmgr_vigs = (tbm_bufmgr_vigs)bufmgr_data;
204 uint32_t *color_formats;
207 return TBM_ERROR_INVALID_PARAMETER;
209 color_formats = (uint32_t *) calloc(1, sizeof(tbm_bufmgr_vigs_color_format_list));
211 return TBM_ERROR_OUT_OF_MEMORY;
213 memcpy(color_formats, tbm_bufmgr_vigs_color_format_list, sizeof(tbm_bufmgr_vigs_color_format_list));
215 *formats = color_formats;
216 *num = sizeof(tbm_bufmgr_vigs_color_format_list) / sizeof(tbm_bufmgr_vigs_color_format_list[0]);
218 return TBM_ERROR_NONE;
222 tbm_vigs_bufmgr_get_plane_data(tbm_backend_bufmgr_data *bufmgr_data,
223 tbm_format format, int plane_idx, int width,
224 int height, uint32_t * size, uint32_t * offset,
225 uint32_t * pitch, int *bo_idx)
227 tbm_bufmgr_vigs bufmgr_vigs = (tbm_bufmgr_vigs)bufmgr_data;
235 return TBM_ERROR_INVALID_PARAMETER;
238 case TBM_FORMAT_RGB888:
239 *size = width * height * 3;
243 return TBM_ERROR_NONE;
244 case TBM_FORMAT_XRGB8888:
245 case TBM_FORMAT_XBGR8888:
246 case TBM_FORMAT_ARGB8888:
247 case TBM_FORMAT_RGBA8888:
248 *size = width * height * 4;
252 return TBM_ERROR_NONE;
253 case TBM_FORMAT_NV21:
254 if (plane_idx == 0) {
255 *size = width * height;
259 } else if (plane_idx == 1) {
260 *size = width * (height >> 1);
261 *offset = width * height;
265 return TBM_ERROR_INVALID_PARAMETER;
267 return TBM_ERROR_NONE;
268 case TBM_FORMAT_NV61:
269 if (plane_idx == 0) {
270 *size = width * height;
274 } else if (plane_idx == 1) {
275 *size = width * height;
276 *offset = width * height;
280 return TBM_ERROR_INVALID_PARAMETER;
282 return TBM_ERROR_NONE;
283 case TBM_FORMAT_YUV420:
284 if (plane_idx == 0) {
285 *size = width * height;
289 } else if (plane_idx == 1) {
290 *size = (width * height) >> 2;
291 *offset = width * height;
294 } else if (plane_idx == 2) {
295 *size = (width * height) >> 2;
296 *offset = (width * height) + (width * height >> 2);
300 return TBM_ERROR_INVALID_PARAMETER;
302 return TBM_ERROR_NONE;
304 return TBM_ERROR_INVALID_PARAMETER;
308 static tbm_backend_bo_data *
309 tbm_vigs_bufmgr_alloc_bo(tbm_backend_bufmgr_data *bufmgr_data, unsigned int size,
310 tbm_bo_memory_type flags, tbm_error_e *error)
312 tbm_bufmgr_vigs bufmgr_vigs = (tbm_bufmgr_vigs)bufmgr_data;
314 struct vigs_drm_device *drm_dev;
315 struct vigs_drm_surface *sfc;
316 uint32_t width = 2048, height;
318 char buf[STRERR_BUFSIZE];
320 if (bufmgr_vigs == NULL || bufmgr_vigs->drm_dev == NULL) {
321 TBM_ERR("bufmgr_data is null\n");
323 *error = TBM_ERROR_INVALID_PARAMETER;
327 drm_dev = bufmgr_vigs->drm_dev;
329 height = ((uint32_t) size + (width * 4) - 1) / (width * 4);
331 ret = vigs_drm_surface_create(drm_dev, width, height, width * 4, vigs_drm_surface_bgra8888, 0, &sfc);
333 TBM_ERR("vigs_drm_suface_create failed: %s", strerror_r(errno, buf, STRERR_BUFSIZE));
335 *error = TBM_ERROR_INVALID_PARAMETER;
339 bo_vigs = calloc(1, sizeof(struct _tbm_bo_vigs));
341 TBM_ERR("fail to allocate the bo_vigs private\n");
342 vigs_drm_gem_unref(&sfc->gem);
344 *error = TBM_ERROR_OUT_OF_MEMORY;
347 bo_vigs->bufmgr_vigs = bufmgr_vigs;
350 ret = vigs_drm_gem_get_name(&sfc->gem);
352 TBM_ERR("vigs_drm_gem_get_name failed: %s", strerror_r(errno, buf, STRERR_BUFSIZE));
353 vigs_drm_gem_unref(&sfc->gem);
356 *error = TBM_ERROR_INVALID_OPERATION;
360 if (drmHashInsert(bufmgr_vigs->hash_bos, bo_vigs->sfc->gem.name, (void *)bo_vigs) < 0)
361 TBM_ERR("Cannot insert bo_vigs to Hash(%d)\n", bo_vigs->sfc->gem.name);
363 TBM_DBG("size = %d, flags = 0x%X", size, flags);
366 *error = TBM_ERROR_NONE;
368 return (tbm_backend_bo_data *)bo_vigs;
371 static tbm_backend_bo_data *
372 tbm_bufmgr_vigs_alloc_bo_with_format(tbm_backend_bufmgr_data *bufmgr_data, int format, int bo_idx,
373 int width, int height, tbm_bo_memory_type flags, tbm_error_e *error)
375 tbm_bufmgr_vigs bufmgr_vigs = (tbm_bufmgr_vigs)bufmgr_data;
377 struct vigs_drm_device *drm_dev;
378 struct vigs_drm_surface *sfc;
380 char buf[STRERR_BUFSIZE];
382 if (bufmgr_vigs == NULL || bufmgr_vigs->drm_dev == NULL) {
383 TBM_ERR("bufmgr_data is null\n");
385 *error = TBM_ERROR_INVALID_PARAMETER;
390 TBM_ERR("Not supported bo idx");
392 *error = TBM_ERROR_INVALID_PARAMETER;
396 drm_dev = bufmgr_vigs->drm_dev;
399 case TBM_FORMAT_RGB888:
400 ret = vigs_drm_surface_create(drm_dev, width, height, width * 3, vigs_drm_surface_bgra8888, 0, &sfc);
402 case TBM_FORMAT_XRGB8888:
403 case TBM_FORMAT_XBGR8888:
404 ret = vigs_drm_surface_create(drm_dev, width, height, width * 4, vigs_drm_surface_bgra8888, 0, &sfc);
406 case TBM_FORMAT_ARGB8888:
407 case TBM_FORMAT_RGBA8888:
408 ret = vigs_drm_surface_create(drm_dev, width, height, width * 4, vigs_drm_surface_bgra8888, 0, &sfc);
410 case TBM_FORMAT_NV21:
411 ret = vigs_drm_surface_create(drm_dev, width, height * 3 >> 1, width, vigs_drm_surface_bgra8888, 0, &sfc);
413 case TBM_FORMAT_NV61:
414 ret = vigs_drm_surface_create(drm_dev, width, height * 2, width, vigs_drm_surface_bgra8888, 0, &sfc);
416 case TBM_FORMAT_YUV420:
417 ret = vigs_drm_surface_create(drm_dev, width >> 2, height * 3 >> 1, width, vigs_drm_surface_bgra8888, 0, &sfc);
420 TBM_ERR("Not supported format");
422 *error = TBM_ERROR_INVALID_PARAMETER;
427 TBM_ERR("vigs_drm_suface_create failed: %s", strerror_r(errno, buf, STRERR_BUFSIZE));
429 *error = TBM_ERROR_INVALID_PARAMETER;
433 bo_vigs = calloc(1, sizeof(struct _tbm_bo_vigs));
435 TBM_ERR("fail to allocate the bo_vigs private\n");
436 vigs_drm_gem_unref(&sfc->gem);
438 *error = TBM_ERROR_OUT_OF_MEMORY;
441 bo_vigs->bufmgr_vigs = bufmgr_vigs;
444 ret = vigs_drm_gem_get_name(&sfc->gem);
446 TBM_ERR("vigs_drm_gem_get_name failed: %s", strerror_r(errno, buf, STRERR_BUFSIZE));
447 vigs_drm_gem_unref(&sfc->gem);
450 *error = TBM_ERROR_INVALID_OPERATION;
454 if (drmHashInsert(bufmgr_vigs->hash_bos, bo_vigs->sfc->gem.name, (void *)bo_vigs) < 0)
455 TBM_ERR("Cannot insert bo_vigs to Hash(%d)\n", bo_vigs->sfc->gem.name);
457 TBM_DBG("width = %d, height = %d, format = %x, flags = 0x%X bo_idx = %d",
458 width, height, format, flags, bo_idx);
461 *error = TBM_ERROR_NONE;
463 return (tbm_backend_bo_data *)bo_vigs;
466 static tbm_backend_bo_data *
467 tbm_vigs_bufmgr_import_fd(tbm_backend_bufmgr_data *bufmgr_data, tbm_fd key, tbm_error_e *error)
469 tbm_bufmgr_vigs bufmgr_vigs = (tbm_bufmgr_vigs)bufmgr_data;
471 struct vigs_drm_device *drm_dev;
472 struct vigs_drm_surface *sfc;
474 char buf[STRERR_BUFSIZE];
475 struct drm_prime_handle arg = {0, };
479 if (bufmgr_vigs == NULL || bufmgr_vigs->drm_dev == NULL) {
480 TBM_ERR("bufmgr_data is null\n");
482 *error = TBM_ERROR_INVALID_PARAMETER;
486 drm_dev = bufmgr_vigs->drm_dev;
489 if (drmIoctl(bufmgr_vigs->drm_dev->fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &arg)) {
490 TBM_ERR("Cannot get gem handle from fd:%d (%s)\n",
491 arg.fd, strerror_r(errno, buf, STRERR_BUFSIZE));
493 *error = TBM_ERROR_INVALID_OPERATION;
498 name = _get_name(bufmgr_vigs->drm_dev->fd, gem);
500 TBM_ERR("Cannot get name from gem:%d, fd:%d (%s)\n",
501 gem, key, strerror_r(errno, buf, STRERR_BUFSIZE));
503 *error = TBM_ERROR_INVALID_OPERATION;
507 ret = drmHashLookup(bufmgr_vigs->hash_bos, name, (void **)&bo_vigs);
509 if (gem == bo_vigs->sfc->gem.handle) {
511 *error = TBM_ERROR_NONE;
512 return (tbm_backend_bo_data *)bo_vigs;
516 ret = vigs_drm_prime_import_fd(drm_dev, key, &sfc);
518 TBM_ERR("vigs_drm_prime_import_fd failed for key %d: %s",
519 key, strerror_r(errno, buf, STRERR_BUFSIZE));
521 *error = TBM_ERROR_INVALID_OPERATION;
525 bo_vigs = calloc(1, sizeof(struct _tbm_bo_vigs));
527 TBM_ERR("fail to allocate the bo_vigs private\n");
528 vigs_drm_gem_unref(&sfc->gem);
530 *error = TBM_ERROR_OUT_OF_MEMORY;
533 bo_vigs->bufmgr_vigs = bufmgr_vigs;
536 ret = vigs_drm_gem_get_name(&sfc->gem);
538 TBM_ERR("vigs_drm_gem_get_name failed: %s", strerror_r(errno, buf, STRERR_BUFSIZE));
539 vigs_drm_gem_unref(&sfc->gem);
542 *error = TBM_ERROR_INVALID_OPERATION;
546 if (drmHashInsert(bufmgr_vigs->hash_bos, bo_vigs->sfc->gem.name, (void *)bo_vigs) < 0)
547 TBM_ERR("Cannot insert bo_vigs to Hash(%d)\n", bo_vigs->sfc->gem.name);
549 TBM_DBG("bo_vigs = %p, key = %u handle = %u", bo_vigs, key, sfc->gem.handle);
552 *error = TBM_ERROR_NONE;
554 return (tbm_backend_bo_data *)bo_vigs;
557 static tbm_backend_bo_data *
558 tbm_vigs_bufmgr_import_key(tbm_backend_bufmgr_data *bufmgr_data, tbm_key key, tbm_error_e *error)
560 tbm_bufmgr_vigs bufmgr_vigs = (tbm_bufmgr_vigs)bufmgr_data;
562 struct vigs_drm_device *drm_dev;
564 struct vigs_drm_surface *sfc;
565 char buf[STRERR_BUFSIZE];
567 if (bufmgr_vigs == NULL || bufmgr_vigs->drm_dev == NULL) {
568 TBM_ERR("bufmgr_data is null\n");
570 *error = TBM_ERROR_INVALID_PARAMETER;
574 drm_dev = bufmgr_vigs->drm_dev;
576 ret = drmHashLookup(bufmgr_vigs->hash_bos, key, (void **)&bo_vigs);
579 *error = TBM_ERROR_NONE;
580 return (tbm_backend_bo_data *)bo_vigs;
583 ret = vigs_drm_surface_open(drm_dev, key, &sfc);
585 TBM_ERR("vigs_drm_surface_open failed for key %u: %s",
586 key, strerror_r(errno, buf, STRERR_BUFSIZE));
588 *error = TBM_ERROR_INVALID_OPERATION;
592 bo_vigs = calloc(1, sizeof(struct _tbm_bo_vigs));
594 TBM_ERR("fail to allocate the bo_vigs private\n");
595 vigs_drm_gem_unref(&sfc->gem);
597 *error = TBM_ERROR_OUT_OF_MEMORY;
600 bo_vigs->bufmgr_vigs = bufmgr_vigs;
603 ret = vigs_drm_gem_get_name(&sfc->gem);
605 TBM_ERR("vigs_drm_gem_get_name failed: %s", strerror_r(errno, buf, STRERR_BUFSIZE));
606 vigs_drm_gem_unref(&sfc->gem);
609 *error = TBM_ERROR_INVALID_OPERATION;
613 if (drmHashInsert(bufmgr_vigs->hash_bos, bo_vigs->sfc->gem.name, (void *)bo_vigs) < 0)
614 TBM_ERR("Cannot insert bo_vigs to Hash(%d)\n", bo_vigs->sfc->gem.name);
616 TBM_DBG("bo_vigs = %p, key = %u handle = %u", bo_vigs, key, sfc->gem.handle);
619 *error = TBM_ERROR_NONE;
621 return (tbm_backend_bo_data *)bo_vigs;
625 tbm_vigs_bo_free(tbm_backend_bo_data *bo_data)
627 tbm_bo_vigs bo_vigs = (tbm_bo_vigs)bo_data;
629 struct vigs_drm_surface *sfc;
630 tbm_bufmgr_vigs bufmgr_vigs;
636 bufmgr_vigs = bo_vigs->bufmgr_vigs;
640 TBM_DBG("bo_vigs = %p", bo_vigs);
644 /* delete bo from hash */
645 ret = drmHashLookup(bufmgr_vigs->hash_bos, sfc->gem.name,
648 drmHashDelete(bufmgr_vigs->hash_bos, sfc->gem.name);
650 TBM_ERR("Cannot find bo_vigs to Hash(%d), ret=%d\n", sfc->gem.name, ret);
652 vigs_drm_gem_unref(&sfc->gem);
658 tbm_vigs_bo_get_size(tbm_backend_bo_data *bo_data, tbm_error_e *error)
660 tbm_bo_vigs bo_vigs = (tbm_bo_vigs)bo_data;
661 struct vigs_drm_surface *sfc;
663 if (!bo_vigs || !bo_vigs->sfc) {
665 *error = TBM_ERROR_INVALID_PARAMETER;
669 TBM_DBG("bo_vigs = %p", bo_vigs);
674 *error = TBM_ERROR_NONE;
676 return sfc->gem.size;
679 static tbm_bo_memory_type
680 tbm_vigs_bo_get_memory_type(tbm_backend_bo_data *bo_data, tbm_error_e *error)
682 tbm_bo_vigs bo_vigs = (tbm_bo_vigs)bo_data;
684 if (!bo_vigs || !bo_vigs->sfc) {
686 *error = TBM_ERROR_INVALID_PARAMETER;
687 return TBM_BO_DEFAULT;
691 *error = TBM_ERROR_NONE;
693 return TBM_BO_DEFAULT;
697 tbm_vigs_bo_get_handle(tbm_backend_bo_data *bo_data, tbm_bo_device_type device, tbm_error_e *error)
699 tbm_bo_vigs bo_vigs = (tbm_bo_vigs)bo_data;
700 struct vigs_drm_surface *sfc;
701 tbm_bo_handle handle;
703 if (!bo_vigs || !bo_vigs->sfc) {
705 *error = TBM_ERROR_INVALID_PARAMETER;
706 return (tbm_bo_handle) NULL;
711 TBM_DBG("bo_vigs = %p, device = %d", bo_vigs, device);
713 handle = get_tbm_bo_handle(sfc, device);
716 *error = TBM_ERROR_INVALID_PARAMETER;
721 *error = TBM_ERROR_NONE;
727 tbm_vigs_bo_map(tbm_backend_bo_data *bo_data, tbm_bo_device_type device,
728 tbm_bo_access_option opt, tbm_error_e *error)
730 tbm_bo_vigs bo_vigs = (tbm_bo_vigs)bo_data;
731 struct vigs_drm_surface *sfc;
732 tbm_bo_handle handle;
735 if (!bo_vigs || !bo_vigs->sfc) {
737 *error = TBM_ERROR_INVALID_PARAMETER;
738 return (tbm_bo_handle) NULL;
743 TBM_DBG("bo_vigs = %p, device = %d, opt = %d", bo_vigs, device, opt);
745 handle = get_tbm_bo_handle(sfc, device);
748 *error = TBM_ERROR_INVALID_PARAMETER;
752 if ((opt & TBM_OPTION_READ) != 0)
753 saf |= VIGS_DRM_SAF_READ;
755 if ((opt & TBM_OPTION_WRITE) != 0)
756 saf |= VIGS_DRM_SAF_WRITE;
758 vigs_drm_surface_start_access(sfc, saf);
761 *error = TBM_ERROR_NONE;
767 tbm_vigs_bo_unmap(tbm_backend_bo_data *bo_data)
769 tbm_bo_vigs bo_vigs = (tbm_bo_vigs)bo_data;
770 struct vigs_drm_surface *sfc;
772 if (!bo_vigs || !bo_vigs->sfc)
773 return TBM_ERROR_INVALID_PARAMETER;
777 TBM_DBG("bo_vigs = %p", bo_vigs);
779 vigs_drm_surface_end_access(sfc, 1);
781 return TBM_ERROR_NONE;
785 tbm_vigs_bo_lock(tbm_backend_bo_data *bo_data, tbm_bo_device_type device,
786 tbm_bo_access_option opt)
788 tbm_bo_vigs bo_vigs = (tbm_bo_vigs)bo_data;
790 if (!bo_vigs || !bo_vigs->sfc)
791 return TBM_ERROR_INVALID_PARAMETER;
793 TBM_DBG("bo_vigs = %p", bo_vigs);
795 return TBM_ERROR_NONE;
799 tbm_vigs_bo_unlock(tbm_backend_bo_data *bo_data)
801 tbm_bo_vigs bo_vigs = (tbm_bo_vigs)bo_data;
803 if (!bo_vigs || !bo_vigs->sfc)
804 return TBM_ERROR_INVALID_PARAMETER;
806 TBM_DBG("bo_vigs = %p", bo_data);
808 return TBM_ERROR_NONE;
812 tbm_vigs_bo_export_fd(tbm_backend_bo_data *bo_data, tbm_error_e *error)
814 tbm_bo_vigs bo_vigs = (tbm_bo_vigs)bo_data;
815 tbm_bufmgr_vigs bufmgr_vigs;
816 struct vigs_drm_surface *sfc;
817 struct vigs_drm_device *drm_dev;
819 char buf[STRERR_BUFSIZE];
821 if (!bo_vigs || !bo_vigs->sfc) {
823 *error = TBM_ERROR_INVALID_PARAMETER;
827 bufmgr_vigs = bo_vigs->bufmgr_vigs;
828 if (!bufmgr_vigs || !bufmgr_vigs->drm_dev) {
830 *error = TBM_ERROR_INVALID_PARAMETER;
834 drm_dev = bufmgr_vigs->drm_dev;
837 ret = vigs_drm_prime_export_fd(drm_dev, sfc, &fd);
839 TBM_ERR("vigs_drm_prime_export_fd failed: %s", strerror_r(errno, buf, STRERR_BUFSIZE));
841 *error = TBM_ERROR_INVALID_OPERATION;
845 TBM_DBG(" bo_vigs:%p, gem:%d(%d)\n", bo_vigs, sfc->gem);
848 *error = TBM_ERROR_NONE;
854 tbm_vigs_bo_export_key(tbm_backend_bo_data *bo_data, tbm_error_e *error)
856 tbm_bo_vigs bo_vigs = (tbm_bo_vigs)bo_data;
857 struct vigs_drm_surface *sfc;
859 char buf[STRERR_BUFSIZE];
861 if (!bo_vigs || !bo_vigs->sfc) {
863 *error = TBM_ERROR_INVALID_PARAMETER;
869 ret = vigs_drm_gem_get_name(&sfc->gem);
871 TBM_ERR("vigs_drm_gem_get_name failed: %s", strerror_r(errno, buf, STRERR_BUFSIZE));
873 *error = TBM_ERROR_INVALID_OPERATION;
877 TBM_DBG(" bo_vigs:%p, gem:%d(%d)\n", bo_vigs, sfc->gem);
880 *error = TBM_ERROR_NONE;
882 return (tbm_key)sfc->gem.name;
886 tbm_vigs_deinit(tbm_backend_bufmgr_data *bufmgr_data)
888 tbm_bufmgr_vigs bufmgr_vigs = (tbm_bufmgr_vigs)bufmgr_data;
889 struct vigs_drm_device *drm_dev;
900 drm_dev = bufmgr_vigs->drm_dev;
904 bufmgr = bufmgr_vigs->bufmgr;
908 if (bufmgr_vigs->hash_bos) {
909 while (drmHashFirst(bufmgr_vigs->hash_bos, &key, &value) > 0) {
911 drmHashDelete(bufmgr_vigs->hash_bos, key);
914 drmHashDestroy(bufmgr_vigs->hash_bos);
915 bufmgr_vigs->hash_bos = NULL;
918 if (tbm_backend_bufmgr_query_display_server(bufmgr, &error)) {
919 tbm_drm_helper_wl_auth_server_deinit();
920 tbm_drm_helper_unset_tbm_master_fd();
925 vigs_drm_device_destroy(drm_dev);
930 static tbm_backend_bufmgr_data *
931 tbm_vigs_init(tbm_bufmgr bufmgr, tbm_error_e *error)
933 tbm_bufmgr_vigs bufmgr_vigs = NULL;
934 tbm_backend_bufmgr_func *bufmgr_func = NULL;
935 tbm_backend_bo_func *bo_func = NULL;
937 struct vigs_drm_device *drm_dev = NULL;
940 char buf[STRERR_BUFSIZE];
946 TBM_ERR("bufmgr is null.\n");
948 *error = TBM_ERROR_INVALID_PARAMETER;
952 bufmgr_vigs = calloc(1, sizeof(struct _tbm_bufmgr_vigs));
954 TBM_ERR("fail to alloc bufmgr_vigs!\n");
956 *error = TBM_ERROR_OUT_OF_MEMORY;
960 /* check the master_fd which already had opened */
961 drm_fd = tbm_drm_helper_get_master_fd();
963 drm_fd = _tbm_vigs_open_drm();
965 TBM_ERR("fail to open drm!\n");
967 *error = TBM_ERROR_INVALID_OPERATION;
971 if (drmIsMaster(drm_fd)) {
972 tbm_drm_helper_set_tbm_master_fd(drm_fd);
974 TBM_INFO("This is Master FD(%d) from open_drm.", drm_fd);
976 /* close the fd and get the authenticated fd from the master fd */
980 /* get the authenticated drm fd from the master fd */
981 if (!tbm_drm_helper_get_auth_info(&(drm_fd), NULL, NULL)) {
982 TBM_ERR("fail to get auth drm info!\n");
984 *error = TBM_ERROR_INVALID_OPERATION;
985 goto fail_get_auth_info;
987 TBM_INFO("This is Authenticated FD(%d)", drm_fd);
990 TBM_INFO("This is Master FD from tbm_drm_helper_get_master_fd(%d)", drm_fd);
992 tbm_drm_helper_set_fd(drm_fd);
994 ret = vigs_drm_device_create(drm_fd, &drm_dev);
996 TBM_ERR("vigs_drm_device_create failed: %s", strerror_r(errno, buf, STRERR_BUFSIZE));
998 *error = TBM_ERROR_INVALID_OPERATION;
999 goto fail_create_vigs_drm_device;
1001 bufmgr_vigs->drm_dev = drm_dev;
1002 g_drm_dev = drm_dev;
1004 bufmgr_vigs->hash_bos = drmHashCreate();
1006 /* alloc and register bufmgr_funcs */
1007 bufmgr_func = tbm_backend_bufmgr_alloc_bufmgr_func(bufmgr, &err);
1009 TBM_ERR("fail to alloc bufmgr_func! err(%d)\n", err);
1011 *error = TBM_ERROR_OUT_OF_MEMORY;
1012 goto fail_alloc_bufmgr_func;
1015 bufmgr_func->bufmgr_get_capabilities = tbm_vigs_bufmgr_get_capabilities;
1016 bufmgr_func->bufmgr_bind_native_display = tbm_vigs_bufmgr_bind_native_display;
1017 bufmgr_func->bufmgr_get_supported_formats = tbm_vigs_bufmgr_get_supported_formats;
1018 bufmgr_func->bufmgr_get_plane_data = tbm_vigs_bufmgr_get_plane_data;
1019 bufmgr_func->bufmgr_alloc_bo = tbm_vigs_bufmgr_alloc_bo;
1020 bufmgr_func->bufmgr_alloc_bo_with_format = tbm_bufmgr_vigs_alloc_bo_with_format;
1021 bufmgr_func->bufmgr_import_fd = tbm_vigs_bufmgr_import_fd;
1022 bufmgr_func->bufmgr_import_key = tbm_vigs_bufmgr_import_key;
1024 err = tbm_backend_bufmgr_register_bufmgr_func(bufmgr, bufmgr_func);
1025 if (err != TBM_ERROR_NONE) {
1026 TBM_ERR("fail to register bufmgr_func! err(%d)\n", err);
1028 *error = TBM_ERROR_INVALID_OPERATION;
1029 goto fail_register_bufmgr_func;
1031 bufmgr_vigs->bufmgr_func = bufmgr_func;
1033 /* alloc and register bo_funcs */
1034 bo_func = tbm_backend_bufmgr_alloc_bo_func(bufmgr, &err);
1036 TBM_ERR("fail to alloc bo_func! err(%d)\n", err);
1038 *error = TBM_ERROR_OUT_OF_MEMORY;
1039 goto fail_alloc_bo_func;
1042 bo_func->bo_free = tbm_vigs_bo_free;
1043 bo_func->bo_get_size = tbm_vigs_bo_get_size;
1044 bo_func->bo_get_memory_types = tbm_vigs_bo_get_memory_type;
1045 bo_func->bo_get_handle = tbm_vigs_bo_get_handle;
1046 bo_func->bo_map = tbm_vigs_bo_map;
1047 bo_func->bo_unmap = tbm_vigs_bo_unmap;
1048 bo_func->bo_lock = tbm_vigs_bo_lock;
1049 bo_func->bo_unlock = tbm_vigs_bo_unlock;
1050 bo_func->bo_export_fd = tbm_vigs_bo_export_fd;
1051 bo_func->bo_export_key = tbm_vigs_bo_export_key;
1053 err = tbm_backend_bufmgr_register_bo_func(bufmgr, bo_func);
1054 if (err != TBM_ERROR_NONE) {
1055 TBM_ERR("fail to register bo_func! err(%d)\n", err);
1057 *error = TBM_ERROR_INVALID_OPERATION;
1058 goto fail_register_bo_func;
1060 bufmgr_vigs->bo_func = bo_func;
1062 TBM_INFO("initialized");
1064 return (tbm_backend_bufmgr_data *)bufmgr_vigs;
1066 fail_register_bo_func:
1067 tbm_backend_bufmgr_free_bo_func(bufmgr, bo_func);
1069 fail_register_bufmgr_func:
1070 tbm_backend_bufmgr_free_bufmgr_func(bufmgr, bufmgr_func);
1071 fail_alloc_bufmgr_func:
1072 drmHashDestroy(bufmgr_vigs->hash_bos);
1073 vigs_drm_device_destroy(drm_dev);
1074 fail_create_vigs_drm_device:
1076 tbm_drm_helper_unset_tbm_master_fd();
1087 tbm_backend_module tbm_backend_module_data = {
1090 TBM_BACKEND_ABI_VERSION_3_0,
1095 struct vigs_drm_device *
1096 tbm_vigs_get_drm_dev(void)