Compare commits

..

5 Commits

Author SHA1 Message Date
Attila Uygun 655c0a7b71 Update android build
Upgrade to gradle 8.0
Compile and target sdk 33
Min sdk 24
Upgrade to Google Mobile Ads SDK 22.0
Enable c++20 and fix compilation issues
2023-05-09 22:22:02 +02:00
Attila Uygun 97271835b0 Remove gn 2023-05-05 08:22:51 +02:00
Attila Uygun 4bab472ed1 Enable extra warnings for all but third-party 2023-05-04 23:21:32 +02:00
Attila Uygun 653c283758 Use std::counting_semaphore 2023-05-04 18:07:30 +02:00
Attila Uygun 771f8a3d78 Update SincResampler 2023-05-03 20:21:26 +02:00
48 changed files with 5002 additions and 5557 deletions

1
.gitignore vendored
View File

@ -1,5 +1,6 @@
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

2
.gn
View File

@ -1,2 +0,0 @@
# The location of the build configuration file.
buildconfig = "//build/gn/BUILDCONFIG.gn"

View File

@ -1,5 +0,0 @@
group("kaliber") {
deps = [
"//src/demo",
]
}

View File

@ -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 (lolipop+) platforms. Supports Linux and Android 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,11 +14,6 @@ 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),

View File

@ -14,7 +14,8 @@
# limitations under the License. # limitations under the License.
# #
cmake_minimum_required(VERSION 3.4.1) cmake_minimum_required(VERSION 3.22.1)
project(kaliber)
# OBOE Library # OBOE Library
set (OBOE_DIR ../../../src/third_party/oboe) set (OBOE_DIR ../../../src/third_party/oboe)
@ -36,9 +37,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++17 -Wall -Werror -D_DEBUG -DVK_USE_PLATFORM_ANDROID_KHR") 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")
else () else ()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 -Wall -Werror -DVK_USE_PLATFORM_ANDROID_KHR") 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")
endif () endif ()
@ -141,6 +142,7 @@ 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

View File

@ -1,13 +1,13 @@
apply plugin: 'com.android.application' apply plugin: 'com.android.application'
android { android {
compileSdkVersion 29 compileSdk 33
ndkVersion '21.3.6528147' ndkVersion '25.1.8937393'
defaultConfig { defaultConfig {
applicationId = 'com.woom.game' applicationId = 'com.woom.game'
minSdkVersion 21 minSdk 24
targetSdkVersion 29 targetSdk 33
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.10.2' version '3.22.1'
path 'CMakeLists.txt' path 'CMakeLists.txt'
} }
} }
@ -39,11 +39,12 @@ 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.0.2' implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3' implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'com.google.android.gms:play-services-ads:19.1.0' implementation 'com.google.android.gms:play-services-ads:22.0.0'
} }

View File

@ -1,6 +1,5 @@
<?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">
@ -20,6 +19,7 @@
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" />

View File

@ -5,7 +5,7 @@ buildscript {
jcenter() jcenter()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:4.1.0' classpath 'com.android.tools.build:gradle:8.0.1'
} }
} }

View File

@ -9,9 +9,13 @@
# 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

View File

@ -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-6.5-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip

View File

@ -1,2 +1,2 @@
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/zipalign -p -f 4 ./app/build/outputs/apk/release/app-release-unsigned.apk ./app-release-aligned.apk
zipalign -f 4 ./app-release.apk ./app-release-aligned.apk ~/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

View File

@ -1,40 +0,0 @@
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" ]
}
}

View File

@ -1,41 +0,0 @@
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")

View File

@ -1,151 +0,0 @@
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}}"
}
}

View File

@ -32,8 +32,8 @@ LDFLAGS = -lX11 -lGL -pthread -lasound -ldl
# Always enable debug information. # Always enable debug information.
CFLAGS += -g CFLAGS += -g
# Make all warnings into errors. # Enable extra warnings and make all warnings into errors.
CFLAGS += -Werror CFLAGS += -Wextra -Werror
# Flags to generate dependency information. # Flags to generate dependency information.
CFLAGS += -MD -MP -MT $@ CFLAGS += -MD -MP -MT $@
@ -75,15 +75,26 @@ 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"))
# --- Engine --- # --- Base ---
ENGINE_SRC := \ BASE_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 \
@ -113,7 +124,25 @@ 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 \
@ -160,6 +189,7 @@ ENGINE_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 \
@ -176,12 +206,24 @@ ENGINE_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
ENGINE_LIB := $(BUILD_DIR)/libengine.a $(BUILD_DIR)/third_party/%.o: $(SRC_ROOT)/third_party/%.c
ENGINE_OBJS := $(call objs_from_src, $(ENGINE_SRC)) @mkdir -p $(@D)
LIBS += $(ENGINE_LIB) $(HUSH_COMPILE) $(CC) -c $(THIRD_PARTY_CFLAGS) -o $@ $<
OBJS += $(ENGINE_OBJS)
$(ENGINE_LIB): $(ENGINE_OBJS) $(BUILD_DIR)/third_party/%.o: $(SRC_ROOT)/third_party/%.cc
@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 ---

View File

@ -1,35 +0,0 @@
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 = []
}

View File

@ -1,41 +0,0 @@
#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

View File

@ -11,7 +11,7 @@
// <---------------------------------------------------------> // <--------------------------------------------------------->
// r0_ (during first load) // r0_ (during first load)
// //
// kKernelSize / 2 kKernelSize / 2 kKernelSize / 2 kKernelSize / 2 // kernel_size_ / 2 kernel_size_ / 2 kernel_size_ / 2 kernel_size_ / 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 kKernelSize / 2 and r3_, r4_ // On the second request r0_ slides to the right by kernel_size_ / 2 and r3_,
// and block_size_ are reinitialized via step (3) in the algorithm below. // r4_ 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,26 +31,27 @@
// //
// The algorithm: // The algorithm:
// //
// 1) Allocate input_buffer of size: request_frames_ + kKernelSize; this ensures // 1) Allocate input_buffer of size: request_frames_ + kernel_size_; this
// 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_ + kKernelSize / 2 // r0_ = input_buffer_ + kernel_size_ / 2
// r1_ = input_buffer_ // r1_ = input_buffer_
// r2_ = r0_ // r2_ = r0_
// //
// r0_ is always request_frames_ in size. r1_, r2_ are kKernelSize / 2 in // r0_ is always request_frames_ in size. r1_, r2_ are kernel_size_ / 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_ - kKernelSize // r3_ = r0_ + request_frames_ - kernel_size_
// r4_ = r0_ + request_frames_ - kKernelSize / 2 // r4_ = r0_ + request_frames_ - kernel_size_ / 2
// block_size_ = r4_ - r2_ = request_frames_ - kKernelSize / 2 // block_size_ = r4_ - r2_ = request_frames_ - kernel_size_ / 2
// //
// 4) Consume request_frames_ frames into r0_. // 4) Consume request_frames_ frames into r0_.
// //
@ -62,9 +63,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 kKernelSize / 2: // r4_, which is kernel_size_ / 2:
// //
// r0_ = r0_ + kKernelSize / 2 = input_buffer_ + kKernelSize // r0_ = r0_ + kernel_size_ / 2 = input_buffer_ + kernel_size_
// //
// 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).
// //
@ -127,7 +128,9 @@ class ScopedSubnormalFloatDisabler {
#endif #endif
}; };
double SincScaleFactor(double io_ratio) { } // namespace
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;
@ -136,19 +139,17 @@ double SincScaleFactor(double io_ratio) {
// 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.
// TODO(crogers): this value is empirical and to be more exact should vary // Note: these values are derived empirically.
// depending on kKernelSize. if (kernel_size == SincResampler::kMaxKernelSize) {
sinc_scale_factor *= 0.9; sinc_scale_factor *= 0.92;
} 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__)
@ -170,26 +171,39 @@ 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)
: io_sample_rate_ratio_(io_sample_rate_ratio), : kernel_size_(KernelSizeFromRequestFrames(request_frames)),
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_ + kKernelSize), input_buffer_size_(request_frames_ + kernel_size_),
// 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) * kKernelStorageSize))), base::AlignedAlloc<32>(sizeof(float) * kernel_storage_size_))),
kernel_pre_sinc_storage_(static_cast<float*>( kernel_pre_sinc_storage_(static_cast<float*>(
base::AlignedAlloc<32>(sizeof(float) * kKernelStorageSize))), base::AlignedAlloc<32>(sizeof(float) * kernel_storage_size_))),
kernel_window_storage_(static_cast<float*>( kernel_window_storage_(static_cast<float*>(
base::AlignedAlloc<32>(sizeof(float) * kKernelStorageSize))), base::AlignedAlloc<32>(sizeof(float) * kernel_storage_size_))),
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() + kKernelSize / 2) { r2_(input_buffer_.get() + kernel_size_ / 2) {
CHECK(request_frames > kKernelSize * 3 / 2) CHECK(request_frames > kernel_size_ * 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_ > kKernelSize and r2_ < r3_. // block_size_ > kernel_size_ and r2_ < r3_.
InitializeCPUSpecificFeatures(); InitializeCPUSpecificFeatures();
DCHECK(convolve_proc_); DCHECK(convolve_proc_);
@ -197,11 +211,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()) * kKernelStorageSize); sizeof(*kernel_storage_.get()) * kernel_storage_size_);
memset(kernel_pre_sinc_storage_.get(), 0, memset(kernel_pre_sinc_storage_.get(), 0,
sizeof(*kernel_pre_sinc_storage_.get()) * kKernelStorageSize); sizeof(*kernel_pre_sinc_storage_.get()) * kernel_storage_size_);
memset(kernel_window_storage_.get(), 0, memset(kernel_window_storage_.get(), 0,
sizeof(*kernel_window_storage_.get()) * kKernelStorageSize); sizeof(*kernel_window_storage_.get()) * kernel_storage_size_);
InitializeKernel(); InitializeKernel();
} }
@ -210,10 +224,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 kKernelSize / 2. // on the second load we need to slide r0_ to the right by kernel_size_ / 2.
r0_ = input_buffer_.get() + (second_load ? kKernelSize : kKernelSize / 2); r0_ = input_buffer_.get() + (second_load ? kernel_size_ : kernel_size_ / 2);
r3_ = r0_ + request_frames_ - kKernelSize; r3_ = r0_ + request_frames_ - kernel_size_;
r4_ = r0_ + request_frames_ - kKernelSize / 2; r4_ = r0_ + request_frames_ - kernel_size_ / 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_);
@ -234,19 +248,20 @@ 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 = SincScaleFactor(io_sample_rate_ratio_); const double sinc_scale_factor =
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 < kKernelSize; ++i) { for (int i = 0; i < kernel_size_; ++i) {
const int idx = i + offset_idx * kKernelSize; const int idx = i + offset_idx * kernel_size_;
const float pre_sinc = const float pre_sinc =
base::kPiFloat * (i - kKernelSize / 2 - subsample_offset); base::kPiFloat * (i - kernel_size_ / 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) / kKernelSize; const float x = (i - subsample_offset) / kernel_size_;
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));
@ -272,10 +287,11 @@ 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 = SincScaleFactor(io_sample_rate_ratio_); const double sinc_scale_factor =
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 < kKernelSize; ++i) { for (int i = 0; i < kernel_size_; ++i) {
const int idx = i + offset_idx * kKernelSize; const int idx = i + offset_idx * kernel_size_;
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];
@ -312,13 +328,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 * kKernelSize; const float* k1 = kernel_storage_.get() + offset_idx * kernel_size_;
const float* k2 = k1 + kKernelSize; const float* k2 = k1 + kernel_size_;
// 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;
@ -326,15 +342,16 @@ 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++ = *destination++ = convolve_proc_(kernel_size_, input_ptr, k1, k2,
convolve_proc_(input_ptr, k1, k2, kernel_interpolation_factor); 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_);
@ -342,11 +359,12 @@ 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()) * kKernelSize); memcpy(r1_, r3_, sizeof(*input_buffer_.get()) * kernel_size_);
// 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_);
@ -381,7 +399,12 @@ double SincResampler::BufferedFrames() const {
return buffer_primed_ ? request_frames_ - virtual_source_idx_ : 0; return buffer_primed_ ? request_frames_ - virtual_source_idx_ : 0;
} }
float SincResampler::Convolve_C(const float* input_ptr, int SincResampler::KernelSize() const {
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) {
@ -390,7 +413,7 @@ float SincResampler::Convolve_C(const float* input_ptr,
// 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 = kKernelSize; int n = kernel_size;
while (n--) { while (n--) {
sum1 += *input_ptr * *k1++; sum1 += *input_ptr * *k1++;
sum2 += *input_ptr++ * *k2++; sum2 += *input_ptr++ * *k2++;
@ -402,7 +425,8 @@ float SincResampler::Convolve_C(const float* input_ptr,
} }
#if defined(_M_X64) || defined(__x86_64__) || defined(__i386__) #if defined(_M_X64) || defined(__x86_64__) || defined(__i386__)
float SincResampler::Convolve_SSE(const float* input_ptr, float SincResampler::Convolve_SSE(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,13 +437,13 @@ float SincResampler::Convolve_SSE(const float* input_ptr,
// 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 < kKernelSize; i += 4) { for (int i = 0; i < kernel_size; 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 < kKernelSize; i += 4) { for (int i = 0; i < kernel_size; 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)));
@ -444,6 +468,7 @@ float SincResampler::Convolve_SSE(const float* input_ptr,
} }
__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,
@ -456,13 +481,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 < kKernelSize; i += 8) { for (size_t i = 0; i < static_cast<size_t>(kernel_size); 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 < kKernelSize; i += 8) { for (size_t i = 0; i < static_cast<size_t>(kernel_size); 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);
@ -490,7 +515,8 @@ __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 float* input_ptr, float SincResampler::Convolve_NEON(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) {
@ -498,7 +524,7 @@ float SincResampler::Convolve_NEON(const float* input_ptr,
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 + kKernelSize; const float* upper = input_ptr + kernel_size;
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;

View File

@ -16,32 +16,40 @@ 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. // expense of performance. Must be a multiple of 32. We aim for 64 for
// TODO(dalecurtis): Test performance to see if we can jack this up to 64+. // perceptible audio quality (see crbug.com/1407622), but fallback to 32 in
static constexpr int kKernelSize = 32; // cases where `request_frames_` is too small (e.g. 10ms of 8kHz audio).
// 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 kKernelSize. // calls back for input. Must be greater than 1.5 * `kernel_size_`.
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*kKernelSize. Specify kDefaultRequestSize if there are no // greater than 1.5*`kernel_size_`. Specify kDefaultRequestSize if there are
// request size constraints. // no 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;
@ -52,10 +60,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 frames that guarantees Resample() will only make a // The maximum size in output frames that guarantees Resample() will only make
// single call to |read_cb_| for more data. Note: If PrimeWithSilence() is // a 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
// kKernelSize / (2 * io_sample_rate_ratio). See the .cc file for details. // `kernel_size_` / (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
@ -77,13 +85,19 @@ 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);
@ -92,21 +106,25 @@ 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 float* input_ptr, static float 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);
#if defined(_M_X64) || defined(__x86_64__) || defined(__i386__) #if defined(_M_X64) || defined(__x86_64__) || defined(__i386__)
static float Convolve_SSE(const float* input_ptr, static float Convolve_SSE(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);
static float Convolve_AVX2(const float* input_ptr, static float Convolve_AVX2(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);
#elif defined(_M_ARM64) || defined(__aarch64__) #elif defined(_M_ARM64) || defined(__aarch64__)
static float Convolve_NEON(const float* input_ptr, static float Convolve_NEON(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);
@ -116,6 +134,9 @@ 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_;
@ -139,9 +160,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 kKernelSize. // Contains kKernelOffsetCount kernels back-to-back, each of size
// The kernel offsets are sub-sample shifts of a windowed sinc shifted from // `kernel_size_`. The kernel offsets are sub-sample shifts of a windowed sinc
// 0.0 to 1.0 sample. // shifted from 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_;
@ -150,10 +171,8 @@ 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 = float (*)(const float*, using ConvolveProc =
const float*, float (*)(const int, const float*, const float*, const float*, double);
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

View File

@ -1,5 +1,7 @@
#include "base/task_runner.h" #include "base/task_runner.h"
#include <thread>
#include "base/log.h" #include "base/log.h"
namespace { namespace {
@ -33,7 +35,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_relaxed); task_count_.fetch_add(1, std::memory_order_release);
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));
} }
@ -68,7 +70,7 @@ void TaskRunner::MultiConsumerRun() {
#endif #endif
task_cb(); task_cb();
task_count_.fetch_sub(1, std::memory_order_relaxed); task_count_.fetch_sub(1, std::memory_order_release);
} }
} }
@ -90,16 +92,13 @@ void TaskRunner::SingleConsumerRun() {
#endif #endif
task_cb(); task_cb();
task_count_.fetch_sub(1, std::memory_order_relaxed); task_count_.fetch_sub(1, std::memory_order_release);
} }
cv_.notify_one();
} }
void TaskRunner::WaitForCompletion() { void TaskRunner::WaitForCompletion() {
std::unique_lock<std::mutex> scoped_lock(lock_); while (task_count_.load(std::memory_order_acquire) > 0)
cv_.wait(scoped_lock, [&]() -> bool { std::this_thread::yield();
return task_count_.load(std::memory_order_relaxed) == 0;
});
} }
} // namespace base } // namespace base

View File

@ -2,7 +2,6 @@
#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>
@ -74,7 +73,6 @@ 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;

View File

@ -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(); semaphore_.release(threads_.size());
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,17 +53,15 @@ 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();
} }

View File

@ -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_;
Semaphore semaphore_; std::counting_semaphore<> semaphore_{0};
std::atomic<bool> quit_{false}; std::atomic<bool> quit_{false};
base::TaskRunner task_runner_; base::TaskRunner task_runner_;

View File

@ -1,25 +0,0 @@
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",
]
}

View File

@ -127,7 +127,7 @@ class Menu {
Button toggle_music_; Button toggle_music_;
Button toggle_vibration_; Button toggle_vibration_;
int high_score_value_ = 0; size_t high_score_value_ = 0;
eng::ImageQuad high_score_; eng::ImageQuad high_score_;
eng::Animator high_score_animator_; eng::Animator high_score_animator_;

View File

@ -1,105 +0,0 @@
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 = []
}

View File

@ -1,4 +1,4 @@
#include "animator.h" #include "engine/animator.h"
#include "base/interpolation.h" #include "base/interpolation.h"
#include "base/log.h" #include "base/log.h"

View File

@ -206,7 +206,7 @@ class Engine {
PersistentData replay_data_; PersistentData replay_data_;
bool recording_ = false; bool recording_ = false;
bool replaying_ = false; bool replaying_ = false;
int replay_index_ = 0; unsigned int replay_index_ = 0;
base::Randomf random_; base::Randomf random_;

View File

@ -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 (size_t y = 0; y < height_; ++y) { for (int y = 0; y < height_; ++y) {
for (size_t x = 0; x < width_; ++x) { for (int 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;
} }

View File

@ -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(int frame) const { Vector2f ImageQuad::GetUVOffset(size_t 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])};

View File

@ -70,7 +70,7 @@ class ImageQuad : public Animatable {
float GetFrameWidth() const; float GetFrameWidth() const;
float GetFrameHeight() const; float GetFrameHeight() const;
base::Vector2f GetUVOffset(int frame) const; base::Vector2f GetUVOffset(size_t frame) const;
}; };
} // namespace eng } // namespace eng

View File

@ -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();
int i = 0; unsigned 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;

View File

@ -11,11 +11,18 @@ 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.AdListener; import com.google.android.gms.ads.AdError;
import com.google.android.gms.ads.AdRequest; import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.InterstitialAd; import com.google.android.gms.ads.FullScreenContentCallback;
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;
@ -35,7 +42,13 @@ 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();
} }
@ -52,44 +65,13 @@ 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.isLoaded()) { if (mInterstitialAd != null) {
mInterstitialAd.show(); mInterstitialAd.show(KaliberActivity.this);
} else { } else {
loadInterstitialAd();
onShowAdResult(false); onShowAdResult(false);
} }
} }
@ -123,10 +105,49 @@ public class KaliberActivity extends NativeActivity {
} }
private void loadInterstitialAd() { private void loadInterstitialAd() {
if (!mInterstitialAd.isLoading()) { AdRequest adRequest = new AdRequest.Builder().build();
AdRequest adRequest = new AdRequest.Builder() InterstitialAd.load(this, getString(R.string.interstitial_ad_unit_id), adRequest,
.setRequestAgent("android_studio:ad_template").build(); new InterstitialAdLoadCallback() {
mInterstitialAd.loadAd(adRequest); @Override
} 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);
}
});
} }
} }

View File

@ -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_++;
} }

View File

@ -13,9 +13,8 @@
#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"
@ -147,7 +146,7 @@ class RendererOpenGL : public Renderer {
std::thread render_thread_; std::thread render_thread_;
bool terminate_render_thread_ = false; bool terminate_render_thread_ = false;
base::Semaphore draw_complete_semaphore_; std::counting_semaphore<> draw_complete_semaphore_{0};
base::TaskRunner* main_thread_task_runner_; base::TaskRunner* main_thread_task_runner_;
#endif // THREADED_RENDERING #endif // THREADED_RENDERING

View File

@ -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;

View File

@ -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;

View File

@ -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 (int i = 0; i < it->second.desc_set_count; ++i) { for (size_t 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 (int i = 0; i < frames_.size(); i++) { for (size_t 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 (int i = 0; i < frames_.size(); ++i) { for (size_t 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 (int i = 0; i < staging_buffers_.size(); i++) { for (size_t 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 (int i = 0; i < staging_buffers_.size(); i++) { for (size_t 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.
int block_idx = size_t 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 (int i = 0; i < binding_count; ++i) { for (size_t 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 (int i = 0; i < binding_count; ++i) for (size_t 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 (int i = 0; i < staging_buffers_.size(); i++) { for (size_t 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);
} }

View File

@ -3,6 +3,7 @@
#include <atomic> #include <atomic>
#include <memory> #include <memory>
#include <semaphore>
#include <string> #include <string>
#include <thread> #include <thread>
#include <tuple> #include <tuple>
@ -11,7 +12,6 @@
#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;
int desc_set_count = 0; size_t 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_;
base::Semaphore semaphore_; std::counting_semaphore<> semaphore_{0};
std::atomic<bool> quit_{false}; std::atomic<bool> quit_{false};
bool InitializeInternal(); bool InitializeInternal();

View File

@ -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 (int i = 0, j = 0; i < num_samples * 2; i += 2) { for (size_t 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 ==
(int)(((float)hw_sample_rate_ / (float)sample_rate_) * (size_t)(((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 (int i = 0; i < num_channels_; ++i) { for (size_t 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(),

View File

@ -1,225 +0,0 @@
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 = []
}

View File

@ -14,6 +14,7 @@
* 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"

View File

@ -16,6 +16,8 @@
#include "PolyphaseResamplerMono.h" #include "PolyphaseResamplerMono.h"
#include <assert.h>
using namespace resampler; using namespace resampler;
#define MONO 1 #define MONO 1

View File

@ -16,6 +16,8 @@
#include "PolyphaseResamplerStereo.h" #include "PolyphaseResamplerStereo.h"
#include <assert.h>
using namespace resampler; using namespace resampler;
#define STEREO 2 #define STEREO 2

View File

@ -14,6 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
#include <assert.h>
#include <math.h> #include <math.h>
#include "SincResampler.h" #include "SincResampler.h"

View File

@ -18,6 +18,8 @@
#include "SincResamplerStereo.h" #include "SincResamplerStereo.h"
#include <assert.h>
using namespace resampler; using namespace resampler;
#define STEREO 2 #define STEREO 2

4673
src/third_party/stb/stb_image.c vendored Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff