}
+
// true if we have initialized OpenCL subsystem with available platforms
-static bool g_isOpenCLActivated = false;
+static bool g_isOpenCLInitialized = false;
+static bool g_isOpenCLAvailable = false;
bool haveOpenCL()
{
CV_TRACE_FUNCTION();
- static bool g_isOpenCLInitialized = false;
- static bool g_isOpenCLAvailable = false;
if (!g_isOpenCLInitialized)
{
{
cl_uint n = 0;
g_isOpenCLAvailable = ::clGetPlatformIDs(0, NULL, &n) == CL_SUCCESS;
- g_isOpenCLActivated = n > 0;
+ g_isOpenCLAvailable &= n > 0;
CV_LOG_INFO(NULL, "OpenCL: found " << n << " platforms");
}
catch (...)
bool isOpenCLActivated()
{
- if (!g_isOpenCLActivated)
+ if (!g_isOpenCLAvailable)
return false; // prevent unnecessary OpenCL activation via useOpenCL()->haveOpenCL() calls
return useOpenCL();
}
haveTempSrcUMats = true; // UMat is created on RAW memory (without proper lifetime management, even from Mat)
}
- void addImage(const Image2D& image)
+ /// Preserve image lifetime (while it is specified as Kernel argument)
+ void registerImageArgument(int arg, const Image2D& image)
{
- images.push_back(image);
+ CV_CheckGE(arg, 0, "");
+ CV_CheckLT(arg, (int)MAX_ARRS, "");
+ if (arg < (int)shadow_images.size() && shadow_images[arg].ptr() != image.ptr()) // TODO future: replace ptr => impl (more strong check)
+ {
+ CV_Check(arg, !isInProgress, "ocl::Kernel: clearing of pending Image2D arguments is not allowed");
+ }
+ shadow_images.reserve(MAX_ARRS);
+ shadow_images.resize(std::max(shadow_images.size(), (size_t)arg + 1));
+ shadow_images[arg] = image;
}
void finit(cl_event e)
{
CV_UNUSED(e);
cleanupUMats();
- images.clear();
isInProgress = false;
release();
}
bool isInProgress;
bool isAsyncRun; // true if kernel was scheduled in async mode
int nu;
- std::list<Image2D> images;
+ std::vector<Image2D> shadow_images;
bool haveTempDstUMats;
bool haveTempSrcUMats;
};
int Kernel::set(int i, const Image2D& image2D)
{
- p->addImage(image2D);
cl_mem h = (cl_mem)image2D.ptr();
- return set(i, &h, sizeof(h));
+ int res = set(i, &h, sizeof(h));
+ if (res >= 0)
+ p->registerImageArgument(i, image2D);
+ return res;
}
int Kernel::set(int i, const UMat& m)