Compare commits

..

No commits in common. "655c0a7b71f026a18bb08b4a0779899055e1c62d" and "8cd680d6a4ee06df31152b3b59c0a07334945f61" have entirely different histories.

48 changed files with 5557 additions and 5002 deletions

1
.gitignore vendored
View File

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

2
.gn Normal file
View File

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

5
BUILD.gn Normal file
View File

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

View File

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

View File

@ -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'
} }

View File

@ -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" />

View File

@ -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'
} }
} }

View File

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

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

View File

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

40
build/gn/BUILD.gn Normal file
View File

@ -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" ]
}
}

41
build/gn/BUILDCONFIG.gn Normal file
View File

@ -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")

151
build/gn/toolchain/BUILD.gn Normal file
View File

@ -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}}"
}
}

View File

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

35
src/base/BUILD.gn Normal file
View File

@ -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 = []
}

41
src/base/semaphore.h Normal file
View File

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

View File

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

View File

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

View File

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

View File

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

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(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();
} }

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

25
src/demo/BUILD.gn Normal file
View File

@ -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",
]
}

View File

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

105
src/engine/BUILD.gn Normal file
View File

@ -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 = []
}

View File

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

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;
unsigned int replay_index_ = 0; 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 (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;
} }

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(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])};

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(size_t frame) const; base::Vector2f GetUVOffset(int 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();
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;

View File

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

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,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

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 (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);
} }

View File

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

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 (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(),

225
src/third_party/BUILD.gn vendored Normal file
View File

@ -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 = []
}

View File

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

View File

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

View File

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

View File

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

View File

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