Commit 9d8d70d6 authored by Roman Donchenko's avatar Roman Donchenko

Merge remote-tracking branch 'origin/2.4' into merge-2.4

Conflicts:
	doc/tutorials/definitions/tocDefinitions.rst
	modules/core/include/opencv2/core/core.hpp
	modules/core/src/system.cpp
	modules/features2d/src/freak.cpp
	modules/ocl/include/opencv2/ocl/ocl.hpp
	modules/ocl/src/cl_context.cpp
	modules/ocl/test/test_api.cpp
parents 172a5d42 e88253cc
......@@ -11,5 +11,6 @@
.. |Author_EricCh| unicode:: Eric U+0020 Christiansen
.. |Author_AndreyP| unicode:: Andrey U+0020 Pavlenko
.. |Author_AlexS| unicode:: Alexander U+0020 Smorkalov
.. |Author_MimmoC| unicode:: Mimmo U+0020 Cosenza
.. |Author_BarisD| unicode:: Bar U+0131 U+015F U+0020 Evrim U+0020 Demir U+00F6 z
.. |Author_DomenicoB| unicode:: Domenico U+0020 Daniele U+0020 Bloisi
......@@ -156,6 +156,21 @@ world of the OpenCV.
:height: 90pt
:width: 90pt
================ =================================================
|ClojureLogo| **Title:** :ref:`clojure_dev_intro`
*Compatibility:* > OpenCV 2.4.4
*Author:* |Author_MimmoC|
A tutorial on how to interactively use OpenCV from the Clojure REPL.
================ =================================================
.. |ClojureLogo| image:: images/clojure-logo.png
:height: 90pt
:width: 90pt
* **Android**
.. tabularcolumns:: m{100pt} m{300pt}
......@@ -314,6 +329,7 @@ world of the OpenCV.
../windows_visual_studio_image_watch/windows_visual_studio_image_watch
../desktop_java/java_dev_intro
../java_eclipse/java_eclipse
../clojure_dev_intro/clojure_dev_intro
../android_binary_package/android_dev_intro
../android_binary_package/O4A_SDK
../android_binary_package/dev_with_OCV_on_Android
......
......@@ -305,6 +305,32 @@ private:
AutoLock& operator = (const AutoLock&);
};
class TLSDataContainer
{
private:
int key_;
protected:
CV_EXPORTS TLSDataContainer();
CV_EXPORTS ~TLSDataContainer(); // virtual is not required
public:
virtual void* createDataInstance() const = 0;
virtual void deleteDataInstance(void* data) const = 0;
CV_EXPORTS void* getData() const;
};
template <typename T>
class TLSData : protected TLSDataContainer
{
public:
inline TLSData() {}
inline ~TLSData() {}
inline T* get() const { return (T*)getData(); }
private:
virtual void* createDataInstance() const { return new T; }
virtual void deleteDataInstance(void* data) const { delete (T*)data; }
};
// The CommandLineParser class is designed for command line arguments parsing
class CV_EXPORTS CommandLineParser
......
......@@ -738,26 +738,6 @@ namespace cv {
bool __termination = false;
}
#if defined CVAPI_EXPORTS && defined WIN32 && !defined WINCE
#ifdef HAVE_WINRT
#pragma warning(disable:4447) // Disable warning 'main' signature found without threading model
#endif
BOOL WINAPI DllMain( HINSTANCE, DWORD, LPVOID );
BOOL WINAPI DllMain( HINSTANCE, DWORD fdwReason, LPVOID lpReserved )
{
if( fdwReason == DLL_THREAD_DETACH || fdwReason == DLL_PROCESS_DETACH )
{
if (lpReserved != NULL) // called after ExitProcess() call
cv::__termination = true;
cv::deleteThreadAllocData();
cv::deleteThreadData();
}
return TRUE;
}
#endif
namespace cv
{
......@@ -841,8 +821,225 @@ void Mutex::lock() { impl->lock(); }
void Mutex::unlock() { impl->unlock(); }
bool Mutex::trylock() { return impl->trylock(); }
//////////////////////////////// thread-local storage ////////////////////////////////
class TLSStorage
{
std::vector<void*> tlsData_;
public:
TLSStorage() { tlsData_.reserve(16); }
~TLSStorage();
inline void* getData(int key) const
{
CV_DbgAssert(key >= 0);
return (key < (int)tlsData_.size()) ? tlsData_[key] : NULL;
}
inline void setData(int key, void* data)
{
CV_DbgAssert(key >= 0);
if (key >= (int)tlsData_.size())
{
tlsData_.resize(key + 1, NULL);
}
tlsData_[key] = data;
}
inline static TLSStorage* get();
};
#ifdef WIN32
#pragma warning(disable:4505) // unreferenced local function has been removed
#ifdef HAVE_WINRT
// using C++11 thread attribute for local thread data
static __declspec( thread ) TLSStorage* g_tlsdata = NULL;
static void deleteThreadData()
{
if (g_tlsdata)
{
delete g_tlsdata;
g_tlsdata = NULL;
}
}
inline TLSStorage* TLSStorage::get()
{
if (!g_tlsdata)
{
g_tlsdata = new TLSStorage;
}
return g_tlsdata;
}
#else
#ifdef WINCE
# define TLS_OUT_OF_INDEXES ((DWORD)0xFFFFFFFF)
#endif
static DWORD tlsKey = TLS_OUT_OF_INDEXES;
static void deleteThreadData()
{
if(tlsKey != TLS_OUT_OF_INDEXES)
{
delete (TLSStorage*)TlsGetValue(tlsKey);
TlsSetValue(tlsKey, NULL);
}
}
inline TLSStorage* TLSStorage::get()
{
if (tlsKey == TLS_OUT_OF_INDEXES)
{
tlsKey = TlsAlloc();
CV_Assert(tlsKey != TLS_OUT_OF_INDEXES);
}
TLSStorage* d = (TLSStorage*)TlsGetValue(tlsKey);
if (!d)
{
d = new TLSStorage;
TlsSetValue(tlsKey, d);
}
return d;
}
#endif //HAVE_WINRT
#if defined CVAPI_EXPORTS && defined WIN32 && !defined WINCE
#ifdef HAVE_WINRT
#pragma warning(disable:4447) // Disable warning 'main' signature found without threading model
#endif
BOOL WINAPI DllMain(HINSTANCE, DWORD fdwReason, LPVOID);
BOOL WINAPI DllMain(HINSTANCE, DWORD fdwReason, LPVOID)
{
if (fdwReason == DLL_THREAD_DETACH || fdwReason == DLL_PROCESS_DETACH)
{
cv::deleteThreadAllocData();
cv::deleteThreadRNGData();
cv::deleteThreadData();
}
return TRUE;
}
#endif
#else
static pthread_key_t tlsKey = 0;
static pthread_once_t tlsKeyOnce = PTHREAD_ONCE_INIT;
static void deleteTLSStorage(void* data)
{
delete (TLSStorage*)data;
}
static void makeKey()
{
int errcode = pthread_key_create(&tlsKey, deleteTLSStorage);
CV_Assert(errcode == 0);
}
inline TLSStorage* TLSStorage::get()
{
pthread_once(&tlsKeyOnce, makeKey);
TLSStorage* d = (TLSStorage*)pthread_getspecific(tlsKey);
if( !d )
{
d = new TLSStorage;
pthread_setspecific(tlsKey, d);
}
return d;
}
#endif
class TLSContainerStorage
{
cv::Mutex mutex_;
std::vector<TLSDataContainer*> tlsContainers_;
public:
TLSContainerStorage() { }
~TLSContainerStorage()
{
for (size_t i = 0; i < tlsContainers_.size(); i++)
{
CV_DbgAssert(tlsContainers_[i] == NULL); // not all keys released
tlsContainers_[i] = NULL;
}
}
int allocateKey(TLSDataContainer* pContainer)
{
cv::AutoLock lock(mutex_);
tlsContainers_.push_back(pContainer);
return (int)tlsContainers_.size() - 1;
}
void releaseKey(int id, TLSDataContainer* pContainer)
{
cv::AutoLock lock(mutex_);
CV_Assert(tlsContainers_[id] == pContainer);
tlsContainers_[id] = NULL;
// currently, we don't go into thread's TLSData and release data for this key
}
void destroyData(int key, void* data)
{
cv::AutoLock lock(mutex_);
TLSDataContainer* k = tlsContainers_[key];
if (!k)
return;
try
{
k->deleteDataInstance(data);
}
catch (...)
{
CV_DbgAssert(k == NULL); // Debug this!
}
}
};
static TLSContainerStorage tlsContainerStorage;
TLSDataContainer::TLSDataContainer()
: key_(-1)
{
key_ = tlsContainerStorage.allocateKey(this);
}
TLSDataContainer::~TLSDataContainer()
{
tlsContainerStorage.releaseKey(key_, this);
key_ = -1;
}
void* TLSDataContainer::getData() const
{
CV_Assert(key_ >= 0);
TLSStorage* tlsData = TLSStorage::get();
void* data = tlsData->getData(key_);
if (!data)
{
data = this->createDataInstance();
CV_DbgAssert(data != NULL);
tlsData->setData(key_, data);
}
return data;
}
TLSStorage::~TLSStorage()
{
for (int i = 0; i < (int)tlsData_.size(); i++)
{
void*& data = tlsData_[i];
if (data)
{
tlsContainerStorage.destroyData(i, data);
data = NULL;
}
}
tlsData_.clear();
}
} // namespace cv
//////////////////////////////// thread-local storage ////////////////////////////////
namespace cv
......
This diff is collapsed.
......@@ -5,4 +5,7 @@ endif()
set(the_description "OpenCL-accelerated Computer Vision")
ocv_define_module(ocl opencv_core opencv_imgproc opencv_features2d opencv_objdetect opencv_video opencv_calib3d opencv_ml "${OPENCL_LIBRARIES}")
if(TARGET opencv_test_ocl)
target_link_libraries(opencv_test_ocl "${OPENCL_LIBRARIES}")
endif()
ocv_warnings_disable(CMAKE_CXX_FLAGS -Wshadow)
......@@ -25,12 +25,26 @@ Returns the list of devices
ocl::setDevice
--------------
Returns void
Initialize OpenCL computation context
.. ocv:function:: void ocl::setDevice( const DeviceInfo* info )
:param info: device info
ocl::initializeContext
--------------------------------
Alternative way to initialize OpenCL computation context.
.. ocv:function:: void ocl::initializeContext(void* pClPlatform, void* pClContext, void* pClDevice)
:param pClPlatform: selected ``platform_id`` (via pointer, parameter type is ``cl_platform_id*``)
:param pClContext: selected ``cl_context`` (via pointer, parameter type is ``cl_context*``)
:param pClDevice: selected ``cl_device_id`` (via pointer, parameter type is ``cl_device_id*``)
This function can be used for context initialization with D3D/OpenGL interoperability.
ocl::setBinaryPath
------------------
Returns void
......
......@@ -118,6 +118,7 @@ namespace cv
const PlatformInfo* platform;
DeviceInfo();
~DeviceInfo();
};
struct PlatformInfo
......@@ -136,6 +137,7 @@ namespace cv
std::vector<const DeviceInfo*> devices;
PlatformInfo();
~PlatformInfo();
};
//////////////////////////////// Initialization & Info ////////////////////////
......@@ -151,6 +153,10 @@ namespace cv
// set device you want to use
CV_EXPORTS void setDevice(const DeviceInfo* info);
// Initialize from OpenCL handles directly.
// Argument types is (pointers): cl_platform_id*, cl_context*, cl_device_id*
CV_EXPORTS void initializeContext(void* pClPlatform, void* pClContext, void* pClDevice);
enum FEATURE_TYPE
{
FEATURE_CL_DOUBLE = 1,
......
......@@ -175,6 +175,7 @@ namespace cv
data = m.data;
datastart = m.datastart;
dataend = m.dataend;
clCxt = m.clCxt;
wholerows = m.wholerows;
wholecols = m.wholecols;
offset = m.offset;
......
This diff is collapsed.
......@@ -40,7 +40,7 @@
//M*/
#include "test_precomp.hpp"
#include "opencv2/core/opencl/runtime/opencl_core.hpp" // for OpenCL types: cl_mem
#include "opencv2/core/opencl/runtime/opencl_core.hpp" // for OpenCL types & functions
#include "opencv2/core/ocl.hpp"
TEST(TestAPI, openCLExecuteKernelInterop)
......@@ -127,3 +127,87 @@ TEST(OCL_TestTAPI, performance)
t = (double)cv::getTickCount() - t;
printf("cpu exec time = %gms per iter\n", t*1000./niters/cv::getTickFrequency());
}
// This test must be DISABLED by default!
// (We can't restore original context for other tests)
TEST(TestAPI, DISABLED_InitializationFromHandles)
{
#define MAX_PLATFORMS 16
cl_platform_id platforms[MAX_PLATFORMS] = { NULL };
cl_uint numPlatforms = 0;
cl_int status = ::clGetPlatformIDs(MAX_PLATFORMS, &platforms[0], &numPlatforms);
ASSERT_EQ(CL_SUCCESS, status) << "clGetPlatformIDs";
ASSERT_NE(0, (int)numPlatforms);
int selectedPlatform = 0;
cl_platform_id platform = platforms[selectedPlatform];
ASSERT_NE((void*)NULL, platform);
cl_device_id device = NULL;
status = ::clGetDeviceIDs(platform, CL_DEVICE_TYPE_ALL, 1, &device, NULL);
ASSERT_EQ(CL_SUCCESS, status) << "clGetDeviceIDs";
ASSERT_NE((void*)NULL, device);
cl_context_properties cps[3] = { CL_CONTEXT_PLATFORM, (cl_context_properties)(platform), 0 };
cl_context context = ::clCreateContext(cps, 1, &device, NULL, NULL, &status);
ASSERT_EQ(CL_SUCCESS, status) << "clCreateContext";
ASSERT_NE((void*)NULL, context);
ASSERT_NO_THROW(cv::ocl::initializeContext(&platform, &context, &device));
status = ::clReleaseContext(context);
ASSERT_EQ(CL_SUCCESS, status) << "clReleaseContext";
#ifdef CL_VERSION_1_2
#if 1
{
cv::ocl::Context* ctx = cv::ocl::Context::getContext();
ASSERT_NE((void*)NULL, ctx);
if (ctx->supportsFeature(cv::ocl::FEATURE_CL_VER_1_2)) // device supports OpenCL 1.2+
{
status = ::clReleaseDevice(device);
ASSERT_EQ(CL_SUCCESS, status) << "clReleaseDevice";
}
}
#else // code below doesn't work on Linux (SEGFAULTs on 1.1- devices are not handled via exceptions)
try
{
status = ::clReleaseDevice(device); // NOTE This works only with !DEVICES! that supports OpenCL 1.2
(void)status; // no check
}
catch (...)
{
// nothing, there is no problem
}
#endif
#endif
// print the name of current device
cv::ocl::Context* ctx = cv::ocl::Context::getContext();
ASSERT_NE((void*)NULL, ctx);
const cv::ocl::DeviceInfo& deviceInfo = ctx->getDeviceInfo();
std::cout << "Device name: " << deviceInfo.deviceName << std::endl;
std::cout << "Platform name: " << deviceInfo.platform->platformName << std::endl;
ASSERT_EQ(context, *(cl_context*)ctx->getOpenCLContextPtr());
ASSERT_EQ(device, *(cl_device_id*)ctx->getOpenCLDeviceIDPtr());
// do some calculations and check results
cv::RNG rng;
Size sz(100, 100);
cv::Mat srcMat = cvtest::randomMat(rng, sz, CV_32FC4, -10, 10, false);
cv::Mat dstMat;
cv::ocl::oclMat srcGpuMat(srcMat);
cv::ocl::oclMat dstGpuMat;
cv::Scalar v = cv::Scalar::all(1);
cv::add(srcMat, v, dstMat);
cv::ocl::add(srcGpuMat, v, dstGpuMat);
cv::Mat dstGpuMatMap;
dstGpuMat.download(dstGpuMatMap);
EXPECT_LE(checkNorm(dstMat, dstGpuMatMap), 1e-3);
}
......@@ -46,7 +46,7 @@ int main(int argc, char** argv)
const char* algorithm_opt = "--algorithm=";
const char* maxdisp_opt = "--max-disparity=";
const char* blocksize_opt = "--blocksize=";
const char* nodisplay_opt = "--no-display=";
const char* nodisplay_opt = "--no-display";
const char* scale_opt = "--scale=";
if(argc < 3)
......
/target
/classes
/checkouts
pom.xml
pom.xml.asc
*.jar
*.class
/.lein-*
/.nrepl-port
(defproject simple-sample "0.1.0-SNAPSHOT"
:pom-addition [:developers [:developer {:id "magomimmo"}
[:name "Mimmo Cosenza"]
[:url "https://github.com/magomimmoo"]]]
:description "A simple project to start REPLing with OpenCV"
:url "http://example.com/FIXME"
:license {:name "BSD 3-Clause License"
:url "http://opensource.org/licenses/BSD-3-Clause"}
:dependencies [[org.clojure/clojure "1.5.1"]
[opencv/opencv "2.4.7"]
[opencv/opencv-native "2.4.7"]]
:main simple-sample.core
:injections [(clojure.lang.RT/loadLibrary org.opencv.core.Core/NATIVE_LIBRARY_NAME)])
;;; to run this code from the terminal: "$ lein run". It will save a
;;; blurred image version of resources/images/lena.png as
;;; resources/images/blurred.png
(ns simple-sample.core
(:import [org.opencv.core Point Rect Mat CvType Size Scalar]
org.opencv.highgui.Highgui
org.opencv.imgproc.Imgproc))
(defn -main [& args]
(let [lena (Highgui/imread "resources/images/lena.png")
blurred (Mat. 512 512 CvType/CV_8UC3)]
(print "Blurring...")
(Imgproc/GaussianBlur lena blurred (Size. 5 5) 3 3)
(Highgui/imwrite "resources/images/blurred.png" blurred)
(println "done!")))
(ns simple-sample.core-test
(:require [clojure.test :refer :all]
[simple-sample.core :refer :all]))
(deftest a-test
(testing "FIXME, I fail."
(is (= 0 1))))
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment