mirror of https://github.com/auygun/kaliber.git
Compare commits
No commits in common. "655c0a7b71f026a18bb08b4a0779899055e1c62d" and "8cd680d6a4ee06df31152b3b59c0a07334945f61" have entirely different histories.
655c0a7b71
...
8cd680d6a4
|
@ -1,6 +1,5 @@
|
||||||
build/android/.gradle
|
build/android/.gradle
|
||||||
build/android/*.apk
|
build/android/*.apk
|
||||||
build/android/*.idsig
|
|
||||||
build/android/app/.cxx
|
build/android/app/.cxx
|
||||||
build/android/app/build
|
build/android/app/build
|
||||||
build/android/build
|
build/android/build
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
# The location of the build configuration file.
|
||||||
|
buildconfig = "//build/gn/BUILDCONFIG.gn"
|
|
@ -1,5 +1,5 @@
|
||||||
A simple, cross-platform 2D game engine with OpenGL and Vulkan renderers.
|
A simple, cross-platform 2D game engine with OpenGL and Vulkan renderers.
|
||||||
Supports Linux and Android platforms.
|
Supports Linux and Android (lolipop+) platforms.
|
||||||
This is a personal hobby project. I've published a little game on
|
This is a personal hobby project. I've published a little game on
|
||||||
[Google Play](https://play.google.com/store/apps/details?id=com.woom.game)
|
[Google Play](https://play.google.com/store/apps/details?id=com.woom.game)
|
||||||
based on this engine. Full game code and assets are included in this repository.
|
based on this engine. Full game code and assets are included in this repository.
|
||||||
|
@ -14,6 +14,11 @@ Android:
|
||||||
cd build/android
|
cd build/android
|
||||||
./gradlew :app:assembleRelease
|
./gradlew :app:assembleRelease
|
||||||
```
|
```
|
||||||
|
GN (linux only for now):
|
||||||
|
```text
|
||||||
|
gn gen --args='is_debug=false' out/release
|
||||||
|
ninja -C out/release
|
||||||
|
```
|
||||||
#### Third-party libraries:
|
#### Third-party libraries:
|
||||||
[glew](https://github.com/nigels-com/glew),
|
[glew](https://github.com/nigels-com/glew),
|
||||||
[jsoncpp](https://github.com/open-source-parsers/jsoncpp),
|
[jsoncpp](https://github.com/open-source-parsers/jsoncpp),
|
||||||
|
|
|
@ -14,8 +14,7 @@
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
#
|
#
|
||||||
|
|
||||||
cmake_minimum_required(VERSION 3.22.1)
|
cmake_minimum_required(VERSION 3.4.1)
|
||||||
project(kaliber)
|
|
||||||
|
|
||||||
# OBOE Library
|
# OBOE Library
|
||||||
set (OBOE_DIR ../../../src/third_party/oboe)
|
set (OBOE_DIR ../../../src/third_party/oboe)
|
||||||
|
@ -37,9 +36,9 @@ add_library(native_app_glue STATIC
|
||||||
|
|
||||||
# now build app's shared lib
|
# now build app's shared lib
|
||||||
if (CMAKE_BUILD_TYPE MATCHES Debug)
|
if (CMAKE_BUILD_TYPE MATCHES Debug)
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++20 -Wall -Werror -Wno-unused-but-set-variable -Wno-deprecated-enum-enum-conversion -Wno-unused-parameter -Wno-unsequenced -D_DEBUG -DVK_USE_PLATFORM_ANDROID_KHR")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 -Wall -Werror -D_DEBUG -DVK_USE_PLATFORM_ANDROID_KHR")
|
||||||
else ()
|
else ()
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++20 -Wall -Werror -Wno-unused-but-set-variable -Wno-deprecated-enum-enum-conversion -Wno-unused-parameter -Wno-unsequenced -DVK_USE_PLATFORM_ANDROID_KHR")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 -Wall -Werror -DVK_USE_PLATFORM_ANDROID_KHR")
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
|
|
||||||
|
@ -142,7 +141,6 @@ add_library(kaliber SHARED
|
||||||
../../../src/third_party/minizip/ioapi.c
|
../../../src/third_party/minizip/ioapi.c
|
||||||
../../../src/third_party/minizip/unzip.c
|
../../../src/third_party/minizip/unzip.c
|
||||||
../../../src/third_party/spirv-reflect/spirv_reflect.c
|
../../../src/third_party/spirv-reflect/spirv_reflect.c
|
||||||
../../../src/third_party/stb/stb_image.c
|
|
||||||
../../../src/third_party/texture_compressor/dxt_encoder_internals.cc
|
../../../src/third_party/texture_compressor/dxt_encoder_internals.cc
|
||||||
../../../src/third_party/texture_compressor/dxt_encoder.cc
|
../../../src/third_party/texture_compressor/dxt_encoder.cc
|
||||||
../../../src/third_party/texture_compressor/texture_compressor_etc1.cc
|
../../../src/third_party/texture_compressor/texture_compressor_etc1.cc
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
apply plugin: 'com.android.application'
|
apply plugin: 'com.android.application'
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdk 33
|
compileSdkVersion 29
|
||||||
ndkVersion '25.1.8937393'
|
ndkVersion '21.3.6528147'
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId = 'com.woom.game'
|
applicationId = 'com.woom.game'
|
||||||
minSdk 24
|
minSdkVersion 21
|
||||||
targetSdk 33
|
targetSdkVersion 29
|
||||||
externalNativeBuild {
|
externalNativeBuild {
|
||||||
cmake {
|
cmake {
|
||||||
arguments '-DANDROID_STL=c++_static'
|
arguments '-DANDROID_STL=c++_static'
|
||||||
|
@ -29,7 +29,7 @@ android {
|
||||||
}
|
}
|
||||||
externalNativeBuild {
|
externalNativeBuild {
|
||||||
cmake {
|
cmake {
|
||||||
version '3.22.1'
|
version '3.10.2'
|
||||||
path 'CMakeLists.txt'
|
path 'CMakeLists.txt'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,12 +39,11 @@ android {
|
||||||
assets.srcDirs = ['../../../assets']
|
assets.srcDirs = ['../../../assets']
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
namespace 'com.woom.game'
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||||
implementation 'androidx.appcompat:appcompat:1.6.1'
|
implementation 'androidx.appcompat:appcompat:1.0.2'
|
||||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
|
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
|
||||||
implementation 'com.google.android.gms:play-services-ads:22.0.0'
|
implementation 'com.google.android.gms:play-services-ads:19.1.0'
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
package="com.woom.game"
|
||||||
android:versionCode="16"
|
android:versionCode="16"
|
||||||
android:versionName="1.0.1">
|
android:versionName="1.0.1">
|
||||||
|
|
||||||
|
@ -19,7 +20,6 @@
|
||||||
android:configChanges="orientation|keyboardHidden"
|
android:configChanges="orientation|keyboardHidden"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:screenOrientation="portrait"
|
android:screenOrientation="portrait"
|
||||||
android:exported="true"
|
|
||||||
android:theme="@android:style/Theme.NoTitleBar.Fullscreen">
|
android:theme="@android:style/Theme.NoTitleBar.Fullscreen">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
|
|
@ -5,7 +5,7 @@ buildscript {
|
||||||
jcenter()
|
jcenter()
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:8.0.1'
|
classpath 'com.android.tools.build:gradle:4.1.0'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,13 +9,9 @@
|
||||||
|
|
||||||
# Specifies the JVM arguments used for the daemon process.
|
# Specifies the JVM arguments used for the daemon process.
|
||||||
# The setting is particularly useful for tweaking memory settings.
|
# The setting is particularly useful for tweaking memory settings.
|
||||||
android.defaults.buildfeatures.buildconfig=true
|
|
||||||
android.enableJetifier=true
|
android.enableJetifier=true
|
||||||
android.nonFinalResIds=false
|
|
||||||
android.nonTransitiveRClass=false
|
|
||||||
android.useAndroidX=true
|
android.useAndroidX=true
|
||||||
org.gradle.jvmargs=-Xmx1536m
|
org.gradle.jvmargs=-Xmx1536m
|
||||||
android.native.buildOutput=verbose
|
|
||||||
|
|
||||||
# When configured, Gradle will run in incubating parallel mode.
|
# When configured, Gradle will run in incubating parallel mode.
|
||||||
# This option should only be used with decoupled projects. More details, visit
|
# This option should only be used with decoupled projects. More details, visit
|
||||||
|
|
|
@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
~/Android/Sdk/build-tools/31.0.0/zipalign -p -f 4 ./app/build/outputs/apk/release/app-release-unsigned.apk ./app-release-aligned.apk
|
jarsigner -keystore ~/key_store/apk_key_store.jks -storepass xxx -keypass xxx -signedjar app-release.apk ./app/build/outputs/apk/release/app-release-unsigned.apk upload
|
||||||
~/Android/Sdk/build-tools/31.0.0/apksigner sign -ks ~/key_store/apk_key_store.jks --ks-key-alias upload --ks-pass stdin ./app-release-aligned.apk
|
zipalign -f 4 ./app-release.apk ./app-release-aligned.apk
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
config("compiler_defaults") {
|
||||||
|
if (current_os == "linux") {
|
||||||
|
cflags = [
|
||||||
|
"-fPIC",
|
||||||
|
"-pthread",
|
||||||
|
"-g",
|
||||||
|
]
|
||||||
|
|
||||||
|
cflags_cc = [
|
||||||
|
"-std=c++17",
|
||||||
|
"-I../../src",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
config("executable_ldconfig") {
|
||||||
|
ldflags = [
|
||||||
|
"-Wl,-rpath=\$ORIGIN/",
|
||||||
|
"-Wl,-rpath-link=",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
config("debug") {
|
||||||
|
defines = [ "_DEBUG" ]
|
||||||
|
|
||||||
|
if (current_os == "linux") {
|
||||||
|
if (current_cpu == "x64") {
|
||||||
|
defines += [ "_GLIBCXX_DEBUG=1" ]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
config("release") {
|
||||||
|
cflags = []
|
||||||
|
defines = [ "NDEBUG" ]
|
||||||
|
|
||||||
|
if (current_os == "linux") {
|
||||||
|
cflags += [ "-Ofast" ]
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
declare_args() {
|
||||||
|
is_debug = false
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target_os == "") {
|
||||||
|
target_os = host_os
|
||||||
|
}
|
||||||
|
if (target_cpu == "") {
|
||||||
|
target_cpu = host_cpu
|
||||||
|
}
|
||||||
|
if (current_cpu == "") {
|
||||||
|
current_cpu = target_cpu
|
||||||
|
}
|
||||||
|
if (current_os == "") {
|
||||||
|
current_os = target_os
|
||||||
|
}
|
||||||
|
|
||||||
|
_compiler_default_config = [ "//build/gn:compiler_defaults" ]
|
||||||
|
|
||||||
|
# Debug/release-related defines.
|
||||||
|
if (is_debug) {
|
||||||
|
_compiler_default_config += [ "//build/gn:debug" ]
|
||||||
|
} else {
|
||||||
|
_compiler_default_config += [ "//build/gn:release" ]
|
||||||
|
}
|
||||||
|
|
||||||
|
set_defaults("executable") {
|
||||||
|
configs = _compiler_default_config
|
||||||
|
configs += [ "//build/gn:executable_ldconfig" ]
|
||||||
|
}
|
||||||
|
set_defaults("static_library") {
|
||||||
|
configs = _compiler_default_config
|
||||||
|
}
|
||||||
|
set_defaults("shared_library") {
|
||||||
|
configs = _compiler_default_config
|
||||||
|
}
|
||||||
|
set_defaults("source_set") {
|
||||||
|
configs = _compiler_default_config
|
||||||
|
}
|
||||||
|
|
||||||
|
set_default_toolchain("//build/gn/toolchain:clang")
|
|
@ -0,0 +1,151 @@
|
||||||
|
toolchain("clang") {
|
||||||
|
tool("cc") {
|
||||||
|
depfile = "{{output}}.d"
|
||||||
|
command = "clang -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_c}} -c {{source}} -o {{output}}"
|
||||||
|
depsformat = "gcc"
|
||||||
|
description = "CC {{output}}"
|
||||||
|
outputs =
|
||||||
|
[ "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o" ]
|
||||||
|
}
|
||||||
|
|
||||||
|
tool("cxx") {
|
||||||
|
depfile = "{{output}}.d"
|
||||||
|
command = "clang++ -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_cc}} -c {{source}} -o {{output}}"
|
||||||
|
depsformat = "gcc"
|
||||||
|
description = "CXX {{output}}"
|
||||||
|
outputs =
|
||||||
|
[ "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o" ]
|
||||||
|
}
|
||||||
|
|
||||||
|
tool("alink") {
|
||||||
|
rspfile = "{{output}}.rsp"
|
||||||
|
command = "rm -f {{output}} && ar rcs {{output}} @$rspfile"
|
||||||
|
description = "AR {{target_output_name}}{{output_extension}}"
|
||||||
|
rspfile_content = "{{inputs}}"
|
||||||
|
outputs =
|
||||||
|
[ "{{target_out_dir}}/{{target_output_name}}{{output_extension}}" ]
|
||||||
|
default_output_extension = ".a"
|
||||||
|
output_prefix = "lib"
|
||||||
|
}
|
||||||
|
|
||||||
|
tool("solink") {
|
||||||
|
soname = "{{target_output_name}}{{output_extension}}" # e.g. "libfoo.so".
|
||||||
|
sofile = "{{output_dir}}/$soname"
|
||||||
|
rspfile = soname + ".rsp"
|
||||||
|
|
||||||
|
command = "clang++ -shared {{ldflags}} -o $sofile -Wl,-soname=$soname @$rspfile"
|
||||||
|
rspfile_content = "-Wl,--whole-archive {{inputs}} {{solibs}} -Wl,--no-whole-archive {{libs}}"
|
||||||
|
|
||||||
|
description = "SOLINK $soname"
|
||||||
|
|
||||||
|
# Use this for {{output_extension}} expansions unless a target manually
|
||||||
|
# overrides it (in which case {{output_extension}} will be what the target
|
||||||
|
# specifies).
|
||||||
|
default_output_extension = ".so"
|
||||||
|
|
||||||
|
# Use this for {{output_dir}} expansions unless a target manually overrides
|
||||||
|
# it (in which case {{output_dir}} will be what the target specifies).
|
||||||
|
default_output_dir = "{{root_out_dir}}"
|
||||||
|
|
||||||
|
outputs = [ sofile ]
|
||||||
|
link_output = sofile
|
||||||
|
depend_output = sofile
|
||||||
|
output_prefix = "lib"
|
||||||
|
}
|
||||||
|
|
||||||
|
tool("link") {
|
||||||
|
outfile = "{{target_output_name}}{{output_extension}}"
|
||||||
|
rspfile = "$outfile.rsp"
|
||||||
|
command = "clang++ {{ldflags}} -o $outfile -Wl,--start-group @$rspfile {{solibs}} -Wl,--end-group {{libs}}"
|
||||||
|
description = "LINK $outfile"
|
||||||
|
default_output_dir = "{{root_out_dir}}"
|
||||||
|
rspfile_content = "{{inputs}}"
|
||||||
|
outputs = [ outfile ]
|
||||||
|
}
|
||||||
|
|
||||||
|
tool("stamp") {
|
||||||
|
command = "touch {{output}}"
|
||||||
|
description = "STAMP {{output}}"
|
||||||
|
}
|
||||||
|
|
||||||
|
tool("copy") {
|
||||||
|
command = "cp -af {{source}} {{output}}"
|
||||||
|
description = "COPY {{source}} {{output}}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
toolchain("gcc") {
|
||||||
|
tool("cc") {
|
||||||
|
depfile = "{{output}}.d"
|
||||||
|
command = "gcc -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_c}} -c {{source}} -o {{output}}"
|
||||||
|
depsformat = "gcc"
|
||||||
|
description = "CC {{output}}"
|
||||||
|
outputs =
|
||||||
|
[ "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o" ]
|
||||||
|
}
|
||||||
|
|
||||||
|
tool("cxx") {
|
||||||
|
depfile = "{{output}}.d"
|
||||||
|
command = "g++ -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_cc}} -c {{source}} -o {{output}}"
|
||||||
|
depsformat = "gcc"
|
||||||
|
description = "CXX {{output}}"
|
||||||
|
outputs =
|
||||||
|
[ "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o" ]
|
||||||
|
}
|
||||||
|
|
||||||
|
tool("alink") {
|
||||||
|
rspfile = "{{output}}.rsp"
|
||||||
|
command = "rm -f {{output}} && ar rcs {{output}} @$rspfile"
|
||||||
|
description = "AR {{target_output_name}}{{output_extension}}"
|
||||||
|
rspfile_content = "{{inputs}}"
|
||||||
|
outputs =
|
||||||
|
[ "{{target_out_dir}}/{{target_output_name}}{{output_extension}}" ]
|
||||||
|
default_output_extension = ".a"
|
||||||
|
output_prefix = "lib"
|
||||||
|
}
|
||||||
|
|
||||||
|
tool("solink") {
|
||||||
|
soname = "{{target_output_name}}{{output_extension}}" # e.g. "libfoo.so".
|
||||||
|
sofile = "{{output_dir}}/$soname"
|
||||||
|
rspfile = soname + ".rsp"
|
||||||
|
|
||||||
|
command = "g++ -shared {{ldflags}} -o $sofile -Wl,-soname=$soname @$rspfile"
|
||||||
|
rspfile_content = "-Wl,--whole-archive {{inputs}} {{solibs}} -Wl,--no-whole-archive {{libs}}"
|
||||||
|
|
||||||
|
description = "SOLINK $soname"
|
||||||
|
|
||||||
|
# Use this for {{output_extension}} expansions unless a target manually
|
||||||
|
# overrides it (in which case {{output_extension}} will be what the target
|
||||||
|
# specifies).
|
||||||
|
default_output_extension = ".so"
|
||||||
|
|
||||||
|
# Use this for {{output_dir}} expansions unless a target manually overrides
|
||||||
|
# it (in which case {{output_dir}} will be what the target specifies).
|
||||||
|
default_output_dir = "{{root_out_dir}}"
|
||||||
|
|
||||||
|
outputs = [ sofile ]
|
||||||
|
link_output = sofile
|
||||||
|
depend_output = sofile
|
||||||
|
output_prefix = "lib"
|
||||||
|
}
|
||||||
|
|
||||||
|
tool("link") {
|
||||||
|
outfile = "{{target_output_name}}{{output_extension}}"
|
||||||
|
rspfile = "$outfile.rsp"
|
||||||
|
command = "g++ {{ldflags}} -o $outfile -Wl,--start-group @$rspfile {{solibs}} -Wl,--end-group {{libs}}"
|
||||||
|
description = "LINK $outfile"
|
||||||
|
default_output_dir = "{{root_out_dir}}"
|
||||||
|
rspfile_content = "{{inputs}}"
|
||||||
|
outputs = [ outfile ]
|
||||||
|
}
|
||||||
|
|
||||||
|
tool("stamp") {
|
||||||
|
command = "touch {{output}}"
|
||||||
|
description = "STAMP {{output}}"
|
||||||
|
}
|
||||||
|
|
||||||
|
tool("copy") {
|
||||||
|
command = "cp -af {{source}} {{output}}"
|
||||||
|
description = "COPY {{source}} {{output}}"
|
||||||
|
}
|
||||||
|
}
|
|
@ -32,8 +32,8 @@ LDFLAGS = -lX11 -lGL -pthread -lasound -ldl
|
||||||
# Always enable debug information.
|
# Always enable debug information.
|
||||||
CFLAGS += -g
|
CFLAGS += -g
|
||||||
|
|
||||||
# Enable extra warnings and make all warnings into errors.
|
# Make all warnings into errors.
|
||||||
CFLAGS += -Wextra -Werror
|
CFLAGS += -Werror
|
||||||
|
|
||||||
# Flags to generate dependency information.
|
# Flags to generate dependency information.
|
||||||
CFLAGS += -MD -MP -MT $@
|
CFLAGS += -MD -MP -MT $@
|
||||||
|
@ -75,26 +75,15 @@ app_exe = $(OUTPUT_DIR)/$(1)_$(ARCH)_$(BUILD)
|
||||||
objs_from_src = $(patsubst $(SRC_ROOT)/%, $(BUILD_DIR)/%.o, $(basename $(1)))
|
objs_from_src = $(patsubst $(SRC_ROOT)/%, $(BUILD_DIR)/%.o, $(basename $(1)))
|
||||||
objs_from_src_in = $(call objs_from_src, $(shell find $(1) -name "*.cc" -o -name "*.cpp" -o -name "*.c"))
|
objs_from_src_in = $(call objs_from_src, $(shell find $(1) -name "*.cc" -o -name "*.cpp" -o -name "*.c"))
|
||||||
|
|
||||||
# --- Base ---
|
# --- Engine ---
|
||||||
|
|
||||||
BASE_SRC := \
|
ENGINE_SRC := \
|
||||||
$(SRC_ROOT)/base/collusion_test.cc \
|
$(SRC_ROOT)/base/collusion_test.cc \
|
||||||
$(SRC_ROOT)/base/log.cc \
|
$(SRC_ROOT)/base/log.cc \
|
||||||
$(SRC_ROOT)/base/sinc_resampler.cc \
|
$(SRC_ROOT)/base/sinc_resampler.cc \
|
||||||
$(SRC_ROOT)/base/task_runner.cc \
|
$(SRC_ROOT)/base/task_runner.cc \
|
||||||
$(SRC_ROOT)/base/thread_pool.cc \
|
$(SRC_ROOT)/base/thread_pool.cc \
|
||||||
$(SRC_ROOT)/base/timer.cc
|
$(SRC_ROOT)/base/timer.cc \
|
||||||
|
|
||||||
BASE_LIB := $(BUILD_DIR)/libengine.a
|
|
||||||
BASE_OBJS := $(call objs_from_src, $(BASE_SRC))
|
|
||||||
LIBS += $(BASE_LIB)
|
|
||||||
OBJS += $(BASE_OBJS)
|
|
||||||
|
|
||||||
$(BASE_LIB): $(BASE_OBJS)
|
|
||||||
|
|
||||||
# --- Engine ---
|
|
||||||
|
|
||||||
ENGINE_SRC := \
|
|
||||||
$(SRC_ROOT)/engine/animatable.cc \
|
$(SRC_ROOT)/engine/animatable.cc \
|
||||||
$(SRC_ROOT)/engine/animator.cc \
|
$(SRC_ROOT)/engine/animator.cc \
|
||||||
$(SRC_ROOT)/engine/audio/audio_alsa.cc \
|
$(SRC_ROOT)/engine/audio/audio_alsa.cc \
|
||||||
|
@ -124,25 +113,7 @@ ENGINE_SRC := \
|
||||||
$(SRC_ROOT)/engine/shader_source.cc \
|
$(SRC_ROOT)/engine/shader_source.cc \
|
||||||
$(SRC_ROOT)/engine/solid_quad.cc \
|
$(SRC_ROOT)/engine/solid_quad.cc \
|
||||||
$(SRC_ROOT)/engine/sound_player.cc \
|
$(SRC_ROOT)/engine/sound_player.cc \
|
||||||
$(SRC_ROOT)/engine/sound.cc
|
$(SRC_ROOT)/engine/sound.cc \
|
||||||
|
|
||||||
ENGINE_LIB := $(BUILD_DIR)/libengine.a
|
|
||||||
ENGINE_OBJS := $(call objs_from_src, $(ENGINE_SRC))
|
|
||||||
LIBS += $(ENGINE_LIB)
|
|
||||||
OBJS += $(ENGINE_OBJS)
|
|
||||||
|
|
||||||
$(ENGINE_LIB): $(ENGINE_OBJS)
|
|
||||||
|
|
||||||
# --- Third-party ---
|
|
||||||
|
|
||||||
# Ignore warnings.
|
|
||||||
THIRD_PARTY_CFLAGS = $(CFLAGS)
|
|
||||||
THIRD_PARTY_CFLAGS := $(filter-out -Wextra -Werror, $(THIRD_PARTY_CFLAGS))
|
|
||||||
|
|
||||||
THIRD_PARTY_CXXFLAGS = $(CXXFLAGS)
|
|
||||||
THIRD_PARTY_CXXFLAGS := $(filter-out -Wextra -Werror, $(THIRD_PARTY_CXXFLAGS))
|
|
||||||
|
|
||||||
THIRD_PARTY_SRC := \
|
|
||||||
$(SRC_ROOT)/third_party/glew/glew.c \
|
$(SRC_ROOT)/third_party/glew/glew.c \
|
||||||
$(SRC_ROOT)/third_party/glslang/glslang/CInterface/glslang_c_interface.cpp \
|
$(SRC_ROOT)/third_party/glslang/glslang/CInterface/glslang_c_interface.cpp \
|
||||||
$(SRC_ROOT)/third_party/glslang/glslang/GenericCodeGen/CodeGen.cpp \
|
$(SRC_ROOT)/third_party/glslang/glslang/GenericCodeGen/CodeGen.cpp \
|
||||||
|
@ -189,7 +160,6 @@ THIRD_PARTY_SRC := \
|
||||||
$(SRC_ROOT)/third_party/glslang/StandAlone/ResourceLimits.cpp \
|
$(SRC_ROOT)/third_party/glslang/StandAlone/ResourceLimits.cpp \
|
||||||
$(SRC_ROOT)/third_party/jsoncpp/jsoncpp.cpp \
|
$(SRC_ROOT)/third_party/jsoncpp/jsoncpp.cpp \
|
||||||
$(SRC_ROOT)/third_party/spirv-reflect/spirv_reflect.c \
|
$(SRC_ROOT)/third_party/spirv-reflect/spirv_reflect.c \
|
||||||
$(SRC_ROOT)/third_party/stb/stb_image.c \
|
|
||||||
$(SRC_ROOT)/third_party/texture_compressor/dxt_encoder_internals.cc \
|
$(SRC_ROOT)/third_party/texture_compressor/dxt_encoder_internals.cc \
|
||||||
$(SRC_ROOT)/third_party/texture_compressor/dxt_encoder.cc \
|
$(SRC_ROOT)/third_party/texture_compressor/dxt_encoder.cc \
|
||||||
$(SRC_ROOT)/third_party/texture_compressor/texture_compressor_etc1.cc \
|
$(SRC_ROOT)/third_party/texture_compressor/texture_compressor_etc1.cc \
|
||||||
|
@ -206,24 +176,12 @@ THIRD_PARTY_SRC := \
|
||||||
$(SRC_ROOT)/third_party/vulkan/loader/unknown_ext_chain.c \
|
$(SRC_ROOT)/third_party/vulkan/loader/unknown_ext_chain.c \
|
||||||
$(SRC_ROOT)/third_party/vulkan/loader/wsi.c
|
$(SRC_ROOT)/third_party/vulkan/loader/wsi.c
|
||||||
|
|
||||||
$(BUILD_DIR)/third_party/%.o: $(SRC_ROOT)/third_party/%.c
|
ENGINE_LIB := $(BUILD_DIR)/libengine.a
|
||||||
@mkdir -p $(@D)
|
ENGINE_OBJS := $(call objs_from_src, $(ENGINE_SRC))
|
||||||
$(HUSH_COMPILE) $(CC) -c $(THIRD_PARTY_CFLAGS) -o $@ $<
|
LIBS += $(ENGINE_LIB)
|
||||||
|
OBJS += $(ENGINE_OBJS)
|
||||||
|
|
||||||
$(BUILD_DIR)/third_party/%.o: $(SRC_ROOT)/third_party/%.cc
|
$(ENGINE_LIB): $(ENGINE_OBJS)
|
||||||
@mkdir -p $(@D)
|
|
||||||
$(HUSH_COMPILE) $(CXX) -c $(THIRD_PARTY_CXXFLAGS) -o $@ $<
|
|
||||||
|
|
||||||
$(BUILD_DIR)/third_party/%.o: $(SRC_ROOT)/third_party/%.cpp
|
|
||||||
@mkdir -p $(@D)
|
|
||||||
$(HUSH_COMPILE) $(CXX) -c $(THIRD_PARTY_CXXFLAGS) -o $@ $<
|
|
||||||
|
|
||||||
THIRD_PARTY_LIB := $(BUILD_DIR)/libthirdparty.a
|
|
||||||
THIRD_PARTY_OBJS := $(call objs_from_src, $(THIRD_PARTY_SRC))
|
|
||||||
LIBS += $(THIRD_PARTY_LIB)
|
|
||||||
OBJS += $(THIRD_PARTY_OBJS)
|
|
||||||
|
|
||||||
$(THIRD_PARTY_LIB): $(THIRD_PARTY_OBJS)
|
|
||||||
|
|
||||||
# --- demo application ---
|
# --- demo application ---
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
source_set("base") {
|
||||||
|
sources = [
|
||||||
|
"closure.h",
|
||||||
|
"collusion_test.cc",
|
||||||
|
"collusion_test.h",
|
||||||
|
"file.h",
|
||||||
|
"hash.h",
|
||||||
|
"interpolation.h",
|
||||||
|
"log.cc",
|
||||||
|
"log.h",
|
||||||
|
"mem.h",
|
||||||
|
"misc.h",
|
||||||
|
"random.h",
|
||||||
|
"sinc_resampler.cc",
|
||||||
|
"sinc_resampler.h",
|
||||||
|
"task_runner.cc",
|
||||||
|
"task_runner.h",
|
||||||
|
"thread_pool.cc",
|
||||||
|
"thread_pool.h",
|
||||||
|
"timer.cc",
|
||||||
|
"timer.h",
|
||||||
|
"vecmath.h",
|
||||||
|
]
|
||||||
|
|
||||||
|
# ldflags = []
|
||||||
|
# libs = []
|
||||||
|
|
||||||
|
if (target_os == "linux") {
|
||||||
|
# ldflags += [ "-L/usr/X11R6/lib" ]
|
||||||
|
|
||||||
|
# libs += [ "X11", "rt", "pthread" ]
|
||||||
|
}
|
||||||
|
|
||||||
|
deps = []
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
#ifndef BASE_SEMAPHORE_H
|
||||||
|
#define BASE_SEMAPHORE_H
|
||||||
|
|
||||||
|
#include <condition_variable>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
|
#include "base/log.h"
|
||||||
|
|
||||||
|
namespace base {
|
||||||
|
|
||||||
|
class Semaphore {
|
||||||
|
public:
|
||||||
|
Semaphore(int count = 0) : count_(count) {}
|
||||||
|
|
||||||
|
void Acquire() {
|
||||||
|
std::unique_lock<std::mutex> scoped_lock(mutex_);
|
||||||
|
cv_.wait(scoped_lock, [&]() { return count_ > 0; });
|
||||||
|
--count_;
|
||||||
|
DCHECK(count_ >= 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Release() {
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> scoped_lock(mutex_);
|
||||||
|
++count_;
|
||||||
|
}
|
||||||
|
cv_.notify_one();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::condition_variable cv_;
|
||||||
|
std::mutex mutex_;
|
||||||
|
int count_ = 0;
|
||||||
|
|
||||||
|
Semaphore(Semaphore const&) = delete;
|
||||||
|
Semaphore& operator=(Semaphore const&) = delete;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace base
|
||||||
|
|
||||||
|
#endif // BASE_SEMAPHORE_H
|
|
@ -11,7 +11,7 @@
|
||||||
// <--------------------------------------------------------->
|
// <--------------------------------------------------------->
|
||||||
// r0_ (during first load)
|
// r0_ (during first load)
|
||||||
//
|
//
|
||||||
// kernel_size_ / 2 kernel_size_ / 2 kernel_size_ / 2 kernel_size_ / 2
|
// kKernelSize / 2 kKernelSize / 2 kKernelSize / 2 kKernelSize / 2
|
||||||
// <---------------> <---------------> <---------------> <--------------->
|
// <---------------> <---------------> <---------------> <--------------->
|
||||||
// r1_ r2_ r3_ r4_
|
// r1_ r2_ r3_ r4_
|
||||||
//
|
//
|
||||||
|
@ -22,8 +22,8 @@
|
||||||
// <------------------ ... ----------------->
|
// <------------------ ... ----------------->
|
||||||
// r0_ (during second load)
|
// r0_ (during second load)
|
||||||
//
|
//
|
||||||
// On the second request r0_ slides to the right by kernel_size_ / 2 and r3_,
|
// On the second request r0_ slides to the right by kKernelSize / 2 and r3_, r4_
|
||||||
// r4_ and block_size_ are reinitialized via step (3) in the algorithm below.
|
// and block_size_ are reinitialized via step (3) in the algorithm below.
|
||||||
//
|
//
|
||||||
// These new regions remain constant until a Flush() occurs. While complicated,
|
// These new regions remain constant until a Flush() occurs. While complicated,
|
||||||
// this allows us to reduce jitter by always requesting the same amount from the
|
// this allows us to reduce jitter by always requesting the same amount from the
|
||||||
|
@ -31,27 +31,26 @@
|
||||||
//
|
//
|
||||||
// The algorithm:
|
// The algorithm:
|
||||||
//
|
//
|
||||||
// 1) Allocate input_buffer of size: request_frames_ + kernel_size_; this
|
// 1) Allocate input_buffer of size: request_frames_ + kKernelSize; this ensures
|
||||||
// ensures
|
|
||||||
// there's enough room to read request_frames_ from the callback into region
|
// there's enough room to read request_frames_ from the callback into region
|
||||||
// r0_ (which will move between the first and subsequent passes).
|
// r0_ (which will move between the first and subsequent passes).
|
||||||
//
|
//
|
||||||
// 2) Let r1_, r2_ each represent half the kernel centered around r0_:
|
// 2) Let r1_, r2_ each represent half the kernel centered around r0_:
|
||||||
//
|
//
|
||||||
// r0_ = input_buffer_ + kernel_size_ / 2
|
// r0_ = input_buffer_ + kKernelSize / 2
|
||||||
// r1_ = input_buffer_
|
// r1_ = input_buffer_
|
||||||
// r2_ = r0_
|
// r2_ = r0_
|
||||||
//
|
//
|
||||||
// r0_ is always request_frames_ in size. r1_, r2_ are kernel_size_ / 2 in
|
// r0_ is always request_frames_ in size. r1_, r2_ are kKernelSize / 2 in
|
||||||
// size. r1_ must be zero initialized to avoid convolution with garbage (see
|
// size. r1_ must be zero initialized to avoid convolution with garbage (see
|
||||||
// step (5) for why).
|
// step (5) for why).
|
||||||
//
|
//
|
||||||
// 3) Let r3_, r4_ each represent half the kernel right aligned with the end of
|
// 3) Let r3_, r4_ each represent half the kernel right aligned with the end of
|
||||||
// r0_ and choose block_size_ as the distance in frames between r4_ and r2_:
|
// r0_ and choose block_size_ as the distance in frames between r4_ and r2_:
|
||||||
//
|
//
|
||||||
// r3_ = r0_ + request_frames_ - kernel_size_
|
// r3_ = r0_ + request_frames_ - kKernelSize
|
||||||
// r4_ = r0_ + request_frames_ - kernel_size_ / 2
|
// r4_ = r0_ + request_frames_ - kKernelSize / 2
|
||||||
// block_size_ = r4_ - r2_ = request_frames_ - kernel_size_ / 2
|
// block_size_ = r4_ - r2_ = request_frames_ - kKernelSize / 2
|
||||||
//
|
//
|
||||||
// 4) Consume request_frames_ frames into r0_.
|
// 4) Consume request_frames_ frames into r0_.
|
||||||
//
|
//
|
||||||
|
@ -63,9 +62,9 @@
|
||||||
//
|
//
|
||||||
// 7) If we're on the second load, in order to avoid overwriting the frames we
|
// 7) If we're on the second load, in order to avoid overwriting the frames we
|
||||||
// just wrapped from r4_ we need to slide r0_ to the right by the size of
|
// just wrapped from r4_ we need to slide r0_ to the right by the size of
|
||||||
// r4_, which is kernel_size_ / 2:
|
// r4_, which is kKernelSize / 2:
|
||||||
//
|
//
|
||||||
// r0_ = r0_ + kernel_size_ / 2 = input_buffer_ + kernel_size_
|
// r0_ = r0_ + kKernelSize / 2 = input_buffer_ + kKernelSize
|
||||||
//
|
//
|
||||||
// r3_, r4_, and block_size_ then need to be reinitialized, so goto (3).
|
// r3_, r4_, and block_size_ then need to be reinitialized, so goto (3).
|
||||||
//
|
//
|
||||||
|
@ -128,9 +127,7 @@ class ScopedSubnormalFloatDisabler {
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace
|
double SincScaleFactor(double io_ratio) {
|
||||||
|
|
||||||
static double SincScaleFactor(double io_ratio, int kernel_size) {
|
|
||||||
// |sinc_scale_factor| is basically the normalized cutoff frequency of the
|
// |sinc_scale_factor| is basically the normalized cutoff frequency of the
|
||||||
// low-pass filter.
|
// low-pass filter.
|
||||||
double sinc_scale_factor = io_ratio > 1.0 ? 1.0 / io_ratio : 1.0;
|
double sinc_scale_factor = io_ratio > 1.0 ? 1.0 / io_ratio : 1.0;
|
||||||
|
@ -139,17 +136,19 @@ static double SincScaleFactor(double io_ratio, int kernel_size) {
|
||||||
// windowing it the transition from pass to stop does not happen right away.
|
// windowing it the transition from pass to stop does not happen right away.
|
||||||
// So we should adjust the low pass filter cutoff slightly downward to avoid
|
// So we should adjust the low pass filter cutoff slightly downward to avoid
|
||||||
// some aliasing at the very high-end.
|
// some aliasing at the very high-end.
|
||||||
// Note: these values are derived empirically.
|
// TODO(crogers): this value is empirical and to be more exact should vary
|
||||||
if (kernel_size == SincResampler::kMaxKernelSize) {
|
// depending on kKernelSize.
|
||||||
sinc_scale_factor *= 0.92;
|
sinc_scale_factor *= 0.9;
|
||||||
} else {
|
|
||||||
DCHECK(kernel_size == SincResampler::kMinKernelSize);
|
|
||||||
sinc_scale_factor *= 0.90;
|
|
||||||
}
|
|
||||||
|
|
||||||
return sinc_scale_factor;
|
return sinc_scale_factor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int CalculateChunkSize(int block_size_, double io_ratio) {
|
||||||
|
return block_size_ / io_ratio;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
// If we know the minimum architecture at compile time, avoid CPU detection.
|
// If we know the minimum architecture at compile time, avoid CPU detection.
|
||||||
void SincResampler::InitializeCPUSpecificFeatures() {
|
void SincResampler::InitializeCPUSpecificFeatures() {
|
||||||
#if defined(_M_ARM64) || defined(__aarch64__)
|
#if defined(_M_ARM64) || defined(__aarch64__)
|
||||||
|
@ -171,39 +170,26 @@ void SincResampler::InitializeCPUSpecificFeatures() {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static int CalculateChunkSize(int block_size_, double io_ratio) {
|
|
||||||
return block_size_ / io_ratio;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Static
|
|
||||||
int SincResampler::KernelSizeFromRequestFrames(int request_frames) {
|
|
||||||
// We want the kernel size to *more* than 1.5 * `request_frames`.
|
|
||||||
constexpr int kSmallKernelLimit = kMaxKernelSize * 3 / 2;
|
|
||||||
return request_frames <= kSmallKernelLimit ? kMinKernelSize : kMaxKernelSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
SincResampler::SincResampler(double io_sample_rate_ratio, int request_frames)
|
SincResampler::SincResampler(double io_sample_rate_ratio, int request_frames)
|
||||||
: kernel_size_(KernelSizeFromRequestFrames(request_frames)),
|
: io_sample_rate_ratio_(io_sample_rate_ratio),
|
||||||
kernel_storage_size_(kernel_size_ * (kKernelOffsetCount + 1)),
|
|
||||||
io_sample_rate_ratio_(io_sample_rate_ratio),
|
|
||||||
request_frames_(request_frames),
|
request_frames_(request_frames),
|
||||||
input_buffer_size_(request_frames_ + kernel_size_),
|
input_buffer_size_(request_frames_ + kKernelSize),
|
||||||
// Create input buffers with a 32-byte alignment for SIMD optimizations.
|
// Create input buffers with a 32-byte alignment for SIMD optimizations.
|
||||||
kernel_storage_(static_cast<float*>(
|
kernel_storage_(static_cast<float*>(
|
||||||
base::AlignedAlloc<32>(sizeof(float) * kernel_storage_size_))),
|
base::AlignedAlloc<32>(sizeof(float) * kKernelStorageSize))),
|
||||||
kernel_pre_sinc_storage_(static_cast<float*>(
|
kernel_pre_sinc_storage_(static_cast<float*>(
|
||||||
base::AlignedAlloc<32>(sizeof(float) * kernel_storage_size_))),
|
base::AlignedAlloc<32>(sizeof(float) * kKernelStorageSize))),
|
||||||
kernel_window_storage_(static_cast<float*>(
|
kernel_window_storage_(static_cast<float*>(
|
||||||
base::AlignedAlloc<32>(sizeof(float) * kernel_storage_size_))),
|
base::AlignedAlloc<32>(sizeof(float) * kKernelStorageSize))),
|
||||||
input_buffer_(static_cast<float*>(
|
input_buffer_(static_cast<float*>(
|
||||||
base::AlignedAlloc<32>(sizeof(float) * input_buffer_size_))),
|
base::AlignedAlloc<32>(sizeof(float) * input_buffer_size_))),
|
||||||
r1_(input_buffer_.get()),
|
r1_(input_buffer_.get()),
|
||||||
r2_(input_buffer_.get() + kernel_size_ / 2) {
|
r2_(input_buffer_.get() + kKernelSize / 2) {
|
||||||
CHECK(request_frames > kernel_size_ * 3 / 2)
|
CHECK(request_frames > kKernelSize * 3 / 2)
|
||||||
<< "request_frames must be greater than 1.5 kernels to allow sufficient "
|
<< "request_frames must be greater than 1.5 kernels to allow sufficient "
|
||||||
"data for resampling";
|
"data for resampling";
|
||||||
// This means that after the first call to Flush we will have
|
// This means that after the first call to Flush we will have
|
||||||
// block_size_ > kernel_size_ and r2_ < r3_.
|
// block_size_ > kKernelSize and r2_ < r3_.
|
||||||
|
|
||||||
InitializeCPUSpecificFeatures();
|
InitializeCPUSpecificFeatures();
|
||||||
DCHECK(convolve_proc_);
|
DCHECK(convolve_proc_);
|
||||||
|
@ -211,11 +197,11 @@ SincResampler::SincResampler(double io_sample_rate_ratio, int request_frames)
|
||||||
Flush();
|
Flush();
|
||||||
|
|
||||||
memset(kernel_storage_.get(), 0,
|
memset(kernel_storage_.get(), 0,
|
||||||
sizeof(*kernel_storage_.get()) * kernel_storage_size_);
|
sizeof(*kernel_storage_.get()) * kKernelStorageSize);
|
||||||
memset(kernel_pre_sinc_storage_.get(), 0,
|
memset(kernel_pre_sinc_storage_.get(), 0,
|
||||||
sizeof(*kernel_pre_sinc_storage_.get()) * kernel_storage_size_);
|
sizeof(*kernel_pre_sinc_storage_.get()) * kKernelStorageSize);
|
||||||
memset(kernel_window_storage_.get(), 0,
|
memset(kernel_window_storage_.get(), 0,
|
||||||
sizeof(*kernel_window_storage_.get()) * kernel_storage_size_);
|
sizeof(*kernel_window_storage_.get()) * kKernelStorageSize);
|
||||||
|
|
||||||
InitializeKernel();
|
InitializeKernel();
|
||||||
}
|
}
|
||||||
|
@ -224,10 +210,10 @@ SincResampler::~SincResampler() = default;
|
||||||
|
|
||||||
void SincResampler::UpdateRegions(bool second_load) {
|
void SincResampler::UpdateRegions(bool second_load) {
|
||||||
// Setup various region pointers in the buffer (see diagram above). If we're
|
// Setup various region pointers in the buffer (see diagram above). If we're
|
||||||
// on the second load we need to slide r0_ to the right by kernel_size_ / 2.
|
// on the second load we need to slide r0_ to the right by kKernelSize / 2.
|
||||||
r0_ = input_buffer_.get() + (second_load ? kernel_size_ : kernel_size_ / 2);
|
r0_ = input_buffer_.get() + (second_load ? kKernelSize : kKernelSize / 2);
|
||||||
r3_ = r0_ + request_frames_ - kernel_size_;
|
r3_ = r0_ + request_frames_ - kKernelSize;
|
||||||
r4_ = r0_ + request_frames_ - kernel_size_ / 2;
|
r4_ = r0_ + request_frames_ - kKernelSize / 2;
|
||||||
block_size_ = r4_ - r2_;
|
block_size_ = r4_ - r2_;
|
||||||
chunk_size_ = CalculateChunkSize(block_size_, io_sample_rate_ratio_);
|
chunk_size_ = CalculateChunkSize(block_size_, io_sample_rate_ratio_);
|
||||||
|
|
||||||
|
@ -248,20 +234,19 @@ void SincResampler::InitializeKernel() {
|
||||||
|
|
||||||
// Generates a set of windowed sinc() kernels.
|
// Generates a set of windowed sinc() kernels.
|
||||||
// We generate a range of sub-sample offsets from 0.0 to 1.0.
|
// We generate a range of sub-sample offsets from 0.0 to 1.0.
|
||||||
const double sinc_scale_factor =
|
const double sinc_scale_factor = SincScaleFactor(io_sample_rate_ratio_);
|
||||||
SincScaleFactor(io_sample_rate_ratio_, kernel_size_);
|
|
||||||
for (int offset_idx = 0; offset_idx <= kKernelOffsetCount; ++offset_idx) {
|
for (int offset_idx = 0; offset_idx <= kKernelOffsetCount; ++offset_idx) {
|
||||||
const float subsample_offset =
|
const float subsample_offset =
|
||||||
static_cast<float>(offset_idx) / kKernelOffsetCount;
|
static_cast<float>(offset_idx) / kKernelOffsetCount;
|
||||||
|
|
||||||
for (int i = 0; i < kernel_size_; ++i) {
|
for (int i = 0; i < kKernelSize; ++i) {
|
||||||
const int idx = i + offset_idx * kernel_size_;
|
const int idx = i + offset_idx * kKernelSize;
|
||||||
const float pre_sinc =
|
const float pre_sinc =
|
||||||
base::kPiFloat * (i - kernel_size_ / 2 - subsample_offset);
|
base::kPiFloat * (i - kKernelSize / 2 - subsample_offset);
|
||||||
kernel_pre_sinc_storage_[idx] = pre_sinc;
|
kernel_pre_sinc_storage_[idx] = pre_sinc;
|
||||||
|
|
||||||
// Compute Blackman window, matching the offset of the sinc().
|
// Compute Blackman window, matching the offset of the sinc().
|
||||||
const float x = (i - subsample_offset) / kernel_size_;
|
const float x = (i - subsample_offset) / kKernelSize;
|
||||||
const float window =
|
const float window =
|
||||||
static_cast<float>(kA0 - kA1 * cos(2.0 * base::kPiDouble * x) +
|
static_cast<float>(kA0 - kA1 * cos(2.0 * base::kPiDouble * x) +
|
||||||
kA2 * cos(4.0 * base::kPiDouble * x));
|
kA2 * cos(4.0 * base::kPiDouble * x));
|
||||||
|
@ -287,11 +272,10 @@ void SincResampler::SetRatio(double io_sample_rate_ratio) {
|
||||||
|
|
||||||
// Optimize reinitialization by reusing values which are independent of
|
// Optimize reinitialization by reusing values which are independent of
|
||||||
// |sinc_scale_factor|. Provides a 3x speedup.
|
// |sinc_scale_factor|. Provides a 3x speedup.
|
||||||
const double sinc_scale_factor =
|
const double sinc_scale_factor = SincScaleFactor(io_sample_rate_ratio_);
|
||||||
SincScaleFactor(io_sample_rate_ratio_, kernel_size_);
|
|
||||||
for (int offset_idx = 0; offset_idx <= kKernelOffsetCount; ++offset_idx) {
|
for (int offset_idx = 0; offset_idx <= kKernelOffsetCount; ++offset_idx) {
|
||||||
for (int i = 0; i < kernel_size_; ++i) {
|
for (int i = 0; i < kKernelSize; ++i) {
|
||||||
const int idx = i + offset_idx * kernel_size_;
|
const int idx = i + offset_idx * kKernelSize;
|
||||||
const float window = kernel_window_storage_[idx];
|
const float window = kernel_window_storage_[idx];
|
||||||
const float pre_sinc = kernel_pre_sinc_storage_[idx];
|
const float pre_sinc = kernel_pre_sinc_storage_[idx];
|
||||||
|
|
||||||
|
@ -328,13 +312,13 @@ void SincResampler::Resample(int frames, float* destination, ReadCB read_cb) {
|
||||||
|
|
||||||
// We'll compute "convolutions" for the two kernels which straddle
|
// We'll compute "convolutions" for the two kernels which straddle
|
||||||
// |virtual_source_idx_|.
|
// |virtual_source_idx_|.
|
||||||
const float* k1 = kernel_storage_.get() + offset_idx * kernel_size_;
|
const float* k1 = kernel_storage_.get() + offset_idx * kKernelSize;
|
||||||
const float* k2 = k1 + kernel_size_;
|
const float* k2 = k1 + kKernelSize;
|
||||||
|
|
||||||
// Ensure |k1|, |k2| are 32-byte aligned for SIMD usage. Should always
|
// Ensure |k1|, |k2| are 32-byte aligned for SIMD usage. Should always
|
||||||
// be true so long as kKernelSize is a multiple of 32.
|
// be true so long as kKernelSize is a multiple of 32.
|
||||||
DCHECK(0u == (reinterpret_cast<uintptr_t>(k1) & 0x1F));
|
DCHECK(0u == reinterpret_cast<uintptr_t>(k1) & 0x1F);
|
||||||
DCHECK(0u == (reinterpret_cast<uintptr_t>(k2) & 0x1F));
|
DCHECK(0u == reinterpret_cast<uintptr_t>(k2) & 0x1F);
|
||||||
|
|
||||||
// Initialize input pointer based on quantized |virtual_source_idx_|.
|
// Initialize input pointer based on quantized |virtual_source_idx_|.
|
||||||
const float* input_ptr = r1_ + source_idx;
|
const float* input_ptr = r1_ + source_idx;
|
||||||
|
@ -342,16 +326,15 @@ void SincResampler::Resample(int frames, float* destination, ReadCB read_cb) {
|
||||||
// Figure out how much to weight each kernel's "convolution".
|
// Figure out how much to weight each kernel's "convolution".
|
||||||
const double kernel_interpolation_factor =
|
const double kernel_interpolation_factor =
|
||||||
virtual_offset_idx - offset_idx;
|
virtual_offset_idx - offset_idx;
|
||||||
*destination++ = convolve_proc_(kernel_size_, input_ptr, k1, k2,
|
*destination++ =
|
||||||
kernel_interpolation_factor);
|
convolve_proc_(input_ptr, k1, k2, kernel_interpolation_factor);
|
||||||
|
|
||||||
// Advance the virtual index.
|
// Advance the virtual index.
|
||||||
virtual_source_idx_ += io_sample_rate_ratio_;
|
virtual_source_idx_ += io_sample_rate_ratio_;
|
||||||
if (!--remaining_frames) {
|
if (!--remaining_frames)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Wrap back around to the start.
|
// Wrap back around to the start.
|
||||||
DCHECK(virtual_source_idx_ > block_size_);
|
DCHECK(virtual_source_idx_ > block_size_);
|
||||||
|
@ -359,12 +342,11 @@ void SincResampler::Resample(int frames, float* destination, ReadCB read_cb) {
|
||||||
|
|
||||||
// Step (3) -- Copy r3_, r4_ to r1_, r2_.
|
// Step (3) -- Copy r3_, r4_ to r1_, r2_.
|
||||||
// This wraps the last input frames back to the start of the buffer.
|
// This wraps the last input frames back to the start of the buffer.
|
||||||
memcpy(r1_, r3_, sizeof(*input_buffer_.get()) * kernel_size_);
|
memcpy(r1_, r3_, sizeof(*input_buffer_.get()) * kKernelSize);
|
||||||
|
|
||||||
// Step (4) -- Reinitialize regions if necessary.
|
// Step (4) -- Reinitialize regions if necessary.
|
||||||
if (r0_ == r2_) {
|
if (r0_ == r2_)
|
||||||
UpdateRegions(true);
|
UpdateRegions(true);
|
||||||
}
|
|
||||||
|
|
||||||
// Step (5) -- Refresh the buffer with more input.
|
// Step (5) -- Refresh the buffer with more input.
|
||||||
read_cb(request_frames_, r0_);
|
read_cb(request_frames_, r0_);
|
||||||
|
@ -399,12 +381,7 @@ double SincResampler::BufferedFrames() const {
|
||||||
return buffer_primed_ ? request_frames_ - virtual_source_idx_ : 0;
|
return buffer_primed_ ? request_frames_ - virtual_source_idx_ : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SincResampler::KernelSize() const {
|
float SincResampler::Convolve_C(const float* input_ptr,
|
||||||
return kernel_size_;
|
|
||||||
}
|
|
||||||
|
|
||||||
float SincResampler::Convolve_C(const int kernel_size,
|
|
||||||
const float* input_ptr,
|
|
||||||
const float* k1,
|
const float* k1,
|
||||||
const float* k2,
|
const float* k2,
|
||||||
double kernel_interpolation_factor) {
|
double kernel_interpolation_factor) {
|
||||||
|
@ -413,7 +390,7 @@ float SincResampler::Convolve_C(const int kernel_size,
|
||||||
|
|
||||||
// Generate a single output sample. Unrolling this loop hurt performance in
|
// Generate a single output sample. Unrolling this loop hurt performance in
|
||||||
// local testing.
|
// local testing.
|
||||||
int n = kernel_size;
|
int n = kKernelSize;
|
||||||
while (n--) {
|
while (n--) {
|
||||||
sum1 += *input_ptr * *k1++;
|
sum1 += *input_ptr * *k1++;
|
||||||
sum2 += *input_ptr++ * *k2++;
|
sum2 += *input_ptr++ * *k2++;
|
||||||
|
@ -425,8 +402,7 @@ float SincResampler::Convolve_C(const int kernel_size,
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(_M_X64) || defined(__x86_64__) || defined(__i386__)
|
#if defined(_M_X64) || defined(__x86_64__) || defined(__i386__)
|
||||||
float SincResampler::Convolve_SSE(const int kernel_size,
|
float SincResampler::Convolve_SSE(const float* input_ptr,
|
||||||
const float* input_ptr,
|
|
||||||
const float* k1,
|
const float* k1,
|
||||||
const float* k2,
|
const float* k2,
|
||||||
double kernel_interpolation_factor) {
|
double kernel_interpolation_factor) {
|
||||||
|
@ -437,13 +413,13 @@ float SincResampler::Convolve_SSE(const int kernel_size,
|
||||||
// Based on |input_ptr| alignment, we need to use loadu or load. Unrolling
|
// Based on |input_ptr| alignment, we need to use loadu or load. Unrolling
|
||||||
// these loops hurt performance in local testing.
|
// these loops hurt performance in local testing.
|
||||||
if (reinterpret_cast<uintptr_t>(input_ptr) & 0x0F) {
|
if (reinterpret_cast<uintptr_t>(input_ptr) & 0x0F) {
|
||||||
for (int i = 0; i < kernel_size; i += 4) {
|
for (int i = 0; i < kKernelSize; i += 4) {
|
||||||
m_input = _mm_loadu_ps(input_ptr + i);
|
m_input = _mm_loadu_ps(input_ptr + i);
|
||||||
m_sums1 = _mm_add_ps(m_sums1, _mm_mul_ps(m_input, _mm_load_ps(k1 + i)));
|
m_sums1 = _mm_add_ps(m_sums1, _mm_mul_ps(m_input, _mm_load_ps(k1 + i)));
|
||||||
m_sums2 = _mm_add_ps(m_sums2, _mm_mul_ps(m_input, _mm_load_ps(k2 + i)));
|
m_sums2 = _mm_add_ps(m_sums2, _mm_mul_ps(m_input, _mm_load_ps(k2 + i)));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (int i = 0; i < kernel_size; i += 4) {
|
for (int i = 0; i < kKernelSize; i += 4) {
|
||||||
m_input = _mm_load_ps(input_ptr + i);
|
m_input = _mm_load_ps(input_ptr + i);
|
||||||
m_sums1 = _mm_add_ps(m_sums1, _mm_mul_ps(m_input, _mm_load_ps(k1 + i)));
|
m_sums1 = _mm_add_ps(m_sums1, _mm_mul_ps(m_input, _mm_load_ps(k1 + i)));
|
||||||
m_sums2 = _mm_add_ps(m_sums2, _mm_mul_ps(m_input, _mm_load_ps(k2 + i)));
|
m_sums2 = _mm_add_ps(m_sums2, _mm_mul_ps(m_input, _mm_load_ps(k2 + i)));
|
||||||
|
@ -468,7 +444,6 @@ float SincResampler::Convolve_SSE(const int kernel_size,
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((target("avx2,fma"))) float SincResampler::Convolve_AVX2(
|
__attribute__((target("avx2,fma"))) float SincResampler::Convolve_AVX2(
|
||||||
const int kernel_size,
|
|
||||||
const float* input_ptr,
|
const float* input_ptr,
|
||||||
const float* k1,
|
const float* k1,
|
||||||
const float* k2,
|
const float* k2,
|
||||||
|
@ -481,13 +456,13 @@ __attribute__((target("avx2,fma"))) float SincResampler::Convolve_AVX2(
|
||||||
// these loops has not been tested or benchmarked.
|
// these loops has not been tested or benchmarked.
|
||||||
bool aligned_input = (reinterpret_cast<uintptr_t>(input_ptr) & 0x1F) == 0;
|
bool aligned_input = (reinterpret_cast<uintptr_t>(input_ptr) & 0x1F) == 0;
|
||||||
if (!aligned_input) {
|
if (!aligned_input) {
|
||||||
for (size_t i = 0; i < static_cast<size_t>(kernel_size); i += 8) {
|
for (size_t i = 0; i < kKernelSize; i += 8) {
|
||||||
m_input = _mm256_loadu_ps(input_ptr + i);
|
m_input = _mm256_loadu_ps(input_ptr + i);
|
||||||
m_sums1 = _mm256_fmadd_ps(m_input, _mm256_load_ps(k1 + i), m_sums1);
|
m_sums1 = _mm256_fmadd_ps(m_input, _mm256_load_ps(k1 + i), m_sums1);
|
||||||
m_sums2 = _mm256_fmadd_ps(m_input, _mm256_load_ps(k2 + i), m_sums2);
|
m_sums2 = _mm256_fmadd_ps(m_input, _mm256_load_ps(k2 + i), m_sums2);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (size_t i = 0; i < static_cast<size_t>(kernel_size); i += 8) {
|
for (size_t i = 0; i < kKernelSize; i += 8) {
|
||||||
m_input = _mm256_load_ps(input_ptr + i);
|
m_input = _mm256_load_ps(input_ptr + i);
|
||||||
m_sums1 = _mm256_fmadd_ps(m_input, _mm256_load_ps(k1 + i), m_sums1);
|
m_sums1 = _mm256_fmadd_ps(m_input, _mm256_load_ps(k1 + i), m_sums1);
|
||||||
m_sums2 = _mm256_fmadd_ps(m_input, _mm256_load_ps(k2 + i), m_sums2);
|
m_sums2 = _mm256_fmadd_ps(m_input, _mm256_load_ps(k2 + i), m_sums2);
|
||||||
|
@ -515,8 +490,7 @@ __attribute__((target("avx2,fma"))) float SincResampler::Convolve_AVX2(
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
#elif defined(_M_ARM64) || defined(__aarch64__)
|
#elif defined(_M_ARM64) || defined(__aarch64__)
|
||||||
float SincResampler::Convolve_NEON(const int kernel_size,
|
float SincResampler::Convolve_NEON(const float* input_ptr,
|
||||||
const float* input_ptr,
|
|
||||||
const float* k1,
|
const float* k1,
|
||||||
const float* k2,
|
const float* k2,
|
||||||
double kernel_interpolation_factor) {
|
double kernel_interpolation_factor) {
|
||||||
|
@ -524,7 +498,7 @@ float SincResampler::Convolve_NEON(const int kernel_size,
|
||||||
float32x4_t m_sums1 = vmovq_n_f32(0);
|
float32x4_t m_sums1 = vmovq_n_f32(0);
|
||||||
float32x4_t m_sums2 = vmovq_n_f32(0);
|
float32x4_t m_sums2 = vmovq_n_f32(0);
|
||||||
|
|
||||||
const float* upper = input_ptr + kernel_size;
|
const float* upper = input_ptr + kKernelSize;
|
||||||
for (; input_ptr < upper;) {
|
for (; input_ptr < upper;) {
|
||||||
m_input = vld1q_f32(input_ptr);
|
m_input = vld1q_f32(input_ptr);
|
||||||
input_ptr += 4;
|
input_ptr += 4;
|
||||||
|
|
|
@ -16,40 +16,32 @@ namespace base {
|
||||||
class SincResampler {
|
class SincResampler {
|
||||||
public:
|
public:
|
||||||
// The kernel size can be adjusted for quality (higher is better) at the
|
// The kernel size can be adjusted for quality (higher is better) at the
|
||||||
// expense of performance. Must be a multiple of 32. We aim for 64 for
|
// expense of performance. Must be a multiple of 32.
|
||||||
// perceptible audio quality (see crbug.com/1407622), but fallback to 32 in
|
// TODO(dalecurtis): Test performance to see if we can jack this up to 64+.
|
||||||
// cases where `request_frames_` is too small (e.g. 10ms of 8kHz audio).
|
static constexpr int kKernelSize = 32;
|
||||||
// Use SincResampler::KernelSize() to check which size is being used.
|
|
||||||
static constexpr int kMaxKernelSize = 64;
|
|
||||||
static constexpr int kMinKernelSize = 32;
|
|
||||||
|
|
||||||
// Default request size. Affects how often and for how much SincResampler
|
// Default request size. Affects how often and for how much SincResampler
|
||||||
// calls back for input. Must be greater than 1.5 * `kernel_size_`.
|
// calls back for input. Must be greater than kKernelSize.
|
||||||
static constexpr int kDefaultRequestSize = 512;
|
static constexpr int kDefaultRequestSize = 512;
|
||||||
|
|
||||||
// A smaller request size, which still allows higher quality resampling, by
|
|
||||||
// guaranteeing we will use kMaxKernelSize.
|
|
||||||
static constexpr int kSmallRequestSize = kMaxKernelSize * 2;
|
|
||||||
|
|
||||||
// The kernel offset count is used for interpolation and is the number of
|
// The kernel offset count is used for interpolation and is the number of
|
||||||
// sub-sample kernel shifts. Can be adjusted for quality (higher is better)
|
// sub-sample kernel shifts. Can be adjusted for quality (higher is better)
|
||||||
// at the expense of allocating more memory.
|
// at the expense of allocating more memory.
|
||||||
static constexpr int kKernelOffsetCount = 32;
|
static constexpr int kKernelOffsetCount = 32;
|
||||||
|
static constexpr int kKernelStorageSize =
|
||||||
|
kKernelSize * (kKernelOffsetCount + 1);
|
||||||
|
|
||||||
// Callback type for providing more data into the resampler. Expects |frames|
|
// Callback type for providing more data into the resampler. Expects |frames|
|
||||||
// of data to be rendered into |destination|; zero padded if not enough frames
|
// of data to be rendered into |destination|; zero padded if not enough frames
|
||||||
// are available to satisfy the request.
|
// are available to satisfy the request.
|
||||||
typedef std::function<void(int frames, float* destination)> ReadCB;
|
typedef std::function<void(int frames, float* destination)> ReadCB;
|
||||||
|
|
||||||
// Returns the kernel size which will be used for a given `request_frames`.
|
|
||||||
static int KernelSizeFromRequestFrames(int request_frames);
|
|
||||||
|
|
||||||
// Constructs a SincResampler with the specified |read_cb|, which is used to
|
// Constructs a SincResampler with the specified |read_cb|, which is used to
|
||||||
// acquire audio data for resampling. |io_sample_rate_ratio| is the ratio
|
// acquire audio data for resampling. |io_sample_rate_ratio| is the ratio
|
||||||
// of input / output sample rates. |request_frames| controls the size in
|
// of input / output sample rates. |request_frames| controls the size in
|
||||||
// frames of the buffer requested by each |read_cb| call. The value must be
|
// frames of the buffer requested by each |read_cb| call. The value must be
|
||||||
// greater than 1.5*`kernel_size_`. Specify kDefaultRequestSize if there are
|
// greater than 1.5*kKernelSize. Specify kDefaultRequestSize if there are no
|
||||||
// no request size constraints.
|
// request size constraints.
|
||||||
SincResampler(double io_sample_rate_ratio, int request_frames);
|
SincResampler(double io_sample_rate_ratio, int request_frames);
|
||||||
|
|
||||||
SincResampler(const SincResampler&) = delete;
|
SincResampler(const SincResampler&) = delete;
|
||||||
|
@ -60,10 +52,10 @@ class SincResampler {
|
||||||
// Resample |frames| of data from |read_cb_| into |destination|.
|
// Resample |frames| of data from |read_cb_| into |destination|.
|
||||||
void Resample(int frames, float* destination, ReadCB read_cb);
|
void Resample(int frames, float* destination, ReadCB read_cb);
|
||||||
|
|
||||||
// The maximum size in output frames that guarantees Resample() will only make
|
// The maximum size in frames that guarantees Resample() will only make a
|
||||||
// a single call to |read_cb_| for more data. Note: If PrimeWithSilence() is
|
// single call to |read_cb_| for more data. Note: If PrimeWithSilence() is
|
||||||
// not called, chunk size will grow after the first two Resample() calls by
|
// not called, chunk size will grow after the first two Resample() calls by
|
||||||
// `kernel_size_` / (2 * io_sample_rate_ratio). See the .cc file for details.
|
// kKernelSize / (2 * io_sample_rate_ratio). See the .cc file for details.
|
||||||
int ChunkSize() const { return chunk_size_; }
|
int ChunkSize() const { return chunk_size_; }
|
||||||
|
|
||||||
// Returns the max number of frames that could be requested (via multiple
|
// Returns the max number of frames that could be requested (via multiple
|
||||||
|
@ -85,19 +77,13 @@ class SincResampler {
|
||||||
// Resample() is in progress.
|
// Resample() is in progress.
|
||||||
void SetRatio(double io_sample_rate_ratio);
|
void SetRatio(double io_sample_rate_ratio);
|
||||||
|
|
||||||
|
float* get_kernel_for_testing() { return kernel_storage_.get(); }
|
||||||
|
|
||||||
// Return number of input frames consumed by a callback but not yet processed.
|
// Return number of input frames consumed by a callback but not yet processed.
|
||||||
// Since input/output ratio can be fractional, so can this value.
|
// Since input/output ratio can be fractional, so can this value.
|
||||||
// Zero before first call to Resample().
|
// Zero before first call to Resample().
|
||||||
double BufferedFrames() const;
|
double BufferedFrames() const;
|
||||||
|
|
||||||
// Return the actual kernel size used by the resampler. Should be
|
|
||||||
// kMaxKernelSize most of the time, but varies based on `request_frames_`;
|
|
||||||
int KernelSize() const;
|
|
||||||
|
|
||||||
float* get_kernel_for_testing() { return kernel_storage_.get(); }
|
|
||||||
|
|
||||||
int kernel_storage_size_for_testing() { return kernel_storage_size_; }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void InitializeKernel();
|
void InitializeKernel();
|
||||||
void UpdateRegions(bool second_load);
|
void UpdateRegions(bool second_load);
|
||||||
|
@ -106,25 +92,21 @@ class SincResampler {
|
||||||
// linearly interpolated using |kernel_interpolation_factor|. On x86, the
|
// linearly interpolated using |kernel_interpolation_factor|. On x86, the
|
||||||
// underlying implementation is chosen at run time based on SSE support. On
|
// underlying implementation is chosen at run time based on SSE support. On
|
||||||
// ARM, NEON support is chosen at compile time based on compilation flags.
|
// ARM, NEON support is chosen at compile time based on compilation flags.
|
||||||
static float Convolve_C(const int kernel_size,
|
static float Convolve_C(const float* input_ptr,
|
||||||
const float* input_ptr,
|
|
||||||
const float* k1,
|
const float* k1,
|
||||||
const float* k2,
|
const float* k2,
|
||||||
double kernel_interpolation_factor);
|
double kernel_interpolation_factor);
|
||||||
#if defined(_M_X64) || defined(__x86_64__) || defined(__i386__)
|
#if defined(_M_X64) || defined(__x86_64__) || defined(__i386__)
|
||||||
static float Convolve_SSE(const int kernel_size,
|
static float Convolve_SSE(const float* input_ptr,
|
||||||
const float* input_ptr,
|
|
||||||
const float* k1,
|
const float* k1,
|
||||||
const float* k2,
|
const float* k2,
|
||||||
double kernel_interpolation_factor);
|
double kernel_interpolation_factor);
|
||||||
static float Convolve_AVX2(const int kernel_size,
|
static float Convolve_AVX2(const float* input_ptr,
|
||||||
const float* input_ptr,
|
|
||||||
const float* k1,
|
const float* k1,
|
||||||
const float* k2,
|
const float* k2,
|
||||||
double kernel_interpolation_factor);
|
double kernel_interpolation_factor);
|
||||||
#elif defined(_M_ARM64) || defined(__aarch64__)
|
#elif defined(_M_ARM64) || defined(__aarch64__)
|
||||||
static float Convolve_NEON(const int kernel_size,
|
static float Convolve_NEON(const float* input_ptr,
|
||||||
const float* input_ptr,
|
|
||||||
const float* k1,
|
const float* k1,
|
||||||
const float* k2,
|
const float* k2,
|
||||||
double kernel_interpolation_factor);
|
double kernel_interpolation_factor);
|
||||||
|
@ -134,9 +116,6 @@ class SincResampler {
|
||||||
// using SincResampler.
|
// using SincResampler.
|
||||||
void InitializeCPUSpecificFeatures();
|
void InitializeCPUSpecificFeatures();
|
||||||
|
|
||||||
const int kernel_size_;
|
|
||||||
const int kernel_storage_size_;
|
|
||||||
|
|
||||||
// The ratio of input / output sample rates.
|
// The ratio of input / output sample rates.
|
||||||
double io_sample_rate_ratio_;
|
double io_sample_rate_ratio_;
|
||||||
|
|
||||||
|
@ -160,9 +139,9 @@ class SincResampler {
|
||||||
// The size (in samples) of the internal buffer used by the resampler.
|
// The size (in samples) of the internal buffer used by the resampler.
|
||||||
const int input_buffer_size_;
|
const int input_buffer_size_;
|
||||||
|
|
||||||
// Contains kKernelOffsetCount kernels back-to-back, each of size
|
// Contains kKernelOffsetCount kernels back-to-back, each of size kKernelSize.
|
||||||
// `kernel_size_`. The kernel offsets are sub-sample shifts of a windowed sinc
|
// The kernel offsets are sub-sample shifts of a windowed sinc shifted from
|
||||||
// shifted from 0.0 to 1.0 sample.
|
// 0.0 to 1.0 sample.
|
||||||
AlignedMemPtr<float[]> kernel_storage_;
|
AlignedMemPtr<float[]> kernel_storage_;
|
||||||
AlignedMemPtr<float[]> kernel_pre_sinc_storage_;
|
AlignedMemPtr<float[]> kernel_pre_sinc_storage_;
|
||||||
AlignedMemPtr<float[]> kernel_window_storage_;
|
AlignedMemPtr<float[]> kernel_window_storage_;
|
||||||
|
@ -171,8 +150,10 @@ class SincResampler {
|
||||||
AlignedMemPtr<float[]> input_buffer_;
|
AlignedMemPtr<float[]> input_buffer_;
|
||||||
|
|
||||||
// Stores the runtime selection of which Convolve function to use.
|
// Stores the runtime selection of which Convolve function to use.
|
||||||
using ConvolveProc =
|
using ConvolveProc = float (*)(const float*,
|
||||||
float (*)(const int, const float*, const float*, const float*, double);
|
const float*,
|
||||||
|
const float*,
|
||||||
|
double);
|
||||||
ConvolveProc convolve_proc_;
|
ConvolveProc convolve_proc_;
|
||||||
|
|
||||||
// Pointers to the various regions inside |input_buffer_|. See the diagram at
|
// Pointers to the various regions inside |input_buffer_|. See the diagram at
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
#include "base/task_runner.h"
|
#include "base/task_runner.h"
|
||||||
|
|
||||||
#include <thread>
|
|
||||||
|
|
||||||
#include "base/log.h"
|
#include "base/log.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
@ -35,7 +33,7 @@ TaskRunner* TaskRunner::GetThreadLocalTaskRunner() {
|
||||||
void TaskRunner::PostTask(const Location& from, Closure task) {
|
void TaskRunner::PostTask(const Location& from, Closure task) {
|
||||||
DCHECK(task) << LOCATION(from);
|
DCHECK(task) << LOCATION(from);
|
||||||
|
|
||||||
task_count_.fetch_add(1, std::memory_order_release);
|
task_count_.fetch_add(1, std::memory_order_relaxed);
|
||||||
std::lock_guard<std::mutex> scoped_lock(lock_);
|
std::lock_guard<std::mutex> scoped_lock(lock_);
|
||||||
queue_.emplace_back(from, std::move(task));
|
queue_.emplace_back(from, std::move(task));
|
||||||
}
|
}
|
||||||
|
@ -70,7 +68,7 @@ void TaskRunner::MultiConsumerRun() {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
task_cb();
|
task_cb();
|
||||||
task_count_.fetch_sub(1, std::memory_order_release);
|
task_count_.fetch_sub(1, std::memory_order_relaxed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,13 +90,16 @@ void TaskRunner::SingleConsumerRun() {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
task_cb();
|
task_cb();
|
||||||
task_count_.fetch_sub(1, std::memory_order_release);
|
task_count_.fetch_sub(1, std::memory_order_relaxed);
|
||||||
}
|
}
|
||||||
|
cv_.notify_one();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TaskRunner::WaitForCompletion() {
|
void TaskRunner::WaitForCompletion() {
|
||||||
while (task_count_.load(std::memory_order_acquire) > 0)
|
std::unique_lock<std::mutex> scoped_lock(lock_);
|
||||||
std::this_thread::yield();
|
cv_.wait(scoped_lock, [&]() -> bool {
|
||||||
|
return task_count_.load(std::memory_order_relaxed) == 0;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace base
|
} // namespace base
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define BASE_TASK_RUNNER_H
|
#define BASE_TASK_RUNNER_H
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
|
#include <condition_variable>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
@ -73,6 +74,7 @@ class TaskRunner {
|
||||||
|
|
||||||
std::deque<Task> queue_;
|
std::deque<Task> queue_;
|
||||||
mutable std::mutex lock_;
|
mutable std::mutex lock_;
|
||||||
|
std::condition_variable cv_;
|
||||||
std::atomic<size_t> task_count_{0};
|
std::atomic<size_t> task_count_{0};
|
||||||
|
|
||||||
static thread_local std::unique_ptr<TaskRunner> thread_local_task_runner;
|
static thread_local std::unique_ptr<TaskRunner> thread_local_task_runner;
|
||||||
|
|
|
@ -33,7 +33,7 @@ void ThreadPool::Shutdown() {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
quit_.store(true, std::memory_order_relaxed);
|
quit_.store(true, std::memory_order_relaxed);
|
||||||
semaphore_.release(threads_.size());
|
semaphore_.Release();
|
||||||
|
|
||||||
for (auto& thread : threads_)
|
for (auto& thread : threads_)
|
||||||
thread.join();
|
thread.join();
|
||||||
|
@ -44,7 +44,7 @@ void ThreadPool::PostTask(const Location& from, Closure task) {
|
||||||
DCHECK((!threads_.empty()));
|
DCHECK((!threads_.empty()));
|
||||||
|
|
||||||
task_runner_.PostTask(from, std::move(task));
|
task_runner_.PostTask(from, std::move(task));
|
||||||
semaphore_.release();
|
semaphore_.Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ThreadPool::PostTaskAndReply(const Location& from,
|
void ThreadPool::PostTaskAndReply(const Location& from,
|
||||||
|
@ -53,15 +53,17 @@ void ThreadPool::PostTaskAndReply(const Location& from,
|
||||||
DCHECK((!threads_.empty()));
|
DCHECK((!threads_.empty()));
|
||||||
|
|
||||||
task_runner_.PostTaskAndReply(from, std::move(task), std::move(reply));
|
task_runner_.PostTaskAndReply(from, std::move(task), std::move(reply));
|
||||||
semaphore_.release();
|
semaphore_.Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ThreadPool::WorkerMain() {
|
void ThreadPool::WorkerMain() {
|
||||||
for (;;) {
|
for (;;) {
|
||||||
semaphore_.acquire();
|
semaphore_.Acquire();
|
||||||
|
|
||||||
if (quit_.load(std::memory_order_relaxed))
|
if (quit_.load(std::memory_order_relaxed)) {
|
||||||
|
semaphore_.Release();
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
task_runner_.MultiConsumerRun();
|
task_runner_.MultiConsumerRun();
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,11 +2,11 @@
|
||||||
#define BASE_THREAD_POOL_H
|
#define BASE_THREAD_POOL_H
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <semaphore>
|
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "base/closure.h"
|
#include "base/closure.h"
|
||||||
|
#include "base/semaphore.h"
|
||||||
#include "base/task_runner.h"
|
#include "base/task_runner.h"
|
||||||
|
|
||||||
namespace base {
|
namespace base {
|
||||||
|
@ -36,13 +36,13 @@ class ThreadPool {
|
||||||
std::function<void(ReturnType)> reply) {
|
std::function<void(ReturnType)> reply) {
|
||||||
task_runner_.PostTaskAndReplyWithResult(from, std::move(task),
|
task_runner_.PostTaskAndReplyWithResult(from, std::move(task),
|
||||||
std::move(reply));
|
std::move(reply));
|
||||||
semaphore_.release();
|
semaphore_.Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<std::thread> threads_;
|
std::vector<std::thread> threads_;
|
||||||
|
|
||||||
std::counting_semaphore<> semaphore_{0};
|
Semaphore semaphore_;
|
||||||
std::atomic<bool> quit_{false};
|
std::atomic<bool> quit_{false};
|
||||||
|
|
||||||
base::TaskRunner task_runner_;
|
base::TaskRunner task_runner_;
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
executable("demo") {
|
||||||
|
sources = [
|
||||||
|
"credits.cc",
|
||||||
|
"credits.h",
|
||||||
|
"damage_type.h",
|
||||||
|
"demo.cc",
|
||||||
|
"demo.h",
|
||||||
|
"enemy.cc",
|
||||||
|
"enemy.h",
|
||||||
|
"hud.cc",
|
||||||
|
"hud.h",
|
||||||
|
"menu.cc",
|
||||||
|
"menu.h",
|
||||||
|
"player.cc",
|
||||||
|
"player.h",
|
||||||
|
"sky_quad.cc",
|
||||||
|
"sky_quad.h",
|
||||||
|
]
|
||||||
|
|
||||||
|
deps = [
|
||||||
|
"//src/base",
|
||||||
|
"//src/engine",
|
||||||
|
"//src/third_party",
|
||||||
|
]
|
||||||
|
}
|
|
@ -127,7 +127,7 @@ class Menu {
|
||||||
Button toggle_music_;
|
Button toggle_music_;
|
||||||
Button toggle_vibration_;
|
Button toggle_vibration_;
|
||||||
|
|
||||||
size_t high_score_value_ = 0;
|
int high_score_value_ = 0;
|
||||||
|
|
||||||
eng::ImageQuad high_score_;
|
eng::ImageQuad high_score_;
|
||||||
eng::Animator high_score_animator_;
|
eng::Animator high_score_animator_;
|
||||||
|
|
|
@ -0,0 +1,105 @@
|
||||||
|
source_set("engine") {
|
||||||
|
sources =
|
||||||
|
[
|
||||||
|
"animatable.cc",
|
||||||
|
"animatable.h",
|
||||||
|
"animator.cc",
|
||||||
|
"animator.h",
|
||||||
|
"audio/audio_base.cc",
|
||||||
|
"audio/audio_base.h",
|
||||||
|
"audio/audio_forward.h",
|
||||||
|
"audio/audio.h",
|
||||||
|
"drawable.cc",
|
||||||
|
"drawable.h",
|
||||||
|
"engine.cc",
|
||||||
|
"engine.h",
|
||||||
|
"font.cc",
|
||||||
|
"font.h",
|
||||||
|
"game_factory.h",
|
||||||
|
"game.h",
|
||||||
|
"image_quad.cc",
|
||||||
|
"image_quad.h",
|
||||||
|
"image.cc",
|
||||||
|
"image.h",
|
||||||
|
"input_event.h",
|
||||||
|
"mesh.cc",
|
||||||
|
"mesh.h",
|
||||||
|
"persistent_data.cc",
|
||||||
|
"persistent_data.h",
|
||||||
|
"platform/asset_file.cc",
|
||||||
|
"platform/asset_file.h",
|
||||||
|
"platform/platform.cc",
|
||||||
|
"platform/platform.h",
|
||||||
|
"renderer/geometry.cc",
|
||||||
|
"renderer/geometry.h",
|
||||||
|
"renderer/opengl/opengl.h",
|
||||||
|
"renderer/opengl/render_command.cc",
|
||||||
|
"renderer/opengl/render_command.h",
|
||||||
|
"renderer/opengl/renderer_opengl.cc",
|
||||||
|
"renderer/opengl/renderer_opengl.h",
|
||||||
|
"renderer/render_resource.h",
|
||||||
|
"renderer/renderer_types.cc",
|
||||||
|
"renderer/renderer_types.h",
|
||||||
|
"renderer/renderer.h",
|
||||||
|
"renderer/shader.cc",
|
||||||
|
"renderer/shader.h",
|
||||||
|
"renderer/texture.cc",
|
||||||
|
"renderer/texture.h",
|
||||||
|
"renderer/vulkan/renderer_vulkan_linux.cc",
|
||||||
|
"renderer/vulkan/renderer_vulkan.cc",
|
||||||
|
"renderer/vulkan/vulkan_context_linux.cc",
|
||||||
|
"renderer/vulkan/vulkan_context.cc",
|
||||||
|
"shader_source.cc",
|
||||||
|
"shader_source.h",
|
||||||
|
"solid_quad.cc",
|
||||||
|
"solid_quad.h",
|
||||||
|
"sound_player.cc",
|
||||||
|
"sound_player.h",
|
||||||
|
"sound.cc",
|
||||||
|
"sound.h",
|
||||||
|
]
|
||||||
|
|
||||||
|
defines = [
|
||||||
|
"VK_USE_PLATFORM_XLIB_KHR",
|
||||||
|
"VULKAN_NON_CMAKE_BUILD",
|
||||||
|
"SYSCONFDIR=\"/etc\"",
|
||||||
|
"FALLBACK_DATA_DIRS=\"/usr/local/share:/usr/share\"",
|
||||||
|
"FALLBACK_CONFIG_DIRS=\"/etc/xdg\"",
|
||||||
|
"HAVE_SECURE_GETENV",
|
||||||
|
]
|
||||||
|
|
||||||
|
ldflags = [] libs = []
|
||||||
|
|
||||||
|
if (target_os == "linux") {
|
||||||
|
sources +=
|
||||||
|
[
|
||||||
|
"audio/audio_alsa.cc",
|
||||||
|
"audio/audio_alsa.h",
|
||||||
|
"platform/asset_file_linux.cc",
|
||||||
|
"platform/platform_linux.cc",
|
||||||
|
"platform/platform_linux.h",
|
||||||
|
"renderer/opengl/renderer_opengl_linux.cc",
|
||||||
|
]
|
||||||
|
|
||||||
|
#ldflags += ["-L/usr/X11R6/lib"]
|
||||||
|
|
||||||
|
libs += [ "X11", "GL", "asound", "pthread" ]
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target_os == "android") {
|
||||||
|
sources += [
|
||||||
|
"audio/audio_oboe.cc",
|
||||||
|
"audio/audio_oboe.h",
|
||||||
|
"platform/asset_file_android.cc",
|
||||||
|
"platform/platform_android.cc",
|
||||||
|
"platform/platform_android.h",
|
||||||
|
"renderer/renderer_android.cc",
|
||||||
|
]
|
||||||
|
|
||||||
|
#ldflags += ["-L/usr/X11R6/lib"]
|
||||||
|
|
||||||
|
#libs += ["X11", "rt", "pthread"]
|
||||||
|
}
|
||||||
|
|
||||||
|
deps = []
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
#include "engine/animator.h"
|
#include "animator.h"
|
||||||
|
|
||||||
#include "base/interpolation.h"
|
#include "base/interpolation.h"
|
||||||
#include "base/log.h"
|
#include "base/log.h"
|
||||||
|
|
|
@ -206,7 +206,7 @@ class Engine {
|
||||||
PersistentData replay_data_;
|
PersistentData replay_data_;
|
||||||
bool recording_ = false;
|
bool recording_ = false;
|
||||||
bool replaying_ = false;
|
bool replaying_ = false;
|
||||||
unsigned int replay_index_ = 0;
|
int replay_index_ = 0;
|
||||||
|
|
||||||
base::Randomf random_;
|
base::Randomf random_;
|
||||||
|
|
||||||
|
|
|
@ -120,8 +120,8 @@ bool Image::CreateMip(const Image& other) {
|
||||||
} else {
|
} else {
|
||||||
const uint32_t* s = reinterpret_cast<const uint32_t*>(other.buffer_.get());
|
const uint32_t* s = reinterpret_cast<const uint32_t*>(other.buffer_.get());
|
||||||
uint32_t* d = reinterpret_cast<uint32_t*>(buffer_.get());
|
uint32_t* d = reinterpret_cast<uint32_t*>(buffer_.get());
|
||||||
for (int y = 0; y < height_; ++y) {
|
for (size_t y = 0; y < height_; ++y) {
|
||||||
for (int x = 0; x < width_; ++x) {
|
for (size_t x = 0; x < width_; ++x) {
|
||||||
*d++ = Mix4(s[0], s[1], s[other.width_], s[other.width_ + 1]);
|
*d++ = Mix4(s[0], s[1], s[other.width_], s[other.width_ + 1]);
|
||||||
s += 2;
|
s += 2;
|
||||||
}
|
}
|
||||||
|
|
|
@ -107,7 +107,7 @@ float ImageQuad::GetFrameHeight() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the uv offset for the given frame.
|
// Return the uv offset for the given frame.
|
||||||
Vector2f ImageQuad::GetUVOffset(size_t frame) const {
|
Vector2f ImageQuad::GetUVOffset(int frame) const {
|
||||||
DCHECK(frame < GetNumFrames())
|
DCHECK(frame < GetNumFrames())
|
||||||
<< "asset: " << asset_name_ << " frame: " << frame;
|
<< "asset: " << asset_name_ << " frame: " << frame;
|
||||||
return {(float)(frame % num_frames_[0]), (float)(frame / num_frames_[0])};
|
return {(float)(frame % num_frames_[0]), (float)(frame / num_frames_[0])};
|
||||||
|
|
|
@ -70,7 +70,7 @@ class ImageQuad : public Animatable {
|
||||||
float GetFrameWidth() const;
|
float GetFrameWidth() const;
|
||||||
float GetFrameHeight() const;
|
float GetFrameHeight() const;
|
||||||
|
|
||||||
base::Vector2f GetUVOffset(size_t frame) const;
|
base::Vector2f GetUVOffset(int frame) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace eng
|
} // namespace eng
|
||||||
|
|
|
@ -106,7 +106,7 @@ bool Mesh::Load(const std::string& file_name) {
|
||||||
vertices_ = std::make_unique<char[]>(vertex_buffer_size);
|
vertices_ = std::make_unique<char[]>(vertex_buffer_size);
|
||||||
|
|
||||||
char* dst = vertices_.get();
|
char* dst = vertices_.get();
|
||||||
unsigned int i = 0;
|
int i = 0;
|
||||||
while (i < vertices.size()) {
|
while (i < vertices.size()) {
|
||||||
for (auto& attr : vertex_description_) {
|
for (auto& attr : vertex_description_) {
|
||||||
auto [attrib_type, data_type, num_elements, type_size] = attr;
|
auto [attrib_type, data_type, num_elements, type_size] = attr;
|
||||||
|
|
|
@ -11,18 +11,11 @@ import android.util.Log;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.core.content.FileProvider;
|
import androidx.core.content.FileProvider;
|
||||||
|
|
||||||
import com.google.android.gms.ads.AdError;
|
import com.google.android.gms.ads.AdListener;
|
||||||
import com.google.android.gms.ads.AdRequest;
|
import com.google.android.gms.ads.AdRequest;
|
||||||
import com.google.android.gms.ads.FullScreenContentCallback;
|
import com.google.android.gms.ads.InterstitialAd;
|
||||||
import com.google.android.gms.ads.LoadAdError;
|
|
||||||
import com.google.android.gms.ads.MobileAds;
|
|
||||||
import com.google.android.gms.ads.initialization.InitializationStatus;
|
|
||||||
import com.google.android.gms.ads.initialization.OnInitializationCompleteListener;
|
|
||||||
import com.google.android.gms.ads.interstitial.InterstitialAd;
|
|
||||||
import com.google.android.gms.ads.interstitial.InterstitialAdLoadCallback;
|
|
||||||
import com.woom.game.R;
|
import com.woom.game.R;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
@ -42,13 +35,7 @@ public class KaliberActivity extends NativeActivity {
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
mInterstitialAd = newInterstitialAd();
|
||||||
MobileAds.initialize(this, new OnInitializationCompleteListener() {
|
|
||||||
@Override
|
|
||||||
public void onInitializationComplete(InitializationStatus initializationStatus) {
|
|
||||||
Log.d("kaliber", "MobileAds initialization complete.");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
loadInterstitialAd();
|
loadInterstitialAd();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,13 +52,44 @@ public class KaliberActivity extends NativeActivity {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private InterstitialAd newInterstitialAd() {
|
||||||
|
InterstitialAd interstitialAd = new InterstitialAd(this);
|
||||||
|
interstitialAd.setAdUnitId(getString(R.string.interstitial_ad_unit_id));
|
||||||
|
interstitialAd.setAdListener(new AdListener() {
|
||||||
|
@Override
|
||||||
|
public void onAdLoaded() {
|
||||||
|
Log.w("kaliber", "Ad loaded.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAdFailedToLoad(int errorCode) {
|
||||||
|
Log.w("kaliber", "Ad failed to load. errorCode: " + errorCode);
|
||||||
|
sHandler.postDelayed(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if (!mInterstitialAd.isLoaded())
|
||||||
|
loadInterstitialAd();
|
||||||
|
}
|
||||||
|
}, 1000 * 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAdClosed() {
|
||||||
|
loadInterstitialAd();
|
||||||
|
onShowAdResult(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return interstitialAd;
|
||||||
|
}
|
||||||
|
|
||||||
public void showInterstitialAd() {
|
public void showInterstitialAd() {
|
||||||
runOnUiThread(new Runnable() {
|
runOnUiThread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
if (mInterstitialAd != null) {
|
if (mInterstitialAd.isLoaded()) {
|
||||||
mInterstitialAd.show(KaliberActivity.this);
|
mInterstitialAd.show();
|
||||||
} else {
|
} else {
|
||||||
|
loadInterstitialAd();
|
||||||
onShowAdResult(false);
|
onShowAdResult(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -105,49 +123,10 @@ public class KaliberActivity extends NativeActivity {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadInterstitialAd() {
|
private void loadInterstitialAd() {
|
||||||
AdRequest adRequest = new AdRequest.Builder().build();
|
if (!mInterstitialAd.isLoading()) {
|
||||||
InterstitialAd.load(this, getString(R.string.interstitial_ad_unit_id), adRequest,
|
AdRequest adRequest = new AdRequest.Builder()
|
||||||
new InterstitialAdLoadCallback() {
|
.setRequestAgent("android_studio:ad_template").build();
|
||||||
@Override
|
mInterstitialAd.loadAd(adRequest);
|
||||||
public void onAdLoaded(@NonNull InterstitialAd interstitialAd) {
|
|
||||||
Log.d("kaliber", "Ad loaded.");
|
|
||||||
mInterstitialAd = interstitialAd;
|
|
||||||
interstitialAd.setFullScreenContentCallback(
|
|
||||||
new FullScreenContentCallback() {
|
|
||||||
@Override
|
|
||||||
public void onAdDismissedFullScreenContent() {
|
|
||||||
Log.d("kaliber", "The ad was dismissed.");
|
|
||||||
mInterstitialAd = null;
|
|
||||||
loadInterstitialAd();
|
|
||||||
onShowAdResult(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onAdFailedToShowFullScreenContent(AdError adError) {
|
|
||||||
Log.d("kaliber", "The ad failed to show.");
|
|
||||||
mInterstitialAd = null;
|
|
||||||
loadInterstitialAd();
|
|
||||||
onShowAdResult(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onAdShowedFullScreenContent() {
|
|
||||||
Log.d("kaliber", "The ad was shown.");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onAdFailedToLoad(@NonNull LoadAdError loadAdError) {
|
|
||||||
Log.d("kaliber", "Ad failed to load. errorCode: " + loadAdError);
|
|
||||||
mInterstitialAd = null;
|
|
||||||
sHandler.postDelayed(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
loadInterstitialAd();
|
|
||||||
}
|
|
||||||
}, 1000 * 10);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -184,7 +184,7 @@ void RendererOpenGL::SetUniform(uint64_t resource_id,
|
||||||
void RendererOpenGL::Present() {
|
void RendererOpenGL::Present() {
|
||||||
EnqueueCommand(std::make_unique<CmdPresent>());
|
EnqueueCommand(std::make_unique<CmdPresent>());
|
||||||
#ifdef THREADED_RENDERING
|
#ifdef THREADED_RENDERING
|
||||||
draw_complete_semaphore_.acquire();
|
draw_complete_semaphore_.Acquire();
|
||||||
#endif // THREADED_RENDERING
|
#endif // THREADED_RENDERING
|
||||||
fps_++;
|
fps_++;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,8 +13,9 @@
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <future>
|
#include <future>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <semaphore>
|
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
|
#include "base/semaphore.h"
|
||||||
#endif // THREADED_RENDERING
|
#endif // THREADED_RENDERING
|
||||||
|
|
||||||
#include "engine/renderer/opengl/opengl.h"
|
#include "engine/renderer/opengl/opengl.h"
|
||||||
|
@ -146,7 +147,7 @@ class RendererOpenGL : public Renderer {
|
||||||
std::thread render_thread_;
|
std::thread render_thread_;
|
||||||
bool terminate_render_thread_ = false;
|
bool terminate_render_thread_ = false;
|
||||||
|
|
||||||
std::counting_semaphore<> draw_complete_semaphore_{0};
|
base::Semaphore draw_complete_semaphore_;
|
||||||
|
|
||||||
base::TaskRunner* main_thread_task_runner_;
|
base::TaskRunner* main_thread_task_runner_;
|
||||||
#endif // THREADED_RENDERING
|
#endif // THREADED_RENDERING
|
||||||
|
|
|
@ -58,7 +58,7 @@ void RendererOpenGL::HandleCmdPresent(RenderCommand* cmd) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#ifdef THREADED_RENDERING
|
#ifdef THREADED_RENDERING
|
||||||
draw_complete_semaphore_.release();
|
draw_complete_semaphore_.Release();
|
||||||
#endif // THREADED_RENDERING
|
#endif // THREADED_RENDERING
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
active_shader_id_ = 0;
|
active_shader_id_ = 0;
|
||||||
|
|
|
@ -55,7 +55,7 @@ void RendererOpenGL::HandleCmdPresent(RenderCommand* cmd) {
|
||||||
if (display_) {
|
if (display_) {
|
||||||
glXSwapBuffers(display_, window_);
|
glXSwapBuffers(display_, window_);
|
||||||
#ifdef THREADED_RENDERING
|
#ifdef THREADED_RENDERING
|
||||||
draw_complete_semaphore_.release();
|
draw_complete_semaphore_.Release();
|
||||||
#endif // THREADED_RENDERING
|
#endif // THREADED_RENDERING
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
active_shader_id_ = 0;
|
active_shader_id_ = 0;
|
||||||
|
|
|
@ -295,7 +295,7 @@ uint64_t RendererVulkan::CreateGeometry(std::unique_ptr<Mesh> mesh) {
|
||||||
// Transfer mesh ownership to the background thread.
|
// Transfer mesh ownership to the background thread.
|
||||||
std::unique_ptr<Mesh> own(mesh);
|
std::unique_ptr<Mesh> own(mesh);
|
||||||
});
|
});
|
||||||
semaphore_.release();
|
semaphore_.Release();
|
||||||
|
|
||||||
return last_resource_id_;
|
return last_resource_id_;
|
||||||
}
|
}
|
||||||
|
@ -387,7 +387,7 @@ void RendererVulkan::UpdateTexture(uint64_t resource_id,
|
||||||
// Transfer image ownership to the background thread.
|
// Transfer image ownership to the background thread.
|
||||||
std::unique_ptr<Image> own(image);
|
std::unique_ptr<Image> own(image);
|
||||||
});
|
});
|
||||||
semaphore_.release();
|
semaphore_.Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RendererVulkan::DestroyTexture(uint64_t resource_id) {
|
void RendererVulkan::DestroyTexture(uint64_t resource_id) {
|
||||||
|
@ -619,7 +619,7 @@ void RendererVulkan::ActivateShader(uint64_t resource_id) {
|
||||||
vkCmdBindPipeline(frames_[current_frame_].draw_command_buffer,
|
vkCmdBindPipeline(frames_[current_frame_].draw_command_buffer,
|
||||||
VK_PIPELINE_BIND_POINT_GRAPHICS, it->second.pipeline);
|
VK_PIPELINE_BIND_POINT_GRAPHICS, it->second.pipeline);
|
||||||
}
|
}
|
||||||
for (size_t i = 0; i < it->second.desc_set_count; ++i) {
|
for (int i = 0; i < it->second.desc_set_count; ++i) {
|
||||||
if (active_descriptor_sets_[i] != penging_descriptor_sets_[i]) {
|
if (active_descriptor_sets_[i] != penging_descriptor_sets_[i]) {
|
||||||
active_descriptor_sets_[i] = penging_descriptor_sets_[i];
|
active_descriptor_sets_[i] = penging_descriptor_sets_[i];
|
||||||
vkCmdBindDescriptorSets(frames_[current_frame_].draw_command_buffer,
|
vkCmdBindDescriptorSets(frames_[current_frame_].draw_command_buffer,
|
||||||
|
@ -735,7 +735,7 @@ bool RendererVulkan::InitializeInternal() {
|
||||||
allocator_info.instance = context_.GetInstance();
|
allocator_info.instance = context_.GetInstance();
|
||||||
vmaCreateAllocator(&allocator_info, &allocator_);
|
vmaCreateAllocator(&allocator_info, &allocator_);
|
||||||
|
|
||||||
for (size_t i = 0; i < frames_.size(); i++) {
|
for (int i = 0; i < frames_.size(); i++) {
|
||||||
// Create command pool, one per frame is recommended.
|
// Create command pool, one per frame is recommended.
|
||||||
VkCommandPoolCreateInfo cmd_pool_info;
|
VkCommandPoolCreateInfo cmd_pool_info;
|
||||||
cmd_pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
|
cmd_pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
|
||||||
|
@ -867,12 +867,12 @@ void RendererVulkan::Shutdown() {
|
||||||
DestroyAllResources();
|
DestroyAllResources();
|
||||||
|
|
||||||
quit_.store(true, std::memory_order_relaxed);
|
quit_.store(true, std::memory_order_relaxed);
|
||||||
semaphore_.release();
|
semaphore_.Release();
|
||||||
setup_thread_.join();
|
setup_thread_.join();
|
||||||
|
|
||||||
vkDeviceWaitIdle(device_);
|
vkDeviceWaitIdle(device_);
|
||||||
|
|
||||||
for (size_t i = 0; i < frames_.size(); ++i) {
|
for (int i = 0; i < frames_.size(); ++i) {
|
||||||
FreePendingResources(i);
|
FreePendingResources(i);
|
||||||
vkDestroyCommandPool(device_, frames_[i].setup_command_pool, nullptr);
|
vkDestroyCommandPool(device_, frames_[i].setup_command_pool, nullptr);
|
||||||
vkDestroyCommandPool(device_, frames_[i].draw_command_pool, nullptr);
|
vkDestroyCommandPool(device_, frames_[i].draw_command_pool, nullptr);
|
||||||
|
@ -1081,7 +1081,7 @@ bool RendererVulkan::AllocateStagingBuffer(uint32_t amount,
|
||||||
FlushSetupBuffer();
|
FlushSetupBuffer();
|
||||||
|
|
||||||
// Clear the whole staging buffer.
|
// Clear the whole staging buffer.
|
||||||
for (size_t i = 0; i < staging_buffers_.size(); i++) {
|
for (int i = 0; i < staging_buffers_.size(); i++) {
|
||||||
staging_buffers_[i].frame_used = 0;
|
staging_buffers_[i].frame_used = 0;
|
||||||
staging_buffers_[i].fill_amount = 0;
|
staging_buffers_[i].fill_amount = 0;
|
||||||
}
|
}
|
||||||
|
@ -1115,9 +1115,9 @@ bool RendererVulkan::AllocateStagingBuffer(uint32_t amount,
|
||||||
// executed.
|
// executed.
|
||||||
vkDeviceWaitIdle(device_);
|
vkDeviceWaitIdle(device_);
|
||||||
|
|
||||||
for (size_t i = 0; i < staging_buffers_.size(); i++) {
|
for (int i = 0; i < staging_buffers_.size(); i++) {
|
||||||
// Clear all blocks but the ones from this frame.
|
// Clear all blocks but the ones from this frame.
|
||||||
size_t block_idx =
|
int block_idx =
|
||||||
(i + current_staging_buffer_) % staging_buffers_.size();
|
(i + current_staging_buffer_) % staging_buffers_.size();
|
||||||
if (staging_buffers_[block_idx].frame_used == frames_drawn_) {
|
if (staging_buffers_[block_idx].frame_used == frames_drawn_) {
|
||||||
break; // We reached something from this frame, abort.
|
break; // We reached something from this frame, abort.
|
||||||
|
@ -1621,7 +1621,7 @@ bool RendererVulkan::CreatePipelineLayout(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < binding_count; ++i) {
|
for (int i = 0; i < binding_count; ++i) {
|
||||||
const SpvReflectDescriptorBinding& binding = *bindings[i];
|
const SpvReflectDescriptorBinding& binding = *bindings[i];
|
||||||
|
|
||||||
DLOG << __func__ << " name: " << binding.name
|
DLOG << __func__ << " name: " << binding.name
|
||||||
|
@ -1735,7 +1735,7 @@ bool RendererVulkan::CreatePipelineLayout(
|
||||||
|
|
||||||
// Use the same layout for all decriptor sets.
|
// Use the same layout for all decriptor sets.
|
||||||
std::vector<VkDescriptorSetLayout> desc_set_layouts;
|
std::vector<VkDescriptorSetLayout> desc_set_layouts;
|
||||||
for (size_t i = 0; i < binding_count; ++i)
|
for (int i = 0; i < binding_count; ++i)
|
||||||
desc_set_layouts.push_back(descriptor_set_layout_);
|
desc_set_layouts.push_back(descriptor_set_layout_);
|
||||||
|
|
||||||
VkPipelineLayoutCreateInfo pipeline_layout_create_info;
|
VkPipelineLayoutCreateInfo pipeline_layout_create_info;
|
||||||
|
@ -1877,14 +1877,14 @@ void RendererVulkan::SetupThreadMain(int preallocate) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
semaphore_.acquire();
|
semaphore_.Acquire();
|
||||||
if (quit_.load(std::memory_order_relaxed))
|
if (quit_.load(std::memory_order_relaxed))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
task_runner_.SingleConsumerRun();
|
task_runner_.SingleConsumerRun();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < staging_buffers_.size(); i++) {
|
for (int i = 0; i < staging_buffers_.size(); i++) {
|
||||||
auto [buffer, allocation] = staging_buffers_[i].buffer;
|
auto [buffer, allocation] = staging_buffers_[i].buffer;
|
||||||
vmaDestroyBuffer(allocator_, buffer, allocation);
|
vmaDestroyBuffer(allocator_, buffer, allocation);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <semaphore>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
@ -12,6 +11,7 @@
|
||||||
|
|
||||||
#include "engine/renderer/vulkan/vulkan_context.h"
|
#include "engine/renderer/vulkan/vulkan_context.h"
|
||||||
|
|
||||||
|
#include "base/semaphore.h"
|
||||||
#include "base/task_runner.h"
|
#include "base/task_runner.h"
|
||||||
#include "engine/renderer/renderer.h"
|
#include "engine/renderer/renderer.h"
|
||||||
#include "third_party/vma/vk_mem_alloc.h"
|
#include "third_party/vma/vk_mem_alloc.h"
|
||||||
|
@ -113,7 +113,7 @@ class RendererVulkan : public Renderer {
|
||||||
std::unique_ptr<char[]> push_constants;
|
std::unique_ptr<char[]> push_constants;
|
||||||
size_t push_constants_size = 0;
|
size_t push_constants_size = 0;
|
||||||
std::vector<std::string> sampler_uniform_names;
|
std::vector<std::string> sampler_uniform_names;
|
||||||
size_t desc_set_count = 0;
|
int desc_set_count = 0;
|
||||||
VkPipelineLayout pipeline_layout = VK_NULL_HANDLE;
|
VkPipelineLayout pipeline_layout = VK_NULL_HANDLE;
|
||||||
VkPipeline pipeline = VK_NULL_HANDLE;
|
VkPipeline pipeline = VK_NULL_HANDLE;
|
||||||
};
|
};
|
||||||
|
@ -181,7 +181,7 @@ class RendererVulkan : public Renderer {
|
||||||
|
|
||||||
std::thread setup_thread_;
|
std::thread setup_thread_;
|
||||||
base::TaskRunner task_runner_;
|
base::TaskRunner task_runner_;
|
||||||
std::counting_semaphore<> semaphore_{0};
|
base::Semaphore semaphore_;
|
||||||
std::atomic<bool> quit_{false};
|
std::atomic<bool> quit_{false};
|
||||||
|
|
||||||
bool InitializeInternal();
|
bool InitializeInternal();
|
||||||
|
|
|
@ -39,7 +39,7 @@ std::array<std::unique_ptr<T[]>, 2> Deinterleave(size_t num_channels,
|
||||||
// Deinterleave into separate channels.
|
// Deinterleave into separate channels.
|
||||||
channels[0] = std::make_unique<T[]>(num_samples);
|
channels[0] = std::make_unique<T[]>(num_samples);
|
||||||
channels[1] = std::make_unique<T[]>(num_samples);
|
channels[1] = std::make_unique<T[]>(num_samples);
|
||||||
for (size_t i = 0, j = 0; i < num_samples * 2; i += 2) {
|
for (int i = 0, j = 0; i < num_samples * 2; i += 2) {
|
||||||
channels[0].get()[j] = static_cast<T>(input_buffer[i]);
|
channels[0].get()[j] = static_cast<T>(input_buffer[i]);
|
||||||
channels[1].get()[j++] = static_cast<T>(input_buffer[i + 1]);
|
channels[1].get()[j++] = static_cast<T>(input_buffer[i + 1]);
|
||||||
}
|
}
|
||||||
|
@ -230,7 +230,7 @@ void Sound::Preprocess(std::unique_ptr<float[]> input_buffer,
|
||||||
} else {
|
} else {
|
||||||
size_t num_resampled_samples = resampler_[0]->ChunkSize();
|
size_t num_resampled_samples = resampler_[0]->ChunkSize();
|
||||||
DCHECK(num_resampled_samples ==
|
DCHECK(num_resampled_samples ==
|
||||||
(size_t)(((float)hw_sample_rate_ / (float)sample_rate_) *
|
(int)(((float)hw_sample_rate_ / (float)sample_rate_) *
|
||||||
samples_per_channel));
|
samples_per_channel));
|
||||||
|
|
||||||
if (!back_buffer_[0]) {
|
if (!back_buffer_[0]) {
|
||||||
|
@ -243,7 +243,7 @@ void Sound::Preprocess(std::unique_ptr<float[]> input_buffer,
|
||||||
num_samples_back_ = num_resampled_samples;
|
num_samples_back_ = num_resampled_samples;
|
||||||
|
|
||||||
// Resample to match the system sample rate.
|
// Resample to match the system sample rate.
|
||||||
for (size_t i = 0; i < num_channels_; ++i) {
|
for (int i = 0; i < num_channels_; ++i) {
|
||||||
resampler_[i]->Resample(num_resampled_samples, back_buffer_[i].get(),
|
resampler_[i]->Resample(num_resampled_samples, back_buffer_[i].get(),
|
||||||
[&](int frames, float* destination) {
|
[&](int frames, float* destination) {
|
||||||
memcpy(destination, channels[i].get(),
|
memcpy(destination, channels[i].get(),
|
||||||
|
|
|
@ -0,0 +1,225 @@
|
||||||
|
source_set("third_party") {
|
||||||
|
sources = [
|
||||||
|
"jsoncpp/json.h",
|
||||||
|
"jsoncpp/jsoncpp.cpp",
|
||||||
|
"minimp3/minimp3_ex.h",
|
||||||
|
"minimp3/minimp3.h",
|
||||||
|
"stb/stb_image.h",
|
||||||
|
"stb/stb_truetype.h",
|
||||||
|
"texture_compressor/dxt_encoder_implementation_autogen.h",
|
||||||
|
"texture_compressor/dxt_encoder_internals.cc",
|
||||||
|
"texture_compressor/dxt_encoder_internals.h",
|
||||||
|
"texture_compressor/dxt_encoder.cc",
|
||||||
|
"texture_compressor/dxt_encoder.h",
|
||||||
|
"texture_compressor/texture_compressor_etc1.cc",
|
||||||
|
"texture_compressor/texture_compressor_etc1.h",
|
||||||
|
"texture_compressor/texture_compressor.cc",
|
||||||
|
"texture_compressor/texture_compressor.h",
|
||||||
|
"glslang/glslang/CInterface/glslang_c_interface.cpp",
|
||||||
|
"glslang/glslang/GenericCodeGen/CodeGen.cpp",
|
||||||
|
"glslang/glslang/GenericCodeGen/Link.cpp",
|
||||||
|
"glslang/glslang/MachineIndependent/attribute.cpp",
|
||||||
|
"glslang/glslang/MachineIndependent/Constant.cpp",
|
||||||
|
"glslang/glslang/MachineIndependent/glslang_tab.cpp",
|
||||||
|
"glslang/glslang/MachineIndependent/InfoSink.cpp",
|
||||||
|
"glslang/glslang/MachineIndependent/Initialize.cpp",
|
||||||
|
"glslang/glslang/MachineIndependent/Intermediate.cpp",
|
||||||
|
"glslang/glslang/MachineIndependent/intermOut.cpp",
|
||||||
|
"glslang/glslang/MachineIndependent/IntermTraverse.cpp",
|
||||||
|
"glslang/glslang/MachineIndependent/iomapper.cpp",
|
||||||
|
"glslang/glslang/MachineIndependent/limits.cpp",
|
||||||
|
"glslang/glslang/MachineIndependent/linkValidate.cpp",
|
||||||
|
"glslang/glslang/MachineIndependent/parseConst.cpp",
|
||||||
|
"glslang/glslang/MachineIndependent/ParseContextBase.cpp",
|
||||||
|
"glslang/glslang/MachineIndependent/ParseHelper.cpp",
|
||||||
|
"glslang/glslang/MachineIndependent/PoolAlloc.cpp",
|
||||||
|
"glslang/glslang/MachineIndependent/preprocessor/Pp.cpp",
|
||||||
|
"glslang/glslang/MachineIndependent/preprocessor/PpAtom.cpp",
|
||||||
|
"glslang/glslang/MachineIndependent/preprocessor/PpContext.cpp",
|
||||||
|
"glslang/glslang/MachineIndependent/preprocessor/PpScanner.cpp",
|
||||||
|
"glslang/glslang/MachineIndependent/preprocessor/PpTokens.cpp",
|
||||||
|
"glslang/glslang/MachineIndependent/propagateNoContraction.cpp",
|
||||||
|
"glslang/glslang/MachineIndependent/reflection.cpp",
|
||||||
|
"glslang/glslang/MachineIndependent/RemoveTree.cpp",
|
||||||
|
"glslang/glslang/MachineIndependent/Scan.cpp",
|
||||||
|
"glslang/glslang/MachineIndependent/ShaderLang.cpp",
|
||||||
|
"glslang/glslang/MachineIndependent/SymbolTable.cpp",
|
||||||
|
"glslang/glslang/MachineIndependent/Versions.cpp",
|
||||||
|
"glslang/glslang/OSDependent/Unix/ossource.cpp",
|
||||||
|
"glslang/OGLCompilersDLL/InitializeDll.cpp",
|
||||||
|
"glslang/SPIRV/CInterface/spirv_c_interface.cpp",
|
||||||
|
"glslang/SPIRV/disassemble.cpp",
|
||||||
|
"glslang/SPIRV/doc.cpp",
|
||||||
|
"glslang/SPIRV/GlslangToSpv.cpp",
|
||||||
|
"glslang/SPIRV/InReadableOrder.cpp",
|
||||||
|
"glslang/SPIRV/Logger.cpp",
|
||||||
|
"glslang/SPIRV/SpvBuilder.cpp",
|
||||||
|
"glslang/SPIRV/SpvPostProcess.cpp",
|
||||||
|
"glslang/SPIRV/SPVRemapper.cpp",
|
||||||
|
"glslang/SPIRV/SpvTools.cpp",
|
||||||
|
"glslang/StandAlone/ResourceLimits.cpp",
|
||||||
|
"spirv-reflect/spirv_reflect.c",
|
||||||
|
"vma/vk_mem_alloc.cpp",
|
||||||
|
]
|
||||||
|
|
||||||
|
defines = [
|
||||||
|
"VK_USE_PLATFORM_XLIB_KHR",
|
||||||
|
"VULKAN_NON_CMAKE_BUILD",
|
||||||
|
"SYSCONFDIR=\"/etc\"",
|
||||||
|
"FALLBACK_DATA_DIRS=\"/usr/local/share:/usr/share\"",
|
||||||
|
"FALLBACK_CONFIG_DIRS=\"/etc/xdg\"",
|
||||||
|
"HAVE_SECURE_GETENV",
|
||||||
|
]
|
||||||
|
|
||||||
|
# ldflags = []
|
||||||
|
# libs = []
|
||||||
|
|
||||||
|
if (target_os == "linux") {
|
||||||
|
sources += [
|
||||||
|
"glew/glew.c",
|
||||||
|
"glew/glew.h",
|
||||||
|
"glew/glxew.h",
|
||||||
|
"vulkan/loader/cJSON.c",
|
||||||
|
"vulkan/loader/debug_utils.c",
|
||||||
|
"vulkan/loader/dev_ext_trampoline.c",
|
||||||
|
"vulkan/loader/extension_manual.c",
|
||||||
|
"vulkan/loader/loader.c",
|
||||||
|
"vulkan/loader/murmurhash.c",
|
||||||
|
"vulkan/loader/phys_dev_ext.c",
|
||||||
|
"vulkan/loader/trampoline.c",
|
||||||
|
"vulkan/loader/unknown_ext_chain.c",
|
||||||
|
"vulkan/loader/wsi.c",
|
||||||
|
]
|
||||||
|
|
||||||
|
# ldflags += [ "-L/usr/X11R6/lib" ]
|
||||||
|
|
||||||
|
libs = [ "dl" ]
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target_os == "android") {
|
||||||
|
sources += [
|
||||||
|
"android/gl3stub.c",
|
||||||
|
"android/gl3stub.h",
|
||||||
|
"android/GLContext.cpp",
|
||||||
|
"android/GLContext.h",
|
||||||
|
"minizip/ioapi.c",
|
||||||
|
"minizip/ioapi.h",
|
||||||
|
"minizip/unzip.c",
|
||||||
|
"minizip/unzip.h",
|
||||||
|
"oboe/include/oboe/AudioStream.h",
|
||||||
|
"oboe/include/oboe/AudioStreamBase.h",
|
||||||
|
"oboe/include/oboe/AudioStreamBuilder.h",
|
||||||
|
"oboe/include/oboe/AudioStreamCallback.h",
|
||||||
|
"oboe/include/oboe/Definitions.h",
|
||||||
|
"oboe/include/oboe/LatencyTuner.h",
|
||||||
|
"oboe/include/oboe/Oboe.h",
|
||||||
|
"oboe/include/oboe/ResultWithValue.h",
|
||||||
|
"oboe/include/oboe/StabilizedCallback.h",
|
||||||
|
"oboe/include/oboe/Utilities.h",
|
||||||
|
"oboe/include/oboe/Version.h",
|
||||||
|
"oboe/src/aaudio/AAudioLoader.cpp",
|
||||||
|
"oboe/src/aaudio/AAudioLoader.h",
|
||||||
|
"oboe/src/aaudio/AudioStreamAAudio.cpp",
|
||||||
|
"oboe/src/aaudio/AudioStreamAAudio.h",
|
||||||
|
"oboe/src/common/AudioClock.h",
|
||||||
|
"oboe/src/common/AudioSourceCaller.cpp",
|
||||||
|
"oboe/src/common/AudioSourceCaller.h",
|
||||||
|
"oboe/src/common/AudioStream.cpp",
|
||||||
|
"oboe/src/common/AudioStreamBuilder.cpp",
|
||||||
|
"oboe/src/common/DataConversionFlowGraph.cpp",
|
||||||
|
"oboe/src/common/DataConversionFlowGraph.h",
|
||||||
|
"oboe/src/common/FilterAudioStream.cpp",
|
||||||
|
"oboe/src/common/FilterAudioStream.h",
|
||||||
|
"oboe/src/common/FixedBlockAdapter.cpp",
|
||||||
|
"oboe/src/common/FixedBlockAdapter.h",
|
||||||
|
"oboe/src/common/FixedBlockReader.cpp",
|
||||||
|
"oboe/src/common/FixedBlockReader.h",
|
||||||
|
"oboe/src/common/FixedBlockWriter.cpp",
|
||||||
|
"oboe/src/common/FixedBlockWriter.h",
|
||||||
|
"oboe/src/common/LatencyTuner.cpp",
|
||||||
|
"oboe/src/common/MonotonicCounter.h",
|
||||||
|
"oboe/src/common/OboeDebug.h",
|
||||||
|
"oboe/src/common/QuirksManager.cpp",
|
||||||
|
"oboe/src/common/QuirksManager.h",
|
||||||
|
"oboe/src/common/SourceFloatCaller.cpp",
|
||||||
|
"oboe/src/common/SourceFloatCaller.h",
|
||||||
|
"oboe/src/common/SourceI16Caller.cpp",
|
||||||
|
"oboe/src/common/SourceI16Caller.h",
|
||||||
|
"oboe/src/common/StabilizedCallback.cpp",
|
||||||
|
"oboe/src/common/Trace.cpp",
|
||||||
|
"oboe/src/common/Trace.h",
|
||||||
|
"oboe/src/common/Utilities.cpp",
|
||||||
|
"oboe/src/common/Version.cpp",
|
||||||
|
"oboe/src/fifo/FifoBuffer.cpp",
|
||||||
|
"oboe/src/fifo/FifoBuffer.h",
|
||||||
|
"oboe/src/fifo/FifoController.cpp",
|
||||||
|
"oboe/src/fifo/FifoController.h",
|
||||||
|
"oboe/src/fifo/FifoControllerBase.cpp",
|
||||||
|
"oboe/src/fifo/FifoControllerBase.h",
|
||||||
|
"oboe/src/fifo/FifoControllerIndirect.cpp",
|
||||||
|
"oboe/src/fifo/FifoControllerIndirect.h",
|
||||||
|
"oboe/src/flowgraph/ClipToRange.cpp",
|
||||||
|
"oboe/src/flowgraph/ClipToRange.h",
|
||||||
|
"oboe/src/flowgraph/FlowGraphNode.cpp",
|
||||||
|
"oboe/src/flowgraph/FlowGraphNode.h",
|
||||||
|
"oboe/src/flowgraph/ManyToMultiConverter.cpp",
|
||||||
|
"oboe/src/flowgraph/ManyToMultiConverter.h",
|
||||||
|
"oboe/src/flowgraph/MonoToMultiConverter.cpp",
|
||||||
|
"oboe/src/flowgraph/MonoToMultiConverter.h",
|
||||||
|
"oboe/src/flowgraph/RampLinear.cpp",
|
||||||
|
"oboe/src/flowgraph/RampLinear.h",
|
||||||
|
"oboe/src/flowgraph/resampler/HyperbolicCosineWindow.h",
|
||||||
|
"oboe/src/flowgraph/resampler/IntegerRatio.cpp",
|
||||||
|
"oboe/src/flowgraph/resampler/IntegerRatio.h",
|
||||||
|
"oboe/src/flowgraph/resampler/KaiserWindow.h",
|
||||||
|
"oboe/src/flowgraph/resampler/LinearResampler.cpp",
|
||||||
|
"oboe/src/flowgraph/resampler/LinearResampler.h",
|
||||||
|
"oboe/src/flowgraph/resampler/MultiChannelResampler.cpp",
|
||||||
|
"oboe/src/flowgraph/resampler/MultiChannelResampler.h",
|
||||||
|
"oboe/src/flowgraph/resampler/PolyphaseResampler.cpp",
|
||||||
|
"oboe/src/flowgraph/resampler/PolyphaseResampler.h",
|
||||||
|
"oboe/src/flowgraph/resampler/PolyphaseResamplerMono.cpp",
|
||||||
|
"oboe/src/flowgraph/resampler/PolyphaseResamplerMono.h",
|
||||||
|
"oboe/src/flowgraph/resampler/PolyphaseResamplerStereo.cpp",
|
||||||
|
"oboe/src/flowgraph/resampler/PolyphaseResamplerStereo.h",
|
||||||
|
"oboe/src/flowgraph/resampler/SincResampler.cpp",
|
||||||
|
"oboe/src/flowgraph/resampler/SincResampler.h",
|
||||||
|
"oboe/src/flowgraph/resampler/SincResamplerStereo.cpp",
|
||||||
|
"oboe/src/flowgraph/resampler/SincResamplerStereo.h",
|
||||||
|
"oboe/src/flowgraph/SampleRateConverter.cpp",
|
||||||
|
"oboe/src/flowgraph/SampleRateConverter.h",
|
||||||
|
"oboe/src/flowgraph/SinkFloat.cpp",
|
||||||
|
"oboe/src/flowgraph/SinkFloat.h",
|
||||||
|
"oboe/src/flowgraph/SinkI16.cpp",
|
||||||
|
"oboe/src/flowgraph/SinkI16.h",
|
||||||
|
"oboe/src/flowgraph/SinkI24.cpp",
|
||||||
|
"oboe/src/flowgraph/SinkI24.h",
|
||||||
|
"oboe/src/flowgraph/SourceFloat.cpp",
|
||||||
|
"oboe/src/flowgraph/SourceFloat.h",
|
||||||
|
"oboe/src/flowgraph/SourceI16.cpp",
|
||||||
|
"oboe/src/flowgraph/SourceI16.h",
|
||||||
|
"oboe/src/flowgraph/SourceI24.cpp",
|
||||||
|
"oboe/src/flowgraph/SourceI24.h",
|
||||||
|
"oboe/src/opensles/AudioInputStreamOpenSLES.cpp",
|
||||||
|
"oboe/src/opensles/AudioInputStreamOpenSLES.h",
|
||||||
|
"oboe/src/opensles/AudioOutputStreamOpenSLES.cpp",
|
||||||
|
"oboe/src/opensles/AudioOutputStreamOpenSLES.h",
|
||||||
|
"oboe/src/opensles/AudioStreamBuffered.cpp",
|
||||||
|
"oboe/src/opensles/AudioStreamBuffered.h",
|
||||||
|
"oboe/src/opensles/AudioStreamOpenSLES.cpp",
|
||||||
|
"oboe/src/opensles/AudioStreamOpenSLES.h",
|
||||||
|
"oboe/src/opensles/EngineOpenSLES.cpp",
|
||||||
|
"oboe/src/opensles/EngineOpenSLES.h",
|
||||||
|
"oboe/src/opensles/OpenSLESUtilities.cpp",
|
||||||
|
"oboe/src/opensles/OpenSLESUtilities.h",
|
||||||
|
"oboe/src/opensles/OutputMixerOpenSLES.cpp",
|
||||||
|
"oboe/src/opensles/OutputMixerOpenSLES.h",
|
||||||
|
"texture_compressor/dxt_encoder_neon.cc",
|
||||||
|
"texture_compressor/dxt_encoder_neon.h",
|
||||||
|
"texture_compressor/texture_compressor_etc1_neon.cc",
|
||||||
|
"texture_compressor/texture_compressor_etc1_neon.h",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
deps = []
|
||||||
|
}
|
|
@ -14,7 +14,6 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include "IntegerRatio.h"
|
#include "IntegerRatio.h"
|
||||||
#include "PolyphaseResampler.h"
|
#include "PolyphaseResampler.h"
|
||||||
|
|
|
@ -16,8 +16,6 @@
|
||||||
|
|
||||||
#include "PolyphaseResamplerMono.h"
|
#include "PolyphaseResamplerMono.h"
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
using namespace resampler;
|
using namespace resampler;
|
||||||
|
|
||||||
#define MONO 1
|
#define MONO 1
|
||||||
|
|
|
@ -16,8 +16,6 @@
|
||||||
|
|
||||||
#include "PolyphaseResamplerStereo.h"
|
#include "PolyphaseResamplerStereo.h"
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
using namespace resampler;
|
using namespace resampler;
|
||||||
|
|
||||||
#define STEREO 2
|
#define STEREO 2
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include "SincResampler.h"
|
#include "SincResampler.h"
|
||||||
|
|
||||||
|
|
|
@ -18,8 +18,6 @@
|
||||||
|
|
||||||
#include "SincResamplerStereo.h"
|
#include "SincResamplerStereo.h"
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
using namespace resampler;
|
using namespace resampler;
|
||||||
|
|
||||||
#define STEREO 2
|
#define STEREO 2
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue