Skip to content

Commit

Permalink
Merge pull request #28 from DAGalpin/main
Browse files Browse the repository at this point in the history
Added GLSLImageProcessor that (mostly) uses Kotlin to implement GL/ES Compute
  • Loading branch information
DAGalpin committed Oct 9, 2023
2 parents 08d5130 + 494e1aa commit c1de268
Show file tree
Hide file tree
Showing 14 changed files with 899 additions and 16 deletions.
14 changes: 7 additions & 7 deletions RenderScriptMigrationSample/README.md
Expand Up @@ -4,18 +4,18 @@

[RenderScript is being deprecated](https://android-developers.googleblog.com/2021/04/android-gpu-compute-going-forward.html) since Android 12. We recommend computationally intensive applications to use [Vulkan](https://www.khronos.org/vulkan), the cross platform industry standard API. Please refer to the [RenderScript Migration Guide](https://developer.android.com/guide/topics/renderscript/migrate) for more details.

To help developers for the migration, this sample is created to demonstrate how to apply the image filtering to a bitmap with the Vulkan compute pipeline. The sample creates a common ImageProcessor interface, on the top of Vulkan Compute and RenderScript, that performs two compute tasks:
To help developers migrate, this sample is created to demonstrate how to apply image filtering to a bitmap with Renderscript Intrinsics, Renderscript Scripts, Vulkan compute pipeline, GLSL compute (in Kotlin). Since the two effects demonstrated can also be implemented using the platform RenderEffect, this is also demonstrated. The sample creates a common ImageProcessor interface that performs two compute tasks:
- HUE rotation: A simple compute task with a single compute kernel.
- Blur: A more complex compute task which executes two compute kernels sequentially.

Both tasks are implemented with RenderScript (intrinsics & custom scripts) and Vulkan to demonstrate the migration from RenderScript to Vulkan Compute pipeline.
Both tasks are implemented with RenderScript (intrinsics & custom scripts), GLSL, and Vulkan to demonstrate the migration from RenderScript to Vulkan or GLSL Compute pipelines.

## Pre-requisites

- Android Studio Arctic Fox 2020.3.1+
- SDK Build Tools 31.0.0+
- NDK r20+
- Android API 29+
- Android Studio Flamingo 2022.2.1+
- SDK Build Tools 34.0.0+
- NDK 22.0.7026061
- Android API 33+

## Getting Started

Expand All @@ -32,7 +32,7 @@ Both tasks are implemented with RenderScript (intrinsics & custom scripts) and V

## Support

We highly recommend to use [Stack Overflow](http://stackoverflow.com/questions/tagged/android) to get help from the Andorid community.
We highly recommend to use [Stack Overflow](http://stackoverflow.com/questions/tagged/android) to get help from the Android community.

If you've found an error in this sample, please file an issue:
https://github.com/android/renderscript-samples
Expand Down
7 changes: 5 additions & 2 deletions RenderScriptMigrationSample/app/build.gradle
Expand Up @@ -2,7 +2,7 @@ apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'

android {
compileSdkVersion 31
compileSdk 33

// When building this project with with SDK build tools of version earlier than 31.0.0, and
// minSdkVersion 29+, the RenderScript compiler will fail with the following error message:
Expand Down Expand Up @@ -44,7 +44,7 @@ android {
sourceSets {
main {
jniLibs {
srcDirs "$android.ndkDirectory/sources/third_party/vulkan/src/build-android/jniLibs"
srcDirs 'src/main/jniLibs/android-binaries-sdk-1.3.261.0'
}
}
}
Expand All @@ -57,6 +57,9 @@ android {
dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.9")
implementation("androidx.graphics:graphics-core:1.0.0-alpha04")
implementation 'androidx.core:core-ktx:1.6.0'
implementation 'androidx.appcompat:appcompat:1.3.1'
implementation 'androidx.constraintlayout:constraintlayout:2.1.0'
Expand Down
9 changes: 7 additions & 2 deletions RenderScriptMigrationSample/app/src/main/cpp/CMakeLists.txt
Expand Up @@ -23,7 +23,8 @@ add_library(rs_migration_jni
ComputePipeline.cpp
ImageProcessor.cpp
VulkanContext.cpp
VulkanResources.cpp)
VulkanResources.cpp
GLDebug.cpp)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++1z")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Weverything -Werror")
Expand All @@ -38,8 +39,12 @@ find_library(libandroid android)
find_library(liblog log)
find_library(libjnigraphics jnigraphics)
find_library(libvulkan vulkan)
find_library(libgl GLESv3)
find_library(libegl EGL)
target_link_libraries(rs_migration_jni
${libandroid}
${liblog}
${libjnigraphics}
${libvulkan})
${libvulkan}
${libgl}
${libegl})
69 changes: 69 additions & 0 deletions RenderScriptMigrationSample/app/src/main/cpp/GLDebug.cpp
@@ -0,0 +1,69 @@
/*
* Copyright (C) 2023 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 <android/log.h>
#include <jni.h>
#include <GLES3/gl32.h>
#include <EGL/egl.h>

// our JNICallback struct.
static thread_local struct JNICallback {
JNIEnv *env;
jmethodID mid;
jobject obj;
} jniCallback;

static void openGLMessageCallback(GLenum source, GLenum type, GLuint id,
GLenum severity, GLsizei, const GLchar* message,
const void* userParam)
{
if ( nullptr != userParam ) {
const JNICallback* callback = reinterpret_cast<const JNICallback*>(userParam);

jstring jniMessageString = callback->env->NewStringUTF(message);
callback->env->CallVoidMethod(callback->obj, callback->mid,
static_cast<jint>(source),
static_cast<jint>(type),
static_cast<jint>(id),
static_cast<jint>(severity),
jniMessageString );
}
}

// There's no way to do this in managed code, so here's something to help out those devs that
// want some more debug info.
extern "C"
JNIEXPORT jboolean JNICALL
Java_com_android_example_rsmigration_GLSLImageProcessorKt_EnableDebugLogging(JNIEnv *env,
jclass,
jobject callback) {
if ( env ) {
auto debugCallback = reinterpret_cast<void (*)(void *, void *)>(eglGetProcAddress("glDebugMessageCallback"));
if (debugCallback) {
// enable debug output
glEnable(GL_DEBUG_OUTPUT);
// call back on the same thread
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);

jniCallback.env = env;
jclass cls = env->GetObjectClass(callback);
jniCallback.mid = env->GetMethodID(cls, "onMessage","(IIIILjava/lang/String;)V");
jniCallback.obj = env->NewWeakGlobalRef(callback);
debugCallback(reinterpret_cast<void*>(openGLMessageCallback), &jniCallback);
}
}
return false;
}

0 comments on commit c1de268

Please sign in to comment.