From 3ac005ddf77a4292608517650df43db9d8684707 Mon Sep 17 00:00:00 2001 From: NicJA Date: Wed, 17 Apr 2019 23:37:32 +0000 Subject: [PATCH] add missing files and rename the mmakefile.src - but disable currently since it needs reworked. Mesa dropped the OpenVG and EGL state trackers from gallium in 2015. EGL support needs to use a different interface (TODO:). git-svn-id: https://svn.aros.org/svn/aros/trunk/AROS@56291 fb15a70f-31f2-0310-bbcc-cdcc74a49acc --- workbench/libs/egl/emul_arosc.c | 107 +++++++++++++++++++++++++++++++ workbench/libs/egl/mmakefile.src | 51 +++++++++++++++ workbench/libs/egl/mmakefile.txt | 74 ---------------------- workbench/libs/egl/tls.c | 132 +++++++++++++++++++++++++++++++++++++++ workbench/libs/egl/tls.h | 39 ++++++++++++ 5 files changed, 329 insertions(+), 74 deletions(-) create mode 100644 workbench/libs/egl/emul_arosc.c create mode 100644 workbench/libs/egl/mmakefile.src delete mode 100644 workbench/libs/egl/mmakefile.txt create mode 100644 workbench/libs/egl/tls.c create mode 100644 workbench/libs/egl/tls.h diff --git a/workbench/libs/egl/emul_arosc.c b/workbench/libs/egl/emul_arosc.c new file mode 100644 index 0000000000..74dc8e44ca --- /dev/null +++ b/workbench/libs/egl/emul_arosc.c @@ -0,0 +1,107 @@ +/* + Copyright © 2009-2019, The AROS Development Team. All rights reserved. + $Id: emul_arosc.c 56280 2019-04-17 18:42:57Z NicJA $ +*/ + +#include + +#include +#include + +#include +#include + +#define IMPLEMENT() bug("------IMPLEMENT(%s)\n", __func__) + +/* + The purpose of this file is to provide implementation for C functions part + of arosnixc.library in code where one does not want to use this library. +*/ + +struct timezone; + +int gettimeofday (struct timeval * tv,struct timezone * tz) +{ + struct MsgPort * timerport = CreateMsgPort(); + struct timerequest * timereq = (struct timerequest *)CreateIORequest(timerport, sizeof(*timereq)); + + + if (timereq) + { + if (OpenDevice("timer.device", UNIT_VBLANK, (struct IORequest *)timereq, 0) == 0) + { + #define TimerBase ((struct Device *)timereq->tr_node.io_Device) + + GetSysTime(tv); + + #undef TimerBase + + CloseDevice((struct IORequest *)timereq); + } + } + + DeleteIORequest((struct IORequest *)timereq); + DeleteMsgPort(timerport); + + return 0; +} + +int usleep (useconds_t usec) +{ + IMPLEMENT(); + return 0; +} + +/* + This implementation of atexit is different than the definition of atexit + function due to how libraries work in AROS. + + Under Linux, when an .so file is used by an application, the library's code + is being shared but the library's data (global, static variables) are COPIED for + each process. Then, an atexit call inside .so will only operate on COPY of data + and thus can for example free memory allocated by one process without + influencing other processes. + + Under AROS, when a .library file is used by an application, library code AND + library data is shared. This means, an atexit call inside .library which was + initially coded under Linux cannot be executed when process is finishing + (for example at CloseLibrary) because such call will most likely free shared + data which will make other processes crash. The best approximation of atexit + in case of .library is to call the atexit functions at library expunge/exit. + + TODO: Check atexit() usage and determine best time to call atexit registered + functions. +*/ + +static struct exit_list { + struct exit_list *next; + void (*func)(void); +} *exit_list = NULL; + +int atexit(void (*function)(void)) +{ + struct exit_list *el; + + el = malloc(sizeof(*el)); + if (el == NULL) + return -1; + + el->next = exit_list; + el->func = function; + exit_list = el; + + return 0; +} + +void __exit_emul(void) +{ + while (exit_list) { + struct exit_list *el = exit_list->next; + + exit_list->func(); + free(exit_list); + exit_list = el; + } +} + +ADD2EXIT(__exit_emul, 0); diff --git a/workbench/libs/egl/mmakefile.src b/workbench/libs/egl/mmakefile.src new file mode 100644 index 0000000000..83023b621f --- /dev/null +++ b/workbench/libs/egl/mmakefile.src @@ -0,0 +1,51 @@ +# $Id: mmakefile.src -1 $ + +include $(SRCDIR)/config/aros.cfg +include $(SRCDIR)/workbench/libs/mesa/mesa.cfg + +EGL_PATH = $(top_srcdir)/src/egl +include $(EGL_PATH)/Makefile.sources + +################################################################################ +# EGL # +################################################################################ + +##MM workbench-libs-egl : includes workbench-libs-mesa-linklib workbench-libs-vega-linklib \ +##MM workbench-libs-gallium-linklib + +EGL_SOURCES = \ + $(addprefix $(EGL_PATH)/$(filter %.c, $(LIBEGL_C_FILES))) \ + egl_arosmesa + +SHARED_LIB_SOURCES = \ + emul_arosc \ + tls + +LIBRARY_SOURCES = \ + $(EGL_SOURCES) \ + $(SHARED_LIB_SOURCES) + +USER_INCLUDES += \ + -I$(EGL_PATH)/main + +USER_CPPFLAGS := -DFEATURE_GL=1 \ + -DFEATURE_VG=1 \ + -D_EGL_NATIVE_PLATFORM=_EGL_PLATFORM_AROS \ + -D_EGL_OS_AROS=1 \ + -DHAVE_AROS_BACKEND + +USER_LDFLAGS := \ + -L$(top_libdir) \ + -lcompiler -lgalliumauxiliary -lmesautil \ + -lpthread -lposixc -lstdcio -lstdc +ifneq ($(TARGET_LIBATOMIC),) +USER_LDFLAGS += $(TARGET_CXX_LIBS) +endif + +#%build_module mmake=workbench-libs-egl \ +# modname=egl modtype=library linklibname=EGL \ +# files="$(LIBRARY_SOURCES)" \ +# uselibs="" + +%common + diff --git a/workbench/libs/egl/mmakefile.txt b/workbench/libs/egl/mmakefile.txt deleted file mode 100644 index 2aa0bb7892..0000000000 --- a/workbench/libs/egl/mmakefile.txt +++ /dev/null @@ -1,74 +0,0 @@ -# $Id: mmakefile.src -1 $ - -include $(SRCDIR)/config/aros.cfg - -################################################################################ -# EGL # -################################################################################ - -#MM workbench-libs-egl : includes workbench-libs-mesa-linklib workbench-libs-vega-linklib \ -#MM workbench-libs-gallium-linklib - -SHARED_LIB_SOURCES = \ - aros/emul_arosc \ - aros/tls \ - -EGL_SOURCES = \ - egl/main/eglapi \ - egl/main/eglarray \ - egl/main/eglconfig \ - egl/main/eglcontext \ - egl/main/eglcurrent \ - egl/main/egldisplay \ - egl/main/egldriver \ - egl/main/eglfallbacks \ - egl/main/eglglobals \ - egl/main/eglimage \ - egl/main/egllog \ - egl/main/eglmisc \ - egl/main/eglmode \ - egl/main/eglscreen \ - egl/main/eglstring \ - egl/main/eglsurface \ - egl/main/eglsync \ - egl/drivers/arosmesa/egl_arosmesa \ - gallium/state_trackers/egl/common/egl_g3d \ - gallium/state_trackers/egl/common/egl_g3d_api \ - gallium/state_trackers/egl/common/egl_g3d_image \ - gallium/state_trackers/egl/common/egl_g3d_st \ - gallium/state_trackers/egl/common/egl_g3d_sync \ - gallium/state_trackers/egl/common/native_helper \ - gallium/state_trackers/egl/aros/native_aros \ - gallium/targets/egl-static/egl \ - gallium/targets/egl-static/egl_st \ - gallium/targets/egl-static/st_GL \ - gallium/targets/egl-static/st_OpenVG \ - -LIBRARY_SOURCES = \ - $(addprefix ../../, $(EGL_SOURCES)) \ - $(addprefix ../../, $(SHARED_LIB_SOURCES)) - -USER_INCLUDES := \ - -I$(AROS_DEVELOPER)/include/gallium \ - -I$(SRCDIR)/$(CURDIR)/../../gallium/state_trackers/egl \ - -I$(SRCDIR)/$(CURDIR)/../../gallium/state_trackers/vega \ - -I$(SRCDIR)/$(CURDIR)/../../egl/main \ - -I$(SRCDIR)/$(CURDIR)/../../mesa \ - -I$(SRCDIR)/$(CURDIR)/../../gallium/include \ - -I$(SRCDIR)/$(CURDIR)/../.. \ - -USER_CPPFLAGS := -DFEATURE_GL=1 \ - -DFEATURE_VG=1 \ - -D_EGL_BUILT_IN_DRIVER_GALLIUM \ - -D_EGL_NATIVE_PLATFORM=_EGL_PLATFORM_AROS \ - -D_EGL_OS_AROS=1 \ - -DHAVE_AROS_BACKEND \ - -D_EGL_MAIN=_eglBuiltInDriverGALLIUM \ - -%build_module mmake=workbench-libs-egl \ - modname=egl modtype=library linklibname=EGL \ - files="$(LIBRARY_SOURCES)" \ - uselibs="galliumauxiliary gallium GL OpenVG stdcio stdc" - -%common - diff --git a/workbench/libs/egl/tls.c b/workbench/libs/egl/tls.c new file mode 100644 index 0000000000..ec626b96fb --- /dev/null +++ b/workbench/libs/egl/tls.c @@ -0,0 +1,132 @@ +/* + Copyright 2010-2019, The AROS Development Team. All rights reserved. + $Id: tls.c 56280 2019-04-17 18:42:57Z NicJA $ +*/ + +#include "tls.h" + +#include + +struct TaskLocalNode +{ + struct TaskLocalNode * tl_Succ; + struct Task * tl_Task; + APTR tl_Data; +}; + +struct TaskLocalStorage +{ + struct TaskLocalNode * tls_Head; + struct SignalSemaphore tls_WriteSemaphore; +}; + +/* Implementation uses locking only when adding objects. Objects are always added + at head. The list is never reordered, thus reading can be done without locking */ + +/* This approach is used to achieve acceptable performance. With semaphore-locking + of read path, the performance was degraded several times. The TLS is used to + hold current per-task GL context - retrieving this context MUST BE fast */ + +struct TaskLocalStorage * CreateTLS() +{ + struct TaskLocalStorage * tls = + AllocVec(sizeof(struct TaskLocalStorage), MEMF_PUBLIC | MEMF_CLEAR); + + InitSemaphore(&tls->tls_WriteSemaphore); + tls->tls_Head = NULL; + + return tls; +} + +VOID InsertIntoTLS(struct TaskLocalStorage * tls, APTR ptr) +{ + struct TaskLocalNode * tl = tl = tls->tls_Head; + struct Task * me = FindTask(NULL); + struct TaskLocalNode * selected = NULL; + + /* Assumption: one task cannot be reviewing the list and adding the head + "at the same time" - do not alter this function to recurse */ + /* Assumption: only task A can add entry for task A */ + + /* Check if task's storage is already on the list */ + while(tl) + { + if (tl->tl_Task == me) + { + selected = tl; + break; + } + tl = tl->tl_Succ; + } + + if (!selected) + { + /* No, it is not. Create, set task pointer and at to head of list */ + selected = AllocVec(sizeof(struct TaskLocalNode), MEMF_PUBLIC | MEMF_CLEAR); + selected->tl_Task = me; + ObtainSemaphore(&tls->tls_WriteSemaphore); + selected->tl_Succ = tls->tls_Head; + tls->tls_Head = selected; + ReleaseSemaphore(&tls->tls_WriteSemaphore); + + } + + /* Set the passed value */ + selected->tl_Data = ptr; +} + +VOID ClearFromTLS(struct TaskLocalStorage * tls) +{ + /* Clearing is inserting a NULL. Element can't be removed from list - since + there is no read locking, altering structure of list when other tasks + are reading it, would cause crashes */ + /* TODO: How real clearing can be achieved: + * a) acquire write lock + * b) copy all element (copy not relink!) from _current list to _new list except for the element that + * is beeing cleared + * c) _old = _current, _current = _new + * d) release write lock + * + * How to delete _old? It can't be deleted right away, because some read tasks can be iterating over it. + * a) put it on garbage collect list (the whole list, not relinking nodes!) and clear it when shutting down + * b) use memory pool to allocate all TLS objects and clear pool at shutdown + * + * Solution b is much easier and convenient + */ + InsertIntoTLS(tls, NULL); +} + +APTR GetFromTLS(struct TaskLocalStorage * tls) +{ + struct TaskLocalNode * tl = tls->tls_Head; + struct Task * me = FindTask(NULL); + APTR data = NULL; + + while(tl) + { + if (tl->tl_Task == me) + { + data = tl->tl_Data; + break; + } + tl = tl->tl_Succ; + } + + return data; +} + +VOID DestroyTLS(struct TaskLocalStorage * tls) +{ + /* Destroy needs no lock. If a task is still iterating over list, we are doomed + anyway */ + struct TaskLocalNode * tl = tls->tls_Head, * temp; + + while (tl) + { + temp = tl->tl_Succ; + FreeVec(tl); + tl = temp; + } + + FreeVec(tls); +} diff --git a/workbench/libs/egl/tls.h b/workbench/libs/egl/tls.h new file mode 100644 index 0000000000..a766dd08e3 --- /dev/null +++ b/workbench/libs/egl/tls.h @@ -0,0 +1,39 @@ +/* + Copyright 2010-2011, The AROS Development Team. All rights reserved. + $Id: tls.h 56280 2019-04-17 18:42:57Z NicJA $ +*/ + +#ifndef TLS_H +#define TLS_H + +#include +#include + +struct TaskLocalStorage; + +struct TaskLocalStorage * CreateTLS(); +VOID InsertIntoTLS(struct TaskLocalStorage * tls, APTR ptr); +APTR GetFromTLS(struct TaskLocalStorage * tls); +VOID ClearFromTLS(struct TaskLocalStorage * tls); +VOID DestroyTLS(struct TaskLocalStorage * tls); + +#define DECLARE_STATIC_TLS(tls) \ +static struct TaskLocalStorage * tls = NULL; \ +static LONG auto_create_##tls() \ +{ \ + tls = CreateTLS(); \ + if (tls) \ + return 1; \ + else \ + return 0; \ +} \ + \ +static VOID auto_destroy_##tls() \ +{ \ + if (tls) \ + DestroyTLS(tls); \ +} \ +ADD2INIT(auto_create_##tls, 5); \ +ADD2EXIT(auto_destroy_##tls, 5); + +#endif /* TLS_H */ -- 2.11.4.GIT