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>
43 #include "tbm_emulator_log.h"
47 static uint32_t tbm_bufmgr_emulator_color_format_list[] =
57 static tbm_bo_handle get_tbm_bo_handle(struct vigs_drm_gem *gem,
60 tbm_bo_handle bo_handle;
63 memset(&bo_handle, 0, sizeof(bo_handle));
66 case TBM_DEVICE_DEFAULT:
68 bo_handle.u32 = gem->handle;
71 ret = vigs_drm_gem_map(gem, 1);
74 bo_handle.ptr = gem->vaddr;
76 TBM_EMULATOR_LOG_ERROR("vigs_drm_gem_map failed: %s",
82 TBM_EMULATOR_LOG_ERROR("TBM_DEVICE_3D not supported");
85 TBM_EMULATOR_LOG_ERROR("TBM_DEVICE_MM not supported");
88 TBM_EMULATOR_LOG_ERROR("%d not supported", device);
95 static void tbm_bufmgr_emulator_deinit(void *priv)
97 struct vigs_drm_device *drm_dev = priv;
99 TBM_EMULATOR_LOG_DEBUG("enter");
101 vigs_drm_device_destroy(drm_dev);
104 static int tbm_bufmgr_emulator_bo_size(tbm_bo bo)
106 struct vigs_drm_surface *sfc;
108 TBM_EMULATOR_LOG_DEBUG("bo = %p", bo);
110 sfc = (struct vigs_drm_surface*)tbm_backend_get_bo_priv(bo);
112 return sfc->gem.size;
115 static void *tbm_bufmgr_emulator_bo_alloc(tbm_bo bo, int size, int flags)
117 struct vigs_drm_device *drm_dev;
118 struct vigs_drm_surface *sfc;
119 uint32_t width = 2048, height;
122 TBM_EMULATOR_LOG_DEBUG("size = %d, flags = 0x%X", size, flags);
124 drm_dev = (struct vigs_drm_device*)tbm_backend_get_bufmgr_priv(bo);
126 height = ((uint32_t)size + (width * 4) - 1) / (width * 4);
128 ret = vigs_drm_surface_create(drm_dev,
131 vigs_drm_surface_bgra8888, 0,
135 TBM_EMULATOR_LOG_ERROR("vigs_drm_suface_create failed: %s",
143 static void tbm_bufmgr_emulator_bo_free(tbm_bo bo)
145 struct vigs_drm_surface *sfc;
147 TBM_EMULATOR_LOG_DEBUG("bo = %p", bo);
149 sfc = (struct vigs_drm_surface*)tbm_backend_get_bo_priv(bo);
151 vigs_drm_gem_unref(&sfc->gem);
154 static void *tbm_bufmgr_emulator_bo_import(tbm_bo bo, unsigned int key)
156 struct vigs_drm_device *drm_dev;
158 struct vigs_drm_surface *sfc;
160 TBM_EMULATOR_LOG_DEBUG("bo = %p, key = %u", bo, key);
162 drm_dev = (struct vigs_drm_device*)tbm_backend_get_bufmgr_priv(bo);
164 ret = vigs_drm_surface_open(drm_dev, key, &sfc);
167 TBM_EMULATOR_LOG_ERROR("vigs_drm_surface_open failed for key %u: %s",
173 TBM_EMULATOR_LOG_DEBUG("handle = %u", sfc->gem.handle);
178 static void *tbm_bufmgr_emulator_bo_import_fd(tbm_bo bo, tbm_fd key)
180 struct vigs_drm_device *drm_dev;
181 struct vigs_drm_surface *sfc;
184 TBM_EMULATOR_LOG_DEBUG("bo = %p, key = %d", bo, key);
186 drm_dev = (struct vigs_drm_device *)tbm_backend_get_bufmgr_priv(bo);
188 ret = vigs_drm_prime_import_fd(drm_dev, key, &sfc);
191 TBM_EMULATOR_LOG_ERROR("vigs_drm_prime_import_fd failed for key %d: %s",
197 TBM_EMULATOR_LOG_DEBUG("handle = %u", sfc->gem.handle);
203 static unsigned int tbm_bufmgr_emulator_bo_export(tbm_bo bo)
205 struct vigs_drm_surface *sfc;
208 TBM_EMULATOR_LOG_DEBUG("bo = %p", bo);
210 sfc = (struct vigs_drm_surface*)tbm_backend_get_bo_priv(bo);
212 ret = vigs_drm_gem_get_name(&sfc->gem);
215 TBM_EMULATOR_LOG_ERROR("vigs_drm_gem_get_name failed: %s",
220 return sfc->gem.name;
223 tbm_fd tbm_bufmgr_emulator_bo_export_fd(tbm_bo bo)
225 struct vigs_drm_device *drm_dev;
226 struct vigs_drm_surface *sfc;
229 TBM_EMULATOR_LOG_DEBUG("bo = %p", bo);
231 drm_dev = (struct vigs_drm_device *)tbm_backend_get_bufmgr_priv(bo);
232 sfc = (struct vigs_drm_surface *)tbm_backend_get_bo_priv(bo);;
234 ret = vigs_drm_prime_export_fd(drm_dev, sfc, &fd);
237 TBM_EMULATOR_LOG_ERROR("vigs_drm_prime_export_fd failed: %s",
245 static tbm_bo_handle tbm_bufmgr_emulator_bo_get_handle(tbm_bo bo, int device)
247 struct vigs_drm_surface *sfc;
249 TBM_EMULATOR_LOG_DEBUG("bo = %p, device = %d", bo, device);
251 sfc = (struct vigs_drm_surface*)tbm_backend_get_bo_priv(bo);
253 return get_tbm_bo_handle(&sfc->gem, device);
256 static tbm_bo_handle tbm_bufmgr_emulator_bo_map(tbm_bo bo, int device, int opt)
258 struct vigs_drm_surface *sfc;
259 tbm_bo_handle handle;
262 TBM_EMULATOR_LOG_DEBUG("bo = %p, device = %d, opt = %d", bo, device, opt);
264 sfc = (struct vigs_drm_surface*)tbm_backend_get_bo_priv(bo);
266 handle = get_tbm_bo_handle(&sfc->gem, device);
272 if ((opt & TBM_OPTION_READ) != 0) {
273 saf |= VIGS_DRM_SAF_READ;
276 if ((opt & TBM_OPTION_WRITE) != 0) {
277 saf |= VIGS_DRM_SAF_WRITE;
280 vigs_drm_surface_start_access(sfc, saf);
285 static int tbm_bufmgr_emulator_bo_unmap(tbm_bo bo)
287 struct vigs_drm_surface *sfc;
289 TBM_EMULATOR_LOG_DEBUG("bo = %p", bo);
291 sfc = (struct vigs_drm_surface*)tbm_backend_get_bo_priv(bo);
293 vigs_drm_surface_end_access(sfc, 1);
298 static int tbm_bufmgr_emulator_bo_cache_flush(tbm_bo bo, int flags)
300 TBM_EMULATOR_LOG_DEBUG("bo = %p, flags = %d", bo, flags);
304 static int tbm_bufmgr_emulator_bo_lock(tbm_bo bo)
306 TBM_EMULATOR_LOG_DEBUG("bo = %p", bo);
310 static int tbm_bufmgr_emulator_bo_unlock(tbm_bo bo)
312 TBM_EMULATOR_LOG_DEBUG("bo = %p", bo);
316 static int tbm_bufmgr_emulator_bo_get_global_key(tbm_bo bo)
318 struct vigs_drm_surface *sfc;
321 TBM_EMULATOR_LOG_DEBUG("bo = %p", bo);
323 sfc = (struct vigs_drm_surface*)tbm_backend_get_bo_priv(bo);
325 ret = vigs_drm_gem_get_name(&sfc->gem);
328 TBM_EMULATOR_LOG_ERROR("vigs_drm_gem_get_name failed: %s",
333 return sfc->gem.name;
336 static int tbm_bufmgr_emulator_surface_get_plane_data(tbm_surface_h surface, 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_get_size(tbm_surface_h surface, int width, int height, tbm_format format)
417 case TBM_FORMAT_RGB888:
420 case TBM_FORMAT_XRGB8888:
421 case TBM_FORMAT_ARGB8888:
424 /* NV21 : Y/CrCb 4:2:0 */
425 /* YUV420 : YUV 4:2:0 */
426 case TBM_FORMAT_NV21:
427 case TBM_FORMAT_YUV420:
430 /* NV61 : Y/CrCb 4:2:2 */
431 case TBM_FORMAT_NV61:
437 return (width * height * bpp) >> 3;
440 static int tbm_bufmgr_emulator_surface_get_num_bos (tbm_format format)
445 case TBM_FORMAT_RGB888:
446 case TBM_FORMAT_XRGB8888:
447 case TBM_FORMAT_ARGB8888:
448 /* NV21 : Y/CrCb 4:2:0 */
449 /* YUV420 : YUV 4:2:0 */
450 case TBM_FORMAT_NV21:
451 case TBM_FORMAT_YUV420:
452 /* NV61 : Y/CrCb 4:2:2 */
453 case TBM_FORMAT_NV61:
462 static int tbm_bufmgr_emulator_surface_supported_format(uint32_t **formats, uint32_t *num)
464 uint32_t *color_formats;
466 color_formats = (uint32_t*)calloc(1, sizeof(tbm_bufmgr_emulator_color_format_list));
468 if (!color_formats) {
472 memcpy(color_formats,
473 tbm_bufmgr_emulator_color_format_list,
474 sizeof(tbm_bufmgr_emulator_color_format_list));
476 *formats = color_formats;
477 *num = sizeof(tbm_bufmgr_emulator_color_format_list)/sizeof(tbm_bufmgr_emulator_color_format_list[0]);
483 MODULEINITPPROTO(tbm_bufmgr_emulator_init);
485 static TBMModuleVersionInfo EmulatorVersRec =
492 TBMModuleData tbmModuleData = { &EmulatorVersRec, tbm_bufmgr_emulator_init };
494 int tbm_bufmgr_emulator_init(tbm_bufmgr bufmgr, int fd)
497 struct vigs_drm_device *drm_dev = NULL;
498 tbm_bufmgr_backend backend = NULL;
500 TBM_EMULATOR_LOG_DEBUG("enter");
506 ret = vigs_drm_device_create(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->flags = TBM_CACHE_CTRL_BACKEND|TBM_LOCK_CTRL_BACKEND;
521 backend->priv = (void*)drm_dev;
522 backend->bufmgr_deinit = tbm_bufmgr_emulator_deinit;
523 backend->bo_size = tbm_bufmgr_emulator_bo_size;
524 backend->bo_alloc = tbm_bufmgr_emulator_bo_alloc;
525 backend->bo_free = tbm_bufmgr_emulator_bo_free;
526 backend->bo_import = tbm_bufmgr_emulator_bo_import;
527 backend->bo_import_fd = tbm_bufmgr_emulator_bo_import_fd;
528 backend->bo_export = tbm_bufmgr_emulator_bo_export;
529 backend->bo_export_fd = tbm_bufmgr_emulator_bo_export_fd;
530 backend->bo_get_handle = tbm_bufmgr_emulator_bo_get_handle;
531 backend->bo_map = tbm_bufmgr_emulator_bo_map;
532 backend->bo_unmap = tbm_bufmgr_emulator_bo_unmap;
533 backend->bo_cache_flush = tbm_bufmgr_emulator_bo_cache_flush;
534 backend->bo_get_global_key = tbm_bufmgr_emulator_bo_get_global_key;
535 backend->bo_lock = tbm_bufmgr_emulator_bo_lock;
536 backend->bo_unlock = tbm_bufmgr_emulator_bo_unlock;
537 backend->surface_get_plane_data = tbm_bufmgr_emulator_surface_get_plane_data;
538 backend->surface_get_size = tbm_bufmgr_emulator_surface_get_size;
539 backend->surface_supported_format = tbm_bufmgr_emulator_surface_supported_format;
540 backend->surface_get_num_bos = tbm_bufmgr_emulator_surface_get_num_bos;
542 if (!tbm_backend_init(bufmgr, backend)) {
543 TBM_EMULATOR_LOG_ERROR("tbm_backend_init failed");
547 TBM_EMULATOR_LOG_INFO("initialized");
553 tbm_backend_free(backend);
557 vigs_drm_device_destroy(drm_dev);