From 44d9d59f085bbf8c0adde6b713c680332ac566fe Mon Sep 17 00:00:00 2001
From: Alexander Alekhin <alexander.alekhin@intel.com>
Date: Sun, 4 Dec 2016 02:19:38 +0300
Subject: [PATCH] ocl: stop using of OpenCL without explicit UMat arguments

---
 modules/core/include/opencv2/core/ocl.hpp |  3 +++
 modules/core/src/ocl.cpp                  | 12 ++++++++++++
 modules/features2d/src/orb.cpp            |  2 +-
 modules/objdetect/src/cascadedetect.cpp   |  5 +++--
 4 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/modules/core/include/opencv2/core/ocl.hpp b/modules/core/include/opencv2/core/ocl.hpp
index 8bbead49d5..1a9549df4c 100644
--- a/modules/core/include/opencv2/core/ocl.hpp
+++ b/modules/core/include/opencv2/core/ocl.hpp
@@ -739,6 +739,9 @@ CV_EXPORTS MatAllocator* getOpenCLAllocator();
 #ifdef __OPENCV_BUILD
 namespace internal {
 
+CV_EXPORTS bool isOpenCLForced();
+#define OCL_FORCE_CHECK(condition) (cv::ocl::internal::isOpenCLForced() || (condition))
+
 CV_EXPORTS bool isPerformanceCheckBypassed();
 #define OCL_PERFORMANCE_CHECK(condition) (cv::ocl::internal::isPerformanceCheckBypassed() || (condition))
 
diff --git a/modules/core/src/ocl.cpp b/modules/core/src/ocl.cpp
index 045b57a6ea..60ecc69546 100644
--- a/modules/core/src/ocl.cpp
+++ b/modules/core/src/ocl.cpp
@@ -6073,6 +6073,18 @@ void* Image2D::ptr() const
     return p ? p->handle : 0;
 }
 
+bool internal::isOpenCLForced()
+{
+    static bool initialized = false;
+    static bool value = false;
+    if (!initialized)
+    {
+        value = getBoolParameter("OPENCV_OPENCL_FORCE", false);
+        initialized = true;
+    }
+    return value;
+}
+
 bool internal::isPerformanceCheckBypassed()
 {
     static bool initialized = false;
diff --git a/modules/features2d/src/orb.cpp b/modules/features2d/src/orb.cpp
index 219e86e109..3b508e4f83 100644
--- a/modules/features2d/src/orb.cpp
+++ b/modules/features2d/src/orb.cpp
@@ -972,7 +972,7 @@ void ORB_Impl::detectAndCompute( InputArray _image, InputArray _mask,
     int halfPatchSize = patchSize / 2;
     int border = std::max(edgeThreshold, std::max(halfPatchSize, HARRIS_BLOCK_SIZE/2))+1;
 
-    bool useOCL = ocl::useOpenCL();
+    bool useOCL = ocl::useOpenCL() && OCL_FORCE_CHECK(_image.isUMat() || _descriptors.isUMat());
 
     Mat image = _image.getMat(), mask = _mask.getMat();
     if( image.type() != CV_8UC1 )
diff --git a/modules/objdetect/src/cascadedetect.cpp b/modules/objdetect/src/cascadedetect.cpp
index 1b99a7c28c..1670ddf69f 100644
--- a/modules/objdetect/src/cascadedetect.cpp
+++ b/modules/objdetect/src/cascadedetect.cpp
@@ -1290,8 +1290,8 @@ void CascadeClassifierImpl::detectMultiScaleNoGrouping( InputArray _image, std::
 
 #ifdef HAVE_OPENCL
     bool use_ocl = tryOpenCL && ocl::useOpenCL() &&
+         OCL_FORCE_CHECK(_image.isUMat()) &&
          featureEvaluator->getLocalSize().area() > 0 &&
-         ocl::Device::getDefault().type() != ocl::Device::TYPE_CPU &&
          (data.minNodesPerTree == data.maxNodesPerTree) &&
          !isOldFormatCascade() &&
          maskGenerator.empty() &&
@@ -1316,7 +1316,8 @@ void CascadeClassifierImpl::detectMultiScaleNoGrouping( InputArray _image, std::
     // OpenCL code
     CV_OCL_RUN(use_ocl, ocl_detectMultiScaleNoGrouping( scales, candidates ))
 
-    tryOpenCL = false;
+    if (use_ocl)
+        tryOpenCL = false;
 #endif
 
     // CPU code