namespace cv {
namespace ocl {
+#if defined(WIN32)
+static bool __termination = false;
+#endif
+
struct __Module
{
__Module();
// nothing
}
+class ContextImpl;
+
+struct CommandQueue
+{
+ ContextImpl* context_;
+ cl_command_queue clQueue_;
+
+ CommandQueue() : context_(NULL), clQueue_(NULL) { }
+ ~CommandQueue() { release(); }
+
+ void create(ContextImpl* context_);
+ void release()
+ {
+#ifdef WIN32
+ // if process is on termination stage (ExitProcess was called and other threads were terminated)
+ // then disable command queue release because it may cause program hang
+ if (!__termination)
+#endif
+ {
+ if(clQueue_)
+ {
+ openCLSafeCall(clReleaseCommandQueue(clQueue_)); // some cleanup problems are here
+ }
+
+ }
+ clQueue_ = NULL;
+ context_ = NULL;
+ }
+};
+
+cv::TLSData<CommandQueue> commandQueueTLSData;
+
//////////////////////////////// OpenCL context ////////////////////////
//This is a global singleton class used to represent a OpenCL context.
class ContextImpl : public Context
public:
const cl_device_id clDeviceID;
cl_context clContext;
- cl_command_queue clCmdQueue;
const DeviceInfo& deviceInfo;
protected:
ContextImpl(const DeviceInfo& deviceInfo, cl_device_id clDeviceID)
- : clDeviceID(clDeviceID), clContext(NULL), clCmdQueue(NULL), deviceInfo(deviceInfo)
+ : clDeviceID(clDeviceID), clContext(NULL), deviceInfo(deviceInfo)
{
// nothing
}
const void* Context::getOpenCLCommandQueuePtr() const
{
- return &(((ContextImpl*)this)->clCmdQueue);
+ ContextImpl* pThis = (ContextImpl*)this;
+ CommandQueue* commandQueue = commandQueueTLSData.get();
+ if (commandQueue->context_ != pThis)
+ {
+ commandQueue->create(pThis);
+ }
+ return &commandQueue->clQueue_;
}
const void* Context::getOpenCLDeviceIDPtr() const
return false;
}
-#if defined(WIN32)
-static bool __termination = false;
-#endif
-
ContextImpl::~ContextImpl()
{
#ifdef WIN32
if (!__termination)
#endif
{
- if(clCmdQueue)
- {
- openCLSafeCall(clReleaseCommandQueue(clCmdQueue)); // some cleanup problems are here
- }
-
if(clContext)
{
openCLSafeCall(clReleaseContext(clContext));
}
}
- clCmdQueue = NULL;
clContext = NULL;
}
cl_context_properties cps[3] = { CL_CONTEXT_PLATFORM, (cl_context_properties)(infoImpl.platform_id), 0 };
cl_context clContext = clCreateContext(cps, 1, &infoImpl.device_id, NULL, NULL, &status);
openCLVerifyCall(status);
- // TODO add CL_QUEUE_PROFILING_ENABLE
- cl_command_queue clCmdQueue = clCreateCommandQueue(clContext, infoImpl.device_id, 0, &status);
- openCLVerifyCall(status);
ContextImpl* ctx = new ContextImpl(infoImpl.info, infoImpl.device_id);
- ctx->clCmdQueue = clCmdQueue;
ctx->clContext = clContext;
ContextImpl* old = NULL;
}
}
+void CommandQueue::create(ContextImpl* context)
+{
+ release();
+ cl_int status = 0;
+ // TODO add CL_QUEUE_PROFILING_ENABLE
+ cl_command_queue clCmdQueue = clCreateCommandQueue(context->clContext, context->clDeviceID, 0, &status);
+ openCLVerifyCall(status);
+ context_ = context;
+ clQueue_ = clCmdQueue;
+}
+
int getOpenCLPlatforms(PlatformsInfo& platforms)
{
if (!__initialized)