diff --git a/hybris/android-headers-4.4/APKBUILD b/hybris/android-headers-4.4/APKBUILD new file mode 100644 index 000000000..96a067b3e --- /dev/null +++ b/hybris/android-headers-4.4/APKBUILD @@ -0,0 +1,29 @@ +pkgname=android-headers-4.4 +_pkgname=android-headers +pkgver=4.4_git20171022 +_pkgver=4.4 +pkgrel=0 +arch="noarch" +url="https://github.com/ubports/android-headers" +license="Apache" +makedepends="" +depends="" +_rev=f636fa26a61b36bef284a7aeba95eb767344b8b4 +source="$pkgname-$_rev.tar.gz::https://github.com/ubports/android-headers/archive/$_rev.tar.gz + android-headers.pc" +pkgdesc="Android headers used for building libhybris" +options="!check" + +builddir="$srcdir/$_pkgname-$_rev" + +package() { + cd "$builddir" + + mkdir -p "${pkgdir}/usr/include" + cp -r "$builddir/19" "${pkgdir}/usr/include/android-$_pkgver" + + install -Dm644 "$srcdir/android-headers.pc" "${pkgdir}/usr/lib/pkgconfig/android-headers-$_pkgver.pc" +} + +sha512sums="c146753908ae0dd9aca0138a0a63e8578d65200d6d9b5154b846a0ac3309d9e33f6edddd92cd420e7b7dcaf73630546eb1bd45927cf8b4921f67dec7db7bb55c android-headers-4.4-f636fa26a61b36bef284a7aeba95eb767344b8b4.tar.gz +331f2670da9ce2690225694196265a55e2f41c35a1a12b71a75de3478b3b266c215be9bd451ab5ea13d4802e9f7d4e1bab8aa006d0df81fc264b2a132a022640 android-headers.pc" diff --git a/hybris/android-headers-4.4/android-headers.pc b/hybris/android-headers-4.4/android-headers.pc new file mode 100644 index 000000000..5c6338d05 --- /dev/null +++ b/hybris/android-headers-4.4/android-headers.pc @@ -0,0 +1,9 @@ +Name: Android header files +Description: Header files needed to write applications for the Android platform +Version: 4.4 + +prefix=/usr +exec_prefix=${prefix} +includedir=${prefix}/include + +Cflags: -I${includedir}/android-4.4 diff --git a/hybris/android-headers-7.1/APKBUILD b/hybris/android-headers-7.1/APKBUILD new file mode 100644 index 000000000..554dd502c --- /dev/null +++ b/hybris/android-headers-7.1/APKBUILD @@ -0,0 +1,39 @@ +pkgname=android-headers-7.1 +_pkgname=android-headers +pkgver=7.1_git20170630 +_pkgver=7.1 +pkgrel=0 +arch="noarch" +url="https://github.com/Halium/android-headers" +license="Apache" +makedepends="" +depends="" +_rev=1f6591ba7d42b91c32acf5a65a2a4fae983d6865 +source="$pkgname-$_rev.tar.gz::https://github.com/Halium/android-headers/archive/$_rev.tar.gz" +pkgdesc="Android headers used for building libhybris" +subpackages="$pkgname-caf:package_caf" + +builddir="$srcdir/$_pkgname-$_rev" + +package() { + cd "$builddir" + make PREFIX=/usr DESTDIR="${pkgdir}" install + + mv ${pkgdir}/usr/include/android ${pkgdir}/usr/include/android-$_pkgver + sed -i "s~${includedir}/android~${includedir}/android-$_pkgver~g" ${pkgdir}/usr/lib/pkgconfig/android-headers.pc + mv "${pkgdir}/usr/lib/pkgconfig/android-headers.pc" "${pkgdir}/usr/lib/pkgconfig/android-headers-$_pkgver.pc" +} + + +package_caf() { + cd "$builddir" + + sed -i 's~/\* CONFIG GOES HERE \*/~#define QCOM_BSP 1\n#define QTI_BSP 1~g' android-config.h + make PREFIX=/usr DESTDIR="${subpkgdir}" install + + mv ${subpkgdir}/usr/include/android ${subpkgdir}/usr/include/android-$_pkgver-caf + sed -i "s~${includedir}/android~${includedir}/android-$_pkgver-caf~g" ${subpkgdir}/usr/lib/pkgconfig/android-headers.pc + mv "${subpkgdir}/usr/lib/pkgconfig/android-headers.pc" "${subpkgdir}/usr/lib/pkgconfig/android-headers-$_pkgver-caf.pc" +} + +sha512sums="652641b469f7faf90c7adf03b14047f9eb24fdb190d9ab131d72f73b2d9357aad80cad48867ede66b0a737661cfb9e26fb4583b9fed15b8d6d667fe53ea14419 android-headers-7.1-1f6591ba7d42b91c32acf5a65a2a4fae983d6865.tar.gz" diff --git a/hybris/libhybris/0001-Make-libhybris-compile-with-musl.patch b/hybris/libhybris/0001-Make-libhybris-compile-with-musl.patch new file mode 100644 index 000000000..250116e08 --- /dev/null +++ b/hybris/libhybris/0001-Make-libhybris-compile-with-musl.patch @@ -0,0 +1,592 @@ +From 98b46a48875cedf8af2445be63f196b6fe9b8648 Mon Sep 17 00:00:00 2001 +From: NeKit +Date: Wed, 1 Nov 2017 15:39:45 +0300 +Subject: [PATCH 1/3] Make libhybris compile with musl + +Hooks for some functions had to be disabled due to musl not having/exposing +them, which might lead to problems depending on how musl/bionic are +(in)compatible. +--- + hybris/common/hooks.c | 44 ++++++++++++++++++++++ + hybris/common/hooks_shm.c | 4 ++ + hybris/common/jb/dlfcn.c | 4 ++ + hybris/common/mm/bionic/libc/include/link.h | 1 + + .../common/mm/bionic/libc/private/libc_logging.h | 13 +++++++ + hybris/common/mm/dlfcn.cpp | 4 ++ + hybris/common/mm/hybris_compat.h | 11 ++++++ + hybris/common/mm/linker.cpp | 11 ++++++ + hybris/common/n/bionic/libc/include/dlfcn.h | 4 +- + hybris/common/n/bionic/libc/include/link.h | 1 + + hybris/common/n/bionic/libc/private/libc_logging.h | 15 +++++++- + hybris/common/n/dlfcn.cpp | 4 ++ + hybris/common/n/hybris_compat.cpp | 8 ++++ + hybris/common/n/hybris_compat.h | 22 +++++++++++ + hybris/include/hybris/common/musl_compat.h | 10 +++++ + hybris/properties/properties.c | 3 ++ + hybris/tests/test_camera.c | 4 ++ + 17 files changed, 160 insertions(+), 3 deletions(-) + create mode 100644 hybris/include/hybris/common/musl_compat.h + +diff --git a/hybris/common/hooks.c b/hybris/common/hooks.c +index 3b21d74..01e1f3e 100644 +--- a/hybris/common/hooks.c ++++ b/hybris/common/hooks.c +@@ -73,6 +73,10 @@ + #include + #include + ++#ifndef __GLIBC__ ++#include ++#endif ++ + #include + + #ifdef WANT_ARM_TRACING +@@ -504,6 +508,7 @@ static int _hybris_hook_pthread_attr_getstacksize(pthread_attr_t const *__attr, + return pthread_attr_getstacksize(realattr, stack_size); + } + ++#ifdef __GLIBC__ + static int _hybris_hook_pthread_attr_setstackaddr(pthread_attr_t *__attr, void *stack_addr) + { + pthread_attr_t *realattr = (pthread_attr_t *) *(uintptr_t *) __attr; +@@ -521,6 +526,7 @@ static int _hybris_hook_pthread_attr_getstackaddr(pthread_attr_t const *__attr, + + return pthread_attr_getstackaddr(realattr, stack_addr); + } ++#endif + + static int _hybris_hook_pthread_attr_setstack(pthread_attr_t *__attr, void *stack_base, size_t stack_size) + { +@@ -1107,6 +1113,7 @@ static int _hybris_hook_pthread_rwlockattr_getpshared(pthread_rwlockattr_t *__at + return pthread_rwlockattr_getpshared(realattr, pshared); + } + ++#ifdef __GLIBC__ + int _hybris_hook_pthread_rwlockattr_setkind_np(pthread_rwlockattr_t *attr, int pref) + { + pthread_rwlockattr_t *realattr = (pthread_rwlockattr_t *) *(uintptr_t *) attr; +@@ -1124,6 +1131,7 @@ int _hybris_hook_pthread_rwlockattr_getkind_np(const pthread_rwlockattr_t *attr, + + return pthread_rwlockattr_getkind_np(realattr, pref); + } ++#endif + + /* + * pthread_rwlock_* functions +@@ -1443,10 +1451,14 @@ static int _hybris_hook_fgetpos(FILE *fp, bionic_fpos_t *pos) + { + TRACE_HOOK("fp %p pos %p", fp, pos); + ++#ifdef __GLIBC__ + fpos_t my_fpos; + int ret = fgetpos(_get_actual_fp(fp), &my_fpos); + + *pos = my_fpos.__pos; ++#else ++ int ret = fgetpos(_get_actual_fp(fp), pos); ++#endif + + return ret; + } +@@ -1532,12 +1544,16 @@ static int _hybris_hook_fsetpos(FILE *fp, const bionic_fpos_t *pos) + { + TRACE_HOOK("fp %p pos %p", fp, pos); + ++#ifdef __GLIBC__ + fpos_t my_fpos; + my_fpos.__pos = *pos; + memset(&my_fpos.__state, 0, sizeof(mbstate_t)); + mbsinit(&my_fpos.__state); + + return fsetpos(_get_actual_fp(fp), &my_fpos); ++#else ++ return fsetpos(_get_actual_fp(fp), pos); ++#endif + } + + static long _hybris_hook_ftell(FILE *fp) +@@ -1815,6 +1831,7 @@ static int _hybris_hook_versionsort(struct bionic_dirent **a, + return strverscmp((*a)->d_name, (*b)->d_name); + } + ++#ifdef __GLIBC__ + static int _hybris_hook_scandirat(int fd, const char *dir, + struct bionic_dirent ***namelist, + int (*filter) (const struct bionic_dirent *), +@@ -1876,6 +1893,7 @@ static int _hybris_hook_scandir(const char *dir, + { + return _hybris_hook_scandirat(AT_FDCWD, dir, namelist, filter, compar); + } ++#endif + + static inline void swap(void **a, void **b) + { +@@ -2125,6 +2143,7 @@ int _hybris_hook_open(const char *pathname, int flags, ...) + return open(target_path, flags, mode); + } + ++#ifdef __GLIBC__ + /** + * Wrap some GCC builtin functions, which don't have any address + */ +@@ -2150,6 +2169,7 @@ __THROW int _hybris_hook___snprintf_chk (char *__restrict __s, size_t __n, int _ + + return ret; + } ++#endif + + static __thread void *tls_hooks[16]; + +@@ -2295,6 +2315,7 @@ static char* _hybris_hook_setlocale(int category, const char *locale) + return setlocale(category, locale); + } + ++#ifdef __GLIBC__ + static void* _hybris_hook_mmap(void *addr, size_t len, int prot, + int flags, int fd, off_t offset) + { +@@ -2310,6 +2331,7 @@ static int _hybris_hook_munmap(void *addr, size_t length) + + return munmap(addr, length); + } ++#endif + + extern size_t strlcat(char *dst, const char *src, size_t siz); + extern size_t strlcpy(char *dst, const char *src, size_t siz); +@@ -2463,7 +2485,9 @@ static struct _hook hooks_common[] = { + HOOK_DIRECT_NO_DEBUG(realloc), + HOOK_DIRECT_NO_DEBUG(memalign), + HOOK_DIRECT_NO_DEBUG(valloc), ++#ifdef __GLIBC__ + HOOK_DIRECT_NO_DEBUG(pvalloc), ++#endif + HOOK_DIRECT(fread), + HOOK_DIRECT_NO_DEBUG(getxattr), + HOOK_DIRECT(mprotect), +@@ -2513,8 +2537,10 @@ static struct _hook hooks_common[] = { + HOOK_DIRECT_NO_DEBUG(bcopy), + HOOK_DIRECT_NO_DEBUG(bzero), + HOOK_DIRECT_NO_DEBUG(ffs), ++#ifdef __GLIBC__ + HOOK_INDIRECT(__sprintf_chk), + HOOK_INDIRECT(__snprintf_chk), ++#endif + /* pthread.h */ + HOOK_DIRECT_NO_DEBUG(getauxval), + HOOK_INDIRECT(gettid), +@@ -2573,8 +2599,10 @@ static struct _hook hooks_common[] = { + HOOK_INDIRECT(pthread_attr_getschedparam), + HOOK_INDIRECT(pthread_attr_setstacksize), + HOOK_INDIRECT(pthread_attr_getstacksize), ++#ifdef __GLIBC__ + HOOK_INDIRECT(pthread_attr_setstackaddr), + HOOK_INDIRECT(pthread_attr_getstackaddr), ++#endif + HOOK_INDIRECT(pthread_attr_setstack), + HOOK_INDIRECT(pthread_attr_getstack), + HOOK_INDIRECT(pthread_attr_setguardsize), +@@ -2682,8 +2710,10 @@ static struct _hook hooks_common[] = { + HOOK_DIRECT_NO_DEBUG(seekdir), + HOOK_DIRECT_NO_DEBUG(telldir), + HOOK_DIRECT_NO_DEBUG(dirfd), ++#ifdef __GLIBC__ + HOOK_INDIRECT(scandir), + HOOK_INDIRECT(scandirat), ++#endif + HOOK_INDIRECT(alphasort), + HOOK_INDIRECT(versionsort), + /* fcntl.h */ +@@ -2707,7 +2737,9 @@ static struct _hook hooks_common[] = { + HOOK_DIRECT_NO_DEBUG(localtime_r), + HOOK_DIRECT_NO_DEBUG(gmtime), + HOOK_DIRECT_NO_DEBUG(abort), ++#ifdef __GLIBC__ + HOOK_DIRECT_NO_DEBUG(writev), ++#endif + /* unistd.h */ + HOOK_DIRECT_NO_DEBUG(access), + /* grp.h */ +@@ -2736,13 +2768,17 @@ static struct _hook hooks_mm[] = { + HOOK_DIRECT(putenv), + HOOK_DIRECT(clearenv), + HOOK_DIRECT_NO_DEBUG(dprintf), ++#ifdef __GLIBC__ + HOOK_DIRECT_NO_DEBUG(mallinfo), ++#endif + HOOK_DIRECT(malloc_usable_size), + HOOK_DIRECT(posix_memalign), + HOOK_DIRECT(mprotect), + HOOK_TO(__gnu_strerror_r, _hybris_hook__gnu_strerror_r), ++#ifdef __GLIBC__ + HOOK_INDIRECT(pthread_rwlockattr_getkind_np), + HOOK_INDIRECT(pthread_rwlockattr_setkind_np), ++#endif + /* unistd.h */ + HOOK_DIRECT(fork), + HOOK_DIRECT_NO_DEBUG(ttyname), +@@ -2764,15 +2800,21 @@ static struct _hook hooks_mm[] = { + HOOK_DIRECT(localeconv), + HOOK_DIRECT(setlocale), + /* sys/mman.h */ ++#ifdef __GLIBC__ ++ // mmap from musl considers offsets from gralloc to be invalid, ++ // so avoid hooking it + HOOK_DIRECT(mmap), + HOOK_DIRECT(munmap), ++#endif + /* wchar.h */ + HOOK_DIRECT_NO_DEBUG(wmemchr), + HOOK_DIRECT_NO_DEBUG(wmemcmp), + HOOK_DIRECT_NO_DEBUG(wmemcpy), + HOOK_DIRECT_NO_DEBUG(wmemmove), + HOOK_DIRECT_NO_DEBUG(wmemset), ++#ifdef __GLIBC__ + HOOK_DIRECT_NO_DEBUG(wmempcpy), ++#endif + HOOK_INDIRECT(fputws), + // It's enough to hook vfwprintf here as fwprintf will call it with a + // proper va_list in place so we don't have to handle this here. +@@ -2826,9 +2868,11 @@ static struct _hook hooks_mm[] = { + /* dirent.h */ + HOOK_TO(readdir64, _hybris_hook_readdir), + HOOK_TO(readdir64_r, _hybris_hook_readdir_r), ++#ifdef __GLIBC__ + HOOK_INDIRECT(scandir), + HOOK_INDIRECT(scandirat), + HOOK_TO(scandir64, _hybris_hook_scandir), ++#endif + }; + + +diff --git a/hybris/common/hooks_shm.c b/hybris/common/hooks_shm.c +index c90cee5..27dfeef 100644 +--- a/hybris/common/hooks_shm.c ++++ b/hybris/common/hooks_shm.c +@@ -33,6 +33,10 @@ + #include + #include + ++#ifndef __GLIBC__ ++#include ++#endif ++ + /* Debug */ + #include "logging.h" + #define LOGD(message, ...) HYBRIS_DEBUG_LOG(HOOKS, message, ##__VA_ARGS__) +diff --git a/hybris/common/jb/dlfcn.c b/hybris/common/jb/dlfcn.c +index 78500e4..6996527 100644 +--- a/hybris/common/jb/dlfcn.c ++++ b/hybris/common/jb/dlfcn.c +@@ -23,6 +23,10 @@ + #include "linker.h" + #include "linker_format.h" + ++#ifndef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ++#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP {{PTHREAD_MUTEX_RECURSIVE}} ++#endif ++ + /* This file hijacks the symbols stubbed out in libdl.so. */ + + #define DL_SUCCESS 0 +diff --git a/hybris/common/mm/bionic/libc/include/link.h b/hybris/common/mm/bionic/libc/include/link.h +index cb8e139..10d105d 100644 +--- a/hybris/common/mm/bionic/libc/include/link.h ++++ b/hybris/common/mm/bionic/libc/include/link.h +@@ -29,6 +29,7 @@ + #define _LINK_H_ + + #include ++#include + #include + + __BEGIN_DECLS +diff --git a/hybris/common/mm/bionic/libc/private/libc_logging.h b/hybris/common/mm/bionic/libc/private/libc_logging.h +index 6beb47e..e526c03 100644 +--- a/hybris/common/mm/bionic/libc/private/libc_logging.h ++++ b/hybris/common/mm/bionic/libc/private/libc_logging.h +@@ -33,6 +33,8 @@ + #include + #include + #include ++#include ++#include + + __BEGIN_DECLS + +@@ -73,7 +75,18 @@ struct abort_msg_t { + // Formats a message to the log (priority 'fatal'), then aborts. + // + ++#ifdef __GLIBC__ + void __libc_fatal(const char* format, ...); ++#else ++void inline __libc_fatal(const char* format, ...) ++{ ++ va_list ap; ++ va_start(ap, format); ++ vfprintf(stderr, format, ap); ++ va_end(ap); ++ abort(); ++} ++#endif + + // + // Formats a message to the log (priority 'fatal'), but doesn't abort. +diff --git a/hybris/common/mm/dlfcn.cpp b/hybris/common/mm/dlfcn.cpp +index 8a8213f..e9f6914 100644 +--- a/hybris/common/mm/dlfcn.cpp ++++ b/hybris/common/mm/dlfcn.cpp +@@ -31,6 +31,10 @@ + + #include "hybris_compat.h" + ++#ifndef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ++#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP {{PTHREAD_MUTEX_RECURSIVE}} ++#endif ++ + #ifdef WANT_ARM_TRACING + #include "../wrappers.h" + #endif +diff --git a/hybris/common/mm/hybris_compat.h b/hybris/common/mm/hybris_compat.h +index 2e10383..de1d852 100644 +--- a/hybris/common/mm/hybris_compat.h ++++ b/hybris/common/mm/hybris_compat.h +@@ -32,6 +32,9 @@ + + #include + #include ++#ifndef __GLIBC__ ++#include ++#endif + + extern "C" size_t strlcpy(char *dest, const char *src, size_t size); + extern "C" size_t strlcat(char *dst, const char *src, size_t size); +@@ -55,4 +58,12 @@ extern "C" size_t strlcat(char *dst, const char *src, size_t size); + #define DT_ANDROID_RELA (DT_LOOS + 4) + #define DT_ANDROID_RELASZ (DT_LOOS + 5) + ++#if defined (__aarch64__) ++ ++#ifndef R_AARCH64_IRELATIVE ++#define R_AARCH64_IRELATIVE 1032 ++#endif ++ ++#endif ++ + #endif +diff --git a/hybris/common/mm/linker.cpp b/hybris/common/mm/linker.cpp +index 10a3853..8fe23b3 100644 +--- a/hybris/common/mm/linker.cpp ++++ b/hybris/common/mm/linker.cpp +@@ -38,6 +38,9 @@ + #include + #include + #include ++#ifndef __GLIBC__ ++#include ++#endif + + #include + #include +@@ -1169,7 +1172,11 @@ static const char* fix_dt_needed(const char* dt_needed, const char* sopath) { + #if !defined(__LP64__) + // Work around incorrect DT_NEEDED entries for old apps: http://b/21364029 + if (get_application_target_sdk_version() <= 22) { ++#ifdef __GLIBC__ + const char* bname = basename(dt_needed); ++#else ++ const char* bname = (const char*) basename((char*)dt_needed); ++#endif + if (bname != dt_needed) { + DL_WARN("'%s' library has invalid DT_NEEDED entry '%s'", sopath, dt_needed); + } +@@ -2900,7 +2907,11 @@ bool soinfo::prelink_image() { + // the main executable and linker; they do not need to have dt_soname + if (soname_ == nullptr && this != somain && (flags_ & FLAG_LINKER) == 0 && + get_application_target_sdk_version() <= 22) { ++#ifdef __GLIBC__ + soname_ = basename(realpath_.c_str()); ++#else ++ soname_ = (const char*) basename((char*) realpath_.c_str()); ++#endif + DL_WARN("%s: is missing DT_SONAME will use basename as a replacement: \"%s\"", + get_realpath(), soname_); + } +diff --git a/hybris/common/n/bionic/libc/include/dlfcn.h b/hybris/common/n/bionic/libc/include/dlfcn.h +index c2e8980..692ce52 100644 +--- a/hybris/common/n/bionic/libc/include/dlfcn.h ++++ b/hybris/common/n/bionic/libc/include/dlfcn.h +@@ -46,8 +46,8 @@ typedef struct { + extern void* dlopen(const char* filename, int flag); + extern int dlclose(void* handle); + extern const char* dlerror(void); +-extern void* dlsym(void* handle, const char* symbol) __nonnull((2)); +-extern void* dlvsym(void* handle, const char* symbol, const char* version) __nonnull((2, 3)); ++extern void* dlsym(void* handle, const char* symbol) __attribute__((nonnull((2)))); ++extern void* dlvsym(void* handle, const char* symbol, const char* version) __attribute__((nonnull((2, 3)))); + extern int dladdr(const void* addr, Dl_info *info); + + enum { +diff --git a/hybris/common/n/bionic/libc/include/link.h b/hybris/common/n/bionic/libc/include/link.h +index cb8e139..10d105d 100644 +--- a/hybris/common/n/bionic/libc/include/link.h ++++ b/hybris/common/n/bionic/libc/include/link.h +@@ -29,6 +29,7 @@ + #define _LINK_H_ + + #include ++#include + #include + + __BEGIN_DECLS +diff --git a/hybris/common/n/bionic/libc/private/libc_logging.h b/hybris/common/n/bionic/libc/private/libc_logging.h +index a696cec..2da0238 100644 +--- a/hybris/common/n/bionic/libc/private/libc_logging.h ++++ b/hybris/common/n/bionic/libc/private/libc_logging.h +@@ -33,6 +33,8 @@ + #include + #include + #include ++#include ++#include + + __BEGIN_DECLS + +@@ -73,7 +75,18 @@ struct abort_msg_t { + // Formats a message to the log (priority 'fatal'), then aborts. + // + +-void __libc_fatal(const char* format, ...); ++#ifdef __GLIBC__ ++ void __libc_fatal(const char* format, ...); ++#else ++void inline __libc_fatal(const char* format, ...) ++{ ++ va_list ap; ++ va_start(ap, format); ++ vfprintf(stderr, format, ap); ++ va_end(ap); ++ abort(); ++} ++#endif + + // + // Formats a message to the log (priority 'fatal'), but doesn't abort. +diff --git a/hybris/common/n/dlfcn.cpp b/hybris/common/n/dlfcn.cpp +index 056f271..91d52ed 100644 +--- a/hybris/common/n/dlfcn.cpp ++++ b/hybris/common/n/dlfcn.cpp +@@ -30,6 +30,10 @@ + + #include "hybris_compat.h" + ++#ifndef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ++#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP {{PTHREAD_MUTEX_RECURSIVE}} ++#endif ++ + /* This file hijacks the symbols stubbed out in libdl.so. */ + + static pthread_mutex_t g_dl_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; +diff --git a/hybris/common/n/hybris_compat.cpp b/hybris/common/n/hybris_compat.cpp +index cfe1e78..5238409 100644 +--- a/hybris/common/n/hybris_compat.cpp ++++ b/hybris/common/n/hybris_compat.cpp +@@ -27,3 +27,11 @@ + */ + + #include "hybris_compat.h" ++ ++#ifndef __GLIBC__ ++const char *gnu_basename(const char *path) ++{ ++ char *base = strrchr(path, '/'); ++ return base ? base + 1 : path; ++} ++#endif +diff --git a/hybris/common/n/hybris_compat.h b/hybris/common/n/hybris_compat.h +index 2e10383..77a0919 100644 +--- a/hybris/common/n/hybris_compat.h ++++ b/hybris/common/n/hybris_compat.h +@@ -32,6 +32,9 @@ + + #include + #include ++#ifndef __GLIBC__ ++#include ++#endif + + extern "C" size_t strlcpy(char *dest, const char *src, size_t size); + extern "C" size_t strlcat(char *dst, const char *src, size_t size); +@@ -55,4 +58,23 @@ extern "C" size_t strlcat(char *dst, const char *src, size_t size); + #define DT_ANDROID_RELA (DT_LOOS + 4) + #define DT_ANDROID_RELASZ (DT_LOOS + 5) + ++#if defined (__aarch64__) ++ ++#ifndef R_AARCH64_TLS_DTPREL32 ++#define R_AARCH64_TLS_DTPREL32 1031 ++#endif ++ ++#ifndef R_AARCH64_IRELATIVE ++#define R_AARCH64_IRELATIVE 1032 ++#endif ++ ++#endif ++ ++#ifndef __GLIBC__ ++#ifndef basename ++const char *gnu_basename(const char *path); ++#define basename gnu_basename ++#endif ++#endif ++ + #endif +diff --git a/hybris/include/hybris/common/musl_compat.h b/hybris/include/hybris/common/musl_compat.h +new file mode 100644 +index 0000000..c5f86f2 +--- /dev/null ++++ b/hybris/include/hybris/common/musl_compat.h +@@ -0,0 +1,10 @@ ++#include ++/* taken from glibc unistd.h and fixes musl */ ++#ifndef TEMP_FAILURE_RETRY ++#define TEMP_FAILURE_RETRY(expression) \ ++ (__extension__ \ ++ ({ long int __result; \ ++ do __result = (long int) (expression); \ ++ while (__result == -1L && errno == EINTR); \ ++ __result; })) ++#endif +diff --git a/hybris/properties/properties.c b/hybris/properties/properties.c +index 55cdda6..ae8bbbc 100644 +--- a/hybris/properties/properties.c ++++ b/hybris/properties/properties.c +@@ -36,6 +36,9 @@ + #include + + #include ++#ifndef __GLIBC__ ++#include ++#endif + #include "properties_p.h" + + +diff --git a/hybris/tests/test_camera.c b/hybris/tests/test_camera.c +index 693a6fb..8f4bc38 100644 +--- a/hybris/tests/test_camera.c ++++ b/hybris/tests/test_camera.c +@@ -40,6 +40,10 @@ + #include + #include + ++#ifndef __GLIBC__ ++#include ++#endif ++ + int shot_counter = 1; + int32_t current_zoom_level = 1; + bool new_camera_frame_available = true; +-- +2.15.1 + diff --git a/hybris/libhybris/0002-tests-Regression-test-for-EGL-glibc-TLS-conflict.patch b/hybris/libhybris/0002-tests-Regression-test-for-EGL-glibc-TLS-conflict.patch new file mode 100644 index 000000000..02703ec44 --- /dev/null +++ b/hybris/libhybris/0002-tests-Regression-test-for-EGL-glibc-TLS-conflict.patch @@ -0,0 +1,75 @@ +From 91f4908067686c28e10894d4bd6042c0a452bf24 Mon Sep 17 00:00:00 2001 +From: Richard Braakman +Date: Wed, 1 Nov 2017 23:35:31 +0300 +Subject: [PATCH 2/3] [tests] Regression test for EGL-glibc TLS conflict bionic + and glibc have different layouts for TLS space. Since libEGL used a bionic + slot directly (in inlined code), libhybris's hooks didn't translate it + properly and libEGL ended up overwriting some unrelated thread-local values + in glibc. + +The problem only showed up when linking with libGLESv2 (which +pulls in libEGL), not when linking with libEGL directly. That's +why the test was added to test_glesv2.c +--- + hybris/tests/test_hwcomposer.cpp | 31 ++++++++++++++++++++++++++++++- + 1 file changed, 30 insertions(+), 1 deletion(-) + +diff --git a/hybris/tests/test_hwcomposer.cpp b/hybris/tests/test_hwcomposer.cpp +index 2253d50..b5d04a4 100644 +--- a/hybris/tests/test_hwcomposer.cpp ++++ b/hybris/tests/test_hwcomposer.cpp +@@ -29,6 +29,23 @@ + #include + #include + ++/* Regression test: make sure that there's no conflict between ++ * the TLS (thread-local storage) slots used via libEGL/bionic ++ * and the TLS space allocated by the host toolchain. The array ++ * declared here should remain unchanged regardless of GL activity. ++ * Since this array is the first __thread storage declared in the main ++ * program, glibc will allocate it before any others. ++ */ ++#define SLOT_FILLER (void *) 0x11122111 /* arbitrary non-zero value */ ++#define S SLOT_FILLER ++__thread void *tls_space[64] = { ++ S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, ++ S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, ++ S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, ++ S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, ++}; ++#undef S ++ + const char vertex_src [] = + " \ + attribute vec4 position; \ +@@ -343,7 +360,7 @@ int main(int argc, char **argv) + glClearColor ( 1. , 1. , 1. , 1.); // background color + float phase = 0; + int i, oldretire = -1, oldrelease = -1, oldrelease2 = -1; +- for (i=0; i<1020*60; ++i) { ++ for (i=0; i<60*60; ++i) { + glClear(GL_COLOR_BUFFER_BIT); + glUniform1f ( phase_loc , phase ); // write the value of phase to the shaders phase + phase = fmodf ( phase + 0.5f , 2.f * 3.141f ); // and update the local variable +@@ -369,6 +386,18 @@ int main(int argc, char **argv) + printf("terminated\n"); + android_dlclose(baz); + #endif ++ ++ int bad_tls = 0; ++ for (i=0; i<64; ++i) { ++ if (tls_space[i] != SLOT_FILLER) { ++ printf("TLS array slot %d polluted: %p\n", i, tls_space[i]); ++ bad_tls++; ++ } ++ } ++ if (bad_tls) ++ return 1; ++ ++ return 0; + } + + // vim:ts=4:sw=4:noexpandtab +-- +2.15.1 + diff --git a/hybris/libhybris/0003-Implement-X11-EGL-platform-based-on-wayland-code.patch b/hybris/libhybris/0003-Implement-X11-EGL-platform-based-on-wayland-code.patch new file mode 100644 index 000000000..fd7b90236 --- /dev/null +++ b/hybris/libhybris/0003-Implement-X11-EGL-platform-based-on-wayland-code.patch @@ -0,0 +1,1672 @@ +From b9251827932545a455bfecea7b259eba5677c3bd Mon Sep 17 00:00:00 2001 +From: NeKit +Date: Wed, 18 Oct 2017 23:12:51 +0300 +Subject: [PATCH 3/3] Implement X11 EGL platform based on wayland code. + +Allow window system to hook eglGetConfigAttrib (needed for X11 +EGL_NATIVE_VISUAL_ID) + +Use custom DRIHYBRIS Xorg extension for buffer sharing to Xorg/glamor when +possible + +Gives huge speedup over XShmPutImage, but requires patched Glamor and DDX driver +to utilize it + +Check for window resizes using Present extension when possible +--- + hybris/configure.ac | 1 + + hybris/egl/egl.c | 13 +- + hybris/egl/platforms/Makefile.am | 2 +- + hybris/egl/platforms/common/eglplatformcommon.cpp | 2 +- + hybris/egl/platforms/x11/Makefile.am | 43 ++ + hybris/egl/platforms/x11/eglplatform_x11.cpp | 235 +++++++ + hybris/egl/platforms/x11/x11_window.cpp | 728 ++++++++++++++++++++++ + hybris/egl/platforms/x11/x11_window.h | 201 ++++++ + hybris/egl/platforms/x11/xcb_drihybris.c | 167 +++++ + hybris/egl/platforms/x11/xcb_drihybris.h | 122 ++++ + hybris/egl/ws.c | 9 + + hybris/egl/ws.h | 2 + + 12 files changed, 1522 insertions(+), 3 deletions(-) + create mode 100644 hybris/egl/platforms/x11/Makefile.am + create mode 100644 hybris/egl/platforms/x11/eglplatform_x11.cpp + create mode 100644 hybris/egl/platforms/x11/x11_window.cpp + create mode 100644 hybris/egl/platforms/x11/x11_window.h + create mode 100644 hybris/egl/platforms/x11/xcb_drihybris.c + create mode 100644 hybris/egl/platforms/x11/xcb_drihybris.h + +diff --git a/hybris/configure.ac b/hybris/configure.ac +index dac8bc9..526567a 100644 +--- a/hybris/configure.ac ++++ b/hybris/configure.ac +@@ -254,6 +254,7 @@ AC_CONFIG_FILES([ + egl/platforms/null/Makefile + egl/platforms/fbdev/Makefile + egl/platforms/wayland/Makefile ++ egl/platforms/x11/Makefile + egl/platforms/hwcomposer/Makefile + egl/platforms/hwcomposer/hwcomposer-egl.pc + glesv1/glesv1_cm.pc +diff --git a/hybris/egl/egl.c b/hybris/egl/egl.c +index f6dcd09..4c02ebf 100644 +--- a/hybris/egl/egl.c ++++ b/hybris/egl/egl.c +@@ -228,7 +228,6 @@ const char * eglQueryString(EGLDisplay dpy, EGLint name) + + HYBRIS_IMPLEMENT_FUNCTION4(egl, EGLBoolean, eglGetConfigs, EGLDisplay, EGLConfig *, EGLint, EGLint *); + HYBRIS_IMPLEMENT_FUNCTION5(egl, EGLBoolean, eglChooseConfig, EGLDisplay, const EGLint *, EGLConfig *, EGLint, EGLint *); +-HYBRIS_IMPLEMENT_FUNCTION4(egl, EGLBoolean, eglGetConfigAttrib, EGLDisplay, EGLConfig, EGLint, EGLint *); + + EGLSurface eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, + EGLNativeWindowType win, +@@ -461,4 +460,16 @@ EGLBoolean eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image) + return ret; + } + ++EGLBoolean eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value) ++{ ++ HYBRIS_DLSYSM(egl, &_eglGetConfigAttrib, "eglGetConfigAttrib"); ++ struct _EGLDisplay *display = hybris_egl_display_get_mapping(dpy); ++ ++ EGLBoolean ret = ws_eglGetConfigAttrib(display, config, attribute, value); ++ if (ret == EGL_FALSE) { ++ return (*_eglGetConfigAttrib)(dpy, config, attribute, value); ++ } ++ return ret; ++} ++ + // vim:ts=4:sw=4:noexpandtab +diff --git a/hybris/egl/platforms/Makefile.am b/hybris/egl/platforms/Makefile.am +index 4126752..c52de15 100644 +--- a/hybris/egl/platforms/Makefile.am ++++ b/hybris/egl/platforms/Makefile.am +@@ -11,4 +11,4 @@ if WANT_WAYLAND + SUBDIRS += wayland + endif + +- ++SUBDIRS += x11 +diff --git a/hybris/egl/platforms/common/eglplatformcommon.cpp b/hybris/egl/platforms/common/eglplatformcommon.cpp +index b512dc0..04aed79 100644 +--- a/hybris/egl/platforms/common/eglplatformcommon.cpp ++++ b/hybris/egl/platforms/common/eglplatformcommon.cpp +@@ -74,7 +74,7 @@ extern "C" void hybris_dump_buffer_to_file(ANativeWindowBuffer *buf) + char b[1024]; + int bytes_pp = 0; + +- if (buf->format == HAL_PIXEL_FORMAT_RGBA_8888) ++ if (buf->format == HAL_PIXEL_FORMAT_RGBA_8888 || buf->format == HAL_PIXEL_FORMAT_BGRA_8888) + bytes_pp = 4; + else if (buf->format == HAL_PIXEL_FORMAT_RGB_565) + bytes_pp = 2; +diff --git a/hybris/egl/platforms/x11/Makefile.am b/hybris/egl/platforms/x11/Makefile.am +new file mode 100644 +index 0000000..22eac5e +--- /dev/null ++++ b/hybris/egl/platforms/x11/Makefile.am +@@ -0,0 +1,43 @@ ++pkglib_LTLIBRARIES = eglplatform_x11.la ++ ++eglplatform_x11_la_SOURCES = eglplatform_x11.cpp x11_window.cpp xcb_drihybris.c ++eglplatform_x11_la_CXXFLAGS = \ ++ -I$(top_srcdir)/common \ ++ -I$(top_srcdir)/include \ ++ -I$(top_srcdir)/egl \ ++ -I$(top_srcdir)/egl/platforms/common \ ++ $(ANDROID_HEADERS_CFLAGS) \ ++ $(WAYLAND_CLIENT_CFLAGS) ++ ++if WANT_DEBUG ++eglplatform_x11_la_CXXFLAGS += -I$(top_srcdir)/common ++endif ++ ++if WANT_TRACE ++eglplatform_x11_la_CXXFLAGS += -DDEBUG ++endif ++ ++if WANT_DEBUG ++eglplatform_x11_la_CXXFLAGS += -ggdb -O0 ++endif ++ ++if !WANT_WL_SERVERSIDE_BUFFERS ++eglplatform_x11_la_CXXFLAGS += -DHYBRIS_NO_SERVER_SIDE_BUFFERS ++endif ++ ++ ++ ++eglplatform_x11_la_LDFLAGS = \ ++ -avoid-version -module -shared -export-dynamic \ ++ $(top_builddir)/egl/platforms/common/libhybris-eglplatformcommon.la \ ++ $(top_builddir)/hardware/libhardware.la \ ++ -lXext -lxcb -lX11-xcb -lxcb-present ++ ++if HAS_ANDROID_4_2_0 ++eglplatform_x11_la_LDFLAGS += $(top_builddir)/libsync/libsync.la ++endif ++ ++if HAS_ANDROID_5_0_0 ++eglplatform_x11_la_LDFLAGS += $(top_builddir)/libsync/libsync.la ++endif ++ +diff --git a/hybris/egl/platforms/x11/eglplatform_x11.cpp b/hybris/egl/platforms/x11/eglplatform_x11.cpp +new file mode 100644 +index 0000000..001b733 +--- /dev/null ++++ b/hybris/egl/platforms/x11/eglplatform_x11.cpp +@@ -0,0 +1,235 @@ ++/**************************************************************************************** ++** ++** Copyright (C) 2013 Jolla Ltd. ++** Contact: Carsten Munk ++** All rights reserved. ++** ++** This file is part of X11 enablement for libhybris ++** ++** You may use this file under the terms of the GNU Lesser General ++** Public License version 2.1 as published by the Free Software Foundation ++** and appearing in the file license.lgpl included in the packaging ++** of this file. ++** ++** This library is free software; you can redistribute it and/or ++** modify it under the terms of the GNU Lesser General Public ++** License version 2.1 as published by the Free Software Foundation ++** and appearing in the file license.lgpl included in the packaging ++** of this file. ++** ++** This library is distributed in the hope that it will be useful, ++** but WITHOUT ANY WARRANTY; without even the implied warranty of ++** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++** Lesser General Public License for more details. ++** ++****************************************************************************************/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++extern "C" { ++#include ++}; ++#include ++ ++#include ++ ++extern "C" { ++#include ++#include ++} ++ ++#include "x11_window.h" ++#include "logging.h" ++ ++#include ++#include ++ ++static gralloc_module_t *gralloc = 0; ++static alloc_device_t *alloc = 0; ++ ++ ++static const char * (*_eglQueryString)(EGLDisplay dpy, EGLint name) = NULL; ++static __eglMustCastToProperFunctionPointerType (*_eglGetProcAddress)(const char *procname) = NULL; ++static EGLSyncKHR (*_eglCreateSyncKHR)(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list) = NULL; ++static EGLBoolean (*_eglDestroySyncKHR)(EGLDisplay dpy, EGLSyncKHR sync) = NULL; ++static EGLint (*_eglClientWaitSyncKHR)(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout) = NULL; ++ ++struct X11Display { ++ _EGLDisplay base; ++ Display *xl_display; ++}; ++ ++extern "C" void x11ws_init_module(struct ws_egl_interface *egl_iface) ++{ ++ int err; ++ hw_get_module(GRALLOC_HARDWARE_MODULE_ID, (const hw_module_t **) &gralloc); ++ err = gralloc_open((const hw_module_t *) gralloc, &alloc); ++ TRACE("++ %lu x11: got gralloc %p err:%s", pthread_self(), gralloc, strerror(-err)); ++ eglplatformcommon_init(egl_iface, gralloc, alloc); ++} ++ ++static void _init_egl_funcs(EGLDisplay display) ++{ ++ if (_eglQueryString != NULL) ++ return; ++ ++ _eglQueryString = (const char * (*)(void*, int)) ++ hybris_android_egl_dlsym("eglQueryString"); ++ assert(_eglQueryString); ++ _eglGetProcAddress = (__eglMustCastToProperFunctionPointerType (*)(const char *)) ++ hybris_android_egl_dlsym("eglGetProcAddress"); ++ assert(_eglGetProcAddress); ++ ++ const char *extensions = (*_eglQueryString)(display, EGL_EXTENSIONS); ++ ++ if (strstr(extensions, "EGL_KHR_fence_sync")) { ++ _eglCreateSyncKHR = (PFNEGLCREATESYNCKHRPROC) ++ (*_eglGetProcAddress)("eglCreateSyncKHR"); ++ assert(_eglCreateSyncKHR); ++ _eglDestroySyncKHR = (PFNEGLDESTROYSYNCKHRPROC) ++ (*_eglGetProcAddress)("eglDestroySyncKHR"); ++ assert(_eglDestroySyncKHR); ++ _eglClientWaitSyncKHR = (PFNEGLCLIENTWAITSYNCKHRPROC) ++ (*_eglGetProcAddress)("eglClientWaitSyncKHR"); ++ assert(_eglClientWaitSyncKHR); ++ } ++} ++ ++extern "C" _EGLDisplay *x11ws_GetDisplay(EGLNativeDisplayType display) ++{ ++ X11Display *xdpy = new X11Display; ++ xdpy->xl_display = (Display *)display; ++ ++ return &xdpy->base; ++} ++ ++extern "C" void x11ws_Terminate(_EGLDisplay *dpy) ++{ ++ X11Display *xdpy = (X11Display *)dpy; ++ int ret = 0; ++ delete xdpy; ++} ++ ++extern "C" EGLNativeWindowType x11ws_CreateWindow(EGLNativeWindowType win, _EGLDisplay *display) ++{ ++ Window xlib_window = (Window) win; ++ X11Display *xdpy = (X11Display *)display; ++ ++ if (win == 0 || xdpy->xl_display == 0) { ++ HYBRIS_ERROR("Running with EGL_PLATFORM=x11 without X server is not possible"); ++ HYBRIS_ERROR("If you want to run a standlone EGL client do it like this:"); ++ HYBRIS_ERROR(" $ export EGL_PLATFORM=null"); ++ HYBRIS_ERROR(" $ test_glevs2"); ++ abort(); ++ } ++ ++ X11NativeWindow *window = new X11NativeWindow(xdpy->xl_display, xlib_window, alloc, gralloc); ++ window->common.incRef(&window->common); ++ return (EGLNativeWindowType) static_cast(window); ++} ++ ++extern "C" void x11ws_DestroyWindow(EGLNativeWindowType win) ++{ ++ X11NativeWindow *window = static_cast((struct ANativeWindow *)win); ++ window->common.decRef(&window->common); ++} ++ ++extern "C" __eglMustCastToProperFunctionPointerType x11ws_eglGetProcAddress(const char *procname) ++{ ++ return eglplatformcommon_eglGetProcAddress(procname); ++} ++ ++extern "C" void x11ws_passthroughImageKHR(EGLContext *ctx, EGLenum *target, EGLClientBuffer *buffer, const EGLint **attrib_list) ++{ ++ eglplatformcommon_passthroughImageKHR(ctx, target, buffer, attrib_list); ++} ++ ++extern "C" const char *x11ws_eglQueryString(EGLDisplay dpy, EGLint name, const char *(*real_eglQueryString)(EGLDisplay dpy, EGLint name)) ++{ ++ const char *ret = eglplatformcommon_eglQueryString(dpy, name, real_eglQueryString); ++ if (ret && name == EGL_EXTENSIONS) ++ { ++ static char eglextensionsbuf[1024]; ++ snprintf(eglextensionsbuf, 1022, "%s %s", ret, ++ "EGL_EXT_swap_buffers_with_damage EGL_WL_create_x11_buffer_from_image" ++ ); ++ ret = eglextensionsbuf; ++ } ++ return ret; ++} ++ ++extern "C" void x11ws_prepareSwap(EGLDisplay dpy, EGLNativeWindowType win, EGLint *damage_rects, EGLint damage_n_rects) ++{ ++ X11NativeWindow *window = static_cast((struct ANativeWindow *)win); ++ window->prepareSwap(damage_rects, damage_n_rects); ++} ++ ++extern "C" void x11ws_finishSwap(EGLDisplay dpy, EGLNativeWindowType win) ++{ ++ _init_egl_funcs(dpy); ++ X11NativeWindow *window = static_cast((struct ANativeWindow *)win); ++ if (_eglCreateSyncKHR) { ++ EGLSyncKHR sync = (*_eglCreateSyncKHR)(dpy, EGL_SYNC_FENCE_KHR, NULL); ++ (*_eglClientWaitSyncKHR)(dpy, sync, EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, EGL_FOREVER_KHR); ++ (*_eglDestroySyncKHR)(dpy, sync); ++ } ++ window->finishSwap(); ++} ++ ++extern "C" void x11ws_setSwapInterval(EGLDisplay dpy, EGLNativeWindowType win, EGLint interval) ++{ ++ X11NativeWindow *window = static_cast((struct ANativeWindow *)win); ++ window->setSwapInterval(interval); ++} ++ ++extern "C" EGLBoolean x11ws_eglGetConfigAttrib(struct _EGLDisplay *display, EGLConfig config, EGLint attribute, EGLint *value) ++{ ++ TRACE("attribute:%i", attribute); ++ if (attribute == EGL_NATIVE_VISUAL_ID) ++ { ++ X11Display *xdpy = (X11Display *)display; ++ XVisualInfo visinfo_template; ++ XVisualInfo *visinfo = NULL; ++ int visinfos_count = 0; ++ ++ visinfo_template.depth = 32; ++ visinfo = XGetVisualInfo (xdpy->xl_display, ++ VisualDepthMask, ++ &visinfo_template, ++ &visinfos_count); ++ ++ if (visinfos_count) ++ { ++ TRACE("visinfo.visualid:%i", attribute); ++ *value = visinfo->visualid; ++ return EGL_TRUE; ++ } ++ ++ } ++ return EGL_FALSE; ++} ++ ++struct ws_module ws_module_info = { ++ x11ws_init_module, ++ x11ws_GetDisplay, ++ x11ws_Terminate, ++ x11ws_CreateWindow, ++ x11ws_DestroyWindow, ++ x11ws_eglGetProcAddress, ++ x11ws_passthroughImageKHR, ++ x11ws_eglQueryString, ++ x11ws_prepareSwap, ++ x11ws_finishSwap, ++ x11ws_setSwapInterval, ++ x11ws_eglGetConfigAttrib ++}; +diff --git a/hybris/egl/platforms/x11/x11_window.cpp b/hybris/egl/platforms/x11/x11_window.cpp +new file mode 100644 +index 0000000..4363e80 +--- /dev/null ++++ b/hybris/egl/platforms/x11/x11_window.cpp +@@ -0,0 +1,728 @@ ++/**************************************************************************************** ++ ** ++ ** Copyright (C) 2013 Jolla Ltd. ++ ** Contact: Carsten Munk ++ ** All rights reserved. ++ ** ++ ** This file is part of Wayland enablement for libhybris ++ ** ++ ** You may use this file under the terms of the GNU Lesser General ++ ** Public License version 2.1 as published by the Free Software Foundation ++ ** and appearing in the file license.lgpl included in the packaging ++ ** of this file. ++ ** ++ ** This library is free software; you can redistribute it and/or ++ ** modify it under the terms of the GNU Lesser General Public ++ ** License version 2.1 as published by the Free Software Foundation ++ ** and appearing in the file license.lgpl included in the packaging ++ ** of this file. ++ ** ++ ** This library is distributed in the hope that it will be useful, ++ ** but WITHOUT ANY WARRANTY; without even the implied warranty of ++ ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ ** Lesser General Public License for more details. ++ ** ++ ****************************************************************************************/ ++ ++#include ++#include "x11_window.h" ++#include ++#include ++#include ++#include ++ ++#include "logging.h" ++#include ++#include "xcb_drihybris.h" ++ ++#if ANDROID_VERSION_MAJOR>=4 && ANDROID_VERSION_MINOR>=2 || ANDROID_VERSION_MAJOR>=5 ++extern "C" { ++#include ++} ++#endif ++ ++void X11NativeWindow::resize(unsigned int width, unsigned int height) ++{ ++ lock(); ++ this->m_defaultWidth = width; ++ this->m_defaultHeight = height; ++ unlock(); ++} ++ ++void X11NativeWindow::lock() ++{ ++ pthread_mutex_lock(&this->mutex); ++} ++ ++void X11NativeWindow::unlock() ++{ ++ pthread_mutex_unlock(&this->mutex); ++} ++ ++X11NativeWindow::X11NativeWindow(Display* xl_display, Window xl_window, alloc_device_t* alloc, gralloc_module_t* gralloc) ++{ ++ int wayland_ok; ++ ++ HYBRIS_TRACE_BEGIN("x11-platform", "create_window", ""); ++ this->m_window = xl_window; ++ this->m_display = xl_display; ++ this->m_connection = XGetXCBConnection(xl_display); ++ this->m_image = 0; ++ this->m_useShm = true; ++ this->m_format = HAL_PIXEL_FORMAT_RGBA_8888; ++ ++ const_cast(ANativeWindow::minSwapInterval) = 0; ++ const_cast(ANativeWindow::maxSwapInterval) = 1; ++ // This is the default as per the EGL documentation ++ this->m_swap_interval = 1; ++ ++ this->m_alloc = alloc; ++ m_gralloc = gralloc; ++ ++ TRACE("getting X11 window information"); ++ ++ XWindowAttributes window_attributes; ++ XGetWindowAttributes(m_display, m_window, &window_attributes); ++ ++ TRACE("window x=%d y=%d width=%d height=%d depth=%d", ++ window_attributes.x, ++ window_attributes.y, ++ window_attributes.width, ++ window_attributes.height, ++ window_attributes.depth); ++ ++ m_width = window_attributes.width; ++ m_height = window_attributes.height; ++ ++ const char *env = getenv("HYBRIS_X11_FORCE_WIDTH"); ++ if (env != NULL) ++ { ++ m_width = atoi(env); ++ TRACE("forced width=%d", m_width); ++ } ++ ++ env = getenv("HYBRIS_X11_FORCE_HEIGHT"); ++ if (env != NULL) ++ { ++ m_height = atoi(env); ++ TRACE("forced height=%d", m_height); ++ } ++ ++ m_defaultWidth = m_width; ++ m_defaultHeight = m_height; ++ ++ env = getenv("HYBRIS_X11_DISABLE_SHM"); ++ if (env != NULL) ++ { ++ m_useShm = false; ++ TRACE("won't use MIT-SHM"); ++ } ++ ++ XGCValues gcvalues; ++ m_gc = XCreateGC(m_display, m_window, 0, &gcvalues); ++ ++ m_xcb_gc = xcb_generate_id(m_connection); ++ xcb_create_gc(m_connection, m_xcb_gc, m_window, 0, 0); ++ ++ m_specialEvent = 0; ++ m_haveDRIHybris = false; ++ tryEnableDRIHybris(); ++ ++ m_usage=GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_SW_READ_OFTEN; ++ pthread_mutex_init(&mutex, NULL); ++ pthread_cond_init(&cond, NULL); ++ m_queueReads = 0; ++ m_freeBufs = 0; ++ m_damage_rects = NULL; ++ m_damage_n_rects = 0; ++ m_lastBuffer = 0; ++ setBufferCount(3); ++ HYBRIS_TRACE_END("x11-platform", "create_window", ""); ++} ++ ++X11NativeWindow::~X11NativeWindow() ++{ ++ std::list::iterator it = m_bufList.begin(); ++ destroyBuffers(); ++} ++ ++// overloads from BaseNativeWindow ++int X11NativeWindow::setSwapInterval(int interval) { ++ TRACE("interval:%i", interval); ++ ++ if (interval < 0) ++ interval = 0; ++ if (interval > 1) ++ interval = 1; ++ ++ HYBRIS_TRACE_BEGIN("x11-platform", "swap_interval", "=%d", interval); ++ ++ lock(); ++ m_swap_interval = interval; ++ unlock(); ++ ++ HYBRIS_TRACE_END("x11-platform", "swap_interval", ""); ++ ++ return 0; ++} ++ ++int X11NativeWindow::dequeueBuffer(BaseNativeWindowBuffer **buffer, int *fenceFd){ ++ HYBRIS_TRACE_BEGIN("x11-platform", "dequeueBuffer", ""); ++ ++ X11NativeWindowBuffer *wnb=NULL; ++ TRACE("%p", buffer); ++ ++ readQueue(false); ++ ++ HYBRIS_TRACE_BEGIN("x11-platform", "dequeueBuffer_wait_for_buffer", ""); ++ ++ HYBRIS_TRACE_COUNTER("x11-platform", "m_freeBufs", "%i", m_freeBufs); ++ ++ while (m_freeBufs == 0) { ++ HYBRIS_TRACE_COUNTER("x11-platform", "m_freeBufs", "%i", m_freeBufs); ++ readQueue(true); ++ } ++ ++ lock(); ++ ++ std::list::iterator it = m_bufList.begin(); ++ for (; it != m_bufList.end(); it++) ++ { ++ if ((*it)->busy) ++ continue; ++ if ((*it)->youngest == 1) ++ continue; ++ break; ++ } ++ ++ if (it==m_bufList.end()) { ++ HYBRIS_TRACE_BEGIN("x11-platform", "dequeueBuffer_worst_case_scenario", ""); ++ HYBRIS_TRACE_END("x11-platform", "dequeueBuffer_worst_case_scenario", ""); ++ ++ it = m_bufList.begin(); ++ for (; it != m_bufList.end() && (*it)->busy; it++) ++ {} ++ ++ } ++ if (it==m_bufList.end()) { ++ unlock(); ++ HYBRIS_TRACE_BEGIN("x11-platform", "dequeueBuffer_no_free_buffers", ""); ++ HYBRIS_TRACE_END("x11-platform", "dequeueBuffer_no_free_buffers", ""); ++ TRACE("%p: no free buffers", buffer); ++ return NO_ERROR; ++ } ++ ++ wnb = *it; ++ assert(wnb!=NULL); ++ HYBRIS_TRACE_END("x11-platform", "dequeueBuffer_wait_for_buffer", ""); ++ ++ /* If the buffer doesn't match the window anymore, re-allocate */ ++ if (wnb->width != m_width || wnb->height != m_height ++ || wnb->format != m_format || wnb->usage != m_usage) ++ { ++ TRACE("wnb:%p,win:%p %i,%i %i,%i x%x,x%x x%x,x%x", ++ wnb,m_window, ++ wnb->width,m_width, wnb->height,m_height, ++ wnb->format,m_format, wnb->usage,m_usage); ++ destroyBuffer(wnb); ++ m_bufList.erase(it); ++ wnb = addBuffer(); ++ } ++ ++ wnb->busy = 1; ++ *buffer = wnb; ++ queue.push_back(wnb); ++ --m_freeBufs; ++ ++ HYBRIS_TRACE_COUNTER("x11-platform", "m_freeBufs", "%i", m_freeBufs); ++ HYBRIS_TRACE_BEGIN("x11-platform", "dequeueBuffer_gotBuffer", "-%p", wnb); ++ HYBRIS_TRACE_END("x11-platform", "dequeueBuffer_gotBuffer", "-%p", wnb); ++ HYBRIS_TRACE_END("x11-platform", "dequeueBuffer_wait_for_buffer", ""); ++ ++ unlock(); ++ return NO_ERROR; ++} ++ ++int X11NativeWindow::lockBuffer(BaseNativeWindowBuffer* buffer){ ++ X11NativeWindowBuffer *wnb = (X11NativeWindowBuffer*) buffer; ++ HYBRIS_TRACE_BEGIN("x11-platform", "lockBuffer", "-%p", wnb); ++ HYBRIS_TRACE_END("x11-platform", "lockBuffer", "-%p", wnb); ++ return NO_ERROR; ++} ++ ++int X11NativeWindow::readQueue(bool block) ++{ ++ int ret = 0; ++ ++ if (++m_queueReads == 1) { ++ if (m_specialEvent) { ++ xcb_generic_event_t *ev; ++ ++ if (!block) ++ { ++ while ((ev = xcb_poll_for_special_event(m_connection, ++ m_specialEvent)) != NULL) { ++ xcb_present_generic_event_t *ge = (xcb_present_generic_event_t *) ev; ++ handlePresentEvent(ge); ++ } ++ } ++ } ++ ++ // all threads waiting on the false branch will wake and return now, so we ++ // can safely set m_queueReads to 0 here instead of relying on every thread ++ // to decrement it. This prevents a race condition when a thread enters readQueue() ++ // before the one in this thread returns. ++ // The new thread would go in the false branch, and there would be no thread in the ++ // true branch, blocking the new thread and any other that will call readQueue in ++ // the future. ++ m_queueReads = 0; ++ ++ pthread_cond_broadcast(&cond); ++ ++ } else if (block) { ++ while (m_queueReads > 0) { ++ pthread_cond_wait(&cond, &mutex); ++ } ++ } ++ ++ return ret; ++} ++ ++void X11NativeWindow::prepareSwap(EGLint *damage_rects, EGLint damage_n_rects) ++{ ++ lock(); ++ m_damage_rects = damage_rects; ++ m_damage_n_rects = damage_n_rects; ++ unlock(); ++} ++ ++void X11NativeWindow::finishSwap() ++{ ++ int ret = 0; ++ lock(); ++ ++ X11NativeWindowBuffer *wnb = queue.front(); ++ if (!wnb) { ++ wnb = m_lastBuffer; ++ } else { ++ queue.pop_front(); ++ } ++ assert(wnb); ++ m_lastBuffer = wnb; ++ wnb->busy = 1; ++ ++ fronted.push_back(wnb); ++ ++ m_damage_rects = NULL; ++ m_damage_n_rects = 0; ++ unlock(); ++ ++ if (m_haveDRIHybris) { ++ if (wnb->pixmap == 0) ++ wnb->pixmap_from_buffer(m_connection, m_window); ++ ++ xcb_copy_area(m_connection, wnb->pixmap, m_window, m_xcb_gc, ++ 0, 0, 0, 0, /* src_x, src_y, dst_x, dst_y */ ++ m_width, m_height); ++ xcb_flush(m_connection); ++ ++ lock(); ++ ++ ++m_freeBufs; ++ HYBRIS_TRACE_COUNTER("x11-platform", "m_freeBufs", "%i", m_freeBufs); ++ ++ std::list::iterator it; ++ for (it = m_bufList.begin(); it != m_bufList.end(); it++) ++ { ++ (*it)->youngest = 0; ++ } ++ wnb->youngest = 1; ++ wnb->busy = 0; ++ ++ unlock(); ++ } else { ++ copyToX11(wnb); ++ } ++} ++ ++static int debugenvchecked = 0; ++ ++int X11NativeWindow::queueBuffer(BaseNativeWindowBuffer* buffer, int fenceFd) ++{ ++ X11NativeWindowBuffer *wnb = (X11NativeWindowBuffer*) buffer; ++ int ret = 0; ++ ++ HYBRIS_TRACE_BEGIN("x11-platform", "queueBuffer", "-%p", wnb); ++ lock(); ++ ++ if (debugenvchecked == 0) ++ { ++ if (getenv("HYBRIS_WAYLAND_DUMP_BUFFERS") != NULL) ++ debugenvchecked = 2; ++ else ++ debugenvchecked = 1; ++ } ++ if (debugenvchecked == 2) ++ { ++ HYBRIS_TRACE_BEGIN("x11-platform", "queueBuffer_dumping_buffer", "-%p", wnb); ++ hybris_dump_buffer_to_file(wnb->getNativeBuffer()); ++ HYBRIS_TRACE_END("x11-platform", "queueBuffer_dumping_buffer", "-%p", wnb); ++ ++ } ++ ++#if ANDROID_VERSION_MAJOR>=4 && ANDROID_VERSION_MINOR>=2 || ANDROID_VERSION_MAJOR>=5 ++ HYBRIS_TRACE_BEGIN("x11-platform", "queueBuffer_waiting_for_fence", "-%p", wnb); ++ if (fenceFd >= 0) ++ { ++ sync_wait(fenceFd, -1); ++ close(fenceFd); ++ } ++ HYBRIS_TRACE_END("x11-platform", "queueBuffer_waiting_for_fence", "-%p", wnb); ++#endif ++ ++ HYBRIS_TRACE_COUNTER("x11-platform", "fronted.size", "%i", fronted.size()); ++ HYBRIS_TRACE_END("x11-platform", "queueBuffer", "-%p", wnb); ++ ++ unlock(); ++ ++ return NO_ERROR; ++} ++ ++int X11NativeWindow::cancelBuffer(BaseNativeWindowBuffer* buffer, int fenceFd){ ++ std::list::iterator it; ++ X11NativeWindowBuffer *wnb = (X11NativeWindowBuffer*) buffer; ++ ++ lock(); ++ HYBRIS_TRACE_BEGIN("x11-platform", "cancelBuffer", "-%p", wnb); ++ ++ /* Check first that it really is our buffer */ ++ for (it = m_bufList.begin(); it != m_bufList.end(); it++) ++ { ++ if ((*it) == wnb) ++ break; ++ } ++ assert(it != m_bufList.end()); ++ ++ wnb->busy = 0; ++ ++m_freeBufs; ++ HYBRIS_TRACE_COUNTER("x11-platform", "m_freeBufs", "%i", m_freeBufs); ++ ++ for (it = m_bufList.begin(); it != m_bufList.end(); it++) ++ { ++ (*it)->youngest = 0; ++ } ++ wnb->youngest = 1; ++ ++ if (m_queueReads != 0) { ++ // Some thread is waiting on wl_display_dispatch_queue(), possibly waiting for a wl_buffer.release ++ // event. Since we have now cancelled a buffer push an artificial event so that the dispatch returns ++ // and the thread can notice the cancelled buffer. This means there is a delay of one roundtrip, ++ // but I don't see other solution except having one dedicated thread for calling wl_display_dispatch_queue(). ++ //wl_callback_destroy(wl_display_sync(m_display)); ++ } ++ ++ HYBRIS_TRACE_END("x11-platform", "cancelBuffer", "-%p", wnb); ++ unlock(); ++ ++ return 0; ++} ++ ++unsigned int X11NativeWindow::width() const { ++ TRACE("value:%i", m_width); ++ return m_width; ++} ++ ++unsigned int X11NativeWindow::height() const { ++ TRACE("value:%i", m_height); ++ return m_height; ++} ++ ++unsigned int X11NativeWindow::format() const { ++ TRACE("value:%i", m_format); ++ return m_format; ++} ++ ++unsigned int X11NativeWindow::defaultWidth() const { ++ TRACE("value:%i", m_defaultWidth); ++ return m_defaultWidth; ++} ++ ++unsigned int X11NativeWindow::defaultHeight() const { ++ TRACE("value:%i", m_defaultHeight); ++ return m_defaultHeight; ++} ++ ++unsigned int X11NativeWindow::queueLength() const { ++ TRACE("WARN: stub"); ++ return 1; ++} ++ ++unsigned int X11NativeWindow::type() const { ++ TRACE(""); ++#if ANDROID_VERSION_MAJOR>=4 && ANDROID_VERSION_MINOR>=3 || ANDROID_VERSION_MAJOR>=5 ++ /* https://android.googlesource.com/platform/system/core/+/bcfa910611b42018db580b3459101c564f802552%5E!/ */ ++ return NATIVE_WINDOW_SURFACE; ++#else ++ return NATIVE_WINDOW_SURFACE_TEXTURE_CLIENT; ++#endif ++} ++ ++unsigned int X11NativeWindow::transformHint() const { ++ TRACE("WARN: stub"); ++ return 0; ++} ++ ++/* ++ * returns the current usage of this window ++ */ ++unsigned int X11NativeWindow::getUsage() const { ++ return m_usage; ++} ++ ++int X11NativeWindow::setBuffersFormat(int format) { ++ if (format != m_format) ++ { ++ TRACE("old-format:x%x new-format:x%x", m_format, format); ++ m_format = format; ++ /* Buffers will be re-allocated when dequeued */ ++ } else { ++ TRACE("format:x%x", format); ++ } ++ return NO_ERROR; ++} ++ ++void X11NativeWindow::destroyBuffer(X11NativeWindowBuffer* wnb) ++{ ++ TRACE("wnb:%p", wnb); ++ ++ assert(wnb != NULL); ++ ++ int ret = 0; ++ ++ wnb->common.decRef(&wnb->common); ++ m_freeBufs--; ++} ++ ++void X11NativeWindow::destroyBuffers() ++{ ++ TRACE(""); ++ ++ std::list::iterator it = m_bufList.begin(); ++ for (; it!=m_bufList.end(); ++it) ++ { ++ destroyBuffer(*it); ++ it = m_bufList.erase(it); ++ } ++ m_bufList.clear(); ++ m_freeBufs = 0; ++} ++ ++X11NativeWindowBuffer *X11NativeWindow::addBuffer() { ++ ++ X11NativeWindowBuffer *wnb; ++ ++ wnb = new ClientX11Buffer(m_alloc, m_width, m_height, m_format, m_usage); ++ m_bufList.push_back(wnb); ++ ++m_freeBufs; ++ ++ TRACE("wnb:%p width:%i height:%i format:x%x usage:x%x", ++ wnb, wnb->width, wnb->height, wnb->format, wnb->usage); ++ ++ return wnb; ++} ++ ++int X11NativeWindow::setBufferCount(int cnt) { ++ int start = 0; ++ ++ TRACE("cnt:%d", cnt); ++ ++ if (m_bufList.size() == cnt) ++ return NO_ERROR; ++ ++ lock(); ++ ++ if (m_bufList.size() > cnt) { ++ /* Decreasing buffer count, remove from beginning */ ++ std::list::iterator it = m_bufList.begin(); ++ for (int i = 0; i <= m_bufList.size() - cnt; i++ ) ++ { ++ destroyBuffer(*it); ++ ++it; ++ m_bufList.pop_front(); ++ } ++ ++ } else { ++ /* Increasing buffer count, start from current size */ ++ for (int i = m_bufList.size(); i < cnt; i++) ++ X11NativeWindowBuffer *unused = addBuffer(); ++ ++ } ++ ++ unlock(); ++ ++ return NO_ERROR; ++} ++ ++int X11NativeWindow::setBuffersDimensions(int width, int height) { ++ if (m_width != width || m_height != height) ++ { ++ TRACE("old-size:%ix%i new-size:%ix%i", m_width, m_height, width, height); ++ m_width = width; ++ m_height = height; ++ /* Buffers will be re-allocated when dequeued */ ++ } else { ++ TRACE("size:%ix%i", width, height); ++ } ++ return NO_ERROR; ++} ++ ++int X11NativeWindow::setUsage(int usage) { ++// if ((usage | GRALLOC_USAGE_HW_TEXTURE) != m_usage) ++// { ++// TRACE("old-usage:x%x new-usage:x%x", m_usage, usage); ++// m_usage = usage | GRALLOC_USAGE_HW_TEXTURE; ++// /* Buffers will be re-allocated when dequeued */ ++// } else { ++// TRACE("usage:x%x", usage); ++// } ++ return NO_ERROR; ++} ++ ++void X11NativeWindow::copyToX11(X11NativeWindowBuffer *wnb) { ++ int ret; ++ void *vaddr; ++ std::list::iterator it; ++ ++ ret = m_gralloc->lock(m_gralloc, wnb->handle, wnb->usage, 0, 0, wnb->width, wnb->height, &vaddr); ++ TRACE("wnb:%p gralloc lock returns %i", wnb, ret); ++ TRACE("wnb:%p lock to vaddr %p", wnb, vaddr); ++ TRACE("wnb:%p width=%d stride=%d height=%d format=%d", wnb, wnb->width, wnb->stride, wnb->height, wnb->format); ++ ++ if (!m_image) ++ { ++ if (m_useShm) ++ { ++ m_image = XShmCreateImage(m_display, ++ CopyFromParent, ++ 32, ++ ZPixmap, 0, &m_shminfo, wnb->stride, wnb->height); ++ ++ m_shminfo.shmid = shmget(IPC_PRIVATE, ++ m_image->bytes_per_line * m_image->height, ++ IPC_CREAT|0777); ++ ++ m_shminfo.shmaddr = m_image->data = (char *)shmat(m_shminfo.shmid, 0, 0); ++ m_shminfo.readOnly = 0; ++ ++ TRACE("m_shminfo.shmaddr %p", m_shminfo.shmaddr); ++ ++ XShmAttach(m_display, &m_shminfo); ++ } ++ else ++ { ++ m_image = XCreateImage(m_display, ++ CopyFromParent, ++ 32, ++ ZPixmap, 0, (char *)vaddr, wnb->stride, wnb->height, 32, 0); ++ } ++ } ++ ++ ++ if (m_useShm) ++ { ++ memcpy(m_image->data, vaddr, m_image->bytes_per_line * m_image->height); ++ m_gralloc->unlock(m_gralloc, wnb->handle); ++ XShmPutImage(m_display, m_window, m_gc, m_image, 0, 0, 0, 0, m_width, m_height, 0); ++ } ++ else ++ { ++ m_image->data = (char *)vaddr; ++ XPutImage(m_display, m_window, m_gc, m_image, 0, 0, 0, 0, m_width, m_height); ++ m_gralloc->unlock(m_gralloc, wnb->handle); ++ } ++ ++ lock(); ++ ++ ++m_freeBufs; ++ HYBRIS_TRACE_COUNTER("x11-platform", "m_freeBufs", "%i", m_freeBufs); ++ for (it = m_bufList.begin(); it != m_bufList.end(); it++) ++ { ++ (*it)->youngest = 0; ++ } ++ wnb->youngest = 1; ++ wnb->busy = 0; ++ ++ unlock(); ++} ++ ++void X11NativeWindow::tryEnableDRIHybris() ++{ ++ const xcb_query_extension_reply_t *extension; ++ xcb_void_cookie_t cookie; ++ xcb_generic_error_t *error; ++ ++ xcb_prefetch_extension_data (m_connection, &xcb_drihybris_id); ++ xcb_prefetch_extension_data (m_connection, &xcb_present_id); ++ ++ extension = xcb_get_extension_data(m_connection, &xcb_drihybris_id); ++ if (!(extension && extension->present)) ++ return; ++ ++ extension = xcb_get_extension_data(m_connection, &xcb_present_id); ++ if (!(extension && extension->present)) ++ return; ++ ++ m_specialEventId = xcb_generate_id(m_connection); ++ m_specialEvent = xcb_register_for_special_xge(m_connection, ++ &xcb_present_id, m_specialEventId, NULL); ++ ++ cookie = xcb_present_select_input_checked(m_connection, ++ m_specialEventId, m_window, ++ XCB_PRESENT_EVENT_MASK_COMPLETE_NOTIFY | ++ XCB_PRESENT_EVENT_MASK_CONFIGURE_NOTIFY); ++ ++ error = xcb_request_check(m_connection, cookie); ++ if (error) { ++ return; ++ } ++ ++ m_haveDRIHybris = true; ++ // HYBRIS_PIXEL_FORMAT_RGBA_8888 is used in glamor for buffer import ++ m_format = HAL_PIXEL_FORMAT_RGBA_8888; ++} ++ ++void X11NativeWindow::handlePresentEvent(xcb_present_generic_event_t *ge) ++{ ++ switch (ge->evtype) { ++ case XCB_PRESENT_CONFIGURE_NOTIFY: { ++ xcb_present_configure_notify_event_t *ce = (xcb_present_configure_notify_event_t *) ge; ++ printf("XCB_PRESENT_CONFIGURE_NOTIFY: %dx%d\n", ce->width, ce->height); ++ resize(ce->width, ce->height); ++ break; ++ } ++ } ++} ++ ++void X11NativeWindowBuffer::pixmap_from_buffer(xcb_connection_t *connection, xcb_drawable_t drawable) ++{ ++ int32_t * fds; ++ fds = (int32_t *)calloc(handle->numFds, sizeof(int)); ++ for (int i = 0; i < handle->numFds; i++) { ++ fds[i] = dup(handle->data[i]); ++ } ++ ++ xcb_drihybris_pixmap_from_buffer_checked(connection, ++ (pixmap = xcb_generate_id(connection)), ++ drawable, ++ stride * height * 4, ++ this->width, height, stride, ++ 32, 32, ++ handle->numInts, ++ handle->numFds, ++ (const uint32_t *)(handle->data + handle->numFds), ++ (const int32_t *)fds); ++ xcb_flush(connection); ++ free(fds); ++} ++ ++// vim: noai:ts=4:sw=4:ss=4:expandtab +diff --git a/hybris/egl/platforms/x11/x11_window.h b/hybris/egl/platforms/x11/x11_window.h +new file mode 100644 +index 0000000..cceaee5 +--- /dev/null ++++ b/hybris/egl/platforms/x11/x11_window.h +@@ -0,0 +1,201 @@ ++/**************************************************************************************** ++ ** ++ ** Copyright (C) 2013 Jolla Ltd. ++ ** Contact: Carsten Munk ++ ** All rights reserved. ++ ** ++ ** This file is part of Wayland enablement for libhybris ++ ** ++ ** You may use this file under the terms of the GNU Lesser General ++ ** Public License version 2.1 as published by the Free Software Foundation ++ ** and appearing in the file license.lgpl included in the packaging ++ ** of this file. ++ ** ++ ** This library is free software; you can redistribute it and/or ++ ** modify it under the terms of the GNU Lesser General Public ++ ** License version 2.1 as published by the Free Software Foundation ++ ** and appearing in the file license.lgpl included in the packaging ++ ** of this file. ++ ** ++ ** This library is distributed in the hope that it will be useful, ++ ** but WITHOUT ANY WARRANTY; without even the implied warranty of ++ ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ ** Lesser General Public License for more details. ++ ** ++ ****************************************************************************************/ ++ ++#ifndef X11_WINDOW_H ++#define X11_WINDOW_H ++#include "nativewindowbase.h" ++#include ++#include ++extern "C" { ++#include ++#include ++#include ++#include ++#include ++} ++#include ++#include ++ ++class X11NativeWindowBuffer : public BaseNativeWindowBuffer ++{ ++public: ++ X11NativeWindowBuffer() : busy(0), youngest(0), other(0) {} ++ X11NativeWindowBuffer(ANativeWindowBuffer *other) ++ { ++ ANativeWindowBuffer::width = other->width; ++ ANativeWindowBuffer::height = other->height; ++ ANativeWindowBuffer::format = other->format; ++ ANativeWindowBuffer::usage = other->usage; ++ ANativeWindowBuffer::handle = other->handle; ++ ANativeWindowBuffer::stride = other->stride; ++ ++ this->busy = 0; ++ this->other = other; ++ this->youngest = 0; ++ this->pixmap = 0; ++ } ++ ++ int busy; ++ int youngest; ++ ANativeWindowBuffer *other; ++ xcb_pixmap_t pixmap; ++ ++ void pixmap_from_buffer(xcb_connection_t *connection, xcb_drawable_t drawable); ++}; ++ ++class ClientX11Buffer : public X11NativeWindowBuffer ++{ ++friend class X11NativeWindow; ++protected: ++ ClientX11Buffer() ++ : m_alloc(0) ++ {} ++ ++ ClientX11Buffer(alloc_device_t* alloc_device, ++ unsigned int width, ++ unsigned int height, ++ unsigned int format, ++ unsigned int usage) ++ { ++ // Base members ++ ANativeWindowBuffer::width = width; ++ ANativeWindowBuffer::height = height; ++ ANativeWindowBuffer::format = format; ++ ANativeWindowBuffer::usage = usage; ++ ++ this->busy = 0; ++ this->other = NULL; ++ this->m_alloc = alloc_device; ++ int alloc_ok = this->m_alloc->alloc(this->m_alloc, ++ this->width ? this->width : 1, this->height ? this->height : 1, ++ this->format, this->usage, ++ &this->handle, &this->stride); ++ assert(alloc_ok == 0); ++ this->youngest = 0; ++ this->common.incRef(&this->common); ++ this->pixmap = 0; ++ } ++ ++ ~ClientX11Buffer() ++ { ++ if (this->m_alloc) ++ m_alloc->free(m_alloc, this->handle); ++ } ++ ++protected: ++ void* vaddr; ++ alloc_device_t* m_alloc; ++ ++public: ++ ++}; ++ ++class X11NativeWindow : public BaseNativeWindow { ++public: ++ X11NativeWindow(Display* xl_display, Window xl_window, alloc_device_t* alloc, gralloc_module_t* gralloc); ++ ~X11NativeWindow(); ++ ++ void lock(); ++ void unlock(); ++ void frame(); ++ void resize(unsigned int width, unsigned int height); ++ void releaseBuffer(struct wl_buffer *buffer); ++ ++ virtual int setSwapInterval(int interval); ++ void prepareSwap(EGLint *damage_rects, EGLint damage_n_rects); ++ void finishSwap(); ++ ++protected: ++ // overloads from BaseNativeWindow ++ virtual int dequeueBuffer(BaseNativeWindowBuffer **buffer, int *fenceFd); ++ virtual int lockBuffer(BaseNativeWindowBuffer* buffer); ++ virtual int queueBuffer(BaseNativeWindowBuffer* buffer, int fenceFd); ++ virtual int cancelBuffer(BaseNativeWindowBuffer* buffer, int fenceFd); ++ virtual unsigned int type() const; ++ virtual unsigned int width() const; ++ virtual unsigned int height() const; ++ virtual unsigned int format() const; ++ virtual unsigned int defaultWidth() const; ++ virtual unsigned int defaultHeight() const; ++ virtual unsigned int queueLength() const; ++ virtual unsigned int transformHint() const; ++ virtual unsigned int getUsage() const; ++ // perform calls ++ virtual int setUsage(int usage); ++ virtual int setBuffersFormat(int format); ++ virtual int setBuffersDimensions(int width, int height); ++ virtual int setBufferCount(int cnt); ++ ++private: ++ X11NativeWindowBuffer *addBuffer(); ++ void destroyBuffer(X11NativeWindowBuffer *); ++ void destroyBuffers(); ++ int readQueue(bool block); ++ ++ void copyToX11(X11NativeWindowBuffer *wnb); ++ void tryEnableDRIHybris(); ++ void handlePresentEvent(xcb_present_generic_event_t *ge); ++ ++ std::list m_bufList; ++ std::list fronted; ++ std::list posted; ++ std::list post_registered; ++ std::deque queue; ++ ++ Display* m_display; ++ Window m_window; ++ XImage *m_image; ++ XShmSegmentInfo m_shminfo; ++ GC m_gc; ++ ++ xcb_connection_t *m_connection; ++ xcb_gcontext_t m_xcb_gc; ++ xcb_present_event_t m_specialEventId; ++ xcb_special_event_t *m_specialEvent; ++ ++ bool m_useShm; ++ bool m_haveDRIHybris; ++ ++ X11NativeWindowBuffer *m_lastBuffer; ++ unsigned int m_width; ++ unsigned int m_height; ++ unsigned int m_format; ++ unsigned int m_defaultWidth; ++ unsigned int m_defaultHeight; ++ unsigned int m_usage; ++ ++ alloc_device_t* m_alloc; ++ pthread_mutex_t mutex; ++ pthread_cond_t cond; ++ int m_queueReads; ++ int m_freeBufs; ++ EGLint *m_damage_rects, m_damage_n_rects; ++ int m_swap_interval; ++ gralloc_module_t *m_gralloc; ++}; ++ ++#endif ++// vim: noai:ts=4:sw=4:ss=4:expandtab +diff --git a/hybris/egl/platforms/x11/xcb_drihybris.c b/hybris/egl/platforms/x11/xcb_drihybris.c +new file mode 100644 +index 0000000..bec3722 +--- /dev/null ++++ b/hybris/egl/platforms/x11/xcb_drihybris.c +@@ -0,0 +1,167 @@ ++/* ++ * This file generated automatically from drihybris.xml by c_client.py. ++ * Edit at your peril. ++ */ ++ ++#include "xcb_drihybris.h" ++#include /* for offsetof() */ ++ ++xcb_extension_t xcb_drihybris_id = { "DRIHYBRIS", 0 }; ++ ++#define ALIGNOF(type) offsetof(struct { char dummy; type member; }, member) ++ ++int ++xcb_drihybris_pixmap_from_buffer_sizeof (const void *_buffer, ++ int32_t pixmap_fd) ++{ ++ char *xcb_tmp = (char *)_buffer; ++ const xcb_drihybris_pixmap_from_buffer_request_t *_aux = (xcb_drihybris_pixmap_from_buffer_request_t *)_buffer; ++ unsigned int xcb_buffer_len = 0; ++ unsigned int xcb_block_len = 0; ++ unsigned int xcb_pad = 0; ++ unsigned int xcb_align_to = 0; ++ ++ ++ xcb_block_len += sizeof(xcb_drihybris_pixmap_from_buffer_request_t); ++ xcb_tmp += xcb_block_len; ++ xcb_buffer_len += xcb_block_len; ++ xcb_block_len = 0; ++ /* ints */ ++ xcb_block_len += _aux->num_ints * sizeof(uint32_t); ++ xcb_tmp += xcb_block_len; ++ xcb_align_to = ALIGNOF(uint32_t); ++ /* insert padding */ ++ xcb_pad = -xcb_block_len & (xcb_align_to - 1); ++ xcb_buffer_len += xcb_block_len + xcb_pad; ++ if (0 != xcb_pad) { ++ xcb_tmp += xcb_pad; ++ xcb_pad = 0; ++ } ++ xcb_block_len = 0; ++ ++ return xcb_buffer_len; ++} ++ ++xcb_void_cookie_t ++xcb_drihybris_pixmap_from_buffer_checked (xcb_connection_t *c, ++ xcb_pixmap_t pixmap, ++ xcb_drawable_t drawable, ++ uint32_t size, ++ uint16_t width, ++ uint16_t height, ++ uint16_t stride, ++ uint8_t depth, ++ uint8_t bpp, ++ uint16_t num_ints, ++ uint16_t num_fds, ++ const uint32_t *ints, ++ const int32_t *fds) ++{ ++ static const xcb_protocol_request_t xcb_req = { ++ .count = 4, ++ .ext = &xcb_drihybris_id, ++ .opcode = XCB_DRIHYBRIS_PIXMAP_FROM_BUFFER, ++ .isvoid = 1 ++ }; ++ ++ struct iovec xcb_parts[6]; ++ xcb_void_cookie_t xcb_ret; ++ xcb_drihybris_pixmap_from_buffer_request_t xcb_out; ++ ++ xcb_out.pixmap = pixmap; ++ xcb_out.drawable = drawable; ++ xcb_out.size = size; ++ xcb_out.width = width; ++ xcb_out.height = height; ++ xcb_out.stride = stride; ++ xcb_out.depth = depth; ++ xcb_out.bpp = bpp; ++ xcb_out.num_ints = num_ints; ++ xcb_out.num_fds = num_fds; ++ ++ xcb_parts[2].iov_base = (char *) &xcb_out; ++ xcb_parts[2].iov_len = sizeof(xcb_out); ++ xcb_parts[3].iov_base = 0; ++ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3; ++ /* uint32_t ints */ ++ xcb_parts[4].iov_base = (char *) ints; ++ xcb_parts[4].iov_len = num_ints * sizeof(uint32_t); ++ xcb_parts[5].iov_base = 0; ++ xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3; ++ ++ xcb_ret.sequence = xcb_send_request_with_fds(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req, num_fds, fds); ++ return xcb_ret; ++} ++ ++xcb_void_cookie_t ++xcb_drihybris_pixmap_from_buffer (xcb_connection_t *c, ++ xcb_pixmap_t pixmap, ++ xcb_drawable_t drawable, ++ uint32_t size, ++ uint16_t width, ++ uint16_t height, ++ uint16_t stride, ++ uint8_t depth, ++ uint8_t bpp, ++ uint16_t num_ints, ++ uint16_t num_fds, ++ const uint32_t *ints, ++ const int32_t *fds) ++{ ++ static const xcb_protocol_request_t xcb_req = { ++ .count = 4, ++ .ext = &xcb_drihybris_id, ++ .opcode = XCB_DRIHYBRIS_PIXMAP_FROM_BUFFER, ++ .isvoid = 1 ++ }; ++ ++ struct iovec xcb_parts[6]; ++ xcb_void_cookie_t xcb_ret; ++ xcb_drihybris_pixmap_from_buffer_request_t xcb_out; ++ ++ xcb_out.pixmap = pixmap; ++ xcb_out.drawable = drawable; ++ xcb_out.size = size; ++ xcb_out.width = width; ++ xcb_out.height = height; ++ xcb_out.stride = stride; ++ xcb_out.depth = depth; ++ xcb_out.bpp = bpp; ++ xcb_out.num_ints = num_ints; ++ xcb_out.num_fds = num_fds; ++ ++ xcb_parts[2].iov_base = (char *) &xcb_out; ++ xcb_parts[2].iov_len = sizeof(xcb_out); ++ xcb_parts[3].iov_base = 0; ++ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3; ++ /* uint32_t ints */ ++ xcb_parts[4].iov_base = (char *) ints; ++ xcb_parts[4].iov_len = num_ints * sizeof(uint32_t); ++ xcb_parts[5].iov_base = 0; ++ xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3; ++ ++ xcb_ret.sequence = xcb_send_request_with_fds(c, 0, xcb_parts + 2, &xcb_req, num_fds, fds); ++ return xcb_ret; ++} ++ ++uint32_t * ++xcb_drihybris_pixmap_from_buffer_ints (const xcb_drihybris_pixmap_from_buffer_request_t *R) ++{ ++ return (uint32_t *) (R + 1); ++} ++ ++int ++xcb_drihybris_pixmap_from_buffer_ints_length (const xcb_drihybris_pixmap_from_buffer_request_t *R) ++{ ++ return R->num_ints; ++} ++ ++xcb_generic_iterator_t ++xcb_drihybris_pixmap_from_buffer_ints_end (const xcb_drihybris_pixmap_from_buffer_request_t *R) ++{ ++ xcb_generic_iterator_t i; ++ i.data = ((uint32_t *) (R + 1)) + (R->num_ints); ++ i.rem = 0; ++ i.index = (char *) i.data - (char *) R; ++ return i; ++} +diff --git a/hybris/egl/platforms/x11/xcb_drihybris.h b/hybris/egl/platforms/x11/xcb_drihybris.h +new file mode 100644 +index 0000000..974828d +--- /dev/null ++++ b/hybris/egl/platforms/x11/xcb_drihybris.h +@@ -0,0 +1,122 @@ ++/* ++ * This file generated automatically from drihybris.xml by c_client.py. ++ * Edit at your peril. ++ */ ++ ++/** ++ * @defgroup XCB_DRIHYBRIS_API XCB DRIHYBRIS API ++ * @brief DRIHYBRIS XCB Protocol Implementation. ++ * @{ ++ **/ ++ ++#ifndef DRIHYBRIS_PROTO_H ++#define DRIHYBRIS_PROTO_H ++ ++#include ++#include ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++#define XCB_DRIHYBRIS_MAJOR_VERSION 1 ++#define XCB_DRIHYBRIS_MINOR_VERSION 0 ++ ++extern xcb_extension_t xcb_drihybris_id; ++ ++/** Opcode for xcb_drihybris_pixmap_from_buffer. */ ++#define XCB_DRIHYBRIS_PIXMAP_FROM_BUFFER 1 ++ ++/** ++ * @brief xcb_drihybris_pixmap_from_buffer_request_t ++ **/ ++typedef struct xcb_drihybris_pixmap_from_buffer_request_t { ++ uint8_t major_opcode; ++ uint8_t minor_opcode; ++ uint16_t length; ++ xcb_pixmap_t pixmap; ++ xcb_drawable_t drawable; ++ uint32_t size; ++ uint16_t width; ++ uint16_t height; ++ uint16_t stride; ++ uint8_t depth; ++ uint8_t bpp; ++ uint16_t num_ints; ++ uint16_t num_fds; ++} xcb_drihybris_pixmap_from_buffer_request_t; ++ ++/** ++ * @brief xcb_drihybris_buffer_from_pixmap_cookie_t ++ **/ ++typedef struct xcb_drihybris_buffer_from_pixmap_cookie_t { ++ unsigned int sequence; ++} xcb_drihybris_buffer_from_pixmap_cookie_t; ++ ++int ++xcb_drihybris_pixmap_from_buffer_sizeof (const void *_buffer, ++ int32_t pixmap_fd); ++ ++/** ++ * ++ * @param c The connection ++ * @return A cookie ++ * ++ * Delivers a request to the X server. ++ * ++ * This form can be used only if the request will not cause ++ * a reply to be generated. Any returned error will be ++ * saved for handling by xcb_request_check(). ++ */ ++xcb_void_cookie_t ++xcb_drihybris_pixmap_from_buffer_checked (xcb_connection_t *c, ++ xcb_pixmap_t pixmap, ++ xcb_drawable_t drawable, ++ uint32_t size, ++ uint16_t width, ++ uint16_t height, ++ uint16_t stride, ++ uint8_t depth, ++ uint8_t bpp, ++ uint16_t num_ints, ++ uint16_t num_fds, ++ const uint32_t *ints, ++ const int32_t *fds); ++ ++/** ++ * ++ * @param c The connection ++ * @return A cookie ++ * ++ * Delivers a request to the X server. ++ * ++ */ ++xcb_void_cookie_t ++xcb_drihybris_pixmap_from_buffer (xcb_connection_t *c, ++ xcb_pixmap_t pixmap, ++ xcb_drawable_t drawable, ++ uint32_t size, ++ uint16_t width, ++ uint16_t height, ++ uint16_t stride, ++ uint8_t depth, ++ uint8_t bpp, ++ uint16_t num_ints, ++ uint16_t num_fds, ++ const uint32_t *ints, ++ const int32_t *fds); ++ ++uint32_t * ++xcb_drihybris_pixmap_from_buffer_ints (const xcb_drihybris_pixmap_from_buffer_request_t *R); ++ ++int ++xcb_drihybris_pixmap_from_buffer_ints_length (const xcb_drihybris_pixmap_from_buffer_request_t *R); ++ ++xcb_generic_iterator_t ++xcb_drihybris_pixmap_from_buffer_ints_end (const xcb_drihybris_pixmap_from_buffer_request_t *R); ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif //DRIHYBRIS_PROTO_H +diff --git a/hybris/egl/ws.c b/hybris/egl/ws.c +index b10c704..36bc180 100644 +--- a/hybris/egl/ws.c ++++ b/hybris/egl/ws.c +@@ -118,4 +118,13 @@ void ws_setSwapInterval(EGLDisplay dpy, EGLNativeWindowType win, EGLint interval + ws->setSwapInterval(dpy, win, interval); + } + ++EGLBoolean ws_eglGetConfigAttrib(struct _EGLDisplay *display, EGLConfig config, EGLint attribute, EGLint *value) ++{ ++ _init_ws(); ++ if (ws->eglGetConfigAttrib) ++ return ws->eglGetConfigAttrib(display, config, attribute, value); ++ else ++ return EGL_FALSE; ++} ++ + // vim:ts=4:sw=4:noexpandtab +diff --git a/hybris/egl/ws.h b/hybris/egl/ws.h +index c4811c0..92b221a 100644 +--- a/hybris/egl/ws.h ++++ b/hybris/egl/ws.h +@@ -37,6 +37,7 @@ struct ws_module { + void (*prepareSwap)(EGLDisplay dpy, EGLNativeWindowType win, EGLint *damage_rects, EGLint damage_n_rects); + void (*finishSwap)(EGLDisplay dpy, EGLNativeWindowType win); + void (*setSwapInterval)(EGLDisplay dpy, EGLNativeWindowType win, EGLint interval); ++ EGLBoolean (*eglGetConfigAttrib)(struct _EGLDisplay *display, EGLConfig config, EGLint attribute, EGLint *value); + }; + + struct _EGLDisplay *ws_GetDisplay(EGLNativeDisplayType native); +@@ -49,5 +50,6 @@ const char *ws_eglQueryString(EGLDisplay dpy, EGLint name, const char *(*real_eg + void ws_prepareSwap(EGLDisplay dpy, EGLNativeWindowType win, EGLint *damage_rects, EGLint damage_n_rects); + void ws_finishSwap(EGLDisplay dpy, EGLNativeWindowType win); + void ws_setSwapInterval(EGLDisplay dpy, EGLNativeWindowType win, EGLint interval); ++EGLBoolean ws_eglGetConfigAttrib(struct _EGLDisplay *display, EGLConfig config, EGLint attribute, EGLint *value); + + #endif +-- +2.15.1 + diff --git a/hybris/libhybris/APKBUILD b/hybris/libhybris/APKBUILD new file mode 100644 index 000000000..60b010f43 --- /dev/null +++ b/hybris/libhybris/APKBUILD @@ -0,0 +1,151 @@ +pkgname=libhybris +pkgver=1.0_git20180212 +pkgrel=1 +arch="armhf aarch64" +url="https://github.com/libhybris/libhybris" +license="Apache" +makedepends="autoconf automake libtool wayland-dev linux-headers bsd-compat-headers + libx11-dev libxcb-dev libxext-dev + android-headers-7.1 android-headers-7.1-caf android-headers-4.4" +depends_dev="bsd-compat-headers android-headers-7.1" +_rev=54dd4749706334882f9c404fca01a19f01325d07 +source="$pkgname-$_rev.tar.gz::https://github.com/libhybris/libhybris/archive/$_rev.tar.gz + 0001-Make-libhybris-compile-with-musl.patch + 0002-tests-Regression-test-for-EGL-glibc-TLS-conflict.patch + 0003-Implement-X11-EGL-platform-based-on-wayland-code.patch" + +pkgdesc="libhybris allows to use bionic-based HW adaptations" +subpackages="$pkgname-dev $pkgname-egl $pkgname-gles $pkgname-libwayland-egl:_wayland + $pkgname-7.1:_specific $pkgname-7.1-caf:_specific $pkgname-4.4:_specific" + +if [ "$CARCH" == "aarch64" ]; then +subpackages="$pkgname-dev $pkgname-egl $pkgname-gles $pkgname-libwayland-egl:_wayland + $pkgname-7.1:_specific $pkgname-7.1-caf:_specific" +fi + +options="!check !strip !tracedeps" + +builddir="$srcdir/$pkgname-$_rev" +_tmppkgdir="$srcdir/tmpinstall" +_main_headers_ver=7.1 + +_bins_specific="test_audio test_camera test_egl_configs test_gps + test_hwcomposer test_input test_lights test_media test_nfc + test_recorder test_sensors test_sf test_vibrator test_wifi" + +_libs_specific="libcamera.so.1.0.0 libhardware.so.2.0.0 + libhybris-common.so.1.0.0 libhybris-eglplatformcommon.so.1.0.0 + libhybris-hwcomposerwindow.so.1.0.0 libis.so.1.0.0 libmedia.so.1 + libmedia.so.1.0.0 libnfc_ndef_nxp.so.1.0.0 libnfc_nxp.so.1.0.0 + libsf.so.1.0.0 libsync.so.2.0.0 libui.so.1.0.0 libvibrator.so.1.0.0 + libwifi.so.1.0.0 + libhybris/eglplatform_fbdev.so libhybris/eglplatform_hwcomposer.so + libhybris/eglplatform_null.so libhybris/eglplatform_wayland.so + libhybris/eglplatform_x11.so" + +build() { + cd "$builddir/hybris" + + NOCONFIGURE=1 ./autogen.sh + + if [ "$CARCH" == "armhf" ]; then + _vers="7.1 7.1-caf 4.4" + _ldpath="/usr/libexec/droid-hybris/system/lib:/vendor/lib:/system/lib" + _arch="arm" + elif [ "$CARCH" == "aarch64" ]; then + _vers="7.1 7.1-caf" + _ldpath="/usr/libexec/droid-hybris/system/lib64:/vendor/lib64:/system/lib64" + _arch="arm64" + fi + + for _headers_ver in $_vers; do + msg "building $pkgname-$_headers_ver" + ./configure \ + --prefix=/usr \ + --enable-wayland \ + --enable-trace \ + --enable-debug \ + --enable-experimental \ + --with-android-headers=/usr/include/android-$_headers_ver \ + --with-default-hybris-ld-library-path=$_ldpath \ + --enable-arch=$_arch \ + --enable-property-cache + make DESTDIR="${_tmppkgdir}/$pkgname-$_headers_ver" install + done +} + +package() { + cd "$builddir/hybris" + + # make DESTDIR="${pkgdir}" install + mkdir -p "${pkgdir}" + cp -a ${_tmppkgdir}/$pkgname-$_main_headers_ver/* "${pkgdir}" + + for _bin in ${_bins_specific}; do + rm "${pkgdir}/usr/bin/${_bin}" + done + + for _lib in ${_libs_specific}; do + rm "${pkgdir}/usr/lib/${_lib}" + done +} + +_specific() { + for _bin in ${_bins_specific}; do + install -Dm755 "${_tmppkgdir}/${subpkgname}/usr/bin/${_bin}" \ + "${subpkgdir}/usr/bin/${_bin}" + done + + for _lib in ${_libs_specific}; do + install -Dm755 "${_tmppkgdir}/${subpkgname}/usr/lib/${_lib}" \ + "${subpkgdir}/usr/lib/${_lib}" + done +} + +egl() { + options="!tracedeps" + pkgdesc="libhybris libEGL runtime libraries" + install -d "$subpkgdir"/usr/lib + mv "$pkgdir"/usr/lib/libEGL.so.* \ + "$subpkgdir"/usr/lib/ +} + +gles() { + options="!tracedeps" + pkgdesc="libhybris libGLESv2 runtime libraries" + install -d "$subpkgdir"/usr/lib + mv "$pkgdir"/usr/lib/libGLES*.so.* \ + "$subpkgdir"/usr/lib/ +} + +_wayland() { + pkgdesc="libhybris libwayland-egl library" + mkdir -p "$subpkgdir"/usr/lib + mv "$pkgdir"/usr/lib/libwayland-egl.so.* "$subpkgdir"/usr/lib/ \ + || return 1 +} + +dev() { + default_dev + + # Avoid conflicts with mesa-dev + rm -f "$subpkgdir"/usr/lib/lib*GL*.so + rm -f "$subpkgdir"/usr/lib/libwayland-egl.so + + cd "$subpkgdir"/usr/lib/pkgconfig + rm -f egl.pc glesv*.pc wayland-egl.pc + + cd "$subpkgdir"/usr/include + # Move libhybris-provided headers into hybris dir + mv CL EGL GLES GLES2 KHR VG hybris + + # Symlink eglhybris.h + mkdir -p EGL + cd EGL + ln -s ../hybris/EGL/eglhybris.h . +} + +sha512sums="798360130e540d9dd29ec937b3d01a1b146881c45ec6a2dd1a599a0164d46886b58927d38575993b525a06e99fcc2dd46f020e70f7e5c7cc43258b840ae183f8 libhybris-54dd4749706334882f9c404fca01a19f01325d07.tar.gz +9655816dc3d89f329801a74f4499c3752cbc96f7ba2e052765335a2cbd7e74cdf45064260ab27537bcd9d64673144eac6f89e31af4b4c6b4a4792ad7b398555d 0001-Make-libhybris-compile-with-musl.patch +1355a4403d1af8bdf75b9e4502cbfc093b9788224ce7c24a1f6a53dd7996d385d31a3362577a4293db6b6d0dd0ae4e88140b38c658ff0a288d9acfc2753859bb 0002-tests-Regression-test-for-EGL-glibc-TLS-conflict.patch +f7d7b460af5f13c37289d7eadfa5eb52248a4a5379a1da07b74231eb4fc9c1ccda6644bcd39bbae89bd068d7f3f6c5fe4e9ae6b41991c1f3b48d6b4d59d951d8 0003-Implement-X11-EGL-platform-based-on-wayland-code.patch"