Merge branch 'master' into master
This commit is contained in:
commit
5a8e5e5817
25 changed files with 279 additions and 149 deletions
|
|
@ -5,8 +5,8 @@ include(CTest)
|
|||
include(GNUInstallDirs)
|
||||
|
||||
if (NOT CMAKE_BUILD_TYPE)
|
||||
message(STATUS "No build type selected, default to release")
|
||||
set(CMAKE_BUILD_TYPE "release")
|
||||
message(STATUS "No build type selected, default to RelWithDebInfo")
|
||||
set(CMAKE_BUILD_TYPE "RelWithDebInfo")
|
||||
endif()
|
||||
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ $ anbox-installer
|
|||
|
||||
This will guide you through the installation process.
|
||||
|
||||
**NOTE:** Anbox is currently in a **pre-alpha development state**. Don't expect a
|
||||
**NOTE:** Anbox is currently in a **alpha development state**. Don't expect a
|
||||
fully working system for a production system with all features you need. You will
|
||||
for sure see bugs and crashes. If you do so, please don't hestitate and report them!
|
||||
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ anbox::PlatformApiStub::WindowStateUpdate::Window PlatformService::unpack_window
|
|||
auto frame_bottom = data.readInt32();
|
||||
auto task_id = data.readInt32();
|
||||
auto stack_id = data.readInt32();
|
||||
auto rotation_angle = data.readInt32();
|
||||
|
||||
return anbox::PlatformApiStub::WindowStateUpdate::Window{
|
||||
-1, // Display id will be added by the caller
|
||||
|
|
|
|||
2
debian/compat
vendored
2
debian/compat
vendored
|
|
@ -1 +1 @@
|
|||
7
|
||||
9
|
||||
|
|
|
|||
4
debian/control
vendored
4
debian/control
vendored
|
|
@ -2,8 +2,8 @@ Source: anbox
|
|||
Section: misc
|
||||
Priority: optional
|
||||
Maintainer: Simon Fels <morphis@gravedo.de>
|
||||
Build-Depends: debhelper (>= 7), dkms, dh-systemd
|
||||
Standards-Version: 3.9.7
|
||||
Build-Depends: debhelper (>= 9), dkms, dh-systemd
|
||||
Standards-Version: 4.1.3
|
||||
Homepage: http://anbox.io
|
||||
Vcs-Browser: https://github.com/anbox/anbox
|
||||
Vcs-Git: https://github.com/anbox/anbox.git
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -1048,8 +1048,10 @@ GL_APICALL void GL_APIENTRY glGetIntegerv(GLenum pname, GLint* params){
|
|||
if (ctx->glGetIntegerv(pname,params))
|
||||
{
|
||||
if (destroyCtx)
|
||||
{
|
||||
deleteGLESContext(ctx);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool es2 = ctx->getCaps()->GL_ARB_ES2_COMPATIBILITY;
|
||||
|
|
|
|||
|
|
@ -753,6 +753,10 @@ int ApiGen::genDecoderHeader(const std::string &filename)
|
|||
|
||||
fprintf(fp, "#include \"IOStream.h\" \n");
|
||||
fprintf(fp, "#include \"%s_%s_context.h\"\n\n\n", m_basename.c_str(), sideString(SERVER_SIDE));
|
||||
if (strcmp(classname.c_str(), "gles2_decoder_context_t") == 0) {
|
||||
fprintf(fp, "\n#include <map>\n");
|
||||
fprintf(fp, "\n#include <mutex>\n");
|
||||
}
|
||||
fprintf(fp, "\n#include \"emugl/common/logging.h\"\n");
|
||||
|
||||
for (size_t i = 0; i < m_decoderHeaders.size(); i++) {
|
||||
|
|
@ -763,6 +767,17 @@ int ApiGen::genDecoderHeader(const std::string &filename)
|
|||
fprintf(fp, "struct %s : public %s_%s_context_t {\n\n",
|
||||
classname.c_str(), m_basename.c_str(), sideString(SERVER_SIDE));
|
||||
fprintf(fp, "\tsize_t decode(void *buf, size_t bufsize, IOStream *stream);\n");
|
||||
if (strcmp(classname.c_str(), "gles2_decoder_context_t") == 0){
|
||||
fprintf(fp,
|
||||
"\tvoid freeShader(); \n\
|
||||
\tvoid freeProgram(); \n\
|
||||
\tstd::map<GLuint, GLuint> m_programs; \n\
|
||||
\tstd::map<GLuint, GLuint> m_shaders; \n\
|
||||
\tstd::mutex m_lock; \n\
|
||||
");
|
||||
|
||||
|
||||
}
|
||||
fprintf(fp, "\n};\n\n");
|
||||
fprintf(fp, "#endif // GUARD_%s\n", classname.c_str());
|
||||
|
||||
|
|
@ -835,6 +850,35 @@ int ApiGen::genDecoderImpl(const std::string &filename)
|
|||
// helper templates
|
||||
fprintf(fp, "using namespace emugl;\n\n");
|
||||
|
||||
// glsl shader/program free;
|
||||
if (strcmp(classname.c_str(), "gles2_decoder_context_t") == 0) {
|
||||
fprintf(fp, "void %s::freeShader(){\n", classname.c_str());
|
||||
fprintf(fp,
|
||||
" \n\
|
||||
\tauto it = m_shaders.begin();\n\
|
||||
\tm_lock.lock();\n\
|
||||
\twhile(it != m_shaders.end()) \n\
|
||||
\t{\n\
|
||||
\t\tthis->glDeleteShader(it->first);\n\
|
||||
\t\tit++;\n\
|
||||
\t}\n\
|
||||
\tm_lock.unlock();\n\
|
||||
}\n\n");
|
||||
|
||||
fprintf(fp, "void %s::freeProgram(){\n", classname.c_str());
|
||||
fprintf(fp,
|
||||
" \n\
|
||||
\tauto it = m_programs.begin(); \n\
|
||||
\tm_lock.lock();\n\
|
||||
\twhile(it != m_programs.end()) \n\
|
||||
\t{\n\
|
||||
\t\tthis->glDeleteProgram(it->first);\n\
|
||||
\t\tit++;\n\
|
||||
\t}\n\
|
||||
\tm_lock.unlock();\n\
|
||||
}\n\n");
|
||||
}
|
||||
|
||||
// decoder switch;
|
||||
fprintf(fp, "size_t %s::decode(void *buf, size_t len, IOStream *stream)\n{\n", classname.c_str());
|
||||
fprintf(fp,
|
||||
|
|
@ -1114,8 +1158,7 @@ int ApiGen::genDecoderImpl(const std::string &filename)
|
|||
varoffset.c_str(),
|
||||
varoffset.c_str(),
|
||||
varoffset.c_str(),
|
||||
classname.c_str(),
|
||||
e->name().c_str()
|
||||
classname.c_str()
|
||||
);
|
||||
|
||||
varoffset += " + 4";
|
||||
|
|
@ -1161,6 +1204,37 @@ int ApiGen::genDecoderImpl(const std::string &filename)
|
|||
|
||||
} // pass;
|
||||
fprintf(fp, "\t\t\tSET_LASTCALL(\"%s\");\n", e->name().c_str());
|
||||
if (strcmp(m_basename.c_str(), "gles2") == 0) {
|
||||
if (strcmp(e->name().c_str(), "glAttachShader") == 0){
|
||||
fprintf(fp, "\n\
|
||||
\t\t\tm_lock.lock();\n\
|
||||
m_shaders.insert({var_shader, 1});\n\
|
||||
m_lock.unlock();\n");
|
||||
} else if(strcmp(e->name().c_str(), "glDeleteProgram") == 0){
|
||||
fprintf(fp,
|
||||
"\t\t\tm_lock.lock(); \n"
|
||||
"\t\t\tauto pro = m_programs.find(var_program); \n"
|
||||
"\t\t\tif (pro != m_programs.end()) \n"
|
||||
"\t\t\t{ \n"
|
||||
"\t\t\t\tm_programs.erase(pro); \n"
|
||||
"\t\t\t}\n"
|
||||
"\t\t\tm_lock.unlock();\n");
|
||||
} else if(strcmp(e->name().c_str(), "glDeleteShader") == 0){
|
||||
fprintf(fp,
|
||||
"\t\t\tm_lock.lock(); \n\
|
||||
\t\t\tauto shader = m_shaders.find(var_shader); \n\
|
||||
\t\t\tif (shader != m_shaders.end()) \n\
|
||||
\t\t\t{ \n\
|
||||
\t\t\t\tm_shaders.erase(shader); \n\
|
||||
\t\t\t} \n\
|
||||
\t\t\tm_lock.unlock(); \n");
|
||||
} else if(strcmp(e->name().c_str(), "glLinkProgram") == 0){
|
||||
fprintf(fp, " \n\
|
||||
\t\t\tm_lock.lock();\n\
|
||||
\t\t\tm_programs.insert({var_program, 1});\n\
|
||||
\t\t\tm_lock.unlock();\n");
|
||||
}
|
||||
}
|
||||
fprintf(fp, "\t\t\tbreak;\n");
|
||||
fprintf(fp, "\t\t}\n");
|
||||
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ bool EntryPoint::parse(unsigned int lc, const std::string & str)
|
|||
std::string vartype, varname;
|
||||
if (!parseParameterDeclaration(field, &vartype, &varname, &error)) {
|
||||
fprintf(stderr,
|
||||
"line: %d: Parsing error in field <%s>\n",
|
||||
"line: %d: Parsing error in field <%s>, error: %s\n",
|
||||
lc,
|
||||
field.c_str(),
|
||||
error.c_str());
|
||||
|
|
|
|||
|
|
@ -204,7 +204,7 @@ private:
|
|||
}
|
||||
|
||||
std::shared_ptr<core::posix::SignalTrap> core::posix::trap_signals_for_process(
|
||||
std::initializer_list<core::posix::Signal> blocked_signals)
|
||||
std::initializer_list<core::posix::Signal> blocked_signals)
|
||||
{
|
||||
return std::make_shared<impl::SignalTrap>(
|
||||
impl::SignalTrap::Scope::process,
|
||||
|
|
|
|||
|
|
@ -312,8 +312,14 @@ static ssize_t ashmem_read(struct file *file, char __user *buf,
|
|||
* once asma->file is set it will never be changed, and will not
|
||||
* be destroyed until all references to the file are dropped and
|
||||
* ashmem_release is called.
|
||||
*
|
||||
* kernel_read supersedes vfs_read from kernel version 3.9
|
||||
*/
|
||||
ret = __vfs_read(asma->file, buf, len, pos);
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0)
|
||||
ret = __vfs_read(asma->file, buf, len, pos);
|
||||
#else
|
||||
ret = kernel_read(asma->file, buf, len, pos);
|
||||
#endif
|
||||
if (ret >= 0)
|
||||
/** Update backing file pos, since f_ops->read() doesn't */
|
||||
asma->file->f_pos = *pos;
|
||||
|
|
|
|||
|
|
@ -137,7 +137,11 @@ static DECLARE_WAIT_QUEUE_HEAD(binder_user_error_wait);
|
|||
static int binder_stop_on_user_error;
|
||||
|
||||
static int binder_set_stop_on_user_error(const char *val,
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)
|
||||
const struct kernel_param *kp)
|
||||
#else
|
||||
struct kernel_param *kp)
|
||||
#endif
|
||||
{
|
||||
int ret;
|
||||
|
||||
|
|
|
|||
|
|
@ -56,8 +56,8 @@ cleanup
|
|||
mkdir build || rm -rf build/*
|
||||
cd build
|
||||
cmake ..
|
||||
make -j10
|
||||
make test
|
||||
VERBOSE=1 make -j10
|
||||
VERBOSE=1 make test
|
||||
cd ..
|
||||
|
||||
cleanup
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
#
|
||||
# Anything else is an error.
|
||||
|
||||
from __future__ import print_function
|
||||
import re
|
||||
import sys
|
||||
import argparse
|
||||
|
|
@ -32,6 +33,9 @@ import argparse
|
|||
re_func = re.compile(r"""^(.*[\* ])([A-Za-z_][A-Za-z0-9_]*)\((.*)\);$""")
|
||||
re_param = re.compile(r"""^(.*[\* ])([A-Za-z_][A-Za-z0-9_]*)$""")
|
||||
|
||||
def eprint(*args, **kwargs):
|
||||
print(*args, file=sys.stderr, **kwargs)
|
||||
|
||||
class Entry:
|
||||
"""Small class used to model a single DLL entry point."""
|
||||
def __init__(self, func_name, return_type, parameters):
|
||||
|
|
@ -128,28 +132,28 @@ def gen_functions_header(entries, prefix_name, verbatim, filename, with_args):
|
|||
"""
|
||||
prefix_name = prefix_name.upper()
|
||||
|
||||
print "// Auto-generated with: %s" % banner_command(sys.argv)
|
||||
print "// DO NOT EDIT THIS FILE"
|
||||
print ""
|
||||
print "#ifndef %s_FUNCTIONS_H" % prefix_name
|
||||
print "#define %s_FUNCTIONS_H" % prefix_name
|
||||
print ""
|
||||
print("// Auto-generated with: %s" % banner_command(sys.argv))
|
||||
print("// DO NOT EDIT THIS FILE")
|
||||
print("")
|
||||
print("#ifndef %s_FUNCTIONS_H" % prefix_name)
|
||||
print("#define %s_FUNCTIONS_H" % prefix_name)
|
||||
print("")
|
||||
for line in verbatim:
|
||||
print line
|
||||
print(line)
|
||||
|
||||
print "#define LIST_%s_FUNCTIONS(X) \\" % prefix_name
|
||||
print("#define LIST_%s_FUNCTIONS(X) \\" % prefix_name)
|
||||
for entry in entries:
|
||||
if with_args:
|
||||
print " X(%s, %s, (%s), (%s)) \\" % \
|
||||
print(" X(%s, %s, (%s), (%s)) \\" % \
|
||||
(entry.return_type, entry.func_name, entry.parameters,
|
||||
entry.call)
|
||||
entry.call))
|
||||
else:
|
||||
print " X(%s, %s, (%s)) \\" % \
|
||||
(entry.return_type, entry.func_name, entry.parameters)
|
||||
print(" X(%s, %s, (%s)) \\" % \
|
||||
(entry.return_type, entry.func_name, entry.parameters))
|
||||
|
||||
print ""
|
||||
print ""
|
||||
print "#endif // %s_FUNCTIONS_H" % prefix_name
|
||||
print("")
|
||||
print("")
|
||||
print("#endif // %s_FUNCTIONS_H" % prefix_name)
|
||||
|
||||
|
||||
|
||||
|
|
@ -199,10 +203,10 @@ def gen_translator(entries):
|
|||
"glProgramUniform3ui": 1,
|
||||
"glProgramUniform4ui": 1,
|
||||
"glBindVertexBuffer": 1,
|
||||
};
|
||||
}
|
||||
translator_nocontext_fail_codes = {
|
||||
"glClientWaitSync" : "GL_WAIT_FAILED",
|
||||
};
|
||||
}
|
||||
def needExternC(entry):
|
||||
if translator_needexternc.has_key(entry.func_name):
|
||||
return "extern \"C\" "
|
||||
|
|
@ -210,14 +214,14 @@ def gen_translator(entries):
|
|||
return ""
|
||||
def get_fail_code(entry):
|
||||
if translator_nocontext_fail_codes.has_key(entry.func_name):
|
||||
return translator_nocontext_fail_codes[entry.func_name];
|
||||
return translator_nocontext_fail_codes[entry.func_name]
|
||||
else:
|
||||
return "0"
|
||||
def gen_cxt_getter(entry):
|
||||
if (entry.return_type == "void"):
|
||||
print " GET_CTX_V2();"
|
||||
print(" GET_CTX_V2();")
|
||||
else:
|
||||
print " GET_CTX_V2_RET(%s);" % get_fail_code(entry)
|
||||
print(" GET_CTX_V2_RET(%s);" % get_fail_code(entry))
|
||||
|
||||
def gen_validations_custom_impl(entry):
|
||||
isGen = entry.func_name.startswith("glGen")
|
||||
|
|
@ -231,14 +235,14 @@ def gen_translator(entries):
|
|||
if entry.return_type == "void":
|
||||
return "SET_ERROR_IF(%s,%s)" % (condition, glerr);
|
||||
else:
|
||||
return "RET_AND_SET_ERROR_IF(%s,%s,%s)" % (condition, glerr, get_fail_code(entry));
|
||||
return "RET_AND_SET_ERROR_IF(%s,%s,%s)" % (condition, glerr, get_fail_code(entry))
|
||||
|
||||
if (isGen or isDelete) and ("n" in entry.varnames):
|
||||
print " %s;" % mySetError("n < 0", "GL_INVALID_VALUE");
|
||||
print(" %s;" % mySetError("n < 0", "GL_INVALID_VALUE"))
|
||||
if (isBufferOp and hasTargetArg):
|
||||
print " %s;" % mySetError("!GLESv2Validate::bufferTarget(ctx, target)", "GL_INVALID_ENUM");
|
||||
print(" %s;" % mySetError("!GLESv2Validate::bufferTarget(ctx, target)", "GL_INVALID_ENUM"))
|
||||
if translator_custom_pre.has_key(entry.func_name):
|
||||
print translator_custom_pre[entry.func_name],
|
||||
print(translator_custom_pre[entry.func_name],)
|
||||
|
||||
def gen_call_ret(entry):
|
||||
globalNameTypes = {
|
||||
|
|
@ -262,53 +266,53 @@ def gen_translator(entries):
|
|||
needsShareGroup = True
|
||||
|
||||
if needsShareGroup:
|
||||
print " if (ctx->shareGroup().get()) {"
|
||||
print(" if (ctx->shareGroup().get()) {")
|
||||
for key in zip(entry.vartypes, entry.varnames):
|
||||
vartype, varname = key
|
||||
if globalNames.has_key(key):
|
||||
print " const GLuint %s = ctx->shareGroup()->getGlobalName(%s, %s);" % (globalNames[key], globalNameTypes[key], varname)
|
||||
print(" const GLuint %s = ctx->shareGroup()->getGlobalName(%s, %s);" % (globalNames[key], globalNameTypes[key], varname))
|
||||
|
||||
globalCall = ", ".join(map(lambda k: globalNames.get(k, k[1]), zip(entry.vartypes, entry.varnames)))
|
||||
|
||||
if needsShareGroup and translator_custom_share_processing.has_key(entry.func_name):
|
||||
print translator_custom_share_processing[entry.func_name],
|
||||
print(translator_custom_share_processing[entry.func_name])
|
||||
|
||||
if (entry.return_type == "void"):
|
||||
if (needsShareGroup):
|
||||
print " ",
|
||||
print(" "),
|
||||
|
||||
if not translator_no_passthrough.has_key(entry.func_name):
|
||||
print " ctx->dispatcher().%s(%s);" % (entry.func_name, globalCall)
|
||||
print(" ctx->dispatcher().%s(%s);" % (entry.func_name, globalCall))
|
||||
|
||||
if needsShareGroup:
|
||||
print " }"
|
||||
print(" }")
|
||||
if translator_custom_post.has_key(entry.func_name):
|
||||
print translator_custom_post[entry.func_name];
|
||||
print(translator_custom_post[entry.func_name])
|
||||
else:
|
||||
if (needsShareGroup):
|
||||
print " ",
|
||||
print(" "),
|
||||
if not translator_no_passthrough.has_key(entry.func_name):
|
||||
print " %s %s = ctx->dispatcher().%s(%s);" % (entry.return_type, entry.func_name + "RET", entry.func_name, globalCall)
|
||||
print(" %s %s = ctx->dispatcher().%s(%s);" % (entry.return_type, entry.func_name + "RET", entry.func_name, globalCall))
|
||||
else:
|
||||
print " %s %s = %s" % (entry.return_type, entry_func_name + "RET", get_fail_code(entry))
|
||||
print(") %s %s = %s" % (entry.return_type, entry_func_name + "RET", get_fail_code(entry)))
|
||||
|
||||
if translator_custom_post.has_key(entry.func_name):
|
||||
print translator_custom_post[entry.func_name];
|
||||
print(translator_custom_post[entry.func_name])
|
||||
|
||||
print " return %s;" % (entry.func_name + "RET");
|
||||
print(" return %s;" % (entry.func_name + "RET"))
|
||||
if needsShareGroup:
|
||||
print " } else return %s;" % (get_fail_code(entry))
|
||||
print(" } else return %s;" % (get_fail_code(entry)))
|
||||
|
||||
print "// Auto-generated with: %s" % banner_command(sys.argv)
|
||||
print "// This file is best left unedited."
|
||||
print "// Try to make changes through gen_translator in gen-entries.py,"
|
||||
print "// and/or parcel out custom functionality in separate code."
|
||||
print("// Auto-generated with: %s" % banner_command(sys.argv))
|
||||
print("// This file is best left unedited.")
|
||||
print("// Try to make changes through gen_translator in gen-entries.py,")
|
||||
print("// and/or parcel out custom functionality in separate code.")
|
||||
for entry in entries:
|
||||
print "%sGL_APICALL %s GL_APIENTRY %s(%s) {" % (needExternC(entry), entry.return_type, entry.func_name, entry.parameters)
|
||||
gen_cxt_getter(entry);
|
||||
gen_validations_custom_impl(entry);
|
||||
gen_call_ret(entry);
|
||||
print "}\n"
|
||||
print("%sGL_APICALL %s GL_APIENTRY %s(%s) {" % (needExternC(entry), entry.return_type, entry.func_name, entry.parameters))
|
||||
gen_cxt_getter(entry)
|
||||
gen_validations_custom_impl(entry)
|
||||
gen_call_ret(entry)
|
||||
print("}\n")
|
||||
|
||||
def gen_dll_wrapper(entries, prefix_name, verbatim, filename):
|
||||
"""Generate a C source file that contains functions that act as wrappers
|
||||
|
|
@ -322,77 +326,77 @@ def gen_dll_wrapper(entries, prefix_name, verbatim, filename):
|
|||
|
||||
ENTRY_PREFIX = "__dll_"
|
||||
|
||||
print "// Auto-generated with: %s" % banner_command(sys.argv)
|
||||
print "// DO NOT EDIT THIS FILE"
|
||||
print ""
|
||||
print "#include <dlfcn.h>"
|
||||
print("// Auto-generated with: %s" % banner_command(sys.argv))
|
||||
print("// DO NOT EDIT THIS FILE")
|
||||
print("")
|
||||
print("#include <dlfcn.h>")
|
||||
for line in verbatim:
|
||||
print line
|
||||
print(line)
|
||||
|
||||
print ""
|
||||
print "///"
|
||||
print "/// W R A P P E R P O I N T E R S"
|
||||
print "///"
|
||||
print ""
|
||||
print("")
|
||||
print("///")
|
||||
print("/// W R A P P E R P O I N T E R S")
|
||||
print("///")
|
||||
print("")
|
||||
for entry in entries:
|
||||
ptr_name = ENTRY_PREFIX + entry.func_name
|
||||
print "static %s (*%s)(%s) = 0;" % \
|
||||
(entry.return_type, ptr_name, entry.parameters)
|
||||
print("static %s (*%s)(%s) = 0;" % \
|
||||
(entry.return_type, ptr_name, entry.parameters))
|
||||
|
||||
print ""
|
||||
print "///"
|
||||
print "/// W R A P P E R F U N C T I O N S"
|
||||
print "///"
|
||||
print ""
|
||||
print("")
|
||||
print("///")
|
||||
print("/// W R A P P E R F U N C T I O N S")
|
||||
print("///")
|
||||
print("")
|
||||
|
||||
for entry in entries:
|
||||
print "%s %s(%s) {" % \
|
||||
(entry.return_type, entry.func_name, entry.parameters)
|
||||
print ("%s %s(%s) {" % \
|
||||
(entry.return_type, entry.func_name, entry.parameters))
|
||||
ptr_name = ENTRY_PREFIX + entry.func_name
|
||||
if entry.return_type != "void":
|
||||
print " return %s(%s);" % (ptr_name, entry.call)
|
||||
print(" return %s(%s);" % (ptr_name, entry.call))
|
||||
else:
|
||||
print " %s(%s);" % (ptr_name, entry.call)
|
||||
print "}\n"
|
||||
print(" %s(%s);" % (ptr_name, entry.call))
|
||||
print("}\n")
|
||||
|
||||
print ""
|
||||
print "///"
|
||||
print "/// I N I T I A L I Z A T I O N F U N C T I O N"
|
||||
print "///"
|
||||
print ""
|
||||
print("")
|
||||
print("///")
|
||||
print("/// I N I T I A L I Z A T I O N F U N C T I O N")
|
||||
print("///")
|
||||
print("")
|
||||
|
||||
print "int %s_dynlink_init(void* lib) {" % prefix_name
|
||||
print("int %s_dynlink_init(void* lib) {" % prefix_name)
|
||||
for entry in entries:
|
||||
ptr_name = ENTRY_PREFIX + entry.func_name
|
||||
print " %s = (%s(*)(%s))dlsym(lib, \"%s\");" % \
|
||||
print(" %s = (%s(*)(%s))dlsym(lib, \"%s\");" % \
|
||||
(ptr_name,
|
||||
entry.return_type,
|
||||
entry.parameters,
|
||||
entry.func_name)
|
||||
print " if (!%s) return -1;" % ptr_name
|
||||
print " return 0;"
|
||||
print "}"
|
||||
entry.func_name))
|
||||
print(" if (!%s) return -1;" % ptr_name)
|
||||
print(" return 0;")
|
||||
print("}")
|
||||
|
||||
|
||||
def gen_windows_def_file(entries):
|
||||
"""Generate a windows DLL .def file. |entries| is a list of Entry instances.
|
||||
"""
|
||||
print "EXPORTS"
|
||||
print("EXPORTS")
|
||||
for entry in entries:
|
||||
print " %s" % entry.func_name
|
||||
print(" %s" % entry.func_name)
|
||||
|
||||
|
||||
def gen_unix_sym_file(entries):
|
||||
"""Generate an ELF linker version file. |entries| is a list of Entry
|
||||
instances.
|
||||
"""
|
||||
print "VERSION {"
|
||||
print "\tglobal:"
|
||||
print("VERSION {")
|
||||
print("\tglobal:")
|
||||
for entry in entries:
|
||||
print "\t\t%s;" % entry.func_name
|
||||
print "\tlocal:"
|
||||
print "\t\t*;"
|
||||
print "};"
|
||||
print("\t\t%s;" % entry.func_name)
|
||||
print("\tlocal:")
|
||||
print("\t\t*;")
|
||||
print("};")
|
||||
|
||||
def gen_symbols(entries, underscore):
|
||||
"""Generate a list of symbols from |entries|, a list of Entry instances.
|
||||
|
|
@ -403,7 +407,7 @@ def gen_symbols(entries, underscore):
|
|||
if underscore:
|
||||
prefix = "_"
|
||||
for entry in entries:
|
||||
print "%s%s" % (prefix, entry.func_name)
|
||||
print("%s%s" % (prefix, entry.func_name))
|
||||
|
||||
def parse_file(filename, lines, mode):
|
||||
"""Generate one of possible outputs from |filename|. |lines| must be a list
|
||||
|
|
@ -413,7 +417,7 @@ def parse_file(filename, lines, mode):
|
|||
entries, prefix_name, verbatim, errors = parse_entries_file(lines)
|
||||
if errors:
|
||||
for error in errors:
|
||||
print >> sys.stderr, "ERROR: %s:%s" % (filename, error)
|
||||
eprint("ERROR: %s:%s" % (filename, error), file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
if not prefix_name:
|
||||
|
|
@ -466,7 +470,7 @@ parser.add_argument("file", help=".entries file path")
|
|||
args = parser.parse_args()
|
||||
|
||||
if not args.mode:
|
||||
print >> sys.stderr, "ERROR: Please use --mode=<name>, see --help."
|
||||
eprint("ERROR: Please use --mode=<name>, see --help.", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
if args.output:
|
||||
|
|
|
|||
|
|
@ -35,6 +35,11 @@ export LD_LIBRARY_PATH="$SNAP_LIBRARY_PATH:$LD_LIBRARY_PATH"
|
|||
# Ref.: https://bugs.launchpad.net/snappy/+bug/1588192
|
||||
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/var/lib/snapd/lib/gl
|
||||
|
||||
# With recent builds on Ubuntu 16.04 the snap does not find the path to
|
||||
# libpulsecommon-8.0.so anymore so we have to teach the linker manually
|
||||
# where it can be found
|
||||
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$SNAP/usr/lib/$ARCH/pulseaudio
|
||||
|
||||
# We set XDG_DATA_HOME to SNAP_USER_COMMON here as this will be the location we will
|
||||
# create all our application launchers in. The system application launcher will
|
||||
# be configured by our installer to look into this directory for available
|
||||
|
|
|
|||
|
|
@ -176,7 +176,7 @@ anbox::cmds::SessionManager::SessionManager()
|
|||
input_manager,
|
||||
display_frame,
|
||||
single_window_);
|
||||
if (!platform)
|
||||
if (!platform)
|
||||
return EXIT_FAILURE;
|
||||
|
||||
auto app_db = std::make_shared<application::Database>();
|
||||
|
|
|
|||
|
|
@ -24,6 +24,9 @@
|
|||
|
||||
namespace anbox {
|
||||
namespace container {
|
||||
|
||||
const std::chrono::milliseconds ManagementApiStub::stop_waiting_timeout{3000};
|
||||
|
||||
ManagementApiStub::ManagementApiStub(
|
||||
const std::shared_ptr<rpc::Channel> &channel)
|
||||
: channel_(channel) {}
|
||||
|
|
@ -75,7 +78,9 @@ void ManagementApiStub::stop_container() {
|
|||
channel_->call_method("stop_container", &message, c->response.get(),
|
||||
google::protobuf::NewCallback(this, &ManagementApiStub::container_stopped, c.get()));
|
||||
|
||||
c->wh.wait_for_all();
|
||||
// If container manager dies before session manager, the session manager
|
||||
// cannot exit if it waits for all, so just wait for 3 seconds.
|
||||
c->wh.wait_for_pending(stop_waiting_timeout);
|
||||
|
||||
if (c->response->has_error()) throw std::runtime_error(c->response->error());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ class ManagementApiStub : public DoNotCopyOrMove {
|
|||
|
||||
mutable std::mutex mutex_;
|
||||
std::shared_ptr<rpc::Channel> channel_;
|
||||
static const std::chrono::milliseconds stop_waiting_timeout;
|
||||
};
|
||||
} // namespace container
|
||||
} // namespace anbox
|
||||
|
|
|
|||
|
|
@ -26,9 +26,9 @@
|
|||
#include "external/android-emugl/shared/OpenglCodecCommon/ChecksumCalculatorThreadInfo.h"
|
||||
#include "external/android-emugl/host/include/OpenGLESDispatch/EGLDispatch.h"
|
||||
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
static const GLint rendererVersion = 1;
|
||||
static std::shared_ptr<anbox::graphics::LayerComposer> composer;
|
||||
|
|
@ -55,53 +55,61 @@ static EGLint rcGetEGLVersion(EGLint *major, EGLint *minor) {
|
|||
return EGL_TRUE;
|
||||
}
|
||||
|
||||
static EGLint rcQueryEGLString(EGLenum name, void *buffer, EGLint bufferSize) {
|
||||
static std::string filter_extensions(const std::string& extensions, const std::vector<std::string>& whitelist) {
|
||||
std::stringstream approved_extensions;
|
||||
auto extension_list = anbox::utils::string_split(extensions, ' ');
|
||||
for (const auto& ext : extension_list) {
|
||||
if (std::find(whitelist.begin(), whitelist.end(), ext) == whitelist.end())
|
||||
continue;
|
||||
|
||||
if (approved_extensions.tellp() > 0)
|
||||
approved_extensions << " ";
|
||||
|
||||
approved_extensions << ext;
|
||||
}
|
||||
return approved_extensions.str();
|
||||
}
|
||||
|
||||
static EGLint rcQueryEGLString(EGLenum name, void* buffer, EGLint bufferSize) {
|
||||
if (!renderer)
|
||||
return 0;
|
||||
|
||||
auto result = s_egl.eglQueryString(renderer->getDisplay(), name);
|
||||
if (!result)
|
||||
std::string result = s_egl.eglQueryString(renderer->getDisplay(), name);
|
||||
if (result.empty())
|
||||
return 0;
|
||||
|
||||
std::string approved_result = result;
|
||||
|
||||
// We need to drop a few extensions from the list reported by the driver
|
||||
// as not all are well enough support by our EGL/GLES stack.
|
||||
if (name == EGL_EXTENSIONS) {
|
||||
std::vector<std::string> common_unsupported_extensions = {
|
||||
// Leads to crashes on the Android side when SurfaceFlinger initializes
|
||||
// EGL/GLES and it queries surfaces for available attributes.
|
||||
"EGL_EXT_buffer_age"
|
||||
// We need to drop a few extensions from the list reported by the driver
|
||||
// as not all are well enough support by our EGL implementation.
|
||||
std::vector<std::string> whitelisted_extensions = {
|
||||
"EGL_KHR_image_base",
|
||||
"EGL_KHR_gl_texture_2D_image",
|
||||
};
|
||||
|
||||
for (const auto &extension : common_unsupported_extensions) {
|
||||
size_t start_pos = approved_result.find(extension);
|
||||
if (start_pos == std::string::npos) continue;
|
||||
approved_result.replace(start_pos, extension.length(), "");
|
||||
}
|
||||
result = filter_extensions(result, whitelisted_extensions);
|
||||
}
|
||||
|
||||
int len = approved_result.length() + 1;
|
||||
int len = result.length() + 1;
|
||||
if (!buffer || len > bufferSize) {
|
||||
return -len;
|
||||
}
|
||||
|
||||
strcpy(static_cast<char *>(buffer), approved_result.c_str());
|
||||
strcpy(static_cast<char*>(buffer), result.c_str());
|
||||
return len;
|
||||
}
|
||||
|
||||
static EGLint rcGetGLString(EGLenum name, void *buffer, EGLint bufferSize) {
|
||||
RenderThreadInfo *tInfo = RenderThreadInfo::get();
|
||||
static EGLint rcGetGLString(EGLenum name, void* buffer, EGLint bufferSize) {
|
||||
RenderThreadInfo* tInfo = RenderThreadInfo::get();
|
||||
std::string result;
|
||||
|
||||
if (tInfo && tInfo->currContext) {
|
||||
const char *str = nullptr;
|
||||
const char* str = nullptr;
|
||||
if (tInfo->currContext->isGL2())
|
||||
str = reinterpret_cast<const char *>(s_gles2.glGetString(name));
|
||||
str = reinterpret_cast<const char*>(s_gles2.glGetString(name));
|
||||
else
|
||||
str = reinterpret_cast<const char *>(s_gles1.glGetString(name));
|
||||
str = reinterpret_cast<const char*>(s_gles1.glGetString(name));
|
||||
|
||||
if (str) result += str;
|
||||
if (str)
|
||||
result += str;
|
||||
}
|
||||
|
||||
// We're forcing version 2.0 no matter what the host provides as
|
||||
|
|
@ -113,27 +121,37 @@ static EGLint rcGetGLString(EGLenum name, void *buffer, EGLint bufferSize) {
|
|||
if (name == GL_VERSION)
|
||||
result = "OpenGL ES 2.0";
|
||||
else if (name == GL_EXTENSIONS) {
|
||||
std::string approved_extensions = result;
|
||||
std::vector<std::string> unsupported_extensions = {
|
||||
// Leaving this enabled gives crippeled text rendering when
|
||||
// using the host mesa GLES drivers.
|
||||
"GL_EXT_unpack_subimage",
|
||||
// We need to drop a few extensions from the list reported by the driver
|
||||
// as not all are well enough support by our GL implementation.
|
||||
std::vector<std::string> whitelisted_extensions = {
|
||||
"GL_OES_EGL_image",
|
||||
"GL_OES_EGL_image_external",
|
||||
"GL_OES_depth24",
|
||||
"GL_OES_depth32",
|
||||
"GL_OES_element_index_uint",
|
||||
"GL_OES_texture_float",
|
||||
"GL_OES_texture_float_linear",
|
||||
"GL_OES_compressed_paletted_texture",
|
||||
"GL_OES_compressed_ETC1_RGB8_texture",
|
||||
"GL_OES_depth_texture",
|
||||
"GL_OES_texture_half_float",
|
||||
"GL_OES_texture_half_float_linear",
|
||||
"GL_OES_packed_depth_stencil",
|
||||
"GL_OES_vertex_half_float",
|
||||
"GL_OES_standard_derivatives",
|
||||
"GL_OES_texture_npot",
|
||||
"GL_OES_rgb8_rgba8",
|
||||
};
|
||||
|
||||
for (const auto &extension : unsupported_extensions) {
|
||||
size_t start_pos = approved_extensions.find(extension);
|
||||
if (start_pos == std::string::npos) continue;
|
||||
approved_extensions.replace(start_pos, extension.length(), "");
|
||||
}
|
||||
|
||||
result = approved_extensions;
|
||||
result = filter_extensions(result, whitelisted_extensions);
|
||||
}
|
||||
|
||||
int nextBufferSize = result.size() + 1;
|
||||
|
||||
if (!buffer || nextBufferSize > bufferSize) return -nextBufferSize;
|
||||
if (!buffer || nextBufferSize > bufferSize)
|
||||
return -nextBufferSize;
|
||||
|
||||
snprintf(static_cast<char *>(buffer), nextBufferSize, "%s", result.c_str());
|
||||
snprintf(static_cast<char*>(buffer), nextBufferSize, "%s", result.c_str());
|
||||
return nextBufferSize;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -84,8 +84,12 @@ intptr_t RenderThread::main() {
|
|||
}
|
||||
|
||||
} while (progress);
|
||||
|
||||
}
|
||||
|
||||
threadInfo.m_gl2Dec.freeShader();
|
||||
threadInfo.m_gl2Dec.freeProgram();
|
||||
|
||||
// Release references to the current thread's context/surfaces if any
|
||||
renderer_->bindContext(0, 0, 0);
|
||||
if (threadInfo.currContext || threadInfo.currDrawSurf || threadInfo.currReadSurf)
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#define GLM_ENABLE_EXPERIMENTAL
|
||||
#include "anbox/graphics/emugl/Renderer.h"
|
||||
#include "anbox/graphics/emugl/DispatchTables.h"
|
||||
#include "anbox/graphics/emugl/RenderThreadInfo.h"
|
||||
|
|
|
|||
|
|
@ -138,7 +138,7 @@ unsigned short BaseSocketMessenger<stream_protocol>::local_port() const {
|
|||
|
||||
template <typename stream_protocol>
|
||||
void BaseSocketMessenger<stream_protocol>::set_no_delay() {
|
||||
const auto fd = socket->native();
|
||||
const auto fd = socket->native_handle();
|
||||
int flag = 1;
|
||||
const auto ret =
|
||||
::setsockopt(fd, IPPROTO_TCP, TCP_NODELAY,
|
||||
|
|
|
|||
|
|
@ -51,7 +51,6 @@ void QemudMessageProcessor::process_commands() {
|
|||
|
||||
unsigned int body_size = 0;
|
||||
::sscanf(header, "%04x", &body_size);
|
||||
if (body_size != buffer_.size() - header_size) break;
|
||||
|
||||
std::string command;
|
||||
// Make sure we only copy as much bytes as we have to and not more
|
||||
|
|
@ -71,7 +70,7 @@ void QemudMessageProcessor::process_commands() {
|
|||
|
||||
void QemudMessageProcessor::send_header(const size_t &size) {
|
||||
char header[header_size + 1];
|
||||
std::snprintf(header, header_size + 1, "%04lx", size);
|
||||
std::snprintf(header, header_size + 1, "%04zx", size);
|
||||
messenger_->send(header, header_size);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -53,7 +53,13 @@ std::shared_ptr<Runtime> Runtime::create(std::uint32_t pool_size) {
|
|||
|
||||
Runtime::Runtime(std::uint32_t pool_size)
|
||||
: pool_size_{pool_size},
|
||||
|
||||
#if BOOST_VERSION >= 106600
|
||||
service_{static_cast<int>(pool_size_)},
|
||||
#else
|
||||
service_{pool_size_},
|
||||
#endif
|
||||
|
||||
strand_{service_},
|
||||
keep_alive_{service_} {}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
#define ANBOX_RUNTIME_H_
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/version.hpp>
|
||||
|
||||
#include <memory.h>
|
||||
#include <functional>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue