diff --git a/3rdparty/openvx/hal/openvx_hal.cpp b/3rdparty/openvx/hal/openvx_hal.cpp index 1e87a9f240..852d6d98f6 100644 --- a/3rdparty/openvx/hal/openvx_hal.cpp +++ b/3rdparty/openvx/hal/openvx_hal.cpp @@ -52,8 +52,17 @@ struct Tick inline ivx::Context& getOpenVXHALContext() { - // not thread safe - static ivx::Context instance = ivx::Context::create(); +#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800) + //CXX11 + static thread_local ivx::Context instance = ivx::Context::create(); +#else //__cplusplus >= 201103L || _MSC_VER >= 1800 + //CXX98 +#ifdef WIN32 + static __declspec(thread) ivx::Context instance = ivx::Context::create(); +#else + static __thread ivx::Context instance = ivx::Context::create(); +#endif +#endif return instance; } diff --git a/modules/core/include/opencv2/core/openvx/ovx_defs.hpp b/modules/core/include/opencv2/core/openvx/ovx_defs.hpp index 3f055dd776..19964c4c47 100644 --- a/modules/core/include/opencv2/core/openvx/ovx_defs.hpp +++ b/modules/core/include/opencv2/core/openvx/ovx_defs.hpp @@ -20,6 +20,12 @@ #define IVX_USE_OPENCV #include "ivx.hpp" +namespace cv{ +namespace ovx{ +// Get common thread local OpenVX context +CV_EXPORTS_W ivx::Context& getOpenVXContext(); +}} + #define CV_OVX_RUN(condition, func, ...) \ if (cv::useOpenVX() && (condition) && func) \ { \ diff --git a/modules/core/src/convert.cpp b/modules/core/src/convert.cpp index e04d89ef27..6c060f9c9c 100644 --- a/modules/core/src/convert.cpp +++ b/modules/core/src/convert.cpp @@ -4673,7 +4673,7 @@ static bool _openvx_cvt(const T* src, size_t sstep, try { - Context context = Context::create(); + Context context = ovx::getOpenVXContext(); // Other conversions are marked as "experimental" if(context.vendorID() == VX_ID_KHRONOS && @@ -5406,7 +5406,7 @@ static bool openvx_LUT(Mat src, Mat dst, Mat _lut) try { - ivx::Context ctx = ivx::Context::create(); + ivx::Context ctx = ovx::getOpenVXContext(); ivx::Image ia = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U8, diff --git a/modules/core/src/ovx.cpp b/modules/core/src/ovx.cpp index a53f5533aa..d906ead09c 100644 --- a/modules/core/src/ovx.cpp +++ b/modules/core/src/ovx.cpp @@ -14,6 +14,38 @@ namespace cv { +namespace ovx +{ +#ifdef HAVE_OPENVX + +// Simple TLSData doesn't work, because default constructor doesn't create any OpenVX context. +struct OpenVXTLSData +{ + OpenVXTLSData() : ctx(ivx::Context::create()) {} + ivx::Context ctx; +}; + +static TLSData& getOpenVXTLSData() +{ + CV_SINGLETON_LAZY_INIT_REF(TLSData, new TLSData()) +} + +struct OpenVXCleanupFunctor +{ + ~OpenVXCleanupFunctor() { getOpenVXTLSData().cleanup(); } +}; +static OpenVXCleanupFunctor g_openvx_cleanup_functor; + +ivx::Context& getOpenVXContext() +{ + return getOpenVXTLSData().get()->ctx; +} + +#endif + +} // namespace + + bool haveOpenVX() { #ifdef HAVE_OPENVX @@ -22,7 +54,7 @@ bool haveOpenVX() { try { - ivx::Context context = ivx::Context::create(); + ivx::Context context = ovx::getOpenVXContext(); vx_uint16 vComp = ivx::compiledWithVersion(); vx_uint16 vCurr = context.version(); g_haveOpenVX = diff --git a/modules/core/src/stat.cpp b/modules/core/src/stat.cpp index 39e0fa7648..3c5fb73de4 100644 --- a/modules/core/src/stat.cpp +++ b/modules/core/src/stat.cpp @@ -1665,7 +1665,7 @@ namespace cv try { - ivx::Context ctx = ivx::Context::create(); + ivx::Context ctx = ovx::getOpenVXContext(); #ifndef VX_VERSION_1_1 if (ctx.vendorID() == VX_ID_KHRONOS) return false; // Do not use OpenVX meanStdDev estimation for sample 1.0.1 implementation due to lack of accuracy @@ -2312,7 +2312,7 @@ static bool openvx_minMaxIdx(Mat &src, double* minVal, double* maxVal, int* minI try { - ivx::Context ctx = ivx::Context::create(); + ivx::Context ctx = ovx::getOpenVXContext(); ivx::Image ia = ivx::Image::createFromHandle(ctx, stype == CV_8UC1 ? VX_DF_IMAGE_U8 : VX_DF_IMAGE_S16, ivx::Image::createAddressing(cols, rows, stype == CV_8UC1 ? 1 : 2, (vx_int32)(src.step[0])), src.ptr()); diff --git a/modules/features2d/src/fast.cpp b/modules/features2d/src/fast.cpp index 98d62a3b2c..8aad5b0433 100644 --- a/modules/features2d/src/fast.cpp +++ b/modules/features2d/src/fast.cpp @@ -354,7 +354,7 @@ static bool openvx_FAST(InputArray _img, std::vector& keypoints, try { - Context context = Context::create(); + Context context = ovx::getOpenVXContext(); Image img = Image::createFromHandle(context, Image::matTypeToFormat(imgMat.type()), Image::createAddressing(imgMat), (void*)imgMat.data); ivx::Scalar threshold = ivx::Scalar::create(context, _threshold); diff --git a/modules/imgproc/src/accum.cpp b/modules/imgproc/src/accum.cpp index 8c457e341b..34a7e07c39 100644 --- a/modules/imgproc/src/accum.cpp +++ b/modules/imgproc/src/accum.cpp @@ -1958,7 +1958,7 @@ static bool openvx_accumulate(InputArray _src, InputOutputArray _dst, InputArray try { - ivx::Context context = ivx::Context::create(); + ivx::Context context = ovx::getOpenVXContext(); ivx::Image srcImage = ivx::Image::createFromHandle(context, ivx::Image::matTypeToFormat(srcMat.type()), ivx::Image::createAddressing(srcMat), srcMat.data); ivx::Image dstImage = ivx::Image::createFromHandle(context, ivx::Image::matTypeToFormat(dstMat.type()), diff --git a/modules/imgproc/src/canny.cpp b/modules/imgproc/src/canny.cpp index cdc4e7aac3..d10b5f7dfa 100644 --- a/modules/imgproc/src/canny.cpp +++ b/modules/imgproc/src/canny.cpp @@ -782,7 +782,7 @@ static bool openvx_canny(const Mat& src, Mat& dst, int loVal, int hiVal, int kSi { using namespace ivx; - Context context = Context::create(); + Context context = ovx::getOpenVXContext(); try { Image _src = Image::createFromHandle( diff --git a/modules/imgproc/src/deriv.cpp b/modules/imgproc/src/deriv.cpp index 01352be333..8486ec899b 100644 --- a/modules/imgproc/src/deriv.cpp +++ b/modules/imgproc/src/deriv.cpp @@ -236,7 +236,7 @@ namespace cv try { - ivx::Context ctx = ivx::Context::create(); + ivx::Context ctx = ovx::getOpenVXContext(); if ((vx_size)ksize > ctx.convolutionMaxDimension()) return false; diff --git a/modules/imgproc/src/featureselect.cpp b/modules/imgproc/src/featureselect.cpp index fc1b034209..ee94153900 100644 --- a/modules/imgproc/src/featureselect.cpp +++ b/modules/imgproc/src/featureselect.cpp @@ -286,7 +286,7 @@ static bool openvx_harris(Mat image, OutputArray _corners, try { - Context context = Context::create(); + Context context = ovx::getOpenVXContext(); Image ovxImage = Image::createFromHandle(context, Image::matTypeToFormat(image.type()), Image::createAddressing(image), image.data); diff --git a/modules/imgproc/src/histogram.cpp b/modules/imgproc/src/histogram.cpp index 235f34786f..a0a2909511 100644 --- a/modules/imgproc/src/histogram.cpp +++ b/modules/imgproc/src/histogram.cpp @@ -1282,7 +1282,7 @@ namespace cv try { - ivx::Context ctx = ivx::Context::create(); + ivx::Context ctx = ovx::getOpenVXContext(); #if VX_VERSION <= VX_VERSION_1_0 if (ctx.vendorID() == VX_ID_KHRONOS && (range % histSize)) return false; @@ -3773,7 +3773,7 @@ static bool openvx_equalize_hist(Mat srcMat, Mat dstMat) try { - Context context = Context::create(); + Context context = ovx::getOpenVXContext(); Image srcImage = Image::createFromHandle(context, Image::matTypeToFormat(srcMat.type()), Image::createAddressing(srcMat), srcMat.data); Image dstImage = Image::createFromHandle(context, Image::matTypeToFormat(dstMat.type()), diff --git a/modules/imgproc/src/imgwarp.cpp b/modules/imgproc/src/imgwarp.cpp index 2f0f2e9d4e..7bcf16a394 100644 --- a/modules/imgproc/src/imgwarp.cpp +++ b/modules/imgproc/src/imgwarp.cpp @@ -4795,7 +4795,7 @@ static bool openvx_remap(Mat src, Mat dst, Mat map1, Mat map2, int interpolation try { - ivx::Context ctx = ivx::Context::create(); + ivx::Context ctx = ovx::getOpenVXContext(); Mat a; if (dst.data != src.data) diff --git a/modules/imgproc/src/pyramids.cpp b/modules/imgproc/src/pyramids.cpp index c0e18c13bf..ff260d1783 100644 --- a/modules/imgproc/src/pyramids.cpp +++ b/modules/imgproc/src/pyramids.cpp @@ -1290,7 +1290,7 @@ static bool openvx_pyrDown( InputArray _src, OutputArray _dst, const Size& _dsz, try { - Context context = Context::create(); + Context context = ovx::getOpenVXContext(); if(context.vendorID() == VX_ID_KHRONOS) { // This implementation performs floor-like rounding diff --git a/modules/imgproc/src/smooth.cpp b/modules/imgproc/src/smooth.cpp index d8514da01b..8ee49fa777 100644 --- a/modules/imgproc/src/smooth.cpp +++ b/modules/imgproc/src/smooth.cpp @@ -1677,7 +1677,7 @@ namespace cv try { - ivx::Context ctx = ivx::Context::create(); + ivx::Context ctx = ovx::getOpenVXContext(); if ((vx_size)(ksize.width) > ctx.convolutionMaxDimension() || (vx_size)(ksize.height) > ctx.convolutionMaxDimension()) return false; @@ -2239,7 +2239,7 @@ static bool openvx_gaussianBlur(InputArray _src, OutputArray _dst, Size ksize, try { - ivx::Context ctx = ivx::Context::create(); + ivx::Context ctx = ovx::getOpenVXContext(); if ((vx_size)(ksize.width) > ctx.convolutionMaxDimension() || (vx_size)(ksize.height) > ctx.convolutionMaxDimension()) return false; @@ -3361,7 +3361,7 @@ namespace cv try { - ivx::Context ctx = ivx::Context::create(); + ivx::Context ctx = ovx::getOpenVXContext(); #ifdef VX_VERSION_1_1 if ((vx_size)ksize > ctx.nonlinearMaxDimension()) return false; diff --git a/modules/imgproc/src/thresh.cpp b/modules/imgproc/src/thresh.cpp index f4f329739f..bd2b73c0bb 100644 --- a/modules/imgproc/src/thresh.cpp +++ b/modules/imgproc/src/thresh.cpp @@ -1301,7 +1301,7 @@ static bool openvx_threshold(Mat src, Mat dst, int thresh, int maxval, int type) try { - ivx::Context ctx = ivx::Context::create(); + ivx::Context ctx = ovx::getOpenVXContext(); ivx::Threshold thh = ivx::Threshold::createBinary(ctx, VX_TYPE_UINT8, thresh); thh.setValueTrue(trueVal); diff --git a/modules/video/src/lkpyramid.cpp b/modules/video/src/lkpyramid.cpp index 7c89bc31fe..739bb10780 100644 --- a/modules/video/src/lkpyramid.cpp +++ b/modules/video/src/lkpyramid.cpp @@ -1099,7 +1099,7 @@ namespace try { - Context context = Context::create(); + Context context = ovx::getOpenVXContext(); if(context.vendorID() == VX_ID_KHRONOS) {