1 From e2189a84d0da40b46c3406860fe087b7b09420b3 Mon Sep 17 00:00:00 2001
2 From: Prajwal Mohan <prajwal.karur.mohan@intel.com>
3 Date: Wed, 10 Oct 2012 09:56:06 -0700
4 Subject: [PATCH] Adding slp subpackage
8 libkms/Makefile.am | 5 +
9 libkms/slp.c | 222 +++++++++++++
10 slp/Makefile.am | 22 ++
11 slp/drm_slp_bufmgr.c | 847 ++++++++++++++++++++++++++++++++++++++++++++++++++
12 slp/drm_slp_bufmgr.h | 201 ++++++++++++
13 slp/libdrm_slp.pc.in | 11 +
14 slp/list.h | 131 ++++++++
15 8 files changed, 1444 insertions(+), 1 deletions(-)
16 create mode 100644 libkms/slp.c
17 create mode 100644 slp/Makefile.am
18 create mode 100644 slp/drm_slp_bufmgr.c
19 create mode 100644 slp/drm_slp_bufmgr.h
20 create mode 100644 slp/libdrm_slp.pc.in
21 create mode 100644 slp/list.h
23 diff --git a/Makefile.am b/Makefile.am
24 index 256a8cc..6e74607 100644
27 @@ -49,7 +49,11 @@ if HAVE_EXYNOS
28 EXYNOS_SUBDIR = exynos
31 -SUBDIRS = . $(LIBKMS_SUBDIR) $(INTEL_SUBDIR) $(NOUVEAU_SUBDIR) $(RADEON_SUBDIR) $(OMAP_SUBDIR) $(EXYNOS_SUBDIR) tests include
36 +SUBDIRS = . $(LIBKMS_SUBDIR) $(INTEL_SUBDIR) $(NOUVEAU_SUBDIR) $(RADEON_SUBDIR) $(OMAP_SUBDIR) $(EXYNOS_SUBDIR) $(SLP_SUBDIR) tests include
38 libdrm_la_LTLIBRARIES = libdrm.la
39 libdrm_ladir = $(libdir)
40 diff --git a/libkms/Makefile.am b/libkms/Makefile.am
41 index fa379a4..df74b7e 100644
42 --- a/libkms/Makefile.am
43 +++ b/libkms/Makefile.am
44 @@ -31,6 +31,11 @@ if HAVE_RADEON
45 libkms_la_SOURCES += radeon.c
49 +libkms_la_SOURCES += slp.c
50 +AM_CFLAGS += -I$(top_srcdir)/exynos
53 libkmsincludedir = ${includedir}/libkms
54 libkmsinclude_HEADERS = libkms.h
56 diff --git a/libkms/slp.c b/libkms/slp.c
58 index 0000000..263f2ab
62 +/**************************************************************************
64 + * Copyright © 2009 VMware, Inc., Palo Alto, CA., USA
65 + * All Rights Reserved.
67 + * Permission is hereby granted, free of charge, to any person obtaining a
68 + * copy of this software and associated documentation files (the
69 + * "Software"), to deal in the Software without restriction, including
70 + * without limitation the rights to use, copy, modify, merge, publish,
71 + * distribute, sub license, and/or sell copies of the Software, and to
72 + * permit persons to whom the Software is furnished to do so, subject to
73 + * the following conditions:
75 + * The above copyright notice and this permission notice (including the
76 + * next paragraph) shall be included in all copies or substantial portions
79 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
80 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
81 + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
82 + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
83 + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
84 + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
85 + * USE OR OTHER DEALINGS IN THE SOFTWARE.
87 + **************************************************************************/
90 +#define HAVE_STDINT_H
91 +#define _FILE_OFFSET_BITS 64
97 +#include "internal.h"
99 +#include <sys/mman.h>
100 +#include <sys/ioctl.h>
101 +#include "xf86drm.h"
103 +#include "exynos_drm.h"
107 + struct kms_bo base;
108 + unsigned map_count;
112 +slp_get_prop(struct kms_driver *kms, unsigned key, unsigned *out)
116 + *out = KMS_BO_TYPE_SCANOUT_X8R8G8B8 | KMS_BO_TYPE_CURSOR_64X64_A8R8G8B8;
125 +slp_destroy(struct kms_driver *kms)
132 +slp_bo_create(struct kms_driver *kms,
133 + const unsigned width, const unsigned height,
134 + const enum kms_bo_type type, const unsigned *attr,
135 + struct kms_bo **out)
137 + struct drm_exynos_gem_create arg;
138 + unsigned size, pitch;
142 + for (i = 0; attr[i]; i += 2) {
153 + bo = calloc(1, sizeof(*bo));
157 + if (type == KMS_BO_TYPE_CURSOR_64X64_A8R8G8B8) {
159 + size = 64 * 64 * 4;
160 + } else if (type == KMS_BO_TYPE_SCANOUT_X8R8G8B8) {
162 + pitch = (pitch + 512 - 1) & ~(512 - 1);
163 + size = pitch * ((height + 4 - 1) & ~(4 - 1));
168 + memset(&arg, 0, sizeof(arg));
171 + ret = drmCommandWriteRead(kms->fd, DRM_EXYNOS_GEM_CREATE, &arg, sizeof(arg));
175 + bo->base.kms = kms;
176 + bo->base.handle = arg.handle;
177 + bo->base.size = size;
178 + bo->base.pitch = pitch;
190 +slp_bo_get_prop(struct kms_bo *bo, unsigned key, unsigned *out)
199 +slp_bo_map(struct kms_bo *_bo, void **out)
201 + struct slp_bo *bo = (struct slp_bo *)_bo;
202 + struct drm_exynos_gem_map_off arg;
206 + if (bo->base.ptr) {
208 + *out = bo->base.ptr;
212 + memset(&arg, 0, sizeof(arg));
213 + arg.handle = bo->base.handle;
215 + ret = drmCommandWriteRead(bo->base.kms->fd, DRM_EXYNOS_GEM_MAP_OFFSET, &arg, sizeof(arg));
219 + map = mmap(0, bo->base.size, PROT_READ | PROT_WRITE, MAP_SHARED, bo->base.kms->fd, arg.offset);
220 + if (map == MAP_FAILED)
223 + bo->base.ptr = map;
225 + *out = bo->base.ptr;
231 +slp_bo_unmap(struct kms_bo *_bo)
233 + struct slp_bo *bo = (struct slp_bo *)_bo;
239 +slp_bo_destroy(struct kms_bo *_bo)
241 + struct slp_bo *bo = (struct slp_bo *)_bo;
242 + struct drm_gem_close arg;
245 + if (bo->base.ptr) {
246 + /* XXX Sanity check map_count */
247 + munmap(bo->base.ptr, bo->base.size);
248 + bo->base.ptr = NULL;
251 + memset(&arg, 0, sizeof(arg));
252 + arg.handle = bo->base.handle;
254 + ret = drmIoctl(bo->base.kms->fd, DRM_IOCTL_GEM_CLOSE, &arg);
263 +slp_create(int fd, struct kms_driver **out)
265 + struct kms_driver *kms;
267 + kms = calloc(1, sizeof(*kms));
273 + kms->bo_create = slp_bo_create;
274 + kms->bo_map = slp_bo_map;
275 + kms->bo_unmap = slp_bo_unmap;
276 + kms->bo_get_prop = slp_bo_get_prop;
277 + kms->bo_destroy = slp_bo_destroy;
278 + kms->get_prop = slp_get_prop;
279 + kms->destroy = slp_destroy;
284 diff --git a/slp/Makefile.am b/slp/Makefile.am
286 index 0000000..132662b
288 +++ b/slp/Makefile.am
295 + -I$(top_srcdir)/slp \
296 + $(PTHREADSTUBS_CFLAGS) \
297 + -I$(top_srcdir)/include/drm
299 +libdrm_slp_la_LTLIBRARIES = libdrm_slp.la
300 +libdrm_slp_ladir = $(libdir)
301 +libdrm_slp_la_LDFLAGS = -version-number 1:0:0 -no-undefined
302 +libdrm_slp_la_LIBADD = ../libdrm.la @PTHREADSTUBS_LIBS@ @CLOCK_LIB@ -ldl
304 +libdrm_slp_la_SOURCES = \
308 +libdrm_slpincludedir = ${includedir}/libdrm
309 +libdrm_slpinclude_HEADERS = drm_slp_bufmgr.h
311 +pkgconfig_DATA = libdrm_slp.pc
312 diff --git a/slp/drm_slp_bufmgr.c b/slp/drm_slp_bufmgr.c
314 index 0000000..f723ded
316 +++ b/slp/drm_slp_bufmgr.c
318 +/**************************************************************************
320 +xserver-xorg-video-sec
322 +Copyright 2011 Samsung Electronics co., Ltd. All Rights Reserved.
324 +Contact: SooChan Lim <sc1.lim@samsung.com>, Sangjin Lee <lsj119@samsung.com>
326 +Permission is hereby granted, free of charge, to any person obtaining a
327 +copy of this software and associated documentation files (the
328 +"Software"), to deal in the Software without restriction, including
329 +without limitation the rights to use, copy, modify, merge, publish,
330 +distribute, sub license, and/or sell copies of the Software, and to
331 +permit persons to whom the Software is furnished to do so, subject to
332 +the following conditions:
334 +The above copyright notice and this permission notice (including the
335 +next paragraph) shall be included in all copies or substantial portions
338 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
339 +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
340 +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
341 +IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
342 +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
343 +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
344 +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
346 +**************************************************************************/
354 +#include <sys/types.h>
355 +#include <sys/stat.h>
362 +#include "drm_slp_bufmgr.h"
365 +#define PREFIX_LIB "libdrm_slp_"
366 +#define SUFFIX_LIB ".so"
367 +#define DEFAULT_LIB PREFIX_LIB"default"SUFFIX_LIB
369 +#define NUM_TRY_LOCK 10
370 +#define SEM_NAME "pixmap_1"
373 +#define DRM_RETURN_IF_FAIL(cond) {if (!(cond)) { fprintf (stderr, "[%s] : '%s' failed.\n", __FUNCTION__, #cond); return; }}
374 +#define DRM_RETURN_VAL_IF_FAIL(cond, val) {if (!(cond)) { fprintf (stderr, "[%s] : '%s' failed.\n", __FUNCTION__, #cond); return val; }}
376 +#define MGR_IS_VALID(mgr) (mgr && \
377 + mgr->link.next && \
378 + mgr->link.next->prev == &mgr->link)
379 +#define BO_IS_VALID(bo) (bo && \
380 + MGR_IS_VALID(bo->bufmgr) && \
382 + bo->list.next->prev == &bo->list)
388 + drm_data_free free_func ;
391 +static struct list_head *gBufMgrs = NULL;
394 +_sem_wait_wrapper(sem_t* sem)
397 + int num_try = NUM_TRY_LOCK;
401 + res = sem_wait(sem);
403 + } while((res == -1) && (errno == EINTR) && (num_try >= 0));
408 + "[libdrm] error %s:%d(sem:%p, num_try:%d) PID:%04d\n",
420 + "[libdrm] LOCK >> %s:%d(sem:%p, num_try:%d) PID:%04d\n",
433 +_sem_post_wrapper(sem_t* sem)
436 + int num_try = NUM_TRY_LOCK;
440 + res = sem_post(sem);
443 + } while((res == -1) && (errno == EINTR) && (num_try >= 0));
448 + "[libdrm] error %s:%d(sem:%p, num_try:%d) PID:%04d\n",
460 + "[libdrm] UNLOCK << %s:%d(sem:%p, num_try:%d) PID:%04d\n",
473 +_sem_open(drm_slp_bufmgr bufmgr)
475 + bufmgr->semObj.handle = sem_open(SEM_NAME, O_CREAT, 0777, 1);
476 + if(bufmgr->semObj.handle == SEM_FAILED)
479 + "[libdrm] error %s:%d(name:%s) PID:%04d\n",
484 + bufmgr->semObj.handle = NULL;
491 + "[libdrm] OPEN %s:%d(sem:%p) PID:%04d\n",
494 + bufmgr->semObj.handle,
499 + bufmgr->semObj.status = STATUS_UNLOCK;
505 +_sem_close(drm_slp_bufmgr bufmgr)
507 + _sem_wait_wrapper(bufmgr->semObj.handle);
508 + sem_unlink(SEM_NAME);
513 +_sem_lock(drm_slp_bufmgr bufmgr)
515 + if(bufmgr->semObj.status != STATUS_UNLOCK) return 0;
517 + if(!_sem_wait_wrapper(bufmgr->semObj.handle)) return 0;
518 + bufmgr->semObj.status = STATUS_LOCK;
523 +_sem_unlock(drm_slp_bufmgr bufmgr)
525 + if(bufmgr->semObj.status != STATUS_LOCK) return 0;
527 + _sem_post_wrapper(bufmgr->semObj.handle);
528 + bufmgr->semObj.status = STATUS_UNLOCK;
532 +static drm_slp_bufmgr
533 +_load_bufmgr(int fd, const char *file, void *arg)
535 + char path[PATH_MAX] = {0,};
536 + drm_slp_bufmgr bufmgr = NULL;
537 + int (*bufmgr_init)(drm_slp_bufmgr bufmgr, int fd, void *arg);
540 + snprintf(path, sizeof(path), BUFMGR_DIR "/%s", file);
542 + module = dlopen(path, RTLD_LAZY);
545 + "[libdrm] failed to load module: %s(%s)\n",
550 + bufmgr_init = dlsym(module, "init_slp_bufmgr");
551 + if (!bufmgr_init) {
553 + "[libdrm] failed to lookup init function: %s(%s)\n",
558 + bufmgr = calloc(sizeof(struct _drm_slp_bufmgr), 1);
564 + if(!bufmgr_init(bufmgr, fd, arg))
566 + fprintf(stderr,"[libdrm] Fail to init module(%s)\n", file);
572 + fprintf(stderr,"[libdrm] Success to load module(%s)\n", file);
578 +drm_slp_bufmgr_init(int fd, void *arg)
580 + drm_slp_bufmgr bufmgr = NULL;
581 + const char *p = NULL;
586 + if(gBufMgrs == NULL)
588 + gBufMgrs = malloc(sizeof(struct list_head));
589 + LIST_INITHEAD(gBufMgrs);
593 + LIST_FOR_EACH_ENTRY(bufmgr, gBufMgrs, link)
595 + if(bufmgr->drm_fd == fd)
597 + bufmgr->ref_count++;
598 + fprintf(stderr, "[libdrm] bufmgr ref: fd=%d, ref_count:%d\n", fd, bufmgr->ref_count);
604 + fprintf(stderr, "[libdrm] bufmgr init: fd=%d\n", fd);
606 + p = getenv ("SLP_BUFMGR_MODULE");
609 + char file[PATH_MAX] = {0,};
610 + snprintf(file, sizeof(file), PREFIX_LIB"%s"SUFFIX_LIB, p);
611 + bufmgr = _load_bufmgr (fd, file, arg);
615 + bufmgr = _load_bufmgr (fd, DEFAULT_LIB, arg);
619 + struct dirent **namelist;
623 + n = scandir(BUFMGR_DIR, &namelist, 0, alphasort);
625 + fprintf(stderr,"[libdrm] no files : %s\n", BUFMGR_DIR);
630 + if (!found && strstr (namelist[n]->d_name, PREFIX_LIB))
632 + char *p = strstr (namelist[n]->d_name, SUFFIX_LIB);
633 + if (!strcmp (p, SUFFIX_LIB))
635 + bufmgr = _load_bufmgr (fd, namelist[n]->d_name, arg);
648 + fprintf(stderr,"[libdrm] backend is NULL.\n");
652 + if (pthread_mutex_init(&bufmgr->lock, NULL) != 0)
654 + bufmgr->bufmgr_destroy(bufmgr);
659 + bufmgr->ref_count = 1;
660 + bufmgr->drm_fd = fd;
662 + LIST_INITHEAD(&bufmgr->bos);
663 + LIST_ADD(&bufmgr->link, gBufMgrs);
669 +drm_slp_bufmgr_destroy(drm_slp_bufmgr bufmgr)
671 + DRM_RETURN_IF_FAIL(MGR_IS_VALID(bufmgr));
673 + fprintf(stderr, "[DRM] bufmgr destroy: bufmgr:%p, drm_fd:%d\n",
674 + bufmgr, bufmgr->drm_fd);
676 + /*Check and Free bos*/
677 + if(!LIST_IS_EMPTY(&bufmgr->bos))
679 + drm_slp_bo bo, tmp;
681 + LIST_FOR_EACH_ENTRY_SAFE(bo, tmp, &bufmgr->bos, list)
683 + fprintf(stderr, "[libdrm] Un-freed bo(%p, ref:%d) \n", bo, bo->ref_cnt);
685 + drm_slp_bo_unref(bo);
689 + LIST_DEL(&bufmgr->link);
690 + bufmgr->bufmgr_destroy(bufmgr);
692 + if(bufmgr->semObj.isOpened)
694 + _sem_close(bufmgr);
697 + pthread_mutex_destroy(&bufmgr->lock);
702 +drm_slp_bufmgr_lock(drm_slp_bufmgr bufmgr)
704 + DRM_RETURN_VAL_IF_FAIL(MGR_IS_VALID(bufmgr), 0);
706 + pthread_mutex_lock(&bufmgr->lock);
708 + if(bufmgr->bufmgr_lock)
711 + ret = bufmgr->bufmgr_lock(bufmgr);
712 + pthread_mutex_unlock(&bufmgr->lock);
716 + if(!bufmgr->semObj.isOpened)
718 + if(_sem_open(bufmgr) != 1)
720 + pthread_mutex_unlock(&bufmgr->lock);
723 + bufmgr->semObj.isOpened = 1;
726 + if(_sem_lock(bufmgr) != 1)
728 + pthread_mutex_unlock(&bufmgr->lock);
732 + pthread_mutex_unlock(&bufmgr->lock);
738 +drm_slp_bufmgr_unlock(drm_slp_bufmgr bufmgr)
740 + DRM_RETURN_VAL_IF_FAIL(MGR_IS_VALID(bufmgr), 0);
742 + pthread_mutex_lock(&bufmgr->lock);
744 + if(bufmgr->bufmgr_unlock)
747 + ret = bufmgr->bufmgr_unlock(bufmgr);
748 + pthread_mutex_unlock(&bufmgr->lock);
752 + if(_sem_unlock(bufmgr) != 1)
754 + pthread_mutex_unlock(&bufmgr->lock);
758 + pthread_mutex_unlock(&bufmgr->lock);
764 +drm_slp_bufmgr_cache_flush(drm_slp_bufmgr bufmgr, drm_slp_bo bo, int flags)
768 + DRM_RETURN_VAL_IF_FAIL(MGR_IS_VALID(bufmgr) || BO_IS_VALID(bo), 0);
771 + flags |= DRM_SLP_CACHE_ALL;
775 + DRM_RETURN_VAL_IF_FAIL(BO_IS_VALID(bo), 0);
780 + pthread_mutex_lock(&bo->bufmgr->lock);
781 + ret = bo->bufmgr->bufmgr_cache_flush(bufmgr, bo, flags);
782 + pthread_mutex_unlock(&bo->bufmgr->lock);
786 + pthread_mutex_lock(&bufmgr->lock);
787 + ret = bufmgr->bufmgr_cache_flush(bufmgr, NULL, flags);
788 + pthread_mutex_unlock(&bufmgr->lock);
795 +drm_slp_bo_size(drm_slp_bo bo)
798 + drm_slp_bufmgr bufmgr;
800 + DRM_RETURN_VAL_IF_FAIL(BO_IS_VALID(bo), 0);
802 + bufmgr = bo->bufmgr;
804 + pthread_mutex_lock(&bufmgr->lock);
805 + size = bo->bufmgr->bo_size(bo);
806 + pthread_mutex_unlock(&bufmgr->lock);
812 +drm_slp_bo_ref(drm_slp_bo bo)
814 + drm_slp_bufmgr bufmgr;
816 + DRM_RETURN_VAL_IF_FAIL(BO_IS_VALID(bo), NULL);
818 + bufmgr = bo->bufmgr;
820 + pthread_mutex_lock(&bufmgr->lock);
824 + pthread_mutex_unlock(&bufmgr->lock);
830 +drm_slp_bo_unref(drm_slp_bo bo)
832 + drm_slp_bufmgr bufmgr;
834 + DRM_RETURN_IF_FAIL(BO_IS_VALID(bo));
836 + bufmgr = bo->bufmgr;
838 + if(0 >= bo->ref_cnt)
841 + pthread_mutex_lock(&bufmgr->lock);
844 + if(bo->ref_cnt == 0)
849 + drm_slp_user_data* old_data;
852 + while(1==drmSLFirst(bo->user_data, &key, &rd))
854 + old_data = (drm_slp_user_data*)rd;
856 + if(old_data->is_valid && old_data->free_func)
859 + old_data->free_func(old_data->data);
860 + old_data->data = NULL;
863 + drmSLDelete(bo->user_data, key);
866 + drmSLDestroy(bo->user_data);
867 + bo->user_data = (void*)0;
870 + LIST_DEL(&bo->list);
871 + bufmgr->bo_free(bo);
876 + pthread_mutex_unlock(&bufmgr->lock);
880 +drm_slp_bo_alloc(drm_slp_bufmgr bufmgr, const char * name, int size, int flags)
882 + drm_slp_bo bo=NULL;
884 + DRM_RETURN_VAL_IF_FAIL( MGR_IS_VALID(bufmgr) && (size > 0), NULL);
886 + bo = calloc(sizeof(struct _drm_slp_bo), 1);
890 + bo->bufmgr = bufmgr;
892 + pthread_mutex_lock(&bufmgr->lock);
893 + if(!bufmgr->bo_alloc(bo, name, size, flags))
896 + pthread_mutex_unlock(&bufmgr->lock);
900 + LIST_ADD(&bo->list, &bufmgr->bos);
901 + pthread_mutex_unlock(&bufmgr->lock);
907 +drm_slp_bo_attach(drm_slp_bufmgr bufmgr,
911 + unsigned int handle)
915 + DRM_RETURN_VAL_IF_FAIL(MGR_IS_VALID(bufmgr), NULL);
917 + bo = calloc(sizeof(struct _drm_slp_bo), 1);
921 + bo->bufmgr = bufmgr;
923 + pthread_mutex_lock(&bufmgr->lock);
924 + if(!bufmgr->bo_attach(bo, name, type, size, handle))
927 + pthread_mutex_unlock(&bufmgr->lock);
931 + LIST_ADD(&bo->list, &bufmgr->bos);
932 + pthread_mutex_unlock(&bufmgr->lock);
938 +drm_slp_bo_import(drm_slp_bufmgr bufmgr, unsigned int key)
942 + DRM_RETURN_VAL_IF_FAIL(MGR_IS_VALID(bufmgr), NULL);
944 + bo = calloc(sizeof(struct _drm_slp_bo), 1);
948 + bo->bufmgr = bufmgr;
950 + pthread_mutex_lock(&bufmgr->lock);
951 + if(!bufmgr->bo_import(bo, key))
954 + pthread_mutex_unlock(&bufmgr->lock);
958 + LIST_ADD(&bo->list, &bufmgr->bos);
959 + pthread_mutex_unlock(&bufmgr->lock);
965 +drm_slp_bo_export(drm_slp_bo bo)
969 + DRM_RETURN_VAL_IF_FAIL(BO_IS_VALID(bo), 0);
971 + pthread_mutex_lock(&bo->bufmgr->lock);
972 + ret = bo->bufmgr->bo_export(bo);
973 + pthread_mutex_unlock(&bo->bufmgr->lock);
979 +drm_slp_bo_get_handle(drm_slp_bo bo, int device)
983 + DRM_RETURN_VAL_IF_FAIL(BO_IS_VALID(bo), 0);
985 + pthread_mutex_lock(&bo->bufmgr->lock);
986 + ret = bo->bufmgr->bo_get_handle(bo, device);
987 + pthread_mutex_unlock(&bo->bufmgr->lock);
993 +drm_slp_bo_map(drm_slp_bo bo, int device, int opt)
997 + DRM_RETURN_VAL_IF_FAIL(BO_IS_VALID(bo), 0);
999 + pthread_mutex_lock(&bo->bufmgr->lock);
1000 + if(bo->bufmgr->bo_lock)
1002 + bo->bufmgr->bo_lock(bo, 0, (void*)0);
1005 + ret = bo->bufmgr->bo_map(bo, device, opt);
1006 + pthread_mutex_unlock(&bo->bufmgr->lock);
1012 +drm_slp_bo_unmap(drm_slp_bo bo, int device)
1016 + DRM_RETURN_VAL_IF_FAIL(BO_IS_VALID(bo), 0);
1018 + pthread_mutex_lock(&bo->bufmgr->lock);
1019 + ret = bo->bufmgr->bo_unmap(bo, device);
1021 + if(bo->bufmgr->bo_unlock)
1023 + bo->bufmgr->bo_unlock(bo);
1025 + pthread_mutex_unlock(&bo->bufmgr->lock);
1031 +drm_slp_bo_swap(drm_slp_bo bo1, drm_slp_bo bo2)
1035 + DRM_RETURN_VAL_IF_FAIL(BO_IS_VALID(bo1), 0);
1036 + DRM_RETURN_VAL_IF_FAIL(BO_IS_VALID(bo2), 0);
1038 + if(bo1->bufmgr->bo_size(bo1) != bo2->bufmgr->bo_size(bo2))
1041 + pthread_mutex_lock(&bo1->bufmgr->lock);
1043 + bo1->priv = bo2->priv;
1045 + pthread_mutex_unlock(&bo1->bufmgr->lock);
1051 +drm_slp_bo_add_user_data(drm_slp_bo bo, unsigned long key, drm_data_free data_free_func)
1054 + drm_slp_user_data* data;
1056 + DRM_RETURN_VAL_IF_FAIL(BO_IS_VALID(bo), 0);
1058 + if(!bo->user_data)
1059 + bo->user_data = drmSLCreate();
1061 + data = calloc(1, sizeof(drm_slp_user_data));
1065 + data->free_func = data_free_func;
1066 + data->data = (void*)0;
1067 + data->is_valid = 0;
1069 + ret = drmSLInsert(bo->user_data, key, data);
1070 + if(ret == 1) /* Already in list */
1080 +drm_slp_bo_set_user_data(drm_slp_bo bo, unsigned long key, void* data)
1083 + drm_slp_user_data* old_data;
1085 + DRM_RETURN_VAL_IF_FAIL(BO_IS_VALID(bo), 0);
1087 + if(!bo->user_data)
1090 + if(drmSLLookup(bo->user_data, key, &rd))
1093 + old_data = (drm_slp_user_data*)rd;
1097 + if(old_data->is_valid)
1099 + if(old_data->free_func)
1101 + if(old_data->data)
1102 + old_data->free_func(old_data->data);
1103 + old_data->data = NULL;
1107 + old_data->is_valid = 1;
1109 + old_data->data = data;
1115 +drm_slp_bo_get_user_data(drm_slp_bo bo, unsigned long key, void** data)
1118 + drm_slp_user_data* old_data;
1120 + DRM_RETURN_VAL_IF_FAIL(BO_IS_VALID(bo) && data && bo->user_data, 0);
1122 + if(drmSLLookup(bo->user_data, key, &rd))
1128 + old_data = (drm_slp_user_data*)rd;
1135 + *data = old_data->data;
1141 +drm_slp_bo_delete_user_data(drm_slp_bo bo, unsigned long key)
1144 + drm_slp_user_data* old_data=(void*)0;
1146 + DRM_RETURN_VAL_IF_FAIL(BO_IS_VALID(bo) && bo->user_data, 0);
1148 + if(drmSLLookup(bo->user_data, key, &rd))
1151 + old_data = (drm_slp_user_data*)rd;
1155 + if(old_data->is_valid && old_data->free_func)
1157 + if(old_data->data)
1158 + old_data->free_func(old_data->data);
1161 + drmSLDelete(bo->user_data, key);
1165 diff --git a/slp/drm_slp_bufmgr.h b/slp/drm_slp_bufmgr.h
1166 new file mode 100644
1167 index 0000000..a4adef5
1169 +++ b/slp/drm_slp_bufmgr.h
1171 +/**************************************************************************
1173 +xserver-xorg-video-sec
1175 +Copyright 2011 Samsung Electronics co., Ltd. All Rights Reserved.
1177 +Contact: SooChan Lim <sc1.lim@samsung.com>, Sangjin Lee <lsj119@samsung.com>
1179 +Permission is hereby granted, free of charge, to any person obtaining a
1180 +copy of this software and associated documentation files (the
1181 +"Software"), to deal in the Software without restriction, including
1182 +without limitation the rights to use, copy, modify, merge, publish,
1183 +distribute, sub license, and/or sell copies of the Software, and to
1184 +permit persons to whom the Software is furnished to do so, subject to
1185 +the following conditions:
1187 +The above copyright notice and this permission notice (including the
1188 +next paragraph) shall be included in all copies or substantial portions
1191 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
1192 +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
1193 +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
1194 +IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
1195 +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
1196 +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
1197 +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1199 +**************************************************************************/
1201 +#ifndef _DRM_SLP_BUFMGR_H_
1202 +#define _DRM_SLP_BUFMGR_H_
1204 +#include <semaphore.h>
1205 +#include <pthread.h>
1206 +#include <xf86drm.h>
1208 +typedef struct _drm_slp_bo * drm_slp_bo;
1209 +typedef struct _drm_slp_bufmgr * drm_slp_bufmgr;
1213 + struct list_head *prev;
1214 + struct list_head *next;
1219 + struct list_head list;
1220 + drm_slp_bufmgr bufmgr;
1221 + int ref_cnt; /*atomic count*/
1224 + /* private data */
1231 + STATUS_READY_TO_LOCK,
1235 +struct _drm_slp_bufmgr
1237 + struct list_head bos; /*list head of bo*/
1239 + pthread_mutex_t lock;
1242 + lock_status status;
1246 + void (*bufmgr_destroy)(drm_slp_bufmgr bufmgr);
1247 + int (*bufmgr_cache_flush)(drm_slp_bufmgr bufmgr, drm_slp_bo bo, int flags);
1249 + int (*bo_size)(drm_slp_bo bo);
1251 + void (*bo_free)(drm_slp_bo bo);
1252 + int (*bo_alloc)(drm_slp_bo bo,
1256 + int (*bo_attach)(drm_slp_bo bo,
1260 + unsigned int handle);
1261 + int (*bo_import)(drm_slp_bo bo, unsigned int key);
1262 + unsigned int (*bo_export)(drm_slp_bo bo);
1264 + unsigned int (*bo_get_handle)(drm_slp_bo bo, int device);
1265 + unsigned int (*bo_map)(drm_slp_bo bo, int device, int opt);
1266 + int (*bo_unmap)(drm_slp_bo bo, int device);
1269 + /* Padding for future extension */
1270 + int (*bufmgr_lock) (drm_slp_bufmgr bufmgr);
1271 + int (*bufmgr_unlock) (drm_slp_bufmgr bufmgr);
1272 + int (*bo_lock) (drm_slp_bo bo, unsigned int checkOnly, unsigned int* isLocked);
1273 + int (*bo_unlock) (drm_slp_bo bo);
1274 + void (*reserved5) (void);
1275 + void (*reserved6) (void);
1277 + /* private data */
1280 + struct list_head link; /*link of bufmgr*/
1286 +/* DRM_SLP_MEM_TYPE */
1287 +#define DRM_SLP_MEM_GEM 0
1288 +#define DRM_SLP_MEM_USERPTR 1
1289 +#define DRM_SLP_MEM_DMABUF 2
1290 +#define DRM_SLP_MEM_GPU 3
1292 +/* DRM_SLP_DEVICE_TYPE */
1293 +#define DRM_SLP_DEVICE_DEFAULT 0 //Default handle
1294 +#define DRM_SLP_DEVICE_CPU 1
1295 +#define DRM_SLP_DEVICE_2D 2
1296 +#define DRM_SLP_DEVICE_3D 3
1297 +#define DRM_SLP_DEVICE_MM 4
1299 +/* DRM_SLP_OPTION */
1300 +#define DRM_SLP_OPTION_READ (1 << 0)
1301 +#define DRM_SLP_OPTION_WRITE (1 << 1)
1303 +/* DRM_SLP_CACHE */
1304 +#define DRM_SLP_CACHE_INV 0x01
1305 +#define DRM_SLP_CACHE_CLN 0x02
1306 +#define DRM_SLP_CACHE_ALL 0x10
1307 +#define DRM_SLP_CACHE_FLUSH (DRM_SLP_CACHE_INV|DRM_SLP_CACHE_CLN)
1308 +#define DRM_SLP_CACHE_FLUSH_ALL (DRM_SLP_CACHE_FLUSH|DRM_SLP_CACHE_ALL)
1310 +enum DRM_SLP_BO_FLAGS{
1311 + DRM_SLP_BO_DEFAULT = 0,
1312 + DRM_SLP_BO_SCANOUT = (1<<0),
1313 + DRM_SLP_BO_NONCACHABLE = (1<<1),
1314 + DRM_SLP_BO_WC = (1<<2),
1317 +/* Functions for buffer mnager */
1319 +drm_slp_bufmgr_init(int fd, void * arg);
1321 +drm_slp_bufmgr_destroy(drm_slp_bufmgr bufmgr);
1323 +drm_slp_bufmgr_lock(drm_slp_bufmgr bufmgr);
1325 +drm_slp_bufmgr_unlock(drm_slp_bufmgr bufmgr);
1327 +drm_slp_bufmgr_cache_flush(drm_slp_bufmgr bufmgr, drm_slp_bo bo, int flags);
1330 +/*Functions for bo*/
1332 +drm_slp_bo_size (drm_slp_bo bo);
1334 +drm_slp_bo_ref(drm_slp_bo bo);
1336 +drm_slp_bo_unref(drm_slp_bo bo);
1338 +drm_slp_bo_alloc(drm_slp_bufmgr bufmgr,
1343 +drm_slp_bo_attach(drm_slp_bufmgr bufmgr,
1347 + unsigned int handle);
1349 +drm_slp_bo_import(drm_slp_bufmgr bufmgr, unsigned int key);
1351 +drm_slp_bo_export(drm_slp_bo bo);
1353 +drm_slp_bo_get_handle(drm_slp_bo, int device);
1355 +drm_slp_bo_map(drm_slp_bo bo, int device, int opt);
1357 +drm_slp_bo_unmap(drm_slp_bo bo, int device);
1359 +drm_slp_bo_swap(drm_slp_bo bo1, drm_slp_bo bo2);
1361 +/*Functions for userdata of bo*/
1362 +typedef void (*drm_data_free)(void *);
1364 +drm_slp_bo_add_user_data(drm_slp_bo bo, unsigned long key, drm_data_free data_free_func);
1366 +drm_slp_bo_delete_user_data(drm_slp_bo bo, unsigned long key);
1368 +drm_slp_bo_set_user_data(drm_slp_bo bo, unsigned long key, void* data);
1370 +drm_slp_bo_get_user_data(drm_slp_bo bo, unsigned long key, void** data);
1371 +#endif /* _DRM_SLP_BUFMGR_H_ */
1372 diff --git a/slp/libdrm_slp.pc.in b/slp/libdrm_slp.pc.in
1373 new file mode 100644
1374 index 0000000..220d38b
1376 +++ b/slp/libdrm_slp.pc.in
1379 +exec_prefix=@exec_prefix@
1381 +includedir=@includedir@
1384 +Description: Userspace interface to kernel DRM services
1385 +Version: @PACKAGE_VERSION@
1387 +Libs: -L${libdir} -ldrm_slp
1388 +Cflags: -I${includedir} -I${includedir}/libdrm
1389 diff --git a/slp/list.h b/slp/list.h
1390 new file mode 100644
1391 index 0000000..e967b93
1397 + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND. USA.
1398 + * All Rights Reserved.
1400 + * Permission is hereby granted, free of charge, to any person obtaining a
1401 + * copy of this software and associated documentation files (the
1402 + * "Software"), to deal in the Software without restriction, including
1403 + * without limitation the rights to use, copy, modify, merge, publish,
1404 + * distribute, sub license, and/or sell copies of the Software, and to
1405 + * permit persons to whom the Software is furnished to do so, subject to
1406 + * the following conditions:
1408 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1409 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1410 + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
1411 + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
1412 + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
1413 + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
1414 + * USE OR OTHER DEALINGS IN THE SOFTWARE.
1416 + * The above copyright notice and this permission notice (including the
1417 + * next paragraph) shall be included in all copies or substantial portions
1418 + * of the Software.
1424 + * List macros heavily inspired by the Linux kernel
1425 + * list handling. No list looping yet.
1427 + * Is not threadsafe, so common operations need to
1428 + * be protected using an external mutex.
1430 +#ifndef _U_DOUBLE_LIST_H_
1431 +#define _U_DOUBLE_LIST_H_
1433 +#include <stddef.h>
1435 +static void list_inithead(struct list_head *item)
1437 + item->prev = item;
1438 + item->next = item;
1441 +static inline void list_add(struct list_head *item, struct list_head *list)
1443 + item->prev = list;
1444 + item->next = list->next;
1445 + list->next->prev = item;
1446 + list->next = item;
1449 +static inline void list_addtail(struct list_head *item, struct list_head *list)
1451 + item->next = list;
1452 + item->prev = list->prev;
1453 + list->prev->next = item;
1454 + list->prev = item;
1457 +static inline void list_replace(struct list_head *from, struct list_head *to)
1459 + to->prev = from->prev;
1460 + to->next = from->next;
1461 + from->next->prev = to;
1462 + from->prev->next = to;
1465 +static inline void list_del(struct list_head *item)
1467 + item->prev->next = item->next;
1468 + item->next->prev = item->prev;
1471 +static inline void list_delinit(struct list_head *item)
1473 + item->prev->next = item->next;
1474 + item->next->prev = item->prev;
1475 + item->next = item;
1476 + item->prev = item;
1479 +#define LIST_INITHEAD(__item) list_inithead(__item)
1480 +#define LIST_ADD(__item, __list) list_add(__item, __list)
1481 +#define LIST_ADDTAIL(__item, __list) list_addtail(__item, __list)
1482 +#define LIST_REPLACE(__from, __to) list_replace(__from, __to)
1483 +#define LIST_DEL(__item) list_del(__item)
1484 +#define LIST_DELINIT(__item) list_delinit(__item)
1486 +#define LIST_ENTRY(__type, __item, __field) \
1487 + ((__type *)(((char *)(__item)) - offsetof(__type, __field)))
1489 +#define LIST_IS_EMPTY(__list) \
1490 + ((__list)->next == (__list))
1492 +#ifndef container_of
1493 +#define container_of(ptr, sample, member) \
1494 + (void *)((char *)(ptr) \
1495 + - ((char *)&(sample)->member - (char *)(sample)))
1498 +#define LIST_FOR_EACH_ENTRY(pos, head, member) \
1499 + for (pos = container_of((head)->next, pos, member); \
1500 + &pos->member != (head); \
1501 + pos = container_of(pos->member.next, pos, member))
1503 +#define LIST_FOR_EACH_ENTRY_SAFE(pos, storage, head, member) \
1504 + for (pos = container_of((head)->next, pos, member), \
1505 + storage = container_of(pos->member.next, pos, member); \
1506 + &pos->member != (head); \
1507 + pos = storage, storage = container_of(storage->member.next, storage, member))
1509 +#define LIST_FOR_EACH_ENTRY_SAFE_REV(pos, storage, head, member) \
1510 + for (pos = container_of((head)->prev, pos, member), \
1511 + storage = container_of(pos->member.prev, pos, member); \
1512 + &pos->member != (head); \
1513 + pos = storage, storage = container_of(storage->member.prev, storage, member))
1515 +#define LIST_FOR_EACH_ENTRY_FROM(pos, start, head, member) \
1516 + for (pos = container_of((start), pos, member); \
1517 + &pos->member != (head); \
1518 + pos = container_of(pos->member.next, pos, member))
1520 +#define LIST_FOR_EACH_ENTRY_FROM_REV(pos, start, head, member) \
1521 + for (pos = container_of((start), pos, member); \
1522 + &pos->member != (head); \
1523 + pos = container_of(pos->member.prev, pos, member))
1525 +#endif /*_U_DOUBLE_LIST_H_*/