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
39 #include <tbm_bufmgr.h>
40 #include <tbm_bufmgr_backend.h>
41 #include <tbm_surface.h>
42 #include <tbm_drm_helper.h>
44 #include "tbm_emulator_log.h"
51 #define VIGS_DRM_NAME "vigs"
53 static uint32_t tbm_bufmgr_emulator_color_format_list[] =
63 static int _tbm_vigs_open_drm(void)
67 fd = drmOpen(VIGS_DRM_NAME, NULL);
69 TBM_EMULATOR_LOG_ERROR ("open vigs drm device failed");
76 static tbm_bo_handle get_tbm_bo_handle(struct vigs_drm_gem *gem,
79 tbm_bo_handle bo_handle;
82 memset(&bo_handle, 0, sizeof(bo_handle));
85 case TBM_DEVICE_DEFAULT:
87 bo_handle.u32 = gem->handle;
90 ret = vigs_drm_gem_map(gem, 1);
93 bo_handle.ptr = gem->vaddr;
95 TBM_EMULATOR_LOG_ERROR("vigs_drm_gem_map failed: %s",
101 TBM_EMULATOR_LOG_ERROR("TBM_DEVICE_3D not supported");
104 TBM_EMULATOR_LOG_ERROR("TBM_DEVICE_MM not supported");
107 TBM_EMULATOR_LOG_ERROR("%d not supported", device);
114 static void tbm_bufmgr_emulator_deinit(void *priv)
116 struct vigs_drm_device *drm_dev = priv;
118 TBM_EMULATOR_LOG_DEBUG("enter");
120 if (tbm_backend_is_display_server()) {
121 tbm_drm_helper_wl_auth_server_deinit();
122 tbm_drm_helper_unset_tbm_master_fd();
127 vigs_drm_device_destroy(drm_dev);
130 static int tbm_bufmgr_emulator_bo_size(tbm_bo bo)
132 struct vigs_drm_surface *sfc;
134 TBM_EMULATOR_LOG_DEBUG("bo = %p", bo);
136 sfc = (struct vigs_drm_surface*)tbm_backend_get_bo_priv(bo);
138 return sfc->gem.size;
141 static void *tbm_bufmgr_emulator_bo_alloc(tbm_bo bo, int size, int flags)
143 struct vigs_drm_device *drm_dev;
144 struct vigs_drm_surface *sfc;
145 uint32_t width = 2048, height;
148 TBM_EMULATOR_LOG_DEBUG("size = %d, flags = 0x%X", size, flags);
150 drm_dev = (struct vigs_drm_device*)tbm_backend_get_bufmgr_priv(bo);
152 height = ((uint32_t)size + (width * 4) - 1) / (width * 4);
154 ret = vigs_drm_surface_create(drm_dev,
157 vigs_drm_surface_bgra8888, 0,
161 TBM_EMULATOR_LOG_ERROR("vigs_drm_suface_create failed: %s",
169 static void tbm_bufmgr_emulator_bo_free(tbm_bo bo)
171 struct vigs_drm_surface *sfc;
173 TBM_EMULATOR_LOG_DEBUG("bo = %p", bo);
175 sfc = (struct vigs_drm_surface*)tbm_backend_get_bo_priv(bo);
177 vigs_drm_gem_unref(&sfc->gem);
180 static void *tbm_bufmgr_emulator_bo_import(tbm_bo bo, unsigned int key)
182 struct vigs_drm_device *drm_dev;
184 struct vigs_drm_surface *sfc;
186 TBM_EMULATOR_LOG_DEBUG("bo = %p, key = %u", bo, key);
188 drm_dev = (struct vigs_drm_device*)tbm_backend_get_bufmgr_priv(bo);
190 ret = vigs_drm_surface_open(drm_dev, key, &sfc);
193 TBM_EMULATOR_LOG_ERROR("vigs_drm_surface_open failed for key %u: %s",
199 TBM_EMULATOR_LOG_DEBUG("handle = %u", sfc->gem.handle);
204 static void *tbm_bufmgr_emulator_bo_import_fd(tbm_bo bo, tbm_fd key)
206 struct vigs_drm_device *drm_dev;
207 struct vigs_drm_surface *sfc;
210 TBM_EMULATOR_LOG_DEBUG("bo = %p, key = %d", bo, key);
212 drm_dev = (struct vigs_drm_device *)tbm_backend_get_bufmgr_priv(bo);
214 ret = vigs_drm_prime_import_fd(drm_dev, key, &sfc);
217 TBM_EMULATOR_LOG_ERROR("vigs_drm_prime_import_fd failed for key %d: %s",
223 TBM_EMULATOR_LOG_DEBUG("handle = %u", sfc->gem.handle);
229 static unsigned int tbm_bufmgr_emulator_bo_export(tbm_bo bo)
231 struct vigs_drm_surface *sfc;
234 TBM_EMULATOR_LOG_DEBUG("bo = %p", bo);
236 sfc = (struct vigs_drm_surface*)tbm_backend_get_bo_priv(bo);
238 ret = vigs_drm_gem_get_name(&sfc->gem);
241 TBM_EMULATOR_LOG_ERROR("vigs_drm_gem_get_name failed: %s",
246 return sfc->gem.name;
249 tbm_fd tbm_bufmgr_emulator_bo_export_fd(tbm_bo bo)
251 struct vigs_drm_device *drm_dev;
252 struct vigs_drm_surface *sfc;
255 TBM_EMULATOR_LOG_DEBUG("bo = %p", bo);
257 drm_dev = (struct vigs_drm_device *)tbm_backend_get_bufmgr_priv(bo);
258 sfc = (struct vigs_drm_surface *)tbm_backend_get_bo_priv(bo);;
260 ret = vigs_drm_prime_export_fd(drm_dev, sfc, &fd);
263 TBM_EMULATOR_LOG_ERROR("vigs_drm_prime_export_fd failed: %s",
271 static tbm_bo_handle tbm_bufmgr_emulator_bo_get_handle(tbm_bo bo, int device)
273 struct vigs_drm_surface *sfc;
275 TBM_EMULATOR_LOG_DEBUG("bo = %p, device = %d", bo, device);
277 sfc = (struct vigs_drm_surface*)tbm_backend_get_bo_priv(bo);
279 return get_tbm_bo_handle(&sfc->gem, device);
282 static tbm_bo_handle tbm_bufmgr_emulator_bo_map(tbm_bo bo, int device, int opt)
284 struct vigs_drm_surface *sfc;
285 tbm_bo_handle handle;
288 TBM_EMULATOR_LOG_DEBUG("bo = %p, device = %d, opt = %d", bo, device, opt);
290 sfc = (struct vigs_drm_surface*)tbm_backend_get_bo_priv(bo);
292 handle = get_tbm_bo_handle(&sfc->gem, device);
298 if ((opt & TBM_OPTION_READ) != 0) {
299 saf |= VIGS_DRM_SAF_READ;
302 if ((opt & TBM_OPTION_WRITE) != 0) {
303 saf |= VIGS_DRM_SAF_WRITE;
306 vigs_drm_surface_start_access(sfc, saf);
311 static int tbm_bufmgr_emulator_bo_unmap(tbm_bo bo)
313 struct vigs_drm_surface *sfc;
315 TBM_EMULATOR_LOG_DEBUG("bo = %p", bo);
317 sfc = (struct vigs_drm_surface*)tbm_backend_get_bo_priv(bo);
319 vigs_drm_surface_end_access(sfc, 1);
324 static int tbm_bufmgr_emulator_bo_lock(tbm_bo bo, int device, int opt)
326 TBM_EMULATOR_LOG_DEBUG("bo = %p", bo);
330 static int tbm_bufmgr_emulator_bo_unlock(tbm_bo bo)
332 TBM_EMULATOR_LOG_DEBUG("bo = %p", bo);
336 static int tbm_bufmgr_emulator_surface_get_plane_data(int width, int height, tbm_format format, int plane_idx, uint32_t *size, uint32_t *offset, uint32_t *pitch, int *bo_idx)
344 case TBM_FORMAT_RGB888:
345 *size = width * height * 3;
350 case TBM_FORMAT_XRGB8888:
351 case TBM_FORMAT_ARGB8888:
352 *size = width * height * 4;
357 case TBM_FORMAT_NV21:
358 if (plane_idx == 0) {
359 *size = width * height;
363 } else if (plane_idx == 1) {
364 *size = width * (height >> 1);
365 *offset = width * height;
372 case TBM_FORMAT_NV61:
373 if (plane_idx == 0) {
374 *size = width * height;
378 } else if (plane_idx == 1) {
379 *size = width * height;
380 *offset = width * height;
387 case TBM_FORMAT_YUV420:
388 if (plane_idx == 0) {
389 *size = width * height;
393 } else if (plane_idx == 1) {
394 *size = (width * height) >> 2;
395 *offset = width * height;
396 *pitch = width >> 1 ;
398 } else if (plane_idx == 2) {
399 *size = (width * height) >> 2;
400 *offset = (width * height) + (width * height >> 2);
412 static int tbm_bufmgr_emulator_surface_supported_format(uint32_t **formats, uint32_t *num)
414 uint32_t *color_formats;
416 color_formats = (uint32_t*)calloc(1, sizeof(tbm_bufmgr_emulator_color_format_list));
418 if (!color_formats) {
422 memcpy(color_formats,
423 tbm_bufmgr_emulator_color_format_list,
424 sizeof(tbm_bufmgr_emulator_color_format_list));
426 *formats = color_formats;
427 *num = sizeof(tbm_bufmgr_emulator_color_format_list)/sizeof(tbm_bufmgr_emulator_color_format_list[0]);
433 tbm_bufmgr_emulator_bind_native_display (tbm_bufmgr bufmgr, void *native_display)
435 struct vigs_drm_device *drm_dev;
439 drm_dev = (struct vigs_drm_device *)tbm_backend_get_priv_from_bufmgr(bufmgr);
441 device_name = drmGetDeviceNameFromFd(drm_dev->fd);
444 TBM_EMULATOR_LOG_ERROR("drmGetDeviceNameFromFd failed");
448 ret = tbm_drm_helper_wl_auth_server_init(native_display, drm_dev->fd, device_name, 0);
451 TBM_EMULATOR_LOG_ERROR("tbm_drm_helper_wl_auth_server_init failed");
461 MODULEINITPPROTO(tbm_bufmgr_emulator_init);
463 static TBMModuleVersionInfo EmulatorVersRec =
470 TBMModuleData tbmModuleData = { &EmulatorVersRec, tbm_bufmgr_emulator_init };
472 int tbm_bufmgr_emulator_init(tbm_bufmgr bufmgr, int fd)
475 struct vigs_drm_device *drm_dev = NULL;
476 tbm_bufmgr_backend backend = NULL;
479 TBM_EMULATOR_LOG_DEBUG("enter");
485 if (tbm_backend_is_display_server()) {
486 drm_fd = tbm_drm_helper_get_master_fd();
489 drm_fd = _tbm_vigs_open_drm();
493 TBM_EMULATOR_LOG_ERROR ("vigs drm device failed");
497 tbm_drm_helper_set_tbm_master_fd(drm_fd);
500 if (!tbm_drm_helper_get_auth_info(&drm_fd, NULL, NULL)) {
501 TBM_EMULATOR_LOG_ERROR ("tbm_drm_helper_get_auth_info failed");
506 ret = vigs_drm_device_create(drm_fd, &drm_dev);
509 TBM_EMULATOR_LOG_ERROR("vigs_drm_device_create failed: %s", strerror(-ret));
513 backend = tbm_backend_alloc();
516 TBM_EMULATOR_LOG_ERROR("tbm_backend_alloc failed");
520 backend->priv = (void*)drm_dev;
521 backend->bufmgr_deinit = tbm_bufmgr_emulator_deinit;
522 backend->bo_size = tbm_bufmgr_emulator_bo_size;
523 backend->bo_alloc = tbm_bufmgr_emulator_bo_alloc;
524 backend->bo_free = tbm_bufmgr_emulator_bo_free;
525 backend->bo_import = tbm_bufmgr_emulator_bo_import;
526 backend->bo_import_fd = tbm_bufmgr_emulator_bo_import_fd;
527 backend->bo_export = tbm_bufmgr_emulator_bo_export;
528 backend->bo_export_fd = tbm_bufmgr_emulator_bo_export_fd;
529 backend->bo_get_handle = tbm_bufmgr_emulator_bo_get_handle;
530 backend->bo_map = tbm_bufmgr_emulator_bo_map;
531 backend->bo_unmap = tbm_bufmgr_emulator_bo_unmap;
532 backend->bo_lock = tbm_bufmgr_emulator_bo_lock;
533 backend->bo_unlock = tbm_bufmgr_emulator_bo_unlock;
534 backend->surface_get_plane_data = tbm_bufmgr_emulator_surface_get_plane_data;
535 backend->surface_supported_format = tbm_bufmgr_emulator_surface_supported_format;
536 backend->bufmgr_bind_native_display = tbm_bufmgr_emulator_bind_native_display;
538 if (!tbm_backend_init(bufmgr, backend)) {
539 TBM_EMULATOR_LOG_ERROR("tbm_backend_init failed");
543 TBM_EMULATOR_LOG_INFO("initialized");
549 tbm_backend_free(backend);
553 vigs_drm_device_destroy(drm_dev);
557 if (tbm_backend_is_display_server()) {
558 tbm_drm_helper_unset_tbm_master_fd();