Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multi-Window Replay as secondary app #2065

Open
wants to merge 4 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 61 additions & 4 deletions HOWTO_android.md
Original file line number Diff line number Diff line change
Expand Up @@ -326,13 +326,32 @@ adb shell "settings put global gpu_debug_layers ''"

Now, we need to install the Replay application that we built as part of the
GFXReconstruct source.
From the top of the source pulled down from the repo by using the

Depending on what version of Android you are using, there are two version of the
replay app that can be installed:

* replay
* multiwin-replay

`multiwin-replay` is more functional and will eventually become the default
`replay` application, however, it currently only works properly in all our test
cases on Android 14 or newer devices.

So install the replay application that will work best for you using the
`gfxrecon.py` script:

**Install Replay APK**

```bash
./android/scripts/gfxrecon.py install-apk android/tools/replay/build/outputs/apk/debug/replay-debug.apk
```

**Install Multi-Windowed Replay APK**

```bash
./android/scripts/gfxrecon.py install-apk android/tools/multi-win-replay/build/outputs/apk/debug/multi-win-replay-debug.apk
```

#### Additional Permissions

A recent change to enable the replay tool on Android 12 and greater has resulted
Expand Down Expand Up @@ -362,12 +381,22 @@ adb shell appops set com.lunarg.gfxreconstruct.replay MANAGE_EXTERNAL_STORAGE al

### 9. Run the replay

Try running the replay using the `gfxrecon.py` script:
Depending if you are using the original `replay` application or the `multiwin-replay`
version of the application, you can execute the replay in the following way
using the `gfxrecon.py` script:

**Original Replay App**

```bash
./android/scripts/gfxrecon.py replay /sdcard/Download/gfxrecon_capture_frames_500_through_700_20221211T130328.gfxr
```

**Multi-windowed Replay App**

```bash
./android/scripts/gfxrecon.py multiwin-replay /sdcard/Download/gfxrecon_capture_frames_500_through_700_20221211T130328.gfxr
```

Voila!
It worked, the replay executes properly.

Expand Down Expand Up @@ -568,21 +597,49 @@ adb shell "setprop debug.hwui.renderer 'skiavk'"

Now, we need to install the Replay application that we built as part of the
GFXReconstruct source.
Install the replay APK from the root of the built source tree by using the

As mentioned in the section above, there are currently 2 replay applications:

* replay
* multiwin-replay

`multiwin-replay` is more functional and will eventually become the default
`replay` application, however, it currently only works properly in all our test
cases on Android 14 or newer devices.

So install the replay application that will work best for you using the
`gfxrecon.py` script:

**Install Replay APK**

```bash
./android/scripts/gfxrecon.py install-apk android/tools/replay/build/outputs/apk/debug/replay-debug.apk
```

**Install Multi-Windowed Replay APK**

```bash
./android/scripts/gfxrecon.py install-apk android/tools/multi-win-replay/build/outputs/apk/debug/multi-win-replay-debug.apk
```

### 12. Run the replay

Try running the replay using the `gfxrecon.py` script:
Depending if you are using the original `replay` application or the `multiwin-replay`
version of the application, you can execute the replay in the following way
using the `gfxrecon.py` script:

**Original Replay App**

```bash
./android/scripts/gfxrecon.py replay /storage/emulated/0/Download/sacredpath_capture_frames_100_through_200_20221215T174939.gfxr
```

**Multi-windowed Replay App**

```bash
./android/scripts/gfxrecon.py multiwin-replay /storage/emulated/0/Download/sacredpath_capture_frames_100_through_200_20221215T174939.gfxr
```

**NOTE:** Please refer to [Additional Permissions](#additional-permissions)
above for additional permissions that may need to be enabled to run the
replay application on certain versions of Android.
32 changes: 32 additions & 0 deletions android/framework/application-multi-win/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
add_library(gfxrecon_application_multiwin STATIC "")

target_compile_definitions(gfxrecon_application_multiwin
PUBLIC
GFXR_MULTI_WINDOW_REPLAY=1
)

target_sources(gfxrecon_application_multiwin
PUBLIC
${GFXRECON_SOURCE_DIR}/framework/application/android_context.h
${GFXRECON_SOURCE_DIR}/framework/application/android_context.cpp
${GFXRECON_SOURCE_DIR}/framework/application/android_window.h
${GFXRECON_SOURCE_DIR}/framework/application/android_window.cpp
${GFXRECON_SOURCE_DIR}/framework/application/application.h
${GFXRECON_SOURCE_DIR}/framework/application/application.cpp
${GFXRECON_SOURCE_DIR}/framework/application/wsi_context.h
${GFXRECON_SOURCE_DIR}/framework/application/wsi_context.cpp
${GFXRECON_SOURCE_DIR}/framework/application/android_jni.cpp
)

target_include_directories(gfxrecon_application_multiwin
PUBLIC
${GFXRECON_SOURCE_DIR}/framework
${ANDROID_NDK}/sources/android/native_app_glue)

target_link_libraries(gfxrecon_application_multiwin
gfxrecon_decode
gfxrecon_graphics
gfxrecon_format
gfxrecon_util
vulkan_registry
platform_specific)
3 changes: 2 additions & 1 deletion android/framework/application/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
add_library(gfxrecon_application STATIC "")

target_sources(gfxrecon_application
PRIVATE
PUBLIC
${GFXRECON_SOURCE_DIR}/framework/application/android_context.h
${GFXRECON_SOURCE_DIR}/framework/application/android_context.cpp
${GFXRECON_SOURCE_DIR}/framework/application/android_window.h
Expand All @@ -10,6 +10,7 @@ target_sources(gfxrecon_application
${GFXRECON_SOURCE_DIR}/framework/application/application.cpp
${GFXRECON_SOURCE_DIR}/framework/application/wsi_context.h
${GFXRECON_SOURCE_DIR}/framework/application/wsi_context.cpp
${GFXRECON_SOURCE_DIR}/framework/application/android_jni.cpp
)

target_include_directories(gfxrecon_application
Expand Down
2 changes: 2 additions & 0 deletions android/gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,5 @@ org.gradle.jvmargs=-Xmx1536m
# org.gradle.parallel=true


android.useAndroidX=true
android.enableJetifier=true
16 changes: 14 additions & 2 deletions android/scripts/gfxrecon.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,23 +32,25 @@
# Supported commands
valid_commands = [
'install-apk',
'multiwin-replay',
'replay'
]

# Arguments
# gfxrecon install-apk <file>
# gfxrecon replay [-p | --push-file <file-on-desktop>] <file-on-device>
# gfxrecon multiwin-replay [-p | --push-file <file-on-desktop>] <file-on-device>

# Application info
app_name = 'com.lunarg.gfxreconstruct.replay'
app_activity = '"com.lunarg.gfxreconstruct.replay/android.app.NativeActivity"'
multiwin_app_activity = '"com.lunarg.gfxreconstruct.replay/.ReplayActivity"'
app_action = 'android.intent.action.MAIN'
app_category = 'android.intent.category.LAUNCHER'

# ADB commands
adb_install = 'adb install -g -t -r'
adb_sdk_version = 'adb shell getprop ro.build.version.sdk'
adb_start = 'adb shell am start -n {} -a {} -c {}'.format(app_activity, app_action, app_category)
adb_stop = 'adb shell am force-stop {}'.format(app_name)
adb_push = 'adb push'
adb_devices = 'adb devices'
Expand Down Expand Up @@ -354,7 +356,7 @@ def InstallApk(install_args):
print('Executing:', cmd)
subprocess.check_call(shlex.split(cmd, posix='win' not in sys.platform))

def Replay(replay_args):
def ReplayCommon(replay_args, activity):
replay_parser = CreateReplayParser()
args = replay_parser.parse_args(replay_args)

Expand All @@ -371,12 +373,20 @@ def Replay(replay_args):
print('Executing:', adb_stop)
subprocess.check_call(shlex.split(adb_stop, posix='win' not in sys.platform))

adb_start = 'adb shell am start -n {} -a {} -c {}'.format(activity, app_action, app_category)

cmd = ' '.join([adb_start, '--es', '"args"', '"{}"'.format(extras)])
print('Executing:', cmd)

# Specify posix=False to prevent removal of quotes from adb extras.
subprocess.check_call(shlex.split(cmd, posix=False))

def Replay(replay_args):
ReplayCommon(replay_args, app_activity)

def MultiWinReplay(replay_args):
ReplayCommon(replay_args, multiwin_app_activity)

if __name__ == '__main__':
devices = QueryAvailableDevices()

Expand All @@ -387,3 +397,5 @@ def Replay(replay_args):
InstallApk(command.args)
elif command.command == 'replay':
Replay(command.args)
elif command.command == 'multiwin-replay':
MultiWinReplay(command.args)
2 changes: 2 additions & 0 deletions android/settings.gradle
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
include ':layer'
include ':replay'
project(':replay').projectDir = file('tools/replay')
include ':multi-win-replay'
project(':multi-win-replay').projectDir = file('tools/multi-win-replay')
1 change: 1 addition & 0 deletions android/tools/multi-win-replay/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build
31 changes: 31 additions & 0 deletions android/tools/multi-win-replay/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>

<!-- This .apk has no Java code itself, so set hasCode to false. -->
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:theme="@style/AppTheme"
android:supportsRtl="true"
android:extractNativeLibs="true"
android:hasCode="true">
<activity android:name=".ReplayActivity"
android:exported="true"
android:configChanges="orientation|screenSize|keyboard|keyboardHidden|screenLayout"
android:screenOrientation="unspecified">
<meta-data android:name="android.app.lib_name"
android:value="gfxrecon-replay" />
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>

</manifest>
50 changes: 50 additions & 0 deletions android/tools/multi-win-replay/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html

cmake_minimum_required(VERSION 3.4.1)

project(gfxrecon-replay)

get_filename_component(GFXRECON_SOURCE_DIR ../../.. ABSOLUTE)

add_library(native_app_glue STATIC
${ANDROID_NDK}/sources/android/native_app_glue/android_native_app_glue.c)

# Export ANativeActivity_onCreate(),
# Refer to: https://github.com/android-ndk/ndk/issues/381.
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -u ANativeActivity_onCreate")

include(../../framework/cmake-config/PlatformConfig.cmake)
add_subdirectory(../../framework/util ${CMAKE_SOURCE_DIR}/../../framework/util/build/tools/replay/${ANDROID_ABI})
add_subdirectory(../../framework/graphics ${CMAKE_SOURCE_DIR}/../../framework/graphics/build/tools/replay/${ANDROID_ABI})
add_subdirectory(../../framework/format ${CMAKE_SOURCE_DIR}/../../framework/format/build/tools/replay/${ANDROID_ABI})
add_subdirectory(../../framework/decode ${CMAKE_SOURCE_DIR}/../../framework/decode/build/tools/replay/${ANDROID_ABI})
add_subdirectory(../../framework/application-multi-win ${CMAKE_SOURCE_DIR}/../../framework/application/build/tools/replay/${ANDROID_ABI})

add_library(gfxrecon-replay
SHARED
${GFXRECON_SOURCE_DIR}/tools/tool_settings.h
${GFXRECON_SOURCE_DIR}/tools/replay/parse_dump_resources_cli.h
${GFXRECON_SOURCE_DIR}/tools/replay/parse_dump_resources_cli.cpp
${GFXRECON_SOURCE_DIR}/tools/replay/replay_settings.h
${GFXRECON_SOURCE_DIR}/tools/replay/replay_pre_processing.h
${GFXRECON_SOURCE_DIR}/tools/replay/android_main.cpp)

target_include_directories(gfxrecon-replay
PUBLIC
${ANDROID_NDK}/sources/android/native_app_glue
${GFXRECON_SOURCE_DIR}/external/precompiled/android/include
${CMAKE_BINARY_DIR})

target_link_libraries(
gfxrecon-replay
nlohmann_json
gfxrecon_application_multiwin
gfxrecon_decode
gfxrecon_graphics
gfxrecon_format
gfxrecon_util
platform_specific
native_app_glue
android
log)
58 changes: 58 additions & 0 deletions android/tools/multi-win-replay/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
apply plugin: 'com.android.application'

android {
compileSdkVersion 33
namespace 'com.lunarg.gfxreconstruct.replay'
ndkVersion '22.1.7171670'
defaultConfig {
applicationId "com.lunarg.gfxreconstruct.replay"
minSdkVersion 26
targetSdkVersion 33
versionCode 1
versionName "1.0"
ndk {
if (project.hasProperty("armeabi-v7a")) {
abiFilters 'armeabi-v7a'
} else if (project.hasProperty("arm64-v8a")) {
abiFilters 'arm64-v8a'
} else if (project.hasProperty("x86")) {
abiFilters 'x86'
} else if (project.hasProperty("x86_64")) {
abiFilters 'x86_64'
} else {
abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
}
}
externalNativeBuild {
cmake {
cppFlags "-fexceptions", "-std=c++17", "-Wno-nullability-completeness"
arguments "-DANDROID_TOOLCHAIN=clang", "-DANDROID_STL=c++_static"
}
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
java.srcDirs = ['src']
res.srcDirs = ['res']
}
}
externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}
}

dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.0'
implementation project(':layer')
}
Loading
Loading