Optimizations & Fixes
This commit is contained in:
parent
0dd0706f52
commit
211bf265ff
@ -254,6 +254,7 @@ void bootstrap(int argc, char *argv[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Fix MCPI Dependencies
|
// Fix MCPI Dependencies
|
||||||
|
char new_mcpi_exe_path[] = MCPI_PATCHED_DIR "/XXXXXX";
|
||||||
{
|
{
|
||||||
// Log
|
// Log
|
||||||
DEBUG("Patching ELF Dependencies...");
|
DEBUG("Patching ELF Dependencies...");
|
||||||
@ -273,7 +274,7 @@ void bootstrap(int argc, char *argv[]) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Patch
|
// Patch
|
||||||
patch_mcpi_elf_dependencies(resolved_path, linker);
|
patch_mcpi_elf_dependencies(resolved_path, new_mcpi_exe_path, linker);
|
||||||
|
|
||||||
// Free Linker Path
|
// Free Linker Path
|
||||||
if (linker != NULL) {
|
if (linker != NULL) {
|
||||||
@ -281,7 +282,7 @@ void bootstrap(int argc, char *argv[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Verify
|
// Verify
|
||||||
if (!starts_with(getenv("MCPI_EXECUTABLE_PATH"), "/tmp")) {
|
if (!starts_with(new_mcpi_exe_path, MCPI_PATCHED_DIR)) {
|
||||||
IMPOSSIBLE();
|
IMPOSSIBLE();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -391,7 +392,7 @@ void bootstrap(int argc, char *argv[]) {
|
|||||||
new_args[argv_start + argc] = NULL;
|
new_args[argv_start + argc] = NULL;
|
||||||
|
|
||||||
// Set Executable Argument
|
// Set Executable Argument
|
||||||
new_args[argv_start] = getenv("MCPI_EXECUTABLE_PATH");
|
new_args[argv_start] = new_mcpi_exe_path;
|
||||||
|
|
||||||
// Non-ARM Systems Need QEMU
|
// Non-ARM Systems Need QEMU
|
||||||
#ifndef __ARM_ARCH
|
#ifndef __ARM_ARCH
|
||||||
|
@ -8,23 +8,21 @@
|
|||||||
#include "patchelf.h"
|
#include "patchelf.h"
|
||||||
|
|
||||||
// Duplicate MCPI Executable Into /tmp
|
// Duplicate MCPI Executable Into /tmp
|
||||||
#define TMP_DIR "/tmp/.minecraft-pi-patched"
|
static void duplicate_mcpi_executable(const char *original_path, char *new_path) {
|
||||||
static void duplicate_mcpi_executable(const char *original_path) {
|
|
||||||
// Ensure Temporary Directory
|
// Ensure Temporary Directory
|
||||||
{
|
{
|
||||||
// Check If It Exists
|
// Check If It Exists
|
||||||
struct stat tmp_stat;
|
struct stat tmp_stat;
|
||||||
int exists = stat(TMP_DIR, &tmp_stat) != 0 ? 0 : S_ISDIR(tmp_stat.st_mode);
|
int exists = stat(MCPI_PATCHED_DIR, &tmp_stat) != 0 ? 0 : S_ISDIR(tmp_stat.st_mode);
|
||||||
if (!exists) {
|
if (!exists) {
|
||||||
// Doesn't Exist
|
// Doesn't Exist
|
||||||
if (mkdir(TMP_DIR, S_IRUSR | S_IWUSR | S_IXUSR) != 0) {
|
if (mkdir(MCPI_PATCHED_DIR, S_IRUSR | S_IWUSR | S_IXUSR) != 0) {
|
||||||
ERR("Unable To Create Temporary Folder: %s", strerror(errno));
|
ERR("Unable To Create Temporary Folder: %s", strerror(errno));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate New File
|
// Generate New File
|
||||||
char new_path[] = TMP_DIR "/XXXXXX";
|
|
||||||
int new_file_fd = mkstemp(new_path);
|
int new_file_fd = mkstemp(new_path);
|
||||||
if (new_file_fd == -1) {
|
if (new_file_fd == -1) {
|
||||||
ERR("Unable To Create Temporary File: %s", strerror(errno));
|
ERR("Unable To Create Temporary File: %s", strerror(errno));
|
||||||
@ -33,7 +31,6 @@ static void duplicate_mcpi_executable(const char *original_path) {
|
|||||||
if (new_file == NULL) {
|
if (new_file == NULL) {
|
||||||
ERR("Unable To Open Temporary File: %s", strerror(errno));
|
ERR("Unable To Open Temporary File: %s", strerror(errno));
|
||||||
}
|
}
|
||||||
set_and_print_env("MCPI_EXECUTABLE_PATH", new_path);
|
|
||||||
|
|
||||||
// Copy Original File
|
// Copy Original File
|
||||||
{
|
{
|
||||||
@ -76,7 +73,7 @@ static void duplicate_mcpi_executable(const char *original_path) {
|
|||||||
"--remove-needed", "libX11.so.6", \
|
"--remove-needed", "libX11.so.6", \
|
||||||
"--remove-needed", "libEGL.so", \
|
"--remove-needed", "libEGL.so", \
|
||||||
"--replace-needed", "libGLESv2.so", "libGLESv1_CM.so.1", \
|
"--replace-needed", "libGLESv2.so", "libGLESv1_CM.so.1", \
|
||||||
exe, \
|
new_path, \
|
||||||
NULL \
|
NULL \
|
||||||
}; \
|
}; \
|
||||||
int _macro_return_code = 0; \
|
int _macro_return_code = 0; \
|
||||||
@ -86,12 +83,9 @@ static void duplicate_mcpi_executable(const char *original_path) {
|
|||||||
} \
|
} \
|
||||||
_macro_return_code; \
|
_macro_return_code; \
|
||||||
})
|
})
|
||||||
void patch_mcpi_elf_dependencies(const char *original_path, const char *linker) {
|
void patch_mcpi_elf_dependencies(const char *original_path, char *new_path, const char *linker) {
|
||||||
// Duplicate MCPI executable into /tmp so it can be modified.
|
// Duplicate MCPI executable into /tmp so it can be modified.
|
||||||
duplicate_mcpi_executable(original_path);
|
duplicate_mcpi_executable(original_path, new_path);
|
||||||
|
|
||||||
// Get Path
|
|
||||||
char *exe = getenv("MCPI_EXECUTABLE_PATH");
|
|
||||||
|
|
||||||
// Run patchelf
|
// Run patchelf
|
||||||
int return_code;
|
int return_code;
|
||||||
@ -107,8 +101,8 @@ void patch_mcpi_elf_dependencies(const char *original_path, const char *linker)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Fix Permissions
|
// Fix Permissions
|
||||||
if (chmod(exe, S_IRUSR | S_IXUSR) != 0) {
|
if (chmod(new_path, S_IRUSR | S_IXUSR) != 0) {
|
||||||
ERR("Unable To Set File Permissions: %s: %s", exe, strerror(errno));
|
ERR("Unable To Set File Permissions: %s: %s", new_path, strerror(errno));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,7 +4,9 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void patch_mcpi_elf_dependencies(const char *original_path, const char *linker);
|
#define MCPI_PATCHED_DIR "/tmp/.minecraft-pi-patched"
|
||||||
|
|
||||||
|
void patch_mcpi_elf_dependencies(const char *original_path, char *new_path, const char *linker);
|
||||||
char *patch_get_interpreter(const char *file);
|
char *patch_get_interpreter(const char *file);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -6,6 +6,7 @@ extern "C" {
|
|||||||
|
|
||||||
#define GL_FALSE 0
|
#define GL_FALSE 0
|
||||||
#define GL_ARRAY_BUFFER_BINDING 0x8894
|
#define GL_ARRAY_BUFFER_BINDING 0x8894
|
||||||
|
#define GL_ARRAY_BUFFER 0x8892
|
||||||
#define GL_TEXTURE_BINDING_2D 0x8069
|
#define GL_TEXTURE_BINDING_2D 0x8069
|
||||||
#define GL_UNSIGNED_BYTE 0x1401
|
#define GL_UNSIGNED_BYTE 0x1401
|
||||||
#define GL_FLOAT 0x1406
|
#define GL_FLOAT 0x1406
|
||||||
|
@ -39,6 +39,21 @@ CALL(11, glFogfv, void, (GLenum pname, const GLfloat *params)) {
|
|||||||
#if defined(MEDIA_LAYER_PROXY_SERVER)
|
#if defined(MEDIA_LAYER_PROXY_SERVER)
|
||||||
#define CALL_GL_POINTER(unique_id, name) \
|
#define CALL_GL_POINTER(unique_id, name) \
|
||||||
CALL(unique_id, name, void, (GLint size, GLenum type, GLsizei stride, const void *pointer)) { \
|
CALL(unique_id, name, void, (GLint size, GLenum type, GLsizei stride, const void *pointer)) { \
|
||||||
|
/* Check */ \
|
||||||
|
static int last_set = 0; \
|
||||||
|
static GLint last_size; \
|
||||||
|
static GLenum last_type; \
|
||||||
|
static GLsizei last_stride; \
|
||||||
|
static const void *last_pointer; \
|
||||||
|
if (last_set && last_size == size && last_type == type && last_stride == stride && last_pointer == pointer) { \
|
||||||
|
return; \
|
||||||
|
} else { \
|
||||||
|
last_set = 1; \
|
||||||
|
last_size = size; \
|
||||||
|
last_type = type; \
|
||||||
|
last_stride = stride; \
|
||||||
|
last_pointer = pointer; \
|
||||||
|
} \
|
||||||
/* Lock Proxy */ \
|
/* Lock Proxy */ \
|
||||||
start_proxy_call(); \
|
start_proxy_call(); \
|
||||||
\
|
\
|
||||||
@ -107,6 +122,31 @@ CALL(14, glBlendFunc, void, (GLenum sfactor, GLenum dfactor)) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Track Bindings
|
||||||
|
#if defined(MEDIA_LAYER_PROXY_SERVER)
|
||||||
|
static GLuint bound_buffer = 0;
|
||||||
|
static GLuint bound_texture = 0;
|
||||||
|
static unsigned char vertex_array_enabled = 0;
|
||||||
|
static unsigned char color_array_enabled = 0;
|
||||||
|
static unsigned char tex_coord_array_enabled = 0;
|
||||||
|
static unsigned char *get_array_enabled_pointer(GLenum array) {
|
||||||
|
switch (array) {
|
||||||
|
case GL_VERTEX_ARRAY: {
|
||||||
|
return &vertex_array_enabled;
|
||||||
|
}
|
||||||
|
case GL_COLOR_ARRAY: {
|
||||||
|
return &color_array_enabled;
|
||||||
|
}
|
||||||
|
case GL_TEXTURE_COORD_ARRAY: {
|
||||||
|
return &tex_coord_array_enabled;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
ERR("Unsupported Array Pointer: %i", array);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
CALL(15, glDrawArrays, void, (GLenum mode, GLint first, GLsizei count)) {
|
CALL(15, glDrawArrays, void, (GLenum mode, GLint first, GLsizei count)) {
|
||||||
#if defined(MEDIA_LAYER_PROXY_SERVER)
|
#if defined(MEDIA_LAYER_PROXY_SERVER)
|
||||||
// Lock Proxy
|
// Lock Proxy
|
||||||
@ -116,6 +156,13 @@ CALL(15, glDrawArrays, void, (GLenum mode, GLint first, GLsizei count)) {
|
|||||||
write_int((uint32_t) mode);
|
write_int((uint32_t) mode);
|
||||||
write_int((uint32_t) first);
|
write_int((uint32_t) first);
|
||||||
write_int((uint32_t) count);
|
write_int((uint32_t) count);
|
||||||
|
write_int(bound_buffer);
|
||||||
|
write_int(bound_texture);
|
||||||
|
if (!vertex_array_enabled) {
|
||||||
|
IMPOSSIBLE();
|
||||||
|
}
|
||||||
|
write_byte(color_array_enabled);
|
||||||
|
write_byte(tex_coord_array_enabled);
|
||||||
|
|
||||||
// Release Proxy
|
// Release Proxy
|
||||||
end_proxy_call();
|
end_proxy_call();
|
||||||
@ -123,7 +170,17 @@ CALL(15, glDrawArrays, void, (GLenum mode, GLint first, GLsizei count)) {
|
|||||||
GLenum mode = (GLenum) read_int();
|
GLenum mode = (GLenum) read_int();
|
||||||
GLint first = (GLint) read_int();
|
GLint first = (GLint) read_int();
|
||||||
GLsizei count = (GLsizei) read_int();
|
GLsizei count = (GLsizei) read_int();
|
||||||
|
GLuint bound_buffer = (GLuint) read_int();
|
||||||
|
GLuint bound_texture = (GLuint) read_int();
|
||||||
|
unsigned char color_array_enabled = read_byte();
|
||||||
|
unsigned char tex_coord_array_enabled = read_byte();
|
||||||
// Run
|
// Run
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, bound_buffer);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, bound_texture);
|
||||||
|
glEnableClientState(GL_VERTEX_ARRAY);
|
||||||
|
#define set_array_enabled(condition, enum) condition ? glEnableClientState(enum) : glDisableClientState(enum);
|
||||||
|
set_array_enabled(color_array_enabled, GL_COLOR_ARRAY);
|
||||||
|
set_array_enabled(tex_coord_array_enabled, GL_TEXTURE_COORD_ARRAY);
|
||||||
glDrawArrays(mode, first, count);
|
glDrawArrays(mode, first, count);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -187,6 +244,7 @@ CALL(18, glBufferData, void, (GLenum target, GLsizeiptr size, const void *data,
|
|||||||
write_int((uint32_t) target);
|
write_int((uint32_t) target);
|
||||||
write_int((uint32_t) size);
|
write_int((uint32_t) size);
|
||||||
write_int((uint32_t) usage);
|
write_int((uint32_t) usage);
|
||||||
|
write_int(bound_buffer);
|
||||||
// Write Data
|
// Write Data
|
||||||
unsigned char is_null = data == NULL;
|
unsigned char is_null = data == NULL;
|
||||||
write_byte(is_null);
|
write_byte(is_null);
|
||||||
@ -200,6 +258,7 @@ CALL(18, glBufferData, void, (GLenum target, GLsizeiptr size, const void *data,
|
|||||||
GLenum target = (GLenum) read_int();
|
GLenum target = (GLenum) read_int();
|
||||||
GLsizeiptr size = (GLsizeiptr) read_int();
|
GLsizeiptr size = (GLsizeiptr) read_int();
|
||||||
GLenum usage = (GLenum) read_int();
|
GLenum usage = (GLenum) read_int();
|
||||||
|
GLuint bound_buffer = (GLuint) read_int();
|
||||||
// Load Data
|
// Load Data
|
||||||
void *data = NULL;
|
void *data = NULL;
|
||||||
unsigned char is_null = read_byte();
|
unsigned char is_null = read_byte();
|
||||||
@ -223,6 +282,7 @@ CALL(18, glBufferData, void, (GLenum target, GLsizeiptr size, const void *data,
|
|||||||
safe_read(data, (size_t) size);
|
safe_read(data, (size_t) size);
|
||||||
}
|
}
|
||||||
// Run
|
// Run
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, bound_buffer);
|
||||||
glBufferData(target, size, data, usage);
|
glBufferData(target, size, data, usage);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -316,6 +376,7 @@ CALL(24, glTexParameteri, void, (GLenum target, GLenum pname, GLint param)) {
|
|||||||
write_int((uint32_t) target);
|
write_int((uint32_t) target);
|
||||||
write_int((uint32_t) pname);
|
write_int((uint32_t) pname);
|
||||||
write_int((uint32_t) param);
|
write_int((uint32_t) param);
|
||||||
|
write_int(bound_texture);
|
||||||
|
|
||||||
// Release Proxy
|
// Release Proxy
|
||||||
end_proxy_call();
|
end_proxy_call();
|
||||||
@ -323,7 +384,9 @@ CALL(24, glTexParameteri, void, (GLenum target, GLenum pname, GLint param)) {
|
|||||||
GLenum target = (GLenum) read_int();
|
GLenum target = (GLenum) read_int();
|
||||||
GLenum pname = (GLenum) read_int();
|
GLenum pname = (GLenum) read_int();
|
||||||
GLint param = (GLint) read_int();
|
GLint param = (GLint) read_int();
|
||||||
|
GLuint bound_texture = (GLuint) read_int();
|
||||||
// Run
|
// Run
|
||||||
|
glBindTexture(GL_TEXTURE_2D, bound_texture);
|
||||||
glTexParameteri(target, pname, param);
|
glTexParameteri(target, pname, param);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -383,6 +446,7 @@ CALL(25, glTexImage2D, void, (GLenum target, GLint level, GLint internalformat,
|
|||||||
write_int((uint32_t) border);
|
write_int((uint32_t) border);
|
||||||
write_int((uint32_t) format);
|
write_int((uint32_t) format);
|
||||||
write_int((uint32_t) type);
|
write_int((uint32_t) type);
|
||||||
|
write_int(bound_texture);
|
||||||
write_byte(is_null);
|
write_byte(is_null);
|
||||||
if (!is_null) {
|
if (!is_null) {
|
||||||
safe_write((void *) pixels, (size_t) size);
|
safe_write((void *) pixels, (size_t) size);
|
||||||
@ -399,6 +463,7 @@ CALL(25, glTexImage2D, void, (GLenum target, GLint level, GLint internalformat,
|
|||||||
GLint border = (GLint) read_int();
|
GLint border = (GLint) read_int();
|
||||||
GLenum format = (GLenum) read_int();
|
GLenum format = (GLenum) read_int();
|
||||||
GLenum type = (GLenum) read_int();
|
GLenum type = (GLenum) read_int();
|
||||||
|
GLuint bound_texture = (GLuint) read_int();
|
||||||
unsigned char is_null = read_byte();
|
unsigned char is_null = read_byte();
|
||||||
void *pixels = NULL;
|
void *pixels = NULL;
|
||||||
if (!is_null) {
|
if (!is_null) {
|
||||||
@ -408,6 +473,7 @@ CALL(25, glTexImage2D, void, (GLenum target, GLint level, GLint internalformat,
|
|||||||
safe_read(pixels, (size_t) size);
|
safe_read(pixels, (size_t) size);
|
||||||
}
|
}
|
||||||
// Run
|
// Run
|
||||||
|
glBindTexture(GL_TEXTURE_2D, bound_texture);
|
||||||
glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels);
|
glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels);
|
||||||
// Free
|
// Free
|
||||||
if (!is_null) {
|
if (!is_null) {
|
||||||
@ -433,22 +499,17 @@ CALL(26, glEnable, void, (GLenum cap)) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
CALL(27, glEnableClientState, void, (GLenum array)) {
|
|
||||||
#if defined(MEDIA_LAYER_PROXY_SERVER)
|
#if defined(MEDIA_LAYER_PROXY_SERVER)
|
||||||
// Lock Proxy
|
void glEnableClientState(GLenum array) {
|
||||||
start_proxy_call();
|
// Set
|
||||||
|
unsigned char *enabled = get_array_enabled_pointer(array);
|
||||||
// Arguments
|
if (*enabled) {
|
||||||
write_int((uint32_t) array);
|
return;
|
||||||
|
} else {
|
||||||
// Release Proxy
|
*enabled = 1;
|
||||||
end_proxy_call();
|
}
|
||||||
#else
|
|
||||||
GLenum array = (GLenum) read_int();
|
|
||||||
// Run
|
|
||||||
glEnableClientState(array);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
CALL(28, glPolygonOffset, void, (GLfloat factor, GLfloat units)) {
|
CALL(28, glPolygonOffset, void, (GLfloat factor, GLfloat units)) {
|
||||||
#if defined(MEDIA_LAYER_PROXY_SERVER)
|
#if defined(MEDIA_LAYER_PROXY_SERVER)
|
||||||
@ -469,22 +530,17 @@ CALL(28, glPolygonOffset, void, (GLfloat factor, GLfloat units)) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
CALL(29, glDisableClientState, void, (GLenum array)) {
|
|
||||||
#if defined(MEDIA_LAYER_PROXY_SERVER)
|
#if defined(MEDIA_LAYER_PROXY_SERVER)
|
||||||
// Lock Proxy
|
void glDisableClientState(GLenum array) {
|
||||||
start_proxy_call();
|
// Set
|
||||||
|
unsigned char *enabled = get_array_enabled_pointer(array);
|
||||||
// Arguments
|
if (!*enabled) {
|
||||||
write_int((uint32_t) array);
|
return;
|
||||||
|
} else {
|
||||||
// Release Proxy
|
*enabled = 0;
|
||||||
end_proxy_call();
|
}
|
||||||
#else
|
|
||||||
GLenum array = (GLenum) read_int();
|
|
||||||
// Run
|
|
||||||
glDisableClientState(array);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
CALL(30, glDepthRangef, void, (GLclampf near, GLclampf far)) {
|
CALL(30, glDepthRangef, void, (GLclampf near, GLclampf far)) {
|
||||||
#if defined(MEDIA_LAYER_PROXY_SERVER)
|
#if defined(MEDIA_LAYER_PROXY_SERVER)
|
||||||
@ -522,24 +578,16 @@ CALL(31, glDepthFunc, void, (GLenum func)) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
CALL(32, glBindBuffer, void, (GLenum target, GLuint buffer)) {
|
|
||||||
#if defined(MEDIA_LAYER_PROXY_SERVER)
|
#if defined(MEDIA_LAYER_PROXY_SERVER)
|
||||||
// Lock Proxy
|
void glBindBuffer(GLenum target, GLuint buffer) {
|
||||||
start_proxy_call();
|
// Set
|
||||||
|
if (target == GL_ARRAY_BUFFER) {
|
||||||
// Arguments
|
bound_buffer = buffer;
|
||||||
write_int((uint32_t) target);
|
} else {
|
||||||
write_int((uint32_t) buffer);
|
PROXY_ERR("Unsupported Buffer Binding: %u", target);
|
||||||
|
}
|
||||||
// Release Proxy
|
|
||||||
end_proxy_call();
|
|
||||||
#else
|
|
||||||
GLenum target = (GLenum) read_int();
|
|
||||||
GLuint buffer = (GLuint) read_int();
|
|
||||||
// Run
|
|
||||||
glBindBuffer(target, buffer);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
CALL(33, glClearColor, void, (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)) {
|
CALL(33, glClearColor, void, (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)) {
|
||||||
#if defined(MEDIA_LAYER_PROXY_SERVER)
|
#if defined(MEDIA_LAYER_PROXY_SERVER)
|
||||||
@ -748,6 +796,7 @@ CALL(44, glTexSubImage2D, void, (GLenum target, GLint level, GLint xoffset, GLin
|
|||||||
write_int((uint32_t) height);
|
write_int((uint32_t) height);
|
||||||
write_int((uint32_t) format);
|
write_int((uint32_t) format);
|
||||||
write_int((uint32_t) type);
|
write_int((uint32_t) type);
|
||||||
|
write_int(bound_texture);
|
||||||
write_byte(is_null);
|
write_byte(is_null);
|
||||||
if (!is_null) {
|
if (!is_null) {
|
||||||
safe_write((void *) pixels, (size_t) size);
|
safe_write((void *) pixels, (size_t) size);
|
||||||
@ -764,6 +813,7 @@ CALL(44, glTexSubImage2D, void, (GLenum target, GLint level, GLint xoffset, GLin
|
|||||||
GLsizei height = (GLsizei) read_int();
|
GLsizei height = (GLsizei) read_int();
|
||||||
GLenum format = (GLenum) read_int();
|
GLenum format = (GLenum) read_int();
|
||||||
GLenum type = (GLenum) read_int();
|
GLenum type = (GLenum) read_int();
|
||||||
|
GLuint bound_texture = (GLuint) read_int();
|
||||||
unsigned char is_null = read_byte();
|
unsigned char is_null = read_byte();
|
||||||
void *pixels = NULL;
|
void *pixels = NULL;
|
||||||
if (!is_null) {
|
if (!is_null) {
|
||||||
@ -773,6 +823,7 @@ CALL(44, glTexSubImage2D, void, (GLenum target, GLint level, GLint xoffset, GLin
|
|||||||
safe_read(pixels, (size_t) size);
|
safe_read(pixels, (size_t) size);
|
||||||
}
|
}
|
||||||
// Run
|
// Run
|
||||||
|
glBindTexture(GL_TEXTURE_2D, bound_texture);
|
||||||
glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
|
glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
|
||||||
// Free
|
// Free
|
||||||
if (!is_null) {
|
if (!is_null) {
|
||||||
@ -887,24 +938,16 @@ CALL(48, glGetFloatv, void, (GLenum pname, GLfloat *params)) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
CALL(49, glBindTexture, void, (GLenum target, GLuint texture)) {
|
|
||||||
#if defined(MEDIA_LAYER_PROXY_SERVER)
|
#if defined(MEDIA_LAYER_PROXY_SERVER)
|
||||||
// Lock Proxy
|
void glBindTexture(GLenum target, GLuint texture) {
|
||||||
start_proxy_call();
|
// Set
|
||||||
|
if (target == GL_TEXTURE_2D) {
|
||||||
// Arguments
|
bound_texture = texture;
|
||||||
write_int((uint32_t) target);
|
} else {
|
||||||
write_int((uint32_t) texture);
|
PROXY_ERR("Unsupported Texture Binding: %u", target);
|
||||||
|
}
|
||||||
// Release Proxy
|
|
||||||
end_proxy_call();
|
|
||||||
#else
|
|
||||||
GLenum target = (GLenum) read_int();
|
|
||||||
GLuint texture = (GLuint) read_int();
|
|
||||||
// Run
|
|
||||||
glBindTexture(target, texture);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
CALL(50, glTranslatef, void, (GLfloat x, GLfloat y, GLfloat z)) {
|
CALL(50, glTranslatef, void, (GLfloat x, GLfloat y, GLfloat z)) {
|
||||||
#if defined(MEDIA_LAYER_PROXY_SERVER)
|
#if defined(MEDIA_LAYER_PROXY_SERVER)
|
||||||
|
@ -9,18 +9,15 @@
|
|||||||
#include "../common/common.h"
|
#include "../common/common.h"
|
||||||
|
|
||||||
// Store Handlers
|
// Store Handlers
|
||||||
__attribute__((const)) static std::vector<proxy_handler_t> &get_handlers() {
|
static std::vector<proxy_handler_t> handlers;
|
||||||
static std::vector<proxy_handler_t> handlers;
|
|
||||||
return handlers;
|
|
||||||
}
|
|
||||||
void _add_handler(unsigned char unique_id, proxy_handler_t handler) {
|
void _add_handler(unsigned char unique_id, proxy_handler_t handler) {
|
||||||
if (get_handlers().size() > unique_id && get_handlers()[unique_id] != NULL) {
|
if (handlers.size() > unique_id && handlers[unique_id] != NULL) {
|
||||||
PROXY_ERR("Duplicate ID: %i", (int) unique_id);
|
PROXY_ERR("Duplicate ID: %i", (int) unique_id);
|
||||||
}
|
}
|
||||||
if (get_handlers().size() <= unique_id) {
|
if (handlers.size() <= unique_id) {
|
||||||
get_handlers().resize(unique_id + 1);
|
handlers.resize(unique_id + 1);
|
||||||
}
|
}
|
||||||
get_handlers()[unique_id] = handler;
|
handlers[unique_id] = handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store Parent PID
|
// Store Parent PID
|
||||||
@ -48,10 +45,7 @@ static void exit_handler(__attribute__((unused)) int signal_id) {
|
|||||||
// Main
|
// Main
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
// Install Signal Handlers
|
// Install Signal Handlers
|
||||||
struct sigaction act_sigint;
|
signal(SIGINT, SIG_IGN);
|
||||||
memset((void *) &act_sigint, 0, sizeof (struct sigaction));
|
|
||||||
act_sigint.sa_handler = &exit_handler;
|
|
||||||
sigaction(SIGINT, &act_sigint, NULL);
|
|
||||||
struct sigaction act_sigterm;
|
struct sigaction act_sigterm;
|
||||||
memset((void *) &act_sigterm, 0, sizeof (struct sigaction));
|
memset((void *) &act_sigterm, 0, sizeof (struct sigaction));
|
||||||
act_sigterm.sa_handler = &exit_handler;
|
act_sigterm.sa_handler = &exit_handler;
|
||||||
@ -84,9 +78,9 @@ int main(int argc, char *argv[]) {
|
|||||||
int running = is_connection_open();
|
int running = is_connection_open();
|
||||||
while (running && !exit_requested) {
|
while (running && !exit_requested) {
|
||||||
unsigned char unique_id = read_byte();
|
unsigned char unique_id = read_byte();
|
||||||
if (get_handlers().size() > unique_id && get_handlers()[unique_id] != NULL) {
|
if (handlers.size() > unique_id && handlers[unique_id] != NULL) {
|
||||||
// Run Method
|
// Run Method
|
||||||
get_handlers()[unique_id]();
|
handlers[unique_id]();
|
||||||
// Check If Connection Is Still Open
|
// Check If Connection Is Still Open
|
||||||
if (!is_connection_open()) {
|
if (!is_connection_open()) {
|
||||||
// Exit
|
// Exit
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
@ -12,23 +14,80 @@
|
|||||||
PROXY_ERR("Attempting To Access Closed Connection"); \
|
PROXY_ERR("Attempting To Access Closed Connection"); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
// Buffer Reads
|
||||||
|
static void *_read_cache = NULL;
|
||||||
|
__attribute__((destructor)) static void _free_read_cache() {
|
||||||
|
if (_read_cache != NULL) {
|
||||||
|
free(_read_cache);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static size_t _read_cache_size = 0;
|
||||||
|
static size_t _read_cache_actual_size = 0;
|
||||||
|
static size_t _read_cache_position = 0;
|
||||||
|
#define max(a, b) (((a) > (b)) ? (a) : (b))
|
||||||
|
#define min(a, b) (((a) < (b)) ? (a) : (b))
|
||||||
void safe_read(void *buf, size_t len) {
|
void safe_read(void *buf, size_t len) {
|
||||||
// Check Data
|
// Check Data
|
||||||
if (buf == NULL) {
|
if (buf == NULL) {
|
||||||
PROXY_ERR("Attempting To Read Into NULL Buffer");
|
PROXY_ERR("Attempting To Read Into NULL Buffer");
|
||||||
}
|
}
|
||||||
|
// Setup
|
||||||
|
size_t to_read = len;
|
||||||
|
// Copy From Read Buffer
|
||||||
|
if (_read_cache != NULL && _read_cache_size > 0) {
|
||||||
|
char *read_cache = (void *) (((unsigned char *) _read_cache) + _read_cache_position);
|
||||||
|
size_t read_cache_size = _read_cache_size - _read_cache_position;
|
||||||
|
if (read_cache_size > 0) {
|
||||||
|
size_t to_copy = min(to_read, read_cache_size);
|
||||||
|
memcpy(buf, read_cache, to_copy);
|
||||||
|
to_read -= to_copy;
|
||||||
|
_read_cache_position += to_copy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Check If Done
|
||||||
|
if (to_read < 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (_read_cache_position < _read_cache_size) {
|
||||||
|
IMPOSSIBLE();
|
||||||
|
}
|
||||||
// Flush Write Cache
|
// Flush Write Cache
|
||||||
flush_write_cache();
|
flush_write_cache();
|
||||||
// Read
|
// Read Remaining Data
|
||||||
size_t to_read = len;
|
size_t to_read_to_cache;
|
||||||
while (to_read > 0) {
|
{
|
||||||
|
int bytes_available;
|
||||||
|
if (ioctl(get_connection_read(), FIONREAD, &bytes_available) == -1) {
|
||||||
|
bytes_available = 0;
|
||||||
|
}
|
||||||
|
to_read_to_cache = max((size_t) bytes_available, to_read);
|
||||||
|
}
|
||||||
|
if (to_read_to_cache < 1) {
|
||||||
|
// Nothing To Read
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Resize Buffer
|
||||||
|
_read_cache_position = 0;
|
||||||
|
_read_cache_size = to_read_to_cache;
|
||||||
|
if (_read_cache == NULL) {
|
||||||
|
_read_cache_actual_size = _read_cache_size;
|
||||||
|
_read_cache = malloc(_read_cache_actual_size);
|
||||||
|
} else if (_read_cache_size > _read_cache_actual_size) {
|
||||||
|
_read_cache_actual_size = _read_cache_size;
|
||||||
|
_read_cache = realloc(_read_cache, _read_cache_actual_size);
|
||||||
|
}
|
||||||
|
ALLOC_CHECK(_read_cache);
|
||||||
|
// Read Into Buffer
|
||||||
|
while (to_read_to_cache > 0) {
|
||||||
CHECK_CONNECTION();
|
CHECK_CONNECTION();
|
||||||
ssize_t x = read(get_connection_read(), (void *) (((unsigned char *) buf) + (len - to_read)), to_read);
|
ssize_t x = read(get_connection_read(), (void *) (((unsigned char *) _read_cache) + (_read_cache_size - to_read_to_cache)), to_read_to_cache);
|
||||||
if (x == -1 && errno != EINTR) {
|
if (x == -1 && errno != EINTR) {
|
||||||
PROXY_ERR("Failed Reading Data To Connection: %s", strerror(errno));
|
PROXY_ERR("Failed Reading Data To Connection: %s", strerror(errno));
|
||||||
}
|
}
|
||||||
to_read -= x;
|
to_read_to_cache -= x;
|
||||||
}
|
}
|
||||||
|
// Copy Remaining Data
|
||||||
|
safe_read((void *) (((unsigned char *) buf) + (len - to_read)), to_read);
|
||||||
}
|
}
|
||||||
// Buffer Writes
|
// Buffer Writes
|
||||||
static void *_write_cache = NULL;
|
static void *_write_cache = NULL;
|
||||||
|
@ -133,13 +133,18 @@ void init_compat() {
|
|||||||
__attribute__((destructor)) static void cleanup_temporary() {
|
__attribute__((destructor)) static void cleanup_temporary() {
|
||||||
// Cleanup Executable
|
// Cleanup Executable
|
||||||
{
|
{
|
||||||
const char *exe = getenv("MCPI_EXECUTABLE_PATH");
|
char *exe = realpath("/proc/self/exe", NULL);
|
||||||
// Check If Executable Is Temporary
|
// Check If Successful
|
||||||
if (exe != NULL && starts_with(exe, "/tmp")) {
|
if (exe != NULL) {
|
||||||
// Cleanup Temporary File
|
// Check If Executable Is Temporary
|
||||||
if (unlink(exe) != 0) {
|
if (starts_with(exe, "/tmp")) {
|
||||||
ERR("Unable To Cleanup Temporary File: %s", strerror(errno));
|
// Cleanup Temporary File
|
||||||
|
if (unlink(exe) != 0) {
|
||||||
|
ERR("Unable To Cleanup Temporary File: %s", strerror(errno));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
// Free
|
||||||
|
free(exe);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,6 +38,7 @@ if (mode === 'client') {
|
|||||||
'libgtk-3-0',
|
'libgtk-3-0',
|
||||||
'libglib2.0-0',
|
'libglib2.0-0',
|
||||||
'libgdk-pixbuf2.0-0',
|
'libgdk-pixbuf2.0-0',
|
||||||
|
'librsvg2-common',
|
||||||
'shared-mime-info',
|
'shared-mime-info',
|
||||||
'libfreeimage3',
|
'libfreeimage3',
|
||||||
'libopenal1'
|
'libopenal1'
|
||||||
@ -59,7 +60,8 @@ const packageExclusions = [
|
|||||||
'librest-*',
|
'librest-*',
|
||||||
'libcups2',
|
'libcups2',
|
||||||
'libcolord2',
|
'libcolord2',
|
||||||
'libmount1'
|
'libmount1',
|
||||||
|
'libwayland-*'
|
||||||
];
|
];
|
||||||
|
|
||||||
// APT
|
// APT
|
||||||
|
Loading…
Reference in New Issue
Block a user