Bare bones port of demos project to android

This commit is contained in:
baldurk
2023-03-23 16:04:19 +00:00
parent 28f4af1e5c
commit 448b78ca68
18 changed files with 893 additions and 11 deletions
+245 -7
View File
@@ -6,6 +6,77 @@ if(APPLE)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}")
endif()
# Configure some stuff that needs to be set really early
if(BUILD_ANDROID)
if(NOT DEFINED ENV{JAVA_HOME})
message(FATAL_ERROR "JAVA_HOME environment variable must be defined for Android build")
endif()
message(STATUS "Using JAVA_HOME = $ENV{JAVA_HOME}")
execute_process(COMMAND $ENV{JAVA_HOME}/bin/java -version
RESULT_VARIABLE _result
OUTPUT_VARIABLE _output
ERROR_VARIABLE _output
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_STRIP_TRAILING_WHITESPACE)
if(NOT _result AND _output MATCHES "version \"([0-9]+).([0-9]+)")
message(STATUS "Java in JAVA_HOME is ${CMAKE_MATCH_1}.${CMAKE_MATCH_2}")
else()
message(STATUS "Java in JAVA_HOME is unknown version ${_output} ${_result}")
endif()
if(DEFINED ENV{ANDROID_HOME} AND EXISTS "$ENV{ANDROID_HOME}/build-tools")
set(ANDROID_SDK_ROOT_PATH "$ENV{ANDROID_HOME}")
elseif(DEFINED ENV{ANDROID_SDK_ROOT} AND EXISTS "$ENV{ANDROID_SDK_ROOT}/build-tools")
set(ANDROID_SDK_ROOT_PATH "$ENV{ANDROID_SDK_ROOT}")
elseif(DEFINED ENV{ANDROID_SDK} AND EXISTS "$ENV{ANDROID_SDK}/build-tools")
set(ANDROID_SDK_ROOT_PATH "$ENV{ANDROID_SDK}")
else()
message(FATAL_ERROR "Can't locate Android SDK, set ANDROID_HOME, ANDROID_SDK_ROOT or ANDROID_SDK")
endif()
message(STATUS "Using Android SDK found in ${ANDROID_SDK_ROOT_PATH}")
if(DEFINED ENV{ANDROID_NDK_HOME} AND EXISTS "$ENV{ANDROID_NDK_HOME}/build/cmake/android.toolchain.cmake")
set(ANDROID_NDK_ROOT_PATH "$ENV{ANDROID_NDK_HOME}")
elseif(DEFINED ENV{ANDROID_NDK_ROOT} AND EXISTS "$ENV{ANDROID_NDK_ROOT}/build/cmake/android.toolchain.cmake")
set(ANDROID_NDK_ROOT_PATH "$ENV{ANDROID_NDK_ROOT}")
elseif(DEFINED ENV{NDK_HOME} AND EXISTS "$ENV{NDK_HOME}/build/cmake/android.toolchain.cmake")
set(ANDROID_NDK_ROOT_PATH "$ENV{NDK_HOME}")
elseif(DEFINED ENV{ANDROID_NDK} AND EXISTS "$ENV{ANDROID_NDK}/build/cmake/android.toolchain.cmake")
set(ANDROID_NDK_ROOT_PATH "$ENV{ANDROID_NDK}")
else()
message(FATAL_ERROR "Can't locate Android NDK, set ANDROID_NDK_HOME, ANDROID_NDK_ROOT, NDK_HOME or ANDROID_NDK")
endif()
message(STATUS "Using Android NDK found in ${ANDROID_NDK_ROOT_PATH}")
set(CMAKE_TOOLCHAIN_FILE
"${ANDROID_NDK_ROOT_PATH}/build/cmake/android.toolchain.cmake"
CACHE STRING
"The Android toolchain file")
# Set default API level to 21 if not configured explicitly
if(NOT ANDROID_PLATFORM)
set(ANDROID_PLATFORM "android-21")
endif()
# default to libc++_static as the other options can cause crashes
if(NOT ANDROID_STL)
set(ANDROID_STL "c++_static")
endif()
# Choose clang if the NDK has both gcc and clang, since gcc sometimes fails
set(CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION "clang")
# Default to arm64 if nothing is specified on the command line.
# Options are {armeabi-v7a,arm64-v8a}
set(ANDROID_ABI "arm64-v8a" CACHE STRING "The Android ABI to build for")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DANDROID=1")
endif()
set(PROJECT demos)
set(VULKAN_SRC
@@ -131,7 +202,7 @@ project(demos)
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
list(APPEND warning_flags -Werror)
list(APPEND warning_flags -Werror -Wno-unused-result)
string(REPLACE ";" " " warning_flags "${warning_flags}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${warning_flags}")
endif()
@@ -148,6 +219,20 @@ if(APPLE)
apple/apple_window.h)
add_executable(demos ${SRC} ${VULKAN_SRC})
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17")
elseif(BUILD_ANDROID)
string(REPLACE "\\" "/" GLUE_SOURCE "${ANDROID_NDK_ROOT_PATH}/sources/android/native_app_glue/android_native_app_glue.c")
include_directories(${ANDROID_NDK_ROOT_PATH}/sources/android/native_app_glue)
list(APPEND OPENGL_SRC
3rdparty/glad/glad_egl.c
gl/gl_test_android.cpp)
list(APPEND SRC
android/android_platform.cpp
android/android_platform.h
android/android_window.cpp
android/android_window.h
${GLUE_SOURCE})
add_library(demos SHARED ${SRC} ${VULKAN_SRC} ${OPENGL_SRC})
elseif(UNIX)
list(APPEND OPENGL_SRC
3rdparty/glad/glad_glx.c
@@ -162,12 +247,20 @@ endif()
install(TARGETS demos DESTINATION .)
if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
set(SHADERC_DIR "linux64")
set(BIN_SUFFIX "x64")
if(BUILD_ANDROID)
set(SHADERC_DIR "dummy")
set(BIN_SUFFIX "")
target_link_libraries(demos PRIVATE ${ANDROID_NDK_ROOT_PATH}/sources/third_party/shaderc/obj/local/${ANDROID_ABI}/libshaderc_combined.a)
target_compile_definitions(demos PRIVATE -DHAVE_SHADERC=1)
target_include_directories(demos PRIVATE ${ANDROID_NDK_ROOT_PATH}/sources/third_party/shaderc/include)
else()
set(SHADERC_DIR "linux32")
set(BIN_SUFFIX "x86")
if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
set(SHADERC_DIR "linux64")
set(BIN_SUFFIX "_x64")
else()
set(SHADERC_DIR "linux32")
set(BIN_SUFFIX "_x86")
endif()
endif()
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/shaderc/${SHADERC_DIR})
@@ -192,11 +285,156 @@ if(APPLE)
target_compile_definitions(demos PRIVATE
-DVK_USE_PLATFORM_MACOS_MVK=1)
set(LIBS ${COCOA_LIBRARY} ${QUARTZCORE_LIBRARY} ${METAL_LIBRARY})
elseif(BUILD_ANDROID)
target_compile_definitions(demos PRIVATE -DVK_USE_PLATFORM_ANDROID_KHR=1)
list(APPEND LIBS PRIVATE -llog -landroid -lEGL)
elseif(UNIX)
target_compile_definitions(demos PRIVATE -DVK_USE_PLATFORM_XCB_KHR=1)
set(LIBS -lX11 -lxcb -lX11-xcb)
endif()
target_link_libraries(demos PRIVATE ${LIBS} ${CMAKE_THREAD_LIBS_INIT} ${CMAKE_DL_LIBS})
set_target_properties(demos PROPERTIES OUTPUT_NAME demos_${BIN_SUFFIX})
set_target_properties(demos PROPERTIES OUTPUT_NAME demos${BIN_SUFFIX})
if(ANDROID)
# Android sets this to off becuase Android is always terrible forever.
# It breaks finding java in the path, so enable it again
set(CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH ON)
#############################
# We need to check that 'java' in PATH is new enough. Temporarily unset the JAVA_HOME env,
# then invoke FindJava.cmake which will search just the PATH, then re-set it.
set(SAVE_JAVA_HOME $ENV{JAVA_HOME})
set(ENV{JAVA_HOME} "")
find_package(Java)
set(ENV{JAVA_HOME} ${SAVE_JAVA_HOME})
if(NOT ${Java_FOUND})
message(FATAL_ERROR "Building Android requires the 'java' program in your PATH. It must be at least Java 8 (1.8)")
endif()
if(${Java_VERSION} VERSION_LESS 1.8)
message(FATAL_ERROR "Building Android requires the 'java' program in your PATH to be at least Java 8 (1.8)")
endif()
message(STATUS "Using Java of version ${Java_VERSION}")
set(ANDROID_BUILD_TOOLS_VERSION "" CACHE STRING "Version of Android build-tools to use instead of the default")
if(ANDROID_BUILD_TOOLS_VERSION STREQUAL "")
# Enumerate the build tools versions available, and pick the most recent
file(GLOB __buildTools RELATIVE "${ANDROID_SDK_ROOT_PATH}/build-tools" "${ANDROID_SDK_ROOT_PATH}/build-tools/*")
list(SORT __buildTools)
list(GET __buildTools -1 ANDROID_BUILD_TOOLS_VERSION)
unset(__buildTools)
endif()
message(STATUS "Using Android build-tools version ${ANDROID_BUILD_TOOLS_VERSION}")
set(APK_TARGET_ID "" CACHE STRING "The Target ID to build the APK for like 'android-99', use <android list targets> to choose another one.")
if(APK_TARGET_ID STREQUAL "")
# This seems different from the platform we're targetting,
# default to the latest available that's greater or equal to our target platform
file(GLOB __platforms RELATIVE "${ANDROID_SDK_ROOT_PATH}/platforms" "${ANDROID_SDK_ROOT_PATH}/platforms/*")
list(SORT __platforms)
# In case we don't find one, target the latest platform
list(GET __platforms -1 APK_TARGET_ID)
string(REPLACE "android-" "" __targetPlat "${ANDROID_PLATFORM}")
# We require at least android 23 for Activity.requestPermissions
if(__targetPlat LESS 23)
set(__targetPlat 23)
endif()
foreach( __plat ${__platforms})
string(REPLACE "android-" "" __curPlat "${__plat}")
if(NOT (__curPlat LESS __targetPlat) )
set(APK_TARGET_ID "android-${__curPlat}")
break()
endif()
endforeach()
unset(__platforms)
unset(__targetPlat)
unset(__curPlat)
endif()
message(STATUS "Using android.jar from platform ${APK_TARGET_ID}")
# Suffix for scripts rather than binaries, which is needed explicitly on windows
set(TOOL_SCRIPT_EXTENSION "")
if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
set(TOOL_SCRIPT_EXTENSION ".bat")
endif()
set(BUILD_TOOLS "${ANDROID_SDK_ROOT_PATH}/build-tools/${ANDROID_BUILD_TOOLS_VERSION}")
set(RT_JAR "$ENV{JAVA_HOME}/jre/lib/rt.jar")
set(JAVA_BIN "$ENV{JAVA_HOME}/bin")
string(REPLACE "\\" "/" ANDROID_JAR "${ANDROID_SDK_ROOT_PATH}/platforms/${APK_TARGET_ID}/android.jar")
if(CMAKE_HOST_WIN32)
set(CLASS_PATH "${ANDROID_JAR}\;obj")
else()
set(CLASS_PATH "${ANDROID_JAR}:obj")
endif()
set(KEYSTORE ${CMAKE_CURRENT_BINARY_DIR}/debug.keystore)
add_custom_command(OUTPUT ${KEYSTORE}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMAND ${JAVA_BIN}/keytool -genkey -keystore ${KEYSTORE} -storepass android -alias rdocandroidkey -keypass android -keyalg RSA -keysize 2048 -validity 10000 -dname "CN=, OU=, O=, L=, S=, C=")
set(APK_VERSION_CODE "10")
set(APK_VERSION_NAME "demos_build")
# Set the package name based on the ABI
if(ANDROID_ABI STREQUAL "armeabi-v7a")
set(ABI_EXTENSION_NAME "arm32")
elseif(ANDROID_ABI STREQUAL "arm64-v8a")
set(ABI_EXTENSION_NAME "arm64")
elseif(ANDROID_ABI STREQUAL "x86")
set(ABI_EXTENSION_NAME "x86")
elseif(ANDROID_ABI STREQUAL "x86_64")
set(ABI_EXTENSION_NAME "x64")
else()
message(FATAL_ERROR "ABI ${ANDROID_ABI} is not supported.")
endif()
set(RENDERDOC_ANDROID_PACKAGE_NAME "org.renderdoc.demos.${ABI_EXTENSION_NAME}")
set(APK_FILE ${CMAKE_BINARY_DIR}/bin/${RENDERDOC_ANDROID_PACKAGE_NAME}.apk)
add_custom_target(apk ALL
DEPENDS ${APK_FILE})
# Copy in android package files, replacing the package name with the architecture-specific package name
configure_file(android/Loader.java ${CMAKE_CURRENT_BINARY_DIR}/src/org/renderdoc/demos/Loader.java)
configure_file(android/AndroidManifest.xml ${CMAKE_CURRENT_BINARY_DIR}/AndroidManifest.xml)
configure_file(android/icon.png ${CMAKE_CURRENT_BINARY_DIR}/res/drawable/icon.png COPYONLY)
add_custom_command(OUTPUT ${APK_FILE}
DEPENDS demos
DEPENDS ${KEYSTORE}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMAND ${CMAKE_COMMAND} -E make_directory libs/lib/${ANDROID_ABI}
COMMAND ${CMAKE_COMMAND} -E make_directory obj
COMMAND ${CMAKE_COMMAND} -E make_directory bin
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:demos> libs/lib/${ANDROID_ABI}/$<TARGET_FILE_NAME:demos>
)
set(D8_SCRIPT "${BUILD_TOOLS}/d8${TOOL_SCRIPT_EXTENSION}")
if(NOT EXISTS ${D8_SCRIPT})
set(DEX_COMMAND ${BUILD_TOOLS}/dx${TOOL_SCRIPT_EXTENSION} --dex --output=bin/classes.dex ./obj)
else()
set(DEX_COMMAND ${D8_SCRIPT} --output ./bin/ ./obj/org/renderdoc/demos/${ABI_EXTENSION_NAME}/*.class)
endif()
add_custom_command(OUTPUT ${APK_FILE} APPEND
COMMAND ${BUILD_TOOLS}/aapt package -f -m -S res -J src -M AndroidManifest.xml -I ${ANDROID_JAR}
COMMAND ${JAVA_BIN}/javac -d ./obj -source 1.7 -target 1.7 -bootclasspath ${RT_JAR} -classpath "${CLASS_PATH}" -sourcepath src src/org/renderdoc/demos/*.java
COMMAND ${DEX_COMMAND}
COMMAND ${BUILD_TOOLS}/aapt package -f -M AndroidManifest.xml --version-code ${APK_VERSION_CODE} --version-name ${APK_VERSION_NAME} -S res -I ${ANDROID_JAR} -F demos-unaligned.apk bin libs
COMMAND ${BUILD_TOOLS}/zipalign -f 4 demos-unaligned.apk demos.apk
COMMAND ${BUILD_TOOLS}/apksigner${TOOL_SCRIPT_EXTENSION} sign --ks ${KEYSTORE} --ks-pass pass:android --key-pass pass:android --ks-key-alias rdocandroidkey demos.apk
COMMAND ${CMAKE_COMMAND} -E copy demos.apk ${APK_FILE})
endif()
@@ -0,0 +1,19 @@
<?xml version="1.0"?>
<!-- BEGIN_INCLUDE(manifest) -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="@RENDERDOC_ANDROID_PACKAGE_NAME@">
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="26"/>
<uses-permission android:name="android.permission.INTERNET" />
<!-- Use GL ES 3.2 version -->
<uses-feature android:glEsVersion="0x00030000" android:required="true" />
<application android:debuggable="true" android:label="demos" android:icon="@drawable/icon" android:hasCode="true">
<activity android:name=".Loader" android:label="RenderDoc" android:exported="true" android:screenOrientation="landscape" android:configChanges="orientation|keyboardHidden">
<meta-data android:name="android.app.lib_name" android:value="demos"/>
</activity>
</application>
</manifest>
<!-- END_INCLUDE(manifest) -->
+20
View File
@@ -0,0 +1,20 @@
package @RENDERDOC_ANDROID_PACKAGE_NAME@;
import android.os.Build;
import android.app.Activity;
import android.view.WindowManager;
import android.os.Environment;
import android.content.Intent;
public class Loader extends android.app.NativeActivity
{
/* load our native library */
static {
System.loadLibrary("demos");
}
@Override
protected void onCreate(android.os.Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
}
@@ -0,0 +1,78 @@
/******************************************************************************
* The MIT License (MIT)
*
* Copyright (c) 2019-2023 Baldur Karlsson
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
******************************************************************************/
#include <stdlib.h>
#include <unistd.h>
#include "test_common.h"
uint64_t GetMemoryUsage()
{
FILE *f = fopen("/proc/self/statm", "r");
if(f == NULL)
{
TEST_WARN("Couldn't open /proc/self/statm");
return 0;
}
char line[512] = {};
fgets(line, 511, f);
fclose(f);
uint32_t rssPages = 0;
int num = sscanf(line, "%*u %u", &rssPages);
if(num == 1 && rssPages > 0)
return rssPages * (uint64_t)sysconf(_SC_PAGESIZE);
return 0;
}
std::string GetCWD()
{
char cwd[MAX_PATH + 1] = {0};
getcwd(cwd, MAX_PATH);
std::string cwdstr = cwd;
for(size_t i = 0; i < cwdstr.size(); i++)
if(cwdstr[i] == '\\')
cwdstr[i] = '/';
while(cwdstr.back() == '/' || cwdstr.back() == '\\')
cwdstr.pop_back();
return cwdstr;
}
std::string GetEnvVar(const char *var)
{
return "";
}
std::string GetExecutableName()
{
return "__undefined__";
}
@@ -0,0 +1,44 @@
/******************************************************************************
* The MIT License (MIT)
*
* Copyright (c) 2019-2023 Baldur Karlsson
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
******************************************************************************/
#pragma once
#include <dlfcn.h>
#include <signal.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <string>
#define DEBUG_BREAK() raise(SIGTRAP)
#define MAX_PATH 256
#define msleep(time) usleep((time)*1000)
#define EXECUTABLE_SUFFIX ""
#define MakeDir(dir) mkdir(dir, 0755)
std::string GetExecutableName();
@@ -0,0 +1,48 @@
/******************************************************************************
* The MIT License (MIT)
*
* Copyright (c) 2019-2023 Baldur Karlsson
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
******************************************************************************/
#include "android_window.h"
#include <android_native_app_glue.h>
extern struct android_app *android_state;
AndroidWindow::AndroidWindow(int width, int height, const char *title) : GraphicsWindow(title)
{
window = android_state->window;
TEST_LOG("android window %p", window);
}
AndroidWindow::~AndroidWindow()
{
}
void AndroidWindow::Resize(int width, int height)
{
}
bool AndroidWindow::Update()
{
return true;
}
+41
View File
@@ -0,0 +1,41 @@
/******************************************************************************
* The MIT License (MIT)
*
* Copyright (c) 2019-2023 Baldur Karlsson
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
******************************************************************************/
#pragma once
#include "../test_common.h"
struct ANativeWindow;
typedef void *EGLSurface;
struct AndroidWindow : public GraphicsWindow
{
AndroidWindow(int width, int height, const char *title);
~AndroidWindow();
void Resize(int width, int height);
bool Update();
ANativeWindow *window;
EGLSurface surface;
};
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

+8
View File
@@ -0,0 +1,8 @@
#!/system/bin/sh
export renderdoc__replay__marker=1
# chain to asan's wrap if needed, now that we exported the env var
if [ -f asan.sh ]; then
./asan.sh "$@"
else
exec "$@"
fi
+15
View File
@@ -121,6 +121,12 @@
<ItemGroup>
<ClCompile Include="3rdparty\fmt\format.cc" />
<ClCompile Include="3rdparty\md5\md5.c" />
<ClCompile Include="android\android_platform.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="android\android_window.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="d3d11\d3d11_1_many_uavs.cpp" />
<ClCompile Include="d3d11\d3d11_amd_shader_extensions.cpp" />
<ClCompile Include="d3d11\d3d11_array_interpolator.cpp" />
@@ -267,6 +273,9 @@
<ClCompile Include="gl\gl_test_linux.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="gl\gl_test_android.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="gl\gl_test_win32.cpp" />
<ClCompile Include="gl\gl_texture_zoo.cpp" />
<ClCompile Include="gl\gl_unshared_context.cpp" />
@@ -358,6 +367,12 @@
<ClInclude Include="3rdparty\glad\khrplatform.h" />
<ClInclude Include="3rdparty\md5\md5.h" />
<ClInclude Include="3rdparty\VulkanMemoryAllocator\vk_mem_alloc.h" />
<ClInclude Include="android\android_platform.h">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClInclude>
<ClInclude Include="android\android_window.h">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClInclude>
<ClInclude Include="d3d11\d3d11_helpers.h" />
<ClInclude Include="d3d11\d3d11_test.h" />
<ClInclude Include="d3d12\d3d12_helpers.h" />
+18
View File
@@ -649,6 +649,15 @@
<ClCompile Include="d3d12\d3d12_map_placed_alias.cpp">
<Filter>D3D12\demos</Filter>
</ClCompile>
<ClCompile Include="android\android_platform.cpp">
<Filter>Android</Filter>
</ClCompile>
<ClCompile Include="android\android_window.cpp">
<Filter>Android</Filter>
</ClCompile>
<ClCompile Include="gl\gl_test_android.cpp">
<Filter>OpenGL</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Filter Include="D3D11">
@@ -720,6 +729,9 @@
<Filter Include="3rdparty\md5">
<UniqueIdentifier>{25327220-a428-4ea2-8894-300df4a61a33}</UniqueIdentifier>
</Filter>
<Filter Include="Android">
<UniqueIdentifier>{cd8bc334-25e7-40a0-99fb-fff5ccf33687}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="d3d11\d3d11_helpers.h">
@@ -913,5 +925,11 @@
<ClInclude Include="3rdparty\md5\md5.h">
<Filter>3rdparty\md5</Filter>
</ClInclude>
<ClInclude Include="android\android_platform.h">
<Filter>Android</Filter>
</ClInclude>
<ClInclude Include="android\android_window.h">
<Filter>Android</Filter>
</ClInclude>
</ItemGroup>
</Project>
+13 -3
View File
@@ -25,9 +25,19 @@
#include "gl_test.h"
#include <stdio.h>
static std::string common = R"EOSHADER(
#if defined(ANDROID)
static std::string version = "#version 320 es";
#else
static std::string version = "#version 410 core";
#endif
#version 410 core
static std::string common = version + R"EOSHADER(
#if defined(GL_ES)
precision highp float;
precision highp int;
#endif
#define v2f v2f_block \
{ \
@@ -60,7 +70,7 @@ std::string GLDefaultPixel = common + R"EOSHADER(
in v2f vertIn;
layout(location = 0, index = 0) out vec4 Color;
layout(location = 0) out vec4 Color;
void main()
{
+172
View File
@@ -0,0 +1,172 @@
/******************************************************************************
* The MIT License (MIT)
*
* Copyright (c) 2019-2023 Baldur Karlsson
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
******************************************************************************/
#include "gl_test.h"
#include <dlfcn.h>
#include <stdio.h>
#include "3rdparty/glad/glad_egl.h"
#include "../android/android_window.h"
EGLDisplay eglDisplay;
EGLConfig config;
void OpenGLGraphicsTest::Prepare(int argc, char **argv)
{
GraphicsTest::Prepare(argc, argv);
static bool prepared = false;
static void *libEGL = NULL;
if(!prepared)
{
prepared = true;
libEGL = dlopen("libEGL.so", RTLD_GLOBAL | RTLD_NOW);
}
if(!libEGL)
Avail = "libEGL.so is not available";
}
bool OpenGLGraphicsTest::Init()
{
if(!GraphicsTest::Init())
return false;
gladLoadEGL();
eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
TEST_LOG("android display %p %d", eglDisplay, eglGetError());
int major = 0, minor = 0;
EGLBoolean initialised = eglInitialize(eglDisplay, &major, &minor);
TEST_LOG("android init %d %d => %d", major, minor, initialised);
const EGLint configAttribs[] = {EGL_RED_SIZE,
8,
EGL_GREEN_SIZE,
8,
EGL_BLUE_SIZE,
8,
EGL_SURFACE_TYPE,
EGL_WINDOW_BIT,
EGL_COLOR_BUFFER_TYPE,
EGL_RGB_BUFFER,
EGL_RENDERABLE_TYPE,
EGL_OPENGL_ES2_BIT,
EGL_NONE};
EGLint numConfigs;
eglChooseConfig(eglDisplay, configAttribs, &config, 1, &numConfigs);
TEST_LOG("android config %p %d (%d)", config, eglGetError(), numConfigs);
mainWindow = new AndroidWindow(screenWidth, screenHeight, screenTitle);
mainContext = MakeContext(mainWindow, NULL);
if(!mainWindow || !mainContext)
{
delete mainWindow;
TEST_ERROR("Couldn't initialise context");
return false;
}
ActivateContext(mainWindow, mainContext);
if(!gladLoadGLES2Loader((GLADloadproc)eglGetProcAddress))
{
delete mainWindow;
TEST_ERROR("Error initialising glad");
return false;
}
PostInit();
return true;
}
GraphicsWindow *OpenGLGraphicsTest::MakeWindow(int width, int height, const char *title)
{
return new AndroidWindow(width, height, title);
}
void *OpenGLGraphicsTest::MakeContext(GraphicsWindow *win, void *share)
{
AndroidWindow *droidwin = (AndroidWindow *)win;
int attribs[64] = {0};
int i = 0;
attribs[i++] = EGL_CONTEXT_CLIENT_VERSION;
attribs[i++] = 3;
attribs[i++] = EGL_CONTEXT_FLAGS_KHR;
if(debugDevice)
attribs[i++] = EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR;
else
attribs[i++] = 0;
attribs[i++] = EGL_NONE;
attribs[i++] = EGL_NONE;
EGLContext ctx = eglCreateContext(eglDisplay, config, share, attribs);
TEST_LOG("android context %p %d", ctx, eglGetError());
droidwin->surface = eglCreateWindowSurface(eglDisplay, config, droidwin->window, NULL);
TEST_LOG("android surface %p %d", droidwin->surface, eglGetError());
return ctx;
}
void OpenGLGraphicsTest::DestroyContext(void *ctx)
{
if(ctx == NULL)
return;
eglMakeCurrent(eglDisplay, 0L, 0L, NULL);
eglDestroyContext(eglDisplay, ctx);
}
void OpenGLGraphicsTest::ActivateContext(GraphicsWindow *win, void *ctx, bool alt)
{
AndroidWindow *droidwin = (AndroidWindow *)win;
if(ctx == NULL)
{
if(win == NULL)
return;
eglMakeCurrent(eglDisplay, NULL, NULL, NULL);
return;
}
eglMakeCurrent(eglDisplay, droidwin->surface, droidwin->surface, (EGLContext)ctx);
}
void OpenGLGraphicsTest::Present(GraphicsWindow *window)
{
AndroidWindow *droidwin = (AndroidWindow *)window;
eglSwapBuffers(eglDisplay, droidwin->surface);
}
+126
View File
@@ -139,6 +139,26 @@ void NuklearShutdown()
UnregisterClassW(wc.lpszClassName, wc.hInstance);
}
#elif defined(ANDROID)
nk_context *NuklearInit(int width, int height, const char *title)
{
return NULL;
}
bool NuklearTick(nk_context *ctx)
{
return false;
}
void NuklearRender()
{
}
void NuklearShutdown()
{
}
#elif defined(__linux__)
#define NK_XLIB_IMPLEMENTATION
@@ -710,3 +730,109 @@ int WINAPI wWinMain(_In_ HINSTANCE hInst, _In_opt_ HINSTANCE hPrevInstance, _In_
}
#endif
#if defined(ANDROID)
#include <android_native_app_glue.h>
#include <sstream>
#include <android/log.h>
struct android_app *android_state;
pthread_t cmdthread_handle = 0;
#define ANDROID_LOG(...) __android_log_print(ANDROID_LOG_INFO, "rd_demos", __VA_ARGS__);
std::vector<std::string> getArgs()
{
JNIEnv *env;
android_state->activity->vm->AttachCurrentThread(&env, 0);
jobject me = android_state->activity->clazz;
jclass acl = env->GetObjectClass(me); // class pointer of NativeActivity
jmethodID giid = env->GetMethodID(acl, "getIntent", "()Landroid/content/Intent;");
jobject intent = env->CallObjectMethod(me, giid); // Got our intent
jclass icl = env->GetObjectClass(intent); // class pointer of Intent
jmethodID gseid =
env->GetMethodID(icl, "getStringExtra", "(Ljava/lang/String;)Ljava/lang/String;");
jstring jsParam1 = (jstring)env->CallObjectMethod(intent, gseid, env->NewStringUTF("rd_demos"));
std::vector<std::string> ret;
if(jsParam1) // Check if arg value found
{
ret.push_back("rd_demos");
const char *param1 = env->GetStringUTFChars(jsParam1, 0);
std::istringstream iss(param1);
while(iss)
{
std::string sub;
iss >> sub;
ret.push_back(sub);
}
}
android_state->activity->vm->DetachCurrentThread();
return ret;
}
void *cmdthread(void *)
{
ANDROID_LOG("cmdthread");
std::vector<std::string> args = getArgs();
if(args.size())
{
std::vector<char *> argv;
for(size_t i = 0; i < args.size(); i++)
{
ANDROID_LOG("argv %d: %s", (int)i, args[i].c_str());
argv.push_back(&args[i][0]);
}
int argc = argv.size();
argv.push_back(NULL);
ANDROID_LOG("premain");
main(argc, argv.data());
ANDROID_LOG("postmain");
}
// activity is done and should be closed
ANativeActivity_finish(android_state->activity);
return NULL;
}
void handle_cmd(android_app *app, int32_t cmd)
{
if(cmd == APP_CMD_INIT_WINDOW)
{
ANDROID_LOG("APP_CMD_INIT_WINDOW");
pthread_create(&cmdthread_handle, NULL, cmdthread, NULL);
}
}
void android_main(struct android_app *state)
{
android_state = state;
android_state->onAppCmd = handle_cmd;
ANDROID_LOG("android_main");
// Used to poll the events in the main loop
int events;
android_poll_source *source;
do
{
if(ALooper_pollAll(1, nullptr, &events, (void **)&source) >= 0)
{
if(source != NULL)
source->process(android_state, source);
}
} while(android_state->destroyRequested == 0);
ANDROID_LOG("end android_main");
android_state = NULL;
}
#endif
+16
View File
@@ -154,6 +154,10 @@ std::string trim(const std::string &str)
static char printBuf[4096] = {};
static FILE *logFile = NULL;
#if defined(ANDROID)
#include <android/log.h>
#endif
void DebugPrint(const char *fmt, ...)
{
va_list args;
@@ -175,6 +179,10 @@ void DebugPrint(const char *fmt, ...)
#if defined(WIN32)
OutputDebugStringA(printBuf);
#endif
#if defined(ANDROID)
__android_log_print(ANDROID_LOG_INFO, "rd_demos", "%s", printBuf);
#endif
}
void LoadXPM(const char **XPM, Texture &tex)
@@ -215,6 +223,10 @@ void LoadXPM(const char **XPM, Texture &tex)
// having to remove the built shaderc files
#define USE_LINKED_SHADERC (1 && HAVE_SHADERC)
#if !USE_LINKED_SHADERC && defined(ANDROID)
#error "can't execute shaderc on android"
#endif
#if USE_LINKED_SHADERC
#include <shaderc/shaderc.h>
#else
@@ -569,6 +581,10 @@ bool GraphicsTest::Init()
HMODULE mod = GetModuleHandleA("renderdoc.dll");
if(mod)
RENDERDOC_GetAPI = (pRENDERDOC_GetAPI)GetProcAddress(mod, "RENDERDOC_GetAPI");
#elif defined(ANDROID)
void *mod = dlopen("libVkLayer_GLES_RenderDoc.so", RTLD_NOW | RTLD_NOLOAD);
if(mod)
RENDERDOC_GetAPI = (pRENDERDOC_GetAPI)dlsym(mod, "RENDERDOC_GetAPI");
#elif defined(__linux__)
void *mod = dlopen("librenderdoc.so", RTLD_NOW | RTLD_NOLOAD);
if(mod)
+2
View File
@@ -26,6 +26,8 @@
#if defined(WIN32)
#include "win32/win32_platform.h"
#elif defined(ANDROID)
#include "android/android_platform.h"
#elif defined(__linux__)
#include "linux/linux_platform.h"
#elif defined(__APPLE__)
+26 -1
View File
@@ -102,6 +102,8 @@ void main()
#if defined(WIN32)
#include "../win32/win32_window.h"
#elif defined(ANDROID)
#include "../android/android_window.h"
#elif defined(__linux__)
#include "../linux/linux_window.h"
#elif defined(__APPLE__)
@@ -161,6 +163,8 @@ void VulkanGraphicsTest::Prepare(int argc, char **argv)
#if defined(WIN32)
enabledInstExts.push_back(VK_KHR_WIN32_SURFACE_EXTENSION_NAME);
#elif defined(ANDROID)
enabledInstExts.push_back(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME);
#elif defined(__linux__)
enabledInstExts.push_back(VK_KHR_XCB_SURFACE_EXTENSION_NAME);
@@ -592,6 +596,11 @@ void VulkanGraphicsTest::Prepare(int argc, char **argv)
if(computeQueueFamilyIndex == ~0U)
computeQueueFamilyIndex = q;
}
else if(queueProps[q].queueFlags & VK_QUEUE_TRANSFER_BIT)
{
if(transferQueueFamilyIndex == ~0U)
transferQueueFamilyIndex = q;
}
}
// if no queue has been selected, find it now
@@ -679,8 +688,13 @@ bool VulkanGraphicsTest::Init()
queueCreates.push_back(vkh::DeviceQueueCreateInfo(graphicsQueueFamilyIndex, 1, priorities));
if(queueFamilyIndex != computeQueueFamilyIndex &&
(graphicsQueueFamilyIndex != computeQueueFamilyIndex || !forceGraphicsQueue) &&
forceComputeQueue)
computeQueueFamilyIndex != ~0U && forceComputeQueue)
queueCreates.push_back(vkh::DeviceQueueCreateInfo(computeQueueFamilyIndex, 1, priorities));
if(queueFamilyIndex != transferQueueFamilyIndex &&
graphicsQueueFamilyIndex != transferQueueFamilyIndex &&
computeQueueFamilyIndex != transferQueueFamilyIndex && transferQueueFamilyIndex != ~0U &&
forceTransferQueue)
queueCreates.push_back(vkh::DeviceQueueCreateInfo(transferQueueFamilyIndex, 1, priorities));
CHECK_VKR(vkCreateDevice(
phys, vkh::DeviceCreateInfo(queueCreates, enabledLayers, devExts, features).next(devInfoNext),
@@ -744,6 +758,8 @@ VulkanWindow *VulkanGraphicsTest::MakeWindow(int width, int height, const char *
{
#if defined(WIN32)
GraphicsWindow *platWin = new Win32Window(width, height, title);
#elif defined(ANDROID)
GraphicsWindow *platWin = new AndroidWindow(width, height, title);
#elif defined(__linux__)
GraphicsWindow *platWin = new X11Window(width, height, 0, title);
#elif defined(__APPLE__)
@@ -1325,6 +1341,15 @@ VulkanWindow::VulkanWindow(VulkanGraphicsTest *test, GraphicsWindow *win)
createInfo.hinstance = GetModuleHandleA(NULL);
vkCreateWin32SurfaceKHR(m_Test->instance, &createInfo, NULL, &surface);
#elif defined(ANDROID)
VkAndroidSurfaceCreateInfoKHR createInfo;
createInfo.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR;
createInfo.pNext = NULL;
createInfo.flags = 0;
createInfo.window = ((AndroidWindow *)win)->window;
vkCreateAndroidSurfaceKHR(m_Test->instance, &createInfo, NULL, &surface);
#elif defined(__linux__)
VkXcbSurfaceCreateInfoKHR createInfo;
+2
View File
@@ -273,8 +273,10 @@ struct VulkanGraphicsTest : public GraphicsTest
bool forceGraphicsQueue = false;
bool forceComputeQueue = false;
bool forceTransferQueue = false;
uint32_t graphicsQueueFamilyIndex = ~0U;
uint32_t computeQueueFamilyIndex = ~0U;
uint32_t transferQueueFamilyIndex = ~0U;
bool hasExt(const char *ext);