diff --git a/samples/android/tutorial-4-opencl/jni/Android.mk b/samples/android/tutorial-4-opencl/jni/Android.mk index a641a931b..4627b08d4 100644 --- a/samples/android/tutorial-4-opencl/jni/Android.mk +++ b/samples/android/tutorial-4-opencl/jni/Android.mk @@ -7,8 +7,15 @@ LOCAL_EXPORT_C_INCLUDES := $(OPENCL_SDK)/include include $(PREBUILT_SHARED_LIBRARY) include $(CLEAR_VARS) +OPENCV_INSTALL_MODULES:=on +ifeq ($(O4A_SDK_ROOT),) + include ../../sdk/native/jni/OpenCV.mk +else + include $(O4A_SDK_ROOT)/sdk/native/jni/OpenCV.mk +endif + LOCAL_MODULE := JNIrender LOCAL_SRC_FILES := jni.c GLrender.cpp CLprocessor.cpp -LOCAL_LDLIBS := -llog -lGLESv2 -lEGL -LOCAL_SHARED_LIBRARIES := OpenCL +LOCAL_LDLIBS += -llog -lGLESv2 -lEGL +LOCAL_SHARED_LIBRARIES += OpenCL include $(BUILD_SHARED_LIBRARY) \ No newline at end of file diff --git a/samples/android/tutorial-4-opencl/jni/CLprocessor.cpp b/samples/android/tutorial-4-opencl/jni/CLprocessor.cpp index 03fec9c30..66699aa52 100644 --- a/samples/android/tutorial-4-opencl/jni/CLprocessor.cpp +++ b/samples/android/tutorial-4-opencl/jni/CLprocessor.cpp @@ -3,6 +3,9 @@ #include +#include +#include + #include "common.hpp" const char oclProgB2B[] = "// clBuffer to clBuffer"; @@ -79,6 +82,8 @@ cl::Program theProgB2B, theProgI2B, theProgI2I; void initCL() { + dumpCLinfo(); + EGLDisplay mEglDisplay = eglGetCurrentDisplay(); if (mEglDisplay == EGL_NO_DISPLAY) LOGE("initCL: eglGetCurrentDisplay() returned 'EGL_NO_DISPLAY', error = %x", eglGetError()); @@ -113,6 +118,12 @@ void initCL() cl::Program::Sources src(1, std::make_pair(oclProgI2I, sizeof(oclProgI2I))); theProgI2I = cl::Program(theContext, src); theProgI2I.build(devs); + + cv::ocl::attachContext(p.getInfo(), p(), theContext(), devs[0]()); + if( cv::ocl::useOpenCL() ) + LOGD("OpenCV+OpenCL works OK!"); + else + LOGE("Can't init OpenCV with OpenCL TAPI"); } catch(cl::Error& e) { @@ -166,3 +177,38 @@ void procOCL_I2I(int texIn, int texOut, int w, int h) theQueue.finish(); LOGD("enqueueReleaseGLObjects() costs %d ms", getTimeInterval(t)); } + +void procOCL_OCV(int tex, int w, int h) +{ + int64_t t = getTimeMs(); + cl::ImageGL imgIn (theContext, CL_MEM_READ_ONLY, GL_TEXTURE_2D, 0, tex); + std::vector < cl::Memory > images(1, imgIn); + theQueue.enqueueAcquireGLObjects(&images); + theQueue.finish(); + cv::UMat uIn, uOut, uTmp; + cv::ocl::convertFromImage(imgIn(), uIn); + LOGD("loading texture data to OpenCV UMat costs %d ms", getTimeInterval(t)); + theQueue.enqueueReleaseGLObjects(&images); + + t = getTimeMs(); + //cv::blur(uIn, uOut, cv::Size(5, 5)); + cv::Laplacian(uIn, uTmp, CV_8U); + cv:multiply(uTmp, 10, uOut); + cv::ocl::finish(); + LOGD("OpenCV processing costs %d ms", getTimeInterval(t)); + + t = getTimeMs(); + cl::ImageGL imgOut(theContext, CL_MEM_WRITE_ONLY, GL_TEXTURE_2D, 0, tex); + images.clear(); + images.push_back(imgOut); + theQueue.enqueueAcquireGLObjects(&images); + cl_mem clBuffer = (cl_mem)uOut.handle(cv::ACCESS_READ); + cl_command_queue q = (cl_command_queue)cv::ocl::Queue::getDefault().ptr(); + size_t offset = 0; + size_t origin[3] = { 0, 0, 0 }; + size_t region[3] = { w, h, 1 }; + CV_Assert(clEnqueueCopyBufferToImage (q, clBuffer, imgOut(), offset, origin, region, 0, NULL, NULL) == CL_SUCCESS); + theQueue.enqueueReleaseGLObjects(&images); + cv::ocl::finish(); + LOGD("uploading results to texture costs %d ms", getTimeInterval(t)); +} diff --git a/samples/android/tutorial-4-opencl/jni/GLrender.cpp b/samples/android/tutorial-4-opencl/jni/GLrender.cpp index ad239dd4f..da671fd59 100644 --- a/samples/android/tutorial-4-opencl/jni/GLrender.cpp +++ b/samples/android/tutorial-4-opencl/jni/GLrender.cpp @@ -238,17 +238,18 @@ void drawFrameProcCPU() drawTex(FBOtex, GL_TEXTURE_2D, 0); } -void procOCL(int tex, int w, int h); void procOCL_I2I(int texIn, int texOut, int w, int h); +void procOCL_OCV(int tex, int w, int h); void drawFrameProcOCL() { drawTex(texOES, GL_TEXTURE_EXTERNAL_OES, FBO); // modify pixels in FBO texture using OpenCL and CL-GL interop - procOCL_I2I(FBOtex, FBOtex2, texWidth, texHeight); + //procOCL_I2I(FBOtex, FBOtex2, texWidth, texHeight); + procOCL_OCV(FBOtex, texWidth, texHeight); // render to screen - drawTex(FBOtex2, GL_TEXTURE_2D, 0); + drawTex(/*FBOtex2*/FBOtex, GL_TEXTURE_2D, 0); } diff --git a/samples/android/tutorial-4-opencl/src/org/opencv/samples/tutorial4/NativeGLRenderer.java b/samples/android/tutorial-4-opencl/src/org/opencv/samples/tutorial4/NativeGLRenderer.java index 19a1337b7..dfd0a2489 100644 --- a/samples/android/tutorial-4-opencl/src/org/opencv/samples/tutorial4/NativeGLRenderer.java +++ b/samples/android/tutorial-4-opencl/src/org/opencv/samples/tutorial4/NativeGLRenderer.java @@ -3,6 +3,7 @@ package org.opencv.samples.tutorial4; public class NativeGLRenderer { static { + System.loadLibrary("opencv_java3"); System.loadLibrary("JNIrender"); } public static native int initGL();