From f9e0f5462051515861ee6757465efb46b225abab Mon Sep 17 00:00:00 2001 From: TheBrokenRail Date: Tue, 4 Jun 2024 18:29:13 -0400 Subject: [PATCH] WIP Trampoline Changes --- .gitmodules | 3 + cmake/options/extra-options.cmake | 14 +- dependencies/CMakeLists.txt | 6 +- dependencies/qemu/CMakeLists.txt | 56 -- dependencies/qemu/trampoline.patch | 56 -- dependencies/trampoline/CMakeLists.txt | 16 + dependencies/trampoline/src | 1 + launcher/CMakeLists.txt | 3 + launcher/src/bootstrap.cpp | 10 +- libreborn/CMakeLists.txt | 4 +- libreborn/include/libreborn/config.h.in | 2 +- media-layer/trampoline/CMakeLists.txt | 12 +- media-layer/trampoline/src/GLESv1_CM.c | 581 --------------- media-layer/trampoline/src/GLESv1_CM.cpp | 660 ++++++++++++++++++ media-layer/trampoline/src/common/common.h | 18 +- .../src/guest/{guest.c => guest.cpp} | 6 +- media-layer/trampoline/src/guest/guest.h | 61 +- .../trampoline/src/host/{host.c => host.cpp} | 6 +- media-layer/trampoline/src/host/host.h | 48 +- ...edia-layer-core.c => media-layer-core.cpp} | 112 ++- 20 files changed, 867 insertions(+), 808 deletions(-) delete mode 100644 dependencies/qemu/CMakeLists.txt delete mode 100644 dependencies/qemu/trampoline.patch create mode 100644 dependencies/trampoline/CMakeLists.txt create mode 160000 dependencies/trampoline/src delete mode 100644 media-layer/trampoline/src/GLESv1_CM.c create mode 100644 media-layer/trampoline/src/GLESv1_CM.cpp rename media-layer/trampoline/src/guest/{guest.c => guest.cpp} (50%) rename media-layer/trampoline/src/host/{host.c => host.cpp} (53%) rename media-layer/trampoline/src/{media-layer-core.c => media-layer-core.cpp} (58%) diff --git a/.gitmodules b/.gitmodules index c9727407..bfb0ea3f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -22,3 +22,6 @@ [submodule "dependencies/symbol-processor/src"] path = dependencies/symbol-processor/src url = https://gitea.thebrokenrail.com/minecraft-pi-reborn/symbol-processor.git +[submodule "dependencies/trampoline/src"] + path = dependencies/trampoline/src + url = https://gitea.thebrokenrail.com/minecraft-pi-reborn/trampoline.git diff --git a/cmake/options/extra-options.cmake b/cmake/options/extra-options.cmake index 18c237e1..5b3e70a4 100644 --- a/cmake/options/extra-options.cmake +++ b/cmake/options/extra-options.cmake @@ -27,7 +27,7 @@ if(NOT MCPI_HEADLESS_MODE) if(BUILD_NATIVE_COMPONENTS AND NOT IS_ARM_TARGETING) set(DEFAULT_USE_MEDIA_LAYER_TRAMPOLINE TRUE) endif() - mcpi_option(USE_MEDIA_LAYER_TRAMPOLINE "Whether To Enable The Media Layer Trampoline (Requires QEMU)" BOOL "${DEFAULT_USE_MEDIA_LAYER_TRAMPOLINE}") + mcpi_option(USE_MEDIA_LAYER_TRAMPOLINE "Whether To Enable The Media Layer Trampoline" BOOL "${DEFAULT_USE_MEDIA_LAYER_TRAMPOLINE}") mcpi_option(USE_GLES1_COMPATIBILITY_LAYER "Whether To Enable The GLESv1_CM Compatibility Layer" BOOL TRUE) else() set(MCPI_USE_MEDIA_LAYER_TRAMPOLINE FALSE) @@ -38,14 +38,10 @@ else() set(BUILD_MEDIA_LAYER_CORE "${BUILD_ARM_COMPONENTS}") endif() -# QEMU -if(BUILD_NATIVE_COMPONENTS) - include(CheckSymbolExists) - check_symbol_exists("__ARM_ARCH" "" MCPI_IS_ARM32_OR_ARM64_TARGETING) - set(MCPI_USE_QEMU TRUE) - if(MCPI_IS_ARM32_OR_ARM64_TARGETING AND NOT MCPI_USE_MEDIA_LAYER_TRAMPOLINE) - set(MCPI_USE_QEMU FALSE) - endif() +# Trampoline Host +set(MCPI_USE_TRAMPOLINE_HOST FALSE) +if(BUILD_NATIVE_COMPONENTS AND (MCPI_USE_MEDIA_LAYER_TRAMPOLINE OR NOT IS_ARM_TARGETING)) + set(MCPI_USE_TRAMPOLINE_HOST TRUE) endif() # Specify Variant Name diff --git a/dependencies/CMakeLists.txt b/dependencies/CMakeLists.txt index c6133041..70f1155a 100644 --- a/dependencies/CMakeLists.txt +++ b/dependencies/CMakeLists.txt @@ -16,10 +16,8 @@ endif() if(BUILD_NATIVE_COMPONENTS OR (BUILD_MEDIA_LAYER_CORE AND NOT MCPI_HEADLESS_MODE)) add_subdirectory(LIEF) endif() -# QEMU -if(BUILD_NATIVE_COMPONENTS AND MCPI_USE_QEMU) - add_subdirectory(qemu) -endif() +# Trampoline +add_subdirectory(trampoline) # GLFW if(BUILD_MEDIA_LAYER_CORE AND NOT MCPI_HEADLESS_MODE) add_subdirectory(glfw) diff --git a/dependencies/qemu/CMakeLists.txt b/dependencies/qemu/CMakeLists.txt deleted file mode 100644 index b6720ca1..00000000 --- a/dependencies/qemu/CMakeLists.txt +++ /dev/null @@ -1,56 +0,0 @@ -project(qemu) - -## QEMU - -# Version -set(QEMU_VERSION "9.0.0") - -# Flatpak Support -set(QEMU_FLATPAK_PATCH "") -if(MCPI_IS_FLATPAK_BUILD) - set(QEMU_FLATPAK_PATCH "sed" "-i" "s/libdrm/libdrm-dis/g" "/meson.build") -endif() - -# Build -include(ExternalProject) -set(PKGCONFIG_ENV "") -if(DEFINED ENV{PKG_CONFIG_LIBDIR}) - set(PKGCONFIG_ENV "PKG_CONFIG_LIBDIR=$ENV{PKG_CONFIG_LIBDIR}") -endif() -ExternalProject_Add(qemu - URL "${CMAKE_CURRENT_SOURCE_DIR}/../../archives/qemu-${QEMU_VERSION}.tar.xz" - # Configure Build - CONFIGURE_COMMAND - "${CMAKE_COMMAND}" "-E" "env" - ${PKGCONFIG_ENV} - "CFLAGS=-s" - "CXXFLAGS=-s" - "/configure" - "--prefix=${CMAKE_INSTALL_PREFIX}" - "--cross-prefix=" - "--cc=${CMAKE_C_COMPILER}" - "--cxx=${CMAKE_CXX_COMPILER}" - "--extra-ldflags=-ldl -Wl,-rpath=$ORIGIN/../lib/native -Wl,--disable-new-dtags" - "--disable-debug-info" - "--target-list=arm-linux-user" - "--without-default-features" - USES_TERMINAL_CONFIGURE TRUE - # Build Command - BUILD_COMMAND "ninja" "qemu-arm" - BUILD_BYPRODUCTS "/qemu-arm" - USES_TERMINAL_BUILD TRUE - # Disable Install/Test Commands - INSTALL_COMMAND "" - TEST_COMMAND "" - # Patch Command - PATCH_COMMAND "patch" "-p1" "<" "${CMAKE_CURRENT_SOURCE_DIR}/trampoline.patch" - COMMAND ${QEMU_FLATPAK_PATCH} -) - -# Install -ExternalProject_Get_property(qemu BINARY_DIR) -install(PROGRAMS "${BINARY_DIR}/qemu-arm" DESTINATION "${MCPI_BIN_DIR}") - -# License -ExternalProject_Get_property(qemu SOURCE_DIR) -install(FILES "${SOURCE_DIR}/COPYING" DESTINATION "${MCPI_LEGAL_DIR}/qemu") diff --git a/dependencies/qemu/trampoline.patch b/dependencies/qemu/trampoline.patch deleted file mode 100644 index 1ff1870c..00000000 --- a/dependencies/qemu/trampoline.patch +++ /dev/null @@ -1,56 +0,0 @@ ---- a/linux-user/syscall.c -+++ b/linux-user/syscall.c -@@ -17,6 +17,7 @@ - * along with this program; if not, see . - */ - #define _ATFILE_SOURCE -+#include - #include "qemu/osdep.h" - #include "qemu/cutils.h" - #include "qemu/path.h" -@@ -9070,6 +9071,17 @@ _syscall5(int, sys_move_mount, int, __from_dfd, const char *, __from_pathname, - int, __to_dfd, const char *, __to_pathname, unsigned int, flag) - #endif - -+// g2h For Trampoline -+static CPUState *_trampoline_g2h_cpu = NULL; -+static void *_trampoline_g2h(uint32_t guest_addr) { -+ if (guest_addr == 0) { -+ return NULL; -+ } -+ return g2h(_trampoline_g2h_cpu, guest_addr); -+} -+// Trampoline Function -+typedef void (*_trampoline_t)(typeof(_trampoline_g2h) *g2h, uint32_t id, uint32_t *args); -+ - /* This is an internal helper for do_syscall so that it is easier - * to have a single return point, so that actions, such as logging - * of syscall results, can be performed. -@@ -9095,6 +9107,27 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int num, abi_long arg1, - void *p; - - switch(num) { -+ case 0x1337: { -+ // Load Trampoline -+ static _trampoline_t _trampoline = NULL; -+ if (_trampoline == NULL) { -+ // Open Library -+ void *_trampoline_handle = dlopen("libmedia-layer-trampoline.so", RTLD_NOW); -+ // Load Function -+ if (_trampoline_handle != NULL) { -+ _trampoline = dlsym(_trampoline_handle, "trampoline"); -+ } -+ } -+ if (_trampoline == NULL) { -+ // Failed To Load -+ qemu_log_mask(LOG_UNIMP, "Unable To Load Media Layer Trampoline: %s\n", dlerror()); -+ return -TARGET_ENOSYS; -+ } -+ // Call Trampoline -+ _trampoline_g2h_cpu = cpu; -+ _trampoline(_trampoline_g2h, arg1, g2h(cpu, arg2)); -+ return 0; -+ } - case TARGET_NR_exit: - /* In old applications this may be used to implement _exit(2). - However in threaded applications it is used for thread termination, diff --git a/dependencies/trampoline/CMakeLists.txt b/dependencies/trampoline/CMakeLists.txt new file mode 100644 index 00000000..1b44c632 --- /dev/null +++ b/dependencies/trampoline/CMakeLists.txt @@ -0,0 +1,16 @@ +project(trampoline) + +## Trampoline Host + +# QEMU +set(QEMU_VERSION "9.0.0") +set(TRAMPOLINE_QEMU_ARCHIVE "${CMAKE_CURRENT_SOURCE_DIR}/../../archives/qemu-${QEMU_VERSION}.tar.xz") +if(NOT MCPI_USE_TRAMPOLINE_HOST) + set(TRAMPOLINE_HEADERS_ONLY TRUE) +endif() + +# Build +add_subdirectory(src) + +# Install +install_trampoline("${MCPI_BIN_DIR}" "${MCPI_LEGAL_DIR}") \ No newline at end of file diff --git a/dependencies/trampoline/src b/dependencies/trampoline/src new file mode 160000 index 00000000..2a1ee6a9 --- /dev/null +++ b/dependencies/trampoline/src @@ -0,0 +1 @@ +Subproject commit 2a1ee6a91bd539bb583f3214a9e1868464bdad44 diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index de635834..e0625136 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -20,6 +20,9 @@ if(NOT MCPI_SERVER_MODE) ) endif() target_link_libraries(launcher reborn-util LIB_LIEF) +if(MCPI_USE_TRAMPOLINE_HOST) + target_link_libraries(launcher trampoline-headers) +endif() # RPath set_target_properties(launcher PROPERTIES INSTALL_RPATH "$ORIGIN/lib/native") target_link_options(launcher PRIVATE "LINKER:--disable-new-dtags") diff --git a/launcher/src/bootstrap.cpp b/launcher/src/bootstrap.cpp index 2cb098af..63fcc496 100644 --- a/launcher/src/bootstrap.cpp +++ b/launcher/src/bootstrap.cpp @@ -177,12 +177,14 @@ void bootstrap() { // Arguments std::vector args; - // Non-ARM Systems Need QEMU + // Use Trampoline Host If Needed +#ifdef MCPI_USE_TRAMPOLINE_HOST + args.push_back("trampoline"); +#endif + // Fix QEMU Bug #ifdef MCPI_USE_QEMU - args.push_back(QEMU_BINARY); - // Fix Bug args.push_back("-B"); - args.push_back("0x40000"); // Arbitary Value (Aligns To 4k And 16k Page Sizes) + args.push_back("0x40000"); // Arbitrary Value (Aligns To 4k And 16k Page Sizes) #endif // Setup Linker diff --git a/libreborn/CMakeLists.txt b/libreborn/CMakeLists.txt index 3d560042..3f5464e8 100644 --- a/libreborn/CMakeLists.txt +++ b/libreborn/CMakeLists.txt @@ -34,14 +34,14 @@ if(BUILD_ARM_COMPONENTS) install(TARGETS reborn-patch EXPORT sdk DESTINATION "${MCPI_SDK_LIB_DIR}") endif() -# Fake LibPNG To Satisy Symbol Versioning Requirement +# Fake LibPNG To Satisfy Symbol Versioning Requirement if(BUILD_ARM_COMPONENTS) add_library(fake-libpng SHARED src/fake-libpng/empty.c) set_target_properties(fake-libpng PROPERTIES OUTPUT_NAME "png12" SOVERSION 0 - LINK_OPTIONS "LINKER:--version-script=${CMAKE_CURRENT_SOURCE_DIR}/src/fake-libpng/empty.vers" ) + target_link_options(fake-libpng PRIVATE "LINKER:--version-script=${CMAKE_CURRENT_SOURCE_DIR}/src/fake-libpng/empty.vers") # Install install(TARGETS fake-libpng DESTINATION "${MCPI_LIB_DIR}") endif() diff --git a/libreborn/include/libreborn/config.h.in b/libreborn/include/libreborn/config.h.in index c1c58c25..c5c90f03 100644 --- a/libreborn/include/libreborn/config.h.in +++ b/libreborn/include/libreborn/config.h.in @@ -13,6 +13,6 @@ #cmakedefine MCPI_VARIANT_NAME "@MCPI_VARIANT_NAME@" #cmakedefine MCPI_SDK_DIR "@MCPI_SDK_DIR@" #cmakedefine MCPI_SKIN_SERVER "@MCPI_SKIN_SERVER@" -#cmakedefine MCPI_USE_QEMU +#cmakedefine MCPI_USE_TRAMPOLINE_HOST #cmakedefine MCPI_DISCORD_INVITE "@MCPI_DISCORD_INVITE@" #cmakedefine MCPI_DOCUMENTATION "@MCPI_DOCUMENTATION@" diff --git a/media-layer/trampoline/CMakeLists.txt b/media-layer/trampoline/CMakeLists.txt index 968c911a..a8d80835 100644 --- a/media-layer/trampoline/CMakeLists.txt +++ b/media-layer/trampoline/CMakeLists.txt @@ -1,16 +1,16 @@ project(media-layer-trampoline) # Configuration -set(MEDIA_LAYER_TRAMPOLINE_SRC src/media-layer-core.c) # Media Layer Trampoline Source +set(MEDIA_LAYER_TRAMPOLINE_SRC src/media-layer-core.cpp) # Media Layer Trampoline Source if(NOT MCPI_HEADLESS_MODE) - list(APPEND MEDIA_LAYER_TRAMPOLINE_SRC src/GLESv1_CM.c) + list(APPEND MEDIA_LAYER_TRAMPOLINE_SRC src/GLESv1_CM.cpp) endif() # Build if(BUILD_NATIVE_COMPONENTS) # Host Component - add_library(media-layer-trampoline src/host/host.c ${MEDIA_LAYER_TRAMPOLINE_SRC}) - target_link_libraries(media-layer-trampoline reborn-util media-layer-core) + add_library(media-layer-trampoline src/host/host.cpp ${MEDIA_LAYER_TRAMPOLINE_SRC}) + target_link_libraries(media-layer-trampoline reborn-util media-layer-core trampoline-headers) if(NOT MCPI_HEADLESS_MODE) target_link_libraries(media-layer-trampoline GLESv1_CM) endif() @@ -19,8 +19,8 @@ if(BUILD_NATIVE_COMPONENTS) install(TARGETS media-layer-trampoline DESTINATION "${MCPI_LIB_DIR}") elseif(BUILD_ARM_COMPONENTS) # Guest Component - add_library(media-layer-core SHARED src/guest/guest.c ${MEDIA_LAYER_TRAMPOLINE_SRC} $) - target_link_libraries(media-layer-core media-layer-headers reborn-util) + add_library(media-layer-core SHARED src/guest/guest.cpp ${MEDIA_LAYER_TRAMPOLINE_SRC} $) + target_link_libraries(media-layer-core PUBLIC media-layer-headers PRIVATE reborn-util PRIVATE trampoline-headers) target_compile_definitions(media-layer-core PRIVATE -DMEDIA_LAYER_TRAMPOLINE_GUEST) # Install if(MCPI_USE_MEDIA_LAYER_TRAMPOLINE) diff --git a/media-layer/trampoline/src/GLESv1_CM.c b/media-layer/trampoline/src/GLESv1_CM.c deleted file mode 100644 index ae64b09d..00000000 --- a/media-layer/trampoline/src/GLESv1_CM.c +++ /dev/null @@ -1,581 +0,0 @@ -#include - -#include -#include - -#include "common/common.h" - -CALL(11, glFogfv, void, (GLenum pname, const GLfloat *params)) -#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST - trampoline(pname, (uint32_t) params); -#else - GLenum pname = next_int(); - GLfloat *params = next_ptr(); - // Run - func(pname, params); -#endif -} - -// 'pointer' Is Only Supported As An Integer, Not As An Actual Pointer -#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST -#define CALL_GL_POINTER(unique_id, name) \ - CALL(unique_id, name, void, (GLint size, GLenum type, GLsizei stride, const void *pointer)) \ - trampoline(size, type, stride, (uint32_t) pointer); \ - } -#else -#define CALL_GL_POINTER(unique_id, name) \ - CALL(unique_id, name, unused, unused) \ - GLint size = next_int(); \ - GLenum type = next_int(); \ - GLsizei stride = next_int(); \ - const void *pointer = (const void *) (uint64_t) next_int(); \ - /* Run */ \ - func(size, type, stride, pointer); \ - } -#endif - -CALL_GL_POINTER(12, glVertexPointer) - -CALL(13, glLineWidth, void, (GLfloat width)) -#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST - trampoline(pun_to(uint32_t, width)); -#else - GLfloat width = next_float(); - // Run - func(width); -#endif -} - -CALL(14, glBlendFunc, void, (GLenum sfactor, GLenum dfactor)) -#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST - trampoline(sfactor, dfactor); -#else - GLenum sfactor = next_int(); - GLenum dfactor = next_int(); - // Run - func(sfactor, dfactor); -#endif -} - -CALL(15, glDrawArrays, void, (GLenum mode, GLint first, GLsizei count)) -#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST - trampoline(mode, first, count); -#else - GLenum mode = next_int(); - GLint first = next_int(); - GLsizei count = next_int(); - // Run - func(mode, first, count); -#endif -} - -CALL(16, glColor4f, void, (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)) -#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST - trampoline(pun_to(uint32_t, red), pun_to(uint32_t, green), pun_to(uint32_t, blue), pun_to(uint32_t, alpha)); -#else - GLfloat red = next_float(); - GLfloat green = next_float(); - GLfloat blue = next_float(); - GLfloat alpha = next_float(); - // Run - func(red, green, blue, alpha); -#endif -} - -CALL(17, glClear, void, (GLbitfield mask)) -#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST - trampoline(mask); -#else - GLbitfield mask = next_int(); - // Run - func(mask); -#endif -} - -CALL(18, glBufferData, void, (GLenum target, GLsizeiptr size, const void *data, GLenum usage)) -#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST - trampoline(target, size, (uint32_t) data, usage); -#else - GLenum target = next_int(); - GLsizeiptr size = next_int(); - const void *data = next_ptr(); - GLenum usage = next_int(); - // Run - func(target, size, data, usage); -#endif -} - -CALL(19, glFogx, void, (GLenum pname, GLfixed param)) -#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST - trampoline(pname, param); -#else - GLenum pname = next_int(); - GLfixed param = next_int(); - // Run - func(pname, param); -#endif -} - -CALL(20, glFogf, void, (GLenum pname, GLfloat param)) -#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST - trampoline(pname, pun_to(uint32_t, param)); -#else - GLenum pname = next_int(); - GLfloat param = next_float(); - // Run - func(pname, param); -#endif -} - -CALL(21, glMatrixMode, void, (GLenum mode)) -#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST - trampoline(mode); -#else - GLenum mode = next_int(); - // Run - func(mode); -#endif -} - -CALL_GL_POINTER(22, glColorPointer) - -CALL(23, glScissor, void, (GLint x, GLint y, GLsizei width, GLsizei height)) -#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST - trampoline(x, y, width, height); -#else - GLint x = next_int(); - GLint y = next_int(); - GLsizei width = next_int(); - GLsizei height = next_int(); - // Run - func(x, y, width, height); -#endif -} - -CALL(24, glTexParameteri, void, (GLenum target, GLenum pname, GLint param)) -#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST - trampoline(target, pname, param); -#else - GLenum target = next_int(); - GLenum pname = next_int(); - GLint param = next_int(); - // Run - func(target, pname, param); -#endif -} - -CALL(25, glTexImage2D, void, (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels)) -#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST - trampoline(target, level, internalformat, width, height, border, format, type, (uint32_t) pixels); -#else - GLenum target = next_int(); - GLint level = next_int(); - GLint internalformat = next_int(); - GLsizei width = next_int(); - GLsizei height = next_int(); - GLint border = next_int(); - GLenum format = next_int(); - GLenum type = next_int(); - const void *pixels = next_ptr(); - // Run - func(target, level, internalformat, width, height, border, format, type, pixels); -#endif -} - -CALL(26, glEnable, void, (GLenum cap)) -#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST - trampoline(cap); -#else - GLenum cap = next_int(); - // Run - func(cap); -#endif -} - -CALL(27, glEnableClientState, void, (GLenum array)) -#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST - trampoline(array); -#else - GLenum array = next_int(); - // Run - func(array); -#endif -} - -CALL(28, glPolygonOffset, void, (GLfloat factor, GLfloat units)) -#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST - trampoline(pun_to(uint32_t, factor), pun_to(uint32_t, units)); -#else - GLfloat factor = next_float(); - GLfloat units = next_float(); - // Run - func(factor, units); -#endif -} - -CALL_GL_POINTER(41, glTexCoordPointer) - -CALL(29, glDisableClientState, void, (GLenum array)) -#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST - trampoline(array); -#else - GLenum array = next_int(); - // Run - func(array); -#endif -} - -CALL(30, glDepthRangef, void, (GLclampf near, GLclampf far)) -#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST - trampoline(pun_to(uint32_t, near), pun_to(uint32_t, far)); -#else - GLclampf near = next_float(); - GLclampf far = next_float(); - // Run - func(near, far); -#endif -} - -CALL(31, glDepthFunc, void, (GLenum func)) -#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST - trampoline(func); -#else - GLenum func2 = next_int(); - // Run - func(func2); -#endif -} - -CALL(32, glBindBuffer, void, (GLenum target, GLuint buffer)) -#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST - trampoline(target, buffer); -#else - GLenum target = next_int(); - GLenum buffer = next_int(); - // Run - func(target, buffer); -#endif -} - -CALL(33, glClearColor, void, (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)) -#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST - trampoline(pun_to(uint32_t, red), pun_to(uint32_t, green), pun_to(uint32_t, blue), pun_to(uint32_t, alpha)); -#else - GLclampf red = next_float(); - GLclampf green = next_float(); - GLclampf blue = next_float(); - GLclampf alpha = next_float(); - // Run - func(red, green, blue, alpha); -#endif -} - -CALL(34, glPopMatrix, void, ()) -#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST - trampoline(); -#else - // Run - func(); -#endif -} - -CALL(35, glLoadIdentity, void, ()) -#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST - trampoline(); -#else - // Run - func(); -#endif -} - -CALL(36, glScalef, void, (GLfloat x, GLfloat y, GLfloat z)) -#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST - trampoline(pun_to(uint32_t, x), pun_to(uint32_t, y), pun_to(uint32_t, z)); -#else - GLfloat x = next_float(); - GLfloat y = next_float(); - GLfloat z = next_float(); - // Run - func(x, y, z); -#endif -} - -CALL(37, glPushMatrix, void, ()) -#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST - trampoline(); -#else - // Run - func(); -#endif -} - -CALL(38, glDepthMask, void, (GLboolean flag)) -#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST - trampoline(flag); -#else - GLboolean flag = next_int(); - // Run - func(flag); -#endif -} - -CALL(39, glHint, void, (GLenum target, GLenum mode)) -#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST - trampoline(target, mode); -#else - GLenum target = next_int(); - GLenum mode = next_int(); - // Run - func(target, mode); -#endif -} - -CALL(40, glMultMatrixf, void, (const GLfloat *m)) -#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST - trampoline((uint32_t) m); -#else - GLfloat *m = next_ptr(); - // Run - func(m); -#endif -} - -CALL(42, glDeleteBuffers, void, (GLsizei n, const GLuint *buffers)) -#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST - trampoline(n, (uint32_t) buffers); -#else - GLsizei n = next_int(); - GLuint *buffers = next_ptr(); - // Run - func(n, buffers); -#endif -} - -CALL(43, glColorMask, void, (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)) -#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST - trampoline(red, green, blue, alpha); -#else - GLboolean red = next_int(); - GLboolean green = next_int(); - GLboolean blue = next_int(); - GLboolean alpha = next_int(); - // Run - func(red, green, blue, alpha); -#endif -} - -CALL(44, glTexSubImage2D, void, (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels)) -#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST - trampoline(target, level, xoffset, yoffset, width, height, format, type, (uint32_t) pixels); -#else - GLenum target = next_int(); - GLint level = next_int(); - GLint xoffset = next_int(); - GLint yoffset = next_int(); - GLsizei width = next_int(); - GLsizei height = next_int(); - GLenum format = next_int(); - GLenum type = next_int(); - const void *pixels = next_ptr(); - // Run - func(target, level, xoffset, yoffset, width, height, format, type, pixels); -#endif -} - -CALL(45, glGenTextures, void, (GLsizei n, GLuint *textures)) -#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST - trampoline(n, (uint32_t) textures); -#else - GLsizei n = next_int(); - GLuint *textures = next_ptr(); - // Run - func(n, textures); -#endif -} - -CALL(46, glDeleteTextures, void, (GLsizei n, const GLuint *textures)) -#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST - trampoline(n, (uint32_t) textures); -#else - GLsizei n = next_int(); - GLuint *textures = next_ptr(); - // Run - func(n, textures); -#endif -} - -CALL(47, glAlphaFunc, void, (GLenum func, GLclampf ref)) -#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST - trampoline(func, pun_to(uint32_t, ref)); -#else - GLenum func2 = next_int(); - GLclampf ref = next_float(); - // Run - func(func2, ref); -#endif -} - -CALL(48, glGetFloatv, void, (GLenum pname, GLfloat *params)) -#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST - trampoline(pname, (uint32_t) params); -#else - GLenum pname = next_int(); - GLfloat *params = next_ptr(); - // Run - func(pname, params); -#endif -} - -CALL(49, glBindTexture, void, (GLenum target, GLuint texture)) -#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST - trampoline(target, texture); -#else - GLenum target = next_int(); - GLuint texture = next_int(); - // Run - func(target, texture); -#endif -} - -CALL(50, glTranslatef, void, (GLfloat x, GLfloat y, GLfloat z)) -#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST - trampoline(pun_to(uint32_t, x), pun_to(uint32_t, y), pun_to(uint32_t, z)); -#else - GLfloat x = next_float(); - GLfloat y = next_float(); - GLfloat z = next_float(); - // Run - func(x, y, z); -#endif -} - -CALL(51, glShadeModel, void, (GLenum mode)) -#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST - trampoline(mode); -#else - GLenum mode = next_int(); - // Run - func(mode); -#endif -} - -CALL(52, glOrthof, void, (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat near, GLfloat far)) -#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST - trampoline(pun_to(uint32_t, left), pun_to(uint32_t, right), pun_to(uint32_t, bottom), pun_to(uint32_t, top), pun_to(uint32_t, near), pun_to(uint32_t, far)); -#else - GLfloat left = next_float(); - GLfloat right = next_float(); - GLfloat bottom = next_float(); - GLfloat top = next_float(); - GLfloat near = next_float(); - GLfloat far = next_float(); - // Run - func(left, right, bottom, top, near, far); -#endif -} - -CALL(53, glDisable, void, (GLenum cap)) -#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST - trampoline(cap); -#else - GLenum cap = next_int(); - // Run - func(cap); -#endif -} - -CALL(54, glCullFace, void, (GLenum mode)) -#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST - trampoline(mode); -#else - GLenum mode = next_int(); - // Run - func(mode); -#endif -} - -CALL(55, glRotatef, void, (GLfloat angle, GLfloat x, GLfloat y, GLfloat z)) -#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST - trampoline(pun_to(uint32_t, angle), pun_to(uint32_t, x), pun_to(uint32_t, y), pun_to(uint32_t, z)); -#else - GLfloat angle = next_float(); - GLfloat x = next_float(); - GLfloat y = next_float(); - GLfloat z = next_float(); - // Run - func(angle, x, y, z); -#endif -} - -CALL(56, glViewport, void, (GLint x, GLint y, GLsizei width, GLsizei height)) -#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST - trampoline(x, y, width, height); -#else - GLint x = next_int(); - GLint y = next_int(); - GLsizei width = next_int(); - GLsizei height = next_int(); - // Run - func(x, y, width, height); -#endif -} - -CALL(57, glNormal3f, void, (GLfloat nx, GLfloat ny, GLfloat nz)) -#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST - trampoline(pun_to(uint32_t, nx), pun_to(uint32_t, ny), pun_to(uint32_t, nz)); -#else - GLfloat nx = next_float(); - GLfloat ny = next_float(); - GLfloat nz = next_float(); - // Run - func(nx, ny, nz); -#endif -} - -CALL(58, glIsEnabled, GLboolean, (GLenum cap)) -#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST - return trampoline(cap); -#else - GLenum cap = next_int(); - // Run - ret(func(cap)); -#endif -} - -CALL(61, glGetIntegerv, void, (GLenum pname, GLint *params)) -#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST - trampoline(pname, (uint32_t) params); -#else - GLenum pname = next_int(); - GLint *params = next_ptr(); - // Run - func(pname, params); -#endif -} - -CALL(65, glReadPixels, void, (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *data)) -#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST - trampoline(x, y, width, height, format, type, (uint32_t) data); -#else - GLint x = next_int(); - GLint y = next_int(); - GLsizei width = next_int(); - GLsizei height = next_int(); - GLenum format = next_int(); - GLenum type = next_int(); - void *data = next_ptr(); - // Run - func(x, y, width, height, format, type, data); -#endif -} - -CALL(67, glGenBuffers, void, (GLsizei n, GLuint *buffers)) -#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST - trampoline(n, (uint32_t) buffers); -#else - GLsizei n = next_int(); - GLuint *buffers = next_ptr(); - // Run - func(n, buffers); -#endif -} diff --git a/media-layer/trampoline/src/GLESv1_CM.cpp b/media-layer/trampoline/src/GLESv1_CM.cpp new file mode 100644 index 00000000..1c88c277 --- /dev/null +++ b/media-layer/trampoline/src/GLESv1_CM.cpp @@ -0,0 +1,660 @@ +#include + +#include +#include + +#include "common/common.h" + +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST +static int get_glFogfv_params_length(GLenum pname) { + return pname == GL_FOG_COLOR ? 4 : 1; +} +#endif +CALL(11, glFogfv, void, (GLenum pname, const GLfloat *params)) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST + trampoline(pname, copy_array(get_glFogfv_params_length(pname), params)); +#else + GLenum pname = args.next(); + const GLfloat *params = args.next_arr(); + func(pname, params); + return 0; +#endif +} + +// 'pointer' Is Only Supported As An Integer, Not As An Actual Pointer +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST +#define CALL_GL_POINTER(unique_id, name) \ + CALL(unique_id, name, void, (GLint size, GLenum type, GLsizei stride, const void *pointer)) \ + trampoline(size, type, stride, uint32_t(pointer)); \ + } +#else +#define CALL_GL_POINTER(unique_id, name) \ + CALL(unique_id, name, unused, unused) \ + GLint size = args.next(); \ + GLenum type = args.next(); \ + GLsizei stride = args.next(); \ + const void *pointer = (const void *) (uint64_t) args.next(); \ + func(size, type, stride, pointer); \ + return 0; \ + } +#endif + +CALL_GL_POINTER(12, glVertexPointer) + +CALL(13, glLineWidth, void, (GLfloat width)) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST + trampoline(width); +#else + func(args.next()); + return 0; +#endif +} + +CALL(14, glBlendFunc, void, (GLenum sfactor, GLenum dfactor)) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST + trampoline(sfactor, dfactor); +#else + GLenum sfactor = args.next(); + GLenum dfactor = args.next(); + func(sfactor, dfactor); + return 0; +#endif +} + +CALL(15, glDrawArrays, void, (GLenum mode, GLint first, GLsizei count)) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST + trampoline(mode, first, count); +#else + GLenum mode = args.next(); + GLint first = args.next(); + GLsizei count = args.next(); + func(mode, first, count); + return 0; +#endif +} + +CALL(16, glColor4f, void, (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST + trampoline(red, green, blue, alpha); +#else + GLfloat red = args.next(); + GLfloat green = args.next(); + GLfloat blue = args.next(); + GLfloat alpha = args.next(); + func(red, green, blue, alpha); + return 0; +#endif +} + +CALL(17, glClear, void, (GLbitfield mask)) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST + trampoline(mask); +#else + func(args.next()); + return 0; +#endif +} + +CALL(18, glBufferData, void, (GLenum target, GLsizeiptr size, const void *data, GLenum usage)) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST + trampoline(target, copy_array(size, (unsigned char *) data), usage); +#else + GLenum target = args.next(); + uint32_t size; + const unsigned char *data = args.next_arr(&size); + GLenum usage = args.next(); + func(target, GLsizeiptr(size), data, usage); + return 0; +#endif +} + +CALL(19, glFogx, void, (GLenum pname, GLfixed param)) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST + trampoline(pname, param); +#else + GLenum pname = args.next(); + GLfixed param = args.next(); + func(pname, param); + return 0; +#endif +} + +CALL(20, glFogf, void, (GLenum pname, GLfloat param)) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST + trampoline(pname, param); +#else + GLenum pname = args.next(); + GLfloat param = args.next(); + func(pname, param); + return 0; +#endif +} + +CALL(21, glMatrixMode, void, (GLenum mode)) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST + trampoline(mode); +#else + func(args.next()); + return 0; +#endif +} + +CALL_GL_POINTER(22, glColorPointer) + +CALL(23, glScissor, void, (GLint x, GLint y, GLsizei width, GLsizei height)) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST + trampoline(x, y, width, height); +#else + GLint x = args.next(); + GLint y = args.next(); + GLsizei width = args.next(); + GLsizei height = args.next(); + func(x, y, width, height); + return 0; +#endif +} + +CALL(24, glTexParameteri, void, (GLenum target, GLenum pname, GLint param)) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST + trampoline(target, pname, param); +#else + GLenum target = args.next(); + GLenum pname = args.next(); + GLint param = args.next(); + func(target, pname, param); + return 0; +#endif +} + +// Get Size (In Memory) Of Specified Texture +static int get_texture_size(const GLsizei width, const GLsizei height, const GLenum format, const GLenum type, bool is_upload) { + // Calculate Per-Pixel Multiplier + int multiplier; + if (type == GL_UNSIGNED_BYTE) { + switch (format) { + case GL_RGB: { + multiplier = 3; + break; + } + case GL_RGBA: { + multiplier = 4; + break; + } + default: { + ERR("Unsupported Texture Format: %u", format); + } + } + } else { + // GL_UNSIGNED_SHORT_* + multiplier = sizeof(unsigned short); + } + // Calculate Line Size + int line_size = width * multiplier; + { + // Handle Alignment + int alignment; + glGetIntegerv(is_upload ? GL_UNPACK_ALIGNMENT : GL_PACK_ALIGNMENT, &alignment); + // Round + int diff = line_size % alignment; + line_size = line_size + (alignment - diff); + } + // Return + return line_size * height; +} + +CALL(25, glTexImage2D, void, (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels)) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST + trampoline(target, level, internalformat, width, height, border, format, type, copy_array(get_texture_size(width, height, format, type, true), (const unsigned char *) pixels)); +#else + GLenum target = args.next(); + GLint level = args.next(); + GLint internalformat = args.next(); + GLsizei width = args.next(); + GLsizei height = args.next(); + GLint border = args.next(); + GLenum format = args.next(); + GLenum type = args.next(); + const unsigned char *pixels = args.next_arr(); + func(target, level, internalformat, width, height, border, format, type, pixels); + return 0; +#endif +} + +CALL(26, glEnable, void, (GLenum cap)) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST + trampoline(cap); +#else + func(args.next()); + return 0; +#endif +} + +CALL(27, glEnableClientState, void, (GLenum array)) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST + trampoline(array); +#else + func(args.next()); + return 0; +#endif +} + +CALL(28, glPolygonOffset, void, (GLfloat factor, GLfloat units)) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST + trampoline(factor, units); +#else + GLfloat factor = args.next(); + GLfloat units = args.next(); + func(factor, units); + return 0; +#endif +} + +CALL_GL_POINTER(41, glTexCoordPointer) + +CALL(29, glDisableClientState, void, (GLenum array)) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST + trampoline(array); +#else + func(args.next()); + return 0; +#endif +} + +CALL(30, glDepthRangef, void, (GLclampf near, GLclampf far)) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST + trampoline(near, far); +#else + GLclampf near = args.next(); + GLclampf far = args.next(); + func(near, far); + return 0; +#endif +} + +CALL(31, glDepthFunc, void, (GLenum func)) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST + trampoline(func); +#else + func(args.next()); + return 0; +#endif +} + +CALL(32, glBindBuffer, void, (GLenum target, GLuint buffer)) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST + trampoline(target, buffer); +#else + GLenum target = args.next(); + GLenum buffer = args.next(); + func(target, buffer); + return 0; +#endif +} + +CALL(33, glClearColor, void, (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST + trampoline(red, green, blue, alpha); +#else + GLclampf red = args.next(); + GLclampf green = args.next(); + GLclampf blue = args.next(); + GLclampf alpha = args.next(); + func(red, green, blue, alpha); + return 0; +#endif +} + +CALL(34, glPopMatrix, void, ()) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST + trampoline(); +#else + func(); + return 0; +#endif +} + +CALL(35, glLoadIdentity, void, ()) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST + trampoline(); +#else + func(); + return 0; +#endif +} + +CALL(36, glScalef, void, (GLfloat x, GLfloat y, GLfloat z)) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST + trampoline(x, y, z); +#else + GLfloat x = args.next(); + GLfloat y = args.next(); + GLfloat z = args.next(); + func(x, y, z); + return 0; +#endif +} + +CALL(37, glPushMatrix, void, ()) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST + trampoline(); +#else + func(); + return 0; +#endif +} + +CALL(38, glDepthMask, void, (GLboolean flag)) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST + trampoline(flag); +#else + func(args.next()); + return 0; +#endif +} + +CALL(39, glHint, void, (GLenum target, GLenum mode)) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST + trampoline(target, mode); +#else + GLenum target = args.next(); + GLenum mode = args.next(); + func(target, mode); + return 0; +#endif +} + +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST +static int get_glMultMatrixf_size() { + return 16; +} +#endif +CALL(40, glMultMatrixf, void, (const GLfloat *m)) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST + trampoline(copy_array(get_glMultMatrixf_size(), m)); +#else + func(args.next_arr()); + return 0; +#endif +} + +CALL(42, glDeleteBuffers, void, (GLsizei n, const GLuint *buffers)) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST + trampoline(copy_array(n, buffers)); +#else + uint32_t n; + const GLuint *buffers = args.next_arr(&n); + func(GLsizei(n), buffers); + return 0; +#endif +} + +CALL(43, glColorMask, void, (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST + trampoline(red, green, blue, alpha); +#else + GLboolean red = args.next(); + GLboolean green = args.next(); + GLboolean blue = args.next(); + GLboolean alpha = args.next(); + func(red, green, blue, alpha); + return 0; +#endif +} + +CALL(44, glTexSubImage2D, void, (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels)) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST + trampoline(target, level, xoffset, yoffset, width, height, format, type, copy_array(get_texture_size(width, height, format, type, true), (const unsigned char *) pixels)); +#else + GLenum target = args.next(); + GLint level = args.next(); + GLint xoffset = args.next(); + GLint yoffset = args.next(); + GLsizei width = args.next(); + GLsizei height = args.next(); + GLenum format = args.next(); + GLenum type = args.next(); + const unsigned char *pixels = args.next_arr(); + func(target, level, xoffset, yoffset, width, height, format, type, pixels); + return 0; +#endif +} + +CALL(45, glGenTextures, void, (GLsizei n, GLuint *textures)) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST + trampoline(n, uint32_t(textures)); +#else + GLsizei n = args.next(); + GLuint *textures = new GLuint[n]; + func(n, textures); + writer(args.next(), textures, n * sizeof(GLuint)); + delete[] textures; + return 0; +#endif +} + +CALL(46, glDeleteTextures, void, (GLsizei n, const GLuint *textures)) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST + trampoline(copy_array(n, textures)); +#else + uint32_t n; + const GLuint *textures = args.next_arr(&n); + func(GLsizei(n), textures); + return 0; +#endif +} + +CALL(47, glAlphaFunc, void, (GLenum func, GLclampf ref)) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST + trampoline(func, ref); +#else + GLenum func2 = args.next(); + GLclampf ref = args.next(); + func(func2, ref); + return 0; +#endif +} + +#ifdef MEDIA_LAYER_TRAMPOLINE_HOST +static int get_glGetFloatv_params_size(GLenum pname) { + switch (pname) { + case GL_MODELVIEW_MATRIX: + case GL_PROJECTION_MATRIX: { + return 16; + } + case GL_ALIASED_LINE_WIDTH_RANGE: + case GL_SMOOTH_LINE_WIDTH_RANGE: { + return 2; + } + default: { + ERR("Unsupported glGetFloatv Property: %u", pname); + } + } +} +#endif +CALL(48, glGetFloatv, void, (GLenum pname, GLfloat *params)) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST + trampoline(pname, uint32_t(params)); +#else + GLenum pname = args.next(); + int size = get_glGetFloatv_params_size(pname); + GLfloat *params = new GLfloat[size]; + func(pname, params); + writer(args.next(), params, size * sizeof(GLfloat)); + delete[] params; + return 0; +#endif +} + +CALL(49, glBindTexture, void, (GLenum target, GLuint texture)) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST + trampoline(target, texture); +#else + GLenum target = args.next(); + GLuint texture = args.next(); + func(target, texture); + return 0; +#endif +} + +CALL(50, glTranslatef, void, (GLfloat x, GLfloat y, GLfloat z)) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST + trampoline(x, y, z); +#else + GLfloat x = args.next(); + GLfloat y = args.next(); + GLfloat z = args.next(); + func(x, y, z); + return 0; +#endif +} + +CALL(51, glShadeModel, void, (GLenum mode)) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST + trampoline(mode); +#else + func(args.next()); + return 0; +#endif +} + +CALL(52, glOrthof, void, (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat near, GLfloat far)) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST + trampoline(left, right, bottom, top, near, far); +#else + GLfloat left = args.next(); + GLfloat right = args.next(); + GLfloat bottom = args.next(); + GLfloat top = args.next(); + GLfloat near = args.next(); + GLfloat far = args.next(); + func(left, right, bottom, top, near, far); + return 0; +#endif +} + +CALL(53, glDisable, void, (GLenum cap)) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST + trampoline(cap); +#else + func(args.next()); + return 0; +#endif +} + +CALL(54, glCullFace, void, (GLenum mode)) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST + trampoline(mode); +#else + func(args.next()); + return 0; +#endif +} + +CALL(55, glRotatef, void, (GLfloat angle, GLfloat x, GLfloat y, GLfloat z)) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST + trampoline(angle, x, y, z); +#else + GLfloat angle = args.next(); + GLfloat x = args.next(); + GLfloat y = args.next(); + GLfloat z = args.next(); + func(angle, x, y, z); + return 0; +#endif +} + +CALL(56, glViewport, void, (GLint x, GLint y, GLsizei width, GLsizei height)) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST + trampoline(x, y, width, height); +#else + GLint x = args.next(); + GLint y = args.next(); + GLsizei width = args.next(); + GLsizei height = args.next(); + func(x, y, width, height); + return 0; +#endif +} + +CALL(57, glNormal3f, void, (GLfloat nx, GLfloat ny, GLfloat nz)) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST + trampoline(nx, ny, nz); +#else + GLfloat nx = args.next(); + GLfloat ny = args.next(); + GLfloat nz = args.next(); + func(nx, ny, nz); + return 0; +#endif +} + +CALL(58, glIsEnabled, GLboolean, (GLenum cap)) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST + return trampoline(cap); +#else + return func(args.next()); +#endif +} + +#ifdef MEDIA_LAYER_TRAMPOLINE_HOST +static int get_glGetIntegerv_params_size(GLenum pname) { + switch (pname) { + case GL_TEXTURE_BINDING_2D: + case GL_PACK_ALIGNMENT: + case GL_UNPACK_ALIGNMENT: { + return 1; + } + case GL_VIEWPORT: { + return 4; + } + default: { + ERR("Unsupported glGetIntegerv Property: %u", pname); + } + } +} +#endif +CALL(61, glGetIntegerv, void, (GLenum pname, GLint *params)) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST + trampoline(pname, uint32_t(params)); +#else + GLenum pname = args.next(); + int size = get_glGetIntegerv_params_size(pname); + GLint *params = new GLint[size]; + func(pname, params); + writer(args.next(), params, size * sizeof(GLint)); + delete[] params; + return 0; +#endif +} + +CALL(65, glReadPixels, void, (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *data)) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST + trampoline(x, y, width, height, format, type, uint32_t(data)); +#else + GLint x = args.next(); + GLint y = args.next(); + GLsizei width = args.next(); + GLsizei height = args.next(); + GLenum format = args.next(); + GLenum type = args.next(); + int data_size = get_texture_size(width, height, format, type, false); + unsigned char *data = new unsigned char[data_size]; + func(x, y, width, height, format, type, data); + writer(args.next(), data, data_size); + delete[] data; + return 0; +#endif +} + +CALL(67, glGenBuffers, void, (GLsizei n, GLuint *buffers)) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST + trampoline(n, uint32_t(buffers)); +#else + GLsizei n = args.next(); + GLuint *buffers = new GLuint[n]; + func(n, buffers); + writer(args.next(), buffers, n * sizeof(GLuint)); + delete[] buffers; + return 0; +#endif +} diff --git a/media-layer/trampoline/src/common/common.h b/media-layer/trampoline/src/common/common.h index cd19826b..6cd0fb40 100644 --- a/media-layer/trampoline/src/common/common.h +++ b/media-layer/trampoline/src/common/common.h @@ -1,21 +1,21 @@ #pragma once +#include +#include + +#include + #if __BYTE_ORDER != __LITTLE_ENDIAN #error "Only Little Endian Is Supported" #endif +static_assert(sizeof(int) == sizeof(int32_t)); +#define block_pointer(T) static_assert(!std::is_pointer::value, "Do Not Use Raw Pointers Here") + #if defined(MEDIA_LAYER_TRAMPOLINE_HOST) #include "../host/host.h" #elif defined(MEDIA_LAYER_TRAMPOLINE_GUEST) #include "../guest/guest.h" #else #error "Invalid Configuration" -#endif - -//#define pun_to(type, x) (*(type *) &(x)) -#define pun_to(type, x) \ - ({ \ - union { typeof(x) a; type b; } _pun; \ - _pun.a = x; \ - _pun.b; \ - }) +#endif \ No newline at end of file diff --git a/media-layer/trampoline/src/guest/guest.c b/media-layer/trampoline/src/guest/guest.cpp similarity index 50% rename from media-layer/trampoline/src/guest/guest.c rename to media-layer/trampoline/src/guest/guest.cpp index c4f80eb2..2b0a5e58 100644 --- a/media-layer/trampoline/src/guest/guest.c +++ b/media-layer/trampoline/src/guest/guest.cpp @@ -3,13 +3,13 @@ #include "guest.h" -uint32_t _trampoline(uint32_t id, uint32_t *args) { +uint32_t _raw_trampoline(const uint32_t id, const uint32_t length, const unsigned char *args) { // Make Syscall - long ret = syscall(0x1337 /* See trampoline.patch */, id, args); + long ret = syscall(0x1337 /* See trampoline.patch */, id, length, args); if (ret == -1) { // Error ERR("Trampoline Error: %s", strerror(errno)); } // Return - return args[0]; + return *(uint32_t *) args; } \ No newline at end of file diff --git a/media-layer/trampoline/src/guest/guest.h b/media-layer/trampoline/src/guest/guest.h index 42e3c253..7a36c951 100644 --- a/media-layer/trampoline/src/guest/guest.h +++ b/media-layer/trampoline/src/guest/guest.h @@ -1,10 +1,65 @@ #pragma once -#include +#include + +#include "../common/common.h" // Trampoline Function -uint32_t _trampoline(uint32_t id, uint32_t *args); -#define trampoline(...) _trampoline(_id, (uint32_t[]){__VA_ARGS__}) +uint32_t _raw_trampoline(uint32_t id, uint32_t length, const unsigned char *args); + +// Compile Trampoline Arguments +template +void _handle_trampoline_arg(unsigned char *&out, const T arg) { + block_pointer(T); + *(T *) out = arg; + out += sizeof(T); +} +// Array Specialization +struct copy_array { + template + copy_array(uint32_t length, T *arr) { + block_pointer(T); + if (arr == nullptr) { + length = 0; + } + this->size = length * sizeof(T); + this->data = arr; + } + copy_array(const char *str) { + this->size = str != nullptr ? (strlen(str) + 1) : 0; + this->data = str; + } + uint32_t size; + const void *data; +}; +template <> +inline void _handle_trampoline_arg(unsigned char *&out, const copy_array arg) { + *(uint32_t *) out = arg.size; + out += sizeof(uint32_t); + if (arg.size > 0) { + memcpy(out, arg.data, arg.size); + out += arg.size; + } +} +// Variadic Templates +__attribute__((unused)) static void _add_to_trampoline_args(__attribute__((unused)) unsigned char *&out) { +} +template +void _add_to_trampoline_args(unsigned char *&out, T first, Args... args) { + _handle_trampoline_arg(out, first); + _add_to_trampoline_args(out, args...); +} + +// Main Trampoline Function +template +unsigned int _trampoline(unsigned int id, Args... args) { + static unsigned char out[MAX_TRAMPOLINE_ARGS_SIZE]; + unsigned char *end = out; + _add_to_trampoline_args(end, args...); + const uint32_t length = end - out; + return _raw_trampoline(id, length, out); +} +#define trampoline(...) _trampoline(_id, ##__VA_ARGS__) // Macro #define CALL(unique_id, name, return_type, args) \ diff --git a/media-layer/trampoline/src/host/host.c b/media-layer/trampoline/src/host/host.cpp similarity index 53% rename from media-layer/trampoline/src/host/host.c rename to media-layer/trampoline/src/host/host.cpp index 1d5ef9ef..9f7d2377 100644 --- a/media-layer/trampoline/src/host/host.c +++ b/media-layer/trampoline/src/host/host.cpp @@ -4,7 +4,7 @@ // Registration static handler_t *handlers[256]; -void _add_handler(unsigned char id, handler_t *handler) { +void _add_handler(const unsigned char id, handler_t *handler) { if (handlers[id]) { ERR("Conflicting Trampolines For ID: %i", (int) id); } @@ -12,6 +12,6 @@ void _add_handler(unsigned char id, handler_t *handler) { } // Trampoline -void trampoline(g2h_t g2h, uint32_t id, uint32_t *args) { - handlers[id](g2h, args); +uint32_t trampoline(const trampoline_writer_t writer, const uint32_t id, const unsigned char *args) { + return handlers[id](writer, args); } \ No newline at end of file diff --git a/media-layer/trampoline/src/host/host.h b/media-layer/trampoline/src/host/host.h index fb3fdd60..d71b726c 100644 --- a/media-layer/trampoline/src/host/host.h +++ b/media-layer/trampoline/src/host/host.h @@ -1,27 +1,49 @@ #pragma once -#include +#include "../common/common.h" // Trampoline Function -typedef void *(*g2h_t)(uint32_t guest_addr); -void trampoline(g2h_t g2h, uint32_t id, uint32_t *args); // See trampoline.patch +extern "C" std::remove_pointer::type trampoline; // Macro -typedef void handler_t(g2h_t g2h, uint32_t *args); +typedef uint32_t handler_t(trampoline_writer_t writer, const unsigned char *args); __attribute__((visibility("internal"))) void _add_handler(unsigned char id, handler_t *handler); #define CALL(unique_id, name, ignored1, ignored2) \ static handler_t _run_##name; \ __attribute__((constructor)) static void _init_##name() { \ _add_handler(unique_id, _run_##name); \ } \ - static void _run_##name(__attribute__((unused)) g2h_t g2h, __attribute__((unused)) uint32_t *args) { \ - __attribute__((unused)) int _current_arg = 0; \ + static uint32_t _run_##name(__attribute__((unused)) trampoline_writer_t writer, const unsigned char *raw_args) { \ + __attribute__((unused)) TrampolineArguments args(raw_args); \ static typeof(name) *func = name; -// Helper Macros -#define next_int() args[_current_arg++] -#define next_ptr() g2h(next_int()) -#define next_float() pun_to(float, next_int()) -#define ret(x) \ - args[0] = x; \ - return; +// Arguemnts +struct TrampolineArguments { + TrampolineArguments(const unsigned char *args) { + this->raw_args = args; + this->position = 0; + } + + template + T next() { + block_pointer(T); + T ret = *(const T *) raw_args; + raw_args += sizeof(T); + return ret; + } + template + const T *next_arr(uint32_t *length = nullptr) { + block_pointer(T); + const uint32_t size = next(); + if (length != nullptr) { + *length = size / sizeof(T); + } + const T *ret = (const T *) raw_args; + raw_args += size; + return ret; + } + +private: + const unsigned char *raw_args; + unsigned int position; +}; diff --git a/media-layer/trampoline/src/media-layer-core.c b/media-layer/trampoline/src/media-layer-core.cpp similarity index 58% rename from media-layer/trampoline/src/media-layer-core.c rename to media-layer/trampoline/src/media-layer-core.cpp index 1bc5ad95..513377a4 100644 --- a/media-layer/trampoline/src/media-layer-core.c +++ b/media-layer/trampoline/src/media-layer-core.cpp @@ -1,53 +1,53 @@ -#include +#include #include -#include #include #include #include "common/common.h" +#include + // SDL Functions CALL(0, SDL_Init, int, (uint32_t flags)) #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST return trampoline(flags); #else - uint32_t flags = next_int(); - // Run - ret(func(flags)); + uint32_t flags = args.next(); + return func(flags); #endif } CALL(1, SDL_PollEvent, int, (SDL_Event *event)) #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST - return trampoline((uint32_t) event); + return trampoline(uint32_t(event)); #else - SDL_Event *event = next_ptr(); - // Run - ret(func(event)); + SDL_Event event; + const int ret = func(&event); + writer(args.next(), &event, sizeof(SDL_Event)); + return ret; #endif } CALL(2, SDL_PushEvent, int, (SDL_Event *event)) #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST - return trampoline((uint32_t) event); + return trampoline(*event); #else - SDL_Event *event = next_ptr(); - // Run - ret(func(event)); + SDL_Event event = args.next(); + return func(&event); #endif } CALL(3, SDL_WM_SetCaption, void, (const char *title, const char *icon)) #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST - trampoline((uint32_t) title, (uint32_t) icon); + trampoline(copy_array(title), copy_array(icon)); #else - char *title = next_ptr(); - char *icon = next_ptr(); - // Run + const char *title = args.next_arr(); + const char *icon = args.next_arr(); func(title, icon); + return 0; #endif } @@ -55,18 +55,16 @@ CALL(4, media_toggle_fullscreen, void, ()) #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST trampoline(); #else - // Run func(); + return 0; #endif } CALL(5, SDL_WM_GrabInput, SDL_GrabMode, (SDL_GrabMode mode)) #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST - return trampoline(mode); + return (SDL_GrabMode) trampoline(mode); #else - SDL_GrabMode mode = next_int(); - // Run - ret(func(mode)); + return func(args.next()); #endif } @@ -74,9 +72,7 @@ CALL(6, SDL_ShowCursor, int, (int32_t toggle)) #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST return trampoline(toggle); #else - int mode = next_int(); - // Run - ret(func(mode)); + return func(args.next()); #endif } @@ -84,8 +80,8 @@ CALL(8, media_swap_buffers, void, ()) #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST trampoline(); #else - // Run func(); + return 0; #endif } @@ -93,50 +89,52 @@ CALL(9, media_cleanup, void, ()) #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST trampoline(); #else - // Run func(); + return 0; #endif } CALL(10, media_get_framebuffer_size, void, (int *width, int *height)) #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST - trampoline((uint32_t) width, (uint32_t) height); + trampoline(uint32_t(width), uint32_t(height)); #else - int *width = next_ptr(); - int *height = next_ptr(); - // Run - func(width, height); + int width; + int height; + func(&width, &height); + writer(args.next(), &width, sizeof(int)); + writer(args.next(), &height, sizeof(int)); + return 0; #endif } CALL(59, media_audio_update, void, (float volume, float x, float y, float z, float yaw)) #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST - trampoline(pun_to(uint32_t, volume), pun_to(uint32_t, x), pun_to(uint32_t, y), pun_to(uint32_t, z), pun_to(uint32_t, yaw)); + trampoline(volume, x, y, z, yaw); #else - float volume = next_float(); - float x = next_float(); - float y = next_float(); - float z = next_float(); - float yaw = next_float(); - // Run + float volume = args.next(); + float x = args.next(); + float y = args.next(); + float z = args.next(); + float yaw = args.next(); func(volume, x, y, z, yaw); + return 0; #endif } CALL(60, media_audio_play, void, (const char *source, const char *name, float x, float y, float z, float pitch, float volume, int is_ui)) #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST - trampoline((uint32_t) source, (uint32_t) name, pun_to(uint32_t, x), pun_to(uint32_t, y), pun_to(uint32_t, z), pun_to(uint32_t, pitch), pun_to(uint32_t, volume), is_ui); + trampoline(copy_array(source), copy_array(name), x, y, z, pitch, volume, is_ui); #else - char *source = next_ptr(); - char *name = next_ptr(); - float x = next_float(); - float y = next_float(); - float z = next_float(); - float pitch = next_float(); - float volume = next_float(); - int is_ui = next_int(); - // Run + const char *source = args.next_arr(); + const char *name = args.next_arr(); + float x = args.next(); + float y = args.next(); + float z = args.next(); + float pitch = args.next(); + float volume = args.next(); + int is_ui = args.next(); func(source, name, x, y, z, pitch, volume, is_ui); + return 0; #endif } @@ -144,9 +142,8 @@ CALL(62, media_set_interactable, void, (int is_interactable)) #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST trampoline(is_interactable); #else - int is_interactable = next_int(); - // Run - func(is_interactable); + func(args.next()); + return 0; #endif } @@ -154,8 +151,8 @@ CALL(63, media_disable_vsync, void, ()) #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST trampoline(); #else - // Run func(); + return 0; #endif } @@ -163,9 +160,8 @@ CALL(64, media_set_raw_mouse_motion_enabled, void, (int enabled)) #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST trampoline(enabled); #else - int enabled = next_int(); - // Run - func(enabled); + func(args.next()); + return 0; #endif } @@ -173,8 +169,8 @@ CALL(66, media_force_egl, void, ()) #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST trampoline(); #else - // Run func(); + return 0; #endif } @@ -182,7 +178,7 @@ CALL(68, media_ensure_loaded, void, ()) #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST trampoline(); #else - // Run func(); + return 0; #endif }