458 Commits

Author SHA1 Message Date
Gerry
5d2eef15d3 Merge branch 'develop' into develop 2021-05-04 22:44:57 -07:00
gfan
44d725a358 Adding animated-image decoder sample under webp/ for Android 12 DP1 2021-05-04 22:39:59 -07:00
gfan
de2c5a5dbe Remove expreiemental build in other-builds\experimental 2021-05-04 22:27:59 -07:00
gfan
93837e9cc5 Update to AGP(Android gradle plugin)4.2.0 2021-05-04 22:07:29 -07:00
github-actions
38164ec877 Merge remote-tracking branch 'origin/main' 2021-04-06 14:41:19 +00:00
Joseph Ryan
87ae9bff54 Update README.md (#788) 2021-04-06 07:40:58 -07:00
github-actions
2309bdff46 Merge remote-tracking branch 'origin/main' 2021-04-02 00:43:11 +00:00
I-CAT
7f0444dbfc Update README.md (#785)
Fixed insecure http urls with secure https urls in repo's README.md
2021-04-01 17:42:50 -07:00
gfan
9d05e29492 Adding animated-image decoder sample under webp/ for Android 12 DP1 2021-03-15 15:05:31 -07:00
github-actions
73cb509746 Merge remote-tracking branch 'origin/main' 2021-03-15 21:30:23 +00:00
Gerry
e056de2470 adding assert.h/cassert into samples to be compliant to NDK-r23 (#781) 2021-03-15 13:13:36 -07:00
github-actions
48e73d9068 Merge remote-tracking branch 'origin/main' 2021-02-12 01:40:17 +00:00
Gerry
539dd9b098 Fixing structure member initialization sequence warning (#775) 2021-02-11 17:39:53 -08:00
github-actions
e9646e6e07 Merge remote-tracking branch 'origin/main' 2021-02-10 02:11:46 +00:00
Gerry
f7ffa0da9e fix b/175151089: fix ndkbuild for hello-jni and nn-sample (#774) 2021-02-09 18:11:16 -08:00
github-actions
a6f7e3e283 Merge remote-tracking branch 'origin/main' 2021-02-02 20:15:48 +00:00
Gerry
8203689f6e Switching to github Action for CI (#770)
Enable github Action for CI, removing travis ci as it is migrating away
2021-02-02 12:15:22 -08:00
github-actions
d97dc293bf Merge remote-tracking branch 'origin/main' 2021-01-06 18:12:22 +00:00
Milind Deore
2f8b9055bf Few types mismatch warnings fixed. (#768) 2021-01-06 10:11:54 -08:00
github-actions
9f97d62883 Merge remote-tracking branch 'origin/main' 2020-12-04 06:22:26 +00:00
Gerry
98a82c2a94 Update README.md for hello-libs to fix issue 744 (#766) 2020-12-03 22:22:01 -08:00
github-actions
9cf165f3d6 Merge remote-tracking branch 'origin/main' 2020-11-13 01:17:44 +00:00
Gerry
d191bf0cb3 Develop resync (#762)
resync to main branch
2020-11-12 17:17:23 -08:00
github-actions
6641e16e1b Merge remote-tracking branch 'origin/main' 2020-11-13 00:48:17 +00:00
Gerry
6c68a701ff Back merge Android 11 samples (nn-api/sequence & image-decoder) to main (#761) 2020-11-12 16:47:55 -08:00
github-actions
52e9b24d40 Merge remote-tracking branch 'origin/main' 2020-11-09 22:50:33 +00:00
Gerry
ee1c6f7b9d Add documentation links for prefab samples (#752)
* Add documentation link for prefab-using sample, deprecate and remove cdep sample
2020-11-09 14:50:03 -08:00
github-actions
7af9752b2f Merge remote-tracking branch 'origin/main' into master 2020-10-28 05:52:31 +00:00
Gerry
8fb8f2906f Adding back the simple prefab dependency sample (#756)
* Add a simpler Prefab sample from Dan Albert.

This sample demonstrates how to use prefab dependency AARs from Maven Center with jsoncpp.
2020-10-27 22:51:47 -07:00
Gerry
751250c0b2 Adding back the simple prefab dependency sample (#756)
* Add a simpler Prefab sample from Dan Albert.

This sample demonstrates how to use prefab dependency AARs from Maven Center with jsoncpp.
2020-10-27 22:09:08 -07:00
Jeremy Walker
1647be8aca Create copy-branch.yml 2020-09-30 13:23:57 -07:00
Don Turner
1fa89b1061 Update oboe to version 1.4.2 2020-08-04 11:24:32 +01:00
Gerry
2b6de82e39 Update prefab sample's README.md to workaround SSL and LLDB conflict (#742) 2020-07-14 13:54:40 -07:00
Gerry
9282f3405f Update hello-jni and nn-sample to kotin in root directory (#741) 2020-07-06 13:16:47 -07:00
gfan
64f7aa1a48 Adding OpenSL ES deprecation message to audio-echo and native-audio samples 2020-06-18 13:58:05 -07:00
Dan Albert
5521ea7d48 Add a sample for creating Prefab AARs. (#727) 2020-06-04 11:15:07 -07:00
Nishant Srivastava
c8669bb389 update hello-oboe sample project (#731) 2020-06-04 11:14:48 -07:00
Nishant Srivastava
17ec60701d Add ndkVersion (#730)
* setup ndkVersion in build script for each project

* switch to latest stable ndk version: 21.2.6472646

Link: https://developer.android.com/ndk/downloads#stable-downloads
2020-06-03 14:02:01 -07:00
Gerry
cc5ce43366 Merge pull request #729 from nisrulz/update/agp-4.0.0
Update all projects to Stable AGP 4.0.0
2020-06-03 08:51:01 -07:00
Nishant Srivastava
fee6bf078f updated gradle wrapper to 6.1.1
- min required for AGP 4.0.0
2020-06-03 10:58:32 +02:00
Nishant Srivastava
b7d603e61a update AGP to v4.0.0 (stable) 2020-06-03 10:57:32 +02:00
gfan
42535c0047 nit: add gradle.properties file to ndk's hello-neon build to prepare for agp 4.0.0 update 2020-06-02 14:22:20 -07:00
Gerry
c93c34084a Merge pull request #720 from bashi-bazouk/master
Clean up -Wunused-variable and -Wimplicit-fallthrough warnings.
2020-06-01 22:56:31 -07:00
Gerry
28f6cb2c71 Merge pull request #735 from android/libs-update
Port github PR# 724
2020-06-01 22:55:00 -07:00
gfan
ba0ad69d15 Port github PR# 724 2020-06-01 22:49:58 -07:00
Gerry
eda2c52631 Merge pull request #714 from android/oboe-prefab
Update hello-oboe with pre-built lib
2020-06-01 22:22:19 -07:00
gfan
438809d228 Update hello-oboe with prefab oboe lib
Test: Studio 4.0 beta4 on Mac with emulator
2020-06-01 22:21:08 -07:00
Gerry
cbdd8129ac Merge pull request #725 from android/remove-beta-samples
Remove Android 11 beta samples to fix issue #722
2020-05-20 10:22:43 -07:00
gfan
f7baf167c4 Remove Android 11 beta samples to fix github issue #722 2020-05-19 18:33:22 -07:00
Gerry
fdc63dd9ad Merge pull request #723 from android/teapot-ndk-fix
Update to the latest NDK for teapot sample
2020-05-01 15:02:46 -07:00
gfan
55a8e23da3 Update NDK version for Teapots sample. 2020-05-01 15:00:21 -07:00
Brian Ledger
dbb6ac6b0e Require C++17 in display-p3/image-view. 2020-04-30 11:35:57 -04:00
Brian Ledger
b51561cb52 Change unintented fallthrough to break in switch. 2020-04-30 11:33:27 -04:00
Brian Ledger
7f4d5563da Add [[fallthrough]] to switches to avoid -Wimplicit-fallthrough 2020-04-28 13:59:53 -04:00
Brian Ledger
d0cb379143 Remove unused variables to prevent -Wunused-variable errors. 2020-04-28 13:28:38 -04:00
Gerry
597b118389 Merge pull request #718 from android/prefab-update
prefab/curl-ssl minor documentation update
2020-04-24 11:42:10 -07:00
gfan
c94a5b8a65 Addressing code review change requests for Prefab/curl-ssl sample 2020-04-24 11:40:51 -07:00
gfan
5845916731 Update READM.md in prefab/curl-ssl sample with more Prefab instructions 2020-04-23 18:51:06 -07:00
Gerry
78af76b2f1 Merge pull request #717 from android/imagedecoder-update
Remove the wrapper from teapots/image-decoder sample
2020-04-23 12:51:02 -07:00
Gerry
71924c528c Merge pull request #716 from Kottsone/master
Fix nn-samples with infinite timeout duration.
2020-04-23 12:49:33 -07:00
gfan
f3570c29d4 Remove wrapper from teapots/image-decoder sample 2020-04-23 12:42:59 -07:00
Kottsone
b53406227c Fix nn-samples with infinite timeout duration. 2020-04-23 12:42:01 -07:00
Gerry
61821c6eef Merge pull request #715 from android/dp3-update
Update R feature samples(nn-sample, image-decoder)
2020-04-23 11:18:03 -07:00
gfan
bdab663dd0 Update R feature samples(nn-sample, image-decoder) with DeveloperPreview 3 2020-04-23 10:42:21 -07:00
Gerry
079f1c45e9 Merge pull request #712 from bashi-bazouk/master
Update initializater orderings to avoid -Wreorder warnings.
2020-04-22 14:37:52 -07:00
Gerry
75a2648ba0 Merge pull request #713 from DanAlbert/update-curl-ssl
Update ndkports dependencies.
2020-04-22 14:02:02 -07:00
Dan Albert
d093e99d08 Update ndkports dependencies. 2020-04-22 12:49:53 -07:00
Brian Ledger
4df28a3b78 Update initializater orderings to avoid -Wreorder warnings. 2020-04-21 17:36:10 -04:00
Gerry
5ea5e3dd90 Merge pull request #706 from android/hello-jni-fix
Patch up PR 704 for a fix
2020-04-09 07:26:44 -07:00
gfan
c14a66ab26 Add 32 bit ABI into 64 bit build, fix contrainlayout error 2020-04-08 23:46:21 -07:00
Dan Albert
9a2a813bba Update Hello JNI dependencies and fix lint issues.
Fixes http://b/153108278
2020-04-02 17:19:08 -07:00
Gerry
99c3331e32 Merge pull request #700 from DanAlbert/update-agp
Update to 4.0.0-beta3, remove workarounds.
2020-03-19 14:08:16 -07:00
Dan Albert
ea79dd5ab4 Update to 4.0.0-beta3, remove workarounds. 2020-03-19 13:14:25 -07:00
Gerry
0632212e7e Merge pull request #699 from Kottsone/master
Update nn-samples with dependency APIs.
2020-03-18 10:06:26 -07:00
Xusong Wang
5d4dd8bcf0 Update nn-samples with dependency APIs. 2020-03-18 09:58:15 -07:00
gfan
3d57ed5207 Fix typo report in github issue #698 2020-03-13 10:31:16 -07:00
Gerry
829f28ba9d Merge pull request #696 from android/endless-tunnel-fix
Added workaround for b/149866792
2020-03-05 18:09:25 -08:00
gfan
5270b7d399 Added workaround for b/149866792 2020-03-05 17:47:21 -08:00
gfan
d2742539ef Fix ci issues 2020-03-05 13:22:46 -08:00
Gerry
a9ebc9ed6c Merge pull request #695 from android/android-r-update
Update nn-samples and image-decoder to use ndk-r21.1
2020-03-04 16:01:00 -08:00
gfan
2380f2b7e1 Update nn-samples and image-decoder to use ndk-r21.1
Test: Pixel 3 + Android R DP1.1
2020-03-04 14:59:59 -08:00
Gerry
7cab1bd4cc Merge pull request #694 from DanAlbert/update-beta-1
Update Prefab sample to use AGP 4.0 beta 1.
2020-02-25 12:53:20 -08:00
Dan Albert
90321c6671 Update Prefab sample to use AGP 4.0 beta 1. 2020-02-25 12:37:32 -08:00
Gerry
5d41688c4e Merge pull request #692 from android/imagedecoder-sample
Adding AImageDecoder sample for Android 11
2020-02-19 09:50:00 -08:00
gfan
7350f4f9b7 adding AImageDecoder sample for Android 11 2020-02-19 09:47:21 -08:00
Gerry
51d02405e8 Merge pull request #691 from Kottsone/master
Add a new NNAPI sample for R features.
2020-02-19 09:32:30 -08:00
Xusong Wang
2891c27af0 Add a new NNAPI sample for R features.
Add a new sample app demonstrating the usage of the NNAPI R features.

Additionally rename the directory and fix some typos.
2020-02-19 09:30:20 -08:00
Gerry
2b6cb3c826 Merge pull request #688 from Kottsone/master
Update the links in nn_sample/README.md
2020-02-18 11:39:19 -08:00
Xusong Wang
83225cb43d Update the links in nn_sample/README.md
Updated the links filing an issue and forking the project.
2020-02-18 11:31:07 -08:00
Gerry
16e67c08cc Merge pull request #685 from DanAlbert/prefab-bug-docs
Link the bugs mentioned in the prefab sample.
2020-02-14 11:41:34 -08:00
Dan Albert
828e5317be Link the bugs mentioned in the prefab sample. 2020-02-14 11:31:50 -08:00
Gerry
c03e6b0e82 Add sample for using C++ dependencies from AARs. (#678)
A sample showing how to import native dependencies from Maven. This
sample uses curl, OpenSSL, and JsonCpp to display a list of the most
recent 10 reviews submitted to AOSP's code review system.
2020-02-13 16:00:13 -08:00
Dan Albert
de4d85aae4 Add sample for using C++ dependencies from AARs.
A sample showing how to import native dependencies from Maven. This
sample uses curl, OpenSSL, and JsonCpp to display a list of the most
recent 10 reviews submitted to AOSP's code review system.
2020-02-13 15:27:49 -08:00
邓超
9ec9d13dd5 Fix file and dir references in README.md, reformat native_engine.cpp (#684)
* Fix file and dir references

* Replace glm's official website link with github repository link

Github seems to have a better cdn than the original website.

* Remove useless variable ident

* Add default branch

* Remove redundant code and space

* Simplify do-while statement
2020-02-06 09:38:53 -08:00
邓超
93c969dd6b Fix Clang Tidy for native-activity (#682)
* Replace ANDROID_NDK with CMAKE_ANDROID_NDK

* Clang-Tidy: Replace errno.h with cerrno

* Clang-Tidy: Replace NULL with nullptr

* Clang-Tidy: Replace 0 with nullptr

* Clang-Tidy: Replace `struct` with `auto`

* Clang-Tidy: Initialize config with nullptr

* Clang-Tidy: Initialize engine

* Clang-Tidy: Replace 1 with true

* Clang-Tidy: Add default to switch

* Revert "Replace ANDROID_NDK with CMAKE_ANDROID_NDK"

This reverts commit aa30c1dc
2020-02-05 10:08:30 -08:00
Gerry
01cb04665a Update display-p3 sample with EGL_EXT_gl_colorspace_display_p3_passthrough (#679)
Test: Pixel 3 XL Android 10
2019-12-19 10:26:49 -08:00
Gerry
a72a345630 minor doc update (#677) 2019-12-10 12:41:14 -08:00
Gerry
fed5f03391 add "side by side ndk" ( multiple NDKs ) support to ci (#675) 2019-12-07 11:23:27 -08:00
Gerry
cffe9c5fa1 Turn on ci for ndk-samples (#674) 2019-12-07 09:23:01 -08:00
gfan
d265aa1c27 fix build for ndkbuild/helloneon 2019-12-06 18:39:56 -08:00
Gerry
e40ea6fb89 adding gradlew wrapper file to nn-sample ndkbuild (#673) 2019-12-06 17:24:20 -08:00
Gerry
3a94e115ce Update build scripts to Studio 3.5.2 version (#672) 2019-12-02 18:05:57 -08:00
Gerry
13f92b9eb4 Some minor updates for ci scripts (#671) 2019-12-02 16:44:49 -08:00
Gerry
7c4c248822 Update midi sample build script with formal Andorid 10 SDK version (#670) 2019-12-02 09:45:34 -08:00
Emre Kultursay
f6998820b0 Fix file and class names in endless-tunnel readme (#667) 2019-12-02 08:03:28 -08:00
Dan Albert
2c97a9eb5b Drop bug in workaround for r21+. (#665)
This workaround for a bug in abspath used to workaround path length
issues in Windows is not needed in r21+ because the abspath bug was
fixed. Unfortunately the bug being fixed means that the workaround now
introduces a bug when forming the path. Only use the workaround for
pre-r21 NDKs.

Bug: http://b/142666190
2019-11-15 11:58:50 -08:00
Randy Li
7541d019b0 teapot: fix missing precision qualifier (#661)
Some GPU devices likes ARM Mali midgard would fail
in compiling this shader.

Signed-off-by: Hsia-Jun Li(Randy) <ayaka@soulik.info>
2019-11-05 17:58:50 -08:00
Sam Protsenko
7c1acc9daa Improve libraries build code (#658)
* hello-libs: Update Gradle plugin version

Update the Android Gradle plugin from current version 3.3.2 to version
3.5.1 and Gradle to version 5.4.1.

Signed-off-by: Sam Protsenko <joe.skb7@gmail.com>

* hello-libs: Remove gen-libs dependency workaround

Seems like it's not needed anymore. With new Gradle version build goes
well every time.

Also, bring back gen-libs dependency (commented out), so that user is
able to actually build libs by uncommenting that dependency along with
include line in settings.gradle.

Signed-off-by: Sam Protsenko <joe.skb7@gmail.com>

* hello-libs: Fix incremental build

When running the build twice, second time fails with linking error:

    some-file.o: error adding symbols: File in wrong format

That's happening because source file's timestamp isn't changed between
those two builds, so CMake tries to reuse previous object file for
"some-file.c", but Gradle runs CMake for 4 different architectures:
  1. x86
  2. x86_64
  3. armeabi-v7a
  4. arm64-v8a

so CMake basically is trying to reuse the object file generated for
different architecture, that's why linker is reporting the "wrong
format" error. That behavior forces the developer to do clean build
every time, instead of incremental build.

Let's fix this issue by keeping the object files in architecture
specific directories, rather than use one single directory for all
architectures object files. This is similar to what "app" module does,
by keeping all object files in arch-specific dir:

    app/.cxx/cmake/debug/${ANDROID_ABI}/...

where ${ANDROID_ABI} is one of architectures listed above.

This issue matters for hello-libs based apps which build some native
libraries along with Java code (rather than using prebuilt .a/.so
versions).

Steps to reproduce (without this patch applied):
  1. Remove hello-libs/distribution/ dir
  2. Import hello-libs project in Android Studio
  3. Uncomment gen-libs related lines in settings.gradle and in
     app/build.gradle; sync project with gradle files
  4. Build the app
  5. Remove hello-libs/distribution/ dir
  6. Build the app again, incrementally (not doing clean build)

Also, you can examine ~/tmp/ dir with and without this patch, to see
what changes exactly.

Signed-off-by: Sam Protsenko <joe.skb7@gmail.com>
2019-10-31 11:40:20 -07:00
Gerry
85a3f6a13d fix issue b/143084750 (#660) 2019-10-31 11:24:45 -07:00
Gerry
23c7df1fcf hello-oboe: add specific oboe-lib version to use (#650) 2019-08-20 13:22:39 -07:00
Gerry
21b8b02662 Minor update to hello-oboe sample concerning error handling. (#648) 2019-08-13 08:28:30 -07:00
Atneya Nair
5bedba530f Merge pull request #647 from googlesamples/hello-oboe
Basic Oboe example.
2019-08-08 09:12:26 -07:00
Atneya Nair
ea02085b6d Adding screenshot 2019-08-07 19:20:31 -07:00
Atneya Nair
889314052f Adding required documentation for use as samples 2019-08-07 17:06:08 -07:00
Atneya Nair
da6092abd9 Updating gradle and renaming method 2019-08-07 14:40:14 -07:00
Atneya Nair
efe8e95144 Cleaning build files and gitignore 2019-08-07 13:48:51 -07:00
Atneya Nair
e435de477b Addressing comments 2019-08-06 17:31:27 -07:00
Atneya Nair
90fe84481b Basic Oboe example. 2019-08-05 15:35:39 -07:00
Gerry
86ceeb248b added more instruction to build native-midi with studio (#630) 2019-03-18 11:10:30 -07:00
Don Turner
9132feeea7 Fix instructions for setting up NDK r20 dependency (#629) 2019-03-14 10:22:27 -07:00
Gerry
957806a765 Add native-midi sample for Android Q (Api-level 29) (#626)
Tested: Android Q GSI Beta + Pixel 3

Change-Id: I6b18fc189cf85de881780a0bc2f8a98c66f1f310
2019-03-13 13:26:21 -07:00
Gerry
f02e0e9724 Update build script to version 3.3.1 (#622) 2019-02-22 13:58:26 -08:00
Gerry
ae568ca67d Update README.md 2019-02-13 09:16:29 -08:00
Gerry
2885276d4c CI script update: no need to install with constraintLayout 1.0.2+ (#618) 2019-01-31 15:06:21 -08:00
Gerry
e55fa5ec38 Sample: display-p3 (#617)
Change: updated README.md, add a few images
Tested: Pixel3 + GSI
2019-01-29 18:37:58 -08:00
Gerry
2e0594d970 Revert "Update build script to version 3.3.0" (#616)
* Revert "Sample: display-p3 (#614)"

This reverts commit 71fd1a1601.

* Revert "Update build script to version 3.3.0 (#612)"

This reverts commit 2464cf2943.
2019-01-29 17:55:35 -08:00
Gerry
71fd1a1601 Sample: display-p3 (#614)
Change: updated README.md, add a few images
Tested: Pixel3 + GSI
2019-01-28 10:24:16 -08:00
Gerry
2464cf2943 Update build script to version 3.3.0 (#612) 2019-01-14 18:40:31 -08:00
Gerry
ac03edbe38 update teapot sample cmake build to use common lib (#601) 2019-01-10 17:45:46 -08:00
Gerry
2ca646d709 Sample: otherbuild\gl3init -- removing redundant minSdk requirment in AndroidManifest.xml (#611)
Tested: Pixel3 XL GSI image
2019-01-10 17:26:17 -08:00
Gerry
5ef0bf3611 hello-gl2: fix a typo (#610) 2019-01-10 15:48:24 -08:00
Gerry
373925bdcf Sample bugfix: (#609)
hello-lib use CMAKE_CURRENT_SOURCE_DIR instead as Studio 3.4 is going
    to make a template CMake Project, from which calling into application's
    top level CMakelists.txt
Tested:
    Pixel3 XL with Pie GSI
2019-01-10 15:17:34 -08:00
Gerry
36f1ed3ee8 Sample native-audio: fix github issue 598 (#608)
Tested:
    Pixel XL
2019-01-10 14:07:57 -08:00
Don Turner
7620a5740c Merge pull request #607 from googlesamples/jettify
Migrate projects to AndroidX
2019-01-10 19:19:17 +00:00
Don Turner
6d57e3633c Change to stable androidx versions, add license 2019-01-10 19:03:05 +00:00
Don Turner
c814ef8e3d Migrate projects to AndroidX 2019-01-10 17:54:28 +00:00
Gerry
a6fe0fb80b minor formatting a few samples' build.gradle, no functional change (#599) 2018-12-09 11:13:58 -08:00
Gerry
8132651aba Samples: try google() maven repo before using jcenter() (#593)
necessary for teapot sample with new version of Android gradle plugin
2018-10-31 20:01:33 -07:00
koseonjae
65acc92b11 Fix logic to push wrong buffer to free queue (#590) 2018-10-30 11:13:40 -07:00
Gerry
0d09e41320 NativeMedia sample: use application's assetManager (#573)
* NativeMedia sample, fixing github issue 571

* Adding global reference to AssetManager on native side
2018-09-13 09:44:39 -07:00
Gerry
0ee3ad13d5 Fix unnecessary re-build for ndk_helper under teapots sample (#566) 2018-09-04 17:38:57 -07:00
daquexian
bae4677473 Update the comment in helloneon.c (#565)
Android.mk -> CMakeLists.txt
2018-09-04 09:28:34 -07:00
Gerry
29fa1bbae8 Link Camera sample doc to blog posts (#564) 2018-08-30 13:56:19 -07:00
Gerry
b360a26f0e Minor update to hello-libs (#563) 2018-08-30 11:53:13 -07:00
Gerry
c9f39dc6e6 Merge pull request #556 from googlesamples/cubemap-teapot
Adding cubemap to teapot sample
2018-08-20 16:43:52 -07:00
gfan
d55315754f Adding cubemap to teapot sample 2018-08-20 16:16:38 -07:00
Gerry
f6f722fa25 Merge pull request #555 from googlesamples/textured-teapot
Adding textured-teapot sample for github issue #314
2018-08-16 18:20:14 -07:00
gfan
ff7f4f76bd Adding textured-teapot sample for github issue #314 2018-08-16 18:15:27 -07:00
gfan
a00d6b1e1a Fix sample audio clip link for native-audio 2018-08-09 16:10:52 -07:00
Gerry
91548abfc1 Merge pull request #553 from jhasse/webp-branch
Clone 1.0.0 branch of libwebp instead of master
2018-08-09 08:09:30 -07:00
Jan Niklas Hasse
83f6c5dada Clone 1.0.0 branch of libwebp instead of master 2018-08-09 15:10:21 +02:00
gfan
93339e548e audio-echo: fix the mono channelMask issue in audio_common.cpp 2018-07-30 16:15:55 -07:00
Gerry
d3943a02d3 Merge pull request #551 from RushiBhatt007/patch-1
typo in readme
2018-07-26 13:58:13 -07:00
Rushi Bhatt
1ee2eae7ba typo in readme 2018-07-27 01:22:09 +05:30
gfan
1500df8913 Teapot sample: adding code according github issue#508 2018-07-20 11:13:56 -07:00
Gerry
1ca97f0cd9 Merge pull request #548 from googlesamples/github-issue-543
Camera Sample: catch & ignore exception from UI to avoid app crash
2018-07-17 11:16:27 -07:00
gerry
997a4d6a30 Camera Sample: catch & ignore exception from UI to avoid app crash 2018-07-17 11:11:18 -07:00
Gerry
fe2c9a5d81 Merge pull request #547 from googlesamples/update-gradle-version
Update to android studio 3.1.3 for all samples
2018-07-16 19:29:02 -07:00
gerry
db61db9274 Update to android studio 3.1.3 for all samples 2018-07-16 18:45:52 -07:00
gerry
f3f60d6b67 Update neon header file for hello-neon sample 2018-07-16 15:46:56 -07:00
Gerry
08e8730baf Merge pull request #544 from googlesamples/ndk18-update
Prepare for ndk-r18 release
2018-07-16 15:45:07 -07:00
gerry
fea8fc7bc6 Prepare for ndk-r18 release 2018-07-14 07:18:53 -07:00
Gerry
33789f3a04 Merge pull request #542 from googlesamples/camera-simulator-fix
Camera Sample: Adding checks for individual camera feature request
2018-07-09 18:52:57 -07:00
gerry
83e99be488 Camera Sample: Adding checks for individual camera feature request 2018-07-09 18:47:12 -07:00
gfan
fc2ed743f9 NativeAudio: disable ( instead of hiding ) uriPlayer UIs 2018-06-29 11:21:11 -07:00
gfan
7ffe0aa7ca Merge branch 'master' of github.com:googlesamples/android-ndk 2018-06-26 11:41:31 -07:00
gerry
144f471abd fixing a bug brought up by @wlbe4: need deep copy of pointers 2018-06-14 08:37:00 -07:00
gerry
deff23178d Minor change for hello-libs's build.gradle and ci script 2018-06-11 22:53:09 -07:00
gerry
ef3621d36e Minor change for hello-libs's build.gradle 2018-06-08 16:11:47 -07:00
gerry
b49c12338b audio-echo: adding a delay effect to the loopback audio path 2018-06-08 15:49:49 -07:00
Gerry
ba2836c7a1 Merge pull request #532 from googlesamples/fix-camera-bug
Fix a bug in camera sample: should copy values instead of pointers
2018-05-29 17:20:40 -07:00
gerry
09c2e54b83 Fix a bug in camera sample: should copy values instead of pointers 2018-05-29 17:04:46 -07:00
Gerry
c065c0a91b Merge pull request #529 from googlesamples/merge-ci
Merge CI-Enabling code
2018-05-18 15:17:18 -07:00
gfan
d0c5bd8160 Fixing travis-ci checked items for constraint-layout version
Change-Id: I65af62d9a052d0e406f8e78805838013faa3107a
2018-05-18 14:47:50 -07:00
gfan
c9714ce64e Re-enable CI for the repo
Change-Id: Ia9a1cac430006f66dffd5702e6e2d8aa2c857d66
2018-05-18 13:17:29 -07:00
guanghuafan
0514d1cec8 Converting nn_sample to Kotlin
Change-Id: Ia0a0ed21e178fb69202b40cc34e0aac7ae05b10e
2018-05-11 15:58:40 -07:00
guanghuafan
7a77bce972 Back merge from public to internal branch 2018-05-11 14:50:23 -07:00
Gerry
d27faab3f4 Merge pull request #521 from googlesamples/bug79184992
fix for b2/79184992
2018-05-03 19:23:27 -07:00
guanghuafan
7069a8dc1b Real fix for b2/79184992 concerning NdkHelper:
- remove  ndk_helper::SensorManager::Process()
  - add -Wno-attributes for gcc case
2018-05-03 14:46:26 -07:00
Gerry
7297fc9952 Merge pull request #518 from googlesamples/b2-78915221
Removed native-activity & endless-tunnel from Java sample list
2018-05-03 13:54:02 -07:00
Gerry
ee9be9402d Merge pull request #516 from googlesamples/cmake-update
Update Teapot CMake scripts for review
2018-05-02 09:50:57 -07:00
guanghuafan
a0b9385daf Removed the following samples from Java sample list
native-activity
  endless-tunnel
  native-plasma
  webp

Related bug: b2/78915221
2018-05-01 17:51:26 -07:00
guanghuafan
5f2cebe64e Update Teapots CMake scripts to adopt CMake's module practice
- using cmake's compile features whenever possible
  - target and module oriented
  - adopting a style for scripts
2018-05-01 15:11:01 -07:00
Gerry
f14c2b583b Merge pull request #507 from googlesamples/shader-sequence-fix
fix shader qualification sequence in endless tunnel sample
2018-03-12 17:21:43 -07:00
gfan
8f92e43e1e fix shader qualification sequence in endless tunnel sample 2018-03-12 17:11:08 -07:00
Gerry
0b8aae2e27 Merge pull request #506 from rprichard/remove-mips
Remove mips from san-angeles' ABI list.
2018-03-12 11:50:26 -07:00
Ryan Prichard
d19aafeddb Remove mips from san-angeles' ABI list.
The ndk-build version of this sample already has this list of ABIs:

    include 'armeabi-v7a', 'arm64-v8a', 'x86'

Bug: https://github.com/googlesamples/android-ndk/issues/505
2018-03-09 15:18:57 -08:00
Gerry
110f6044a6 Merge pull request #503 from googlesamples/display-p3-update
Add popup window display duration ( 1 sec )
2018-03-07 08:53:39 -08:00
guanghuafan
fed6eea2fe Add popup window display duration ( 1 sec ) so we have single layer at compositor. 2018-02-27 09:16:10 -08:00
Gerry
9a6d6cc422 Merge pull request #501 from courtney-g/180223-fp16-bug
Set float when requesting FP16 pixel format
2018-02-23 08:18:36 -08:00
Courtney Goeltzenleuchter
8496674109 Set float when requesting FP16 pixel format
Set color component type to fload for FP16 not 10:10:10:2.
Also set color component type to fixed for all other modes just to
be complete.
2018-02-23 08:15:09 -07:00
Gerry
a63c3b6319 Merge pull request #500 from googlesamples/fix-73597988
Fix 73597988
2018-02-22 16:13:38 -08:00
gfan
a063d299ce Fix b/73597988: endless-tunnel uniform needs to be at the same precision 2018-02-22 16:01:44 -08:00
Gerry
fcf2b3c0f0 Merge pull request #495 from googlesamples/nn_sample
add ndkbuild for nn_sample in master branch
2018-02-12 14:26:02 -08:00
guanghuafan
0d45f4fbf0 add ndkbuild for nn_sample in master branch 2018-02-12 14:20:36 -08:00
guanghuafan
141c6fd905 adding one kotlin sample (converted from hello-jni ) 2018-01-22 11:24:58 -08:00
guanghuafan
4fbe849d8e Rename android-jni-kotlinApp to hello-jni-kotlinApp
Change-Id: Ie09c76969b06e75dd28a98fbd3c41972381b0a51
2018-01-22 10:34:25 -08:00
guanghuafan
626ab90d81 converting hello-jni to kotlin
Change-Id: Ic02c5ca478326c5359e82a23b65a30ebf3f0e8a5
2018-01-19 15:21:13 -08:00
Gerry
00e793b416 Merge pull request #482 from googlesamples/gles3jni-update
Cleaning up gles3jni sample, details in:
2018-01-07 17:55:49 -08:00
guanghuafan
c05adf5ed5 Cleaning up gles3jni sample, details in:
https://github.com/googlesamples/android-ndk/issues/481
2018-01-06 20:44:52 -08:00
Gerry
d9fbf655d9 Merge pull request #479 from uniqueid001/master
Fixed typos in README.md
2018-01-04 14:01:54 -08:00
dhudson
037e51c502 Fixed typos in README.md 2018-01-04 16:58:49 -05:00
Gerry
41640c2646 Merge pull request #477 from googlesamples/neon-readme-update
Update hello-neon README.md to call out release build
2017-12-27 14:12:58 -08:00
guanghuafan
3665f87044 Update hello-neon README.md to call out release build 2017-12-27 14:10:06 -08:00
guanghuafan
19af5fe397 clean-up gradle scripts: leave teapot samples as detailed example,
cleaning the rest to use default and recommend settings

Change-Id: I81d49ff0ca411bd923d2b9cd01481a20642e8a64
2017-12-19 14:49:39 -08:00
guanghuafan
ecd28f01df Merge remote-tracking branch 'github/master'
Change-Id: I9478acde97143e05188ff6af48a43c47d64e8fbd
2017-12-18 10:11:24 -08:00
Gerry
7be737f965 Merge pull request #471 from googlesamples/deprecate-armeabi
Remove the deprecating armeabi ABI from build
2017-12-15 12:31:48 -08:00
guanghuafan
1251a9ae57 Remove the deprecating armeabi ABI from build 2017-12-14 14:58:49 -08:00
Gerry
19cdf4a97d Merge pull request #470 from googlesamples/travis-ndk-update
update travis.ci's NDK to r16b
2017-12-13 14:06:39 -08:00
gfan
ba6a5a46cf update travis.ci's NDK to r16b 2017-12-13 13:39:20 -08:00
Gerry
70532a23d0 Merge pull request #465 from CainKernel/master
Fix #464 Memory Bug
2017-12-04 21:16:30 -08:00
cain
4342f10ecb Fix #464 Memory Bug 2017-12-05 10:38:56 +08:00
Gerry
9105871c5c Merge pull request #463 from miaowang14/master
Simple NN API code sample
2017-12-01 15:26:07 -08:00
Miao Wang
4ca6cf8bcf Simple NN API code sample 2017-12-01 14:41:00 -08:00
Miao Wang
c8483ba25e Simple NN API code sample 2017-12-01 14:24:20 -08:00
Miao Wang
bed770394b Merge "Simple NN API code sample" 2017-12-01 22:04:07 +00:00
Miao Wang
36829c8831 Simple NN API code sample
Change-Id: I49acd9fd09cf72303a1bd4b67ecaf29de032d043
2017-12-01 13:50:40 -08:00
Hakuro Matsuda
7b67b11152 Merge pull request #462 from googlesamples/gl3esjni-update
Minor update gles3jni to use version 3.2 headers for API 24+
2017-12-01 16:46:31 +09:00
guanghuafan
ee7d81d25d Minor update gles3jni to use version 3.2 headers when building for api level 24+ 2017-11-30 21:18:36 -08:00
Gerry
840858984e Merge pull request #461 from googlesamples/ndkbuild-abspath-fix
add abspath workaround for windows ndk-build projects
2017-11-29 16:10:57 -08:00
guanghuafan
1ad4d0903e add abspath workaround for windows ndk-build projects
tested: Windows & Mac OS
2017-11-29 15:47:47 -08:00
Gerry
8d8f692515 Merge pull request #460 from googlesamples/libs-documentation
Fix wrong doc in hello-libs' README.md
2017-11-29 11:09:25 -08:00
guanghuafan
ce096f5a90 Fix wrong doc in hello-libs' README.md 2017-11-29 09:22:28 -08:00
guanghuafan
ae0bb4de87 Update ndk-build and experimental build scripts to Android Studio 3.0.1
directory: other-builds
tested: Mac OS
2017-11-28 23:41:44 -08:00
Gerry
f7559b1bd2 Merge pull request #458 from googlesamples/AS-3.0-update
Update CMake build to Android Studio 3.0.0
2017-11-28 16:45:55 -08:00
guanghuafan
982fe0ea3f Update CMake build to Android Studio 3.0.0 2017-11-28 16:31:55 -08:00
Gerry
8cefd52cc0 Merge pull request #457 from googlesamples/hello-libs-newline-fix
hello-libs: added newline to the end of app/build.gradle
2017-11-27 08:15:21 -08:00
guanghuafan
452325872c hello-libs: added newline to the end of app/build.gradle according to codereview 2017-11-27 08:04:22 -08:00
Gerry
5ce57be98c Merge pull request #456 from googlesamples/issue-450-fixup
Patch for https://github.com/googlesamples/android-ndk/issues/450
2017-11-26 21:26:06 -08:00
guanghuafan
1d853dcd0e Patch for https://github.com/googlesamples/android-ndk/issues/450 to disable lib build
Tested: Android 8.0 Oreo / Pixel XL
2017-11-26 21:18:27 -08:00
Gerry
a919f0a182 Merge pull request #455 from joe-skb7/master
hello-libs: Update to Gradle plugin 3.0.1 and fix collateral issues
2017-11-26 20:21:50 -08:00
Sam Protsenko
66f5d19575 hello-libs: Move to Gradle plugin 3.0.1
In Android Studio 3.0 there is new Gradle plugin available. Update
project build files correspondingly (so it works with new Gradle).

Signed-off-by: Sam Protsenko <joe.skb7@gmail.com>
2017-11-23 00:46:57 +02:00
Sam Protsenko
121545716f hello-libs: Remove pre-build libraries
Remove distribution directory with pre-built libraries, because:
 1. Keeping binary files under Git control is considered a bad practice
 2. It can be confusing, because we want to demonstrate how to build
    those 3rd party libraries (for all architectures of interest) and
    distribute (install) them manually.

Signed-off-by: Sam Protsenko <joe.skb7@gmail.com>
2017-11-23 00:46:57 +02:00
Sam Protsenko
561ca312b3 hello-libs: Fix dependencies issue with new Gradle plugin
Before Gradle plugin 3.0.0 (Android Studio before 3.0), building app
module was starting building of externalNativeBuild of gen-libs module,
as dependency. Indeed, we have this dependency declared at
app/build.gradle file:

    dependencies {
        compile project(':gen-libs')
    }

But after updating Android Studio to v3.0.1 (and Gradle plugin to v3.0.1)
build error started to appear. That build error is connected with unmet
dependencies (attempt to build libhello-libs.so before gen-libs module
libraries). So I presume it's some bug in new Gradle or new Gradle
plugin. If so, this patch is just a workaround. Still we need it until
the issue is fixed in Gradle/plugin. This issue was first reported as
 #450 (see [1]), and then reported to Google ([2]).

With this patch, next sequence works fine:

  1. Remove pre-built libraries (distribution/ directory)
  2. Enable gen-libs module building (comment out corresponding lines
     in app/build.gradle and settings.gradle files)
  3. Start project building

[1] https://github.com/googlesamples/android-ndk/issues/450
[2] https://issuetracker.google.com/issues/69616088

Signed-off-by: Sam Protsenko <joe.skb7@gmail.com>
2017-11-23 00:30:58 +02:00
Sam Protsenko
12b56395dc hello-libs: Add abiFilters to gen-libs module
After updating Android Studio to v3.0.1 (and Gradle plugin to v3.0.1),
I noticed that libhello-libs.so is being built for more architectures
than libgperf.so. Also I noticed that app/build.gradle has abiFilters,
but gen-lib/build.gradle doesn't. This leads to linking errors. That
issue is reported as #450. See [1] for details.

Adding the same abiFilters line to gen-lib/build.gradle fixes the issue.

While at it, remove armeabi architecture from app/build.gradle
abiFilters, as it's deprecated now. See [2] for details.

[1] https://github.com/googlesamples/android-ndk/issues/450
[2] https://developer.android.com/ndk/guides/abis.html

Signed-off-by: Sam Protsenko <joe.skb7@gmail.com>
2017-11-23 00:11:03 +02:00
Gerry
0730b1481d Merge pull request #452 from TheScottyJr/patch-1
Replaced deprecated display.getWidth() and display.getHeight()
2017-11-18 11:45:16 -08:00
Scotty Stephens
bc09c07703 Updated Plasma.java
display.getWidth() and display.getHeight() are deprecated
2017-11-18 11:46:52 -05:00
Gerry
ac44886a2e Merge pull request #451 from googlesamples/build-update
Update samples to build with new NDK (15/16) about cstring header file
2017-11-15 05:51:10 -08:00
guanghuafan
be3c1073d9 Update samples to build with new NDK (15/16) about cstring header file 2017-11-15 05:28:05 -08:00
guanghuafan
fe5ebe49b7 Removing existing nnapi sample ( non-published )
Change-Id: Ib8ee66c9c185054bbd79ee2a68b8ba46dc8badf5
2017-11-14 11:48:20 -08:00
Hakuro Matsuda
4df5a2705e Merge pull request #447 from googlesamples/issue-439
Teapot samples: bugfix for 439
2017-11-03 19:42:05 +09:00
guanghuafan
544f79e832 Teapot samples: Fixing reported issue: https://github.com/googlesamples/android-ndk/issues/439 2017-11-02 22:17:47 -07:00
Gerry
2020d9674a Merge pull request #446 from googlesamples/fix-readme-from-pr-325
Integrate changes from PR-325
2017-10-31 14:54:39 -07:00
guanghuafan
96a8d9f6c4 Integrate changes from PR-325 2017-10-31 14:53:03 -07:00
guanghuafan
d62990d07e hello-neon build change: replace productFlavor with ndk.abiFilters in module build.gradle 2017-10-31 11:27:38 -07:00
Gerry
bf81ce11cb Merge pull request #445 from googlesamples/AS-3.0-update
Update build for Android Studio 3.0
2017-10-31 10:51:10 -07:00
guanghuafan
c1cf5243a0 Update build for Android Studio 3.0 2017-10-31 10:45:56 -07:00
gfan
37f050a694 NNAPI Sample: Addressing more code review feedback
Change-Id: Ib475453cc8d663eff36258c319f6118bbb5aa534
2017-10-26 16:26:01 -07:00
Gerry
f9f26dfce3 Merge pull request #443 from DanAlbert/fix-includes
Add missing includes to the teapots sample.
2017-10-26 11:54:29 -07:00
Gerry
5f472ab8bd Merge pull request #442 from rayworks/master
destroy the thread attributes properly
2017-10-26 11:52:11 -07:00
Dan Albert
085a6a42a1 Add missing includes to the teapots sample.
The newest NDK cleans up some accidental transitive includes, so decls
from these headers are no longer being leaked.
2017-10-26 11:41:45 -07:00
rayworks
5f47759b78 destroy the thread attributes properly 2017-10-26 09:25:02 +08:00
guanghuafan
ff56425aa7 Adding NNAPI sample under nnapi directory
Change-Id: I11fe96ac81b8e551be9ca5d5b47a54914384f8e1
2017-10-19 21:44:55 -07:00
Gerry
e3a4c5c4b4 Merge pull request #440 from justinjoy/pr/camera-entry-loop
camera/**/camera_manager.cpp: iterate entry properly
2017-10-10 09:53:50 -07:00
Justin Kim
7c57321e53 camera/**/camera_manager.cpp: iterate entry properly
entry.count has the total number of entry.

Signed-off-by: Justin Kim <justin.kim@collabora.com>
2017-10-10 11:10:31 +09:00
Gerry
6862354e75 Merge pull request #434 from dturner/patch-1
Improve readability for README.md
2017-09-08 14:22:38 -07:00
Don Turner
fb592e78a3 CMakeLists.txt sequence now correct 2017-09-08 22:19:41 +01:00
Don Turner
abbaf0f7eb Improve readability for README.md 2017-09-08 19:14:47 +01:00
Gerry
f5bb5e68a4 Merge pull request #432 from sjfricke/master
refactored ImageReader::PresentImages
2017-09-04 20:30:56 -07:00
sjfricke
5dbb7de0b6 refactored ImageReader::PresentImages
Moved all ints to int32_t to be type safe and removed assert checking from each seperate present image degree switch function
2017-09-04 18:16:06 -05:00
Gerry
6b6639aaf7 Merge pull request #431 from sjfricke/image-reader
Camera: added GetLatestImage method
2017-08-30 22:19:52 -07:00
sjfricke
c23af27415 Camera: added GetLatestImage method
As this being a very main source for anyone learning to use the Native Camera API calls it would be nice to show more information that if they plan to do real time processing that they should not be using  as it will cause huge delay when scaling up resolution of preview. Just adding the extra comment and function can help prevent searching and trying to debug why there is such a random image delay
2017-08-31 00:08:10 -05:00
Gerry
ec8b01d255 Merge pull request #430 from googlesamples/issue392-fix
native-media: fix issue 392
2017-08-29 16:03:01 -07:00
guanghuafan
d1e9e9aa8e native-media: fix issue 392. Tested on NDK-r12b 2017-08-29 14:53:43 -07:00
Gerry
647a22d2e6 Merge pull request #428 from googlesamples/sample-wcg
adding sample wcg
2017-08-25 15:03:03 -07:00
guanghuafan
32ef8066b7 adding wide color gamut ( display P3 ) sample: display-p3
Change-Id: I32fbdaa193bad6c10a3ebd63c4c7eccbe5c8aee7
2017-08-25 14:59:38 -07:00
guanghuafan
e9d20b27b9 rename DisplayP3Image to display-p3
Change-Id: Id7f052b22a861b1513925528e5855d508a8f2c15
2017-08-24 15:47:21 -07:00
Gerry
65481f0a09 Merge pull request #427 from googlesamples/camera-basic-add-thread
camera/basic sample: write file in a separate thread
2017-08-21 23:03:33 -07:00
guanghuafan
94b34fdfbd camera/basic sample: write file in a separate thread 2017-08-21 23:00:34 -07:00
Gerry
c200ed13c0 Merge pull request #426 from googlesamples/fix-issue-425
fix github issue 425
2017-08-21 15:14:43 -07:00
guanghuafan
4c1dceef59 Adding toast to prompt the capture jpg location for
https://github.com/googlesamples/android-ndk/issues/425
2017-08-21 13:23:03 -07:00
guanghuafan
501170b366 publish camera texture-view to camera/texture-view 2017-08-20 23:02:12 -07:00
guanghuafan
02f5c60446 Add camera texture-view sample into camera/texture-view
Change-Id: I8dc476b5aba300c9cce97d2d67927749bae83d67
2017-08-20 22:38:45 -07:00
Gerry
54bb32e8c4 Merge pull request #424 from googlesamples/hello-neon-update
Sample Update
2017-08-15 11:46:33 -07:00
guanghuafan
dab9270d94 Sample Update -- hello-neon:
minor format updates in printf and build script
   compile flags matched the ones inside branch master-ndkbuild
2017-08-15 10:30:53 -07:00
guanghuafan
79d3b91f6e Prepare to release camera sample to public
Change-Id: I276bce881a619efe8acebeaec277a3aeb7915533
2017-08-11 14:38:58 -07:00
guanghuafan
028943ba2f Adding basic camera sample for review
Change-Id: Ib26e2dfb3fbdd00a94e39b2b02f7226ec5521114
2017-08-11 14:14:59 -07:00
guanghuafan
8b1657888e Minor change in comment
Change-Id: I1a548420d6dc0991123af0a4d49c7926ae5865c9
2017-08-04 12:04:06 -07:00
Gerry
c2be70fb07 Merge pull request #421 from googlesamples/hello-neon-update
Hello neon update
2017-07-28 15:49:34 -07:00
guanghuafan
74fc5c6742 hello-neon: port the original neon intrinsics for x86:
https://github.com/googlesamples/android-ndk/issues/420

Tested on: nexus player, debug buid, around ~40% boost
2017-07-28 15:00:06 -07:00
guanghuafan
08e36ecdd5 Android Studio 3.0.0 dimension update
Info:
https://developer.android.com/studio/build/gradle-plugin-3-0-0-migration.html?utm_source=android-studio#variant_aware
2017-07-27 20:08:45 -07:00
Gerry
3fc9759238 Merge pull request #417 from googlesamples/experimental-build-version-update
Update experimental build for ndk-r15
2017-07-27 17:10:01 -07:00
guanghuafan
34c90893d5 Update experimental build for ndk-r15 2017-07-27 17:08:10 -07:00
guanghuafan
a9b96b9e2e Update minSdkVersion/NDK to 14 2017-07-24 20:51:27 -07:00
guanghuafan
15e98b333b DisplayP3ImageView:
create third_party directory if not exists with gradle script

Change-Id: Icd38fe2c228eb938f18e5cb4d27901d125324f2c
2017-07-23 15:23:47 -07:00
Gerry
099fdb134f Merge pull request #412 from googlesamples/audio-echo-ui
audio-echo: update UI, no functional change
2017-07-18 18:09:03 -07:00
guanghuafan
bbe1887918 audio-echo: update UI, no functional change 2017-07-18 18:05:51 -07:00
guanghuafan
e651dfc250 Adding DisplayP3ImageView sample
Change-Id: Ia76286963756acbbc802032a3061779819c3fae8
2017-07-18 17:01:40 -07:00
Gerry
4a0b0345ff Merge pull request #410 from googlesamples/echo-fix
fixing issue in audio-echo
2017-07-18 10:54:39 -07:00
Gerry
9c9a261426 Merge pull request #411 from googlesamples/choroegrapher-comment-change
teapot project, chorographer-30fps: update comment
2017-07-18 08:27:47 -07:00
guanghuafan
43b6765cfe teapot project, chorographer-30fps: update comment to address code-review 2017-07-17 21:31:22 -07:00
guanghuafan
58a539c092 audio-echo: play silent buffers at the beginning then,
inside player callback thread, switch to
            the captured frames when audio has indeed
            captured from recorder
native-audio:
            release lock when resetting playback to CLIP_NONE
2017-07-17 17:50:23 -07:00
Gerry
582a5f6e7b Merge pull request #409 from googlesamples/choroegrapher-api-17-fix
pass choreopher timestamp from java to jni to get correct 30 fps
2017-07-12 17:06:41 -07:00
guanghuafan
8ff094e003 pass choreopher timestamp from java to jni to get correct 30 fps 2017-07-12 16:57:27 -07:00
Gerry
161bc4ca8a Merge pull request #408 from googlesamples/jnihelper-fix
JNIHelper update
2017-07-12 16:49:43 -07:00
guanghuafan
5848d0f4a6 handles the case when getExternalFilesDir() returns NULL case in JNIHelper
this avoid the hang when running on android-17
2017-07-12 15:32:18 -07:00
Gerry
6ce21f99e0 Merge pull request #407 from googlesamples/choreographer-update
update choreographer-30fps to render according to time-stamp
2017-07-12 14:22:14 -07:00
guanghuafan
ed0473128d update choreographer-30fps to render according to time-stamp 2017-07-12 09:27:16 -07:00
Gerry
3eb8e661f1 Merge pull request #403 from Jose-Parente/addGoogleRepository
Add google maven repository declaration
2017-07-11 12:54:41 -07:00
Gerry
c333a0c00f Merge pull request #405 from googlesamples/asensormanager-getinstance-fix
workaround ASensorManager_getInstance() deprecation issue in NDK-r15
2017-07-11 12:53:32 -07:00
guanghuafan
a748044c71 workaround ASensorManager_getInstance() deprecation issue in NDK-r15 2017-07-11 11:32:15 -07:00
parentej
4ae02bc43c Add google maven repository declaration
com.android.support:appcompat-v7 is no longer available
on the Android SDK off-line repository, it needs to be
downloaded from the google online repository instead
2017-06-26 14:44:26 +01:00
Gerry
bfdc36d7ed Merge pull request #400 from googlesamples/native_app_glue_fix
Remove app_dummy() from NativeActivity derived samples
2017-06-20 16:51:13 -07:00
guanghuafan
f50e487927 Remove app_dummy() from NativeActivity derived samples
to fix build warnings. Refer to: https://github.com/android-ndk/ndk/issues/381
2017-06-20 11:54:06 -07:00
Gerry
a00e94db9b Merge pull request #399 from stolk/master
Request an ES3 context, not an ES2 context.
2017-06-16 17:57:12 -07:00
Bram Stolk
a0b2107d36 Request an ES3 context, not an ES2 context. 2017-06-14 12:03:22 -07:00
Gerry
80af267251 Merge pull request #396 from googlesamples/teapot-shader-precision-fix
Fixing mis-matching precision for vMaterialSpecular in shaders
2017-06-12 21:20:33 -07:00
guanghuafan
75ddc607ea Fixing mis-matching precision for vMaterialSpecular in shaders 2017-06-12 21:11:21 -07:00
guanghuafan
6c69adc749 make webp to compile with ndk-r15 canary build
modified:   webp/view/CMakeLists.txt
2017-06-05 17:31:15 -07:00
Gerry
bf9bc364dc Merge pull request #390 from googlesamples/cdep
Update hello-cdep to include all ABIs
2017-05-16 19:26:22 -07:00
guanghuafan
f45281b422 Update hello-cdep to include all ABIs 2017-05-16 19:21:56 -07:00
Gerry
763de3d9d5 Merge pull request #389 from googlesamples/cdep
Adding CDEP example
2017-05-16 15:18:02 -07:00
guanghuafan
2c12300aa6 Adding CDEP example 2017-05-16 15:17:10 -07:00
Gerry
6b9c06ab42 Merge pull request #387 from googlesamples/fix-379
fixing github issue #379
2017-05-10 18:22:06 -07:00
guanghuafan
5c4099d839 fixing github issue https://github.com/googlesamples/android-ndk/issues/379 2017-05-10 18:18:44 -07:00
Gerry
fec5d88d36 Merge pull request #378 from googlesamples/webpupdate
Update webp to clone libwebp repo as native code dependency
2017-04-13 11:22:12 -07:00
ggfan
43db47722a Update webp to clone libwebp repo as native code dependency 2017-04-12 18:46:17 -07:00
Gerry
dd30b1f934 Merge pull request #375 from googlesamples/webp
fix bug in webp sample for releasing memory and function return type
2017-03-31 15:50:58 -07:00
guanghuafan
e468e9884c fix bug in webp sample for releasing memory and function return type 2017-03-31 14:57:43 -07:00
Gerry
842fcd9c9c Merge pull request #376 from DanAlbert/no-gcc
Stop hard coding GCC.
2017-03-31 12:08:36 -07:00
Dan Albert
64c31c08a0 Stop hard coding GCC.
This has been deprecated for over a year.
2017-03-31 11:43:24 -07:00
Gerry
db9f73f10e Merge pull request #374 from googlesamples/isnan-update
Update Teapot sample to use C++11's std::isnan()
2017-03-30 16:30:19 -07:00
ggfan
81c3648b0d Update Teapot sample to use C++11's std::isnan()
Compiler is tighting supportability in earlier versions
to comply with standard
2017-03-30 16:16:11 -07:00
Gerry
becff48d0d Merge pull request #373 from googlesamples/clang-update
Use clang to build teapot samples
2017-03-30 15:57:56 -07:00
ggfan
d4eca6261d Use clang to build teapot samples, gcc is not supported 2017-03-30 15:48:52 -07:00
Gerry
6fd4907f36 Merge pull request #370 from googlesamples/unified-header-fix
Fix unified header related issues:
2017-03-23 09:45:26 -07:00
guanghuafan
68a03a83f3 Fix unified header related issues:
1) included OpenSLES.h BEFORE OpenSLES_Android.h
       OpenSLES.h inclusion is removed from OpenSLES_Abndroid.h
  2) added stdlib.h/cstdlib concerning malloc for sample
       endless tunnel
       native-activity
       teapots derivative samples
2017-03-22 18:31:57 -07:00
Gerry
dc29d85c34 Merge pull request #368 from googlesamples/gles3init-fix
fix OpenGL2 min android version
2017-03-10 13:00:08 -08:00
guanghuafan
aafd24e614 fix OpenGL2 min android version 2017-03-10 12:45:29 -08:00
Gerry
39e4f6d348 Merge pull request #353 from adithya321/master
Update SDK Version to 25
2017-03-07 08:59:08 -08:00
Adithya J
50cda1932c Update support library version to 25.2.0 2017-03-07 17:55:48 +05:30
Adithya J
9d8bc765b6 Update Android Plugin for Gradle to 2.3.0 2017-03-07 16:24:45 +05:30
Gerry
4fc1943ceb Merge pull request #363 from phillipao/patch-3
Fix an outdated link in README.md
2017-02-21 18:55:51 -08:00
Phillip Oertel
20c21ce06d Fix an outdated link in README.md
http://tools.android.com/tech-docs/external-c-builds has a redirector gadget. The gadget is broken, but the source has a reference to https://developer.android.com/studio/projects/add-native-code.html, so I guess that's the right place.
2017-02-21 16:58:38 -08:00
Adithya J
38220c3dae Update SDK Version to 25 2017-02-05 20:21:43 +05:30
Clayton Wilkinson
f011fd1565 Merge pull request #351 from claywilkinson/master
Updating constraint-layout version to 1.0.0-beta4
2017-01-20 10:55:09 -08:00
Clayton Wilkinson
90760d967e Updating constraint-layout version to 1.0.0-beta4 2017-01-19 12:01:19 -08:00
Gerry
3476c7fbc4 Merge pull request #347 from googlesamples/ndkhelper_google_style
Update source style in teapot/ndk_helper/ directory, no functional change
2017-01-03 15:55:35 -08:00
guanghuafan
94a8492f2d Update source style in teapot/ndk_helper/ directory, no functional change 2017-01-03 15:00:44 -08:00
Gerry
240a2a6047 Merge pull request #346 from googlesamples/vecmath-format-fix
Very minor format change into teapots/common/ndk_helper/vecmath.cpp
2017-01-03 11:54:22 -08:00
guanghuafan
ba2cdcd926 Very minor format change into teapots/common/ndk_helper/vecmath.cpp 2017-01-03 11:52:12 -08:00
Gerry
64f940ad1e Merge pull request #343 from googlesamples/ndkhelper-consolidation
Consolidating ndk_helper source code
2016-12-27 11:53:16 -08:00
Gerry
8ed05369c2 Merge pull request #345 from ggfan/hello-jni-fix
fix issue https://github.com/googlesamples/android-ndk/issues/336
2016-12-27 11:42:14 -08:00
guanghuafan
d05cb61787 Consolidating ndk_helper source code
Tested: Nexus 9(android-23) Nexus 5X (android-24)
2016-12-27 09:14:55 -08:00
Gerry
ce21708ea1 Merge pull request #344 from Jacksgong/feature/fix-compilation
fix(hello-libs): fix the EXT_LIB_ROOT point to wrong path which will raise compile failed
2016-12-26 07:21:12 -08:00
Jacksgong
7bf93d2032 fix(hello-libs): fix the EXT_LIB_ROOT point to wrong path, which will raise compile failed 2016-12-24 22:50:13 +08:00
guanghuafan
af08a8f54e fix issue https://github.com/googlesamples/android-ndk/issues/336 2016-12-12 15:29:55 +08:00
Gerry
6e2e998056 Merge pull request #339 from googlesamples/as-update-to-2-2-3
Update to Android Studio 2.2.3
2016-12-09 14:59:53 +08:00
guanghuafan
957cd0206a Update to Android Studio 2.2.3
Tested a few samples on Android 22
2016-12-09 14:22:55 +08:00
Gerry
cdcf133392 Merge pull request #335 from googlesamples/native-media-clip-no-compress-fix
Fix java player problem in native-media sample
2016-11-29 10:45:44 -08:00
Quddus Chong
2290a14124 Fixed in-line comment typo across Native Activity samples. 2016-11-29 10:07:08 -08:00
qchong
402ff1b1a3 Fixed typo in in-line comments. (#329) 2016-11-29 09:55:41 -08:00
ggfan
ede8ba6160 Fix java player problem in native-media sample
github issue: https://github.com/googlesamples/android-ndk/issues/333
tested: Mac X build + Nexus 6 target
2016-11-29 09:19:22 -08:00
Gerry
c2a375aa48 Merge pull request #327 from googlesamples/fixit-hello-libs
Fix Android Studio hello-libs import description panel
2016-11-15 16:20:43 -08:00
guanghuafan
a43d1f58ac Fix Android Studio hello-libs import description panel
b/32918281
2016-11-15 16:12:48 -08:00
Gerry
c226949677 Merge pull request #326 from googlesamples/native-codec-typo-fix
Fixing typo in native-codec java source
2016-11-15 09:35:41 -08:00
guanghuafan
f1cc2add22 Fixing typo in native-codec java source
Related Issue#
    https://github.com/googlesamples/android-ndk/issues/324
2016-11-15 09:21:05 -08:00
Gerry
2e76ccf4a3 Merge pull request #320 from googlesamples/native-audio-uriplay-removal
Disable uriPlayer from UI to workaround bug:
2016-10-31 13:54:16 -07:00
guanghuafan
a8e83c33f7 Disable uriPlayer from UI to workaround bug:
https://github.com/googlesamples/android-ndk/issues/229
2016-10-31 09:27:22 -07:00
Gerry
d4423dd87f Merge pull request #318 from googlesamples/native-activity-fix
Fix github issue:   https://github.com/googlesamples/android-ndk/issues/317
2016-10-24 11:40:42 -07:00
guanghuafan
066d0ce81d Fix github issue:
https://github.com/googlesamples/android-ndk/issues/317
2016-10-24 10:09:05 -07:00
guanghuafan
893677a11c Fix hello-jni to use multi_abis to avoid "all", which is reserved and
will be included for every flavors to build ( it means common to all flavours)
2016-10-13 12:45:00 -07:00
guanghuafan
36c1ed3389 Port Courtney's fix of vertex attribute for gles3init 2016-10-12 15:59:11 -07:00
Gerry
f4f65fcd30 Merge pull request #303 from tberghammer/cmake-cleanup
Cleanup the cmake build files
2016-10-05 17:35:48 -07:00
Tamas Berghammer
00edde0c2d Cleanup the cmake build files
* Uniformalize the syntax used for the different projects
* Remove the usage of "glob" expressions
* Sort file lists to alphabetical order
* Replace uses of include_directories with target_include_directories
* Move some of the logic to subdirectories
* Remove a copy of native app glue
2016-10-05 15:09:11 -07:00
guanghuafan
c1bfc3c72b Restore origin commented code for hello-libs/settings.gradle to fix bug:
https://github.com/googlesamples/android-ndk/issues/301
2016-10-04 20:25:37 -07:00
Gerry
d065f33e1a Merge pull request #298 from googlesamples/use-shared-lib
Change to audio-echo to use shared lib
2016-09-22 17:06:11 -07:00
guanghuafan
5ba31b2aea Change to audio-echo to use shared lib and add packing workaround in CMakeLists.txt 2016-09-22 16:39:42 -07:00
Gerry
73034a7894 Merge pull request #299 from tberghammer/gles3jni
Fix the build of the gles3jni sample
2016-09-22 10:37:19 -07:00
Tamas Berghammer
42f77c0247 Fix the build of gles3jni sample
Previously it was specifying ANDROID_PLATFORM for cmake instead of
ANDROID_PLATFORM_LEVEL.
2016-09-22 18:06:40 +01:00
Tamas Berghammer
be56a770eb Fix a cmake message command in the gles3jni sample
The first argument of the message comment is the log level. Setting it
to FATAL_ERROR will fail the configure stage instead of silently
ignoring the error.
2016-09-22 18:05:55 +01:00
Gerry
78f9252f6d Merge pull request #296 from googlesamples/jnicall-fix
fix hello-jni and derivatives for JNIEXPORT and JNICALL modifiers
2016-09-19 15:30:01 -07:00
guanghuafan
be388d71dc fix hello-jni and derivatives for JNIEXPORT and JNICALL modifiers 2016-09-19 15:12:32 -07:00
guanghuafan
c6f78d2eae Fix Readme.md issues and other minor modifications 2016-09-19 12:23:34 -07:00
Gerry
2b00aa210e Merge pull request #292 from jiawen/master-cmake
Set event rate after enabling sensor so it takes effect.
2016-09-15 11:30:37 -07:00
Jiawen Chen
ca59693a6c Set event rate after enabling sensor so it takes effect.
The NDK documentation was not clear, but you are supposed to set the event rate
on an ASensorEventQueue only after enabling its associated sensor. It also needs
to be re-set after re-enabling the sensor. Without it, events arrive at some
"default rate" (quite slowly on some devices).
2016-09-15 09:33:09 -07:00
Gerry
7056c3829f Merge pull request #287 from googlesamples/merge-experimental
Merging experimental build into cmake
2016-08-31 11:35:22 -07:00
guanghuafan
f2e9168305 Merging experimental build into cmake 2016-08-30 18:15:13 -07:00
Gerry
c45e61a127 Merge pull request #285 from googlesamples/merge-ndkbuild
Merging master-ndkbuild branch into cmake branch
2016-08-25 13:47:31 -07:00
guanghuafan
a550ca9b3a Merging master-ndkbuild branch into cmake branch
source code are shared with cmake's copy
  two-libs and test-libstdc++ are not shared with cmake
also consolidated Teapots project into one projects called teapots:
  Teapot
  MoreTeapots
  choregrapher-30fps (has its own ndk-helper code)
2016-08-25 12:46:25 -07:00
Gerry
f4b89cbc83 Merge pull request #283 from googlesamples/cmake-update-2-2-beta2
Update builds and use productFlavours for cmake branch
2016-08-23 15:01:32 -07:00
guanghuafan
1cae952643 Prepare version update change for code review 2016-08-22 23:26:13 -07:00
guanghuafan
3856be5d00 Update build to android studio/gradle version 2.2.0-beta1 2016-08-22 16:53:20 -07:00
Gerry
d13ee448fc Merge pull request #279 from googlesamples/webp-sample
Add a simple web psample
2016-08-22 11:57:53 -07:00
Gerry
c5ba8e03e6 Merge pull request #279 from googlesamples/webp-sample
Add a simple web psample
2016-08-22 08:19:37 -07:00
guanghuafan
74b3ef447a Add webp sample to show wepb decode usage 2016-08-22 08:18:42 -07:00
Gerry
4b0d65709f Merge pull request #276 from dpull/patch-1
Update build.gradle
2016-08-08 08:42:28 -07:00
Acai
a1e355464b Update build.gradle
A problem occurred evaluating project ':gen-libs'.
> Could not find method cmake() for arguments
2016-08-07 13:15:10 +08:00
Gerry
6fbed5176a Merge pull request #274 from googlesamples/san-angeles-cmake-fix
Fix sample san-angeles for:
2016-08-05 10:14:50 -07:00
guanghuafan
10bfd27a90 Fix sample san-angeles for:
external build 'path' should be file
   add apk split feature
Branch:
   master-cmake
Tested:
   Mac X build, nexus 6 & emulator for target
2016-08-05 10:04:34 -07:00
Gerry
5526ecd2bf Merge pull request #264 from ggfan/PRIu64-fix
fixed issue https://github.com/googlesamples/android-ndk/issues/263:
2016-07-22 16:27:12 -07:00
guanghuafan
c3dfab5ac8 fixed issue https://github.com/googlesamples/android-ndk/issues/263:
using standard C++ headers, instead of c headers to fix PRIu64 issue
2016-07-22 16:05:30 -07:00
Gerry
253f127899 Merge pull request #247 from ggfan/beta-update-master-cmake
update build to android studio 2.2.0 alpha5.
2016-07-13 14:10:27 -05:00
guanghuafan
d9b2262a42 update to Android 2.2-alpha5 2016-06-30 21:51:48 -07:00
Gerry
27bdc797b2 Merge pull request #241 from ggfan/hello-neon-list
Merge pull request #240 from ggfan/hello-neon
2016-06-29 09:22:48 -07:00
Gerry
f00d42780f Merge pull request #240 from ggfan/hello-neon
Ported hello-neon sample to master-cmake branch
2016-06-28 18:27:59 -07:00
Gerry
1cb28cc1c9 Merge pull request #240 from ggfan/hello-neon
Ported hello-neon sample to master-cmake branch
2016-06-28 09:06:51 -07:00
guanghuafan
e4154823b1 Ported hello-neon sample to cmake 2016-06-27 17:51:46 -07:00
Gerry
baef9c5981 Merge pull request #236 from googlesamples/cmake-p4-update
Update to android studio preview 4 with cmake support
2016-06-23 17:10:30 -07:00
guanghuafan
1513a7f228 Update to android studio preview 4 with cmake support 2016-06-23 17:03:15 -07:00
guanghuafan
b9ca563983 Fix error in hello-libs CMakeLists.txt 2016-06-17 11:35:48 -07:00
Gerry
7b536dd543 Merge pull request #231 from ggfan/hello-libs-fix
revert hello-libs shared lib import: gradle still needs to pack shared…
2016-06-14 11:58:10 -07:00
guanghuafan
4692f6e217 revert hello-libs shared lib import: gradle still need to pack shared lib 2016-06-14 11:40:55 -07:00
Gerry
5a9a9d4d00 Merge pull request #230 from ggfan/hello-libs-fix
fix hello-libs build issue
2016-06-13 16:47:08 -07:00
guanghuafan
9606647c02 fix hello-libs build issue 2016-06-13 16:24:53 -07:00
Gerry
382e664d36 Merge pull request #225 from ggfan/more-cmake
Add a few more samples:
2016-06-08 14:45:45 -07:00
guanghuafan
1aaccfa48e Add a few more samples:
audio-echo
   bitmap-plasma
   MoreTeapot
   choreographer
   gles3jni
   hello-gl2
   native-audio
   native-codec
   native-media
   native-plasma
   san-angeles
   sensor-graph
2016-06-07 23:25:54 -07:00
Gerry
40826299f2 Merge pull request #221 from ggfan/more-cmake
Porting hello-libs and Teapot to cmake branch
2016-06-02 12:16:27 -07:00
guanghuafan
56f5266e2f porting hello-libs, Teapot, endless-tunnel to cmake branch
known issue: endless-tunnel audio play is broken on Android-N DP3
               will be fixed in DP4 in audio framework
2016-06-02 11:59:58 -07:00
Gerry
6f57603a96 Merge pull request #216 from ggfan/native-activity-fix
removing comment about gradle.properties, no code changes
2016-05-26 16:14:34 -07:00
guanghuafan
3b15137063 removing comment about gradle.properties, no code change 2016-05-26 14:13:42 -07:00
Gerry
2ada825fa5 Merge pull request #215 from ggfan/jnicallback-fix-cmake
remove JNI_OnUnload(): it never get called
2016-05-26 06:59:36 -07:00
guanghuafan
7128677f99 remove JNI_OnUnload(): it never get called 2016-05-25 21:54:14 -07:00
Gerry
13628bd30e Merge pull request #213 from ggfan/more-cmake
porting native-activity sample to cmake
2016-05-25 17:14:12 -07:00
guanghuafan
a450fb0629 porting native-activity sample to cmake 2016-05-25 15:13:54 -07:00
guanghuafan
b2e30e055d Porting samples to android-cmake 2016-05-24 13:33:58 -07:00
Gerry
05708a4da9 Merge pull request #198 from ggfan/runtime-permission2
light-weighted implementation for run-time permission request
2016-05-13 00:05:39 -07:00
Gerry
8a747bbc48 Merge pull request #200 from ggfan/sensor-graph
Rename sensor-graph/app name to sensor-graph/accelerometer
2016-05-10 21:14:53 -07:00
guanghuafan
84a9fee0f4 Rename app name to accelerometer 2016-05-10 17:59:34 -07:00
Gerry
06c71cda05 Merge pull request #197 from ggfan/debuginfo
adding debug related info
2016-05-10 17:08:09 -07:00
Gerry
9f61cd9fd2 Merge pull request #199 from ggfan/hello-jni
Revert platformVersion from Hello-Jni:
2016-05-10 14:06:36 -07:00
guanghuafan
925003c48d revert platformVersion from Hello-Jni:
if version is too low (lower than the supporting for 64),
  all 64 bit ABI will not build and run anymore.
2016-05-10 13:57:30 -07:00
Gerry
6b2f55967c Merge pull request #194 from ggfan/enable-native-player
re-enable native player for native-media
2016-05-09 20:43:26 -07:00
Gerry
58607fbcb5 Merge pull request #196 from ggfan/endless-tunnel
Fix issues/192
2016-05-09 18:08:25 -07:00
guanghuafan
732b622d8a Update README, adding REFERENCE.md to document debugging configurations 2016-05-09 18:05:44 -07:00
guanghuafan
29961621b5 Fix issues/192
the default parameter swapped the order for up/low bound in Random()
  by mistake, this fixes it.
2016-05-09 12:09:41 -07:00
guanghuafan
db5a8fbba6 re-enable native player for native-media since it only broken for andriod-N 2016-05-09 09:46:33 -07:00
guanghuafan
8475b22612 Enable Runtime permission for audio-echo and native-audio 2016-05-06 13:51:38 -07:00
Gerry
d65f99e513 Merge pull request #191 from ggfan/readme-update
Update master README.md file for known issues
2016-05-05 15:50:45 -07:00
guanghuafan
0d09ba0a19 Update master README.md file for known issues 2016-05-05 15:27:21 -07:00
Gerry
cd4d5a85d9 Merge pull request #190 from ggfan/native-plasma
Requesting 565 window format in native-plasma to make it work
2016-05-05 12:18:36 -07:00
guanghuafan
5f16af3b8e Requesting 565 window format in native-plasma to make it work 2016-05-05 11:26:27 -07:00
Gerry
41b5c24a9e Merge pull request #188 from ggfan/native-audio
change flag to mutex lock for native-audio
2016-05-04 16:12:19 -07:00
guanghuafan
b50e07edc5 change flag to mutex lock for native-audio 2016-05-04 15:34:32 -07:00
Gerry
53b2217ca9 Merge pull request #187 from ggfan/endless-tunnel2
Update platformVersion to all samples
2016-05-03 14:41:56 -07:00
guanghuafan
8016d75e13 Merge in new sample choreographer-30fps 2016-05-03 12:01:35 -07:00
guanghuafan
015402ed7d Update platformVersion to all samples 2016-05-03 11:48:21 -07:00
Gerry
8d39815b0a Merge pull request #184 from hak/master
Sample showing a frame rate throttle technique using Choreographer API.
2016-05-03 11:19:35 -07:00
Hak Matsuda
f0f5e53763 Sample showing a frame rate throttle technique using Choreographer API.
This technique would be useful to save battery and to avoid thermal throttling on devices.

- Use native Choreographer API in API level 24~.
- Use EGL extension in API level 17~.
- Fallback to Java Choreographer API in API level 16~.
- The sample runs only in API level 16~.

Tested: on N6P.
2016-05-02 15:13:00 -07:00
Gerry
a28dfa39d1 Merge pull request #183 from ggfan/undless-tunnel
remove gpg reference since there is gpg in this game
2016-04-29 18:05:27 -07:00
guanghuafan
47525dd4dd remove gpg reference since there is gpg in this game 2016-04-29 17:59:53 -07:00
Gerry
793cdfe7ea Merge pull request #182 from ggfan/asset-manager2
Update for native-codec & native-media:
2016-04-29 17:43:18 -07:00
guanghuafan
f9007017fd disabling native_player for native-media temporarily 2016-04-29 15:32:12 -07:00
guanghuafan
7d537f1908 Update for native-codec & native-media:
1) play from assets rather than from /sdcard
 2) if clip not found, mlooper will not be there, do not call rewind()
 3) update NativeMedia.ts to native-media

Tested: build on Mac, runs on Android-N/N5X
Known Issue: native-media native player still is not working
2016-04-29 14:46:34 -07:00
Gerry
3698ae314c Merge pull request #180 from ggfan/native-audio-update
adding .google dir into native-audio
2016-04-27 22:56:12 -07:00
guanghuafan
c5118fe6bc removing C++ and only keep NDK in android studio's categories 2016-04-27 22:25:54 -07:00
guanghuafan
b804cb4c10 adding .google dir into native-audio 2016-04-27 21:43:25 -07:00
Gerry
a498a7809c Merge pull request #178 from ggfan/plugin-update
Update plugin to 0.7.0-rc1 for clang build on windows(*) platform
2016-04-25 12:58:36 -07:00
guanghuafan
3676d46761 update hello-libs to 0.7.0-rc1 2016-04-24 19:13:45 -07:00
guanghuafan
e0890876e7 update to gradle plugin 0.7.0-rc1
switch to clang to build app
2016-04-24 15:46:54 -07:00
Gerry
64c1ac83f1 Merge pull request #177 from googlesamples/proppy-patch-7
travis: ignore quote when checking for version
2016-04-22 14:32:26 -07:00
Gerry
12991ef033 Merge pull request #176 from ggfan/remove-3rd-party
Removed hello-thirdparty: hello-libs replacing it
2016-04-22 12:34:58 -07:00
Johan Euphrosine
ba864d8bb6 travis: xargs should only consume 1 arg 2016-04-22 12:19:59 -07:00
Johan Euphrosine
59ddee29cb travis: unquote before sort|uniq 2016-04-22 12:13:32 -07:00
guanghuafan
55ea753ec7 update CI file for directory change 2016-04-22 12:03:52 -07:00
Johan Euphrosine
72232a6731 travis: ignore quote when checking for version 2016-04-22 11:53:00 -07:00
guanghuafan
3771f78f67 trick away unused compiler warning 2016-04-22 11:29:35 -07:00
guanghuafan
107e10a675 Removed hello-thirdparty: hello-libs replacing it
add c++11 into hello-libs
  add android import related into hello-libs
2016-04-22 11:12:29 -07:00
1422 changed files with 69009 additions and 11665 deletions

131
.ci_tools/build_samples.sh Executable file
View File

@@ -0,0 +1,131 @@
#!/bin/bash
# - Configure SDK/NDK locations so we do not depends on local.properties, e.g
# - export ANDROID_HOME=$HOME/dev/sdk
# - export ANDROID_NDK_HOME=$ANDROID_HOME/ndk-bundle
# - executing in repo root directory
# Configurations:
# temp file name to hold build result
BUILD_RESULT_FILE=build_result.txt
# Repo root directory
NDK_SAMPLE_REPO=.
declare projects=(
audio-echo
bitmap-plasma
camera
endless-tunnel
gles3jni
hello-gl2
hello-jni
hello-jniCallback
hello-libs
hello-neon
native-activity
native-audio
native-codec
native-media
native-plasma
nn-samples
prefab/curl-ssl
prefab/prefab-publishing
san-angeles
sensor-graph
# webp
teapots
## ndk-build samples
other-builds/ndkbuild/bitmap-plasma
other-builds/ndkbuild/gles3jni
other-builds/ndkbuild/hello-gl2
other-builds/ndkbuild/hello-jni
other-builds/ndkbuild/hello-libs
other-builds/ndkbuild/hello-neon
other-builds/ndkbuild/native-activity
other-builds/ndkbuild/native-audio
other-builds/ndkbuild/native-codec
other-builds/ndkbuild/native-media
other-builds/ndkbuild/native-plasma
other-builds/ndkbuild/nn-samples
other-builds/ndkbuild/san-angeles
other-builds/ndkbuild/teapots
)
for d in "${projects[@]}"; do
pushd ${NDK_SAMPLE_REPO}/${d} >/dev/null
TERM=dumb ./gradlew -q clean assembleDebug
popd >/dev/null
done
# Check the apks that all get built fine
declare apks=(
audio-echo/app/build/outputs/apk/debug/app-debug.apk
bitmap-plasma/app/build/outputs/apk/debug/app-debug.apk
camera/basic/build/outputs/apk/debug/basic-debug.apk
camera/texture-view/build/outputs/apk/debug/texture-view-debug.apk
endless-tunnel/app/build/outputs/apk/debug/app-debug.apk
gles3jni/app/build/outputs/apk/debug/app-debug.apk
hello-gl2/app/build/outputs/apk/debug/app-debug.apk
hello-jni/app/build/outputs/apk/arm8/debug/app-arm8-debug.apk
hello-jniCallback/app/build/outputs/apk/debug/app-debug.apk
hello-libs/app/build/outputs/apk/debug/app-debug.apk
hello-neon/app/build/outputs/apk/debug/app-debug.apk
native-activity/app/build/outputs/apk/debug/app-debug.apk
native-audio/app/build/outputs/apk/debug/app-debug.apk
native-codec/app/build/outputs/apk/debug/app-debug.apk
native-media/app/build/outputs/apk/debug/app-debug.apk
native-plasma/app/build/outputs/apk/debug/app-debug.apk
nn-samples/basic/build/outputs/apk/debug/basic-debug.apk
nn-samples/sequence/build/outputs/apk/debug/sequence-debug.apk
prefab/curl-ssl/app/build/outputs/apk/debug/app-debug.apk
prefab/prefab-publishing/mylibrary/build/outputs/aar/mylibrary-debug.aar
sensor-graph/accelerometer/build/outputs/apk/debug/accelerometer-debug.apk
san-angeles/app/build/outputs/apk/debug/app-armeabi-v7a-debug.apk
san-angeles/app/build/outputs/apk/debug/app-arm64-v8a-debug.apk
san-angeles/app/build/outputs/apk/debug/app-x86-debug.apk
teapots/classic-teapot/build/outputs/apk/debug/classic-teapot-debug.apk
teapots/more-teapots/build/outputs/apk/debug/more-teapots-debug.apk
teapots/choreographer-30fps/build/outputs/apk/debug/choreographer-30fps-debug.apk
teapots/image-decoder/build/outputs/apk/debug/image-decoder-debug.apk
# webp/view/build/outputs/apk/debug/view-arm7-debug.apk
## other-builds
other-builds/ndkbuild/bitmap-plasma/app/build/outputs/apk/debug/app-debug.apk
other-builds/ndkbuild/gles3jni/app/build/outputs/apk/debug/app-debug.apk
other-builds/ndkbuild/hello-gl2/app/build/outputs/apk/debug/app-debug.apk
other-builds/ndkbuild/hello-jni/app/build/outputs/apk/debug/app-debug.apk
other-builds/ndkbuild/hello-libs/app/build/outputs/apk/debug/app-debug.apk
other-builds/ndkbuild/hello-neon/app/build/outputs/apk/arm7/debug/app-arm7-debug.apk
other-builds/ndkbuild/native-activity/app/build/outputs/apk/debug/app-debug.apk
other-builds/ndkbuild/native-audio/app/build/outputs/apk/debug/app-debug.apk
other-builds/ndkbuild/native-codec/app/build/outputs/apk/debug/app-debug.apk
other-builds/ndkbuild/native-media/app/build/outputs/apk/debug/app-debug.apk
other-builds/ndkbuild/native-plasma/app/build/outputs/apk/debug/app-debug.apk
other-builds/ndkbuild/nn-samples/basic/build/outputs/apk/debug/basic-debug.apk
other-builds/ndkbuild/san-angeles/app/build/outputs/apk/debug/app-armeabi-v7a-debug.apk
other-builds/ndkbuild/san-angeles/app/build/outputs/apk/debug/app-arm64-v8a-debug.apk
other-builds/ndkbuild/san-angeles/app/build/outputs/apk/debug/app-x86-debug.apk
other-builds/ndkbuild/teapots/more-teapots/build/outputs/apk/debug/more-teapots-debug.apk
other-builds/ndkbuild/teapots/classic-teapot/build/outputs/apk/debug/classic-teapot-debug.apk
)
rm -fr ${BUILD_RESULT_FILE}
for apk in "${apks[@]}"; do
if [ ! -f ${NDK_SAMPLE_REPO}/${apk} ]; then
export SAMPLE_CI_RESULT=1
echo ${apk} does not build >> ${BUILD_RESULT_FILE}
fi
done
if [ -f ${BUILD_RESULT_FILE} ]; then
echo "******* Failed Builds ********:"
cat ${BUILD_RESULT_FILE}
else
echo "======= BUILD SUCCESS ======="
fi
rm -fr ${BUILD_RESULT_FILE}

31
.ci_tools/misc_ci.sh Executable file
View File

@@ -0,0 +1,31 @@
#!/bin/bash
set +e
MISC_STATUS=0
# check that all Support section of the README are the same.
for f in */README.md; do
sed -n '/Support/,/License/p' $f > /tmp/$(dirname $f).readme;
done && diff -u --from-file=/tmp/hello-jni.readme /tmp/*.readme
MISC_STATUS=$(($MISC_STATUS + $?))
# check that all targetSdkVersion are 26+
# test "$(grep -H targetSdkVersion */app/build.gradle | tee /dev/stderr | cut -d= -f 2 | xargs -n1 echo | sort | uniq | wc -l)" = "2"
# check that there is no tabs in AndroidManifest
(! grep -n $'\t' */*/src/main/AndroidManifest.xml) | cat -t;
MISC_STATUS=$(($MISC_STATUS + ${PIPESTATUS[0]}))
# check that there is no trailing spaces in AndroidManifest
(! grep -E '\s+$' */*/src/main/AndroidManifest.xml) | cat -e;
MISC_STATUS=$(($MISC_STATUS + ${PIPESTATUS[0]}))
## Fix the builder then enable it [TBD]
#(cd builder && ./gradlew test)
# print build failure summary
# pandoc builder/build/reports/tests/index.html -t plain | sed -n '/^Failed tests/,/default-package/p'
# print lint results details
# for f in */app/build/outputs/lint-results.html; do pandoc $f -t plain; done
# populate the error to final status
if [[ "$MISC_STATUS" -ne 0 ]]; then
SAMPLE_CI_RESULT=$(($SAMPLE_CI_RESULT + 1))
fi

4
.ci_tools/run_samples.sh Executable file
View File

@@ -0,0 +1,4 @@
#!/bin/bash
# TBD: load apks on emulator
#

100
.ci_tools/setup_env.sh Executable file
View File

@@ -0,0 +1,100 @@
#!/bin/bash
# assumption:
# - pwd must be inside the repo's homed directory (android-ndk)
# - upon completion, we are still in the same directory ( no change )
# parse all build.gradle to find the specified tokens' version
# usage:
# retrive_versions token version_file
# where
# token: the token to search for inside build.grade
# version string is right after the token string
# version_file: file to hold the given versions
# one version at a line
retrieve_versions() {
# $1: token; $2 version_file
if [[ -z $1 ]] || [[ -z $2 ]]; then
echo "input string(s) may be empty: token: $1; version_file: $2"
return 1
fi
find . -type f -name 'build.gradle' -exec grep $1 {} + | \
sed "s/^.*$1//" | sed 's/[=+]//g' | \
sed 's/"//g' | sed "s/'//g" | \
sed 's/[[:space:]]//g' | \
awk '!seen[$0]++' > $2
return 0
}
# helper function for src_str > target_str
# Usage
# comp_ver_string src_str target_str
# return:
# 0: src_str <= target_str
# 1: otherwise
comp_ver_string () {
# $1: src_str, $2: target_str
if [[ $1 == $2 ]]
then
return 0
fi
local IFS=.
local i ver1=($1) ver2=($2)
# fill empty fields in ver1 with zeros
for ((i=${#ver1[@]}; i<${#ver2[@]}; i++))
do
ver1[i]=0
done
for ((i=0; i<${#ver1[@]}; i++))
do
if [[ -z ${ver2[i]} ]]
then
# fill empty fields in ver2 with zeros
ver2[i]=0
fi
if ((10#${ver1[i]} < 10#${ver2[i]}))
then
return 0
fi
if ((10#${ver1[i]} > 10#${ver2[i]}))
then
return 1
fi
done
return 0
}
# prepare to install necessary packages
if [ -f ~/.android/repositories.cfg ]; then
touch ~/.android/repositories.cfg
fi
TMP_SETUP_FILENAME=versions_.txt
## Retrieve all necessary Android Platforms and install them all
retrieve_versions compileSdkVersion $TMP_SETUP_FILENAME
# Install platforms
while read -r version_; do
version_=${version_//android-/}
echo y | $ANDROID_HOME/tools/bin/sdkmanager "platforms;android-$version_";
done < $TMP_SETUP_FILENAME
# echo "Android platforms:"; cat $TMP_SETUP_FILENAME
# Install side by side ndks
retrieve_versions ndkVersion $TMP_SETUP_FILENAME
while read -r version_; do
echo y | $ANDROID_HOME/tools/bin/sdkmanager "ndk;$version_" --channel=3;
done < $TMP_SETUP_FILENAME
# echo "NDK versions:"; cat $TMP_SETUP_FILENAME
# add customized cmake installation
echo y | $ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager "cmake;3.18.1"
rm -f $TMP_SETUP_FILENAME

30
.github/workflows/build.yml vendored Normal file
View File

@@ -0,0 +1,30 @@
name: build
on:
push:
branches: [ main develop ]
pull_request:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: set up JDK 1.8
uses: actions/setup-java@v1
with:
java-version: 1.8
- name: setup env
run:
source .ci_tools/setup_env.sh
- name: build samples
run: |
export SAMPLE_CI_RESULT=0
source .ci_tools/build_samples.sh
source .ci_tools/run_samples.sh
eval "[[ $SAMPLE_CI_RESULT == 0 ]]"

31
.github/workflows/copy-branch.yml vendored Normal file
View File

@@ -0,0 +1,31 @@
# Duplicates default main branch to the old master branch
name: Duplicates main to old master branch
# Controls when the action will run. Triggers the workflow on push or pull request
# events but only for the main branch
on:
push:
branches: [ main ]
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
# This workflow contains a single job called "copy-branch"
copy-branch:
# The type of runner that the job will run on
runs-on: ubuntu-latest
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it,
# but specifies master branch (old default).
- uses: actions/checkout@v2
with:
fetch-depth: 0
ref: master
- run: |
git config user.name github-actions
git config user.email github-actions@github.com
git merge origin/main
git push

8
.gitignore vendored
View File

@@ -4,4 +4,10 @@
local.properties
build
*~
.DS_Store
.externalNativeBuild
libwebp
.DS_Store
**/ndkHelperBin
**/.cxx
display-p3/third_party

View File

@@ -1,40 +0,0 @@
language: android
sudo: true
android:
components:
- tools
- platform-tools
- build-tools-23.0.2
- android-23
- extra-google-m2repository
- extra-android-m2repository
addons:
apt_packages:
- pandoc
artifacts:
paths:
- $(git ls-files -o | grep app/build/outputs | tr "\n" ":")
before_install:
- git clone https://github.com/urho3d/android-ndk.git $HOME/android-ndk-root
- export ANDROID_NDK_HOME=$HOME/android-ndk-root
script:
# check that all Support section of the README are the same.
- for f in */README.md; do sed -n '/Support/,/License/p' $f > /tmp/$(dirname $f).readme; done && diff -u --from-file=/tmp/hello-jni.readme /tmp/*.readme
# check that all compileSdkVersion are 23.
- test "$(grep -H compileSdkVersion */app/build.gradle | tee /dev/stderr | cut -d= -f 2 | sort | uniq | wc -l)" = "1"
# check that all targetSdkVersion are 22 or 23
- test "$(grep -H targetSdkVersion */app/build.gradle | tee /dev/stderr | cut -d= -f 2 | sort | uniq | wc -l)" = "2"
# check that all build-tools-23 are 23.
- test "$(grep -H buildToolsVersion */app/build.gradle | tee /dev/stderr | cut -d= -f 2 | sort | uniq | wc -l)" = "1"
# check that there is no tabs in AndroidManifest
- |-
(! grep -n $'\t' */app/src/main/AndroidManifest.xml) | cat -t; test ${PIPESTATUS[0]} -eq 0
# check that there is no trailing spaces in AndroidManifest
- |-
(! grep -E '\s+$' */app/src/main/AndroidManifest.xml) | cat -e; test ${PIPESTATUS[0]} -eq 0
- (cd hello-thirdparty && ./gradlew download_and_stage_gpg_sdk)
- (cd builder && ./gradlew test)
# print build failure summary
- pandoc builder/build/reports/tests/index.html -t plain | sed -n '/^Failed tests/,/default-package/p'
# print lint results details
# - for f in */app/build/outputs/lint-results.html; do pandoc $f -t plain; done

View File

@@ -1,65 +0,0 @@
apply plugin: 'com.android.model.application'
// Retrieve ndk path to config cpufeatures src code into this project
// native_app_glue is configured as dependent module, so we avoid confusing
// NOTICE/repo.prop files get displayed multiple times inside IDE
def ndkDir = System.getenv("ANDROID_NDK_HOME")
def propertiesFile = project.rootProject.file('local.properties')
if (propertiesFile.exists()) {
Properties properties = new Properties()
properties.load(propertiesFile.newDataInputStream())
ndkDir = properties.getProperty('ndk.dir')
}
model {
android {
compileSdkVersion = 23
buildToolsVersion = '23.0.2'
defaultConfig {
applicationId = 'com.sample.moreteapots'
minSdkVersion.apiLevel = 17
targetSdkVersion.apiLevel = 22
}
ndk {
moduleName = 'MoreTeapotsNativeActivity'
// temporarily use gcc since clang does not work on windows (*)
// also clang warning about inline, so could not use -Wall, -Werror
// toolchain = "clang"
stl = 'gnustl_static'
cppFlags.addAll(['-I' + "${ndkDir}/sources/android/cpufeatures",
'-I' + file('src/main/jni/ndk_helper')])
cppFlags.addAll(['-std=c++11', '-Werror', '-Wall',
'-fno-exceptions', '-fno-rtti'])
ldLibs.addAll(['android', 'log', 'EGL', 'GLESv2','atomic'])
}
// Turn on hard float support in armeabi-v7a
abis {
create('armeabi-v7a') {
cppFlags.addAll(['-mhard-float', '-D_NDK_MATH_NO_SOFTFP=1',
'-mfloat-abi=hard'])
ldLibs.add('m_hard')
ldFlags.add('-Wl,--no-warn-mismatch')
}
}
sources {
main {
jni {
dependencies {
project ':nativeactivity' linkage 'static'
}
source {
srcDirs 'src/main/jni'
srcDirs "${ndkDir}/sources/android/cpufeatures"
}
}
}
}
buildTypes {
release {
minifyEnabled = false
proguardFiles.add(file('proguard-rules.txt'))
}
}
}
}

View File

@@ -1,205 +0,0 @@
/*
* Copyright 2013 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sample.helper;
import java.io.File;
import java.io.FileInputStream;
import javax.microedition.khronos.opengles.GL10;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.media.AudioManager;
import android.media.AudioTrack;
import android.opengl.GLUtils;
import android.util.Log;
public class NDKHelper
{
private static Context context;
public static void setContext(Context c)
{
Log.i("NDKHelper", "setContext:" + c);
context = c;
}
//
// Load Bitmap
// Java helper is useful decoding PNG, TIFF etc rather than linking libPng
// etc separately
//
private int nextPOT(int i)
{
int pot = 1;
while (pot < i)
pot <<= 1;
return pot;
}
private Bitmap scaleBitmap(Bitmap bitmapToScale, float newWidth, float newHeight)
{
if (bitmapToScale == null)
return null;
// get the original width and height
int width = bitmapToScale.getWidth();
int height = bitmapToScale.getHeight();
// create a matrix for the manipulation
Matrix matrix = new Matrix();
// resize the bit map
matrix.postScale(newWidth / width, newHeight / height);
// recreate the new Bitmap and set it back
return Bitmap.createBitmap(bitmapToScale, 0, 0, bitmapToScale.getWidth(),
bitmapToScale.getHeight(), matrix, true);
}
public boolean loadTexture(String path)
{
Bitmap bitmap = null;
try
{
String str = path;
if (!path.startsWith("/"))
{
str = "/" + path;
}
File file = new File(context.getExternalFilesDir(null), str);
if (file.canRead())
{
bitmap = BitmapFactory.decodeStream(new FileInputStream(file));
} else
{
bitmap = BitmapFactory.decodeStream(context.getResources().getAssets()
.open(path));
}
// Matrix matrix = new Matrix();
// // resize the bit map
// matrix.postScale(-1F, 1F);
//
// // recreate the new Bitmap and set it back
// bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
// bitmap.getHeight(), matrix, true);
} catch (Exception e)
{
Log.w("NDKHelper", "Coundn't load a file:" + path);
return false;
}
if (bitmap != null)
{
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
}
return true;
}
public Bitmap openBitmap(String path, boolean iScalePOT)
{
Bitmap bitmap = null;
try
{
bitmap = BitmapFactory.decodeStream(context.getResources().getAssets()
.open(path));
if (iScalePOT)
{
int originalWidth = getBitmapWidth(bitmap);
int originalHeight = getBitmapHeight(bitmap);
int width = nextPOT(originalWidth);
int height = nextPOT(originalHeight);
if (originalWidth != width || originalHeight != height)
{
// Scale it
bitmap = scaleBitmap(bitmap, width, height);
}
}
} catch (Exception e)
{
Log.w("NDKHelper", "Coundn't load a file:" + path);
}
return bitmap;
}
public int getBitmapWidth(Bitmap bmp)
{
return bmp.getWidth();
}
public int getBitmapHeight(Bitmap bmp)
{
return bmp.getHeight();
}
public void getBitmapPixels(Bitmap bmp, int[] pixels)
{
int w = bmp.getWidth();
int h = bmp.getHeight();
bmp.getPixels(pixels, 0, w, 0, 0, w, h);
}
public void closeBitmap(Bitmap bmp)
{
bmp.recycle();
}
public static String getNativeLibraryDirectory(Context appContext)
{
ApplicationInfo ai = context.getApplicationInfo();
Log.w("NDKHelper", "ai.nativeLibraryDir:" + ai.nativeLibraryDir);
if ((ai.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0
|| (ai.flags & ApplicationInfo.FLAG_SYSTEM) == 0)
{
return ai.nativeLibraryDir;
}
return "/system/lib/";
}
@TargetApi(17)
public int getNativeAudioBufferSize()
{
int SDK_INT = android.os.Build.VERSION.SDK_INT;
if (SDK_INT >= 17)
{
AudioManager am = (AudioManager) context
.getSystemService(Context.AUDIO_SERVICE);
String framesPerBuffer = am
.getProperty(AudioManager.PROPERTY_OUTPUT_FRAMES_PER_BUFFER);
return Integer.parseInt(framesPerBuffer);
} else
{
return 0;
}
}
public int getNativeAudioSampleRate()
{
return AudioTrack.getNativeOutputSampleRate(AudioManager.STREAM_SYSTEM);
}
}

View File

@@ -1,365 +0,0 @@
/*
* Copyright 2013 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <EGL/egl.h>
#include <GLES2/gl2.h>
#include <fstream>
#include <iostream>
#include "JNIHelper.h"
namespace ndk_helper {
#define CLASS_NAME "android/app/NativeActivity"
//---------------------------------------------------------------------------
// JNI Helper functions
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// Singleton
//---------------------------------------------------------------------------
JNIHelper* JNIHelper::GetInstance() {
static JNIHelper helper;
return &helper;
}
//---------------------------------------------------------------------------
// Ctor
//---------------------------------------------------------------------------
JNIHelper::JNIHelper() { pthread_mutex_init(&mutex_, NULL); }
//---------------------------------------------------------------------------
// Dtor
//---------------------------------------------------------------------------
JNIHelper::~JNIHelper() {
pthread_mutex_lock(&mutex_);
JNIEnv* env;
activity_->vm->AttachCurrentThread(&env, NULL);
env->DeleteGlobalRef(jni_helper_java_ref_);
env->DeleteGlobalRef(jni_helper_java_class_);
activity_->vm->DetachCurrentThread();
pthread_mutex_destroy(&mutex_);
}
//---------------------------------------------------------------------------
// Init
//---------------------------------------------------------------------------
void JNIHelper::Init(ANativeActivity* activity, const char* helper_class_name) {
JNIHelper& helper = *GetInstance();
pthread_mutex_lock(&helper.mutex_);
helper.activity_ = activity;
JNIEnv* env;
helper.activity_->vm->AttachCurrentThread(&env, NULL);
// Retrieve app name
jclass android_content_Context = env->GetObjectClass(helper.activity_->clazz);
jmethodID midGetPackageName = env->GetMethodID(
android_content_Context, "getPackageName", "()Ljava/lang/String;");
jstring packageName = (jstring)env->CallObjectMethod(helper.activity_->clazz,
midGetPackageName);
const char* appname = env->GetStringUTFChars(packageName, NULL);
helper.app_name_ = std::string(appname);
jclass cls = helper.RetrieveClass(env, helper_class_name);
helper.jni_helper_java_class_ = (jclass)env->NewGlobalRef(cls);
jmethodID constructor =
env->GetMethodID(helper.jni_helper_java_class_, "<init>", "()V");
helper.jni_helper_java_ref_ =
env->NewObject(helper.jni_helper_java_class_, constructor);
helper.jni_helper_java_ref_ = env->NewGlobalRef(helper.jni_helper_java_ref_);
env->ReleaseStringUTFChars(packageName, appname);
helper.activity_->vm->DetachCurrentThread();
pthread_mutex_unlock(&helper.mutex_);
}
//---------------------------------------------------------------------------
// readFile
//---------------------------------------------------------------------------
bool JNIHelper::ReadFile(const char* fileName,
std::vector<uint8_t>* buffer_ref) {
if (activity_ == NULL) {
LOGI(
"JNIHelper has not been initialized.Call init() to initialize the "
"helper");
return false;
}
// First, try reading from externalFileDir;
JNIEnv* env;
pthread_mutex_lock(&mutex_);
activity_->vm->AttachCurrentThread(&env, NULL);
jstring str_path = GetExternalFilesDirJString(env);
const char* path = env->GetStringUTFChars(str_path, NULL);
std::string s(path);
if (fileName[0] != '/') {
s.append("/");
}
s.append(fileName);
std::ifstream f(s.c_str(), std::ios::binary);
env->ReleaseStringUTFChars(str_path, path);
env->DeleteLocalRef(str_path);
activity_->vm->DetachCurrentThread();
if (f) {
LOGI("reading:%s", s.c_str());
f.seekg(0, std::ifstream::end);
int32_t fileSize = f.tellg();
f.seekg(0, std::ifstream::beg);
buffer_ref->reserve(fileSize);
buffer_ref->assign(std::istreambuf_iterator<char>(f),
std::istreambuf_iterator<char>());
f.close();
pthread_mutex_unlock(&mutex_);
return true;
} else {
// Fallback to assetManager
AAssetManager* assetManager = activity_->assetManager;
AAsset* assetFile =
AAssetManager_open(assetManager, fileName, AASSET_MODE_BUFFER);
if (!assetFile) {
pthread_mutex_unlock(&mutex_);
return false;
}
uint8_t* data = (uint8_t*)AAsset_getBuffer(assetFile);
int32_t size = AAsset_getLength(assetFile);
if (data == NULL) {
AAsset_close(assetFile);
LOGI("Failed to load:%s", fileName);
pthread_mutex_unlock(&mutex_);
return false;
}
buffer_ref->reserve(size);
buffer_ref->assign(data, data + size);
AAsset_close(assetFile);
pthread_mutex_unlock(&mutex_);
return true;
}
}
std::string JNIHelper::GetExternalFilesDir() {
if (activity_ == NULL) {
LOGI(
"JNIHelper has not been initialized. Call init() to initialize the "
"helper");
return std::string("");
}
pthread_mutex_lock(&mutex_);
// First, try reading from externalFileDir;
JNIEnv* env;
activity_->vm->AttachCurrentThread(&env, NULL);
jstring strPath = GetExternalFilesDirJString(env);
const char* path = env->GetStringUTFChars(strPath, NULL);
std::string s(path);
env->ReleaseStringUTFChars(strPath, path);
env->DeleteLocalRef(strPath);
activity_->vm->DetachCurrentThread();
pthread_mutex_unlock(&mutex_);
return s;
}
uint32_t JNIHelper::LoadTexture(const char* file_name) {
if (activity_ == NULL) {
LOGI(
"JNIHelper has not been initialized. Call init() to initialize the "
"helper");
return 0;
}
JNIEnv* env;
jmethodID mid;
pthread_mutex_lock(&mutex_);
activity_->vm->AttachCurrentThread(&env, NULL);
jstring name = env->NewStringUTF(file_name);
GLuint tex;
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_LINEAR_MIPMAP_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
mid = env->GetMethodID(jni_helper_java_class_, "loadTexture",
"(Ljava/lang/String;)Z");
jboolean ret = env->CallBooleanMethod(jni_helper_java_ref_, mid, name);
if (!ret) {
glDeleteTextures(1, &tex);
tex = -1;
LOGI("Texture load failed %s", file_name);
}
// Generate mipmap
glGenerateMipmap(GL_TEXTURE_2D);
env->DeleteLocalRef(name);
activity_->vm->DetachCurrentThread();
pthread_mutex_unlock(&mutex_);
return tex;
}
std::string JNIHelper::ConvertString(const char* str, const char* encode) {
if (activity_ == NULL) {
LOGI(
"JNIHelper has not been initialized. Call init() to initialize the "
"helper");
return std::string("");
}
JNIEnv* env;
pthread_mutex_lock(&mutex_);
activity_->vm->AttachCurrentThread(&env, NULL);
int32_t iLength = strlen((const char*)str);
jbyteArray array = env->NewByteArray(iLength);
env->SetByteArrayRegion(array, 0, iLength, (const signed char*)str);
jstring strEncode = env->NewStringUTF(encode);
jclass cls = env->FindClass("java/lang/String");
jmethodID ctor = env->GetMethodID(cls, "<init>", "([BLjava/lang/String;)V");
jstring object = (jstring)env->NewObject(cls, ctor, array, strEncode);
const char* cparam = env->GetStringUTFChars(object, NULL);
std::string s = std::string(cparam);
env->ReleaseStringUTFChars(object, cparam);
env->DeleteLocalRef(strEncode);
env->DeleteLocalRef(object);
activity_->vm->DetachCurrentThread();
pthread_mutex_unlock(&mutex_);
return s;
}
//---------------------------------------------------------------------------
// Audio helpers
//---------------------------------------------------------------------------
int32_t JNIHelper::GetNativeAudioBufferSize() {
if (activity_ == NULL) {
LOGI(
"JNIHelper has not been initialized. Call init() to initialize the "
"helper");
return 0;
}
JNIEnv* env;
jmethodID mid;
pthread_mutex_lock(&mutex_);
activity_->vm->AttachCurrentThread(&env, NULL);
mid = env->GetMethodID(jni_helper_java_class_, "getNativeAudioBufferSize",
"()I");
int32_t i = env->CallIntMethod(jni_helper_java_ref_, mid);
activity_->vm->DetachCurrentThread();
pthread_mutex_unlock(&mutex_);
return i;
}
int32_t JNIHelper::GetNativeAudioSampleRate() {
if (activity_ == NULL) {
LOGI(
"JNIHelper has not been initialized. Call init() to initialize the "
"helper");
return 0;
}
JNIEnv* env;
jmethodID mid;
pthread_mutex_lock(&mutex_);
activity_->vm->AttachCurrentThread(&env, NULL);
mid = env->GetMethodID(jni_helper_java_class_, "getNativeAudioSampleRate",
"()I");
int32_t i = env->CallIntMethod(jni_helper_java_ref_, mid);
activity_->vm->DetachCurrentThread();
pthread_mutex_unlock(&mutex_);
return i;
}
//---------------------------------------------------------------------------
// Misc implementations
//---------------------------------------------------------------------------
jclass JNIHelper::RetrieveClass(JNIEnv* jni, const char* class_name) {
jclass activity_class = jni->FindClass(CLASS_NAME);
jmethodID get_class_loader = jni->GetMethodID(
activity_class, "getClassLoader", "()Ljava/lang/ClassLoader;");
jobject cls = jni->CallObjectMethod(activity_->clazz, get_class_loader);
jclass class_loader = jni->FindClass("java/lang/ClassLoader");
jmethodID find_class = jni->GetMethodID(
class_loader, "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;");
jstring str_class_name = jni->NewStringUTF(class_name);
jclass class_retrieved =
(jclass)jni->CallObjectMethod(cls, find_class, str_class_name);
jni->DeleteLocalRef(str_class_name);
return class_retrieved;
}
jstring JNIHelper::GetExternalFilesDirJString(JNIEnv* env) {
if (activity_ == NULL) {
LOGI(
"JNIHelper has not been initialized. Call init() to initialize the "
"helper");
return NULL;
}
// Invoking getExternalFilesDir() java API
jclass cls_Env = env->FindClass(CLASS_NAME);
jmethodID mid = env->GetMethodID(cls_Env, "getExternalFilesDir",
"(Ljava/lang/String;)Ljava/io/File;");
jobject obj_File = env->CallObjectMethod(activity_->clazz, mid, NULL);
jclass cls_File = env->FindClass("java/io/File");
jmethodID mid_getPath =
env->GetMethodID(cls_File, "getPath", "()Ljava/lang/String;");
jstring obj_Path = (jstring)env->CallObjectMethod(obj_File, mid_getPath);
return obj_Path;
}
} // namespace ndkHelper

View File

@@ -1,183 +0,0 @@
/*
* Copyright 2013 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <jni.h>
#include <vector>
#include <string>
#include <android/log.h>
#include <android_native_app_glue.h>
#define LOGI(...) \
((void)__android_log_print( \
ANDROID_LOG_INFO, ndk_helper::JNIHelper::GetInstance()->GetAppName(), \
__VA_ARGS__))
#define LOGW(...) \
((void)__android_log_print( \
ANDROID_LOG_WARN, ndk_helper::JNIHelper::GetInstance()->GetAppName(), \
__VA_ARGS__))
#define LOGE(...) \
((void)__android_log_print( \
ANDROID_LOG_ERROR, ndk_helper::JNIHelper::GetInstance()->GetAppName(), \
__VA_ARGS__))
namespace ndk_helper {
/******************************************************************
* Helper functions for JNI calls
* This class wraps JNI calls and provides handy interface calling commonly used
*features
* in Java SDK.
* Such as
* - loading graphics files (e.g. PNG, JPG)
* - character code conversion
* - retrieving system properties which only supported in Java SDK
*
* NOTE: To use this class, add NDKHelper.java as a corresponding helpers in
*Java code
*/
class JNIHelper {
private:
std::string app_name_;
ANativeActivity* activity_;
jobject jni_helper_java_ref_;
jclass jni_helper_java_class_;
// mutex for synchronization
// This class uses singleton pattern and can be invoked from multiple threads,
// each methods locks the mutex for a thread safety
mutable pthread_mutex_t mutex_;
jstring GetExternalFilesDirJString(JNIEnv* env);
jclass RetrieveClass(JNIEnv* jni, const char* class_name);
JNIHelper();
~JNIHelper();
JNIHelper(const JNIHelper& rhs);
JNIHelper& operator=(const JNIHelper& rhs);
public:
/*
* To load your own Java classes, JNIHelper requires to be initialized with a
*ANativeActivity handle.
* This methods need to be called before any call to the helper class.
* Static member of the class
*
* arguments:
* in: activity, pointer to ANativeActivity. Used internally to set up JNI
*environment
* in: helper_class_name, pointer to Java side helper class name. (e.g.
*"com/sample/helper/NDKHelper" in samples )
*/
static void Init(ANativeActivity* activity, const char* helper_class_name);
/*
* Retrieve the singleton object of the helper.
* Static member of the class
* Methods in the class are designed as thread safe.
*/
static JNIHelper* GetInstance();
/*
* Read a file from a strorage.
* First, the method tries to read the file from an external storage.
* If it fails to read, it falls back to use assset manager and try to read
*the file from APK asset.
*
* arguments:
* in: file_name, file name to read
* out: buffer_ref, pointer to a vector buffer to read a file.
* when the call succeeded, the buffer includes contents of specified
*file
* when the call failed, contents of the buffer remains same
* return:
* true when file read succeeded
* false when it failed to read the file
*/
bool ReadFile(const char* file_name, std::vector<uint8_t>* buffer_ref);
/*
* Load and create OpenGL texture from given file name.
* The method invokes BitmapFactory in Java so it can read jpeg/png formatted
*files
*
* The methods creates mip-map and set texture parameters like this,
* glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
*GL_LINEAR_MIPMAP_NEAREST );
* glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
* glGenerateMipmap( GL_TEXTURE_2D );
*
* arguments:
* in: file_name, file name to read, PNG&JPG is supported
* return:
* OpenGL texture name when the call succeeded
* When it failed to load the texture, it returns -1
*/
uint32_t LoadTexture(const char* file_name);
/*
* Convert string from character code other than UTF-8
*
* arguments:
* in: str, pointer to a string which is encoded other than UTF-8
* in: encoding, pointer to a character encoding string.
* The encoding string can be any valid java.nio.charset.Charset name
* e.g. "UTF-16", "Shift_JIS"
* return: converted input string as an UTF-8 std::string
*/
std::string ConvertString(const char* str, const char* encode);
/*
* Retrieve external file directory through JNI call
*
* return: std::string containing external file diretory
*/
std::string GetExternalFilesDir();
/*
* Audio helper
* Retrieves native audio buffer size which is required to achieve low latency
*audio
*
* return: Native audio buffer size which is a hint to achieve low latency
*audio
* If the API is not supported (API level < 17), it returns 0
*/
int32_t GetNativeAudioBufferSize();
/*
* Audio helper
* Retrieves native audio sample rate which is required to achieve low latency
*audio
*
* return: Native audio sample rate which is a hint to achieve low latency
*audio
*/
int32_t GetNativeAudioSampleRate();
/*
* Retrieves application bundle name
*
* return: pointer to an app name string
*
*/
const char* GetAppName() { return app_name_.c_str(); }
};
} // namespace ndkHelper

View File

@@ -1,512 +0,0 @@
/*
* Copyright 2013 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <EGL/egl.h>
#include "gl3stub.h"
GLboolean gl3stubInit()
{
#define FIND_PROC(s) s = (void*)eglGetProcAddress(#s);
FIND_PROC( glReadBuffer );
FIND_PROC( glDrawRangeElements );
FIND_PROC( glTexImage3D );
FIND_PROC( glTexSubImage3D );
FIND_PROC( glCopyTexSubImage3D );
FIND_PROC( glCompressedTexImage3D );
FIND_PROC( glCompressedTexSubImage3D );
FIND_PROC( glGenQueries );
FIND_PROC( glDeleteQueries );
FIND_PROC( glIsQuery );
FIND_PROC( glBeginQuery );
FIND_PROC( glEndQuery );
FIND_PROC( glGetQueryiv );
FIND_PROC( glGetQueryObjectuiv );
FIND_PROC( glUnmapBuffer );
FIND_PROC( glGetBufferPointerv );
FIND_PROC( glDrawBuffers );
FIND_PROC( glUniformMatrix2x3fv );
FIND_PROC( glUniformMatrix3x2fv );
FIND_PROC( glUniformMatrix2x4fv );
FIND_PROC( glUniformMatrix4x2fv );
FIND_PROC( glUniformMatrix3x4fv );
FIND_PROC( glUniformMatrix4x3fv );
FIND_PROC( glBlitFramebuffer );
FIND_PROC( glRenderbufferStorageMultisample );
FIND_PROC( glFramebufferTextureLayer );
FIND_PROC( glMapBufferRange );
FIND_PROC( glFlushMappedBufferRange );
FIND_PROC( glBindVertexArray );
FIND_PROC( glDeleteVertexArrays );
FIND_PROC( glGenVertexArrays );
FIND_PROC( glIsVertexArray );
FIND_PROC( glGetIntegeri_v );
FIND_PROC( glBeginTransformFeedback );
FIND_PROC( glEndTransformFeedback );
FIND_PROC( glBindBufferRange );
FIND_PROC( glBindBufferBase );
FIND_PROC( glTransformFeedbackVaryings );
FIND_PROC( glGetTransformFeedbackVarying );
FIND_PROC( glVertexAttribIPointer );
FIND_PROC( glGetVertexAttribIiv );
FIND_PROC( glGetVertexAttribIuiv );
FIND_PROC( glVertexAttribI4i );
FIND_PROC( glVertexAttribI4ui );
FIND_PROC( glVertexAttribI4iv );
FIND_PROC( glVertexAttribI4uiv );
FIND_PROC( glGetUniformuiv );
FIND_PROC( glGetFragDataLocation );
FIND_PROC( glUniform1ui );
FIND_PROC( glUniform2ui );
FIND_PROC( glUniform3ui );
FIND_PROC( glUniform4ui );
FIND_PROC( glUniform1uiv );
FIND_PROC( glUniform2uiv );
FIND_PROC( glUniform3uiv );
FIND_PROC( glUniform4uiv );
FIND_PROC( glClearBufferiv );
FIND_PROC( glClearBufferuiv );
FIND_PROC( glClearBufferfv );
FIND_PROC( glClearBufferfi );
FIND_PROC( glGetStringi );
FIND_PROC( glCopyBufferSubData );
FIND_PROC( glGetUniformIndices );
FIND_PROC( glGetActiveUniformsiv );
FIND_PROC( glGetUniformBlockIndex );
FIND_PROC( glGetActiveUniformBlockiv );
FIND_PROC( glGetActiveUniformBlockName );
FIND_PROC( glUniformBlockBinding );
FIND_PROC( glDrawArraysInstanced );
FIND_PROC( glDrawElementsInstanced );
FIND_PROC( glFenceSync );
FIND_PROC( glIsSync );
FIND_PROC( glDeleteSync );
FIND_PROC( glClientWaitSync );
FIND_PROC( glWaitSync );
FIND_PROC( glGetInteger64v );
FIND_PROC( glGetSynciv );
FIND_PROC( glGetInteger64i_v );
FIND_PROC( glGetBufferParameteri64v );
FIND_PROC( glGenSamplers );
FIND_PROC( glDeleteSamplers );
FIND_PROC( glIsSampler );
FIND_PROC( glBindSampler );
FIND_PROC( glSamplerParameteri );
FIND_PROC( glSamplerParameteriv );
FIND_PROC( glSamplerParameterf );
FIND_PROC( glSamplerParameterfv );
FIND_PROC( glGetSamplerParameteriv );
FIND_PROC( glGetSamplerParameterfv );
FIND_PROC( glVertexAttribDivisor );
FIND_PROC( glBindTransformFeedback );
FIND_PROC( glDeleteTransformFeedbacks );
FIND_PROC( glGenTransformFeedbacks );
FIND_PROC( glIsTransformFeedback );
FIND_PROC( glPauseTransformFeedback );
FIND_PROC( glResumeTransformFeedback );
FIND_PROC( glGetProgramBinary );
FIND_PROC( glProgramBinary );
FIND_PROC( glProgramParameteri );
FIND_PROC( glInvalidateFramebuffer );
FIND_PROC( glInvalidateSubFramebuffer );
FIND_PROC( glTexStorage2D );
FIND_PROC( glTexStorage3D );
FIND_PROC( glGetInternalformativ );
#undef FIND_PROC
if( !glReadBuffer || !glDrawRangeElements || !glTexImage3D || !glTexSubImage3D
|| !glCopyTexSubImage3D || !glCompressedTexImage3D
|| !glCompressedTexSubImage3D || !glGenQueries || !glDeleteQueries
|| !glIsQuery || !glBeginQuery || !glEndQuery || !glGetQueryiv
|| !glGetQueryObjectuiv || !glUnmapBuffer || !glGetBufferPointerv
|| !glDrawBuffers || !glUniformMatrix2x3fv || !glUniformMatrix3x2fv
|| !glUniformMatrix2x4fv || !glUniformMatrix4x2fv || !glUniformMatrix3x4fv
|| !glUniformMatrix4x3fv || !glBlitFramebuffer
|| !glRenderbufferStorageMultisample || !glFramebufferTextureLayer
|| !glMapBufferRange || !glFlushMappedBufferRange || !glBindVertexArray
|| !glDeleteVertexArrays || !glGenVertexArrays || !glIsVertexArray
|| !glGetIntegeri_v || !glBeginTransformFeedback || !glEndTransformFeedback
|| !glBindBufferRange || !glBindBufferBase || !glTransformFeedbackVaryings
|| !glGetTransformFeedbackVarying || !glVertexAttribIPointer
|| !glGetVertexAttribIiv || !glGetVertexAttribIuiv || !glVertexAttribI4i
|| !glVertexAttribI4ui || !glVertexAttribI4iv || !glVertexAttribI4uiv
|| !glGetUniformuiv || !glGetFragDataLocation || !glUniform1ui
|| !glUniform2ui || !glUniform3ui || !glUniform4ui || !glUniform1uiv
|| !glUniform2uiv || !glUniform3uiv || !glUniform4uiv || !glClearBufferiv
|| !glClearBufferuiv || !glClearBufferfv || !glClearBufferfi || !glGetStringi
|| !glCopyBufferSubData || !glGetUniformIndices || !glGetActiveUniformsiv
|| !glGetUniformBlockIndex || !glGetActiveUniformBlockiv
|| !glGetActiveUniformBlockName || !glUniformBlockBinding
|| !glDrawArraysInstanced || !glDrawElementsInstanced || !glFenceSync
|| !glIsSync || !glDeleteSync || !glClientWaitSync || !glWaitSync
|| !glGetInteger64v || !glGetSynciv || !glGetInteger64i_v
|| !glGetBufferParameteri64v || !glGenSamplers || !glDeleteSamplers
|| !glIsSampler || !glBindSampler || !glSamplerParameteri
|| !glSamplerParameteriv || !glSamplerParameterf || !glSamplerParameterfv
|| !glGetSamplerParameteriv || !glGetSamplerParameterfv
|| !glVertexAttribDivisor || !glBindTransformFeedback
|| !glDeleteTransformFeedbacks || !glGenTransformFeedbacks
|| !glIsTransformFeedback || !glPauseTransformFeedback
|| !glResumeTransformFeedback || !glGetProgramBinary || !glProgramBinary
|| !glProgramParameteri || !glInvalidateFramebuffer
|| !glInvalidateSubFramebuffer || !glTexStorage2D || !glTexStorage3D
|| !glGetInternalformativ )
{
return GL_FALSE;
}
return GL_TRUE;
}
/* Function pointer definitions */GL_APICALL void (* GL_APIENTRY glReadBuffer)( GLenum mode );
GL_APICALL void (* GL_APIENTRY glDrawRangeElements)( GLenum mode,
GLuint start,
GLuint end,
GLsizei count,
GLenum type,
const GLvoid* indices );
GL_APICALL void (* GL_APIENTRY glTexImage3D)( GLenum target,
GLint level,
GLint internalformat,
GLsizei width,
GLsizei height,
GLsizei depth,
GLint border,
GLenum format,
GLenum type,
const GLvoid* pixels );
GL_APICALL void (* GL_APIENTRY glTexSubImage3D)( GLenum target,
GLint level,
GLint xoffset,
GLint yoffset,
GLint zoffset,
GLsizei width,
GLsizei height,
GLsizei depth,
GLenum format,
GLenum type,
const GLvoid* pixels );
GL_APICALL void (* GL_APIENTRY glCopyTexSubImage3D)( GLenum target,
GLint level,
GLint xoffset,
GLint yoffset,
GLint zoffset,
GLint x,
GLint y,
GLsizei width,
GLsizei height );
GL_APICALL void (* GL_APIENTRY glCompressedTexImage3D)( GLenum target,
GLint level,
GLenum internalformat,
GLsizei width,
GLsizei height,
GLsizei depth,
GLint border,
GLsizei imageSize,
const GLvoid* data );
GL_APICALL void (* GL_APIENTRY glCompressedTexSubImage3D)( GLenum target,
GLint level,
GLint xoffset,
GLint yoffset,
GLint zoffset,
GLsizei width,
GLsizei height,
GLsizei depth,
GLenum format,
GLsizei imageSize,
const GLvoid* data );
GL_APICALL void (* GL_APIENTRY glGenQueries)( GLsizei n, GLuint* ids );
GL_APICALL void (* GL_APIENTRY glDeleteQueries)( GLsizei n, const GLuint* ids );
GL_APICALL GLboolean (* GL_APIENTRY glIsQuery)( GLuint id );
GL_APICALL void (* GL_APIENTRY glBeginQuery)( GLenum target, GLuint id );
GL_APICALL void (* GL_APIENTRY glEndQuery)( GLenum target );
GL_APICALL void (* GL_APIENTRY glGetQueryiv)( GLenum target, GLenum pname, GLint* params );
GL_APICALL void (* GL_APIENTRY glGetQueryObjectuiv)( GLuint id,
GLenum pname,
GLuint* params );
GL_APICALL GLboolean (* GL_APIENTRY glUnmapBuffer)( GLenum target );
GL_APICALL void (* GL_APIENTRY glGetBufferPointerv)( GLenum target,
GLenum pname,
GLvoid** params );
GL_APICALL void (* GL_APIENTRY glDrawBuffers)( GLsizei n, const GLenum* bufs );
GL_APICALL void (* GL_APIENTRY glUniformMatrix2x3fv)( GLint location,
GLsizei count,
GLboolean transpose,
const GLfloat* value );
GL_APICALL void (* GL_APIENTRY glUniformMatrix3x2fv)( GLint location,
GLsizei count,
GLboolean transpose,
const GLfloat* value );
GL_APICALL void (* GL_APIENTRY glUniformMatrix2x4fv)( GLint location,
GLsizei count,
GLboolean transpose,
const GLfloat* value );
GL_APICALL void (* GL_APIENTRY glUniformMatrix4x2fv)( GLint location,
GLsizei count,
GLboolean transpose,
const GLfloat* value );
GL_APICALL void (* GL_APIENTRY glUniformMatrix3x4fv)( GLint location,
GLsizei count,
GLboolean transpose,
const GLfloat* value );
GL_APICALL void (* GL_APIENTRY glUniformMatrix4x3fv)( GLint location,
GLsizei count,
GLboolean transpose,
const GLfloat* value );
GL_APICALL void (* GL_APIENTRY glBlitFramebuffer)( GLint srcX0,
GLint srcY0,
GLint srcX1,
GLint srcY1,
GLint dstX0,
GLint dstY0,
GLint dstX1,
GLint dstY1,
GLbitfield mask,
GLenum filter );
GL_APICALL void (* GL_APIENTRY glRenderbufferStorageMultisample)( GLenum target,
GLsizei samples,
GLenum internalformat,
GLsizei width,
GLsizei height );
GL_APICALL void (* GL_APIENTRY glFramebufferTextureLayer)( GLenum target,
GLenum attachment,
GLuint texture,
GLint level,
GLint layer );
GL_APICALL GLvoid* (* GL_APIENTRY glMapBufferRange)( GLenum target,
GLintptr offset,
GLsizeiptr length,
GLbitfield access );
GL_APICALL void (* GL_APIENTRY glFlushMappedBufferRange)( GLenum target,
GLintptr offset,
GLsizeiptr length );
GL_APICALL void (* GL_APIENTRY glBindVertexArray)( GLuint array );
GL_APICALL void (* GL_APIENTRY glDeleteVertexArrays)( GLsizei n, const GLuint* arrays );
GL_APICALL void (* GL_APIENTRY glGenVertexArrays)( GLsizei n, GLuint* arrays );
GL_APICALL GLboolean (* GL_APIENTRY glIsVertexArray)( GLuint array );
GL_APICALL void (* GL_APIENTRY glGetIntegeri_v)( GLenum target,
GLuint index,
GLint* data );
GL_APICALL void (* GL_APIENTRY glBeginTransformFeedback)( GLenum primitiveMode );
GL_APICALL void (* GL_APIENTRY glEndTransformFeedback)( void );
GL_APICALL void (* GL_APIENTRY glBindBufferRange)( GLenum target,
GLuint index,
GLuint buffer,
GLintptr offset,
GLsizeiptr size );
GL_APICALL void (* GL_APIENTRY glBindBufferBase)( GLenum target,
GLuint index,
GLuint buffer );
GL_APICALL void (* GL_APIENTRY glTransformFeedbackVaryings)( GLuint program,
GLsizei count,
const GLchar* const * varyings,
GLenum bufferMode );
GL_APICALL void (* GL_APIENTRY glGetTransformFeedbackVarying)( GLuint program,
GLuint index,
GLsizei bufSize,
GLsizei* length,
GLsizei* size,
GLenum* type,
GLchar* name );
GL_APICALL void (* GL_APIENTRY glVertexAttribIPointer)( GLuint index,
GLint size,
GLenum type,
GLsizei stride,
const GLvoid* pointer );
GL_APICALL void (* GL_APIENTRY glGetVertexAttribIiv)( GLuint index,
GLenum pname,
GLint* params );
GL_APICALL void (* GL_APIENTRY glGetVertexAttribIuiv)( GLuint index,
GLenum pname,
GLuint* params );
GL_APICALL void (* GL_APIENTRY glVertexAttribI4i)( GLuint index,
GLint x,
GLint y,
GLint z,
GLint w );
GL_APICALL void (* GL_APIENTRY glVertexAttribI4ui)( GLuint index,
GLuint x,
GLuint y,
GLuint z,
GLuint w );
GL_APICALL void (* GL_APIENTRY glVertexAttribI4iv)( GLuint index, const GLint* v );
GL_APICALL void (* GL_APIENTRY glVertexAttribI4uiv)( GLuint index, const GLuint* v );
GL_APICALL void (* GL_APIENTRY glGetUniformuiv)( GLuint program,
GLint location,
GLuint* params );
GL_APICALL GLint (* GL_APIENTRY glGetFragDataLocation)( GLuint program,
const GLchar *name );
GL_APICALL void (* GL_APIENTRY glUniform1ui)( GLint location, GLuint v0 );
GL_APICALL void (* GL_APIENTRY glUniform2ui)( GLint location, GLuint v0, GLuint v1 );
GL_APICALL void (* GL_APIENTRY glUniform3ui)( GLint location,
GLuint v0,
GLuint v1,
GLuint v2 );
GL_APICALL void (* GL_APIENTRY glUniform4ui)( GLint location,
GLuint v0,
GLuint v1,
GLuint v2,
GLuint v3 );
GL_APICALL void (* GL_APIENTRY glUniform1uiv)( GLint location,
GLsizei count,
const GLuint* value );
GL_APICALL void (* GL_APIENTRY glUniform2uiv)( GLint location,
GLsizei count,
const GLuint* value );
GL_APICALL void (* GL_APIENTRY glUniform3uiv)( GLint location,
GLsizei count,
const GLuint* value );
GL_APICALL void (* GL_APIENTRY glUniform4uiv)( GLint location,
GLsizei count,
const GLuint* value );
GL_APICALL void (* GL_APIENTRY glClearBufferiv)( GLenum buffer,
GLint drawbuffer,
const GLint* value );
GL_APICALL void (* GL_APIENTRY glClearBufferuiv)( GLenum buffer,
GLint drawbuffer,
const GLuint* value );
GL_APICALL void (* GL_APIENTRY glClearBufferfv)( GLenum buffer,
GLint drawbuffer,
const GLfloat* value );
GL_APICALL void (* GL_APIENTRY glClearBufferfi)( GLenum buffer,
GLint drawbuffer,
GLfloat depth,
GLint stencil );
GL_APICALL const GLubyte* (* GL_APIENTRY glGetStringi)( GLenum name, GLuint index );
GL_APICALL void (* GL_APIENTRY glCopyBufferSubData)( GLenum readTarget,
GLenum writeTarget,
GLintptr readOffset,
GLintptr writeOffset,
GLsizeiptr size );
GL_APICALL void (* GL_APIENTRY glGetUniformIndices)( GLuint program,
GLsizei uniformCount,
const GLchar* const * uniformNames,
GLuint* uniformIndices );
GL_APICALL void (* GL_APIENTRY glGetActiveUniformsiv)( GLuint program,
GLsizei uniformCount,
const GLuint* uniformIndices,
GLenum pname,
GLint* params );
GL_APICALL GLuint (* GL_APIENTRY glGetUniformBlockIndex)( GLuint program,
const GLchar* uniformBlockName );
GL_APICALL void (* GL_APIENTRY glGetActiveUniformBlockiv)( GLuint program,
GLuint uniformBlockIndex,
GLenum pname,
GLint* params );
GL_APICALL void (* GL_APIENTRY glGetActiveUniformBlockName)( GLuint program,
GLuint uniformBlockIndex,
GLsizei bufSize,
GLsizei* length,
GLchar* uniformBlockName );
GL_APICALL void (* GL_APIENTRY glUniformBlockBinding)( GLuint program,
GLuint uniformBlockIndex,
GLuint uniformBlockBinding );
GL_APICALL void (* GL_APIENTRY glDrawArraysInstanced)( GLenum mode,
GLint first,
GLsizei count,
GLsizei instanceCount );
GL_APICALL void (* GL_APIENTRY glDrawElementsInstanced)( GLenum mode,
GLsizei count,
GLenum type,
const GLvoid* indices,
GLsizei instanceCount );
GL_APICALL GLsync (* GL_APIENTRY glFenceSync)( GLenum condition, GLbitfield flags );
GL_APICALL GLboolean (* GL_APIENTRY glIsSync)( GLsync sync );
GL_APICALL void (* GL_APIENTRY glDeleteSync)( GLsync sync );
GL_APICALL GLenum (* GL_APIENTRY glClientWaitSync)( GLsync sync,
GLbitfield flags,
GLuint64 timeout );
GL_APICALL void (* GL_APIENTRY glWaitSync)( GLsync sync,
GLbitfield flags,
GLuint64 timeout );
GL_APICALL void (* GL_APIENTRY glGetInteger64v)( GLenum pname, GLint64* params );
GL_APICALL void (* GL_APIENTRY glGetSynciv)( GLsync sync,
GLenum pname,
GLsizei bufSize,
GLsizei* length,
GLint* values );
GL_APICALL void (* GL_APIENTRY glGetInteger64i_v)( GLenum target,
GLuint index,
GLint64* data );
GL_APICALL void (* GL_APIENTRY glGetBufferParameteri64v)( GLenum target,
GLenum pname,
GLint64* params );
GL_APICALL void (* GL_APIENTRY glGenSamplers)( GLsizei count, GLuint* samplers );
GL_APICALL void (* GL_APIENTRY glDeleteSamplers)( GLsizei count, const GLuint* samplers );
GL_APICALL GLboolean (* GL_APIENTRY glIsSampler)( GLuint sampler );
GL_APICALL void (* GL_APIENTRY glBindSampler)( GLuint unit, GLuint sampler );
GL_APICALL void (* GL_APIENTRY glSamplerParameteri)( GLuint sampler,
GLenum pname,
GLint param );
GL_APICALL void (* GL_APIENTRY glSamplerParameteriv)( GLuint sampler,
GLenum pname,
const GLint* param );
GL_APICALL void (* GL_APIENTRY glSamplerParameterf)( GLuint sampler,
GLenum pname,
GLfloat param );
GL_APICALL void (* GL_APIENTRY glSamplerParameterfv)( GLuint sampler,
GLenum pname,
const GLfloat* param );
GL_APICALL void (* GL_APIENTRY glGetSamplerParameteriv)( GLuint sampler,
GLenum pname,
GLint* params );
GL_APICALL void (* GL_APIENTRY glGetSamplerParameterfv)( GLuint sampler,
GLenum pname,
GLfloat* params );
GL_APICALL void (* GL_APIENTRY glVertexAttribDivisor)( GLuint index, GLuint divisor );
GL_APICALL void (* GL_APIENTRY glBindTransformFeedback)( GLenum target, GLuint id );
GL_APICALL void (* GL_APIENTRY glDeleteTransformFeedbacks)( GLsizei n, const GLuint* ids );
GL_APICALL void (* GL_APIENTRY glGenTransformFeedbacks)( GLsizei n, GLuint* ids );
GL_APICALL GLboolean (* GL_APIENTRY glIsTransformFeedback)( GLuint id );
GL_APICALL void (* GL_APIENTRY glPauseTransformFeedback)( void );
GL_APICALL void (* GL_APIENTRY glResumeTransformFeedback)( void );
GL_APICALL void (* GL_APIENTRY glGetProgramBinary)( GLuint program,
GLsizei bufSize,
GLsizei* length,
GLenum* binaryFormat,
GLvoid* binary );
GL_APICALL void (* GL_APIENTRY glProgramBinary)( GLuint program,
GLenum binaryFormat,
const GLvoid* binary,
GLsizei length );
GL_APICALL void (* GL_APIENTRY glProgramParameteri)( GLuint program,
GLenum pname,
GLint value );
GL_APICALL void (* GL_APIENTRY glInvalidateFramebuffer)( GLenum target,
GLsizei numAttachments,
const GLenum* attachments );
GL_APICALL void (* GL_APIENTRY glInvalidateSubFramebuffer)( GLenum target,
GLsizei numAttachments,
const GLenum* attachments,
GLint x,
GLint y,
GLsizei width,
GLsizei height );
GL_APICALL void (* GL_APIENTRY glTexStorage2D)( GLenum target,
GLsizei levels,
GLenum internalformat,
GLsizei width,
GLsizei height );
GL_APICALL void (* GL_APIENTRY glTexStorage3D)( GLenum target,
GLsizei levels,
GLenum internalformat,
GLsizei width,
GLsizei height,
GLsizei depth );
GL_APICALL void (* GL_APIENTRY glGetInternalformativ)( GLenum target,
GLenum internalformat,
GLenum pname,
GLsizei bufSize,
GLint* params );

View File

@@ -1,663 +0,0 @@
#ifndef __gl3_h_
#define __gl3_h_
/*
* stub gl3.h for dynamic loading, based on:
* gl3.h last updated on $Date: 2013-02-12 14:37:24 -0800 (Tue, 12 Feb 2013) $
*
* Changes:
* - Added #include <GLES2/gl2.h>
* - Removed duplicate OpenGL ES 2.0 declarations
* - Converted OpenGL ES 3.0 function prototypes to function pointer
* declarations
* - Added gl3stubInit() declaration
*/
#include <GLES2/gl2.h>
#include <android/api-level.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
** Copyright (c) 2007-2013 The Khronos Group Inc.
**
** Permission is hereby granted, free of charge, to any person obtaining a
** copy of this software and/or associated documentation files (the
** "Materials"), to deal in the Materials without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Materials, and to
** permit persons to whom the Materials are furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be included
** in all copies or substantial portions of the Materials.
**
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
*/
/*
* This files is for apps that want to use ES3 if present,
* but continue to work on pre-API-18 devices. They can't just link to -lGLESv3
*since
* that library doesn't exist on pre-API-18 devices.
* The function dynamically check if OpenGLES3.0 APIs are present and fill in if
*there are.
* Also the header defines some extra variables for OpenGLES3.0.
*
*/
/* Call this function before calling any OpenGL ES 3.0 functions. It will
* return GL_TRUE if the OpenGL ES 3.0 was successfully initialized, GL_FALSE
* otherwise. */
GLboolean gl3stubInit();
/*-------------------------------------------------------------------------
* Data type definitions
*-----------------------------------------------------------------------*/
/* OpenGL ES 3.0 */
typedef unsigned short GLhalf;
#if __ANDROID_API__ <= 19
typedef khronos_int64_t GLint64;
typedef khronos_uint64_t GLuint64;
typedef struct __GLsync* GLsync;
#endif
/*-------------------------------------------------------------------------
* Token definitions
*-----------------------------------------------------------------------*/
/* OpenGL ES core versions */
#define GL_ES_VERSION_3_0 1
/* OpenGL ES 3.0 */
#define GL_READ_BUFFER 0x0C02
#define GL_UNPACK_ROW_LENGTH 0x0CF2
#define GL_UNPACK_SKIP_ROWS 0x0CF3
#define GL_UNPACK_SKIP_PIXELS 0x0CF4
#define GL_PACK_ROW_LENGTH 0x0D02
#define GL_PACK_SKIP_ROWS 0x0D03
#define GL_PACK_SKIP_PIXELS 0x0D04
#define GL_COLOR 0x1800
#define GL_DEPTH 0x1801
#define GL_STENCIL 0x1802
#define GL_RED 0x1903
#define GL_RGB8 0x8051
#define GL_RGBA8 0x8058
#define GL_RGB10_A2 0x8059
#define GL_TEXTURE_BINDING_3D 0x806A
#define GL_UNPACK_SKIP_IMAGES 0x806D
#define GL_UNPACK_IMAGE_HEIGHT 0x806E
#define GL_TEXTURE_3D 0x806F
#define GL_TEXTURE_WRAP_R 0x8072
#define GL_MAX_3D_TEXTURE_SIZE 0x8073
#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368
#define GL_MAX_ELEMENTS_VERTICES 0x80E8
#define GL_MAX_ELEMENTS_INDICES 0x80E9
#define GL_TEXTURE_MIN_LOD 0x813A
#define GL_TEXTURE_MAX_LOD 0x813B
#define GL_TEXTURE_BASE_LEVEL 0x813C
#define GL_TEXTURE_MAX_LEVEL 0x813D
#define GL_MIN 0x8007
#define GL_MAX 0x8008
#define GL_DEPTH_COMPONENT24 0x81A6
#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD
#define GL_TEXTURE_COMPARE_MODE 0x884C
#define GL_TEXTURE_COMPARE_FUNC 0x884D
#define GL_CURRENT_QUERY 0x8865
#define GL_QUERY_RESULT 0x8866
#define GL_QUERY_RESULT_AVAILABLE 0x8867
#define GL_BUFFER_MAPPED 0x88BC
#define GL_BUFFER_MAP_POINTER 0x88BD
#define GL_STREAM_READ 0x88E1
#define GL_STREAM_COPY 0x88E2
#define GL_STATIC_READ 0x88E5
#define GL_STATIC_COPY 0x88E6
#define GL_DYNAMIC_READ 0x88E9
#define GL_DYNAMIC_COPY 0x88EA
#define GL_MAX_DRAW_BUFFERS 0x8824
#define GL_DRAW_BUFFER0 0x8825
#define GL_DRAW_BUFFER1 0x8826
#define GL_DRAW_BUFFER2 0x8827
#define GL_DRAW_BUFFER3 0x8828
#define GL_DRAW_BUFFER4 0x8829
#define GL_DRAW_BUFFER5 0x882A
#define GL_DRAW_BUFFER6 0x882B
#define GL_DRAW_BUFFER7 0x882C
#define GL_DRAW_BUFFER8 0x882D
#define GL_DRAW_BUFFER9 0x882E
#define GL_DRAW_BUFFER10 0x882F
#define GL_DRAW_BUFFER11 0x8830
#define GL_DRAW_BUFFER12 0x8831
#define GL_DRAW_BUFFER13 0x8832
#define GL_DRAW_BUFFER14 0x8833
#define GL_DRAW_BUFFER15 0x8834
#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49
#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A
#define GL_SAMPLER_3D 0x8B5F
#define GL_SAMPLER_2D_SHADOW 0x8B62
#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B
#define GL_PIXEL_PACK_BUFFER 0x88EB
#define GL_PIXEL_UNPACK_BUFFER 0x88EC
#define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED
#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF
#define GL_FLOAT_MAT2x3 0x8B65
#define GL_FLOAT_MAT2x4 0x8B66
#define GL_FLOAT_MAT3x2 0x8B67
#define GL_FLOAT_MAT3x4 0x8B68
#define GL_FLOAT_MAT4x2 0x8B69
#define GL_FLOAT_MAT4x3 0x8B6A
#define GL_SRGB 0x8C40
#define GL_SRGB8 0x8C41
#define GL_SRGB8_ALPHA8 0x8C43
#define GL_COMPARE_REF_TO_TEXTURE 0x884E
#define GL_MAJOR_VERSION 0x821B
#define GL_MINOR_VERSION 0x821C
#define GL_NUM_EXTENSIONS 0x821D
#define GL_RGBA32F 0x8814
#define GL_RGB32F 0x8815
#define GL_RGBA16F 0x881A
#define GL_RGB16F 0x881B
#define GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD
#define GL_MAX_ARRAY_TEXTURE_LAYERS 0x88FF
#define GL_MIN_PROGRAM_TEXEL_OFFSET 0x8904
#define GL_MAX_PROGRAM_TEXEL_OFFSET 0x8905
#define GL_MAX_VARYING_COMPONENTS 0x8B4B
#define GL_TEXTURE_2D_ARRAY 0x8C1A
#define GL_TEXTURE_BINDING_2D_ARRAY 0x8C1D
#define GL_R11F_G11F_B10F 0x8C3A
#define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B
#define GL_RGB9_E5 0x8C3D
#define GL_UNSIGNED_INT_5_9_9_9_REV 0x8C3E
#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 0x8C76
#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE 0x8C7F
#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80
#define GL_TRANSFORM_FEEDBACK_VARYINGS 0x8C83
#define GL_TRANSFORM_FEEDBACK_BUFFER_START 0x8C84
#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE 0x8C85
#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88
#define GL_RASTERIZER_DISCARD 0x8C89
#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A
#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B
#define GL_INTERLEAVED_ATTRIBS 0x8C8C
#define GL_SEPARATE_ATTRIBS 0x8C8D
#define GL_TRANSFORM_FEEDBACK_BUFFER 0x8C8E
#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING 0x8C8F
#define GL_RGBA32UI 0x8D70
#define GL_RGB32UI 0x8D71
#define GL_RGBA16UI 0x8D76
#define GL_RGB16UI 0x8D77
#define GL_RGBA8UI 0x8D7C
#define GL_RGB8UI 0x8D7D
#define GL_RGBA32I 0x8D82
#define GL_RGB32I 0x8D83
#define GL_RGBA16I 0x8D88
#define GL_RGB16I 0x8D89
#define GL_RGBA8I 0x8D8E
#define GL_RGB8I 0x8D8F
#define GL_RED_INTEGER 0x8D94
#define GL_RGB_INTEGER 0x8D98
#define GL_RGBA_INTEGER 0x8D99
#define GL_SAMPLER_2D_ARRAY 0x8DC1
#define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4
#define GL_SAMPLER_CUBE_SHADOW 0x8DC5
#define GL_UNSIGNED_INT_VEC2 0x8DC6
#define GL_UNSIGNED_INT_VEC3 0x8DC7
#define GL_UNSIGNED_INT_VEC4 0x8DC8
#define GL_INT_SAMPLER_2D 0x8DCA
#define GL_INT_SAMPLER_3D 0x8DCB
#define GL_INT_SAMPLER_CUBE 0x8DCC
#define GL_INT_SAMPLER_2D_ARRAY 0x8DCF
#define GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2
#define GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3
#define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4
#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7
#define GL_BUFFER_ACCESS_FLAGS 0x911F
#define GL_BUFFER_MAP_LENGTH 0x9120
#define GL_BUFFER_MAP_OFFSET 0x9121
#define GL_DEPTH_COMPONENT32F 0x8CAC
#define GL_DEPTH32F_STENCIL8 0x8CAD
#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD
#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210
#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211
#define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212
#define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213
#define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214
#define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215
#define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216
#define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217
#define GL_FRAMEBUFFER_DEFAULT 0x8218
#define GL_FRAMEBUFFER_UNDEFINED 0x8219
#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A
#define GL_DEPTH_STENCIL 0x84F9
#define GL_UNSIGNED_INT_24_8 0x84FA
#define GL_DEPTH24_STENCIL8 0x88F0
#define GL_UNSIGNED_NORMALIZED 0x8C17
#define GL_DRAW_FRAMEBUFFER_BINDING GL_FRAMEBUFFER_BINDING
#define GL_READ_FRAMEBUFFER 0x8CA8
#define GL_DRAW_FRAMEBUFFER 0x8CA9
#define GL_READ_FRAMEBUFFER_BINDING 0x8CAA
#define GL_RENDERBUFFER_SAMPLES 0x8CAB
#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4
#define GL_MAX_COLOR_ATTACHMENTS 0x8CDF
#define GL_COLOR_ATTACHMENT1 0x8CE1
#define GL_COLOR_ATTACHMENT2 0x8CE2
#define GL_COLOR_ATTACHMENT3 0x8CE3
#define GL_COLOR_ATTACHMENT4 0x8CE4
#define GL_COLOR_ATTACHMENT5 0x8CE5
#define GL_COLOR_ATTACHMENT6 0x8CE6
#define GL_COLOR_ATTACHMENT7 0x8CE7
#define GL_COLOR_ATTACHMENT8 0x8CE8
#define GL_COLOR_ATTACHMENT9 0x8CE9
#define GL_COLOR_ATTACHMENT10 0x8CEA
#define GL_COLOR_ATTACHMENT11 0x8CEB
#define GL_COLOR_ATTACHMENT12 0x8CEC
#define GL_COLOR_ATTACHMENT13 0x8CED
#define GL_COLOR_ATTACHMENT14 0x8CEE
#define GL_COLOR_ATTACHMENT15 0x8CEF
#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56
#define GL_MAX_SAMPLES 0x8D57
#define GL_HALF_FLOAT 0x140B
#define GL_MAP_READ_BIT 0x0001
#define GL_MAP_WRITE_BIT 0x0002
#define GL_MAP_INVALIDATE_RANGE_BIT 0x0004
#define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008
#define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010
#define GL_MAP_UNSYNCHRONIZED_BIT 0x0020
#define GL_RG 0x8227
#define GL_RG_INTEGER 0x8228
#define GL_R8 0x8229
#define GL_RG8 0x822B
#define GL_R16F 0x822D
#define GL_R32F 0x822E
#define GL_RG16F 0x822F
#define GL_RG32F 0x8230
#define GL_R8I 0x8231
#define GL_R8UI 0x8232
#define GL_R16I 0x8233
#define GL_R16UI 0x8234
#define GL_R32I 0x8235
#define GL_R32UI 0x8236
#define GL_RG8I 0x8237
#define GL_RG8UI 0x8238
#define GL_RG16I 0x8239
#define GL_RG16UI 0x823A
#define GL_RG32I 0x823B
#define GL_RG32UI 0x823C
#define GL_VERTEX_ARRAY_BINDING 0x85B5
#define GL_R8_SNORM 0x8F94
#define GL_RG8_SNORM 0x8F95
#define GL_RGB8_SNORM 0x8F96
#define GL_RGBA8_SNORM 0x8F97
#define GL_SIGNED_NORMALIZED 0x8F9C
#define GL_PRIMITIVE_RESTART_FIXED_INDEX 0x8D69
#define GL_COPY_READ_BUFFER 0x8F36
#define GL_COPY_WRITE_BUFFER 0x8F37
#define GL_COPY_READ_BUFFER_BINDING GL_COPY_READ_BUFFER
#define GL_COPY_WRITE_BUFFER_BINDING GL_COPY_WRITE_BUFFER
#define GL_UNIFORM_BUFFER 0x8A11
#define GL_UNIFORM_BUFFER_BINDING 0x8A28
#define GL_UNIFORM_BUFFER_START 0x8A29
#define GL_UNIFORM_BUFFER_SIZE 0x8A2A
#define GL_MAX_VERTEX_UNIFORM_BLOCKS 0x8A2B
#define GL_MAX_FRAGMENT_UNIFORM_BLOCKS 0x8A2D
#define GL_MAX_COMBINED_UNIFORM_BLOCKS 0x8A2E
#define GL_MAX_UNIFORM_BUFFER_BINDINGS 0x8A2F
#define GL_MAX_UNIFORM_BLOCK_SIZE 0x8A30
#define GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS 0x8A31
#define GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS 0x8A33
#define GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT 0x8A34
#define GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH 0x8A35
#define GL_ACTIVE_UNIFORM_BLOCKS 0x8A36
#define GL_UNIFORM_TYPE 0x8A37
#define GL_UNIFORM_SIZE 0x8A38
#define GL_UNIFORM_NAME_LENGTH 0x8A39
#define GL_UNIFORM_BLOCK_INDEX 0x8A3A
#define GL_UNIFORM_OFFSET 0x8A3B
#define GL_UNIFORM_ARRAY_STRIDE 0x8A3C
#define GL_UNIFORM_MATRIX_STRIDE 0x8A3D
#define GL_UNIFORM_IS_ROW_MAJOR 0x8A3E
#define GL_UNIFORM_BLOCK_BINDING 0x8A3F
#define GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40
#define GL_UNIFORM_BLOCK_NAME_LENGTH 0x8A41
#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42
#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES 0x8A43
#define GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER 0x8A44
#define GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46
#define GL_INVALID_INDEX 0xFFFFFFFFu
#define GL_MAX_VERTEX_OUTPUT_COMPONENTS 0x9122
#define GL_MAX_FRAGMENT_INPUT_COMPONENTS 0x9125
#define GL_MAX_SERVER_WAIT_TIMEOUT 0x9111
#define GL_OBJECT_TYPE 0x9112
#define GL_SYNC_CONDITION 0x9113
#define GL_SYNC_STATUS 0x9114
#define GL_SYNC_FLAGS 0x9115
#define GL_SYNC_FENCE 0x9116
#define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117
#define GL_UNSIGNALED 0x9118
#define GL_SIGNALED 0x9119
#define GL_ALREADY_SIGNALED 0x911A
#define GL_TIMEOUT_EXPIRED 0x911B
#define GL_CONDITION_SATISFIED 0x911C
#define GL_WAIT_FAILED 0x911D
#define GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001
#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFFull
#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR 0x88FE
#define GL_ANY_SAMPLES_PASSED 0x8C2F
#define GL_ANY_SAMPLES_PASSED_CONSERVATIVE 0x8D6A
#define GL_SAMPLER_BINDING 0x8919
#define GL_RGB10_A2UI 0x906F
#define GL_TEXTURE_SWIZZLE_R 0x8E42
#define GL_TEXTURE_SWIZZLE_G 0x8E43
#define GL_TEXTURE_SWIZZLE_B 0x8E44
#define GL_TEXTURE_SWIZZLE_A 0x8E45
#define GL_GREEN 0x1904
#define GL_BLUE 0x1905
#define GL_INT_2_10_10_10_REV 0x8D9F
#define GL_TRANSFORM_FEEDBACK 0x8E22
#define GL_TRANSFORM_FEEDBACK_PAUSED 0x8E23
#define GL_TRANSFORM_FEEDBACK_ACTIVE 0x8E24
#define GL_TRANSFORM_FEEDBACK_BINDING 0x8E25
#define GL_PROGRAM_BINARY_RETRIEVABLE_HINT 0x8257
#define GL_PROGRAM_BINARY_LENGTH 0x8741
#define GL_NUM_PROGRAM_BINARY_FORMATS 0x87FE
#define GL_PROGRAM_BINARY_FORMATS 0x87FF
#define GL_COMPRESSED_R11_EAC 0x9270
#define GL_COMPRESSED_SIGNED_R11_EAC 0x9271
#define GL_COMPRESSED_RG11_EAC 0x9272
#define GL_COMPRESSED_SIGNED_RG11_EAC 0x9273
#define GL_COMPRESSED_RGB8_ETC2 0x9274
#define GL_COMPRESSED_SRGB8_ETC2 0x9275
#define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276
#define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277
#define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278
#define GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279
#define GL_TEXTURE_IMMUTABLE_FORMAT 0x912F
#define GL_MAX_ELEMENT_INDEX 0x8D6B
#define GL_NUM_SAMPLE_COUNTS 0x9380
#define GL_TEXTURE_IMMUTABLE_LEVELS 0x82DF
/*-------------------------------------------------------------------------
* Entrypoint definitions
*-----------------------------------------------------------------------*/
/* OpenGL ES 3.0 */
extern GL_APICALL void (*GL_APIENTRY glReadBuffer)(GLenum mode);
extern GL_APICALL void (*GL_APIENTRY glDrawRangeElements)(
GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type,
const GLvoid* indices);
extern GL_APICALL void (*GL_APIENTRY glTexImage3D)(
GLenum target, GLint level, GLint internalformat, GLsizei width,
GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type,
const GLvoid* pixels);
extern GL_APICALL void (*GL_APIENTRY glTexSubImage3D)(
GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type,
const GLvoid* pixels);
extern GL_APICALL void (*GL_APIENTRY glCopyTexSubImage3D)(
GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
GLint x, GLint y, GLsizei width, GLsizei height);
extern GL_APICALL void (*GL_APIENTRY glCompressedTexImage3D)(
GLenum target, GLint level, GLenum internalformat, GLsizei width,
GLsizei height, GLsizei depth, GLint border, GLsizei imageSize,
const GLvoid* data);
extern GL_APICALL void (*GL_APIENTRY glCompressedTexSubImage3D)(
GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
GLsizei width, GLsizei height, GLsizei depth, GLenum format,
GLsizei imageSize, const GLvoid* data);
extern GL_APICALL void (*GL_APIENTRY glGenQueries)(GLsizei n, GLuint* ids);
extern GL_APICALL void (*GL_APIENTRY glDeleteQueries)(GLsizei n,
const GLuint* ids);
extern GL_APICALL GLboolean (*GL_APIENTRY glIsQuery)(GLuint id);
extern GL_APICALL void (*GL_APIENTRY glBeginQuery)(GLenum target, GLuint id);
extern GL_APICALL void (*GL_APIENTRY glEndQuery)(GLenum target);
extern GL_APICALL void (*GL_APIENTRY glGetQueryiv)(GLenum target, GLenum pname,
GLint* params);
extern GL_APICALL void (*GL_APIENTRY glGetQueryObjectuiv)(GLuint id,
GLenum pname,
GLuint* params);
extern GL_APICALL GLboolean (*GL_APIENTRY glUnmapBuffer)(GLenum target);
extern GL_APICALL void (*GL_APIENTRY glGetBufferPointerv)(GLenum target,
GLenum pname,
GLvoid** params);
extern GL_APICALL void (*GL_APIENTRY glDrawBuffers)(GLsizei n,
const GLenum* bufs);
extern GL_APICALL void (*GL_APIENTRY glUniformMatrix2x3fv)(
GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
extern GL_APICALL void (*GL_APIENTRY glUniformMatrix3x2fv)(
GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
extern GL_APICALL void (*GL_APIENTRY glUniformMatrix2x4fv)(
GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
extern GL_APICALL void (*GL_APIENTRY glUniformMatrix4x2fv)(
GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
extern GL_APICALL void (*GL_APIENTRY glUniformMatrix3x4fv)(
GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
extern GL_APICALL void (*GL_APIENTRY glUniformMatrix4x3fv)(
GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
extern GL_APICALL void (*GL_APIENTRY glBlitFramebuffer)(
GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0,
GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
extern GL_APICALL void (*GL_APIENTRY glRenderbufferStorageMultisample)(
GLenum target, GLsizei samples, GLenum internalformat, GLsizei width,
GLsizei height);
extern GL_APICALL void (*GL_APIENTRY glFramebufferTextureLayer)(
GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
extern GL_APICALL GLvoid* (*GL_APIENTRY glMapBufferRange)(GLenum target,
GLintptr offset,
GLsizeiptr length,
GLbitfield access);
extern GL_APICALL void (*GL_APIENTRY glFlushMappedBufferRange)(
GLenum target, GLintptr offset, GLsizeiptr length);
extern GL_APICALL void (*GL_APIENTRY glBindVertexArray)(GLuint array);
extern GL_APICALL void (*GL_APIENTRY
glDeleteVertexArrays)(GLsizei n,
const GLuint* arrays);
extern GL_APICALL void (*GL_APIENTRY glGenVertexArrays)(GLsizei n,
GLuint* arrays);
extern GL_APICALL GLboolean (*GL_APIENTRY glIsVertexArray)(GLuint array);
extern GL_APICALL void (*GL_APIENTRY glGetIntegeri_v)(GLenum target,
GLuint index,
GLint* data);
extern GL_APICALL void (*GL_APIENTRY
glBeginTransformFeedback)(GLenum primitiveMode);
extern GL_APICALL void (*GL_APIENTRY glEndTransformFeedback)(void);
extern GL_APICALL void (*GL_APIENTRY
glBindBufferRange)(GLenum target, GLuint index,
GLuint buffer, GLintptr offset,
GLsizeiptr size);
extern GL_APICALL void (*GL_APIENTRY glBindBufferBase)(GLenum target,
GLuint index,
GLuint buffer);
extern GL_APICALL void (*GL_APIENTRY glTransformFeedbackVaryings)(
GLuint program, GLsizei count, const GLchar* const* varyings,
GLenum bufferMode);
extern GL_APICALL void (*GL_APIENTRY glGetTransformFeedbackVarying)(
GLuint program, GLuint index, GLsizei bufSize, GLsizei* length,
GLsizei* size, GLenum* type, GLchar* name);
extern GL_APICALL void (*GL_APIENTRY
glVertexAttribIPointer)(GLuint index, GLint size,
GLenum type, GLsizei stride,
const GLvoid* pointer);
extern GL_APICALL void (*GL_APIENTRY glGetVertexAttribIiv)(GLuint index,
GLenum pname,
GLint* params);
extern GL_APICALL void (*GL_APIENTRY glGetVertexAttribIuiv)(GLuint index,
GLenum pname,
GLuint* params);
extern GL_APICALL void (*GL_APIENTRY glVertexAttribI4i)(GLuint index, GLint x,
GLint y, GLint z,
GLint w);
extern GL_APICALL void (*GL_APIENTRY glVertexAttribI4ui)(GLuint index, GLuint x,
GLuint y, GLuint z,
GLuint w);
extern GL_APICALL void (*GL_APIENTRY glVertexAttribI4iv)(GLuint index,
const GLint* v);
extern GL_APICALL void (*GL_APIENTRY glVertexAttribI4uiv)(GLuint index,
const GLuint* v);
extern GL_APICALL void (*GL_APIENTRY glGetUniformuiv)(GLuint program,
GLint location,
GLuint* params);
extern GL_APICALL GLint (*GL_APIENTRY
glGetFragDataLocation)(GLuint program,
const GLchar* name);
extern GL_APICALL void (*GL_APIENTRY glUniform1ui)(GLint location, GLuint v0);
extern GL_APICALL void (*GL_APIENTRY glUniform2ui)(GLint location, GLuint v0,
GLuint v1);
extern GL_APICALL void (*GL_APIENTRY glUniform3ui)(GLint location, GLuint v0,
GLuint v1, GLuint v2);
extern GL_APICALL void (*GL_APIENTRY glUniform4ui)(GLint location, GLuint v0,
GLuint v1, GLuint v2,
GLuint v3);
extern GL_APICALL void (*GL_APIENTRY glUniform1uiv)(GLint location,
GLsizei count,
const GLuint* value);
extern GL_APICALL void (*GL_APIENTRY glUniform2uiv)(GLint location,
GLsizei count,
const GLuint* value);
extern GL_APICALL void (*GL_APIENTRY glUniform3uiv)(GLint location,
GLsizei count,
const GLuint* value);
extern GL_APICALL void (*GL_APIENTRY glUniform4uiv)(GLint location,
GLsizei count,
const GLuint* value);
extern GL_APICALL void (*GL_APIENTRY glClearBufferiv)(GLenum buffer,
GLint drawbuffer,
const GLint* value);
extern GL_APICALL void (*GL_APIENTRY glClearBufferuiv)(GLenum buffer,
GLint drawbuffer,
const GLuint* value);
extern GL_APICALL void (*GL_APIENTRY glClearBufferfv)(GLenum buffer,
GLint drawbuffer,
const GLfloat* value);
extern GL_APICALL void (*GL_APIENTRY
glClearBufferfi)(GLenum buffer, GLint drawbuffer,
GLfloat depth, GLint stencil);
extern GL_APICALL const GLubyte* (*GL_APIENTRY glGetStringi)(GLenum name,
GLuint index);
extern GL_APICALL void (*GL_APIENTRY glCopyBufferSubData)(GLenum readTarget,
GLenum writeTarget,
GLintptr readOffset,
GLintptr writeOffset,
GLsizeiptr size);
extern GL_APICALL void (*GL_APIENTRY glGetUniformIndices)(
GLuint program, GLsizei uniformCount, const GLchar* const* uniformNames,
GLuint* uniformIndices);
extern GL_APICALL void (*GL_APIENTRY glGetActiveUniformsiv)(
GLuint program, GLsizei uniformCount, const GLuint* uniformIndices,
GLenum pname, GLint* params);
extern GL_APICALL GLuint (*GL_APIENTRY glGetUniformBlockIndex)(
GLuint program, const GLchar* uniformBlockName);
extern GL_APICALL void (*GL_APIENTRY glGetActiveUniformBlockiv)(
GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint* params);
extern GL_APICALL void (*GL_APIENTRY glGetActiveUniformBlockName)(
GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei* length,
GLchar* uniformBlockName);
extern GL_APICALL void (*GL_APIENTRY glUniformBlockBinding)(
GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding);
extern GL_APICALL void (*GL_APIENTRY glDrawArraysInstanced)(
GLenum mode, GLint first, GLsizei count, GLsizei instanceCount);
extern GL_APICALL void (*GL_APIENTRY glDrawElementsInstanced)(
GLenum mode, GLsizei count, GLenum type, const GLvoid* indices,
GLsizei instanceCount);
extern GL_APICALL GLsync (*GL_APIENTRY glFenceSync)(GLenum condition,
GLbitfield flags);
extern GL_APICALL GLboolean (*GL_APIENTRY glIsSync)(GLsync sync);
extern GL_APICALL void (*GL_APIENTRY glDeleteSync)(GLsync sync);
extern GL_APICALL GLenum (*GL_APIENTRY glClientWaitSync)(GLsync sync,
GLbitfield flags,
GLuint64 timeout);
extern GL_APICALL void (*GL_APIENTRY glWaitSync)(GLsync sync, GLbitfield flags,
GLuint64 timeout);
extern GL_APICALL void (*GL_APIENTRY glGetInteger64v)(GLenum pname,
GLint64* params);
extern GL_APICALL void (*GL_APIENTRY glGetSynciv)(GLsync sync, GLenum pname,
GLsizei bufSize,
GLsizei* length,
GLint* values);
extern GL_APICALL void (*GL_APIENTRY glGetInteger64i_v)(GLenum target,
GLuint index,
GLint64* data);
extern GL_APICALL void (*GL_APIENTRY glGetBufferParameteri64v)(GLenum target,
GLenum pname,
GLint64* params);
extern GL_APICALL void (*GL_APIENTRY glGenSamplers)(GLsizei count,
GLuint* samplers);
extern GL_APICALL void (*GL_APIENTRY glDeleteSamplers)(GLsizei count,
const GLuint* samplers);
extern GL_APICALL GLboolean (*GL_APIENTRY glIsSampler)(GLuint sampler);
extern GL_APICALL void (*GL_APIENTRY glBindSampler)(GLuint unit,
GLuint sampler);
extern GL_APICALL void (*GL_APIENTRY glSamplerParameteri)(GLuint sampler,
GLenum pname,
GLint param);
extern GL_APICALL void (*GL_APIENTRY glSamplerParameteriv)(GLuint sampler,
GLenum pname,
const GLint* param);
extern GL_APICALL void (*GL_APIENTRY glSamplerParameterf)(GLuint sampler,
GLenum pname,
GLfloat param);
extern GL_APICALL void (*GL_APIENTRY
glSamplerParameterfv)(GLuint sampler, GLenum pname,
const GLfloat* param);
extern GL_APICALL void (*GL_APIENTRY glGetSamplerParameteriv)(GLuint sampler,
GLenum pname,
GLint* params);
extern GL_APICALL void (*GL_APIENTRY glGetSamplerParameterfv)(GLuint sampler,
GLenum pname,
GLfloat* params);
extern GL_APICALL void (*GL_APIENTRY glVertexAttribDivisor)(GLuint index,
GLuint divisor);
extern GL_APICALL void (*GL_APIENTRY glBindTransformFeedback)(GLenum target,
GLuint id);
extern GL_APICALL void (*GL_APIENTRY
glDeleteTransformFeedbacks)(GLsizei n,
const GLuint* ids);
extern GL_APICALL void (*GL_APIENTRY glGenTransformFeedbacks)(GLsizei n,
GLuint* ids);
extern GL_APICALL GLboolean (*GL_APIENTRY glIsTransformFeedback)(GLuint id);
extern GL_APICALL void (*GL_APIENTRY glPauseTransformFeedback)(void);
extern GL_APICALL void (*GL_APIENTRY glResumeTransformFeedback)(void);
extern GL_APICALL void (*GL_APIENTRY glGetProgramBinary)(GLuint program,
GLsizei bufSize,
GLsizei* length,
GLenum* binaryFormat,
GLvoid* binary);
extern GL_APICALL void (*GL_APIENTRY glProgramBinary)(GLuint program,
GLenum binaryFormat,
const GLvoid* binary,
GLsizei length);
extern GL_APICALL void (*GL_APIENTRY glProgramParameteri)(GLuint program,
GLenum pname,
GLint value);
extern GL_APICALL void (*GL_APIENTRY glInvalidateFramebuffer)(
GLenum target, GLsizei numAttachments, const GLenum* attachments);
extern GL_APICALL void (*GL_APIENTRY glInvalidateSubFramebuffer)(
GLenum target, GLsizei numAttachments, const GLenum* attachments, GLint x,
GLint y, GLsizei width, GLsizei height);
extern GL_APICALL void (*GL_APIENTRY
glTexStorage2D)(GLenum target, GLsizei levels,
GLenum internalformat,
GLsizei width, GLsizei height);
extern GL_APICALL void (*GL_APIENTRY glTexStorage3D)(
GLenum target, GLsizei levels, GLenum internalformat, GLsizei width,
GLsizei height, GLsizei depth);
extern GL_APICALL void (*GL_APIENTRY glGetInternalformativ)(
GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize,
GLint* params);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -1,167 +0,0 @@
/*
* Copyright 2013 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <EGL/egl.h>
#include <GLES2/gl2.h>
#include "shader.h"
#include "JNIHelper.h"
namespace ndk_helper {
#define DEBUG (1)
bool shader::CompileShader(
GLuint *shader, const GLenum type, const char *str_file_name,
const std::map<std::string, std::string> &map_parameters) {
std::vector<uint8_t> data;
if (!JNIHelper::GetInstance()->ReadFile(str_file_name, &data)) {
LOGI("Can not open a file:%s", str_file_name);
return false;
}
const char REPLACEMENT_TAG = '*';
// Fill-in parameters
std::string str(data.begin(), data.end());
std::string str_replacement_map(data.size(), ' ');
std::map<std::string, std::string>::const_iterator it =
map_parameters.begin();
std::map<std::string, std::string>::const_iterator itEnd =
map_parameters.end();
while (it != itEnd) {
size_t pos = 0;
while ((pos = str.find(it->first, pos)) != std::string::npos) {
// Check if the sub string is already touched
size_t replaced_pos = str_replacement_map.find(REPLACEMENT_TAG, pos);
if (replaced_pos == std::string::npos || replaced_pos > pos) {
str.replace(pos, it->first.length(), it->second);
str_replacement_map.replace(pos, it->first.length(), it->first.length(),
REPLACEMENT_TAG);
pos += it->second.length();
} else {
// The replacement target has been touched by other tag, skipping them
pos += it->second.length();
}
}
it++;
}
LOGI("Patched Shdader:\n%s", str.c_str());
std::vector<uint8_t> v(str.begin(), str.end());
str.clear();
return shader::CompileShader(shader, type, v);
}
bool shader::CompileShader(GLuint *shader, const GLenum type,
const GLchar *source, const int32_t iSize) {
if (source == NULL || iSize <= 0) return false;
*shader = glCreateShader(type);
glShaderSource(*shader, 1, &source, &iSize); // Not specifying 3rd parameter
// (size) could be troublesome..
glCompileShader(*shader);
#if defined(DEBUG)
GLint logLength;
glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength);
if (logLength > 0) {
GLchar *log = (GLchar *)malloc(logLength);
glGetShaderInfoLog(*shader, logLength, &logLength, log);
LOGI("Shader compile log:\n%s", log);
free(log);
}
#endif
GLint status;
glGetShaderiv(*shader, GL_COMPILE_STATUS, &status);
if (status == 0) {
glDeleteShader(*shader);
return false;
}
return true;
}
bool shader::CompileShader(GLuint *shader, const GLenum type,
std::vector<uint8_t> &data) {
if (!data.size()) return false;
const GLchar *source = (GLchar *)&data[0];
int32_t iSize = data.size();
return shader::CompileShader(shader, type, source, iSize);
}
bool shader::CompileShader(GLuint *shader, const GLenum type,
const char *strFileName) {
std::vector<uint8_t> data;
bool b = JNIHelper::GetInstance()->ReadFile(strFileName, &data);
if (!b) {
LOGI("Can not open a file:%s", strFileName);
return false;
}
return shader::CompileShader(shader, type, data);
}
bool shader::LinkProgram(const GLuint prog) {
GLint status;
glLinkProgram(prog);
#if defined(DEBUG)
GLint logLength;
glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength);
if (logLength > 0) {
GLchar *log = (GLchar *)malloc(logLength);
glGetProgramInfoLog(prog, logLength, &logLength, log);
LOGI("Program link log:\n%s", log);
free(log);
}
#endif
glGetProgramiv(prog, GL_LINK_STATUS, &status);
if (status == 0) {
LOGI("Program link failed\n");
return false;
}
return true;
}
bool shader::ValidateProgram(const GLuint prog) {
GLint logLength, status;
glValidateProgram(prog);
glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength);
if (logLength > 0) {
GLchar *log = (GLchar *)malloc(logLength);
glGetProgramInfoLog(prog, logLength, &logLength, log);
LOGI("Program validate log:\n%s", log);
free(log);
}
glGetProgramiv(prog, GL_VALIDATE_STATUS, &status);
if (status == 0) return false;
return true;
}
} // namespace ndkHelper

View File

@@ -1,362 +0,0 @@
/*
* Copy_right 2013 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* y_ou may_ not use this file ex_cept in compliance with the License.
* You may_ obtain a copy_ of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by_ applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either ex_press or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
//--------------------------------------------------------------------------------
// vecmath.cpp
//--------------------------------------------------------------------------------
#include "vecmath.h"
namespace ndk_helper {
//--------------------------------------------------------------------------------
// vec3
//--------------------------------------------------------------------------------
Vec3::Vec3(const Vec4& vec) {
x_ = vec.x_;
y_ = vec.y_;
z_ = vec.z_;
}
//--------------------------------------------------------------------------------
// vec4
//--------------------------------------------------------------------------------
Vec4 Vec4::operator*(const Mat4& rhs) const {
Vec4 out;
out.x_ = x_ * rhs.f_[0] + y_ * rhs.f_[1] + z_ * rhs.f_[2] + w_ * rhs.f_[3];
out.y_ = x_ * rhs.f_[4] + y_ * rhs.f_[5] + z_ * rhs.f_[6] + w_ * rhs.f_[7];
out.z_ = x_ * rhs.f_[8] + y_ * rhs.f_[9] + z_ * rhs.f_[10] + w_ * rhs.f_[11];
out.w_ =
x_ * rhs.f_[12] + y_ * rhs.f_[13] + z_ * rhs.f_[14] + w_ * rhs.f_[15];
return out;
}
//--------------------------------------------------------------------------------
// mat4
//--------------------------------------------------------------------------------
Mat4::Mat4() {
for (int32_t i = 0; i < 16; ++i) f_[i] = 0.f;
}
Mat4::Mat4(const float* mIn) {
for (int32_t i = 0; i < 16; ++i) f_[i] = mIn[i];
}
Mat4 Mat4::operator*(const Mat4& rhs) const {
Mat4 ret;
ret.f_[0] = f_[0] * rhs.f_[0] + f_[4] * rhs.f_[1] + f_[8] * rhs.f_[2] +
f_[12] * rhs.f_[3];
ret.f_[1] = f_[1] * rhs.f_[0] + f_[5] * rhs.f_[1] + f_[9] * rhs.f_[2] +
f_[13] * rhs.f_[3];
ret.f_[2] = f_[2] * rhs.f_[0] + f_[6] * rhs.f_[1] + f_[10] * rhs.f_[2] +
f_[14] * rhs.f_[3];
ret.f_[3] = f_[3] * rhs.f_[0] + f_[7] * rhs.f_[1] + f_[11] * rhs.f_[2] +
f_[15] * rhs.f_[3];
ret.f_[4] = f_[0] * rhs.f_[4] + f_[4] * rhs.f_[5] + f_[8] * rhs.f_[6] +
f_[12] * rhs.f_[7];
ret.f_[5] = f_[1] * rhs.f_[4] + f_[5] * rhs.f_[5] + f_[9] * rhs.f_[6] +
f_[13] * rhs.f_[7];
ret.f_[6] = f_[2] * rhs.f_[4] + f_[6] * rhs.f_[5] + f_[10] * rhs.f_[6] +
f_[14] * rhs.f_[7];
ret.f_[7] = f_[3] * rhs.f_[4] + f_[7] * rhs.f_[5] + f_[11] * rhs.f_[6] +
f_[15] * rhs.f_[7];
ret.f_[8] = f_[0] * rhs.f_[8] + f_[4] * rhs.f_[9] + f_[8] * rhs.f_[10] +
f_[12] * rhs.f_[11];
ret.f_[9] = f_[1] * rhs.f_[8] + f_[5] * rhs.f_[9] + f_[9] * rhs.f_[10] +
f_[13] * rhs.f_[11];
ret.f_[10] = f_[2] * rhs.f_[8] + f_[6] * rhs.f_[9] + f_[10] * rhs.f_[10] +
f_[14] * rhs.f_[11];
ret.f_[11] = f_[3] * rhs.f_[8] + f_[7] * rhs.f_[9] + f_[11] * rhs.f_[10] +
f_[15] * rhs.f_[11];
ret.f_[12] = f_[0] * rhs.f_[12] + f_[4] * rhs.f_[13] + f_[8] * rhs.f_[14] +
f_[12] * rhs.f_[15];
ret.f_[13] = f_[1] * rhs.f_[12] + f_[5] * rhs.f_[13] + f_[9] * rhs.f_[14] +
f_[13] * rhs.f_[15];
ret.f_[14] = f_[2] * rhs.f_[12] + f_[6] * rhs.f_[13] + f_[10] * rhs.f_[14] +
f_[14] * rhs.f_[15];
ret.f_[15] = f_[3] * rhs.f_[12] + f_[7] * rhs.f_[13] + f_[11] * rhs.f_[14] +
f_[15] * rhs.f_[15];
return ret;
}
Vec4 Mat4::operator*(const Vec4& rhs) const {
Vec4 ret;
ret.x_ = rhs.x_ * f_[0] + rhs.y_ * f_[4] + rhs.z_ * f_[8] + rhs.w_ * f_[12];
ret.y_ = rhs.x_ * f_[1] + rhs.y_ * f_[5] + rhs.z_ * f_[9] + rhs.w_ * f_[13];
ret.z_ = rhs.x_ * f_[2] + rhs.y_ * f_[6] + rhs.z_ * f_[10] + rhs.w_ * f_[14];
ret.w_ = rhs.x_ * f_[3] + rhs.y_ * f_[7] + rhs.z_ * f_[11] + rhs.w_ * f_[15];
return ret;
}
Mat4 Mat4::Inverse() {
Mat4 ret;
float det_1;
float pos = 0;
float neg = 0;
float temp;
temp = f_[0] * f_[5] * f_[10];
if (temp >= 0)
pos += temp;
else
neg += temp;
temp = f_[4] * f_[9] * f_[2];
if (temp >= 0)
pos += temp;
else
neg += temp;
temp = f_[8] * f_[1] * f_[6];
if (temp >= 0)
pos += temp;
else
neg += temp;
temp = -f_[8] * f_[5] * f_[2];
if (temp >= 0)
pos += temp;
else
neg += temp;
temp = -f_[4] * f_[1] * f_[10];
if (temp >= 0)
pos += temp;
else
neg += temp;
temp = -f_[0] * f_[9] * f_[6];
if (temp >= 0)
pos += temp;
else
neg += temp;
det_1 = pos + neg;
if (det_1 == 0.0) {
// Error
} else {
det_1 = 1.0f / det_1;
ret.f_[0] = (f_[5] * f_[10] - f_[9] * f_[6]) * det_1;
ret.f_[1] = -(f_[1] * f_[10] - f_[9] * f_[2]) * det_1;
ret.f_[2] = (f_[1] * f_[6] - f_[5] * f_[2]) * det_1;
ret.f_[4] = -(f_[4] * f_[10] - f_[8] * f_[6]) * det_1;
ret.f_[5] = (f_[0] * f_[10] - f_[8] * f_[2]) * det_1;
ret.f_[6] = -(f_[0] * f_[6] - f_[4] * f_[2]) * det_1;
ret.f_[8] = (f_[4] * f_[9] - f_[8] * f_[5]) * det_1;
ret.f_[9] = -(f_[0] * f_[9] - f_[8] * f_[1]) * det_1;
ret.f_[10] = (f_[0] * f_[5] - f_[4] * f_[1]) * det_1;
/* Calculate -C * inverse(A) */
ret.f_[12] =
-(f_[12] * ret.f_[0] + f_[13] * ret.f_[4] + f_[14] * ret.f_[8]);
ret.f_[13] =
-(f_[12] * ret.f_[1] + f_[13] * ret.f_[5] + f_[14] * ret.f_[9]);
ret.f_[14] =
-(f_[12] * ret.f_[2] + f_[13] * ret.f_[6] + f_[14] * ret.f_[10]);
ret.f_[3] = 0.0f;
ret.f_[7] = 0.0f;
ret.f_[11] = 0.0f;
ret.f_[15] = 1.0f;
}
*this = ret;
return *this;
}
//--------------------------------------------------------------------------------
// Misc
//--------------------------------------------------------------------------------
Mat4 Mat4::RotationX(const float fAngle) {
Mat4 ret;
float fCosine, fSine;
fCosine = cosf(fAngle);
fSine = sinf(fAngle);
ret.f_[0] = 1.0f;
ret.f_[4] = 0.0f;
ret.f_[8] = 0.0f;
ret.f_[12] = 0.0f;
ret.f_[1] = 0.0f;
ret.f_[5] = fCosine;
ret.f_[9] = fSine;
ret.f_[13] = 0.0f;
ret.f_[2] = 0.0f;
ret.f_[6] = -fSine;
ret.f_[10] = fCosine;
ret.f_[14] = 0.0f;
ret.f_[3] = 0.0f;
ret.f_[7] = 0.0f;
ret.f_[11] = 0.0f;
ret.f_[15] = 1.0f;
return ret;
}
Mat4 Mat4::RotationY(const float fAngle) {
Mat4 ret;
float fCosine, fSine;
fCosine = cosf(fAngle);
fSine = sinf(fAngle);
ret.f_[0] = fCosine;
ret.f_[4] = 0.0f;
ret.f_[8] = -fSine;
ret.f_[12] = 0.0f;
ret.f_[1] = 0.0f;
ret.f_[5] = 1.0f;
ret.f_[9] = 0.0f;
ret.f_[13] = 0.0f;
ret.f_[2] = fSine;
ret.f_[6] = 0.0f;
ret.f_[10] = fCosine;
ret.f_[14] = 0.0f;
ret.f_[3] = 0.0f;
ret.f_[7] = 0.0f;
ret.f_[11] = 0.0f;
ret.f_[15] = 1.0f;
return ret;
}
Mat4 Mat4::RotationZ(const float fAngle) {
Mat4 ret;
float fCosine, fSine;
fCosine = cosf(fAngle);
fSine = sinf(fAngle);
ret.f_[0] = fCosine;
ret.f_[4] = fSine;
ret.f_[8] = 0.0f;
ret.f_[12] = 0.0f;
ret.f_[1] = -fSine;
ret.f_[5] = fCosine;
ret.f_[9] = 0.0f;
ret.f_[13] = 0.0f;
ret.f_[2] = 0.0f;
ret.f_[6] = 0.0f;
ret.f_[10] = 1.0f;
ret.f_[14] = 0.0f;
ret.f_[3] = 0.0f;
ret.f_[7] = 0.0f;
ret.f_[11] = 0.0f;
ret.f_[15] = 1.0f;
return ret;
}
Mat4 Mat4::Translation(const float fX, const float fY, const float fZ) {
Mat4 ret;
ret.f_[0] = 1.0f;
ret.f_[4] = 0.0f;
ret.f_[8] = 0.0f;
ret.f_[12] = fX;
ret.f_[1] = 0.0f;
ret.f_[5] = 1.0f;
ret.f_[9] = 0.0f;
ret.f_[13] = fY;
ret.f_[2] = 0.0f;
ret.f_[6] = 0.0f;
ret.f_[10] = 1.0f;
ret.f_[14] = fZ;
ret.f_[3] = 0.0f;
ret.f_[7] = 0.0f;
ret.f_[11] = 0.0f;
ret.f_[15] = 1.0f;
return ret;
}
Mat4 Mat4::Translation(const Vec3 vec) {
Mat4 ret;
ret.f_[0] = 1.0f;
ret.f_[4] = 0.0f;
ret.f_[8] = 0.0f;
ret.f_[12] = vec.x_;
ret.f_[1] = 0.0f;
ret.f_[5] = 1.0f;
ret.f_[9] = 0.0f;
ret.f_[13] = vec.y_;
ret.f_[2] = 0.0f;
ret.f_[6] = 0.0f;
ret.f_[10] = 1.0f;
ret.f_[14] = vec.z_;
ret.f_[3] = 0.0f;
ret.f_[7] = 0.0f;
ret.f_[11] = 0.0f;
ret.f_[15] = 1.0f;
return ret;
}
Mat4 Mat4::Perspective(float width, float height, float nearPlane,
float farPlane) {
float n2 = 2.0f * nearPlane;
float rcpnmf = 1.f / (nearPlane - farPlane);
Mat4 result;
result.f_[0] = n2 / width;
result.f_[4] = 0;
result.f_[8] = 0;
result.f_[12] = 0;
result.f_[1] = 0;
result.f_[5] = n2 / height;
result.f_[9] = 0;
result.f_[13] = 0;
result.f_[2] = 0;
result.f_[6] = 0;
result.f_[10] = (farPlane + nearPlane) * rcpnmf;
result.f_[14] = farPlane * rcpnmf * n2;
result.f_[3] = 0;
result.f_[7] = 0;
result.f_[11] = -1.0;
result.f_[15] = 0;
return result;
}
Mat4 Mat4::LookAt(const Vec3& vec_eye, const Vec3& vec_at, const Vec3& vec_up) {
Vec3 vec_forward, vec_up_norm, vec_side;
Mat4 result;
vec_forward.x_ = vec_eye.x_ - vec_at.x_;
vec_forward.y_ = vec_eye.y_ - vec_at.y_;
vec_forward.z_ = vec_eye.z_ - vec_at.z_;
vec_forward.Normalize();
vec_up_norm = vec_up;
vec_up_norm.Normalize();
vec_side = vec_up_norm.Cross(vec_forward);
vec_up_norm = vec_forward.Cross(vec_side);
result.f_[0] = vec_side.x_;
result.f_[4] = vec_side.y_;
result.f_[8] = vec_side.z_;
result.f_[12] = 0;
result.f_[1] = vec_up_norm.x_;
result.f_[5] = vec_up_norm.y_;
result.f_[9] = vec_up_norm.z_;
result.f_[13] = 0;
result.f_[2] = vec_forward.x_;
result.f_[6] = vec_forward.y_;
result.f_[10] = vec_forward.z_;
result.f_[14] = 0;
result.f_[3] = 0;
result.f_[7] = 0;
result.f_[11] = 0;
result.f_[15] = 1.0;
result.PostTranslate(-vec_eye.x_, -vec_eye.y_, -vec_eye.z_);
return result;
}
} // namespace ndkHelper

View File

@@ -1,959 +0,0 @@
/*
* Copyright 2013 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef VECMATH_H_
#define VECMATH_H_
#include <math.h>
#include "JNIHelper.h"
namespace ndk_helper {
/******************************************************************
* Helper class for vector math operations
* Currently all implementations are in pure C++.
* Each class is an opaque class so caller does not have a direct access
* to each element. This is for an ease of future optimization to use vector
*operations.
*
*/
class Vec2;
class Vec3;
class Vec4;
class Mat4;
/******************************************************************
* 2 elements vector class
*
*/
class Vec2 {
private:
float x_;
float y_;
public:
friend class Vec3;
friend class Vec4;
friend class Mat4;
friend class Quaternion;
Vec2() { x_ = y_ = 0.f; }
Vec2(const float fX, const float fY) {
x_ = fX;
y_ = fY;
}
Vec2(const Vec2& vec) {
x_ = vec.x_;
y_ = vec.y_;
}
Vec2(const float* pVec) {
x_ = (*pVec++);
y_ = (*pVec++);
}
// Operators
Vec2 operator*(const Vec2& rhs) const {
Vec2 ret;
ret.x_ = x_ * rhs.x_;
ret.y_ = y_ * rhs.y_;
return ret;
}
Vec2 operator/(const Vec2& rhs) const {
Vec2 ret;
ret.x_ = x_ / rhs.x_;
ret.y_ = y_ / rhs.y_;
return ret;
}
Vec2 operator+(const Vec2& rhs) const {
Vec2 ret;
ret.x_ = x_ + rhs.x_;
ret.y_ = y_ + rhs.y_;
return ret;
}
Vec2 operator-(const Vec2& rhs) const {
Vec2 ret;
ret.x_ = x_ - rhs.x_;
ret.y_ = y_ - rhs.y_;
return ret;
}
Vec2& operator+=(const Vec2& rhs) {
x_ += rhs.x_;
y_ += rhs.y_;
return *this;
}
Vec2& operator-=(const Vec2& rhs) {
x_ -= rhs.x_;
y_ -= rhs.y_;
return *this;
}
Vec2& operator*=(const Vec2& rhs) {
x_ *= rhs.x_;
y_ *= rhs.y_;
return *this;
}
Vec2& operator/=(const Vec2& rhs) {
x_ /= rhs.x_;
y_ /= rhs.y_;
return *this;
}
// External operators
friend Vec2 operator-(const Vec2& rhs) { return Vec2(rhs) *= -1; }
friend Vec2 operator*(const float lhs, const Vec2& rhs) {
Vec2 ret;
ret.x_ = lhs * rhs.x_;
ret.y_ = lhs * rhs.y_;
return ret;
}
friend Vec2 operator/(const float lhs, const Vec2& rhs) {
Vec2 ret;
ret.x_ = lhs / rhs.x_;
ret.y_ = lhs / rhs.y_;
return ret;
}
// Operators with float
Vec2 operator*(const float& rhs) const {
Vec2 ret;
ret.x_ = x_ * rhs;
ret.y_ = y_ * rhs;
return ret;
}
Vec2& operator*=(const float& rhs) {
x_ = x_ * rhs;
y_ = y_ * rhs;
return *this;
}
Vec2 operator/(const float& rhs) const {
Vec2 ret;
ret.x_ = x_ / rhs;
ret.y_ = y_ / rhs;
return ret;
}
Vec2& operator/=(const float& rhs) {
x_ = x_ / rhs;
y_ = y_ / rhs;
return *this;
}
// Compare
bool operator==(const Vec2& rhs) const {
if (x_ != rhs.x_ || y_ != rhs.y_) return false;
return true;
}
bool operator!=(const Vec2& rhs) const {
if (x_ == rhs.x_) return false;
return true;
}
float Length() const { return sqrtf(x_ * x_ + y_ * y_); }
Vec2 Normalize() {
float len = Length();
x_ = x_ / len;
y_ = y_ / len;
return *this;
}
float Dot(const Vec2& rhs) { return x_ * rhs.x_ + y_ * rhs.y_; }
bool Validate() {
if (isnan(x_) || isnan(y_)) return false;
return true;
}
void Value(float& fX, float& fY) {
fX = x_;
fY = y_;
}
void Dump() { LOGI("Vec2 %f %f", x_, y_); }
};
/******************************************************************
* 3 elements vector class
*
*/
class Vec3 {
private:
float x_, y_, z_;
public:
friend class Vec4;
friend class Mat4;
friend class Quaternion;
Vec3() { x_ = y_ = z_ = 0.f; }
Vec3(const float fX, const float fY, const float fZ) {
x_ = fX;
y_ = fY;
z_ = fZ;
}
Vec3(const Vec3& vec) {
x_ = vec.x_;
y_ = vec.y_;
z_ = vec.z_;
}
Vec3(const float* pVec) {
x_ = (*pVec++);
y_ = (*pVec++);
z_ = *pVec;
}
Vec3(const Vec2& vec, float f) {
x_ = vec.x_;
y_ = vec.y_;
z_ = f;
}
Vec3(const Vec4& vec);
// Operators
Vec3 operator*(const Vec3& rhs) const {
Vec3 ret;
ret.x_ = x_ * rhs.x_;
ret.y_ = y_ * rhs.y_;
ret.z_ = z_ * rhs.z_;
return ret;
}
Vec3 operator/(const Vec3& rhs) const {
Vec3 ret;
ret.x_ = x_ / rhs.x_;
ret.y_ = y_ / rhs.y_;
ret.z_ = z_ / rhs.z_;
return ret;
}
Vec3 operator+(const Vec3& rhs) const {
Vec3 ret;
ret.x_ = x_ + rhs.x_;
ret.y_ = y_ + rhs.y_;
ret.z_ = z_ + rhs.z_;
return ret;
}
Vec3 operator-(const Vec3& rhs) const {
Vec3 ret;
ret.x_ = x_ - rhs.x_;
ret.y_ = y_ - rhs.y_;
ret.z_ = z_ - rhs.z_;
return ret;
}
Vec3& operator+=(const Vec3& rhs) {
x_ += rhs.x_;
y_ += rhs.y_;
z_ += rhs.z_;
return *this;
}
Vec3& operator-=(const Vec3& rhs) {
x_ -= rhs.x_;
y_ -= rhs.y_;
z_ -= rhs.z_;
return *this;
}
Vec3& operator*=(const Vec3& rhs) {
x_ *= rhs.x_;
y_ *= rhs.y_;
z_ *= rhs.z_;
return *this;
}
Vec3& operator/=(const Vec3& rhs) {
x_ /= rhs.x_;
y_ /= rhs.y_;
z_ /= rhs.z_;
return *this;
}
// External operators
friend Vec3 operator-(const Vec3& rhs) { return Vec3(rhs) *= -1; }
friend Vec3 operator*(const float lhs, const Vec3& rhs) {
Vec3 ret;
ret.x_ = lhs * rhs.x_;
ret.y_ = lhs * rhs.y_;
ret.z_ = lhs * rhs.z_;
return ret;
}
friend Vec3 operator/(const float lhs, const Vec3& rhs) {
Vec3 ret;
ret.x_ = lhs / rhs.x_;
ret.y_ = lhs / rhs.y_;
ret.z_ = lhs / rhs.z_;
return ret;
}
// Operators with float
Vec3 operator*(const float& rhs) const {
Vec3 ret;
ret.x_ = x_ * rhs;
ret.y_ = y_ * rhs;
ret.z_ = z_ * rhs;
return ret;
}
Vec3& operator*=(const float& rhs) {
x_ = x_ * rhs;
y_ = y_ * rhs;
z_ = z_ * rhs;
return *this;
}
Vec3 operator/(const float& rhs) const {
Vec3 ret;
ret.x_ = x_ / rhs;
ret.y_ = y_ / rhs;
ret.z_ = z_ / rhs;
return ret;
}
Vec3& operator/=(const float& rhs) {
x_ = x_ / rhs;
y_ = y_ / rhs;
z_ = z_ / rhs;
return *this;
}
// Compare
bool operator==(const Vec3& rhs) const {
if (x_ != rhs.x_ || y_ != rhs.y_ || z_ != rhs.z_) return false;
return true;
}
bool operator!=(const Vec3& rhs) const {
if (x_ == rhs.x_) return false;
return true;
}
float Length() const { return sqrtf(x_ * x_ + y_ * y_ + z_ * z_); }
Vec3 Normalize() {
float len = Length();
x_ = x_ / len;
y_ = y_ / len;
z_ = z_ / len;
return *this;
}
float Dot(const Vec3& rhs) { return x_ * rhs.x_ + y_ * rhs.y_ + z_ * rhs.z_; }
Vec3 Cross(const Vec3& rhs) {
Vec3 ret;
ret.x_ = y_ * rhs.z_ - z_ * rhs.y_;
ret.y_ = z_ * rhs.x_ - x_ * rhs.z_;
ret.z_ = x_ * rhs.y_ - y_ * rhs.x_;
return ret;
}
bool Validate() {
if (isnan(x_) || isnan(y_) || isnan(z_)) return false;
return true;
}
void Value(float& fX, float& fY, float& fZ) {
fX = x_;
fY = y_;
fZ = z_;
}
void Dump() { LOGI("Vec3 %f %f %f", x_, y_, z_); }
};
/******************************************************************
* 4 elements vector class
*
*/
class Vec4 {
private:
float x_, y_, z_, w_;
public:
friend class Vec3;
friend class Mat4;
friend class Quaternion;
Vec4() { x_ = y_ = z_ = w_ = 0.f; }
Vec4(const float fX, const float fY, const float fZ, const float fW) {
x_ = fX;
y_ = fY;
z_ = fZ;
w_ = fW;
}
Vec4(const Vec4& vec) {
x_ = vec.x_;
y_ = vec.y_;
z_ = vec.z_;
w_ = vec.w_;
}
Vec4(const Vec3& vec, const float fW) {
x_ = vec.x_;
y_ = vec.y_;
z_ = vec.z_;
w_ = fW;
}
Vec4(const float* pVec) {
x_ = (*pVec++);
y_ = (*pVec++);
z_ = *pVec;
w_ = *pVec;
}
// Operators
Vec4 operator*(const Vec4& rhs) const {
Vec4 ret;
ret.x_ = x_ * rhs.x_;
ret.y_ = y_ * rhs.y_;
ret.z_ = z_ * rhs.z_;
ret.w_ = z_ * rhs.w_;
return ret;
}
Vec4 operator/(const Vec4& rhs) const {
Vec4 ret;
ret.x_ = x_ / rhs.x_;
ret.y_ = y_ / rhs.y_;
ret.z_ = z_ / rhs.z_;
ret.w_ = z_ / rhs.w_;
return ret;
}
Vec4 operator+(const Vec4& rhs) const {
Vec4 ret;
ret.x_ = x_ + rhs.x_;
ret.y_ = y_ + rhs.y_;
ret.z_ = z_ + rhs.z_;
ret.w_ = z_ + rhs.w_;
return ret;
}
Vec4 operator-(const Vec4& rhs) const {
Vec4 ret;
ret.x_ = x_ - rhs.x_;
ret.y_ = y_ - rhs.y_;
ret.z_ = z_ - rhs.z_;
ret.w_ = z_ - rhs.w_;
return ret;
}
Vec4& operator+=(const Vec4& rhs) {
x_ += rhs.x_;
y_ += rhs.y_;
z_ += rhs.z_;
w_ += rhs.w_;
return *this;
}
Vec4& operator-=(const Vec4& rhs) {
x_ -= rhs.x_;
y_ -= rhs.y_;
z_ -= rhs.z_;
w_ -= rhs.w_;
return *this;
}
Vec4& operator*=(const Vec4& rhs) {
x_ *= rhs.x_;
y_ *= rhs.y_;
z_ *= rhs.z_;
w_ *= rhs.w_;
return *this;
}
Vec4& operator/=(const Vec4& rhs) {
x_ /= rhs.x_;
y_ /= rhs.y_;
z_ /= rhs.z_;
w_ /= rhs.w_;
return *this;
}
// External operators
friend Vec4 operator-(const Vec4& rhs) { return Vec4(rhs) *= -1; }
friend Vec4 operator*(const float lhs, const Vec4& rhs) {
Vec4 ret;
ret.x_ = lhs * rhs.x_;
ret.y_ = lhs * rhs.y_;
ret.z_ = lhs * rhs.z_;
ret.w_ = lhs * rhs.w_;
return ret;
}
friend Vec4 operator/(const float lhs, const Vec4& rhs) {
Vec4 ret;
ret.x_ = lhs / rhs.x_;
ret.y_ = lhs / rhs.y_;
ret.z_ = lhs / rhs.z_;
ret.w_ = lhs / rhs.w_;
return ret;
}
// Operators with float
Vec4 operator*(const float& rhs) const {
Vec4 ret;
ret.x_ = x_ * rhs;
ret.y_ = y_ * rhs;
ret.z_ = z_ * rhs;
ret.w_ = w_ * rhs;
return ret;
}
Vec4& operator*=(const float& rhs) {
x_ = x_ * rhs;
y_ = y_ * rhs;
z_ = z_ * rhs;
w_ = w_ * rhs;
return *this;
}
Vec4 operator/(const float& rhs) const {
Vec4 ret;
ret.x_ = x_ / rhs;
ret.y_ = y_ / rhs;
ret.z_ = z_ / rhs;
ret.w_ = w_ / rhs;
return ret;
}
Vec4& operator/=(const float& rhs) {
x_ = x_ / rhs;
y_ = y_ / rhs;
z_ = z_ / rhs;
w_ = w_ / rhs;
return *this;
}
// Compare
bool operator==(const Vec4& rhs) const {
if (x_ != rhs.x_ || y_ != rhs.y_ || z_ != rhs.z_ || w_ != rhs.w_)
return false;
return true;
}
bool operator!=(const Vec4& rhs) const {
if (x_ == rhs.x_) return false;
return true;
}
Vec4 operator*(const Mat4& rhs) const;
float Length() const { return sqrtf(x_ * x_ + y_ * y_ + z_ * z_ + w_ * w_); }
Vec4 Normalize() {
float len = Length();
x_ = x_ / len;
y_ = y_ / len;
z_ = z_ / len;
w_ = w_ / len;
return *this;
}
float Dot(const Vec3& rhs) { return x_ * rhs.x_ + y_ * rhs.y_ + z_ * rhs.z_; }
Vec3 Cross(const Vec3& rhs) {
Vec3 ret;
ret.x_ = y_ * rhs.z_ - z_ * rhs.y_;
ret.y_ = z_ * rhs.x_ - x_ * rhs.z_;
ret.z_ = x_ * rhs.y_ - y_ * rhs.x_;
return ret;
}
bool Validate() {
if (isnan(x_) || isnan(y_) || isnan(z_) || isnan(w_)) return false;
return true;
}
void Value(float& fX, float& fY, float& fZ, float& fW) {
fX = x_;
fY = y_;
fZ = z_;
fW = w_;
}
};
/******************************************************************
* 4x4 matrix
*
*/
class Mat4 {
private:
float f_[16];
public:
friend class Vec3;
friend class Vec4;
friend class Quaternion;
Mat4();
Mat4(const float*);
Mat4 operator*(const Mat4& rhs) const;
Vec4 operator*(const Vec4& rhs) const;
Mat4 operator+(const Mat4& rhs) const {
Mat4 ret;
for (int32_t i = 0; i < 16; ++i) {
ret.f_[i] = f_[i] + rhs.f_[i];
}
return ret;
}
Mat4 operator-(const Mat4& rhs) const {
Mat4 ret;
for (int32_t i = 0; i < 16; ++i) {
ret.f_[i] = f_[i] - rhs.f_[i];
}
return ret;
}
Mat4& operator+=(const Mat4& rhs) {
for (int32_t i = 0; i < 16; ++i) {
f_[i] += rhs.f_[i];
}
return *this;
}
Mat4& operator-=(const Mat4& rhs) {
for (int32_t i = 0; i < 16; ++i) {
f_[i] -= rhs.f_[i];
}
return *this;
}
Mat4& operator*=(const Mat4& rhs) {
Mat4 ret;
ret.f_[0] = f_[0] * rhs.f_[0] + f_[4] * rhs.f_[1] + f_[8] * rhs.f_[2] +
f_[12] * rhs.f_[3];
ret.f_[1] = f_[1] * rhs.f_[0] + f_[5] * rhs.f_[1] + f_[9] * rhs.f_[2] +
f_[13] * rhs.f_[3];
ret.f_[2] = f_[2] * rhs.f_[0] + f_[6] * rhs.f_[1] + f_[10] * rhs.f_[2] +
f_[14] * rhs.f_[3];
ret.f_[3] = f_[3] * rhs.f_[0] + f_[7] * rhs.f_[1] + f_[11] * rhs.f_[2] +
f_[15] * rhs.f_[3];
ret.f_[4] = f_[0] * rhs.f_[4] + f_[4] * rhs.f_[5] + f_[8] * rhs.f_[6] +
f_[12] * rhs.f_[7];
ret.f_[5] = f_[1] * rhs.f_[4] + f_[5] * rhs.f_[5] + f_[9] * rhs.f_[6] +
f_[13] * rhs.f_[7];
ret.f_[6] = f_[2] * rhs.f_[4] + f_[6] * rhs.f_[5] + f_[10] * rhs.f_[6] +
f_[14] * rhs.f_[7];
ret.f_[7] = f_[3] * rhs.f_[4] + f_[7] * rhs.f_[5] + f_[11] * rhs.f_[6] +
f_[15] * rhs.f_[7];
ret.f_[8] = f_[0] * rhs.f_[8] + f_[4] * rhs.f_[9] + f_[8] * rhs.f_[10] +
f_[12] * rhs.f_[11];
ret.f_[9] = f_[1] * rhs.f_[8] + f_[5] * rhs.f_[9] + f_[9] * rhs.f_[10] +
f_[13] * rhs.f_[11];
ret.f_[10] = f_[2] * rhs.f_[8] + f_[6] * rhs.f_[9] + f_[10] * rhs.f_[10] +
f_[14] * rhs.f_[11];
ret.f_[11] = f_[3] * rhs.f_[8] + f_[7] * rhs.f_[9] + f_[11] * rhs.f_[10] +
f_[15] * rhs.f_[11];
ret.f_[12] = f_[0] * rhs.f_[12] + f_[4] * rhs.f_[13] + f_[8] * rhs.f_[14] +
f_[12] * rhs.f_[15];
ret.f_[13] = f_[1] * rhs.f_[12] + f_[5] * rhs.f_[13] + f_[9] * rhs.f_[14] +
f_[13] * rhs.f_[15];
ret.f_[14] = f_[2] * rhs.f_[12] + f_[6] * rhs.f_[13] + f_[10] * rhs.f_[14] +
f_[14] * rhs.f_[15];
ret.f_[15] = f_[3] * rhs.f_[12] + f_[7] * rhs.f_[13] + f_[11] * rhs.f_[14] +
f_[15] * rhs.f_[15];
*this = ret;
return *this;
}
Mat4 operator*(const float rhs) {
Mat4 ret;
for (int32_t i = 0; i < 16; ++i) {
ret.f_[i] = f_[i] * rhs;
}
return ret;
}
Mat4& operator*=(const float rhs) {
for (int32_t i = 0; i < 16; ++i) {
f_[i] *= rhs;
}
return *this;
}
Mat4& operator=(const Mat4& rhs) {
for (int32_t i = 0; i < 16; ++i) {
f_[i] = rhs.f_[i];
}
return *this;
}
Mat4 Inverse();
Mat4 Transpose() {
Mat4 ret;
ret.f_[0] = f_[0];
ret.f_[1] = f_[4];
ret.f_[2] = f_[8];
ret.f_[3] = f_[12];
ret.f_[4] = f_[1];
ret.f_[5] = f_[5];
ret.f_[6] = f_[9];
ret.f_[7] = f_[13];
ret.f_[8] = f_[2];
ret.f_[9] = f_[6];
ret.f_[10] = f_[10];
ret.f_[11] = f_[14];
ret.f_[12] = f_[3];
ret.f_[13] = f_[7];
ret.f_[14] = f_[11];
ret.f_[15] = f_[15];
*this = ret;
return *this;
}
Mat4& PostTranslate(float tx, float ty, float tz) {
f_[12] += (tx * f_[0]) + (ty * f_[4]) + (tz * f_[8]);
f_[13] += (tx * f_[1]) + (ty * f_[5]) + (tz * f_[9]);
f_[14] += (tx * f_[2]) + (ty * f_[6]) + (tz * f_[10]);
f_[15] += (tx * f_[3]) + (ty * f_[7]) + (tz * f_[11]);
return *this;
}
float* Ptr() { return f_; }
//--------------------------------------------------------------------------------
// Misc
//--------------------------------------------------------------------------------
static Mat4 Perspective(float width, float height, float nearPlane,
float farPlane);
static Mat4 LookAt(const Vec3& vEye, const Vec3& vAt, const Vec3& vUp);
static Mat4 Translation(const float fX, const float fY, const float fZ);
static Mat4 Translation(const Vec3 vec);
static Mat4 RotationX(const float angle);
static Mat4 RotationY(const float angle);
static Mat4 RotationZ(const float angle);
static Mat4 Identity() {
Mat4 ret;
ret.f_[0] = 1.f;
ret.f_[1] = 0;
ret.f_[2] = 0;
ret.f_[3] = 0;
ret.f_[4] = 0;
ret.f_[5] = 1.f;
ret.f_[6] = 0;
ret.f_[7] = 0;
ret.f_[8] = 0;
ret.f_[9] = 0;
ret.f_[10] = 1.f;
ret.f_[11] = 0;
ret.f_[12] = 0;
ret.f_[13] = 0;
ret.f_[14] = 0;
ret.f_[15] = 1.f;
return ret;
}
void Dump() {
LOGI("%f %f %f %f", f_[0], f_[1], f_[2], f_[3]);
LOGI("%f %f %f %f", f_[4], f_[5], f_[6], f_[7]);
LOGI("%f %f %f %f", f_[8], f_[9], f_[10], f_[11]);
LOGI("%f %f %f %f", f_[12], f_[13], f_[14], f_[15]);
}
};
/******************************************************************
* Quaternion class
*
*/
class Quaternion {
private:
float x_, y_, z_, w_;
public:
friend class Vec3;
friend class Vec4;
friend class Mat4;
Quaternion() {
x_ = 0.f;
y_ = 0.f;
z_ = 0.f;
w_ = 1.f;
}
Quaternion(const float fX, const float fY, const float fZ, const float fW) {
x_ = fX;
y_ = fY;
z_ = fZ;
w_ = fW;
}
Quaternion(const Vec3 vec, const float fW) {
x_ = vec.x_;
y_ = vec.y_;
z_ = vec.z_;
w_ = fW;
}
Quaternion(const float* p) {
x_ = *p++;
y_ = *p++;
z_ = *p++;
w_ = *p++;
}
Quaternion operator*(const Quaternion rhs) {
Quaternion ret;
ret.x_ = x_ * rhs.w_ + y_ * rhs.z_ - z_ * rhs.y_ + w_ * rhs.x_;
ret.y_ = -x_ * rhs.z_ + y_ * rhs.w_ + z_ * rhs.x_ + w_ * rhs.y_;
ret.z_ = x_ * rhs.y_ - y_ * rhs.x_ + z_ * rhs.w_ + w_ * rhs.z_;
ret.w_ = -x_ * rhs.x_ - y_ * rhs.y_ - z_ * rhs.z_ + w_ * rhs.w_;
return ret;
}
Quaternion& operator*=(const Quaternion rhs) {
Quaternion ret;
ret.x_ = x_ * rhs.w_ + y_ * rhs.z_ - z_ * rhs.y_ + w_ * rhs.x_;
ret.y_ = -x_ * rhs.z_ + y_ * rhs.w_ + z_ * rhs.x_ + w_ * rhs.y_;
ret.z_ = x_ * rhs.y_ - y_ * rhs.x_ + z_ * rhs.w_ + w_ * rhs.z_;
ret.w_ = -x_ * rhs.x_ - y_ * rhs.y_ - z_ * rhs.z_ + w_ * rhs.w_;
*this = ret;
return *this;
}
Quaternion Conjugate() {
x_ = -x_;
y_ = -y_;
z_ = -z_;
return *this;
}
// Non destuctive version
Quaternion Conjugated() {
Quaternion ret;
ret.x_ = -x_;
ret.y_ = -y_;
ret.z_ = -z_;
ret.w_ = w_;
return ret;
}
void ToMatrix(Mat4& mat) {
float x2 = x_ * x_ * 2.0f;
float y2 = y_ * y_ * 2.0f;
float z2 = z_ * z_ * 2.0f;
float xy = x_ * y_ * 2.0f;
float yz = y_ * z_ * 2.0f;
float zx = z_ * x_ * 2.0f;
float xw = x_ * w_ * 2.0f;
float yw = y_ * w_ * 2.0f;
float zw = z_ * w_ * 2.0f;
mat.f_[0] = 1.0f - y2 - z2;
mat.f_[1] = xy + zw;
mat.f_[2] = zx - yw;
mat.f_[4] = xy - zw;
mat.f_[5] = 1.0f - z2 - x2;
mat.f_[6] = yz + xw;
mat.f_[8] = zx + yw;
mat.f_[9] = yz - xw;
mat.f_[10] = 1.0f - x2 - y2;
mat.f_[3] = mat.f_[7] = mat.f_[11] = mat.f_[12] = mat.f_[13] = mat.f_[14] =
0.0f;
mat.f_[15] = 1.0f;
}
void ToMatrixPreserveTranslate(Mat4& mat) {
float x2 = x_ * x_ * 2.0f;
float y2 = y_ * y_ * 2.0f;
float z2 = z_ * z_ * 2.0f;
float xy = x_ * y_ * 2.0f;
float yz = y_ * z_ * 2.0f;
float zx = z_ * x_ * 2.0f;
float xw = x_ * w_ * 2.0f;
float yw = y_ * w_ * 2.0f;
float zw = z_ * w_ * 2.0f;
mat.f_[0] = 1.0f - y2 - z2;
mat.f_[1] = xy + zw;
mat.f_[2] = zx - yw;
mat.f_[4] = xy - zw;
mat.f_[5] = 1.0f - z2 - x2;
mat.f_[6] = yz + xw;
mat.f_[8] = zx + yw;
mat.f_[9] = yz - xw;
mat.f_[10] = 1.0f - x2 - y2;
mat.f_[3] = mat.f_[7] = mat.f_[11] = 0.0f;
mat.f_[15] = 1.0f;
}
static Quaternion RotationAxis(const Vec3 axis, const float angle) {
Quaternion ret;
float s = sinf(angle / 2);
ret.x_ = s * axis.x_;
ret.y_ = s * axis.y_;
ret.z_ = s * axis.z_;
ret.w_ = cosf(angle / 2);
return ret;
}
void Value(float& fX, float& fY, float& fZ, float& fW) {
fX = x_;
fY = y_;
fZ = z_;
fW = w_;
}
};
} // namespace ndk_helper
#endif /* VECMATH_H_ */

View File

@@ -1,39 +0,0 @@
apply plugin: 'com.android.model.library'
def ndkDir = System.getenv("ANDROID_NDK_HOME")
def propertiesFile = project.rootProject.file('local.properties')
if (propertiesFile.exists()) {
Properties properties = new Properties()
properties.load(propertiesFile.newDataInputStream())
ndkDir = properties.getProperty('ndk.dir')
}
model {
android {
compileSdkVersion = 23
buildToolsVersion = '23.0.2'
defaultConfig.with {
minSdkVersion.apiLevel = 9
targetSdkVersion.apiLevel = 23
versionCode = 1
versionName = '0.0.1'
}
ndk {
moduleName = 'native-activity'
ldLibs.addAll(['log', 'android'])
ldFlags.add('-c')
}
sources {
main {
jni {
source {
srcDir "${ndkDir}/sources/android/native_app_glue"
}
exportedHeaders {
srcDir "${ndkDir}/sources/android/native_app_glue"
}
}
}
}
}
}

View File

@@ -1,7 +0,0 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="native_activity.android.example.com.nativeactivity">
<application>
</application>
</manifest>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 837 KiB

View File

@@ -1,2 +0,0 @@
include ':app'
include ':nativeactivity'

View File

@@ -1,33 +1,50 @@
NDK Samples [![Build Status](https://travis-ci.org/googlesamples/android-ndk.svg?branch=master)](https://travis-ci.org/googlesamples/android-ndk) [![Build status](https://ci.appveyor.com/api/projects/status/48tbtqwg4heytmnq?svg=true)](https://ci.appveyor.com/project/proppy/android-ndk)
NDK Samples [![build](https://github.com/android/ndk-samples/workflows/build/badge.svg)](https://github.com/android/ndk-samples/actions)
===========
This repository contains [Android NDK][0] samples with Android Studio [C++ integration](https://www.youtube.com/watch?v=f7ihSQ44WO0&feature=youtu.be).
These samples uses the new [Gradle Experimental Android plugin](http://tools.android.com/tech-docs/new-build-system/gradle-experimental) with C++ support.
These samples use the new [CMake Android plugin](https://developer.android.com/studio/projects/add-native-code.html) with C++ support.
Samples could also be built with other build systems:
- for ndk-build with Android Studio, refer to directory [other-builds/ndkbuild](https://github.com/googlesamples/android-ndk/tree/master/other-builds/ndkbuild)
- for gradle-experimental plugin, refer to directory other-builds/experimental. Note that gradle-experimental does not work with unified headers yet: use NDK version up to r15 and Android Studio up to version 2.3. When starting new project, please use CMake or ndk-build plugin.
Additional Android Studio samples:
- [Google Play Game Samples with Android Studio](https://github.com/playgameservices/cpp-android-basic-samples)
- [Google Android Vulkan Tutorials](https://github.com/googlesamples/android-vulkan-tutorials)
- [Android Vulkan API Basic Samples](https://github.com/googlesamples/vulkan-basic-samples)
- [Android High Performance Audio](https://github.com/googlesamples/android-audio-high-performance)
Documentation
- [Add Native Code to Your Project](https://developer.android.com/studio/projects/add-native-code.html)
- [Configure NDK for Android Studio/Gradle Plugin](https://github.com/android/ndk-samples/wiki/Configure-NDK-Path)
- [CMake for NDK](https://developer.android.com/ndk/guides/cmake.html)
Known Issues
- For Studio related issues, refer to [Android Studio known issues](http://tools.android.com/knownissues) page
- For NDK issues, refer to [ndk issues](https://github.com/android/ndk/issues)
For samples using `Android.mk` build system with `ndk-build` see the [android-mk](https://github.com/googlesamples/android-ndk/tree/android-mk) branch.
Build Steps
----------
- With Android Studio: "Open An Existing Android Studio Project" or "File" > "Open", then navigate to & select project's build.gradle file.
- On Command Line: set up ANDROID_HOME and ANDROID_NDK_HOME to your SDK and NDK path, cd to individual sample dir, and do "gradlew assembleDebug"
Support
-------
- [Google+ Community](https://plus.google.com/communities/105153134372062985968)
- [Stack Overflow](http://stackoverflow.com/questions/tagged/android)
For any issues you found in these samples, please
- submit patches with pull requests, see [CONTRIBUTING.md](CONTRIBUTING.md) for more details, or
- [create bugs](https://github.com/googlesamples/android-ndk/issues/new) here.
If you've found an error in these samples, please [file an issue](https://github.com/googlesamples/android-ndk/issues/new).
For Android NDK generic questions, please ask on [Stack Overflow](https://stackoverflow.com/questions/tagged/android), Android teams are periodically monitoring questions there.
Patches and new samples are encouraged, and may be submitted by [forking this project](https://github.com/googlesamples/android-ndk/fork) and
submitting a pull request through GitHub. Please see [CONTRIBUTING.md](CONTRIBUTING.md) for more details.
License
-------
Copyright 2015 The Android Open Source Project, Inc.
Copyright 2018 The Android Open Source Project, Inc.
Licensed to the Apache Software Foundation (ASF) under one or more contributor
license agreements. See the NOTICE file distributed with this work for
@@ -36,7 +53,7 @@ file to you under the Apache License, Version 2.0 (the "License"); you may not
use this file except in compliance with the License. You may obtain a copy of
the License at
http://www.apache.org/licenses/LICENSE-2.0
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT

11
REFERENCE.md Normal file
View File

@@ -0,0 +1,11 @@
Android Studio/Gradle DSL References
| Name |Function | Type | Options | Default |
|---------------|-----------|:-------------:|----------|---------|
| debuggable | Debugging Java code | bool | true / false ||
| ndk.debuggable| Debugging JNI code | bool | true / false ||
Notation:
&nbsp;&nbsp;&nbsp;&nbsp; dot(".") notation is same as closure ("{}") notation

View File

@@ -1,65 +0,0 @@
apply plugin: 'com.android.model.application'
// Retrieve ndk path to config cpufeatures src code into this project
// native_app_glue is configured as dependent module, so we avoid confusing
// NOTICE/repo.prop files get displayed multiple times inside IDE
def ndkDir = System.getenv("ANDROID_NDK_HOME")
def propertiesFile = project.rootProject.file('local.properties')
if (propertiesFile.exists()) {
Properties properties = new Properties()
properties.load(propertiesFile.newDataInputStream())
ndkDir = properties.getProperty('ndk.dir')
}
model {
android {
compileSdkVersion = 23
buildToolsVersion = '23.0.2'
defaultConfig {
applicationId = 'com.sample.teapot'
minSdkVersion.apiLevel = 17
targetSdkVersion.apiLevel = 22
}
ndk {
moduleName = 'TeapotNativeActivity'
// temporarily use gcc since clang does not work on windows (*)
// also clang warning about inline, so could not use -Wall, -Werror
// toolchain = "clang"
stl = 'gnustl_static'
cppFlags.addAll(['-I' + "${ndkDir}/sources/android/cpufeatures",
'-I' + file('src/main/jni/ndk_helper')])
cppFlags.addAll(['-std=c++11', '-Werror', '-Wall',
'-fno-exceptions', '-fno-rtti'])
ldLibs.addAll(['android', 'log', 'EGL', 'GLESv2','atomic'])
}
// Turn on hard float support in armeabi-v7a
abis {
create('armeabi-v7a') {
cppFlags.addAll(['-mhard-float', '-D_NDK_MATH_NO_SOFTFP=1',
'-mfloat-abi=hard'])
ldLibs.add('m_hard')
ldFlags.add('-Wl,--no-warn-mismatch')
}
}
sources {
main {
jni {
dependencies {
project ':nativeactivity' linkage 'static'
}
source {
srcDirs 'src/main/jni'
srcDirs "${ndkDir}/sources/android/cpufeatures"
}
}
}
}
buildTypes {
release {
minifyEnabled = false
proguardFiles.add(file('proguard-rules.txt'))
}
}
}
}

View File

@@ -1,205 +0,0 @@
/*
* Copyright 2013 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sample.helper;
import java.io.File;
import java.io.FileInputStream;
import javax.microedition.khronos.opengles.GL10;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.media.AudioManager;
import android.media.AudioTrack;
import android.opengl.GLUtils;
import android.util.Log;
public class NDKHelper
{
private static Context context;
public static void setContext(Context c)
{
Log.i("NDKHelper", "setContext:" + c);
context = c;
}
//
// Load Bitmap
// Java helper is useful decoding PNG, TIFF etc rather than linking libPng
// etc separately
//
private int nextPOT(int i)
{
int pot = 1;
while (pot < i)
pot <<= 1;
return pot;
}
private Bitmap scaleBitmap(Bitmap bitmapToScale, float newWidth, float newHeight)
{
if (bitmapToScale == null)
return null;
// get the original width and height
int width = bitmapToScale.getWidth();
int height = bitmapToScale.getHeight();
// create a matrix for the manipulation
Matrix matrix = new Matrix();
// resize the bit map
matrix.postScale(newWidth / width, newHeight / height);
// recreate the new Bitmap and set it back
return Bitmap.createBitmap(bitmapToScale, 0, 0, bitmapToScale.getWidth(),
bitmapToScale.getHeight(), matrix, true);
}
public boolean loadTexture(String path)
{
Bitmap bitmap = null;
try
{
String str = path;
if (!path.startsWith("/"))
{
str = "/" + path;
}
File file = new File(context.getExternalFilesDir(null), str);
if (file.canRead())
{
bitmap = BitmapFactory.decodeStream(new FileInputStream(file));
} else
{
bitmap = BitmapFactory.decodeStream(context.getResources().getAssets()
.open(path));
}
// Matrix matrix = new Matrix();
// // resize the bit map
// matrix.postScale(-1F, 1F);
//
// // recreate the new Bitmap and set it back
// bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
// bitmap.getHeight(), matrix, true);
} catch (Exception e)
{
Log.w("NDKHelper", "Coundn't load a file:" + path);
return false;
}
if (bitmap != null)
{
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
}
return true;
}
public Bitmap openBitmap(String path, boolean iScalePOT)
{
Bitmap bitmap = null;
try
{
bitmap = BitmapFactory.decodeStream(context.getResources().getAssets()
.open(path));
if (iScalePOT)
{
int originalWidth = getBitmapWidth(bitmap);
int originalHeight = getBitmapHeight(bitmap);
int width = nextPOT(originalWidth);
int height = nextPOT(originalHeight);
if (originalWidth != width || originalHeight != height)
{
// Scale it
bitmap = scaleBitmap(bitmap, width, height);
}
}
} catch (Exception e)
{
Log.w("NDKHelper", "Coundn't load a file:" + path);
}
return bitmap;
}
public int getBitmapWidth(Bitmap bmp)
{
return bmp.getWidth();
}
public int getBitmapHeight(Bitmap bmp)
{
return bmp.getHeight();
}
public void getBitmapPixels(Bitmap bmp, int[] pixels)
{
int w = bmp.getWidth();
int h = bmp.getHeight();
bmp.getPixels(pixels, 0, w, 0, 0, w, h);
}
public void closeBitmap(Bitmap bmp)
{
bmp.recycle();
}
public static String getNativeLibraryDirectory(Context appContext)
{
ApplicationInfo ai = context.getApplicationInfo();
Log.w("NDKHelper", "ai.nativeLibraryDir:" + ai.nativeLibraryDir);
if ((ai.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0
|| (ai.flags & ApplicationInfo.FLAG_SYSTEM) == 0)
{
return ai.nativeLibraryDir;
}
return "/system/lib/";
}
@TargetApi(17)
public int getNativeAudioBufferSize()
{
int SDK_INT = android.os.Build.VERSION.SDK_INT;
if (SDK_INT >= 17)
{
AudioManager am = (AudioManager) context
.getSystemService(Context.AUDIO_SERVICE);
String framesPerBuffer = am
.getProperty(AudioManager.PROPERTY_OUTPUT_FRAMES_PER_BUFFER);
return Integer.parseInt(framesPerBuffer);
} else
{
return 0;
}
}
public int getNativeAudioSampleRate()
{
return AudioTrack.getNativeOutputSampleRate(AudioManager.STREAM_SYSTEM);
}
}

View File

@@ -1,240 +0,0 @@
/*
* Copyright 2013 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
//--------------------------------------------------------------------------------
// GLContext.cpp
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
// includes
//--------------------------------------------------------------------------------
#include <unistd.h>
#include "GLContext.h"
#include "gl3stub.h"
namespace ndk_helper {
//--------------------------------------------------------------------------------
// eGLContext
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
// Ctor
//--------------------------------------------------------------------------------
GLContext::GLContext() {}
void GLContext::InitGLES() {
if (gles_initialized_) return;
//
// Initialize OpenGL ES 3 if available
//
const char* versionStr = (const char*)glGetString(GL_VERSION);
if (strstr(versionStr, "OpenGL ES 3.") && gl3stubInit()) {
es3_supported_ = true;
gl_version_ = 3.0f;
} else {
gl_version_ = 2.0f;
}
gles_initialized_ = true;
}
//--------------------------------------------------------------------------------
// Dtor
//--------------------------------------------------------------------------------
GLContext::~GLContext() { Terminate(); }
bool GLContext::Init(ANativeWindow* window) {
if (egl_context_initialized_) return true;
//
// Initialize EGL
//
window_ = window;
InitEGLSurface();
InitEGLContext();
InitGLES();
egl_context_initialized_ = true;
return true;
}
bool GLContext::InitEGLSurface() {
display_ = eglGetDisplay(EGL_DEFAULT_DISPLAY);
eglInitialize(display_, 0, 0);
/*
* Here specify the attributes of the desired configuration.
* Below, we select an EGLConfig with at least 8 bits per color
* component compatible with on-screen windows
*/
const EGLint attribs[] = {
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, // Request opengl ES2.0
EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_BLUE_SIZE, 8,
EGL_GREEN_SIZE, 8, EGL_RED_SIZE, 8,
EGL_DEPTH_SIZE, 24, EGL_NONE};
color_size_ = 8;
depth_size_ = 24;
EGLint num_configs;
eglChooseConfig(display_, attribs, &config_, 1, &num_configs);
if (!num_configs) {
// Fall back to 16bit depth buffer
const EGLint attribs[] = {
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, // Request opengl ES2.0
EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_BLUE_SIZE, 8,
EGL_GREEN_SIZE, 8, EGL_RED_SIZE, 8,
EGL_DEPTH_SIZE, 16, EGL_NONE};
eglChooseConfig(display_, attribs, &config_, 1, &num_configs);
depth_size_ = 16;
}
if (!num_configs) {
LOGW("Unable to retrieve EGL config");
return false;
}
surface_ = eglCreateWindowSurface(display_, config_, window_, NULL);
eglQuerySurface(display_, surface_, EGL_WIDTH, &screen_width_);
eglQuerySurface(display_, surface_, EGL_HEIGHT, &screen_height_);
return true;
}
bool GLContext::InitEGLContext() {
const EGLint context_attribs[] = {EGL_CONTEXT_CLIENT_VERSION,
2, // Request opengl ES2.0
EGL_NONE};
context_ = eglCreateContext(display_, config_, NULL, context_attribs);
if (eglMakeCurrent(display_, surface_, surface_, context_) == EGL_FALSE) {
LOGW("Unable to eglMakeCurrent");
return false;
}
context_valid_ = true;
return true;
}
EGLint GLContext::Swap() {
bool b = eglSwapBuffers(display_, surface_);
if (!b) {
EGLint err = eglGetError();
if (err == EGL_BAD_SURFACE) {
// Recreate surface
InitEGLSurface();
return EGL_SUCCESS; // Still consider glContext is valid
} else if (err == EGL_CONTEXT_LOST || err == EGL_BAD_CONTEXT) {
// Context has been lost!!
context_valid_ = false;
Terminate();
InitEGLContext();
}
return err;
}
return EGL_SUCCESS;
}
void GLContext::Terminate() {
if (display_ != EGL_NO_DISPLAY) {
eglMakeCurrent(display_, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
if (context_ != EGL_NO_CONTEXT) {
eglDestroyContext(display_, context_);
}
if (surface_ != EGL_NO_SURFACE) {
eglDestroySurface(display_, surface_);
}
eglTerminate(display_);
}
display_ = EGL_NO_DISPLAY;
context_ = EGL_NO_CONTEXT;
surface_ = EGL_NO_SURFACE;
context_valid_ = false;
}
EGLint GLContext::Resume(ANativeWindow* window) {
if (egl_context_initialized_ == false) {
Init(window);
return EGL_SUCCESS;
}
int32_t original_widhth = screen_width_;
int32_t original_height = screen_height_;
// Create surface
window_ = window;
surface_ = eglCreateWindowSurface(display_, config_, window_, NULL);
eglQuerySurface(display_, surface_, EGL_WIDTH, &screen_width_);
eglQuerySurface(display_, surface_, EGL_HEIGHT, &screen_height_);
if (screen_width_ != original_widhth || screen_height_ != original_height) {
// Screen resized
LOGI("Screen resized");
}
if (eglMakeCurrent(display_, surface_, surface_, context_) == EGL_TRUE)
return EGL_SUCCESS;
EGLint err = eglGetError();
LOGW("Unable to eglMakeCurrent %d", err);
if (err == EGL_CONTEXT_LOST) {
// Recreate context
LOGI("Re-creating egl context");
InitEGLContext();
} else {
// Recreate surface
Terminate();
InitEGLSurface();
InitEGLContext();
}
return err;
}
void GLContext::Suspend() {
if (surface_ != EGL_NO_SURFACE) {
eglDestroySurface(display_, surface_);
surface_ = EGL_NO_SURFACE;
}
}
bool GLContext::Invalidate() {
Terminate();
egl_context_initialized_ = false;
return true;
}
bool GLContext::CheckExtension(const char* extension) {
if (extension == NULL) return false;
std::string extensions = std::string((char*)glGetString(GL_EXTENSIONS));
std::string str = std::string(extension);
str.append(" ");
size_t pos = 0;
if (extensions.find(extension, pos) != std::string::npos) {
return true;
}
return false;
}
} // namespace ndkHelper

View File

@@ -1,111 +0,0 @@
/*
* Copyright 2013 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
//--------------------------------------------------------------------------------
// GLContext.h
//--------------------------------------------------------------------------------
#ifndef GLCONTEXT_H_
#define GLCONTEXT_H_
#include <EGL/egl.h>
#include <GLES2/gl2.h>
#include <android/log.h>
#include "JNIHelper.h"
namespace ndk_helper {
//--------------------------------------------------------------------------------
// Constants
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
// Class
//--------------------------------------------------------------------------------
/******************************************************************
* OpenGL context handler
* The class handles OpenGL and EGL context based on Android activity life cycle
* The caller needs to call corresponding methods for each activity life cycle
*events as it's done in sample codes.
*
* Also the class initializes OpenGL ES3 when the compatible driver is installed
*in the device.
* getGLVersion() returns 3.0~ when the device supports OpenGLES3.0
*
* Thread safety: OpenGL context is expecting used within dedicated single
*thread,
* thus GLContext class is not designed as a thread-safe
*/
class GLContext {
private:
// EGL configurations
ANativeWindow* window_;
EGLDisplay display_ {EGL_NO_DISPLAY};
EGLSurface surface_ {EGL_NO_SURFACE};
EGLContext context_ {EGL_NO_CONTEXT};
EGLConfig config_ {nullptr};
// Screen parameters
int32_t screen_width_ {0};
int32_t screen_height_ {0};
int32_t color_size_;
int32_t depth_size_;
// Flags
bool gles_initialized_ {false};
bool egl_context_initialized_ {false};
bool es3_supported_ {false};
float gl_version_;
bool context_valid_ {false};
void InitGLES();
void Terminate();
bool InitEGLSurface();
bool InitEGLContext();
GLContext(GLContext const&);
void operator=(GLContext const&);
GLContext();
virtual ~GLContext();
public:
static GLContext* GetInstance() {
// Singleton
static GLContext instance;
return &instance;
}
bool Init(ANativeWindow* window);
EGLint Swap();
bool Invalidate();
void Suspend();
EGLint Resume(ANativeWindow* window);
int32_t GetScreenWidth() { return screen_width_; }
int32_t GetScreenHeight() { return screen_height_; }
int32_t GetBufferColorSize() { return color_size_; }
int32_t GetBufferDepthSize() { return depth_size_; }
float GetGLVersion() { return gl_version_; }
bool CheckExtension(const char* extension);
};
} // namespace ndkHelper
#endif /* GLCONTEXT_H_ */

View File

@@ -1,365 +0,0 @@
/*
* Copyright 2013 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <EGL/egl.h>
#include <GLES2/gl2.h>
#include <fstream>
#include <iostream>
#include "JNIHelper.h"
namespace ndk_helper {
#define CLASS_NAME "android/app/NativeActivity"
//---------------------------------------------------------------------------
// JNI Helper functions
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// Singleton
//---------------------------------------------------------------------------
JNIHelper* JNIHelper::GetInstance() {
static JNIHelper helper;
return &helper;
}
//---------------------------------------------------------------------------
// Ctor
//---------------------------------------------------------------------------
JNIHelper::JNIHelper() { pthread_mutex_init(&mutex_, NULL); }
//---------------------------------------------------------------------------
// Dtor
//---------------------------------------------------------------------------
JNIHelper::~JNIHelper() {
pthread_mutex_lock(&mutex_);
JNIEnv* env;
activity_->vm->AttachCurrentThread(&env, NULL);
env->DeleteGlobalRef(jni_helper_java_ref_);
env->DeleteGlobalRef(jni_helper_java_class_);
activity_->vm->DetachCurrentThread();
pthread_mutex_destroy(&mutex_);
}
//---------------------------------------------------------------------------
// Init
//---------------------------------------------------------------------------
void JNIHelper::Init(ANativeActivity* activity, const char* helper_class_name) {
JNIHelper& helper = *GetInstance();
pthread_mutex_lock(&helper.mutex_);
helper.activity_ = activity;
JNIEnv* env;
helper.activity_->vm->AttachCurrentThread(&env, NULL);
// Retrieve app name
jclass android_content_Context = env->GetObjectClass(helper.activity_->clazz);
jmethodID midGetPackageName = env->GetMethodID(
android_content_Context, "getPackageName", "()Ljava/lang/String;");
jstring packageName = (jstring)env->CallObjectMethod(helper.activity_->clazz,
midGetPackageName);
const char* appname = env->GetStringUTFChars(packageName, NULL);
helper.app_name_ = std::string(appname);
jclass cls = helper.RetrieveClass(env, helper_class_name);
helper.jni_helper_java_class_ = (jclass)env->NewGlobalRef(cls);
jmethodID constructor =
env->GetMethodID(helper.jni_helper_java_class_, "<init>", "()V");
helper.jni_helper_java_ref_ =
env->NewObject(helper.jni_helper_java_class_, constructor);
helper.jni_helper_java_ref_ = env->NewGlobalRef(helper.jni_helper_java_ref_);
env->ReleaseStringUTFChars(packageName, appname);
helper.activity_->vm->DetachCurrentThread();
pthread_mutex_unlock(&helper.mutex_);
}
//---------------------------------------------------------------------------
// readFile
//---------------------------------------------------------------------------
bool JNIHelper::ReadFile(const char* fileName,
std::vector<uint8_t>* buffer_ref) {
if (activity_ == NULL) {
LOGI(
"JNIHelper has not been initialized.Call init() to initialize the "
"helper");
return false;
}
// First, try reading from externalFileDir;
JNIEnv* env;
pthread_mutex_lock(&mutex_);
activity_->vm->AttachCurrentThread(&env, NULL);
jstring str_path = GetExternalFilesDirJString(env);
const char* path = env->GetStringUTFChars(str_path, NULL);
std::string s(path);
if (fileName[0] != '/') {
s.append("/");
}
s.append(fileName);
std::ifstream f(s.c_str(), std::ios::binary);
env->ReleaseStringUTFChars(str_path, path);
env->DeleteLocalRef(str_path);
activity_->vm->DetachCurrentThread();
if (f) {
LOGI("reading:%s", s.c_str());
f.seekg(0, std::ifstream::end);
int32_t fileSize = f.tellg();
f.seekg(0, std::ifstream::beg);
buffer_ref->reserve(fileSize);
buffer_ref->assign(std::istreambuf_iterator<char>(f),
std::istreambuf_iterator<char>());
f.close();
pthread_mutex_unlock(&mutex_);
return true;
} else {
// Fallback to assetManager
AAssetManager* assetManager = activity_->assetManager;
AAsset* assetFile =
AAssetManager_open(assetManager, fileName, AASSET_MODE_BUFFER);
if (!assetFile) {
pthread_mutex_unlock(&mutex_);
return false;
}
uint8_t* data = (uint8_t*)AAsset_getBuffer(assetFile);
int32_t size = AAsset_getLength(assetFile);
if (data == NULL) {
AAsset_close(assetFile);
LOGI("Failed to load:%s", fileName);
pthread_mutex_unlock(&mutex_);
return false;
}
buffer_ref->reserve(size);
buffer_ref->assign(data, data + size);
AAsset_close(assetFile);
pthread_mutex_unlock(&mutex_);
return true;
}
}
std::string JNIHelper::GetExternalFilesDir() {
if (activity_ == NULL) {
LOGI(
"JNIHelper has not been initialized. Call init() to initialize the "
"helper");
return std::string("");
}
pthread_mutex_lock(&mutex_);
// First, try reading from externalFileDir;
JNIEnv* env;
activity_->vm->AttachCurrentThread(&env, NULL);
jstring strPath = GetExternalFilesDirJString(env);
const char* path = env->GetStringUTFChars(strPath, NULL);
std::string s(path);
env->ReleaseStringUTFChars(strPath, path);
env->DeleteLocalRef(strPath);
activity_->vm->DetachCurrentThread();
pthread_mutex_unlock(&mutex_);
return s;
}
uint32_t JNIHelper::LoadTexture(const char* file_name) {
if (activity_ == NULL) {
LOGI(
"JNIHelper has not been initialized. Call init() to initialize the "
"helper");
return 0;
}
JNIEnv* env;
jmethodID mid;
pthread_mutex_lock(&mutex_);
activity_->vm->AttachCurrentThread(&env, NULL);
jstring name = env->NewStringUTF(file_name);
GLuint tex;
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_LINEAR_MIPMAP_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
mid = env->GetMethodID(jni_helper_java_class_, "loadTexture",
"(Ljava/lang/String;)Z");
jboolean ret = env->CallBooleanMethod(jni_helper_java_ref_, mid, name);
if (!ret) {
glDeleteTextures(1, &tex);
tex = -1;
LOGI("Texture load failed %s", file_name);
}
// Generate mipmap
glGenerateMipmap(GL_TEXTURE_2D);
env->DeleteLocalRef(name);
activity_->vm->DetachCurrentThread();
pthread_mutex_unlock(&mutex_);
return tex;
}
std::string JNIHelper::ConvertString(const char* str, const char* encode) {
if (activity_ == NULL) {
LOGI(
"JNIHelper has not been initialized. Call init() to initialize the "
"helper");
return std::string("");
}
JNIEnv* env;
pthread_mutex_lock(&mutex_);
activity_->vm->AttachCurrentThread(&env, NULL);
int32_t iLength = strlen((const char*)str);
jbyteArray array = env->NewByteArray(iLength);
env->SetByteArrayRegion(array, 0, iLength, (const signed char*)str);
jstring strEncode = env->NewStringUTF(encode);
jclass cls = env->FindClass("java/lang/String");
jmethodID ctor = env->GetMethodID(cls, "<init>", "([BLjava/lang/String;)V");
jstring object = (jstring)env->NewObject(cls, ctor, array, strEncode);
const char* cparam = env->GetStringUTFChars(object, NULL);
std::string s = std::string(cparam);
env->ReleaseStringUTFChars(object, cparam);
env->DeleteLocalRef(strEncode);
env->DeleteLocalRef(object);
activity_->vm->DetachCurrentThread();
pthread_mutex_unlock(&mutex_);
return s;
}
//---------------------------------------------------------------------------
// Audio helpers
//---------------------------------------------------------------------------
int32_t JNIHelper::GetNativeAudioBufferSize() {
if (activity_ == NULL) {
LOGI(
"JNIHelper has not been initialized. Call init() to initialize the "
"helper");
return 0;
}
JNIEnv* env;
jmethodID mid;
pthread_mutex_lock(&mutex_);
activity_->vm->AttachCurrentThread(&env, NULL);
mid = env->GetMethodID(jni_helper_java_class_, "getNativeAudioBufferSize",
"()I");
int32_t i = env->CallIntMethod(jni_helper_java_ref_, mid);
activity_->vm->DetachCurrentThread();
pthread_mutex_unlock(&mutex_);
return i;
}
int32_t JNIHelper::GetNativeAudioSampleRate() {
if (activity_ == NULL) {
LOGI(
"JNIHelper has not been initialized. Call init() to initialize the "
"helper");
return 0;
}
JNIEnv* env;
jmethodID mid;
pthread_mutex_lock(&mutex_);
activity_->vm->AttachCurrentThread(&env, NULL);
mid = env->GetMethodID(jni_helper_java_class_, "getNativeAudioSampleRate",
"()I");
int32_t i = env->CallIntMethod(jni_helper_java_ref_, mid);
activity_->vm->DetachCurrentThread();
pthread_mutex_unlock(&mutex_);
return i;
}
//---------------------------------------------------------------------------
// Misc implementations
//---------------------------------------------------------------------------
jclass JNIHelper::RetrieveClass(JNIEnv* jni, const char* class_name) {
jclass activity_class = jni->FindClass(CLASS_NAME);
jmethodID get_class_loader = jni->GetMethodID(
activity_class, "getClassLoader", "()Ljava/lang/ClassLoader;");
jobject cls = jni->CallObjectMethod(activity_->clazz, get_class_loader);
jclass class_loader = jni->FindClass("java/lang/ClassLoader");
jmethodID find_class = jni->GetMethodID(
class_loader, "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;");
jstring str_class_name = jni->NewStringUTF(class_name);
jclass class_retrieved =
(jclass)jni->CallObjectMethod(cls, find_class, str_class_name);
jni->DeleteLocalRef(str_class_name);
return class_retrieved;
}
jstring JNIHelper::GetExternalFilesDirJString(JNIEnv* env) {
if (activity_ == NULL) {
LOGI(
"JNIHelper has not been initialized. Call init() to initialize the "
"helper");
return NULL;
}
// Invoking getExternalFilesDir() java API
jclass cls_Env = env->FindClass(CLASS_NAME);
jmethodID mid = env->GetMethodID(cls_Env, "getExternalFilesDir",
"(Ljava/lang/String;)Ljava/io/File;");
jobject obj_File = env->CallObjectMethod(activity_->clazz, mid, NULL);
jclass cls_File = env->FindClass("java/io/File");
jmethodID mid_getPath =
env->GetMethodID(cls_File, "getPath", "()Ljava/lang/String;");
jstring obj_Path = (jstring)env->CallObjectMethod(obj_File, mid_getPath);
return obj_Path;
}
} // namespace ndkHelper

View File

@@ -1,40 +0,0 @@
/*
* Copyright 2013 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _NDKSUPPORT_H
#define _NDKSUPPORT_H
/******************************************************************
* NDK support helpers
* Utility module to provide misc functionalities that is used widely in native
*applications,
* such as gesture detection, jni bridge, openGL context etc.
*
* The purpose of this module is,
* - Provide best practices using NDK
* - Provide handy utility functions for NDK development
* - Make NDK samples more simpler and readable
*/
#include "gl3stub.h" //GLES3 stubs
#include "GLContext.h" //EGL & OpenGL manager
#include "shader.h" //Shader compiler support
#include "vecmath.h" //Vector math support, C++ implementation n current version
#include "tapCamera.h" //Tap/Pinch camera control
#include "JNIHelper.h" //JNI support
#include "gestureDetector.h" //Tap/Doubletap/Pinch detector
#include "perfMonitor.h" //FPS counter
#include "interpolator.h" //Interpolator
#endif

View File

@@ -1,296 +0,0 @@
/*
* Copyright 2013 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "gestureDetector.h"
//--------------------------------------------------------------------------------
// gestureDetector.cpp
//--------------------------------------------------------------------------------
namespace ndk_helper {
//--------------------------------------------------------------------------------
// includes
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
// GestureDetector
//--------------------------------------------------------------------------------
GestureDetector::GestureDetector() { dp_factor_ = 1.f; }
void GestureDetector::SetConfiguration(AConfiguration* config) {
dp_factor_ = 160.f / AConfiguration_getDensity(config);
}
//--------------------------------------------------------------------------------
// TapDetector
//--------------------------------------------------------------------------------
GESTURE_STATE TapDetector::Detect(const AInputEvent* motion_event) {
if (AMotionEvent_getPointerCount(motion_event) > 1) {
// Only support single touch
return false;
}
int32_t action = AMotionEvent_getAction(motion_event);
unsigned int flags = action & AMOTION_EVENT_ACTION_MASK;
switch (flags) {
case AMOTION_EVENT_ACTION_DOWN:
down_pointer_id_ = AMotionEvent_getPointerId(motion_event, 0);
down_x_ = AMotionEvent_getX(motion_event, 0);
down_y_ = AMotionEvent_getY(motion_event, 0);
break;
case AMOTION_EVENT_ACTION_UP: {
int64_t eventTime = AMotionEvent_getEventTime(motion_event);
int64_t downTime = AMotionEvent_getDownTime(motion_event);
if (eventTime - downTime <= TAP_TIMEOUT) {
if (down_pointer_id_ == AMotionEvent_getPointerId(motion_event, 0)) {
float x = AMotionEvent_getX(motion_event, 0) - down_x_;
float y = AMotionEvent_getY(motion_event, 0) - down_y_;
if (x * x + y * y < TOUCH_SLOP * TOUCH_SLOP * dp_factor_) {
LOGI("TapDetector: Tap detected");
return GESTURE_STATE_ACTION;
}
}
}
break;
}
}
return GESTURE_STATE_NONE;
}
//--------------------------------------------------------------------------------
// DoubletapDetector
//--------------------------------------------------------------------------------
GESTURE_STATE DoubletapDetector::Detect(const AInputEvent* motion_event) {
if (AMotionEvent_getPointerCount(motion_event) > 1) {
// Only support single double tap
return false;
}
bool tap_detected = tap_detector_.Detect(motion_event);
int32_t action = AMotionEvent_getAction(motion_event);
unsigned int flags = action & AMOTION_EVENT_ACTION_MASK;
switch (flags) {
case AMOTION_EVENT_ACTION_DOWN: {
int64_t eventTime = AMotionEvent_getEventTime(motion_event);
if (eventTime - last_tap_time_ <= DOUBLE_TAP_TIMEOUT) {
float x = AMotionEvent_getX(motion_event, 0) - last_tap_x_;
float y = AMotionEvent_getY(motion_event, 0) - last_tap_y_;
if (x * x + y * y < DOUBLE_TAP_SLOP * DOUBLE_TAP_SLOP * dp_factor_) {
LOGI("DoubletapDetector: Doubletap detected");
return GESTURE_STATE_ACTION;
}
}
break;
}
case AMOTION_EVENT_ACTION_UP:
if (tap_detected) {
last_tap_time_ = AMotionEvent_getEventTime(motion_event);
last_tap_x_ = AMotionEvent_getX(motion_event, 0);
last_tap_y_ = AMotionEvent_getY(motion_event, 0);
}
break;
}
return GESTURE_STATE_NONE;
}
void DoubletapDetector::SetConfiguration(AConfiguration* config) {
dp_factor_ = 160.f / AConfiguration_getDensity(config);
tap_detector_.SetConfiguration(config);
}
//--------------------------------------------------------------------------------
// PinchDetector
//--------------------------------------------------------------------------------
int32_t PinchDetector::FindIndex(const AInputEvent* event, int32_t id) {
int32_t count = AMotionEvent_getPointerCount(event);
for (auto i = 0; i < count; ++i) {
if (id == AMotionEvent_getPointerId(event, i)) return i;
}
return -1;
}
GESTURE_STATE PinchDetector::Detect(const AInputEvent* event) {
GESTURE_STATE ret = GESTURE_STATE_NONE;
int32_t action = AMotionEvent_getAction(event);
uint32_t flags = action & AMOTION_EVENT_ACTION_MASK;
event_ = event;
int32_t count = AMotionEvent_getPointerCount(event);
switch (flags) {
case AMOTION_EVENT_ACTION_DOWN:
vec_pointers_.push_back(AMotionEvent_getPointerId(event, 0));
break;
case AMOTION_EVENT_ACTION_POINTER_DOWN: {
int32_t iIndex = (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >>
AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
vec_pointers_.push_back(AMotionEvent_getPointerId(event, iIndex));
if (count == 2) {
// Start new pinch
ret = GESTURE_STATE_START;
}
} break;
case AMOTION_EVENT_ACTION_UP:
vec_pointers_.pop_back();
break;
case AMOTION_EVENT_ACTION_POINTER_UP: {
int32_t index = (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >>
AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
int32_t released_pointer_id = AMotionEvent_getPointerId(event, index);
std::vector<int32_t>::iterator it = vec_pointers_.begin();
std::vector<int32_t>::iterator it_end = vec_pointers_.end();
int32_t i = 0;
for (; it != it_end; ++it, ++i) {
if (*it == released_pointer_id) {
vec_pointers_.erase(it);
break;
}
}
if (i <= 1) {
// Reset pinch or drag
if (count != 2) {
// Start new pinch
ret = GESTURE_STATE_START | GESTURE_STATE_END;
}
}
} break;
case AMOTION_EVENT_ACTION_MOVE:
switch (count) {
case 1:
break;
default:
// Multi touch
ret = GESTURE_STATE_MOVE;
break;
}
break;
case AMOTION_EVENT_ACTION_CANCEL:
break;
}
return ret;
}
bool PinchDetector::GetPointers(Vec2& v1, Vec2& v2) {
if (vec_pointers_.size() < 2) return false;
int32_t index = FindIndex(event_, vec_pointers_[0]);
if (index == -1) return false;
float x = AMotionEvent_getX(event_, index);
float y = AMotionEvent_getY(event_, index);
index = FindIndex(event_, vec_pointers_[1]);
if (index == -1) return false;
float x2 = AMotionEvent_getX(event_, index);
float y2 = AMotionEvent_getY(event_, index);
v1 = Vec2(x, y);
v2 = Vec2(x2, y2);
return true;
}
//--------------------------------------------------------------------------------
// DragDetector
//--------------------------------------------------------------------------------
int32_t DragDetector::FindIndex(const AInputEvent* event, int32_t id) {
int32_t count = AMotionEvent_getPointerCount(event);
for (auto i = 0; i < count; ++i) {
if (id == AMotionEvent_getPointerId(event, i)) return i;
}
return -1;
}
GESTURE_STATE DragDetector::Detect(const AInputEvent* event) {
GESTURE_STATE ret = GESTURE_STATE_NONE;
int32_t action = AMotionEvent_getAction(event);
int32_t index = (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >>
AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
uint32_t flags = action & AMOTION_EVENT_ACTION_MASK;
event_ = event;
int32_t count = AMotionEvent_getPointerCount(event);
switch (flags) {
case AMOTION_EVENT_ACTION_DOWN:
vec_pointers_.push_back(AMotionEvent_getPointerId(event, 0));
ret = GESTURE_STATE_START;
break;
case AMOTION_EVENT_ACTION_POINTER_DOWN:
vec_pointers_.push_back(AMotionEvent_getPointerId(event, index));
break;
case AMOTION_EVENT_ACTION_UP:
vec_pointers_.pop_back();
ret = GESTURE_STATE_END;
break;
case AMOTION_EVENT_ACTION_POINTER_UP: {
int32_t released_pointer_id = AMotionEvent_getPointerId(event, index);
std::vector<int32_t>::iterator it = vec_pointers_.begin();
std::vector<int32_t>::iterator it_end = vec_pointers_.end();
int32_t i = 0;
for (; it != it_end; ++it, ++i) {
if (*it == released_pointer_id) {
vec_pointers_.erase(it);
break;
}
}
if (i <= 1) {
// Reset pinch or drag
if (count == 2) {
ret = GESTURE_STATE_START;
}
}
break;
}
case AMOTION_EVENT_ACTION_MOVE:
switch (count) {
case 1:
// Drag
ret = GESTURE_STATE_MOVE;
break;
default:
break;
}
break;
case AMOTION_EVENT_ACTION_CANCEL:
break;
}
return ret;
}
bool DragDetector::GetPointer(Vec2& v) {
if (vec_pointers_.size() < 1) return false;
int32_t iIndex = FindIndex(event_, vec_pointers_[0]);
if (iIndex == -1) return false;
float x = AMotionEvent_getX(event_, iIndex);
float y = AMotionEvent_getY(event_, iIndex);
v = Vec2(x, y);
return true;
}
} // namespace ndkHelper

View File

@@ -1,144 +0,0 @@
/*
* Copyright 2013 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
//--------------------------------------------------------------------------------
// gestureDetector.h
//--------------------------------------------------------------------------------
#ifndef GESTUREDETECTOR_H_
#define GESTUREDETECTOR_H_
#include <vector>
#include <android/sensor.h>
#include <android/log.h>
#include <android_native_app_glue.h>
#include <android/native_window_jni.h>
#include "JNIHelper.h"
#include "vecmath.h"
namespace ndk_helper {
//--------------------------------------------------------------------------------
// Constants
//--------------------------------------------------------------------------------
const int32_t DOUBLE_TAP_TIMEOUT = 300 * 1000000;
const int32_t TAP_TIMEOUT = 180 * 1000000;
const int32_t DOUBLE_TAP_SLOP = 100;
const int32_t TOUCH_SLOP = 8;
enum {
GESTURE_STATE_NONE = 0,
GESTURE_STATE_START = 1,
GESTURE_STATE_MOVE = 2,
GESTURE_STATE_END = 4,
GESTURE_STATE_ACTION = (GESTURE_STATE_START | GESTURE_STATE_END),
};
typedef int32_t GESTURE_STATE;
/******************************************************************
* Base class of Gesture Detectors
* GestureDetectors handles input events and detect gestures
* Note that different detectors may detect gestures with an event at
* same time. The caller needs to manage gesture priority accordingly
*
*/
class GestureDetector {
protected:
float dp_factor_;
public:
GestureDetector();
virtual ~GestureDetector() {}
virtual void SetConfiguration(AConfiguration* config);
virtual GESTURE_STATE Detect(const AInputEvent* motion_event) = 0;
};
/******************************************************************
* Tap gesture detector
* Returns GESTURE_STATE_ACTION when a tap gesture is detected
*
*/
class TapDetector : public GestureDetector {
private:
int32_t down_pointer_id_;
float down_x_;
float down_y_;
public:
TapDetector() {}
virtual ~TapDetector() {}
virtual GESTURE_STATE Detect(const AInputEvent* motion_event);
};
/******************************************************************
* Pinch gesture detector
* Returns GESTURE_STATE_ACTION when a double-tap gesture is detected
*
*/
class DoubletapDetector : public GestureDetector {
private:
TapDetector tap_detector_;
int64_t last_tap_time_;
float last_tap_x_;
float last_tap_y_;
public:
DoubletapDetector() {}
virtual ~DoubletapDetector() {}
virtual GESTURE_STATE Detect(const AInputEvent* motion_event);
virtual void SetConfiguration(AConfiguration* config);
};
/******************************************************************
* Double gesture detector
* Returns pinch gesture state when a pinch gesture is detected
* The class handles multiple touches more than 2
* When the finger 1,2,3 are tapped and then finger 1 is released,
* the detector start new pinch gesture with finger 2 & 3.
*/
class PinchDetector : public GestureDetector {
private:
int32_t FindIndex(const AInputEvent* event, int32_t id);
const AInputEvent* event_;
std::vector<int32_t> vec_pointers_;
public:
PinchDetector() {}
virtual ~PinchDetector() {}
virtual GESTURE_STATE Detect(const AInputEvent* event);
bool GetPointers(Vec2& v1, Vec2& v2);
};
/******************************************************************
* Drag gesture detector
* Returns drag gesture state when a drag-tap gesture is detected
*
*/
class DragDetector : public GestureDetector {
private:
int32_t FindIndex(const AInputEvent* event, int32_t id);
const AInputEvent* event_;
std::vector<int32_t> vec_pointers_;
public:
DragDetector() {}
virtual ~DragDetector() {}
virtual GESTURE_STATE Detect(const AInputEvent* event);
bool GetPointer(Vec2& v);
};
} // namespace ndkHelper
#endif /* GESTUREDETECTOR_H_ */

View File

@@ -1,512 +0,0 @@
/*
* Copyright 2013 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <EGL/egl.h>
#include "gl3stub.h"
GLboolean gl3stubInit()
{
#define FIND_PROC(s) s = (void*)eglGetProcAddress(#s);
FIND_PROC( glReadBuffer );
FIND_PROC( glDrawRangeElements );
FIND_PROC( glTexImage3D );
FIND_PROC( glTexSubImage3D );
FIND_PROC( glCopyTexSubImage3D );
FIND_PROC( glCompressedTexImage3D );
FIND_PROC( glCompressedTexSubImage3D );
FIND_PROC( glGenQueries );
FIND_PROC( glDeleteQueries );
FIND_PROC( glIsQuery );
FIND_PROC( glBeginQuery );
FIND_PROC( glEndQuery );
FIND_PROC( glGetQueryiv );
FIND_PROC( glGetQueryObjectuiv );
FIND_PROC( glUnmapBuffer );
FIND_PROC( glGetBufferPointerv );
FIND_PROC( glDrawBuffers );
FIND_PROC( glUniformMatrix2x3fv );
FIND_PROC( glUniformMatrix3x2fv );
FIND_PROC( glUniformMatrix2x4fv );
FIND_PROC( glUniformMatrix4x2fv );
FIND_PROC( glUniformMatrix3x4fv );
FIND_PROC( glUniformMatrix4x3fv );
FIND_PROC( glBlitFramebuffer );
FIND_PROC( glRenderbufferStorageMultisample );
FIND_PROC( glFramebufferTextureLayer );
FIND_PROC( glMapBufferRange );
FIND_PROC( glFlushMappedBufferRange );
FIND_PROC( glBindVertexArray );
FIND_PROC( glDeleteVertexArrays );
FIND_PROC( glGenVertexArrays );
FIND_PROC( glIsVertexArray );
FIND_PROC( glGetIntegeri_v );
FIND_PROC( glBeginTransformFeedback );
FIND_PROC( glEndTransformFeedback );
FIND_PROC( glBindBufferRange );
FIND_PROC( glBindBufferBase );
FIND_PROC( glTransformFeedbackVaryings );
FIND_PROC( glGetTransformFeedbackVarying );
FIND_PROC( glVertexAttribIPointer );
FIND_PROC( glGetVertexAttribIiv );
FIND_PROC( glGetVertexAttribIuiv );
FIND_PROC( glVertexAttribI4i );
FIND_PROC( glVertexAttribI4ui );
FIND_PROC( glVertexAttribI4iv );
FIND_PROC( glVertexAttribI4uiv );
FIND_PROC( glGetUniformuiv );
FIND_PROC( glGetFragDataLocation );
FIND_PROC( glUniform1ui );
FIND_PROC( glUniform2ui );
FIND_PROC( glUniform3ui );
FIND_PROC( glUniform4ui );
FIND_PROC( glUniform1uiv );
FIND_PROC( glUniform2uiv );
FIND_PROC( glUniform3uiv );
FIND_PROC( glUniform4uiv );
FIND_PROC( glClearBufferiv );
FIND_PROC( glClearBufferuiv );
FIND_PROC( glClearBufferfv );
FIND_PROC( glClearBufferfi );
FIND_PROC( glGetStringi );
FIND_PROC( glCopyBufferSubData );
FIND_PROC( glGetUniformIndices );
FIND_PROC( glGetActiveUniformsiv );
FIND_PROC( glGetUniformBlockIndex );
FIND_PROC( glGetActiveUniformBlockiv );
FIND_PROC( glGetActiveUniformBlockName );
FIND_PROC( glUniformBlockBinding );
FIND_PROC( glDrawArraysInstanced );
FIND_PROC( glDrawElementsInstanced );
FIND_PROC( glFenceSync );
FIND_PROC( glIsSync );
FIND_PROC( glDeleteSync );
FIND_PROC( glClientWaitSync );
FIND_PROC( glWaitSync );
FIND_PROC( glGetInteger64v );
FIND_PROC( glGetSynciv );
FIND_PROC( glGetInteger64i_v );
FIND_PROC( glGetBufferParameteri64v );
FIND_PROC( glGenSamplers );
FIND_PROC( glDeleteSamplers );
FIND_PROC( glIsSampler );
FIND_PROC( glBindSampler );
FIND_PROC( glSamplerParameteri );
FIND_PROC( glSamplerParameteriv );
FIND_PROC( glSamplerParameterf );
FIND_PROC( glSamplerParameterfv );
FIND_PROC( glGetSamplerParameteriv );
FIND_PROC( glGetSamplerParameterfv );
FIND_PROC( glVertexAttribDivisor );
FIND_PROC( glBindTransformFeedback );
FIND_PROC( glDeleteTransformFeedbacks );
FIND_PROC( glGenTransformFeedbacks );
FIND_PROC( glIsTransformFeedback );
FIND_PROC( glPauseTransformFeedback );
FIND_PROC( glResumeTransformFeedback );
FIND_PROC( glGetProgramBinary );
FIND_PROC( glProgramBinary );
FIND_PROC( glProgramParameteri );
FIND_PROC( glInvalidateFramebuffer );
FIND_PROC( glInvalidateSubFramebuffer );
FIND_PROC( glTexStorage2D );
FIND_PROC( glTexStorage3D );
FIND_PROC( glGetInternalformativ );
#undef FIND_PROC
if( !glReadBuffer || !glDrawRangeElements || !glTexImage3D || !glTexSubImage3D
|| !glCopyTexSubImage3D || !glCompressedTexImage3D
|| !glCompressedTexSubImage3D || !glGenQueries || !glDeleteQueries
|| !glIsQuery || !glBeginQuery || !glEndQuery || !glGetQueryiv
|| !glGetQueryObjectuiv || !glUnmapBuffer || !glGetBufferPointerv
|| !glDrawBuffers || !glUniformMatrix2x3fv || !glUniformMatrix3x2fv
|| !glUniformMatrix2x4fv || !glUniformMatrix4x2fv || !glUniformMatrix3x4fv
|| !glUniformMatrix4x3fv || !glBlitFramebuffer
|| !glRenderbufferStorageMultisample || !glFramebufferTextureLayer
|| !glMapBufferRange || !glFlushMappedBufferRange || !glBindVertexArray
|| !glDeleteVertexArrays || !glGenVertexArrays || !glIsVertexArray
|| !glGetIntegeri_v || !glBeginTransformFeedback || !glEndTransformFeedback
|| !glBindBufferRange || !glBindBufferBase || !glTransformFeedbackVaryings
|| !glGetTransformFeedbackVarying || !glVertexAttribIPointer
|| !glGetVertexAttribIiv || !glGetVertexAttribIuiv || !glVertexAttribI4i
|| !glVertexAttribI4ui || !glVertexAttribI4iv || !glVertexAttribI4uiv
|| !glGetUniformuiv || !glGetFragDataLocation || !glUniform1ui
|| !glUniform2ui || !glUniform3ui || !glUniform4ui || !glUniform1uiv
|| !glUniform2uiv || !glUniform3uiv || !glUniform4uiv || !glClearBufferiv
|| !glClearBufferuiv || !glClearBufferfv || !glClearBufferfi || !glGetStringi
|| !glCopyBufferSubData || !glGetUniformIndices || !glGetActiveUniformsiv
|| !glGetUniformBlockIndex || !glGetActiveUniformBlockiv
|| !glGetActiveUniformBlockName || !glUniformBlockBinding
|| !glDrawArraysInstanced || !glDrawElementsInstanced || !glFenceSync
|| !glIsSync || !glDeleteSync || !glClientWaitSync || !glWaitSync
|| !glGetInteger64v || !glGetSynciv || !glGetInteger64i_v
|| !glGetBufferParameteri64v || !glGenSamplers || !glDeleteSamplers
|| !glIsSampler || !glBindSampler || !glSamplerParameteri
|| !glSamplerParameteriv || !glSamplerParameterf || !glSamplerParameterfv
|| !glGetSamplerParameteriv || !glGetSamplerParameterfv
|| !glVertexAttribDivisor || !glBindTransformFeedback
|| !glDeleteTransformFeedbacks || !glGenTransformFeedbacks
|| !glIsTransformFeedback || !glPauseTransformFeedback
|| !glResumeTransformFeedback || !glGetProgramBinary || !glProgramBinary
|| !glProgramParameteri || !glInvalidateFramebuffer
|| !glInvalidateSubFramebuffer || !glTexStorage2D || !glTexStorage3D
|| !glGetInternalformativ )
{
return GL_FALSE;
}
return GL_TRUE;
}
/* Function pointer definitions */GL_APICALL void (* GL_APIENTRY glReadBuffer)( GLenum mode );
GL_APICALL void (* GL_APIENTRY glDrawRangeElements)( GLenum mode,
GLuint start,
GLuint end,
GLsizei count,
GLenum type,
const GLvoid* indices );
GL_APICALL void (* GL_APIENTRY glTexImage3D)( GLenum target,
GLint level,
GLint internalformat,
GLsizei width,
GLsizei height,
GLsizei depth,
GLint border,
GLenum format,
GLenum type,
const GLvoid* pixels );
GL_APICALL void (* GL_APIENTRY glTexSubImage3D)( GLenum target,
GLint level,
GLint xoffset,
GLint yoffset,
GLint zoffset,
GLsizei width,
GLsizei height,
GLsizei depth,
GLenum format,
GLenum type,
const GLvoid* pixels );
GL_APICALL void (* GL_APIENTRY glCopyTexSubImage3D)( GLenum target,
GLint level,
GLint xoffset,
GLint yoffset,
GLint zoffset,
GLint x,
GLint y,
GLsizei width,
GLsizei height );
GL_APICALL void (* GL_APIENTRY glCompressedTexImage3D)( GLenum target,
GLint level,
GLenum internalformat,
GLsizei width,
GLsizei height,
GLsizei depth,
GLint border,
GLsizei imageSize,
const GLvoid* data );
GL_APICALL void (* GL_APIENTRY glCompressedTexSubImage3D)( GLenum target,
GLint level,
GLint xoffset,
GLint yoffset,
GLint zoffset,
GLsizei width,
GLsizei height,
GLsizei depth,
GLenum format,
GLsizei imageSize,
const GLvoid* data );
GL_APICALL void (* GL_APIENTRY glGenQueries)( GLsizei n, GLuint* ids );
GL_APICALL void (* GL_APIENTRY glDeleteQueries)( GLsizei n, const GLuint* ids );
GL_APICALL GLboolean (* GL_APIENTRY glIsQuery)( GLuint id );
GL_APICALL void (* GL_APIENTRY glBeginQuery)( GLenum target, GLuint id );
GL_APICALL void (* GL_APIENTRY glEndQuery)( GLenum target );
GL_APICALL void (* GL_APIENTRY glGetQueryiv)( GLenum target, GLenum pname, GLint* params );
GL_APICALL void (* GL_APIENTRY glGetQueryObjectuiv)( GLuint id,
GLenum pname,
GLuint* params );
GL_APICALL GLboolean (* GL_APIENTRY glUnmapBuffer)( GLenum target );
GL_APICALL void (* GL_APIENTRY glGetBufferPointerv)( GLenum target,
GLenum pname,
GLvoid** params );
GL_APICALL void (* GL_APIENTRY glDrawBuffers)( GLsizei n, const GLenum* bufs );
GL_APICALL void (* GL_APIENTRY glUniformMatrix2x3fv)( GLint location,
GLsizei count,
GLboolean transpose,
const GLfloat* value );
GL_APICALL void (* GL_APIENTRY glUniformMatrix3x2fv)( GLint location,
GLsizei count,
GLboolean transpose,
const GLfloat* value );
GL_APICALL void (* GL_APIENTRY glUniformMatrix2x4fv)( GLint location,
GLsizei count,
GLboolean transpose,
const GLfloat* value );
GL_APICALL void (* GL_APIENTRY glUniformMatrix4x2fv)( GLint location,
GLsizei count,
GLboolean transpose,
const GLfloat* value );
GL_APICALL void (* GL_APIENTRY glUniformMatrix3x4fv)( GLint location,
GLsizei count,
GLboolean transpose,
const GLfloat* value );
GL_APICALL void (* GL_APIENTRY glUniformMatrix4x3fv)( GLint location,
GLsizei count,
GLboolean transpose,
const GLfloat* value );
GL_APICALL void (* GL_APIENTRY glBlitFramebuffer)( GLint srcX0,
GLint srcY0,
GLint srcX1,
GLint srcY1,
GLint dstX0,
GLint dstY0,
GLint dstX1,
GLint dstY1,
GLbitfield mask,
GLenum filter );
GL_APICALL void (* GL_APIENTRY glRenderbufferStorageMultisample)( GLenum target,
GLsizei samples,
GLenum internalformat,
GLsizei width,
GLsizei height );
GL_APICALL void (* GL_APIENTRY glFramebufferTextureLayer)( GLenum target,
GLenum attachment,
GLuint texture,
GLint level,
GLint layer );
GL_APICALL GLvoid* (* GL_APIENTRY glMapBufferRange)( GLenum target,
GLintptr offset,
GLsizeiptr length,
GLbitfield access );
GL_APICALL void (* GL_APIENTRY glFlushMappedBufferRange)( GLenum target,
GLintptr offset,
GLsizeiptr length );
GL_APICALL void (* GL_APIENTRY glBindVertexArray)( GLuint array );
GL_APICALL void (* GL_APIENTRY glDeleteVertexArrays)( GLsizei n, const GLuint* arrays );
GL_APICALL void (* GL_APIENTRY glGenVertexArrays)( GLsizei n, GLuint* arrays );
GL_APICALL GLboolean (* GL_APIENTRY glIsVertexArray)( GLuint array );
GL_APICALL void (* GL_APIENTRY glGetIntegeri_v)( GLenum target,
GLuint index,
GLint* data );
GL_APICALL void (* GL_APIENTRY glBeginTransformFeedback)( GLenum primitiveMode );
GL_APICALL void (* GL_APIENTRY glEndTransformFeedback)( void );
GL_APICALL void (* GL_APIENTRY glBindBufferRange)( GLenum target,
GLuint index,
GLuint buffer,
GLintptr offset,
GLsizeiptr size );
GL_APICALL void (* GL_APIENTRY glBindBufferBase)( GLenum target,
GLuint index,
GLuint buffer );
GL_APICALL void (* GL_APIENTRY glTransformFeedbackVaryings)( GLuint program,
GLsizei count,
const GLchar* const * varyings,
GLenum bufferMode );
GL_APICALL void (* GL_APIENTRY glGetTransformFeedbackVarying)( GLuint program,
GLuint index,
GLsizei bufSize,
GLsizei* length,
GLsizei* size,
GLenum* type,
GLchar* name );
GL_APICALL void (* GL_APIENTRY glVertexAttribIPointer)( GLuint index,
GLint size,
GLenum type,
GLsizei stride,
const GLvoid* pointer );
GL_APICALL void (* GL_APIENTRY glGetVertexAttribIiv)( GLuint index,
GLenum pname,
GLint* params );
GL_APICALL void (* GL_APIENTRY glGetVertexAttribIuiv)( GLuint index,
GLenum pname,
GLuint* params );
GL_APICALL void (* GL_APIENTRY glVertexAttribI4i)( GLuint index,
GLint x,
GLint y,
GLint z,
GLint w );
GL_APICALL void (* GL_APIENTRY glVertexAttribI4ui)( GLuint index,
GLuint x,
GLuint y,
GLuint z,
GLuint w );
GL_APICALL void (* GL_APIENTRY glVertexAttribI4iv)( GLuint index, const GLint* v );
GL_APICALL void (* GL_APIENTRY glVertexAttribI4uiv)( GLuint index, const GLuint* v );
GL_APICALL void (* GL_APIENTRY glGetUniformuiv)( GLuint program,
GLint location,
GLuint* params );
GL_APICALL GLint (* GL_APIENTRY glGetFragDataLocation)( GLuint program,
const GLchar *name );
GL_APICALL void (* GL_APIENTRY glUniform1ui)( GLint location, GLuint v0 );
GL_APICALL void (* GL_APIENTRY glUniform2ui)( GLint location, GLuint v0, GLuint v1 );
GL_APICALL void (* GL_APIENTRY glUniform3ui)( GLint location,
GLuint v0,
GLuint v1,
GLuint v2 );
GL_APICALL void (* GL_APIENTRY glUniform4ui)( GLint location,
GLuint v0,
GLuint v1,
GLuint v2,
GLuint v3 );
GL_APICALL void (* GL_APIENTRY glUniform1uiv)( GLint location,
GLsizei count,
const GLuint* value );
GL_APICALL void (* GL_APIENTRY glUniform2uiv)( GLint location,
GLsizei count,
const GLuint* value );
GL_APICALL void (* GL_APIENTRY glUniform3uiv)( GLint location,
GLsizei count,
const GLuint* value );
GL_APICALL void (* GL_APIENTRY glUniform4uiv)( GLint location,
GLsizei count,
const GLuint* value );
GL_APICALL void (* GL_APIENTRY glClearBufferiv)( GLenum buffer,
GLint drawbuffer,
const GLint* value );
GL_APICALL void (* GL_APIENTRY glClearBufferuiv)( GLenum buffer,
GLint drawbuffer,
const GLuint* value );
GL_APICALL void (* GL_APIENTRY glClearBufferfv)( GLenum buffer,
GLint drawbuffer,
const GLfloat* value );
GL_APICALL void (* GL_APIENTRY glClearBufferfi)( GLenum buffer,
GLint drawbuffer,
GLfloat depth,
GLint stencil );
GL_APICALL const GLubyte* (* GL_APIENTRY glGetStringi)( GLenum name, GLuint index );
GL_APICALL void (* GL_APIENTRY glCopyBufferSubData)( GLenum readTarget,
GLenum writeTarget,
GLintptr readOffset,
GLintptr writeOffset,
GLsizeiptr size );
GL_APICALL void (* GL_APIENTRY glGetUniformIndices)( GLuint program,
GLsizei uniformCount,
const GLchar* const * uniformNames,
GLuint* uniformIndices );
GL_APICALL void (* GL_APIENTRY glGetActiveUniformsiv)( GLuint program,
GLsizei uniformCount,
const GLuint* uniformIndices,
GLenum pname,
GLint* params );
GL_APICALL GLuint (* GL_APIENTRY glGetUniformBlockIndex)( GLuint program,
const GLchar* uniformBlockName );
GL_APICALL void (* GL_APIENTRY glGetActiveUniformBlockiv)( GLuint program,
GLuint uniformBlockIndex,
GLenum pname,
GLint* params );
GL_APICALL void (* GL_APIENTRY glGetActiveUniformBlockName)( GLuint program,
GLuint uniformBlockIndex,
GLsizei bufSize,
GLsizei* length,
GLchar* uniformBlockName );
GL_APICALL void (* GL_APIENTRY glUniformBlockBinding)( GLuint program,
GLuint uniformBlockIndex,
GLuint uniformBlockBinding );
GL_APICALL void (* GL_APIENTRY glDrawArraysInstanced)( GLenum mode,
GLint first,
GLsizei count,
GLsizei instanceCount );
GL_APICALL void (* GL_APIENTRY glDrawElementsInstanced)( GLenum mode,
GLsizei count,
GLenum type,
const GLvoid* indices,
GLsizei instanceCount );
GL_APICALL GLsync (* GL_APIENTRY glFenceSync)( GLenum condition, GLbitfield flags );
GL_APICALL GLboolean (* GL_APIENTRY glIsSync)( GLsync sync );
GL_APICALL void (* GL_APIENTRY glDeleteSync)( GLsync sync );
GL_APICALL GLenum (* GL_APIENTRY glClientWaitSync)( GLsync sync,
GLbitfield flags,
GLuint64 timeout );
GL_APICALL void (* GL_APIENTRY glWaitSync)( GLsync sync,
GLbitfield flags,
GLuint64 timeout );
GL_APICALL void (* GL_APIENTRY glGetInteger64v)( GLenum pname, GLint64* params );
GL_APICALL void (* GL_APIENTRY glGetSynciv)( GLsync sync,
GLenum pname,
GLsizei bufSize,
GLsizei* length,
GLint* values );
GL_APICALL void (* GL_APIENTRY glGetInteger64i_v)( GLenum target,
GLuint index,
GLint64* data );
GL_APICALL void (* GL_APIENTRY glGetBufferParameteri64v)( GLenum target,
GLenum pname,
GLint64* params );
GL_APICALL void (* GL_APIENTRY glGenSamplers)( GLsizei count, GLuint* samplers );
GL_APICALL void (* GL_APIENTRY glDeleteSamplers)( GLsizei count, const GLuint* samplers );
GL_APICALL GLboolean (* GL_APIENTRY glIsSampler)( GLuint sampler );
GL_APICALL void (* GL_APIENTRY glBindSampler)( GLuint unit, GLuint sampler );
GL_APICALL void (* GL_APIENTRY glSamplerParameteri)( GLuint sampler,
GLenum pname,
GLint param );
GL_APICALL void (* GL_APIENTRY glSamplerParameteriv)( GLuint sampler,
GLenum pname,
const GLint* param );
GL_APICALL void (* GL_APIENTRY glSamplerParameterf)( GLuint sampler,
GLenum pname,
GLfloat param );
GL_APICALL void (* GL_APIENTRY glSamplerParameterfv)( GLuint sampler,
GLenum pname,
const GLfloat* param );
GL_APICALL void (* GL_APIENTRY glGetSamplerParameteriv)( GLuint sampler,
GLenum pname,
GLint* params );
GL_APICALL void (* GL_APIENTRY glGetSamplerParameterfv)( GLuint sampler,
GLenum pname,
GLfloat* params );
GL_APICALL void (* GL_APIENTRY glVertexAttribDivisor)( GLuint index, GLuint divisor );
GL_APICALL void (* GL_APIENTRY glBindTransformFeedback)( GLenum target, GLuint id );
GL_APICALL void (* GL_APIENTRY glDeleteTransformFeedbacks)( GLsizei n, const GLuint* ids );
GL_APICALL void (* GL_APIENTRY glGenTransformFeedbacks)( GLsizei n, GLuint* ids );
GL_APICALL GLboolean (* GL_APIENTRY glIsTransformFeedback)( GLuint id );
GL_APICALL void (* GL_APIENTRY glPauseTransformFeedback)( void );
GL_APICALL void (* GL_APIENTRY glResumeTransformFeedback)( void );
GL_APICALL void (* GL_APIENTRY glGetProgramBinary)( GLuint program,
GLsizei bufSize,
GLsizei* length,
GLenum* binaryFormat,
GLvoid* binary );
GL_APICALL void (* GL_APIENTRY glProgramBinary)( GLuint program,
GLenum binaryFormat,
const GLvoid* binary,
GLsizei length );
GL_APICALL void (* GL_APIENTRY glProgramParameteri)( GLuint program,
GLenum pname,
GLint value );
GL_APICALL void (* GL_APIENTRY glInvalidateFramebuffer)( GLenum target,
GLsizei numAttachments,
const GLenum* attachments );
GL_APICALL void (* GL_APIENTRY glInvalidateSubFramebuffer)( GLenum target,
GLsizei numAttachments,
const GLenum* attachments,
GLint x,
GLint y,
GLsizei width,
GLsizei height );
GL_APICALL void (* GL_APIENTRY glTexStorage2D)( GLenum target,
GLsizei levels,
GLenum internalformat,
GLsizei width,
GLsizei height );
GL_APICALL void (* GL_APIENTRY glTexStorage3D)( GLenum target,
GLsizei levels,
GLenum internalformat,
GLsizei width,
GLsizei height,
GLsizei depth );
GL_APICALL void (* GL_APIENTRY glGetInternalformativ)( GLenum target,
GLenum internalformat,
GLenum pname,
GLsizei bufSize,
GLint* params );

View File

@@ -1,153 +0,0 @@
/*
* Copyright 2013 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "interpolator.h"
#include <math.h>
#include "interpolator.h"
namespace ndk_helper {
//-------------------------------------------------
// Ctor
//-------------------------------------------------
Interpolator::Interpolator() { list_params_.clear(); }
//-------------------------------------------------
// Dtor
//-------------------------------------------------
Interpolator::~Interpolator() { list_params_.clear(); }
void Interpolator::Clear() { list_params_.clear(); }
Interpolator& Interpolator::Set(const float start, const float dest,
const INTERPOLATOR_TYPE type,
const double duration) {
// init the parameters for the interpolation process
start_time_ = PerfMonitor::GetCurrentTime();
dest_time_ = start_time_ + duration;
type_ = type;
start_value_ = start;
dest_value_ = dest;
return *this;
}
Interpolator& Interpolator::Add(const float dest, const INTERPOLATOR_TYPE type,
const double duration) {
InterpolatorParams param;
param.dest_value_ = dest;
param.type_ = type;
param.duration_ = duration;
list_params_.push_back(param);
return *this;
}
bool Interpolator::Update(const double current_time, float& p) {
bool bContinue;
if (current_time >= dest_time_) {
p = dest_value_;
if (list_params_.size()) {
InterpolatorParams& item = list_params_.front();
Set(dest_value_, item.dest_value_, item.type_, item.duration_);
list_params_.pop_front();
bContinue = true;
} else {
bContinue = false;
}
} else {
float t = (float)(current_time - start_time_);
float d = (float)(dest_time_ - start_time_);
float b = start_value_;
float c = dest_value_ - start_value_;
p = GetFormula(type_, t, b, d, c);
bContinue = true;
}
return bContinue;
}
float Interpolator::GetFormula(const INTERPOLATOR_TYPE type, const float t,
const float b, const float d, const float c) {
float t1;
switch (type) {
case INTERPOLATOR_TYPE_LINEAR:
// simple linear interpolation - no easing
return (c * t / d + b);
case INTERPOLATOR_TYPE_EASEINQUAD:
// quadratic (t^2) easing in - accelerating from zero velocity
t1 = t / d;
return (c * t1 * t1 + b);
case INTERPOLATOR_TYPE_EASEOUTQUAD:
// quadratic (t^2) easing out - decelerating to zero velocity
t1 = t / d;
return (-c * t1 * (t1 - 2) + b);
case INTERPOLATOR_TYPE_EASEINOUTQUAD:
// quadratic easing in/out - acceleration until halfway, then deceleration
t1 = t / d / 2;
if (t1 < 1)
return (c / 2 * t1 * t1 + b);
else {
t1 = t1 - 1;
return (-c / 2 * (t1 * (t1 - 2) - 1) + b);
}
case INTERPOLATOR_TYPE_EASEINCUBIC:
// cubic easing in - accelerating from zero velocity
t1 = t / d;
return (c * t1 * t1 * t1 + b);
case INTERPOLATOR_TYPE_EASEOUTCUBIC:
// cubic easing in - accelerating from zero velocity
t1 = t / d - 1;
return (c * (t1 * t1 * t1 + 1) + b);
case INTERPOLATOR_TYPE_EASEINOUTCUBIC:
// cubic easing in - accelerating from zero velocity
t1 = t / d / 2;
if (t1 < 1)
return (c / 2 * t1 * t1 * t1 + b);
else {
t1 -= 2;
return (c / 2 * (t1 * t1 * t1 + 2) + b);
}
case INTERPOLATOR_TYPE_EASEINQUART:
// quartic easing in - accelerating from zero velocity
t1 = t / d;
return (c * t1 * t1 * t1 * t1 + b);
case INTERPOLATOR_TYPE_EASEINEXPO:
// exponential (2^t) easing in - accelerating from zero velocity
if (t == 0)
return b;
else
return (c * powf(2, (10 * (t / d - 1))) + b);
case INTERPOLATOR_TYPE_EASEOUTEXPO:
// exponential (2^t) easing out - decelerating to zero velocity
if (t == d)
return (b + c);
else
return (c * (-powf(2, -10 * t / d) + 1) + b);
default:
return 0;
}
}
} // namespace ndkHelper

View File

@@ -1,80 +0,0 @@
/*
* Copyright 2013 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef INTERPOLATOR_H_
#define INTERPOLATOR_H_
#include <jni.h>
#include <errno.h>
#include <time.h>
#include "JNIHelper.h"
#include "perfMonitor.h"
#include <list>
namespace ndk_helper {
enum INTERPOLATOR_TYPE {
INTERPOLATOR_TYPE_LINEAR,
INTERPOLATOR_TYPE_EASEINQUAD,
INTERPOLATOR_TYPE_EASEOUTQUAD,
INTERPOLATOR_TYPE_EASEINOUTQUAD,
INTERPOLATOR_TYPE_EASEINCUBIC,
INTERPOLATOR_TYPE_EASEOUTCUBIC,
INTERPOLATOR_TYPE_EASEINOUTCUBIC,
INTERPOLATOR_TYPE_EASEINQUART,
INTERPOLATOR_TYPE_EASEINEXPO,
INTERPOLATOR_TYPE_EASEOUTEXPO,
};
struct InterpolatorParams {
float dest_value_;
INTERPOLATOR_TYPE type_;
double duration_;
};
/******************************************************************
* Interpolates values with several interpolation methods
*/
class Interpolator {
private:
double start_time_;
double dest_time_;
INTERPOLATOR_TYPE type_;
float start_value_;
float dest_value_;
std::list<InterpolatorParams> list_params_;
float GetFormula(const INTERPOLATOR_TYPE type, const float t, const float b,
const float d, const float c);
public:
Interpolator();
~Interpolator();
Interpolator& Set(const float start, const float dest,
const INTERPOLATOR_TYPE type, double duration);
Interpolator& Add(const float dest, const INTERPOLATOR_TYPE type,
const double duration);
bool Update(const double currentTime, float& p);
void Clear();
};
} // namespace ndkHelper
#endif /* INTERPOLATOR_H_ */

View File

@@ -1,56 +0,0 @@
/*
* Copyright 2013 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "perfMonitor.h"
namespace ndk_helper {
PerfMonitor::PerfMonitor() {
for (int32_t i = 0; i < NUM_SAMPLES; ++i) ticklist_[i] = 0;
}
PerfMonitor::~PerfMonitor() {}
double PerfMonitor::UpdateTick(double currentTick) {
ticksum_ -= ticklist_[tickindex_];
ticksum_ += currentTick;
ticklist_[tickindex_] = currentTick;
tickindex_ = (tickindex_ + 1) % NUM_SAMPLES;
return ((double)ticksum_ / NUM_SAMPLES);
}
bool PerfMonitor::Update(float &fFPS) {
struct timeval Time;
gettimeofday(&Time, NULL);
double time = Time.tv_sec + Time.tv_usec * 1.0 / 1000000.0;
double tick = time - last_tick_;
double d = UpdateTick(tick);
last_tick_ = time;
if (Time.tv_sec - tv_last_sec_ >= 1) {
current_FPS_ = 1.f / d;
tv_last_sec_ = Time.tv_sec;
fFPS = current_FPS_;
return true;
} else {
fFPS = current_FPS_;
return false;
}
}
} // namespace ndkHelper

View File

@@ -1,59 +0,0 @@
/*
* Copyright 2013 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef PERFMONITOR_H_
#define PERFMONITOR_H_
#include <jni.h>
#include <errno.h>
#include <time.h>
#include "JNIHelper.h"
namespace ndk_helper {
const int32_t NUM_SAMPLES = 100;
/******************************************************************
* Helper class for a performance monitoring and get current tick time
*/
class PerfMonitor {
private:
float current_FPS_;
time_t tv_last_sec_ {0};
double last_tick_{static_cast<double>(0.0)};
int32_t tickindex_ {0};
double ticksum_ {0.0};
double ticklist_[NUM_SAMPLES];
double UpdateTick(double current_tick);
public:
PerfMonitor();
virtual ~PerfMonitor();
bool Update(float &fFPS);
static double GetCurrentTime() {
struct timeval time;
gettimeofday(&time, NULL);
double ret = time.tv_sec + time.tv_usec * 1.0 / 1000000.0;
return ret;
}
};
} // namespace ndkHelper
#endif /* PERFMONITOR_H_ */

View File

@@ -1,120 +0,0 @@
/*
* Copyright 2013 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef SHADER_H_
#define SHADER_H_
#include <jni.h>
#include <vector>
#include <map>
#include <string>
#include <EGL/egl.h>
#include <GLES/gl.h>
#include <android/log.h>
#include "JNIHelper.h"
namespace ndk_helper {
namespace shader {
/******************************************************************
* Shader compiler helper
* namespace: ndkHelper::shader
*
*/
/******************************************************************
* CompileShader() with vector
*
* arguments:
* out: shader, shader variable
* in: type, shader type (i.e. GL_VERTEX_SHADER/GL_FRAGMENT_SHADER)
* in: data, source vector
* return: true if a shader compilation succeeded, false if it failed
*
*/
bool CompileShader(GLuint *shader, const GLenum type,
std::vector<uint8_t> &data);
/******************************************************************
* CompileShader() with buffer
*
* arguments:
* out: shader, shader variable
* in: type, shader type (i.e. GL_VERTEX_SHADER/GL_FRAGMENT_SHADER)
* in: source, source buffer
* in: iSize, buffer size
* return: true if a shader compilation succeeded, false if it failed
*
*/
bool CompileShader(GLuint *shader, const GLenum type, const GLchar *source,
const int32_t iSize);
/******************************************************************
* CompileShader() with filename
*
* arguments:
* out: shader, shader variable
* in: type, shader type (i.e. GL_VERTEX_SHADER/GL_FRAGMENT_SHADER)
* in: strFilename, filename
* return: true if a shader compilation succeeded, false if it failed
*
*/
bool CompileShader(GLuint *shader, const GLenum type, const char *strFileName);
/******************************************************************
* CompileShader() with std::map helps patching on a shader on the fly.
*
* arguments:
* out: shader, shader variable
* in: type, shader type (i.e. GL_VERTEX_SHADER/GL_FRAGMENT_SHADER)
* in: mapParameters
* For a example,
* map : %KEY% -> %VALUE% replaces all %KEY% entries in the given shader
*code to %VALUE"
* return: true if a shader compilation succeeded, false if it failed
*
*/
bool CompileShader(GLuint *shader, const GLenum type, const char *str_file_name,
const std::map<std::string, std::string> &map_parameters);
/******************************************************************
* LinkProgram()
*
* arguments:
* in: program, program
* return: true if a shader linkage succeeded, false if it failed
*
*/
bool LinkProgram(const GLuint prog);
/******************************************************************
* validateProgram()
*
* arguments:
* in: program, program
* return: true if a shader validation succeeded, false if it failed
*
*/
bool ValidateProgram(const GLuint prog);
} // namespace shader
} // namespace ndkHelper
#endif /* SHADER_H_ */

View File

@@ -1,271 +0,0 @@
/*
* Copyright 2013 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
//----------------------------------------------------------
// tapCamera.cpp
// Camera control with tap
//
//----------------------------------------------------------
#include <fstream>
#include "tapCamera.h"
namespace ndk_helper {
const float TRANSFORM_FACTOR = 15.f;
const float TRANSFORM_FACTORZ = 10.f;
const float MOMENTUM_FACTOR_DECREASE = 0.85f;
const float MOMENTUM_FACTOR_DECREASE_SHIFT = 0.9f;
const float MOMENTUM_FACTOR = 0.8f;
const float MOMENTUM_FACTOR_THRESHOLD = 0.001f;
//----------------------------------------------------------
// Ctor
//----------------------------------------------------------
TapCamera::TapCamera() {
// Init offset
InitParameters();
vec_flip_ = Vec2(1.f, -1.f);
flip_z_ = -1.f;
vec_pinch_transform_factor_ = Vec3(1.f, 1.f, 1.f);
vec_ball_center_ = Vec2(0, 0);
vec_ball_now_ = Vec2(0, 0);
vec_ball_down_ = Vec2(0, 0);
vec_pinch_start_ = Vec2(0, 0);
vec_pinch_start_center_ = Vec2(0, 0);
vec_flip_ = Vec2(0, 0);
}
void TapCamera::InitParameters() {
// Init parameters
vec_offset_ = Vec3();
vec_offset_now_ = Vec3();
quat_ball_rot_ = Quaternion();
quat_ball_now_ = Quaternion();
quat_ball_now_.ToMatrix(mat_rotation_);
camera_rotation_ = 0.f;
vec_drag_delta_ = Vec2();
vec_offset_delta_ = Vec3();
momentum_ = false;
}
//----------------------------------------------------------
// Dtor
//----------------------------------------------------------
TapCamera::~TapCamera() {}
void TapCamera::Update() {
if (momentum_) {
float momenttum_steps = momemtum_steps_;
// Momentum rotation
Vec2 v = vec_drag_delta_;
BeginDrag(Vec2()); // NOTE:This call reset _VDragDelta
Drag(v * vec_flip_);
// Momentum shift
vec_offset_ += vec_offset_delta_;
BallUpdate();
EndDrag();
// Decrease deltas
vec_drag_delta_ = v * MOMENTUM_FACTOR_DECREASE;
vec_offset_delta_ = vec_offset_delta_ * MOMENTUM_FACTOR_DECREASE_SHIFT;
// Count steps
momemtum_steps_ = momenttum_steps * MOMENTUM_FACTOR_DECREASE;
if (momemtum_steps_ < MOMENTUM_FACTOR_THRESHOLD) {
momentum_ = false;
}
} else {
vec_drag_delta_ *= MOMENTUM_FACTOR;
vec_offset_delta_ = vec_offset_delta_ * MOMENTUM_FACTOR;
BallUpdate();
}
Vec3 vec = vec_offset_ + vec_offset_now_;
Vec3 vec_tmp(TRANSFORM_FACTOR, -TRANSFORM_FACTOR, TRANSFORM_FACTORZ);
vec *= vec_tmp * vec_pinch_transform_factor_;
mat_transform_ = Mat4::Translation(vec);
}
Mat4& TapCamera::GetRotationMatrix() { return mat_rotation_; }
Mat4& TapCamera::GetTransformMatrix() { return mat_transform_; }
void TapCamera::Reset(const bool bAnimate) {
InitParameters();
Update();
}
//----------------------------------------------------------
// Drag control
//----------------------------------------------------------
void TapCamera::BeginDrag(const Vec2& v) {
if (dragging_) EndDrag();
if (pinching_) EndPinch();
Vec2 vec = v * vec_flip_;
vec_ball_now_ = vec;
vec_ball_down_ = vec_ball_now_;
dragging_ = true;
momentum_ = false;
vec_last_input_ = vec;
vec_drag_delta_ = Vec2();
}
void TapCamera::EndDrag() {
quat_ball_down_ = quat_ball_now_;
quat_ball_rot_ = Quaternion();
dragging_ = false;
momentum_ = true;
momemtum_steps_ = 1.0f;
}
void TapCamera::Drag(const Vec2& v) {
if (!dragging_) return;
Vec2 vec = v * vec_flip_;
vec_ball_now_ = vec;
vec_drag_delta_ = vec_drag_delta_ * MOMENTUM_FACTOR + (vec - vec_last_input_);
vec_last_input_ = vec;
}
//----------------------------------------------------------
// Pinch controll
//----------------------------------------------------------
void TapCamera::BeginPinch(const Vec2& v1, const Vec2& v2) {
if (dragging_) EndDrag();
if (pinching_) EndPinch();
BeginDrag(Vec2());
vec_pinch_start_center_ = (v1 + v2) / 2.f;
Vec2 vec = v1 - v2;
float x_diff;
float y_diff;
vec.Value(x_diff, y_diff);
pinch_start_distance_SQ_ = x_diff * x_diff + y_diff * y_diff;
camera_rotation_start_ = atan2f(y_diff, x_diff);
camera_rotation_now_ = 0;
pinching_ = true;
momentum_ = false;
// Init momentum factors
vec_offset_delta_ = Vec3();
}
void TapCamera::EndPinch() {
pinching_ = false;
momentum_ = true;
momemtum_steps_ = 1.f;
vec_offset_ += vec_offset_now_;
camera_rotation_ += camera_rotation_now_;
vec_offset_now_ = Vec3();
camera_rotation_now_ = 0;
EndDrag();
}
void TapCamera::Pinch(const Vec2& v1, const Vec2& v2) {
if (!pinching_) return;
// Update momentum factor
vec_offset_last_ = vec_offset_now_;
float x_diff, y_diff;
Vec2 vec = v1 - v2;
vec.Value(x_diff, y_diff);
float fDistanceSQ = x_diff * x_diff + y_diff * y_diff;
float f = pinch_start_distance_SQ_ / fDistanceSQ;
if (f < 1.f)
f = -1.f / f + 1.0f;
else
f = f - 1.f;
if (isnan(f)) f = 0.f;
vec = (v1 + v2) / 2.f - vec_pinch_start_center_;
vec_offset_now_ = Vec3(vec, flip_z_ * f);
// Update momentum factor
vec_offset_delta_ = vec_offset_delta_ * MOMENTUM_FACTOR +
(vec_offset_now_ - vec_offset_last_);
//
// Update ration quaternion
float fRotation = atan2f(y_diff, x_diff);
camera_rotation_now_ = fRotation - camera_rotation_start_;
// Trackball rotation
quat_ball_rot_ = Quaternion(0.f, 0.f, sinf(-camera_rotation_now_ * 0.5f),
cosf(-camera_rotation_now_ * 0.5f));
}
//----------------------------------------------------------
// Trackball controll
//----------------------------------------------------------
void TapCamera::BallUpdate() {
if (dragging_) {
Vec3 vec_from = PointOnSphere(vec_ball_down_);
Vec3 vec_to = PointOnSphere(vec_ball_now_);
Vec3 vec = vec_from.Cross(vec_to);
float w = vec_from.Dot(vec_to);
Quaternion qDrag = Quaternion(vec, w);
qDrag = qDrag * quat_ball_down_;
quat_ball_now_ = quat_ball_rot_ * qDrag;
}
quat_ball_now_.ToMatrix(mat_rotation_);
}
Vec3 TapCamera::PointOnSphere(Vec2& point) {
Vec3 ball_mouse;
float mag;
Vec2 vec = (point - vec_ball_center_) / ball_radius_;
mag = vec.Dot(vec);
if (mag > 1.f) {
float scale = 1.f / sqrtf(mag);
vec *= scale;
ball_mouse = Vec3(vec, 0.f);
} else {
ball_mouse = Vec3(vec, sqrtf(1.f - mag));
}
return ball_mouse;
}
} // namespace ndkHelper

View File

@@ -1,108 +0,0 @@
/*
* Copyright 2013 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <vector>
#include <string>
#include <GLES2/gl2.h>
#include "JNIHelper.h"
#include "vecmath.h"
#include "interpolator.h"
namespace ndk_helper {
/******************************************************************
* Camera control helper class with a tap gesture
* This class is mainly used for 3D space camera control in samples.
*
*/
class TapCamera {
private:
// Trackball
Vec2 vec_ball_center_;
float ball_radius_ {0.75f};
Quaternion quat_ball_now_;
Quaternion quat_ball_down_;
Vec2 vec_ball_now_;
Vec2 vec_ball_down_;
Quaternion quat_ball_rot_;
bool dragging_ {false};
bool pinching_ {false};
// Pinch related info
Vec2 vec_pinch_start_;
Vec2 vec_pinch_start_center_;
float pinch_start_distance_SQ_ {0.0f};
// Camera shift
Vec3 vec_offset_;
Vec3 vec_offset_now_;
// Camera Rotation
float camera_rotation_ {0.0f};
float camera_rotation_start_ {0.0f};
float camera_rotation_now_ {0.0f};
// Momentum support
bool momentum_ {false};
Vec2 vec_drag_delta_;
Vec2 vec_last_input_;
Vec3 vec_offset_last_;
Vec3 vec_offset_delta_;
float momemtum_steps_;
Vec2 vec_flip_;
float flip_z_ {0.0f};
Mat4 mat_rotation_;
Mat4 mat_transform_;
Vec3 vec_pinch_transform_factor_;
Vec3 PointOnSphere(Vec2& point);
void BallUpdate();
void InitParameters();
public:
TapCamera();
virtual ~TapCamera();
void BeginDrag(const Vec2& vec);
void EndDrag();
void Drag(const Vec2& vec);
void Update();
Mat4& GetRotationMatrix();
Mat4& GetTransformMatrix();
void BeginPinch(const Vec2& v1, const Vec2& v2);
void EndPinch();
void Pinch(const Vec2& v1, const Vec2& v2);
void SetFlip(const float x, const float y, const float z) {
vec_flip_ = Vec2(x, y);
flip_z_ = z;
}
void SetPinchTransformFactor(const float x, const float y, const float z) {
vec_pinch_transform_factor_ = Vec3(x, y, z);
}
void Reset(const bool bAnimate);
};
} // namespace ndkHelper

Binary file not shown.

View File

@@ -1,39 +0,0 @@
apply plugin: 'com.android.model.library'
def ndkDir = System.getenv("ANDROID_NDK_HOME")
def propertiesFile = project.rootProject.file('local.properties')
if (propertiesFile.exists()) {
Properties properties = new Properties()
properties.load(propertiesFile.newDataInputStream())
ndkDir = properties.getProperty('ndk.dir')
}
model {
android {
compileSdkVersion = 23
buildToolsVersion = '23.0.2'
defaultConfig.with {
minSdkVersion.apiLevel = 9
targetSdkVersion.apiLevel = 23
versionCode = 1
versionName = '0.0.1'
}
ndk {
moduleName = 'native-activity'
ldLibs.addAll(['log', 'android'])
ldFlags.add('-c')
}
sources {
main {
jni {
source {
srcDir "${ndkDir}/sources/android/native_app_glue"
}
exportedHeaders {
srcDir "${ndkDir}/sources/android/native_app_glue"
}
}
}
}
}
}

View File

@@ -1,7 +0,0 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="native_activity.android.example.com.nativeactivity">
<application>
</application>
</manifest>

View File

@@ -1,2 +0,0 @@
include ':app'
include ':nativeactivity'

View File

@@ -1,23 +0,0 @@
version: '{build}'
clone_folder: c:\projects\android-ndk
init:
- cd \
- appveyor DownloadFile http://dl.google.com/android/android-sdk_r24.3.4-windows.zip
- 7z x android-sdk_r24.3.4-windows.zip > nul
- appveyor DownloadFile http://dl.google.com/android/ndk/android-ndk-r10e-windows-x86_64.exe
- android-ndk-r10e-windows-x86_64.exe > nul
- cd c:\projects\android-ndk
environment:
ANDROID_NDK_HOME: C:\android-ndk-r10e
ANDROID_HOME: C:\android-sdk-windows
install:
- echo y | C:\android-sdk-windows\tools\android.bat update sdk --no-ui --all --filter android-23
- echo y | C:\android-sdk-windows\tools\android.bat update sdk --no-ui --all --filter platform-tools
- echo y | C:\android-sdk-windows\tools\android.bat update sdk --no-ui --all --filter tools
- echo y | C:\android-sdk-windows\tools\android.bat update sdk --no-ui --all --filter build-tools-23.0.2
- echo y | C:\android-sdk-windows\tools\android.bat update sdk --no-ui --all --filter extra-google-m2repository
- echo y | C:\android-sdk-windows\tools\android.bat update sdk --no-ui --all --filter extra-android-m2repository
build_script:
- cd c:\projects\android-ndk\hello-thirdparty && gradlew download_and_stage_gpg_sdk
- cd c:\projects\android-ndk\builder && gradlew test
test: off

View File

@@ -1,6 +1,6 @@
status: PUBLISHED
technologies: [Android, NDK]
categories: [NDK, C++]
categories: [NDK]
languages: [C++, Java]
solutions: [Mobile]
github: googlesamples/android-ndk

View File

@@ -4,11 +4,13 @@ The sample demos how to use OpenSL ES to create a player and recorder in Android
* Android L AndroidOne
* Android M Nexus 5, Nexus 9
This sample uses the new [Gradle Experimental Android plugin](http://tools.android.com/tech-docs/new-build-system/gradle-experimental) with C++ support.
This sample uses the new Android Studio with CMake support, and shows how to use shared stl lib with android studio version 2.2.0, see CMakeLists.txt for details
***Note that OpenSL ES is [deprecated from Android 11](https://developer.android.com/preview/features#deprecate-opensl), developers are recommended to use [Oboe](https://github.com/google/oboe) library instead.***
Pre-requisites
--------------
- Android Studio 1.3+ with [NDK](https://developer.android.com/ndk/) bundle.
- Android Studio 2.2+ with [NDK](https://developer.android.com/ndk/) bundle.
Getting Started
---------------
@@ -69,7 +71,6 @@ Patches are encouraged, and may be submitted by [forking this project](https://g
submitting a pull request through GitHub. Please see [CONTRIBUTING.md](../CONTRIBUTING.md) for more details.
- [Stack Overflow](http://stackoverflow.com/questions/tagged/android-ndk)
- [Google+ Community](https://plus.google.com/communities/105153134372062985968)
- [Android Tools Feedbacks](http://tools.android.com/feedback)
License

View File

@@ -1,29 +1,42 @@
apply plugin: 'com.android.model.application'
apply plugin: 'com.android.application'
model {
android {
compileSdkVersion = 23
buildToolsVersion = '23.0.2'
android {
compileSdkVersion 29
ndkVersion '21.2.6472646'
defaultConfig {
applicationId='com.google.sample.echo'
minSdkVersion.apiLevel = 17
targetSdkVersion.apiLevel = 22
versionCode = 1
versionName = '1.0'
}
ndk {
moduleName = 'echo'
//toolchain = "clang"
stl = 'c++_static' //std::mutex not in gnustl_static
cppFlags.add('-std=c++11')
ldLibs.addAll(['android', 'log', 'OpenSLES', 'atomic'])
}
buildTypes {
release {
minifyEnabled=false
proguardFiles.add(file('proguard-android.txt'))
defaultConfig {
applicationId 'com.google.sample.echo'
/*
To run on earlier version of Android than android-21, do:
*) set this minSDKVersion and cmake's ANDROID_PLATFORM to your version
*) set ANDROID_STL to c++_static for some very earlier version android.
*/
minSdkVersion 23
targetSdkVersion 28
versionCode 1
versionName '1.0'
externalNativeBuild {
cmake {
arguments '-DANDROID_STL=c++_static'
}
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'),
'proguard-rules.pro'
}
}
externalNativeBuild {
cmake {
version '3.18.1'
path 'src/main/cpp/CMakeLists.txt'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.0.2'
}

View File

@@ -1,11 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.google.sample.echo" >
<uses-permission android:name="android.permission.RECORD_AUDIO"></uses-permission>
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"></uses-permission>
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<!-- debug-writing file need external storage writing -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application
android:allowBackup="false"
android:fullBackupContent="false"

View File

@@ -0,0 +1,23 @@
cmake_minimum_required(VERSION 3.4.1)
project(echo LANGUAGES C CXX)
add_library(echo
SHARED
audio_main.cpp
audio_player.cpp
audio_recorder.cpp
audio_effect.cpp
audio_common.cpp
debug_utils.cpp)
#include libraries needed for echo lib
target_link_libraries(echo
PRIVATE
OpenSLES
android
log
atomic)
target_compile_options(echo
PRIVATE
-Wall -Werror)

View File

@@ -0,0 +1,47 @@
/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#ifndef NATIVE_AUDIO_ANDROID_DEBUG_H_H
#define NATIVE_AUDIO_ANDROID_DEBUG_H_H
#include <android/log.h>
#if 1
#define MODULE_NAME "AUDIO-ECHO"
#define LOGV(...) \
__android_log_print(ANDROID_LOG_VERBOSE, MODULE_NAME, __VA_ARGS__)
#define LOGD(...) \
__android_log_print(ANDROID_LOG_DEBUG, MODULE_NAME, __VA_ARGS__)
#define LOGI(...) \
__android_log_print(ANDROID_LOG_INFO, MODULE_NAME, __VA_ARGS__)
#define LOGW(...) \
__android_log_print(ANDROID_LOG_WARN, MODULE_NAME, __VA_ARGS__)
#define LOGE(...) \
__android_log_print(ANDROID_LOG_ERROR, MODULE_NAME, __VA_ARGS__)
#define LOGF(...) \
__android_log_print(ANDROID_LOG_FATAL, MODULE_NAME, __VA_ARGS__)
#else
#define LOGV(...)
#define LOGD(...)
#define LOGI(...)
#define LOGW(...)
#define LOGE(...)
#define LOGF(...)
#endif
#endif // NATIVE_AUDIO_ANDROID_DEBUG_H_H

View File

@@ -0,0 +1,66 @@
/*
* Copyright 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "audio_common.h"
void ConvertToSLSampleFormat(SLAndroidDataFormat_PCM_EX* pFormat,
SampleFormat* pSampleInfo_) {
assert(pFormat);
memset(pFormat, 0, sizeof(*pFormat));
pFormat->formatType = SL_DATAFORMAT_PCM;
// Only support 2 channels
// For channelMask, refer to wilhelm/src/android/channels.c for details
if (pSampleInfo_->channels_ <= 1) {
pFormat->numChannels = 1;
pFormat->channelMask = SL_SPEAKER_FRONT_LEFT;
} else {
pFormat->numChannels = 2;
pFormat->channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT;
}
pFormat->sampleRate = pSampleInfo_->sampleRate_;
pFormat->endianness = SL_BYTEORDER_LITTLEENDIAN;
pFormat->bitsPerSample = pSampleInfo_->pcmFormat_;
pFormat->containerSize = pSampleInfo_->pcmFormat_;
/*
* fixup for android extended representations...
*/
pFormat->representation = pSampleInfo_->representation_;
switch (pFormat->representation) {
case SL_ANDROID_PCM_REPRESENTATION_UNSIGNED_INT:
pFormat->bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_8;
pFormat->containerSize = SL_PCMSAMPLEFORMAT_FIXED_8;
pFormat->formatType = SL_ANDROID_DATAFORMAT_PCM_EX;
break;
case SL_ANDROID_PCM_REPRESENTATION_SIGNED_INT:
pFormat->bitsPerSample =
SL_PCMSAMPLEFORMAT_FIXED_16; // supports 16, 24, and 32
pFormat->containerSize = SL_PCMSAMPLEFORMAT_FIXED_16;
pFormat->formatType = SL_ANDROID_DATAFORMAT_PCM_EX;
break;
case SL_ANDROID_PCM_REPRESENTATION_FLOAT:
pFormat->bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_32;
pFormat->containerSize = SL_PCMSAMPLEFORMAT_FIXED_32;
pFormat->formatType = SL_ANDROID_DATAFORMAT_PCM_EX;
break;
case 0:
break;
default:
assert(0);
}
}

View File

@@ -14,10 +14,10 @@
* limitations under the License.
*/
#ifndef NATIVE_AUDIO_AUDIO_COMMON_H
#define NATIVE_AUDIO_AUDIO_COMMON_H
#include <SLES/OpenSLES.h>
#include <SLES/OpenSLES_Android.h>
#include "android_debug.h"
@@ -27,52 +27,53 @@
/*
* Audio Sample Controls...
*/
#define AUDIO_SAMPLE_CHANNELS 1
#define AUDIO_SAMPLE_CHANNELS 1
/*
* Sample Buffer Controls...
*/
#define RECORD_DEVICE_KICKSTART_BUF_COUNT 2
#define PLAY_KICKSTART_BUFFER_COUNT 3
#define DEVICE_SHADOW_BUFFER_QUEUE_LEN 4
#define BUF_COUNT 16
#define RECORD_DEVICE_KICKSTART_BUF_COUNT 2
#define PLAY_KICKSTART_BUFFER_COUNT 3
#define DEVICE_SHADOW_BUFFER_QUEUE_LEN 4
#define BUF_COUNT 16
struct SampleFormat {
uint32_t sampleRate_;
uint32_t framesPerBuf_;
uint16_t channels_;
uint16_t pcmFormat_; //8 bit, 16 bit, 24 bit ...
uint32_t representation_; //android extensions
uint32_t sampleRate_;
uint32_t framesPerBuf_;
uint16_t channels_;
uint16_t pcmFormat_; // 8 bit, 16 bit, 24 bit ...
uint32_t representation_; // android extensions
};
extern void ConvertToSLSampleFormat(SLAndroidDataFormat_PCM_EX *pFormat,
extern void ConvertToSLSampleFormat(SLAndroidDataFormat_PCM_EX* pFormat,
SampleFormat* format);
/*
* GetSystemTicks(void): return the time in micro sec
*/
__inline__ uint64_t GetSystemTicks(void) {
struct timeval Time;
gettimeofday( &Time, NULL );
struct timeval Time;
gettimeofday(&Time, NULL);
return (static_cast<uint64_t>(1000000) * Time.tv_sec + Time.tv_usec);
return (static_cast<uint64_t>(1000000) * Time.tv_sec + Time.tv_usec);
}
#define SLASSERT(x) do {\
assert(SL_RESULT_SUCCESS == (x));\
(void) (x);\
} while (0)
#define SLASSERT(x) \
do { \
assert(SL_RESULT_SUCCESS == (x)); \
(void)(x); \
} while (0)
/*
* Interface for player and recorder to communicate with engine
*/
#define ENGINE_SERVICE_MSG_KICKSTART_PLAYER 1
#define ENGINE_SERVICE_MSG_RETRIEVE_DUMP_BUFS 2
#define ENGINE_SERVICE_MSG_KICKSTART_PLAYER 1
#define ENGINE_SERVICE_MSG_RETRIEVE_DUMP_BUFS 2
#define ENGINE_SERVICE_MSG_RECORDED_AUDIO_AVAILABLE 3
typedef bool (*ENGINE_CALLBACK)(void* pCTX, uint32_t msg, void* pData);
/*
* flag to enable file dumping
*/
//#define ENABLE_LOG 1
// #define ENABLE_LOG 1
#endif //NATIVE_AUDIO_AUDIO_COMMON_H
#endif // NATIVE_AUDIO_AUDIO_COMMON_H

View File

@@ -0,0 +1,170 @@
/*
* Copyright 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "audio_effect.h"
#include "audio_common.h"
#include <climits>
#include <cstring>
/*
* Mixing Audio in integer domain to avoid FP calculation
* (FG * ( MixFactor * 16 ) + BG * ( (1.0f-MixFactor) * 16 )) / 16
*/
static const int32_t kFloatToIntMapFactor = 128;
static const uint32_t kMsPerSec = 1000;
/**
* Constructor for AudioDelay
* @param sampleRate
* @param channelCount
* @param format
* @param delayTimeInMs
*/
AudioDelay::AudioDelay(int32_t sampleRate, int32_t channelCount,
SLuint32 format, size_t delayTimeInMs,
float decayWeight)
: AudioFormat(sampleRate, channelCount, format),
delayTime_(delayTimeInMs),
decayWeight_(decayWeight) {
feedbackFactor_ = static_cast<int32_t>(decayWeight_ * kFloatToIntMapFactor);
liveAudioFactor_ = kFloatToIntMapFactor - feedbackFactor_;
allocateBuffer();
}
/**
* Destructor
*/
AudioDelay::~AudioDelay() {
if (buffer_) delete static_cast<uint8_t*>(buffer_);
}
/**
* Configure for delay time ( in miliseconds ), dynamically adjustable
* @param delayTimeInMS in miliseconds
* @return true if delay time is set successfully
*/
bool AudioDelay::setDelayTime(size_t delayTimeInMS) {
if (delayTimeInMS == delayTime_) return true;
std::lock_guard<std::mutex> lock(lock_);
if (buffer_) {
delete static_cast<uint8_t*>(buffer_);
buffer_ = nullptr;
}
delayTime_ = delayTimeInMS;
allocateBuffer();
return buffer_ != nullptr;
}
/**
* Internal helper function to allocate buffer for the delay
* - calculate the buffer size for the delay time
* - allocate and zero out buffer (0 means silent audio)
* - configure bufSize_ to be size of audioFrames
*/
void AudioDelay::allocateBuffer(void) {
float floatDelayTime = (float)delayTime_ / kMsPerSec;
float fNumFrames = floatDelayTime * (float)sampleRate_ / kMsPerSec;
size_t sampleCount = static_cast<uint32_t>(fNumFrames + 0.5f) * channelCount_;
uint32_t bytePerSample = format_ / 8;
assert(bytePerSample <= 4 && bytePerSample);
uint32_t bytePerFrame = channelCount_ * bytePerSample;
// get bufCapacity in bytes
bufCapacity_ = sampleCount * bytePerSample;
bufCapacity_ =
((bufCapacity_ + bytePerFrame - 1) / bytePerFrame) * bytePerFrame;
buffer_ = new uint8_t[bufCapacity_];
assert(buffer_);
memset(buffer_, 0, bufCapacity_);
curPos_ = 0;
// bufSize_ is in Frames ( not samples, not bytes )
bufSize_ = bufCapacity_ / bytePerFrame;
}
size_t AudioDelay::getDelayTime(void) const { return delayTime_; }
/**
* setDecayWeight(): set the decay factor
* ratio: value of 0.0 -- 1.0f;
*
* the calculation is in integer ( not in float )
* for performance purpose
*/
void AudioDelay::setDecayWeight(float weight) {
if (weight > 0.0f && weight < 1.0f) {
float feedback = (weight * kFloatToIntMapFactor + 0.5f);
feedbackFactor_ = static_cast<int32_t>(feedback);
liveAudioFactor_ = kFloatToIntMapFactor - feedbackFactor_;
}
}
float AudioDelay::getDecayWeight(void) const { return decayWeight_; }
/**
* process() filter live audio with "echo" effect:
* delay time is run-time adjustable
* decay time could also be adjustable, but not used
* in this sample, hardcoded to .5
*
* @param liveAudio is recorded audio stream
* @param channelCount for liveAudio, must be 2 for stereo
* @param numFrames is length of liveAudio in Frames ( not in byte )
*/
void AudioDelay::process(int16_t* liveAudio, int32_t numFrames) {
if (feedbackFactor_ == 0 || bufSize_ < numFrames) {
return;
}
if (!lock_.try_lock()) {
return;
}
if (numFrames + curPos_ > bufSize_) {
curPos_ = 0;
}
// process every sample
int32_t sampleCount = channelCount_ * numFrames;
int16_t* samples = &static_cast<int16_t*>(buffer_)[curPos_ * channelCount_];
for (size_t idx = 0; idx < sampleCount; idx++) {
#if 1
int32_t curSample =
(samples[idx] * feedbackFactor_ + liveAudio[idx] * liveAudioFactor_) /
kFloatToIntMapFactor;
if (curSample > SHRT_MAX)
curSample = SHRT_MAX;
else if (curSample < SHRT_MIN)
curSample = SHRT_MIN;
liveAudio[idx] = samples[idx];
samples[idx] = static_cast<int16_t>(curSample);
#else
// Pure delay
int16_t tmp = liveAudio[idx];
liveAudio[idx] = samples[idx];
samples[idx] = tmp;
#endif
}
curPos_ += numFrames;
lock_.unlock();
}

View File

@@ -0,0 +1,66 @@
/*
* Copyright 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef EFFECT_PROCESSOR_H
#define EFFECT_PROCESSOR_H
#include <SLES/OpenSLES_Android.h>
#include <cstdint>
#include <atomic>
#include <mutex>
class AudioFormat {
protected:
int32_t sampleRate_ = SL_SAMPLINGRATE_48;
int32_t channelCount_ = 2;
SLuint32 format_ = SL_PCMSAMPLEFORMAT_FIXED_16;
AudioFormat(int32_t sampleRate, int32_t channelCount, SLuint32 format)
: sampleRate_(sampleRate), channelCount_(channelCount), format_(format){};
virtual ~AudioFormat() {}
};
/**
* An audio delay effect:
* - decay is for feedback(echo)weight
* - delay time is adjustable
*/
class AudioDelay : public AudioFormat {
public:
~AudioDelay();
explicit AudioDelay(int32_t sampleRate, int32_t channelCount, SLuint32 format,
size_t delayTimeInMs, float Weight);
bool setDelayTime(size_t delayTimeInMiliSec);
size_t getDelayTime(void) const;
void setDecayWeight(float weight);
float getDecayWeight(void) const;
void process(int16_t *liveAudio, int32_t numFrames);
private:
size_t delayTime_ = 0;
float decayWeight_ = 0.5;
void *buffer_ = nullptr;
size_t bufCapacity_ = 0;
size_t bufSize_ = 0;
size_t curPos_ = 0;
std::mutex lock_;
int32_t feedbackFactor_;
int32_t liveAudioFactor_;
void allocateBuffer(void);
};
#endif // EFFECT_PROCESSOR_H

View File

@@ -0,0 +1,259 @@
/*
* Copyright 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "jni_interface.h"
#include "audio_recorder.h"
#include "audio_player.h"
#include "audio_effect.h"
#include "audio_common.h"
#include <jni.h>
#include <SLES/OpenSLES_Android.h>
#include <sys/types.h>
#include <cassert>
#include <cstring>
struct EchoAudioEngine {
SLmilliHertz fastPathSampleRate_;
uint32_t fastPathFramesPerBuf_;
uint16_t sampleChannels_;
uint16_t bitsPerSample_;
SLObjectItf slEngineObj_;
SLEngineItf slEngineItf_;
AudioRecorder *recorder_;
AudioPlayer *player_;
AudioQueue *freeBufQueue_; // Owner of the queue
AudioQueue *recBufQueue_; // Owner of the queue
sample_buf *bufs_;
uint32_t bufCount_;
uint32_t frameCount_;
int64_t echoDelay_;
float echoDecay_;
AudioDelay *delayEffect_;
};
static EchoAudioEngine engine;
bool EngineService(void *ctx, uint32_t msg, void *data);
JNIEXPORT void JNICALL Java_com_google_sample_echo_MainActivity_createSLEngine(
JNIEnv *env, jclass type, jint sampleRate, jint framesPerBuf,
jlong delayInMs, jfloat decay) {
SLresult result;
memset(&engine, 0, sizeof(engine));
engine.fastPathSampleRate_ = static_cast<SLmilliHertz>(sampleRate) * 1000;
engine.fastPathFramesPerBuf_ = static_cast<uint32_t>(framesPerBuf);
engine.sampleChannels_ = AUDIO_SAMPLE_CHANNELS;
engine.bitsPerSample_ = SL_PCMSAMPLEFORMAT_FIXED_16;
result = slCreateEngine(&engine.slEngineObj_, 0, NULL, 0, NULL, NULL);
SLASSERT(result);
result =
(*engine.slEngineObj_)->Realize(engine.slEngineObj_, SL_BOOLEAN_FALSE);
SLASSERT(result);
result = (*engine.slEngineObj_)
->GetInterface(engine.slEngineObj_, SL_IID_ENGINE,
&engine.slEngineItf_);
SLASSERT(result);
// compute the RECOMMENDED fast audio buffer size:
// the lower latency required
// *) the smaller the buffer should be (adjust it here) AND
// *) the less buffering should be before starting player AFTER
// receiving the recorder buffer
// Adjust the bufSize here to fit your bill [before it busts]
uint32_t bufSize = engine.fastPathFramesPerBuf_ * engine.sampleChannels_ *
engine.bitsPerSample_;
bufSize = (bufSize + 7) >> 3; // bits --> byte
engine.bufCount_ = BUF_COUNT;
engine.bufs_ = allocateSampleBufs(engine.bufCount_, bufSize);
assert(engine.bufs_);
engine.freeBufQueue_ = new AudioQueue(engine.bufCount_);
engine.recBufQueue_ = new AudioQueue(engine.bufCount_);
assert(engine.freeBufQueue_ && engine.recBufQueue_);
for (uint32_t i = 0; i < engine.bufCount_; i++) {
engine.freeBufQueue_->push(&engine.bufs_[i]);
}
engine.echoDelay_ = delayInMs;
engine.echoDecay_ = decay;
engine.delayEffect_ = new AudioDelay(
engine.fastPathSampleRate_, engine.sampleChannels_, engine.bitsPerSample_,
engine.echoDelay_, engine.echoDecay_);
assert(engine.delayEffect_);
}
JNIEXPORT jboolean JNICALL
Java_com_google_sample_echo_MainActivity_configureEcho(JNIEnv *env, jclass type,
jint delayInMs,
jfloat decay) {
engine.echoDelay_ = delayInMs;
engine.echoDecay_ = decay;
engine.delayEffect_->setDelayTime(delayInMs);
engine.delayEffect_->setDecayWeight(decay);
return JNI_FALSE;
}
JNIEXPORT jboolean JNICALL
Java_com_google_sample_echo_MainActivity_createSLBufferQueueAudioPlayer(
JNIEnv *env, jclass type) {
SampleFormat sampleFormat;
memset(&sampleFormat, 0, sizeof(sampleFormat));
sampleFormat.pcmFormat_ = (uint16_t)engine.bitsPerSample_;
sampleFormat.framesPerBuf_ = engine.fastPathFramesPerBuf_;
// SampleFormat.representation_ = SL_ANDROID_PCM_REPRESENTATION_SIGNED_INT;
sampleFormat.channels_ = (uint16_t)engine.sampleChannels_;
sampleFormat.sampleRate_ = engine.fastPathSampleRate_;
engine.player_ = new AudioPlayer(&sampleFormat, engine.slEngineItf_);
assert(engine.player_);
if (engine.player_ == nullptr) return JNI_FALSE;
engine.player_->SetBufQueue(engine.recBufQueue_, engine.freeBufQueue_);
engine.player_->RegisterCallback(EngineService, (void *)&engine);
return JNI_TRUE;
}
JNIEXPORT void JNICALL
Java_com_google_sample_echo_MainActivity_deleteSLBufferQueueAudioPlayer(
JNIEnv *env, jclass type) {
if (engine.player_) {
delete engine.player_;
engine.player_ = nullptr;
}
}
JNIEXPORT jboolean JNICALL
Java_com_google_sample_echo_MainActivity_createAudioRecorder(JNIEnv *env,
jclass type) {
SampleFormat sampleFormat;
memset(&sampleFormat, 0, sizeof(sampleFormat));
sampleFormat.pcmFormat_ = static_cast<uint16_t>(engine.bitsPerSample_);
// SampleFormat.representation_ = SL_ANDROID_PCM_REPRESENTATION_SIGNED_INT;
sampleFormat.channels_ = engine.sampleChannels_;
sampleFormat.sampleRate_ = engine.fastPathSampleRate_;
sampleFormat.framesPerBuf_ = engine.fastPathFramesPerBuf_;
engine.recorder_ = new AudioRecorder(&sampleFormat, engine.slEngineItf_);
if (!engine.recorder_) {
return JNI_FALSE;
}
engine.recorder_->SetBufQueues(engine.freeBufQueue_, engine.recBufQueue_);
engine.recorder_->RegisterCallback(EngineService, (void *)&engine);
return JNI_TRUE;
}
JNIEXPORT void JNICALL
Java_com_google_sample_echo_MainActivity_deleteAudioRecorder(JNIEnv *env,
jclass type) {
if (engine.recorder_) delete engine.recorder_;
engine.recorder_ = nullptr;
}
JNIEXPORT void JNICALL
Java_com_google_sample_echo_MainActivity_startPlay(JNIEnv *env, jclass type) {
engine.frameCount_ = 0;
/*
* start player: make it into waitForData state
*/
if (SL_BOOLEAN_FALSE == engine.player_->Start()) {
LOGE("====%s failed", __FUNCTION__);
return;
}
engine.recorder_->Start();
}
JNIEXPORT void JNICALL
Java_com_google_sample_echo_MainActivity_stopPlay(JNIEnv *env, jclass type) {
engine.recorder_->Stop();
engine.player_->Stop();
delete engine.recorder_;
delete engine.player_;
engine.recorder_ = NULL;
engine.player_ = NULL;
}
JNIEXPORT void JNICALL Java_com_google_sample_echo_MainActivity_deleteSLEngine(
JNIEnv *env, jclass type) {
delete engine.recBufQueue_;
delete engine.freeBufQueue_;
releaseSampleBufs(engine.bufs_, engine.bufCount_);
if (engine.slEngineObj_ != NULL) {
(*engine.slEngineObj_)->Destroy(engine.slEngineObj_);
engine.slEngineObj_ = NULL;
engine.slEngineItf_ = NULL;
}
if (engine.delayEffect_) {
delete engine.delayEffect_;
engine.delayEffect_ = nullptr;
}
}
uint32_t dbgEngineGetBufCount(void) {
uint32_t count = engine.player_->dbgGetDevBufCount();
count += engine.recorder_->dbgGetDevBufCount();
count += engine.freeBufQueue_->size();
count += engine.recBufQueue_->size();
LOGE(
"Buf Disrtibutions: PlayerDev=%d, RecDev=%d, FreeQ=%d, "
"RecQ=%d",
engine.player_->dbgGetDevBufCount(),
engine.recorder_->dbgGetDevBufCount(), engine.freeBufQueue_->size(),
engine.recBufQueue_->size());
if (count != engine.bufCount_) {
LOGE("====Lost Bufs among the queue(supposed = %d, found = %d)", BUF_COUNT,
count);
}
return count;
}
/*
* simple message passing for player/recorder to communicate with engine
*/
bool EngineService(void *ctx, uint32_t msg, void *data) {
assert(ctx == &engine);
switch (msg) {
case ENGINE_SERVICE_MSG_RETRIEVE_DUMP_BUFS: {
*(static_cast<uint32_t *>(data)) = dbgEngineGetBufCount();
break;
}
case ENGINE_SERVICE_MSG_RECORDED_AUDIO_AVAILABLE: {
// adding audio delay effect
sample_buf *buf = static_cast<sample_buf *>(data);
assert(engine.fastPathFramesPerBuf_ ==
buf->size_ / engine.sampleChannels_ / (engine.bitsPerSample_ / 8));
engine.delayEffect_->process(reinterpret_cast<int16_t *>(buf->buf_),
engine.fastPathFramesPerBuf_);
break;
}
default:
assert(false);
return false;
}
return true;
}

View File

@@ -0,0 +1,260 @@
/*
* Copyright 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <cstdlib>
#include "audio_player.h"
/*
* Called by OpenSL SimpleBufferQueue for every audio buffer played
* directly pass thru to our handler.
* The regularity of this callback from openSL/Android System affects
* playback continuity. If it does not callback in the regular time
* slot, you are under big pressure for audio processing[here we do
* not do any filtering/mixing]. Callback from fast audio path are
* much more regular than other audio paths by my observation. If it
* very regular, you could buffer much less audio samples between
* recorder and player, hence lower latency.
*/
void bqPlayerCallback(SLAndroidSimpleBufferQueueItf bq, void *ctx) {
(static_cast<AudioPlayer *>(ctx))->ProcessSLCallback(bq);
}
void AudioPlayer::ProcessSLCallback(SLAndroidSimpleBufferQueueItf bq) {
#ifdef ENABLE_LOG
logFile_->logTime();
#endif
std::lock_guard<std::mutex> lock(stopMutex_);
// retrieve the finished device buf and put onto the free queue
// so recorder could re-use it
sample_buf *buf;
if (!devShadowQueue_->front(&buf)) {
/*
* This should not happen: we got a callback,
* but we have no buffer in deviceShadowedQueue
* we lost buffers this way...(ERROR)
*/
if (callback_) {
uint32_t count;
callback_(ctx_, ENGINE_SERVICE_MSG_RETRIEVE_DUMP_BUFS, &count);
}
return;
}
devShadowQueue_->pop();
if (buf != &silentBuf_) {
buf->size_ = 0;
freeQueue_->push(buf);
if (!playQueue_->front(&buf)) {
#ifdef ENABLE_LOG
logFile_->log("%s", "====Warning: running out of the Audio buffers");
#endif
return;
}
devShadowQueue_->push(buf);
(*bq)->Enqueue(bq, buf->buf_, buf->size_);
playQueue_->pop();
return;
}
if (playQueue_->size() < PLAY_KICKSTART_BUFFER_COUNT) {
(*bq)->Enqueue(bq, buf->buf_, buf->size_);
devShadowQueue_->push(&silentBuf_);
return;
}
assert(PLAY_KICKSTART_BUFFER_COUNT <=
(DEVICE_SHADOW_BUFFER_QUEUE_LEN - devShadowQueue_->size()));
for (int32_t idx = 0; idx < PLAY_KICKSTART_BUFFER_COUNT; idx++) {
playQueue_->front(&buf);
playQueue_->pop();
devShadowQueue_->push(buf);
(*bq)->Enqueue(bq, buf->buf_, buf->size_);
}
}
AudioPlayer::AudioPlayer(SampleFormat *sampleFormat, SLEngineItf slEngine)
: freeQueue_(nullptr),
playQueue_(nullptr),
devShadowQueue_(nullptr),
callback_(nullptr) {
SLresult result;
assert(sampleFormat);
sampleInfo_ = *sampleFormat;
result = (*slEngine)
->CreateOutputMix(slEngine, &outputMixObjectItf_, 0, NULL, NULL);
SLASSERT(result);
// realize the output mix
result =
(*outputMixObjectItf_)->Realize(outputMixObjectItf_, SL_BOOLEAN_FALSE);
SLASSERT(result);
// configure audio source
SLDataLocator_AndroidSimpleBufferQueue loc_bufq = {
SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, DEVICE_SHADOW_BUFFER_QUEUE_LEN};
SLAndroidDataFormat_PCM_EX format_pcm;
ConvertToSLSampleFormat(&format_pcm, &sampleInfo_);
SLDataSource audioSrc = {&loc_bufq, &format_pcm};
// configure audio sink
SLDataLocator_OutputMix loc_outmix = {SL_DATALOCATOR_OUTPUTMIX,
outputMixObjectItf_};
SLDataSink audioSnk = {&loc_outmix, NULL};
/*
* create fast path audio player: SL_IID_BUFFERQUEUE and SL_IID_VOLUME
* and other non-signal processing interfaces are ok.
*/
SLInterfaceID ids[2] = {SL_IID_BUFFERQUEUE, SL_IID_VOLUME};
SLboolean req[2] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE};
result = (*slEngine)->CreateAudioPlayer(
slEngine, &playerObjectItf_, &audioSrc, &audioSnk,
sizeof(ids) / sizeof(ids[0]), ids, req);
SLASSERT(result);
// realize the player
result = (*playerObjectItf_)->Realize(playerObjectItf_, SL_BOOLEAN_FALSE);
SLASSERT(result);
// get the play interface
result = (*playerObjectItf_)
->GetInterface(playerObjectItf_, SL_IID_PLAY, &playItf_);
SLASSERT(result);
// get the buffer queue interface
result = (*playerObjectItf_)
->GetInterface(playerObjectItf_, SL_IID_BUFFERQUEUE,
&playBufferQueueItf_);
SLASSERT(result);
// register callback on the buffer queue
result = (*playBufferQueueItf_)
->RegisterCallback(playBufferQueueItf_, bqPlayerCallback, this);
SLASSERT(result);
result = (*playItf_)->SetPlayState(playItf_, SL_PLAYSTATE_STOPPED);
SLASSERT(result);
// create an empty queue to track deviceQueue
devShadowQueue_ = new AudioQueue(DEVICE_SHADOW_BUFFER_QUEUE_LEN);
assert(devShadowQueue_);
silentBuf_.cap_ = (format_pcm.containerSize >> 3) * format_pcm.numChannels *
sampleInfo_.framesPerBuf_;
silentBuf_.buf_ = new uint8_t[silentBuf_.cap_];
memset(silentBuf_.buf_, 0, silentBuf_.cap_);
silentBuf_.size_ = silentBuf_.cap_;
#ifdef ENABLE_LOG
std::string name = "play";
logFile_ = new AndroidLog(name);
#endif
}
AudioPlayer::~AudioPlayer() {
std::lock_guard<std::mutex> lock(stopMutex_);
// destroy buffer queue audio player object, and invalidate all associated
// interfaces
if (playerObjectItf_ != NULL) {
(*playerObjectItf_)->Destroy(playerObjectItf_);
}
// Consume all non-completed audio buffers
sample_buf *buf = NULL;
while (devShadowQueue_->front(&buf)) {
buf->size_ = 0;
devShadowQueue_->pop();
if(buf != &silentBuf_) {
freeQueue_->push(buf);
}
}
delete devShadowQueue_;
while (playQueue_->front(&buf)) {
buf->size_ = 0;
playQueue_->pop();
freeQueue_->push(buf);
}
// destroy output mix object, and invalidate all associated interfaces
if (outputMixObjectItf_) {
(*outputMixObjectItf_)->Destroy(outputMixObjectItf_);
}
delete[] silentBuf_.buf_;
}
void AudioPlayer::SetBufQueue(AudioQueue *playQ, AudioQueue *freeQ) {
playQueue_ = playQ;
freeQueue_ = freeQ;
}
SLresult AudioPlayer::Start(void) {
SLuint32 state;
SLresult result = (*playItf_)->GetPlayState(playItf_, &state);
if (result != SL_RESULT_SUCCESS) {
return SL_BOOLEAN_FALSE;
}
if (state == SL_PLAYSTATE_PLAYING) {
return SL_BOOLEAN_TRUE;
}
result = (*playItf_)->SetPlayState(playItf_, SL_PLAYSTATE_STOPPED);
SLASSERT(result);
result =
(*playBufferQueueItf_)
->Enqueue(playBufferQueueItf_, silentBuf_.buf_, silentBuf_.size_);
SLASSERT(result);
devShadowQueue_->push(&silentBuf_);
result = (*playItf_)->SetPlayState(playItf_, SL_PLAYSTATE_PLAYING);
SLASSERT(result);
return SL_BOOLEAN_TRUE;
}
void AudioPlayer::Stop(void) {
SLuint32 state;
SLresult result = (*playItf_)->GetPlayState(playItf_, &state);
SLASSERT(result);
if (state == SL_PLAYSTATE_STOPPED) return;
std::lock_guard<std::mutex> lock(stopMutex_);
result = (*playItf_)->SetPlayState(playItf_, SL_PLAYSTATE_STOPPED);
SLASSERT(result);
(*playBufferQueueItf_)->Clear(playBufferQueueItf_);
#ifdef ENABLE_LOG
if (logFile_) {
delete logFile_;
logFile_ = nullptr;
}
#endif
}
void AudioPlayer::RegisterCallback(ENGINE_CALLBACK cb, void *ctx) {
callback_ = cb;
ctx_ = ctx;
}
uint32_t AudioPlayer::dbgGetDevBufCount(void) {
return (devShadowQueue_->size());
}

View File

@@ -0,0 +1,55 @@
/*
* Copyright 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef NATIVE_AUDIO_AUDIO_PLAYER_H
#define NATIVE_AUDIO_AUDIO_PLAYER_H
#include <sys/types.h>
#include "audio_common.h"
#include "buf_manager.h"
#include "debug_utils.h"
class AudioPlayer {
// buffer queue player interfaces
SLObjectItf outputMixObjectItf_;
SLObjectItf playerObjectItf_;
SLPlayItf playItf_;
SLAndroidSimpleBufferQueueItf playBufferQueueItf_;
SampleFormat sampleInfo_;
AudioQueue *freeQueue_; // user
AudioQueue *playQueue_; // user
AudioQueue *devShadowQueue_; // owner
ENGINE_CALLBACK callback_;
void *ctx_;
sample_buf silentBuf_;
#ifdef ENABLE_LOG
AndroidLog *logFile_;
#endif
std::mutex stopMutex_;
public:
explicit AudioPlayer(SampleFormat *sampleFormat, SLEngineItf engine);
~AudioPlayer();
void SetBufQueue(AudioQueue *playQ, AudioQueue *freeQ);
SLresult Start(void);
void Stop(void);
void ProcessSLCallback(SLAndroidSimpleBufferQueueItf bq);
uint32_t dbgGetDevBufCount(void);
void RegisterCallback(ENGINE_CALLBACK cb, void *ctx);
};
#endif // NATIVE_AUDIO_AUDIO_PLAYER_H

View File

@@ -0,0 +1,213 @@
/*
* Copyright 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <cstring>
#include <cstdlib>
#include "audio_recorder.h"
/*
* bqRecorderCallback(): called for every buffer is full;
* pass directly to handler
*/
void bqRecorderCallback(SLAndroidSimpleBufferQueueItf bq, void *rec) {
(static_cast<AudioRecorder *>(rec))->ProcessSLCallback(bq);
}
void AudioRecorder::ProcessSLCallback(SLAndroidSimpleBufferQueueItf bq) {
#ifdef ENABLE_LOG
recLog_->logTime();
#endif
assert(bq == recBufQueueItf_);
sample_buf *dataBuf = NULL;
devShadowQueue_->front(&dataBuf);
devShadowQueue_->pop();
dataBuf->size_ = dataBuf->cap_; // device only calls us when it is really
// full
callback_(ctx_, ENGINE_SERVICE_MSG_RECORDED_AUDIO_AVAILABLE, dataBuf);
recQueue_->push(dataBuf);
sample_buf *freeBuf;
while (freeQueue_->front(&freeBuf) && devShadowQueue_->push(freeBuf)) {
freeQueue_->pop();
SLresult result = (*bq)->Enqueue(bq, freeBuf->buf_, freeBuf->cap_);
SLASSERT(result);
}
++audioBufCount;
// should leave the device to sleep to save power if no buffers
if (devShadowQueue_->size() == 0) {
(*recItf_)->SetRecordState(recItf_, SL_RECORDSTATE_STOPPED);
}
}
AudioRecorder::AudioRecorder(SampleFormat *sampleFormat, SLEngineItf slEngine)
: freeQueue_(nullptr),
recQueue_(nullptr),
devShadowQueue_(nullptr),
callback_(nullptr) {
SLresult result;
sampleInfo_ = *sampleFormat;
SLAndroidDataFormat_PCM_EX format_pcm;
ConvertToSLSampleFormat(&format_pcm, &sampleInfo_);
// configure audio source
SLDataLocator_IODevice loc_dev = {SL_DATALOCATOR_IODEVICE,
SL_IODEVICE_AUDIOINPUT,
SL_DEFAULTDEVICEID_AUDIOINPUT, NULL};
SLDataSource audioSrc = {&loc_dev, NULL};
// configure audio sink
SLDataLocator_AndroidSimpleBufferQueue loc_bq = {
SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, DEVICE_SHADOW_BUFFER_QUEUE_LEN};
SLDataSink audioSnk = {&loc_bq, &format_pcm};
// create audio recorder
// (requires the RECORD_AUDIO permission)
const SLInterfaceID id[2] = {SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
SL_IID_ANDROIDCONFIGURATION};
const SLboolean req[2] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE};
result = (*slEngine)->CreateAudioRecorder(
slEngine, &recObjectItf_, &audioSrc, &audioSnk,
sizeof(id) / sizeof(id[0]), id, req);
SLASSERT(result);
// Configure the voice recognition preset which has no
// signal processing for lower latency.
SLAndroidConfigurationItf inputConfig;
result = (*recObjectItf_)
->GetInterface(recObjectItf_, SL_IID_ANDROIDCONFIGURATION,
&inputConfig);
if (SL_RESULT_SUCCESS == result) {
SLuint32 presetValue = SL_ANDROID_RECORDING_PRESET_VOICE_RECOGNITION;
(*inputConfig)
->SetConfiguration(inputConfig, SL_ANDROID_KEY_RECORDING_PRESET,
&presetValue, sizeof(SLuint32));
}
result = (*recObjectItf_)->Realize(recObjectItf_, SL_BOOLEAN_FALSE);
SLASSERT(result);
result =
(*recObjectItf_)->GetInterface(recObjectItf_, SL_IID_RECORD, &recItf_);
SLASSERT(result);
result = (*recObjectItf_)
->GetInterface(recObjectItf_, SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
&recBufQueueItf_);
SLASSERT(result);
result = (*recBufQueueItf_)
->RegisterCallback(recBufQueueItf_, bqRecorderCallback, this);
SLASSERT(result);
devShadowQueue_ = new AudioQueue(DEVICE_SHADOW_BUFFER_QUEUE_LEN);
assert(devShadowQueue_);
#ifdef ENABLE_LOG
std::string name = "rec";
recLog_ = new AndroidLog(name);
#endif
}
SLboolean AudioRecorder::Start(void) {
if (!freeQueue_ || !recQueue_ || !devShadowQueue_) {
LOGE("====NULL poiter to Start(%p, %p, %p)", freeQueue_, recQueue_,
devShadowQueue_);
return SL_BOOLEAN_FALSE;
}
audioBufCount = 0;
SLresult result;
// in case already recording, stop recording and clear buffer queue
result = (*recItf_)->SetRecordState(recItf_, SL_RECORDSTATE_STOPPED);
SLASSERT(result);
result = (*recBufQueueItf_)->Clear(recBufQueueItf_);
SLASSERT(result);
for (int i = 0; i < RECORD_DEVICE_KICKSTART_BUF_COUNT; i++) {
sample_buf *buf = NULL;
if (!freeQueue_->front(&buf)) {
LOGE("=====OutOfFreeBuffers @ startingRecording @ (%d)", i);
break;
}
freeQueue_->pop();
assert(buf->buf_ && buf->cap_ && !buf->size_);
result = (*recBufQueueItf_)->Enqueue(recBufQueueItf_, buf->buf_, buf->cap_);
SLASSERT(result);
devShadowQueue_->push(buf);
}
result = (*recItf_)->SetRecordState(recItf_, SL_RECORDSTATE_RECORDING);
SLASSERT(result);
return (result == SL_RESULT_SUCCESS ? SL_BOOLEAN_TRUE : SL_BOOLEAN_FALSE);
}
SLboolean AudioRecorder::Stop(void) {
// in case already recording, stop recording and clear buffer queue
SLuint32 curState;
SLresult result = (*recItf_)->GetRecordState(recItf_, &curState);
SLASSERT(result);
if (curState == SL_RECORDSTATE_STOPPED) {
return SL_BOOLEAN_TRUE;
}
result = (*recItf_)->SetRecordState(recItf_, SL_RECORDSTATE_STOPPED);
SLASSERT(result);
result = (*recBufQueueItf_)->Clear(recBufQueueItf_);
SLASSERT(result);
#ifdef ENABLE_LOG
recLog_->flush();
#endif
return SL_BOOLEAN_TRUE;
}
AudioRecorder::~AudioRecorder() {
// destroy audio recorder object, and invalidate all associated interfaces
if (recObjectItf_ != NULL) {
(*recObjectItf_)->Destroy(recObjectItf_);
}
if (devShadowQueue_) {
sample_buf *buf = NULL;
while (devShadowQueue_->front(&buf)) {
devShadowQueue_->pop();
freeQueue_->push(buf);
}
delete (devShadowQueue_);
}
#ifdef ENABLE_LOG
if (recLog_) {
delete recLog_;
}
#endif
}
void AudioRecorder::SetBufQueues(AudioQueue *freeQ, AudioQueue *recQ) {
assert(freeQ && recQ);
freeQueue_ = freeQ;
recQueue_ = recQ;
}
void AudioRecorder::RegisterCallback(ENGINE_CALLBACK cb, void *ctx) {
callback_ = cb;
ctx_ = ctx;
}
int32_t AudioRecorder::dbgGetDevBufCount(void) {
return devShadowQueue_->size();
}

View File

@@ -24,32 +24,32 @@
#include "debug_utils.h"
class AudioRecorder {
SLObjectItf recObjectItf_;
SLRecordItf recItf_;
SLAndroidSimpleBufferQueueItf recBufQueueItf_;
SLObjectItf recObjectItf_;
SLRecordItf recItf_;
SLAndroidSimpleBufferQueueItf recBufQueueItf_;
SampleFormat sampleInfo_;
AudioQueue *freeQueue_; // user
AudioQueue *recQueue_; // user
AudioQueue *devShadowQueue_; // owner
uint32_t audioBufCount;
SampleFormat sampleInfo_;
AudioQueue *freeQueue_; // user
AudioQueue *recQueue_; // user
AudioQueue *devShadowQueue_; // owner
uint32_t audioBufCount;
ENGINE_CALLBACK callback_;
void *ctx_;
ENGINE_CALLBACK callback_;
void *ctx_;
public:
explicit AudioRecorder(SampleFormat *, SLEngineItf engineEngine);
~AudioRecorder();
SLboolean Start(void);
SLboolean Stop(void);
void SetBufQueues(AudioQueue *freeQ, AudioQueue *recQ);
void ProcessSLCallback(SLAndroidSimpleBufferQueueItf bq);
void RegisterCallback(ENGINE_CALLBACK cb, void *ctx);
int32_t dbgGetDevBufCount(void);
public:
explicit AudioRecorder(SampleFormat *, SLEngineItf engineEngine);
~AudioRecorder();
SLboolean Start(void);
SLboolean Stop(void);
void SetBufQueues(AudioQueue *freeQ, AudioQueue *recQ);
void ProcessSLCallback(SLAndroidSimpleBufferQueueItf bq);
void RegisterCallback(ENGINE_CALLBACK cb, void *ctx);
int32_t dbgGetDevBufCount(void);
#ifdef ENABLE_LOG
AndroidLog *recLog_;
#ifdef ENABLE_LOG
AndroidLog *recLog_;
#endif
};
#endif //NATIVE_AUDIO_AUDIO_RECORDER_H
#endif // NATIVE_AUDIO_AUDIO_RECORDER_H

View File

@@ -0,0 +1,202 @@
/*
* Copyright 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef NATIVE_AUDIO_BUF_MANAGER_H
#define NATIVE_AUDIO_BUF_MANAGER_H
#include <sys/types.h>
#include <SLES/OpenSLES.h>
#include <atomic>
#include <cassert>
#include <memory>
#include <limits>
#ifndef CACHE_ALIGN
#define CACHE_ALIGN 64
#endif
/*
* ProducerConsumerQueue, borrowed from Ian NiLewis
*/
template <typename T>
class ProducerConsumerQueue {
public:
explicit ProducerConsumerQueue(int size)
: ProducerConsumerQueue(size, new T[size]) {}
explicit ProducerConsumerQueue(int size, T* buffer)
: size_(size), buffer_(buffer) {
// This is necessary because we depend on twos-complement wraparound
// to take care of overflow conditions.
assert(size < std::numeric_limits<int>::max());
}
bool push(const T& item) {
return push([&](T* ptr) -> bool {
*ptr = item;
return true;
});
}
// get() is idempotent between calls to commit().
T* getWriteablePtr() {
T* result = nullptr;
bool check __attribute__((unused)); //= false;
check = push([&](T* head) -> bool {
result = head;
return false; // don't increment
});
// if there's no space, result should not have been set, and vice versa
assert(check == (result != nullptr));
return result;
}
bool commitWriteablePtr(T* ptr) {
bool result = push([&](T* head) -> bool {
// this writer func does nothing, because we assume that the caller
// has already written to *ptr after acquiring it from a call to get().
// So just double-check that ptr is actually at the write head, and
// return true to indicate that it's safe to advance.
// if this isn't the same pointer we got from a call to get(), then
// something has gone terribly wrong. Either there was an intervening
// call to push() or commit(), or the pointer is spurious.
assert(ptr == head);
return true;
});
return result;
}
// writer() can return false, which indicates that the caller
// of push() changed its mind while writing (e.g. ran out of bytes)
template <typename F>
bool push(const F& writer) {
bool result = false;
int readptr = read_.load(std::memory_order_acquire);
int writeptr = write_.load(std::memory_order_relaxed);
// note that while readptr and writeptr will eventually
// wrap around, taking their difference is still valid as
// long as size_ < MAXINT.
int space = size_ - (int)(writeptr - readptr);
if (space >= 1) {
result = true;
// writer
if (writer(buffer_.get() + (writeptr % size_))) {
++writeptr;
write_.store(writeptr, std::memory_order_release);
}
}
return result;
}
// front out the queue, but not pop-out
bool front(T* out_item) {
return front([&](T* ptr) -> bool {
*out_item = *ptr;
return true;
});
}
void pop(void) {
int readptr = read_.load(std::memory_order_relaxed);
++readptr;
read_.store(readptr, std::memory_order_release);
}
template <typename F>
bool front(const F& reader) {
bool result = false;
int writeptr = write_.load(std::memory_order_acquire);
int readptr = read_.load(std::memory_order_relaxed);
// As above, wraparound is ok
int available = (int)(writeptr - readptr);
if (available >= 1) {
result = true;
reader(buffer_.get() + (readptr % size_));
}
return result;
}
uint32_t size(void) {
int writeptr = write_.load(std::memory_order_acquire);
int readptr = read_.load(std::memory_order_relaxed);
return (uint32_t)(writeptr - readptr);
}
private:
int size_;
std::unique_ptr<T> buffer_;
// forcing cache line alignment to eliminate false sharing of the
// frequently-updated read and write pointers. The object is to never
// let these get into the "shared" state where they'd cause a cache miss
// for every write.
alignas(CACHE_ALIGN) std::atomic<int> read_{0};
alignas(CACHE_ALIGN) std::atomic<int> write_{0};
};
struct sample_buf {
uint8_t* buf_; // audio sample container
uint32_t cap_; // buffer capacity in byte
uint32_t size_; // audio sample size (n buf) in byte
};
using AudioQueue = ProducerConsumerQueue<sample_buf*>;
__inline__ void releaseSampleBufs(sample_buf* bufs, uint32_t& count) {
if (!bufs || !count) {
return;
}
for (uint32_t i = 0; i < count; i++) {
if (bufs[i].buf_) delete[] bufs[i].buf_;
}
delete[] bufs;
}
__inline__ sample_buf* allocateSampleBufs(uint32_t count, uint32_t sizeInByte) {
if (count <= 0 || sizeInByte <= 0) {
return nullptr;
}
sample_buf* bufs = new sample_buf[count];
assert(bufs);
memset(bufs, 0, sizeof(sample_buf) * count);
uint32_t allocSize = (sizeInByte + 3) & ~3; // padding to 4 bytes aligned
uint32_t i;
for (i = 0; i < count; i++) {
bufs[i].buf_ = new uint8_t[allocSize];
if (bufs[i].buf_ == nullptr) {
LOGW("====Requesting %d buffers, allocated %d in %s", count, i,
__FUNCTION__);
break;
}
bufs[i].cap_ = sizeInByte;
bufs[i].size_ = 0; // 0 data in it
}
if (i < 2) {
releaseSampleBufs(bufs, i);
bufs = nullptr;
}
count = i;
return bufs;
}
#endif // NATIVE_AUDIO_BUF_MANAGER_H

View File

@@ -0,0 +1,104 @@
/*
* Copyright 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <cstdio>
#include <sys/stat.h>
#include "debug_utils.h"
#include "android_debug.h"
#include <inttypes.h>
static const char* FILE_PREFIX = "/sdcard/data/audio";
volatile uint32_t AndroidLog::fileIdx_ = 0;
AndroidLog::AndroidLog() : fp_(NULL), prevTick_(static_cast<uint64_t>(0)) {
fileName_ = FILE_PREFIX;
openFile();
}
AndroidLog::AndroidLog(std::string& file_name)
: fp_(NULL), prevTick_(static_cast<uint64_t>(0)) {
fileName_ = std::string(FILE_PREFIX) + std::string("_") + file_name;
openFile();
}
AndroidLog::~AndroidLog() { flush(); }
void AndroidLog::flush() {
if (fp_) {
fflush(fp_);
fclose(fp_);
fp_ = NULL;
}
prevTick_ = static_cast<uint64_t>(0);
}
void AndroidLog::log(void* buf, uint32_t size) {
Lock fileLock(&mutex_);
if (!buf || !size) return;
if (fp_ || openFile()) {
fwrite(buf, size, 1, fp_);
}
}
void AndroidLog::log(const char* fmt, ...) {
Lock fileLock(&mutex_);
if (!fmt) {
return;
}
if (fp_ || openFile()) {
va_list vp;
va_start(vp, fmt);
vfprintf(fp_, fmt, vp);
va_end(vp);
}
}
FILE* AndroidLog::openFile() {
Lock fileLock(&mutex_);
if (fp_) {
return fp_;
}
char fileName[64];
sprintf(fileName, "%s_%d", fileName_.c_str(), AndroidLog::fileIdx_++);
fp_ = fopen(fileName, "wb");
if (fp_ == NULL) {
LOGE("====failed to open file %s", fileName);
}
return fp_;
}
void AndroidLog::logTime() {
if (prevTick_ == static_cast<uint64_t>(0)) {
/*
* init counter, bypass the first one
*/
prevTick_ = getCurrentTicks();
return;
}
uint64_t curTick = getCurrentTicks();
uint64_t delta = curTick - prevTick_;
log("%" PRIu64 " %" PRIu64 "\n", curTick, delta);
prevTick_ = curTick;
}
uint64_t AndroidLog::getCurrentTicks() {
struct timeval Time;
gettimeofday(&Time, NULL);
return (static_cast<uint64_t>(1000000) * Time.tv_sec + Time.tv_usec);
}

View File

@@ -19,7 +19,6 @@
#include <mutex>
#include <string>
/*
* debug_write_file()
* Write given data to a file as binary file. File name is
@@ -27,36 +26,36 @@
* requirement: must have /sdcard/data already created on android device
*/
class Lock {
public:
explicit Lock(std::recursive_mutex* mtx) {
mutex_ = mtx;
mutex_->lock();
}
~Lock() {
mutex_->unlock();
}
private:
std::recursive_mutex *mutex_;
public:
explicit Lock(std::recursive_mutex* mtx) {
mutex_ = mtx;
mutex_->lock();
}
~Lock() { mutex_->unlock(); }
private:
std::recursive_mutex* mutex_;
};
class AndroidLog {
public:
AndroidLog();
AndroidLog(std::string &fileName);
~AndroidLog();
void log(void* buf, uint32_t size);
void log(const char* fmt, ...);
void logTime();
void flush();
static volatile uint32_t fileIdx_;
private:
uint64_t getCurrentTicks();
FILE* fp_;
FILE* openFile();
uint64_t prevTick_; //Tick in milisecond
std::recursive_mutex mutex_;
std::string fileName_;
public:
AndroidLog();
AndroidLog(std::string& fileName);
~AndroidLog();
void log(void* buf, uint32_t size);
void log(const char* fmt, ...);
void logTime();
void flush();
static volatile uint32_t fileIdx_;
private:
uint64_t getCurrentTicks();
FILE* fp_;
FILE* openFile();
uint64_t prevTick_; // Tick in milisecond
std::recursive_mutex mutex_;
std::string fileName_;
};
void debug_write_file(void* buf, uint32_t size);
#endif //NATIVE_AUDIO_DEBUG_UTILS_H
#endif // NATIVE_AUDIO_DEBUG_UTILS_H

View File

@@ -0,0 +1,54 @@
/*
* Copyright 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef JNI_INTERFACE_H
#define JNI_INTERFACE_H
#include <jni.h>
#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT void JNICALL Java_com_google_sample_echo_MainActivity_createSLEngine(
JNIEnv *env, jclass, jint, jint, jlong delayInMs, jfloat decay);
JNIEXPORT void JNICALL Java_com_google_sample_echo_MainActivity_deleteSLEngine(
JNIEnv *env, jclass type);
JNIEXPORT jboolean JNICALL
Java_com_google_sample_echo_MainActivity_createSLBufferQueueAudioPlayer(
JNIEnv *env, jclass);
JNIEXPORT void JNICALL
Java_com_google_sample_echo_MainActivity_deleteSLBufferQueueAudioPlayer(
JNIEnv *env, jclass type);
JNIEXPORT jboolean JNICALL
Java_com_google_sample_echo_MainActivity_createAudioRecorder(JNIEnv *env,
jclass type);
JNIEXPORT void JNICALL
Java_com_google_sample_echo_MainActivity_deleteAudioRecorder(JNIEnv *env,
jclass type);
JNIEXPORT void JNICALL
Java_com_google_sample_echo_MainActivity_startPlay(JNIEnv *env, jclass type);
JNIEXPORT void JNICALL
Java_com_google_sample_echo_MainActivity_stopPlay(JNIEnv *env, jclass type);
JNIEXPORT jboolean JNICALL
Java_com_google_sample_echo_MainActivity_configureEcho(JNIEnv *env, jclass type,
jint delayInMs,
jfloat decay);
#ifdef __cplusplus
}
#endif
#endif // JNI_INTERFACE_H

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015 The Android Open Source Project
* Copyright 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,40 +16,123 @@
package com.google.sample.echo;
import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioRecord;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
public static final String AUDIO_SAMPLE = "AUDIO_SAMPLE:";
TextView status_view;
String nativeSampleRate;
String nativeSampleBufSize;
boolean supportRecording;
Boolean isPlaying;
public class MainActivity extends Activity
implements ActivityCompat.OnRequestPermissionsResultCallback {
private static final int AUDIO_ECHO_REQUEST = 0;
private Button controlButton;
private TextView statusView;
private String nativeSampleRate;
private String nativeSampleBufSize;
private SeekBar delaySeekBar;
private TextView curDelayTV;
private int echoDelayProgress;
private SeekBar decaySeekBar;
private TextView curDecayTV;
private float echoDecayProgress;
private boolean supportRecording;
private Boolean isPlaying = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
status_view = (TextView)findViewById(R.id.statusView);
controlButton = (Button)findViewById((R.id.capture_control_button));
statusView = (TextView)findViewById(R.id.statusView);
queryNativeAudioParameters();
delaySeekBar = (SeekBar)findViewById(R.id.delaySeekBar);
curDelayTV = (TextView)findViewById(R.id.curDelay);
echoDelayProgress = delaySeekBar.getProgress() * 1000 / delaySeekBar.getMax();
delaySeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
float curVal = (float)progress / delaySeekBar.getMax();
curDelayTV.setText(String.format("%s", curVal));
setSeekBarPromptPosition(delaySeekBar, curDelayTV);
if (!fromUser) return;
echoDelayProgress = progress * 1000 / delaySeekBar.getMax();
configureEcho(echoDelayProgress, echoDecayProgress);
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {}
});
delaySeekBar.post(new Runnable() {
@Override
public void run() {
setSeekBarPromptPosition(delaySeekBar, curDelayTV);
}
});
decaySeekBar = (SeekBar)findViewById(R.id.decaySeekBar);
curDecayTV = (TextView)findViewById(R.id.curDecay);
echoDecayProgress = (float)decaySeekBar.getProgress() / decaySeekBar.getMax();
decaySeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
float curVal = (float)progress / seekBar.getMax();
curDecayTV.setText(String.format("%s", curVal));
setSeekBarPromptPosition(decaySeekBar, curDecayTV);
if (!fromUser)
return;
echoDecayProgress = curVal;
configureEcho(echoDelayProgress, echoDecayProgress);
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {}
});
decaySeekBar.post(new Runnable() {
@Override
public void run() {
setSeekBarPromptPosition(decaySeekBar, curDecayTV);
}
});
// initialize native audio system
updateNativeAudioUI();
if (supportRecording) {
createSLEngine(Integer.parseInt(nativeSampleRate), Integer.parseInt(nativeSampleBufSize));
createSLEngine(
Integer.parseInt(nativeSampleRate),
Integer.parseInt(nativeSampleBufSize),
echoDelayProgress,
echoDecayProgress);
}
isPlaying = false;
}
private void setSeekBarPromptPosition(SeekBar seekBar, TextView label) {
float thumbX = (float)seekBar.getProgress()/ seekBar.getMax() *
seekBar.getWidth() + seekBar.getX();
label.setX(thumbX - label.getWidth()/2.0f);
}
@Override
protected void onDestroy() {
if (supportRecording) {
@@ -84,81 +167,138 @@ public class MainActivity extends Activity {
return super.onOptionsItemSelected(item);
}
public void startEcho(View view) {
if(!supportRecording || isPlaying) {
private void startEcho() {
if(!supportRecording){
return;
}
if(!createSLBufferQueueAudioPlayer()) {
status_view.setText("Failed to create Audio Player");
return;
}
if(!createAudioRecorder()) {
if (!isPlaying) {
if(!createSLBufferQueueAudioPlayer()) {
statusView.setText(getString(R.string.player_error_msg));
return;
}
if(!createAudioRecorder()) {
deleteSLBufferQueueAudioPlayer();
statusView.setText(getString(R.string.recorder_error_msg));
return;
}
startPlay(); // startPlay() triggers startRecording()
statusView.setText(getString(R.string.echoing_status_msg));
} else {
stopPlay(); // stopPlay() triggers stopRecording()
updateNativeAudioUI();
deleteAudioRecorder();
deleteSLBufferQueueAudioPlayer();
status_view.setText("Failed to create Audio Recorder");
}
isPlaying = !isPlaying;
controlButton.setText(getString(isPlaying ?
R.string.cmd_stop_echo: R.string.cmd_start_echo));
}
public void onEchoClick(View view) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) !=
PackageManager.PERMISSION_GRANTED) {
statusView.setText(getString(R.string.request_permission_status_msg));
ActivityCompat.requestPermissions(
this,
new String[] { Manifest.permission.RECORD_AUDIO },
AUDIO_ECHO_REQUEST);
return;
}
startPlay(); //this must include startRecording()
isPlaying = true;
status_view.setText("Engine Echoing ....");
startEcho();
}
public void stopEcho(View view) {
if(!supportRecording || !isPlaying) {
return;
}
stopPlay(); //this must include stopRecording()
updateNativeAudioUI();
deleteSLBufferQueueAudioPlayer();
deleteAudioRecorder();
isPlaying = false;
}
public void getLowLatencyParameters(View view) {
updateNativeAudioUI();
return;
}
private void queryNativeAudioParameters() {
supportRecording = true;
AudioManager myAudioMgr = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
if(myAudioMgr == null) {
supportRecording = false;
return;
}
nativeSampleRate = myAudioMgr.getProperty(AudioManager.PROPERTY_OUTPUT_SAMPLE_RATE);
nativeSampleBufSize =myAudioMgr.getProperty(AudioManager.PROPERTY_OUTPUT_FRAMES_PER_BUFFER);
// hardcoded channel to mono: both sides -- C++ and Java sides
int recBufSize = AudioRecord.getMinBufferSize(
Integer.parseInt(nativeSampleRate),
AudioFormat.CHANNEL_IN_MONO,
AudioFormat.ENCODING_PCM_16BIT);
supportRecording = true;
if (recBufSize == AudioRecord.ERROR ||
recBufSize == AudioRecord.ERROR_BAD_VALUE) {
recBufSize == AudioRecord.ERROR_BAD_VALUE) {
supportRecording = false;
}
}
private void updateNativeAudioUI() {
if (!supportRecording) {
status_view.setText("Error: Audio recording is not supported");
statusView.setText(getString(R.string.mic_error_msg));
controlButton.setEnabled(false);
return;
}
status_view.setText("nativeSampleRate = " + nativeSampleRate + "\n" +
"nativeSampleBufSize = " + nativeSampleBufSize + "\n");
statusView.setText(getString(R.string.fast_audio_info_msg,
nativeSampleRate, nativeSampleBufSize));
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
/*
* if any permission failed, the sample could not play
*/
if (AUDIO_ECHO_REQUEST != requestCode) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
return;
}
if (grantResults.length != 1 ||
grantResults[0] != PackageManager.PERMISSION_GRANTED) {
/*
* When user denied permission, throw a Toast to prompt that RECORD_AUDIO
* is necessary; also display the status on UI
* Then application goes back to the original state: it behaves as if the button
* was not clicked. The assumption is that user will re-click the "start" button
* (to retry), or shutdown the app in normal way.
*/
statusView.setText(getString(R.string.permission_error_msg));
Toast.makeText(getApplicationContext(),
getString(R.string.permission_prompt_msg),
Toast.LENGTH_SHORT).show();
return;
}
/*
* When permissions are granted, we prompt the user the status. User would
* re-try the "start" button to perform the normal operation. This saves us the extra
* logic in code for async processing of the button listener.
*/
statusView.setText(getString(R.string.permission_granted_msg,getString(R.string.cmd_start_echo)));
// The callback runs on app's thread, so we are safe to resume the action
startEcho();
}
/*
* Loading our Libs
* Loading our lib
*/
static {
System.loadLibrary("echo");
}
/*
* jni function implementations...
* jni function declarations
*/
public static native void createSLEngine(int rate, int framesPerBuf);
public static native void deleteSLEngine();
static native void createSLEngine(int rate, int framesPerBuf,
long delayInMs, float decay);
static native void deleteSLEngine();
static native boolean configureEcho(int delayInMs, float decay);
static native boolean createSLBufferQueueAudioPlayer();
static native void deleteSLBufferQueueAudioPlayer();
public static native boolean createSLBufferQueueAudioPlayer();
public static native void deleteSLBufferQueueAudioPlayer();
public static native boolean createAudioRecorder();
public static native void deleteAudioRecorder();
public static native void startPlay();
public static native void stopPlay();
static native boolean createAudioRecorder();
static native void deleteAudioRecorder();
static native void startPlay();
static native void stopPlay();
}

View File

@@ -1,66 +0,0 @@
/*
* Copyright 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "audio_common.h"
void ConvertToSLSampleFormat(SLAndroidDataFormat_PCM_EX *pFormat,
SampleFormat* pSampleInfo_) {
assert(pFormat);
memset(pFormat, 0, sizeof(*pFormat));
pFormat->formatType = SL_DATAFORMAT_PCM;
if( pSampleInfo_->channels_ <= 1 ) {
pFormat->numChannels = 1;
pFormat->channelMask = SL_SPEAKER_FRONT_CENTER;
} else {
pFormat->numChannels = 2;
pFormat->channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT;
}
pFormat->sampleRate = pSampleInfo_->sampleRate_;
pFormat->endianness = SL_BYTEORDER_LITTLEENDIAN;
pFormat->bitsPerSample = pSampleInfo_->pcmFormat_;
pFormat->containerSize = pSampleInfo_->pcmFormat_;
/*
* fixup for android extended representations...
*/
pFormat->representation = pSampleInfo_->representation_;
switch (pFormat->representation) {
case SL_ANDROID_PCM_REPRESENTATION_UNSIGNED_INT:
pFormat->bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_8;
pFormat->containerSize = SL_PCMSAMPLEFORMAT_FIXED_8;
pFormat->formatType = SL_ANDROID_DATAFORMAT_PCM_EX;
break;
case SL_ANDROID_PCM_REPRESENTATION_SIGNED_INT:
pFormat->bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_16; //supports 16, 24, and 32
pFormat->containerSize = SL_PCMSAMPLEFORMAT_FIXED_16;
pFormat->formatType = SL_ANDROID_DATAFORMAT_PCM_EX;
break;
case SL_ANDROID_PCM_REPRESENTATION_FLOAT:
pFormat->bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_32;
pFormat->containerSize = SL_PCMSAMPLEFORMAT_FIXED_32;
pFormat->formatType = SL_ANDROID_DATAFORMAT_PCM_EX;
break;
case 0:
break;
default:
assert(0);
}
}

View File

@@ -1,243 +0,0 @@
/*
* Copyright 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <cassert>
#include <cstring>
#include <jni.h>
#include <sys/types.h>
#include <SLES/OpenSLES.h>
#include "audio_common.h"
#include "audio_recorder.h"
#include "audio_player.h"
struct EchoAudioEngine {
SLmilliHertz fastPathSampleRate_;
uint32_t fastPathFramesPerBuf_;
uint16_t sampleChannels_;
uint16_t bitsPerSample_;
SLObjectItf slEngineObj_;
SLEngineItf slEngineItf_;
AudioRecorder *recorder_;
AudioPlayer *player_;
AudioQueue *freeBufQueue_; //Owner of the queue
AudioQueue *recBufQueue_; //Owner of the queue
sample_buf *bufs_;
uint32_t bufCount_;
uint32_t frameCount_;
};
static EchoAudioEngine engine;
bool EngineService(void* ctx, uint32_t msg, void* data );
extern "C" {
JNIEXPORT void JNICALL
Java_com_google_sample_echo_MainActivity_createSLEngine(JNIEnv *env, jclass, jint, jint);
JNIEXPORT void JNICALL
Java_com_google_sample_echo_MainActivity_deleteSLEngine(JNIEnv *env, jclass type);
JNIEXPORT jboolean JNICALL
Java_com_google_sample_echo_MainActivity_createSLBufferQueueAudioPlayer(JNIEnv *env, jclass);
JNIEXPORT void JNICALL
Java_com_google_sample_echo_MainActivity_deleteSLBufferQueueAudioPlayer(JNIEnv *env, jclass type);
JNIEXPORT jboolean JNICALL
Java_com_google_sample_echo_MainActivity_createAudioRecorder(JNIEnv *env, jclass type);
JNIEXPORT void JNICALL
Java_com_google_sample_echo_MainActivity_deleteAudioRecorder(JNIEnv *env, jclass type);
JNIEXPORT void JNICALL
Java_com_google_sample_echo_MainActivity_startPlay(JNIEnv *env, jclass type);
JNIEXPORT void JNICALL
Java_com_google_sample_echo_MainActivity_stopPlay(JNIEnv *env, jclass type);
}
JNIEXPORT void JNICALL
Java_com_google_sample_echo_MainActivity_createSLEngine(
JNIEnv *env, jclass type, jint sampleRate, jint framesPerBuf) {
SLresult result;
memset(&engine, 0, sizeof(engine));
engine.fastPathSampleRate_ = static_cast<SLmilliHertz>(sampleRate) * 1000;
engine.fastPathFramesPerBuf_ = static_cast<uint32_t>(framesPerBuf);
engine.sampleChannels_ = AUDIO_SAMPLE_CHANNELS;
engine.bitsPerSample_ = SL_PCMSAMPLEFORMAT_FIXED_16;
result = slCreateEngine(&engine.slEngineObj_, 0, NULL, 0, NULL, NULL);
SLASSERT(result);
result = (*engine.slEngineObj_)->Realize(engine.slEngineObj_, SL_BOOLEAN_FALSE);
SLASSERT(result);
result = (*engine.slEngineObj_)->GetInterface(engine.slEngineObj_, SL_IID_ENGINE, &engine.slEngineItf_);
SLASSERT(result);
// compute the RECOMMENDED fast audio buffer size:
// the lower latency required
// *) the smaller the buffer should be (adjust it here) AND
// *) the less buffering should be before starting player AFTER
// receiving the recordered buffer
// Adjust the bufSize here to fit your bill [before it busts]
uint32_t bufSize = engine.fastPathFramesPerBuf_ * engine.sampleChannels_
* engine.bitsPerSample_;
bufSize = (bufSize + 7) >> 3; // bits --> byte
engine.bufCount_ = BUF_COUNT;
engine.bufs_ = allocateSampleBufs(engine.bufCount_, bufSize);
assert(engine.bufs_);
engine.freeBufQueue_ = new AudioQueue (engine.bufCount_);
engine.recBufQueue_ = new AudioQueue (engine.bufCount_);
assert(engine.freeBufQueue_ && engine.recBufQueue_);
for(int i=0; i<engine.bufCount_; i++) {
engine.freeBufQueue_->push(&engine.bufs_[i]);
}
}
JNIEXPORT jboolean JNICALL
Java_com_google_sample_echo_MainActivity_createSLBufferQueueAudioPlayer(JNIEnv *env, jclass type) {
SampleFormat sampleFormat;
memset(&sampleFormat, 0, sizeof(sampleFormat));
sampleFormat.pcmFormat_ = (uint16_t)engine.bitsPerSample_;
sampleFormat.framesPerBuf_ = engine.fastPathFramesPerBuf_;
// SampleFormat.representation_ = SL_ANDROID_PCM_REPRESENTATION_SIGNED_INT;
sampleFormat.channels_ = (uint16_t)engine.sampleChannels_;
sampleFormat.sampleRate_ = engine.fastPathSampleRate_;
engine.player_ = new AudioPlayer(&sampleFormat, engine.slEngineItf_);
assert(engine.player_);
if(engine.player_ == nullptr)
return JNI_FALSE;
engine.player_->SetBufQueue(engine.recBufQueue_, engine.freeBufQueue_);
engine.player_->RegisterCallback(EngineService, (void*)&engine);
return JNI_TRUE;
}
JNIEXPORT void JNICALL
Java_com_google_sample_echo_MainActivity_deleteSLBufferQueueAudioPlayer(JNIEnv *env, jclass type) {
if(engine.player_) {
delete engine.player_;
engine.player_= nullptr;
}
}
JNIEXPORT jboolean JNICALL
Java_com_google_sample_echo_MainActivity_createAudioRecorder(JNIEnv *env, jclass type) {
SampleFormat sampleFormat;
memset(&sampleFormat, 0, sizeof(sampleFormat));
sampleFormat.pcmFormat_ = static_cast<uint16_t>(engine.bitsPerSample_);
// SampleFormat.representation_ = SL_ANDROID_PCM_REPRESENTATION_SIGNED_INT;
sampleFormat.channels_ = engine.sampleChannels_;
sampleFormat.sampleRate_ = engine.fastPathSampleRate_;
sampleFormat.framesPerBuf_ = engine.fastPathFramesPerBuf_;
engine.recorder_ = new AudioRecorder(&sampleFormat, engine.slEngineItf_);
if(!engine.recorder_) {
return JNI_FALSE;
}
engine.recorder_->SetBufQueues(engine.freeBufQueue_, engine.recBufQueue_);
engine.recorder_->RegisterCallback(EngineService, (void*)&engine);
return JNI_TRUE;
}
JNIEXPORT void JNICALL
Java_com_google_sample_echo_MainActivity_deleteAudioRecorder(JNIEnv *env, jclass type) {
if(engine.recorder_)
delete engine.recorder_;
engine.recorder_ = nullptr;
}
JNIEXPORT void JNICALL
Java_com_google_sample_echo_MainActivity_startPlay(JNIEnv *env, jclass type) {
engine.frameCount_ = 0;
/*
* start player: make it into waitForData state
*/
if(SL_BOOLEAN_FALSE == engine.player_->Start()){
LOGE("====%s failed", __FUNCTION__);
return;
}
engine.recorder_->Start();
}
JNIEXPORT void JNICALL
Java_com_google_sample_echo_MainActivity_stopPlay(JNIEnv *env, jclass type) {
engine.recorder_->Stop();
engine.player_ ->Stop();
delete engine.recorder_;
delete engine.player_;
engine.recorder_ = NULL;
engine.player_ = NULL;
}
JNIEXPORT void JNICALL
Java_com_google_sample_echo_MainActivity_deleteSLEngine(JNIEnv *env, jclass type) {
delete engine.recBufQueue_;
delete engine.freeBufQueue_;
releaseSampleBufs(engine.bufs_, engine.bufCount_);
if (engine.slEngineObj_ != NULL) {
(*engine.slEngineObj_)->Destroy(engine.slEngineObj_);
engine.slEngineObj_ = NULL;
engine.slEngineItf_ = NULL;
}
}
uint32_t dbgEngineGetBufCount(void) {
uint32_t count = engine.player_->dbgGetDevBufCount();
count += engine.recorder_->dbgGetDevBufCount();
count += engine.freeBufQueue_->size();
count += engine.recBufQueue_->size();
LOGE("Buf Disrtibutions: PlayerDev=%d, RecDev=%d, FreeQ=%d, "
"RecQ=%d",
engine.player_->dbgGetDevBufCount(),
engine.recorder_->dbgGetDevBufCount(),
engine.freeBufQueue_->size(),
engine.recBufQueue_->size());
if(count != engine.bufCount_) {
LOGE("====Lost Bufs among the queue(supposed = %d, found = %d)",
BUF_COUNT, count);
}
return count;
}
/*
* simple message passing for player/recorder to communicate with engine
*/
bool EngineService(void* ctx, uint32_t msg, void* data ) {
assert(ctx == &engine);
switch (msg) {
case ENGINE_SERVICE_MSG_KICKSTART_PLAYER:
engine.player_->PlayAudioBuffers(PLAY_KICKSTART_BUFFER_COUNT);
// we only allow it to call once, so tell caller do not call
// anymore
return false;
case ENGINE_SERVICE_MSG_RETRIEVE_DUMP_BUFS:
*(static_cast<uint32_t*>(data)) = dbgEngineGetBufCount();
break;
default:
assert(false);
return false;
}
return true;
}

View File

@@ -1,269 +0,0 @@
/*
* Copyright 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <cstdlib>
#include "audio_player.h"
/*
* Called by OpenSL SimpleBufferQueue for every audio buffer played
* directly pass thru to our handler.
* The regularity of this callback from openSL/Android System affects
* playback continuity. If it does not callback in the regular time
* slot, you are under big pressure for audio processing[here we do
* not do any filtering/mixing]. Callback from fast audio path are
* much more regular than other audio paths by my observation. If it
* very regular, you could buffer much less audio samples between
* recorder and player, hence lower latency.
*/
void bqPlayerCallback(SLAndroidSimpleBufferQueueItf bq, void *ctx) {
(static_cast<AudioPlayer *>(ctx))->ProcessSLCallback(bq);
}
void AudioPlayer::ProcessSLCallback(SLAndroidSimpleBufferQueueItf bq) {
#ifdef ENABLE_LOG
logFile_->logTime();
#endif
// retrieve the finished device buf and put onto the free queue
// so recorder could re-use it
sample_buf *buf;
if(!devShadowQueue_->front(&buf)) {
/*
* This should not happen: we got a callback,
* but we have no buffer in deviceShadowedQueue
* we lost buffers this way...(ERROR)
*/
if(callback_) {
uint32_t count;
callback_(ctx_, ENGINE_SERVICE_MSG_RETRIEVE_DUMP_BUFS, &count);
}
return;
}
devShadowQueue_->pop();
buf->size_ = 0;
freeQueue_->push(buf);
while(playQueue_->front(&buf) && devShadowQueue_->push(buf)) {
(*bq)->Enqueue(bq, buf->buf_, buf->size_);
playQueue_->pop();
}
}
AudioPlayer::AudioPlayer(SampleFormat *sampleFormat, SLEngineItf slEngine) :
playQueue_(nullptr),freeQueue_(nullptr), devShadowQueue_(nullptr),
callback_(nullptr)
{
SLresult result;
assert(sampleFormat);
sampleInfo_ = *sampleFormat;
result = (*slEngine)->CreateOutputMix(slEngine, &outputMixObjectItf_,
0, NULL, NULL);
SLASSERT(result);
// realize the output mix
result = (*outputMixObjectItf_)->Realize(outputMixObjectItf_, SL_BOOLEAN_FALSE);
SLASSERT(result);
// configure audio source
SLDataLocator_AndroidSimpleBufferQueue loc_bufq = {
SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE,
DEVICE_SHADOW_BUFFER_QUEUE_LEN };
SLAndroidDataFormat_PCM_EX format_pcm;
ConvertToSLSampleFormat(&format_pcm, &sampleInfo_);
SLDataSource audioSrc = {&loc_bufq, &format_pcm};
// configure audio sink
SLDataLocator_OutputMix loc_outmix = {SL_DATALOCATOR_OUTPUTMIX, outputMixObjectItf_};
SLDataSink audioSnk = {&loc_outmix, NULL};
/*
* create fast path audio player: SL_IID_BUFFERQUEUE and SL_IID_VOLUME interfaces ok,
* NO others!
*/
SLInterfaceID ids[2] = { SL_IID_BUFFERQUEUE, SL_IID_VOLUME};
SLboolean req[2] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE};
result = (*slEngine)->CreateAudioPlayer(slEngine, &playerObjectItf_, &audioSrc, &audioSnk,
sizeof(ids)/sizeof(ids[0]), ids, req);
SLASSERT(result);
// realize the player
result = (*playerObjectItf_)->Realize(playerObjectItf_, SL_BOOLEAN_FALSE);
SLASSERT(result);
// get the play interface
result = (*playerObjectItf_)->GetInterface(playerObjectItf_, SL_IID_PLAY, &playItf_);
SLASSERT(result);
// get the buffer queue interface
result = (*playerObjectItf_)->GetInterface(playerObjectItf_, SL_IID_BUFFERQUEUE,
&playBufferQueueItf_);
SLASSERT(result);
// register callback on the buffer queue
result = (*playBufferQueueItf_)->RegisterCallback(playBufferQueueItf_, bqPlayerCallback, this);
SLASSERT(result);
result = (*playItf_)->SetPlayState(playItf_, SL_PLAYSTATE_STOPPED);
SLASSERT(result);
// create an empty queue to track deviceQueue
devShadowQueue_ = new AudioQueue(DEVICE_SHADOW_BUFFER_QUEUE_LEN);
assert(devShadowQueue_);
#ifdef ENABLE_LOG
std::string name = "play";
logFile_ = new AndroidLog(name);
#endif
}
AudioPlayer::~AudioPlayer() {
// destroy buffer queue audio player object, and invalidate all associated interfaces
if (playerObjectItf_ != NULL) {
(*playerObjectItf_)->Destroy(playerObjectItf_);
}
if(devShadowQueue_) {
delete devShadowQueue_;
}
// destroy output mix object, and invalidate all associated interfaces
if (outputMixObjectItf_) {
(*outputMixObjectItf_)->Destroy(outputMixObjectItf_);
}
}
void AudioPlayer::SetBufQueue(AudioQueue *playQ, AudioQueue *freeQ) {
playQueue_ = playQ;
freeQueue_ = freeQ;
}
SLresult AudioPlayer::Start(void) {
SLuint32 state;
SLresult result = (*playItf_)->GetPlayState(playItf_, &state);
if (result != SL_RESULT_SUCCESS) {
return SL_BOOLEAN_FALSE;
}
if(state == SL_PLAYSTATE_PLAYING) {
return SL_BOOLEAN_TRUE;
}
result = (*playItf_)->SetPlayState(playItf_, SL_PLAYSTATE_STOPPED);
SLASSERT(result);
result = (*playItf_)->SetPlayState(playItf_, SL_PLAYSTATE_PLAYING);
SLASSERT(result);
// send pre-defined audio buffers to device
int i = PLAY_KICKSTART_BUFFER_COUNT;
while(i--) {
sample_buf *buf;
if(!playQueue_->front(&buf)) //we have buffers for sure
break;
if(SL_RESULT_SUCCESS !=
(*playBufferQueueItf_)->Enqueue(playBufferQueueItf_, buf, buf->size_))
{
LOGE("====failed to enqueue (%d) in %s", i, __FUNCTION__);
return SL_BOOLEAN_FALSE;
} else {
playQueue_->pop();
devShadowQueue_->push(buf);
}
}
return SL_BOOLEAN_TRUE;
}
void AudioPlayer::Stop(void) {
SLuint32 state;
SLresult result = (*playItf_)->GetPlayState(playItf_, &state);
SLASSERT(result);
if(state == SL_PLAYSTATE_STOPPED)
return;
result = (*playItf_)->SetPlayState(playItf_, SL_PLAYSTATE_STOPPED);
SLASSERT(result);
// Consume all non-completed audio buffers
sample_buf *buf = NULL;
while(devShadowQueue_->front(&buf)) {
buf->size_ = 0;
devShadowQueue_->pop();
freeQueue_->push(buf);
}
while(playQueue_->front(&buf)) {
buf->size_ = 0;
playQueue_->pop();
freeQueue_->push(buf);
}
#ifdef ENABLE_LOG
if (logFile_) {
delete logFile_;
logFile_ = nullptr;
}
#endif
}
void AudioPlayer::PlayAudioBuffers(int32_t count) {
if(!count) {
return;
}
while(count--) {
sample_buf *buf = NULL;
if(!playQueue_->front(&buf)) {
uint32_t totalBufCount;
callback_(ctx_, ENGINE_SERVICE_MSG_RETRIEVE_DUMP_BUFS,
&totalBufCount);
LOGE("====Run out of buffers in %s @(count = %d), totalBuf =%d",
__FUNCTION__, count, totalBufCount);
break;
}
if(!devShadowQueue_->push(buf)) {
break; // PlayerBufferQueue is full!!!
}
SLresult result = (*playBufferQueueItf_)->Enqueue(playBufferQueueItf_,
buf->buf_, buf->size_);
if(result != SL_RESULT_SUCCESS) {
if(callback_) {
uint32_t totalBufCount;
callback_(ctx_, ENGINE_SERVICE_MSG_RETRIEVE_DUMP_BUFS,
&totalBufCount);
}
LOGE("%s Error @( %p, %d ), result = %d", __FUNCTION__,
(void*)buf->buf_, buf->size_, result);
/*
* when this happens, a buffer is lost. Need to remove the buffer
* from top of the devShadowQueue. Since I do not have it now,
* just pop out the one that is being played right now. Afer a
* cycle it will be normal.
*/
devShadowQueue_->front(&buf), devShadowQueue_->pop();
freeQueue_->push(buf);
break;
}
playQueue_->pop(); // really pop out the buffer
}
}
void AudioPlayer::RegisterCallback(ENGINE_CALLBACK cb, void *ctx) {
callback_ = cb;
ctx_ = ctx;
}
uint32_t AudioPlayer::dbgGetDevBufCount(void) {
return (devShadowQueue_->size());
}

View File

@@ -1,55 +0,0 @@
/*
* Copyright 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef NATIVE_AUDIO_AUDIO_PLAYER_H
#define NATIVE_AUDIO_AUDIO_PLAYER_H
#include <sys/types.h>
#include <SLES/OpenSLES_Android.h>
#include "audio_common.h"
#include "buf_manager.h"
#include "debug_utils.h"
class AudioPlayer {
// buffer queue player interfaces
SLObjectItf outputMixObjectItf_;
SLObjectItf playerObjectItf_;
SLPlayItf playItf_;
SLAndroidSimpleBufferQueueItf playBufferQueueItf_;
SampleFormat sampleInfo_;
AudioQueue *freeQueue_; // user
AudioQueue *playQueue_; // user
AudioQueue *devShadowQueue_; // owner
ENGINE_CALLBACK callback_;
void *ctx_;
#ifdef ENABLE_LOG
AndroidLog *logFile_;
#endif
public:
explicit AudioPlayer(SampleFormat *sampleFormat, SLEngineItf engine);
~AudioPlayer();
void SetBufQueue(AudioQueue *playQ, AudioQueue *freeQ);
SLresult Start(void);
void Stop(void);
void ProcessSLCallback(SLAndroidSimpleBufferQueueItf bq);
uint32_t dbgGetDevBufCount(void);
void PlayAudioBuffers(int32_t count);
void RegisterCallback(ENGINE_CALLBACK cb, void *ctx);
};
#endif //NATIVE_AUDIO_AUDIO_PLAYER_H

View File

@@ -1,222 +0,0 @@
/*
* Copyright 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <cstring>
#include <cstdlib>
#include "audio_recorder.h"
/*
* bqRecorderCallback(): called for every buffer is full;
* pass directly to handler
*/
void bqRecorderCallback(SLAndroidSimpleBufferQueueItf bq, void *rec) {
(static_cast<AudioRecorder *>(rec))->ProcessSLCallback(bq);
}
void AudioRecorder::ProcessSLCallback(SLAndroidSimpleBufferQueueItf bq) {
#ifdef ENABLE_LOG
recLog_->logTime();
#endif
assert(bq == recBufQueueItf_);
sample_buf *dataBuf = NULL;
devShadowQueue_->front(&dataBuf);
devShadowQueue_->pop();
dataBuf->size_ = dataBuf->cap_; //device only calls us when it is really full
recQueue_->push(dataBuf);
sample_buf* freeBuf;
while (freeQueue_->front(&freeBuf) && devShadowQueue_->push(freeBuf)) {
freeQueue_->pop();
SLresult result = (*bq)->Enqueue(bq, freeBuf->buf_, freeBuf->cap_);
SLASSERT(result);
}
/*
* PLAY_KICKSTART_BUFFER_COUNT: # of buffers cached in the queue before
* STARTING player. it is defined in audio_common.h. Whatever buffered
* here is the part of the audio LATENCY! adjust to fit your bill [ until
* it busts ]
*/
if(++audioBufCount == PLAY_KICKSTART_BUFFER_COUNT && callback_) {
callback_(ctx_, ENGINE_SERVICE_MSG_KICKSTART_PLAYER, NULL);
}
// should leave the device to sleep to save power if no buffers
if(devShadowQueue_->size() == 0) {
(*recItf_)->SetRecordState(recItf_, SL_RECORDSTATE_STOPPED);
}
}
AudioRecorder::AudioRecorder(SampleFormat *sampleFormat, SLEngineItf slEngine) :
freeQueue_(nullptr), devShadowQueue_(nullptr), recQueue_(nullptr),
callback_(nullptr)
{
SLresult result;
sampleInfo_ = *sampleFormat;
SLAndroidDataFormat_PCM_EX format_pcm;
ConvertToSLSampleFormat(&format_pcm, &sampleInfo_);
// configure audio source
SLDataLocator_IODevice loc_dev = {SL_DATALOCATOR_IODEVICE,
SL_IODEVICE_AUDIOINPUT,
SL_DEFAULTDEVICEID_AUDIOINPUT,
NULL };
SLDataSource audioSrc = {&loc_dev, NULL };
// configure audio sink
SLDataLocator_AndroidSimpleBufferQueue loc_bq = {
SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE,
DEVICE_SHADOW_BUFFER_QUEUE_LEN };
SLDataSink audioSnk = {&loc_bq, &format_pcm};
// create audio recorder
// (requires the RECORD_AUDIO permission)
const SLInterfaceID id[2] = {SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
SL_IID_ANDROIDCONFIGURATION };
const SLboolean req[2] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE};
result = (*slEngine)->CreateAudioRecorder(slEngine,
&recObjectItf_,
&audioSrc,
&audioSnk,
sizeof(id)/sizeof(id[0]),
id, req);
SLASSERT(result);
// Configure the voice recognition preset which has no
// signal processing for lower latency.
SLAndroidConfigurationItf inputConfig;
result = (*recObjectItf_)->GetInterface(recObjectItf_,
SL_IID_ANDROIDCONFIGURATION,
&inputConfig);
if (SL_RESULT_SUCCESS == result) {
SLuint32 presetValue = SL_ANDROID_RECORDING_PRESET_VOICE_RECOGNITION;
(*inputConfig)->SetConfiguration(inputConfig,
SL_ANDROID_KEY_RECORDING_PRESET,
&presetValue,
sizeof(SLuint32));
}
result = (*recObjectItf_)->Realize(recObjectItf_, SL_BOOLEAN_FALSE);
SLASSERT(result);
result = (*recObjectItf_)->GetInterface(recObjectItf_,
SL_IID_RECORD, &recItf_);
SLASSERT(result);
result = (*recObjectItf_)->GetInterface(recObjectItf_,
SL_IID_ANDROIDSIMPLEBUFFERQUEUE, &recBufQueueItf_);
SLASSERT(result);
result = (*recBufQueueItf_)->RegisterCallback(recBufQueueItf_,
bqRecorderCallback, this);
SLASSERT(result);
devShadowQueue_ = new AudioQueue(DEVICE_SHADOW_BUFFER_QUEUE_LEN);
assert(devShadowQueue_);
#ifdef ENABLE_LOG
std::string name = "rec";
recLog_ = new AndroidLog(name);
#endif
}
SLboolean AudioRecorder::Start(void) {
if(!freeQueue_ || !recQueue_ || !devShadowQueue_) {
LOGE("====NULL poiter to Start(%p, %p, %p)", freeQueue_, recQueue_, devShadowQueue_);
return SL_BOOLEAN_FALSE;
}
audioBufCount = 0;
SLresult result;
// in case already recording, stop recording and clear buffer queue
result = (*recItf_)->SetRecordState(recItf_, SL_RECORDSTATE_STOPPED);
SLASSERT(result);
result = (*recBufQueueItf_)->Clear(recBufQueueItf_);
SLASSERT(result);
for(int i =0; i < RECORD_DEVICE_KICKSTART_BUF_COUNT; i++ ) {
sample_buf *buf = NULL;
if(!freeQueue_->front(&buf)) {
LOGE("=====OutOfFreeBuffers @ startingRecording @ (%d)", i);
break;
}
freeQueue_->pop();
assert(buf->buf_ && buf->cap_ && !buf->size_);
result = (*recBufQueueItf_)->Enqueue(recBufQueueItf_, buf->buf_,
buf->cap_);
SLASSERT(result);
devShadowQueue_->push(buf);
}
result = (*recItf_)->SetRecordState(recItf_, SL_RECORDSTATE_RECORDING);
SLASSERT(result);
return (result == SL_RESULT_SUCCESS? SL_BOOLEAN_TRUE:SL_BOOLEAN_FALSE);
}
SLboolean AudioRecorder::Stop(void) {
// in case already recording, stop recording and clear buffer queue
SLuint32 curState;
SLresult result = (*recItf_)->GetRecordState(recItf_, &curState);
SLASSERT(result);
if( curState == SL_RECORDSTATE_STOPPED) {
return SL_BOOLEAN_TRUE;
}
result = (*recItf_)->SetRecordState(recItf_, SL_RECORDSTATE_STOPPED);
SLASSERT(result);
result = (*recBufQueueItf_)->Clear(recBufQueueItf_);
SLASSERT(result);
sample_buf *buf = NULL;
while(devShadowQueue_->front(&buf)) {
devShadowQueue_->pop();
freeQueue_->push(buf);
}
#ifdef ENABLE_LOG
recLog_->flush();
#endif
return SL_BOOLEAN_TRUE;
}
AudioRecorder::~AudioRecorder() {
// destroy audio recorder object, and invalidate all associated interfaces
if (recObjectItf_ != NULL) {
(*recObjectItf_)->Destroy(recObjectItf_);
}
if(devShadowQueue_)
delete (devShadowQueue_);
#ifdef ENABLE_LOG
if(recLog_) {
delete recLog_;
}
#endif
}
void AudioRecorder::SetBufQueues(AudioQueue *freeQ, AudioQueue *recQ) {
assert(freeQ && recQ);
freeQueue_ = freeQ;
recQueue_ = recQ;
}
void AudioRecorder::RegisterCallback(ENGINE_CALLBACK cb, void *ctx) {
callback_ = cb;
ctx_ = ctx;
}
int32_t AudioRecorder::dbgGetDevBufCount(void) {
return devShadowQueue_->size();
}

View File

@@ -1,198 +0,0 @@
/*
* Copyright 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef NATIVE_AUDIO_BUF_MANAGER_H
#define NATIVE_AUDIO_BUF_MANAGER_H
#include <sys/types.h>
#include <SLES/OpenSLES.h>
#include <atomic>
#include <cassert>
#include <memory>
#include <limits>
#ifndef CACHE_ALIGN
#define CACHE_ALIGN 64
#endif
/*
* ProducerConsumerQueue, borrowed from Ian NiLewis
*/
template <typename T>
class ProducerConsumerQueue {
public:
explicit ProducerConsumerQueue(int size)
: ProducerConsumerQueue(size, new T[size]) {}
explicit ProducerConsumerQueue(int size, T* buffer)
: size_(size), buffer_(buffer) {
// This is necessary because we depend on twos-complement wraparound
// to take care of overflow conditions.
assert(size < std::numeric_limits<int>::max());
}
bool push(const T& item) {
return push([&](T* ptr) -> bool {*ptr = item; return true; });
}
// get() is idempotent between calls to commit().
T*getWriteablePtr() {
T* result = nullptr;
bool check __attribute__((unused));//= false;
check = push([&](T* head)-> bool {
result = head;
return false; // don't increment
});
// if there's no space, result should not have been set, and vice versa
assert(check == (result != nullptr));
return result;
}
bool commitWriteablePtr(T *ptr) {
bool result = push([&](T* head)-> bool {
// this writer func does nothing, because we assume that the caller
// has already written to *ptr after acquiring it from a call to get().
// So just double-check that ptr is actually at the write head, and
// return true to indicate that it's safe to advance.
// if this isn't the same pointer we got from a call to get(), then
// something has gone terribly wrong. Either there was an intervening
// call to push() or commit(), or the pointer is spurious.
assert(ptr == head);
return true;
});
return result;
}
// writer() can return false, which indicates that the caller
// of push() changed its mind while writing (e.g. ran out of bytes)
template<typename F>
bool push(const F& writer) {
bool result = false;
int readptr = read_.load(std::memory_order_acquire);
int writeptr = write_.load(std::memory_order_relaxed);
// note that while readptr and writeptr will eventually
// wrap around, taking their difference is still valid as
// long as size_ < MAXINT.
int space = size_ - (int)(writeptr - readptr);
if (space >= 1) {
result = true;
// writer
if (writer(buffer_.get() + (writeptr % size_))) {
++writeptr;
write_.store(writeptr, std::memory_order_release);
}
}
return result;
}
// front out the queue, but not pop-out
bool front(T* out_item) {
return front([&](T* ptr)-> bool {*out_item = *ptr; return true;});
}
void pop(void) {
int readptr = read_.load(std::memory_order_relaxed);
++readptr;
read_.store(readptr, std::memory_order_release);
}
template<typename F>
bool front(const F& reader) {
bool result = false;
int writeptr = write_.load(std::memory_order_acquire);
int readptr = read_.load(std::memory_order_relaxed);
// As above, wraparound is ok
int available = (int)(writeptr - readptr);
if (available >= 1) {
result = true;
reader(buffer_.get() + (readptr % size_));
}
return result;
}
uint32_t size(void) {
int writeptr = write_.load(std::memory_order_acquire);
int readptr = read_.load(std::memory_order_relaxed);
return (uint32_t)(writeptr - readptr);
}
private:
int size_;
std::unique_ptr<T> buffer_;
// forcing cache line alignment to eliminate false sharing of the
// frequently-updated read and write pointers. The object is to never
// let these get into the "shared" state where they'd cause a cache miss
// for every write.
alignas(CACHE_ALIGN) std::atomic<int> read_ { 0 };
alignas(CACHE_ALIGN) std::atomic<int> write_ { 0 };
};
struct sample_buf {
uint8_t *buf_; // audio sample container
uint32_t cap_; // buffer capacity in byte
uint32_t size_; // audio sample size (n buf) in byte
};
using AudioQueue = ProducerConsumerQueue<sample_buf*>;
__inline__ void releaseSampleBufs(sample_buf* bufs, uint32_t& count) {
if(!bufs || !count) {
return;
}
for(int i=0; i<count; i++) {
if(bufs[i].buf_) delete [] bufs[i].buf_;
}
delete [] bufs;
}
__inline__ sample_buf *allocateSampleBufs(uint32_t count, uint32_t sizeInByte){
if (count <= 0 || sizeInByte <= 0) {
return nullptr;
}
sample_buf* bufs = new sample_buf[count];
assert(bufs);
memset(bufs, 0, sizeof(sample_buf) * count);
uint32_t allocSize = (sizeInByte + 3) & ~3; // padding to 4 bytes aligned
uint32_t i ;
for(i =0; i < count; i++) {
bufs[i].buf_ = new uint8_t [allocSize];
if(bufs[i].buf_ == nullptr) {
LOGW("====Requesting %d buffers, allocated %d in %s", __FUNCTION__);
break;
}
bufs[i].cap_ = sizeInByte;
bufs[i].size_ = 0; //0 data in it
}
if(i < 2) {
releaseSampleBufs(bufs, i);
bufs = nullptr;
}
count = i;
return bufs;
}
#endif //NATIVE_AUDIO_BUF_MANAGER_H

View File

@@ -1,106 +0,0 @@
/*
* Copyright 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <cstdio>
#include <sys/stat.h>
#include "debug_utils.h"
#include "android_debug.h"
#include <inttypes.h>
static const char* FILE_PREFIX="/sdcard/data/audio";
volatile uint32_t AndroidLog::fileIdx_ = 0;
AndroidLog::AndroidLog() : fp_(NULL), prevTick_(static_cast<uint64_t>(0)) {
fileName_ = FILE_PREFIX;
openFile();
}
AndroidLog::AndroidLog(std::string& file_name) : fp_(NULL), prevTick_(static_cast<uint64_t>(0)) {
fileName_ = std::string(FILE_PREFIX) + std::string("_") + file_name;
openFile();
}
AndroidLog::~AndroidLog() {
flush();
}
void AndroidLog::flush() {
if(fp_) {
fflush(fp_);
fclose(fp_);
fp_ = NULL;
}
prevTick_ = static_cast<uint64_t>(0);
}
void AndroidLog::log(void *buf, uint32_t size) {
Lock fileLock(&mutex_);
if(!buf || !size)
return;
if(fp_ || openFile()) {
fwrite(buf, size, 1, fp_);
}
}
void AndroidLog::log(const char *fmt, ...) {
Lock fileLock (&mutex_);
if(!fmt) {
return;
}
if(fp_ || openFile()) {
va_list vp;
va_start(vp, fmt);
vfprintf(fp_, fmt, vp);
va_end(vp);
}
}
FILE* AndroidLog::openFile() {
Lock fileLock(&mutex_);
if(fp_) {
return fp_;
}
char fileName[64];
sprintf(fileName, "%s_%d", fileName_.c_str(), AndroidLog::fileIdx_++);
fp_ = fopen(fileName,"wb");
if (fp_ == NULL) {
LOGE("====failed to open file %s", fileName);
}
return fp_;
}
void AndroidLog::logTime() {
if(prevTick_ == static_cast<uint64_t>(0)){
/*
* init counter, bypass the first one
*/
prevTick_ = getCurrentTicks();
return;
}
uint64_t curTick = getCurrentTicks();
uint64_t delta = curTick - prevTick_;
log("%" PRIu64 " %" PRIu64 "\n", curTick, delta);
prevTick_ = curTick;
}
uint64_t AndroidLog::getCurrentTicks() {
struct timeval Time;
gettimeofday( &Time, NULL );
return (static_cast<uint64_t>(1000000) * Time.tv_sec + Time.tv_usec);
}

View File

@@ -1,34 +1,103 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:id="@+id/mainLayout"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">
<Button
android:id="@+id/button_start_capture"
<TextView
android:id="@+id/curDelay"
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/StartEcho"
android:onClick="startEcho" />
<Button
android:id="@+id/button_stop_capture"
android:layout_alignParentTop="true"
android:layout_marginTop="192dp"
android:layout_toRightOf="@+id/minDelayLabel"
android:text="@string/init_delay_val_msg"
android:visibility="visible" />
<TextView
android:id="@+id/minDelayLabel"
android:layout_gravity="start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/StopEcho"
android:onClick="stopEcho"
android:layout_toEndOf="@+id/button_start_capture"
android:layout_alignBottom="@+id/button_start_capture"
android:layout_alignParentEnd="true" />
<Button
android:layout_alignParentLeft="true"
android:layout_below="@+id/curDelay"
android:layout_marginTop="0dp"
android:text="@string/min_delay_label_msg"
android:visibility="visible" />
<SeekBar
android:id="@+id/delaySeekBar"
android:layout_alignParentRight="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignTop="@+id/minDelayLabel"
android:layout_centerHorizontal="true"
android:layout_toRightOf="@+id/minDelayLabel"
android:maxHeight="3dp"
android:minHeight="3dp"
android:max="10"
android:progress="1" />
<TextView
android:id="@+id/curDecay"
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/GetParam"
android:layout_below="@id/minDelayLabel"
android:layout_marginTop="20dp"
android:layout_toRightOf="@+id/minDecayLabel"
android:text="@string/init_decay_val_msg"
android:visibility="visible" />
<TextView
android:id="@+id/minDecayLabel"
android:layout_gravity="start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="@+id/curDecay"
android:layout_marginTop="0dp"
android:text="@string/min_decay_label_msg"
android:visibility="visible" />
<SeekBar
android:id="@+id/decaySeekBar"
android:layout_alignParentRight="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignTop="@+id/minDecayLabel"
android:layout_centerHorizontal="true"
android:layout_toRightOf="@+id/minDecayLabel"
android:maxHeight="3dp"
android:minHeight="3dp"
android:max="10"
android:progress="1" />
<Button
android:id="@+id/capture_control_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/decaySeekBar"
android:layout_centerHorizontal="true"
android:layout_marginTop="30dp"
android:onClick="onEchoClick"
android:text="@string/cmd_start_echo"
android:textAllCaps="false" />
<Button
android:id="@+id/get_parameter_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@+id/statusView"
android:layout_alignParentStart="true"
android:onClick="getLowLatencyParameters" />
<TextView android:text="@string/init_status"
android:onClick="getLowLatencyParameters"
android:text="@string/cmd_get_param"
android:textAllCaps="false" />
<TextView android:text="@string/init_status_msg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:lines="3"

View File

@@ -1,8 +1,24 @@
<resources>
<string name="app_name">audio-echo</string>
<string name="init_status">Status:</string>
<string name="init_status_msg">Starting Up</string>
<string name="request_permission_status_msg">"Requesting RECORD_AUDIO Permission..."</string>
<string name="echoing_status_msg">Engine Echoing...</string>
<string name="action_settings">Settings</string>
<string name="StartEcho">Start</string>
<string name="StopEcho">Stop</string>
<string name="GetParam">Get Param</string>
<string name="cmd_start_echo">Start Echo</string>
<string name="cmd_stop_echo">Stop Echo</string>
<string name="cmd_get_param">FastPathInfo</string>
<string name="fast_audio_info_msg">nativeSampleRate = %1$s\nnativeSampleBufSize = %2$s\n</string>
<string name="player_error_msg">Failed to Create Audio Player</string>
<string name="recorder_error_msg">Failed to Create Audio Recorder</string>
<string name="mic_error_msg">"Audio recording is not supported"</string>
<string name="permission_prompt_msg">"This sample needs RECORD_AUDIO permission"</string>
<string name="permission_granted_msg">RECORD_AUDIO permission granted, touch %1$s to begin</string>
<string name="permission_error_msg">"Permission for RECORD_AUDIO was denied"</string>
<string name="min_delay_label_msg">delay(seconds)</string>
<string name="init_delay_val_msg">0.1</string>
<string name="min_decay_label_msg">decay(decimal)</string>
<string name="init_decay_val_msg">0.1</string>
</resources>

View File

@@ -2,10 +2,11 @@
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle-experimental:0.7.0-beta1'
classpath 'com.android.tools.build:gradle:4.2.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
@@ -14,6 +15,7 @@ buildscript {
allprojects {
repositories {
google()
jcenter()
}
}

View File

@@ -15,4 +15,6 @@
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
# org.gradle.parallel=true
android.enableJetifier=true
android.useAndroidX=true

Binary file not shown.

View File

@@ -1,6 +1,5 @@
#Wed Aug 12 09:56:01 PDT 2015
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-bin.zip

147
audio-echo/gradlew vendored
View File

@@ -1,4 +1,20 @@
#!/usr/bin/env bash
#!/usr/bin/env sh
#
# Copyright 2015 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
##
@@ -6,47 +22,6 @@
##
##############################################################################
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn ( ) {
echo "$*"
}
die ( ) {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
esac
# For Cygwin, ensure paths are in UNIX format before anything is touched.
if $cygwin ; then
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
fi
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
@@ -61,9 +36,49 @@ while [ -h "$PRG" ] ; do
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >&-
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >&-
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
@@ -90,7 +105,7 @@ location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
@@ -110,10 +125,11 @@ if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
# For Cygwin or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
@@ -138,27 +154,30 @@ if $cygwin ; then
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
i=`expr $i + 1`
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
0) set -- ;;
1) set -- "$args0" ;;
2) set -- "$args0" "$args1" ;;
3) set -- "$args0" "$args1" "$args2" ;;
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
JVM_OPTS=("$@")
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
APP_ARGS=`save "$@"`
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
exec "$JAVACMD" "$@"

View File

@@ -1,3 +1,19 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@@ -8,14 +24,14 @@
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
@@ -46,10 +62,9 @@ echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windowz variants
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
@@ -60,11 +75,6 @@ set _SKIP=2
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$
:execute
@rem Setup the command line

View File

@@ -1,6 +1,6 @@
status: PUBLISHED
technologies: [Android, NDK]
categories: [NDK, C++]
categories: [NDK]
languages: [C++, Java]
solutions: [Mobile]
github: googlesamples/android-ndk

View File

@@ -2,11 +2,11 @@ Bitmap Plasma
=============
Bitmap Plasma is an Android sample that uses JNI to render a plasma effect in an Android [Bitmap](http://developer.android.com/reference/android/graphics/Bitmap.html) from C code.
This sample uses the new [Gradle Experimental Android plugin](http://tools.android.com/tech-docs/new-build-system/gradle-experimental) with C++ support.
This sample uses the new [Android Studio CMake plugin](http://tools.android.com/tech-docs/external-c-builds) with C++ support.
Pre-requisites
--------------
- Android Studio 1.3+ with [NDK](https://developer.android.com/ndk/) bundle.
- Android Studio 2.2+ with [NDK](https://developer.android.com/ndk/) bundle.
Getting Started
---------------
@@ -30,7 +30,6 @@ Patches are encouraged, and may be submitted by [forking this project](https://g
submitting a pull request through GitHub. Please see [CONTRIBUTING.md](../CONTRIBUTING.md) for more details.
- [Stack Overflow](http://stackoverflow.com/questions/tagged/android-ndk)
- [Google+ Community](https://plus.google.com/communities/105153134372062985968)
- [Android Tools Feedbacks](http://tools.android.com/feedback)
License

View File

@@ -1,26 +1,25 @@
apply plugin: 'com.android.model.application'
apply plugin: 'com.android.application'
model {
android {
compileSdkVersion = 23
buildToolsVersion = '23.0.2'
android {
compileSdkVersion 29
ndkVersion '21.2.6472646'
defaultConfig.with {
applicationId = 'com.example.plasma'
minSdkVersion.apiLevel = 8
targetSdkVersion.apiLevel = 23
defaultConfig.with {
applicationId 'com.example.plasma'
minSdkVersion 14
targetSdkVersion 28
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'),
'proguard-rules.pro'
}
ndk {
moduleName = 'plasma'
//toolchain = 'clang' // clang does not like inline, throw warnings
CFlags.addAll(['-Wall', '-Werror'])
ldLibs.addAll(['m', 'log', 'jnigraphics'])
}
buildTypes {
release {
minifyEnabled = false
proguardFiles.add(file('proguard-rules.txt'))
}
}
externalNativeBuild {
cmake {
version '3.18.1'
path 'src/main/cpp/CMakeLists.txt'
}
}
}

View File

@@ -0,0 +1,13 @@
cmake_minimum_required(VERSION 3.4.1)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Werror -Wno-unused-function")
add_library(plasma SHARED
plasma.c)
# Include libraries needed for plasma lib
target_link_libraries(plasma
android
jnigraphics
log
m)

View File

@@ -140,7 +140,7 @@ static uint16_t palette[PALETTE_SIZE];
static uint16_t make565(int red, int green, int blue)
{
return (uint16_t)( ((red << 8) & 0xf800) |
((green << 2) & 0x03e0) |
((green << 3) & 0x07e0) |
((blue >> 3) & 0x001f) );
}

View File

@@ -17,6 +17,7 @@ package com.example.plasma;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.graphics.Point;
import android.os.Bundle;
import android.content.Context;
import android.view.View;
@@ -33,7 +34,9 @@ public class Plasma extends Activity
{
super.onCreate(savedInstanceState);
Display display = getWindowManager().getDefaultDisplay();
setContentView(new PlasmaView(this, display.getWidth(), display.getHeight()));
Point displaySize = new Point();
display.getSize(displaySize);
setContentView(new PlasmaView(this, displaySize.x, displaySize.y));
}
// load our native library

View File

@@ -1,15 +1,17 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle-experimental:0.7.0-beta1'
classpath 'com.android.tools.build:gradle:4.2.0'
}
}
allprojects {
repositories {
google()
jcenter()
}
}

Binary file not shown.

View File

@@ -1,6 +1,5 @@
#Wed Apr 10 15:27:10 PDT 2013
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-bin.zip

147
bitmap-plasma/gradlew vendored
View File

@@ -1,4 +1,20 @@
#!/usr/bin/env bash
#!/usr/bin/env sh
#
# Copyright 2015 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
##
@@ -6,47 +22,6 @@
##
##############################################################################
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn ( ) {
echo "$*"
}
die ( ) {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
esac
# For Cygwin, ensure paths are in UNIX format before anything is touched.
if $cygwin ; then
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
fi
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
@@ -61,9 +36,49 @@ while [ -h "$PRG" ] ; do
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >&-
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >&-
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
@@ -90,7 +105,7 @@ location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
@@ -110,10 +125,11 @@ if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
# For Cygwin or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
@@ -138,27 +154,30 @@ if $cygwin ; then
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
i=`expr $i + 1`
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
0) set -- ;;
1) set -- "$args0" ;;
2) set -- "$args0" "$args1" ;;
3) set -- "$args0" "$args1" "$args2" ;;
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
JVM_OPTS=("$@")
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
APP_ARGS=`save "$@"`
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
exec "$JAVACMD" "$@"

View File

@@ -1,3 +1,19 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@@ -8,14 +24,14 @@
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
@@ -46,10 +62,9 @@ echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windowz variants
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
@@ -60,11 +75,6 @@ set _SKIP=2
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$
:execute
@rem Setup the command line

View File

@@ -5,10 +5,10 @@ repositories {
}
dependencies {
compile 'org.gradle:gradle-tooling-api:+'
compile 'org.slf4j:slf4j-api:1.7.7'
compile 'org.eclipse.jgit:org.eclipse.jgit:4.0.1.201506240215-r'
compile 'com.google.guava:guava:+'
implementation 'org.gradle:gradle-tooling-api:+'
implementation 'org.slf4j:slf4j-api:1.7.7'
implementation 'org.eclipse.jgit:org.eclipse.jgit:4.0.1.201506240215-r'
implementation 'com.google.guava:guava:+'
testCompile 'junit:junit:4.12'
}

Binary file not shown.

View File

@@ -1,6 +1,5 @@
#Thu Jun 18 16:35:58 PDT 2015
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-bin.zip

147
builder/gradlew vendored
View File

@@ -1,4 +1,20 @@
#!/usr/bin/env bash
#!/usr/bin/env sh
#
# Copyright 2015 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
##
@@ -6,47 +22,6 @@
##
##############################################################################
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn ( ) {
echo "$*"
}
die ( ) {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
esac
# For Cygwin, ensure paths are in UNIX format before anything is touched.
if $cygwin ; then
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
fi
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
@@ -61,9 +36,49 @@ while [ -h "$PRG" ] ; do
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >&-
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >&-
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
@@ -90,7 +105,7 @@ location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
@@ -110,10 +125,11 @@ if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
# For Cygwin or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
@@ -138,27 +154,30 @@ if $cygwin ; then
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
i=`expr $i + 1`
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
0) set -- ;;
1) set -- "$args0" ;;
2) set -- "$args0" "$args1" ;;
3) set -- "$args0" "$args1" "$args2" ;;
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
JVM_OPTS=("$@")
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
APP_ARGS=`save "$@"`
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
exec "$JAVACMD" "$@"

30
builder/gradlew.bat vendored
View File

@@ -1,3 +1,19 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@@ -8,14 +24,14 @@
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
@@ -46,10 +62,9 @@ echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windowz variants
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
@@ -60,11 +75,6 @@ set _SKIP=2
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$
:execute
@rem Setup the command line

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

69
camera/README.md Normal file
View File

@@ -0,0 +1,69 @@
NdkCamera Sample
=============
Two API samples:
- texture-view:
Preview NDK camera image with [Android TextureView](https://developer.android.com/reference/android/view/TextureView.html)
- basic:
A basic NdkCamera sample to preview camera images with AReadImage and take jpeg photos.
Exposure and sensitivity are adjustable for preview, however capturing photos is in auto mode
(it could be adjustable with similar method as used for preview).
Other Resources
---------------
- Getting familiar with the 5 Camera2 objects
![Camera2 API Model](Camera2ProgrammingModel.png)
- [Camera2 blogs](https://medium.com/androiddevelopers/camera-enumeration-on-android-9a053b910cb5)
- [Camera2 Java
documentation](https://developer.android.com/reference/android/hardware/camera2/package-summary)
Pre-requisites
--------------
- Android Studio 2.3.0+ with [NDK-r15+](https://developer.android.com/ndk/) bundle
- Android device running android-24+
Getting Started
---------------
1. Download Android Studio from [latest stable release](http://developer.android.com/sdk/index.html) or [canary](http://tools.android.com/download/studio/canary)
1. Launch Android Studio
1. Select "Import project (Eclipse ADT, Gradle,etc)"
1. Browse into downloaded sample directory, select webp/build.gradle
1. Click *Tools/Android/Sync Project with Gradle Files*.
1. Click *Run/Run 'app'*.
Screenshots
-----------
![screenshot](ndkCamera.png)
Support
-------
If you've found an error in these samples, please [file an issue](https://github.com/googlesamples/android-ndk/issues/new).
Patches are encouraged, and may be submitted by [forking this project](https://github.com/googlesamples/android-ndk/fork) and
submitting a pull request through GitHub. Please see [CONTRIBUTING.md](../CONTRIBUTING.md) for more details.
For generic questions about Android Camera and other feedbacks, please go to
- [Stack Overflow](http://stackoverflow.com/questions/tagged/android-camera)
- [Android Tools Feedbacks](http://tools.android.com/feedback)
License
-------
Copyright 2015 Google, Inc.
Licensed to the Apache Software Foundation (ASF) under one or more contributor
license agreements. See the NOTICE file distributed with this work for
additional information regarding copyright ownership. The ASF licenses this
file to you under the Apache License, Version 2.0 (the "License"); you may not
use this file except in compliance with the License. You may obtain a copy of
the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
License for the specific language governing permissions and limitations under
the License.

38
camera/basic/build.gradle Normal file
View File

@@ -0,0 +1,38 @@
apply plugin: 'com.android.application'
android {
compileSdkVersion 29
ndkVersion '21.2.6472646'
defaultConfig {
applicationId 'com.sample.camera.basic'
minSdkVersion 24
targetSdkVersion 28
ndk {
abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
}
externalNativeBuild {
cmake {
arguments '-DANDROID_STL=c++_static'
}
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'),
'proguard-rules.pro'
}
}
externalNativeBuild {
cmake {
version '3.18.1'
path 'src/main/cpp/CMakeLists.txt'
}
}
}
dependencies {
implementation fileTree(dir:'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:28.0.0'
}

View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.sample.camera.basic"
android:versionCode="1"
android:versionName="1.0">
<uses-feature android:name="android.hardware.camera" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:allowBackup="false"
android:fullBackupContent="false"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:screenOrientation="sensorLandscape"
android:configChanges="keyboardHidden|orientation|screenSize"
android:hasCode="true">
<activity android:name="com.sample.camera.basic.CameraActivity"
android:label="@string/app_name">
<meta-data android:name="android.app.lib_name"
android:value="ndk_camera" />
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>

View File

@@ -0,0 +1,52 @@
#
# Copyright (C) 2017 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
cmake_minimum_required(VERSION 3.4.1)
set(CMAKE_VERBOSE_MAKEFILE on)
set(COMMON_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../../../common)
# build native_app_glue as a static lib
include_directories(${ANDROID_NDK}/sources/android/native_app_glue
${COMMON_SOURCE_DIR})
add_library(app_glue STATIC
${ANDROID_NDK}/sources/android/native_app_glue/android_native_app_glue.c)
# now build app's shared lib
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Werror")
# Export ANativeActivity_onCreate(),
# Refer to: https://github.com/android-ndk/ndk/issues/381.
set(CMAKE_SHARED_LINKER_FLAGS
"${CMAKE_SHARED_LINKER_FLAGS} -u ANativeActivity_onCreate")
add_library(ndk_camera SHARED
${CMAKE_CURRENT_SOURCE_DIR}/android_main.cpp
${CMAKE_CURRENT_SOURCE_DIR}/camera_engine.cpp
${CMAKE_CURRENT_SOURCE_DIR}/camera_manager.cpp
${CMAKE_CURRENT_SOURCE_DIR}/camera_listeners.cpp
${CMAKE_CURRENT_SOURCE_DIR}/image_reader.cpp
${CMAKE_CURRENT_SOURCE_DIR}/camera_ui.cpp
${COMMON_SOURCE_DIR}/utils/camera_utils.cpp)
# add lib dependencies
target_link_libraries(ndk_camera
android
log
m
app_glue
camera2ndk
mediandk)

Some files were not shown because too many files have changed in this diff Show More