diff --git a/samples/android/tutorial-4-opencl/CMakeLists.txt b/samples/android/tutorial-4-opencl/CMakeLists.txt index 94e955fe36..92d24050ff 100644 --- a/samples/android/tutorial-4-opencl/CMakeLists.txt +++ b/samples/android/tutorial-4-opencl/CMakeLists.txt @@ -1,12 +1,4 @@ set(sample example-tutorial-4-opencl) -if(NOT DEFINED ANDROID_OPENCL_SDK) - message(STATUS "Sample ${sample} is disabled, because ANDROID_OPENCL_SDK is not specified") - return() -endif() -if(ANDROID_NATIVE_API_LEVEL LESS 14) - message(STATUS "Sample ${sample} is disabled, because ANDROID_NATIVE_API_LEVEL < 14") - return() -endif() if(BUILD_FAT_JAVA_LIB) set(native_deps opencv_java) @@ -14,12 +6,10 @@ else() set(native_deps opencv_imgproc) endif() -include_directories(${ANDROID_OPENCL_SDK}/include) -link_directories(${ANDROID_OPENCL_SDK}/lib/${ANDROID_NDK_ABI_NAME}) add_android_project(${sample} "${CMAKE_CURRENT_SOURCE_DIR}" LIBRARY_DEPS "${OPENCV_ANDROID_LIB_DIR}" SDK_TARGET 21 "${ANDROID_SDK_TARGET}" - NATIVE_DEPS ${native_deps} -lGLESv2 -lEGL -lOpenCL + NATIVE_DEPS ${native_deps} -lGLESv2 -lEGL COPY_LIBS YES ) if(TARGET ${sample}) diff --git a/samples/android/tutorial-4-opencl/build.gradle.in b/samples/android/tutorial-4-opencl/build.gradle.in index 17a5d37190..48412c9b04 100644 --- a/samples/android/tutorial-4-opencl/build.gradle.in +++ b/samples/android/tutorial-4-opencl/build.gradle.in @@ -53,8 +53,10 @@ android { dependencies { //implementation fileTree(dir: 'libs', include: ['*.jar']) if (gradle.opencv_source == "sdk_path") { + println 'Using OpenCV from SDK' implementation project(':opencv') } else if (gradle.opencv_source == "maven_local" || gradle.opencv_source == "maven_cenral") { + println 'Using OpenCV from Maven repo' implementation 'org.opencv:opencv:@OPENCV_VERSION_PLAIN@' } } diff --git a/samples/android/tutorial-4-opencl/jni/CLprocessor.cpp b/samples/android/tutorial-4-opencl/jni/CLprocessor.cpp index 27b878b3fa..ecc1c63a15 100644 --- a/samples/android/tutorial-4-opencl/jni/CLprocessor.cpp +++ b/samples/android/tutorial-4-opencl/jni/CLprocessor.cpp @@ -1,6 +1,8 @@ +#ifdef OPENCL_FOUND #define __CL_ENABLE_EXCEPTIONS #define CL_USE_DEPRECATED_OPENCL_1_1_APIS /*let's give a chance for OpenCL 1.1 devices*/ #include +#endif #include #include @@ -10,7 +12,9 @@ #include #include "common.hpp" +#include "CLprocessor.hpp" +#ifdef OPENCL_FOUND const char oclProgB2B[] = "// clBuffer to clBuffer"; const char oclProgI2B[] = "// clImage to clBuffer"; const char oclProgI2I[] = \ @@ -33,7 +37,7 @@ const char oclProgI2I[] = \ " write_imagef(imgOut, pos, sum*10); \n" \ "} \n"; -void dumpCLinfo() +static void dumpCLinfo() { LOGD("*** OpenCL info ***"); try @@ -83,7 +87,7 @@ cl::CommandQueue theQueue; cl::Program theProgB2B, theProgI2B, theProgI2I; bool haveOpenCL = false; -extern "C" void initCL() +int initCL() { dumpCLinfo(); @@ -133,20 +137,24 @@ extern "C" void initCL() catch(const cl::Error& e) { LOGE("cl::Error: %s (%d)", e.what(), e.err()); + return 1; } catch(const std::exception& e) { LOGE("std::exception: %s", e.what()); + return 2; } catch(...) { LOGE( "OpenCL info: unknown error while initializing OpenCL stuff" ); + return 3; } LOGD("initCL completed"); -} -extern "C" void closeCL() -{ + if (haveOpenCL) + return 0; + else + return 4; } #define GL_TEXTURE_2D 0x0DE1 @@ -230,6 +238,16 @@ void procOCL_OCV(int texIn, int texOut, int w, int h) cv::ocl::finish(); LOGD("uploading results to texture costs %d ms", getTimeInterval(t)); } +#else +int initCL() +{ + return 5; +} +#endif + +void closeCL() +{ +} void drawFrameProcCPU(int w, int h, int texOut) { @@ -263,7 +281,7 @@ void drawFrameProcCPU(int w, int h, int texOut) enum ProcMode {PROC_MODE_NO_PROC=0, PROC_MODE_CPU=1, PROC_MODE_OCL_DIRECT=2, PROC_MODE_OCL_OCV=3}; -extern "C" void processFrame(int tex1, int tex2, int w, int h, int mode) +void processFrame(int tex1, int tex2, int w, int h, int mode) { switch(mode) { @@ -271,12 +289,14 @@ extern "C" void processFrame(int tex1, int tex2, int w, int h, int mode) case PROC_MODE_CPU: drawFrameProcCPU(w, h, tex2); break; +#ifdef OPENCL_FOUND case PROC_MODE_OCL_DIRECT: procOCL_I2I(tex1, tex2, w, h); break; case PROC_MODE_OCL_OCV: procOCL_OCV(tex1, tex2, w, h); break; +#endif default: LOGE("Unexpected processing mode: %d", mode); } diff --git a/samples/android/tutorial-4-opencl/jni/CLprocessor.hpp b/samples/android/tutorial-4-opencl/jni/CLprocessor.hpp new file mode 100644 index 0000000000..c293f253b5 --- /dev/null +++ b/samples/android/tutorial-4-opencl/jni/CLprocessor.hpp @@ -0,0 +1,8 @@ +#ifndef __CL_PROCESSOR_HPP__ +#define __CL_PROCESSOR_HPP__ + +int initCL(); +void closeCL(); +void processFrame(int tex1, int tex2, int w, int h, int mode); + +#endif diff --git a/samples/android/tutorial-4-opencl/jni/CMakeLists.txt b/samples/android/tutorial-4-opencl/jni/CMakeLists.txt index 923ccd318e..0e728f47ab 100644 --- a/samples/android/tutorial-4-opencl/jni/CMakeLists.txt +++ b/samples/android/tutorial-4-opencl/jni/CMakeLists.txt @@ -4,17 +4,32 @@ set(target JNIpart) project(${target} CXX) if (OPENCV_FROM_SDK) + message(STATUS "Using OpenCV from local SDK") set(ANDROID_OPENCV_COMPONENTS "opencv_java" CACHE STRING "") else() + message(STATUS "Using OpenCV from AAR (Maven repo)") set(ANDROID_OPENCV_COMPONENTS "OpenCV::opencv_java${OPENCV_VERSION_MAJOR}" CACHE STRING "") endif() message(STATUS "ANDROID_ABI=${ANDROID_ABI}") find_package(OpenCV REQUIRED COMPONENTS ${ANDROID_OPENCV_COMPONENTS}) +find_package(OpenCL QUIET) file(GLOB srcs *.cpp *.c) file(GLOB hdrs *.hpp *.h) include_directories("${CMAKE_CURRENT_LIST_DIR}") add_library(${target} SHARED ${srcs} ${hdrs}) -target_link_libraries(${target} ${ANDROID_OPENCV_COMPONENTS} -lGLESv2 -lEGL -lOpenCL) + +target_link_libraries(${target} ${ANDROID_OPENCV_COMPONENTS} -lGLESv2 -lEGL -llog) + +if(OpenCL_FOUND) + include_directories(${OpenCL_INCLUDE_DIRS}) + target_link_libraries(${OpenCL_LIBRARIES}) + add_definitions("-DOPENCL_FOUND") +elseif(DEFINED ANDROID_OPENCL_SDK) + include_directories(${ANDROID_OPENCL_SDK}/include) + link_directories(${ANDROID_OPENCL_SDK}/lib/${ANDROID_NDK_ABI_NAME}) + target_link_libraries(-lOpenCL) + add_definitions("-DOPENCL_FOUND") +endif() diff --git a/samples/android/tutorial-4-opencl/jni/jni.c b/samples/android/tutorial-4-opencl/jni/jni.c deleted file mode 100644 index 0c48ab6063..0000000000 --- a/samples/android/tutorial-4-opencl/jni/jni.c +++ /dev/null @@ -1,20 +0,0 @@ -#include - -int initCL(); -void closeCL(); -void processFrame(int tex1, int tex2, int w, int h, int mode); - -JNIEXPORT jint JNICALL Java_org_opencv_samples_tutorial4_NativePart_initCL(JNIEnv * env, jclass cls) -{ - return initCL(); -} - -JNIEXPORT void JNICALL Java_org_opencv_samples_tutorial4_NativePart_closeCL(JNIEnv * env, jclass cls) -{ - closeCL(); -} - -JNIEXPORT void JNICALL Java_org_opencv_samples_tutorial4_NativePart_processFrame(JNIEnv * env, jclass cls, jint tex1, jint tex2, jint w, jint h, jint mode) -{ - processFrame(tex1, tex2, w, h, mode); -} diff --git a/samples/android/tutorial-4-opencl/jni/jni.cpp b/samples/android/tutorial-4-opencl/jni/jni.cpp new file mode 100644 index 0000000000..354fcb30b0 --- /dev/null +++ b/samples/android/tutorial-4-opencl/jni/jni.cpp @@ -0,0 +1,36 @@ +#include +#include "CLprocessor.hpp" + +extern "C" { +JNIEXPORT jboolean JNICALL Java_org_opencv_samples_tutorial4_NativePart_builtWithOpenCL(JNIEnv * env, jclass cls); + +JNIEXPORT jint JNICALL Java_org_opencv_samples_tutorial4_NativePart_initCL(JNIEnv * env, jclass cls); + +JNIEXPORT void JNICALL Java_org_opencv_samples_tutorial4_NativePart_closeCL(JNIEnv * env, jclass cls); + +JNIEXPORT void JNICALL Java_org_opencv_samples_tutorial4_NativePart_processFrame(JNIEnv * env, jclass cls, jint tex1, jint tex2, jint w, jint h, jint mode); + +JNIEXPORT jboolean JNICALL Java_org_opencv_samples_tutorial4_NativePart_builtWithOpenCL(JNIEnv * env, jclass cls) +{ +#ifdef OPENCL_FOUND + return JNI_TRUE; +#else + return JNI_FALSE; +#endif +} + +JNIEXPORT jint JNICALL Java_org_opencv_samples_tutorial4_NativePart_initCL(JNIEnv * env, jclass cls) +{ + return initCL(); +} + +JNIEXPORT void JNICALL Java_org_opencv_samples_tutorial4_NativePart_closeCL(JNIEnv * env, jclass cls) +{ + closeCL(); +} + +JNIEXPORT void JNICALL Java_org_opencv_samples_tutorial4_NativePart_processFrame(JNIEnv * env, jclass cls, jint tex1, jint tex2, jint w, jint h, jint mode) +{ + processFrame(tex1, tex2, w, h, mode); +} +} // extern "C" diff --git a/samples/android/tutorial-4-opencl/res/menu/menu.xml b/samples/android/tutorial-4-opencl/res/menu/menu.xml deleted file mode 100644 index a737e39d2c..0000000000 --- a/samples/android/tutorial-4-opencl/res/menu/menu.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/samples/android/tutorial-4-opencl/src/org/opencv/samples/tutorial4/MyGLSurfaceView.java b/samples/android/tutorial-4-opencl/src/org/opencv/samples/tutorial4/MyGLSurfaceView.java index edaf34631c..72ab023ef0 100644 --- a/samples/android/tutorial-4-opencl/src/org/opencv/samples/tutorial4/MyGLSurfaceView.java +++ b/samples/android/tutorial-4-opencl/src/org/opencv/samples/tutorial4/MyGLSurfaceView.java @@ -65,7 +65,8 @@ public class MyGLSurfaceView extends CameraGLSurfaceView implements CameraGLSurf Toast.makeText(getContext(), "onCameraViewStarted", Toast.LENGTH_SHORT).show(); } }); - NativePart.initCL(); + if (NativePart.builtWithOpenCL()) + NativePart.initCL(); frameCounter = 0; lastNanoTime = System.nanoTime(); } diff --git a/samples/android/tutorial-4-opencl/src/org/opencv/samples/tutorial4/NativePart.java b/samples/android/tutorial-4-opencl/src/org/opencv/samples/tutorial4/NativePart.java index e3d11709a9..2ef890ee82 100644 --- a/samples/android/tutorial-4-opencl/src/org/opencv/samples/tutorial4/NativePart.java +++ b/samples/android/tutorial-4-opencl/src/org/opencv/samples/tutorial4/NativePart.java @@ -12,6 +12,7 @@ public class NativePart { public static final int PROCESSING_MODE_OCL_DIRECT = 2; public static final int PROCESSING_MODE_OCL_OCV = 3; + public static native boolean builtWithOpenCL(); public static native int initCL(); public static native void closeCL(); public static native void processFrame(int tex1, int tex2, int w, int h, int mode); diff --git a/samples/android/tutorial-4-opencl/src/org/opencv/samples/tutorial4/Tutorial4Activity.java b/samples/android/tutorial-4-opencl/src/org/opencv/samples/tutorial4/Tutorial4Activity.java index 0be55df65e..8738501ede 100644 --- a/samples/android/tutorial-4-opencl/src/org/opencv/samples/tutorial4/Tutorial4Activity.java +++ b/samples/android/tutorial-4-opencl/src/org/opencv/samples/tutorial4/Tutorial4Activity.java @@ -1,6 +1,5 @@ package org.opencv.samples.tutorial4; -import android.app.Activity; import android.content.pm.ActivityInfo; import android.os.Bundle; import android.view.Menu; @@ -10,11 +9,20 @@ import android.view.Window; import android.view.WindowManager; import android.widget.TextView; -public class Tutorial4Activity extends Activity { +import org.opencv.android.CameraActivity; + +public class Tutorial4Activity extends CameraActivity { private MyGLSurfaceView mView; private TextView mProcMode; + private boolean builtWithOpenCL = false; + + private MenuItem mItemNoProc; + private MenuItem mItemCpu; + private MenuItem mItemOclDirect; + private MenuItem mItemOclOpenCV; + @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -38,6 +46,7 @@ public class Tutorial4Activity extends Activity { } }); + builtWithOpenCL = NativePart.builtWithOpenCL(); mView.setProcessingMode(NativePart.PROCESSING_MODE_NO_PROCESSING); } @@ -55,48 +64,37 @@ public class Tutorial4Activity extends Activity { @Override public boolean onCreateOptionsMenu(Menu menu) { - MenuInflater inflater = getMenuInflater(); - inflater.inflate(R.menu.menu, menu); - return super.onCreateOptionsMenu(menu); + mItemNoProc = menu.add("No processing"); + mItemCpu = menu.add("Use CPU code"); + if (builtWithOpenCL) { + mItemOclOpenCV = menu.add("Use OpenCL via OpenCV"); + mItemOclDirect = menu.add("Use OpenCL direct"); + } + return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - case R.id.no_proc: - runOnUiThread(new Runnable() { - public void run() { - mProcMode.setText("Processing mode: No Processing"); - } - }); - mView.setProcessingMode(NativePart.PROCESSING_MODE_NO_PROCESSING); - return true; - case R.id.cpu: - runOnUiThread(new Runnable() { - public void run() { - mProcMode.setText("Processing mode: CPU"); - } - }); - mView.setProcessingMode(NativePart.PROCESSING_MODE_CPU); - return true; - case R.id.ocl_direct: - runOnUiThread(new Runnable() { - public void run() { - mProcMode.setText("Processing mode: OpenCL direct"); - } - }); - mView.setProcessingMode(NativePart.PROCESSING_MODE_OCL_DIRECT); - return true; - case R.id.ocl_ocv: - runOnUiThread(new Runnable() { - public void run() { - mProcMode.setText("Processing mode: OpenCL via OpenCV (TAPI)"); - } - }); - mView.setProcessingMode(NativePart.PROCESSING_MODE_OCL_OCV); - return true; - default: - return false; + String procName = "Not selected"; + int procMode = NativePart.PROCESSING_MODE_NO_PROCESSING; + + if (item == mItemNoProc) { + procMode = NativePart.PROCESSING_MODE_NO_PROCESSING; + procName = "Processing mode: No Processing"; + } else if (item == mItemCpu) { + procMode = NativePart.PROCESSING_MODE_CPU; + procName = "Processing mode: CPU"; + } else if (item == mItemOclOpenCV && builtWithOpenCL) { + procMode = NativePart.PROCESSING_MODE_OCL_OCV; + procName = "Processing mode: OpenCL via OpenCV (TAPI)"; + } else if (item == mItemOclDirect && builtWithOpenCL) { + procMode = NativePart.PROCESSING_MODE_OCL_DIRECT; + procName = "Processing mode: OpenCL direct"; } + + mView.setProcessingMode(procMode); + mProcMode.setText(procName); + + return true; } -} \ No newline at end of file +}