[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [50348] trunk/blender/source/blender/ compositor/intern: Compositor: initialize OpenCL only when the option is enabled.

Brecht Van Lommel brechtvanlommel at pandora.be
Mon Sep 3 14:52:21 CEST 2012


Revision: 50348
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=50348
Author:   blendix
Date:     2012-09-03 12:52:21 +0000 (Mon, 03 Sep 2012)
Log Message:
-----------
Compositor: initialize OpenCL only when the option is enabled. This eliminates
error prints or even crashes for poor OpenCL implementations when not using it.

Modified Paths:
--------------
    trunk/blender/source/blender/compositor/intern/COM_WorkScheduler.cpp
    trunk/blender/source/blender/compositor/intern/COM_WorkScheduler.h
    trunk/blender/source/blender/compositor/intern/COM_compositor.cpp

Modified: trunk/blender/source/blender/compositor/intern/COM_WorkScheduler.cpp
===================================================================
--- trunk/blender/source/blender/compositor/intern/COM_WorkScheduler.cpp	2012-09-03 12:35:32 UTC (rev 50347)
+++ trunk/blender/source/blender/compositor/intern/COM_WorkScheduler.cpp	2012-09-03 12:52:21 UTC (rev 50348)
@@ -54,6 +54,7 @@
 #if COM_CURRENT_THREADING_MODEL == COM_TM_QUEUE
 /// @brief list of all thread for every CPUDevice in cpudevices a thread exists
 static ListBase g_cputhreads;
+static bool g_cpuInitialized = false;
 /// @brief all scheduled work for the cpu
 static ThreadQueue *g_cpuqueue;
 static ThreadQueue *g_gpuqueue;
@@ -67,11 +68,13 @@
 /// @brief all scheduled work for the gpu
 #ifdef COM_OPENCL_ENABLED
 static bool g_openclActive = false;
+static bool g_openclInitialized = false;
 #endif
 #endif
 #endif
 
 #define MAX_HIGHLIGHT 8
+static bool g_highlightInitialized = false;
 extern "C" {
 int g_highlightIndex;
 void **g_highlightedNodes;
@@ -255,40 +258,59 @@
 	printf("OPENCL error: %s\n", errinfo);
 }
 
-void WorkScheduler::initialize()
+void WorkScheduler::initialize(bool use_opencl)
 {
-	if (g_highlightedNodesRead) MEM_freeN(g_highlightedNodesRead);
-	if (g_highlightedNodes)     MEM_freeN(g_highlightedNodes);
+	/* initialize highlighting */
+	if (!g_highlightInitialized) {
+		if (g_highlightedNodesRead) MEM_freeN(g_highlightedNodesRead);
+		if (g_highlightedNodes)     MEM_freeN(g_highlightedNodes);
 
-	g_highlightedNodesRead = NULL;
-	g_highlightedNodes = NULL;
+		g_highlightedNodesRead = NULL;
+		g_highlightedNodes = NULL;
 
-	COM_startReadHighlights();
+		COM_startReadHighlights();
+
+		g_highlightInitialized = true;
+	}
+
 #if COM_CURRENT_THREADING_MODEL == COM_TM_QUEUE
-	int numberOfCPUThreads = BLI_system_thread_count();
+	/* initialize CPU threads */
+	if (!g_cpuInitialized) {
+		int numberOfCPUThreads = BLI_system_thread_count();
 
-	for (int index = 0; index < numberOfCPUThreads; index++) {
-		CPUDevice *device = new CPUDevice();
-		device->initialize();
-		g_cpudevices.push_back(device);
+		for (int index = 0; index < numberOfCPUThreads; index++) {
+			CPUDevice *device = new CPUDevice();
+			device->initialize();
+			g_cpudevices.push_back(device);
+		}
+
+		g_cpuInitialized = true;
 	}
+
 #ifdef COM_OPENCL_ENABLED
-	g_context = NULL;
-	g_program = NULL;
-	if (clCreateContextFromType) {
-		cl_uint numberOfPlatforms = 0;
-		cl_int error;
-		error = clGetPlatformIDs(0, 0, &numberOfPlatforms);
-		if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error));  }
-		if (G.f & G_DEBUG) printf("%d number of platforms\n", numberOfPlatforms);
-		cl_platform_id *platforms = (cl_platform_id *)MEM_mallocN(sizeof(cl_platform_id) * numberOfPlatforms, __func__);
-		error = clGetPlatformIDs(numberOfPlatforms, platforms, 0);
-		unsigned int indexPlatform;
-		for (indexPlatform = 0; indexPlatform < numberOfPlatforms; indexPlatform++) {
-			cl_platform_id platform = platforms[indexPlatform];
-			cl_uint numberOfDevices = 0;
-			clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 0, 0, &numberOfDevices);
-			if (numberOfDevices > 0) {
+	/* deinitialize OpenCL GPU's */
+	if (use_opencl && !g_openclInitialized) {
+		g_context = NULL;
+		g_program = NULL;
+
+		OCL_init(); /* this will check and skip if already initialized */
+
+		if (clCreateContextFromType) {
+			cl_uint numberOfPlatforms = 0;
+			cl_int error;
+			error = clGetPlatformIDs(0, 0, &numberOfPlatforms);
+			if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error));  }
+			if (G.f & G_DEBUG) printf("%d number of platforms\n", numberOfPlatforms);
+			cl_platform_id *platforms = (cl_platform_id *)MEM_mallocN(sizeof(cl_platform_id) * numberOfPlatforms, __func__);
+			error = clGetPlatformIDs(numberOfPlatforms, platforms, 0);
+			unsigned int indexPlatform;
+			for (indexPlatform = 0; indexPlatform < numberOfPlatforms; indexPlatform++) {
+				cl_platform_id platform = platforms[indexPlatform];
+				cl_uint numberOfDevices = 0;
+				clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 0, 0, &numberOfDevices);
+				if (numberOfDevices <= 0)
+					continue;
+
 				cl_device_id *cldevices = (cl_device_id *)MEM_mallocN(sizeof(cl_device_id) * numberOfDevices, __func__);
 				clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, numberOfDevices, cldevices, 0);
 
@@ -324,8 +346,10 @@
 				}
 				MEM_freeN(cldevices);
 			}
+			MEM_freeN(platforms);
 		}
-		MEM_freeN(platforms);
+
+		g_openclInitialized = true;
 	}
 #endif
 #endif
@@ -334,37 +358,51 @@
 void WorkScheduler::deinitialize()
 {
 #if COM_CURRENT_THREADING_MODEL == COM_TM_QUEUE
-	Device *device;
-	while (g_cpudevices.size() > 0) {
-		device = g_cpudevices.back();
-		g_cpudevices.pop_back();
-		device->deinitialize();
-		delete device;
+	/* deinitialize CPU threads */
+	if (g_cpuInitialized) {
+		Device *device;
+		while (g_cpudevices.size() > 0) {
+			device = g_cpudevices.back();
+			g_cpudevices.pop_back();
+			device->deinitialize();
+			delete device;
+		}
+
+		g_cpuInitialized = false;
 	}
+
 #ifdef COM_OPENCL_ENABLED
-	while (g_gpudevices.size() > 0) {
-		device = g_gpudevices.back();
-		g_gpudevices.pop_back();
-		device->deinitialize();
-		delete device;
+	/* deinitialize OpenCL GPU's */
+	if (g_openclInitialized) {
+		while (g_gpudevices.size() > 0) {
+			device = g_gpudevices.back();
+			g_gpudevices.pop_back();
+			device->deinitialize();
+			delete device;
+		}
+		if (g_program) {
+			clReleaseProgram(g_program);
+			g_program = NULL;
+		}
+		if (g_context) {
+			clReleaseContext(g_context);
+			g_context = NULL;
+		}
+
+		g_openclInitialized = false;
 	}
-	if (g_program) {
-		clReleaseProgram(g_program);
-		g_program = NULL;
-	}
-	if (g_context) {
-		clReleaseContext(g_context);
-		g_context = NULL;
-	}
 #endif
 #endif
 
-	if (g_highlightedNodes) {
-		MEM_freeN(g_highlightedNodes);
-	}
+	/* deinitialize highlighting */
+	if (g_highlightInitialized) {
+		if (g_highlightedNodes)
+			MEM_freeN(g_highlightedNodes);
 
-	if (g_highlightedNodesRead) {
-		MEM_freeN(g_highlightedNodesRead);
+		if (g_highlightedNodesRead)
+			MEM_freeN(g_highlightedNodesRead);
+
+		g_highlightInitialized = false;
 	}
 }
 

Modified: trunk/blender/source/blender/compositor/intern/COM_WorkScheduler.h
===================================================================
--- trunk/blender/source/blender/compositor/intern/COM_WorkScheduler.h	2012-09-03 12:35:32 UTC (rev 50347)
+++ trunk/blender/source/blender/compositor/intern/COM_WorkScheduler.h	2012-09-03 12:52:21 UTC (rev 50348)
@@ -74,8 +74,10 @@
 	 * After mutex initialization the system is queried in order to count the number of CPUDevices and GPUDevices to be created.
 	 * For every hardware thread a CPUDevice and for every OpenCL GPU device a OpenCLDevice is created.
 	 * these devices are stored in a separate list (cpudevices & gpudevices)
+	 *
+	 * This function can be called multiple times to lazily initialize OpenCL.
 	 */
-	static void initialize();
+	static void initialize(bool use_opencl);
 
 	/**
 	 * @brief deinitialize the WorkScheduler

Modified: trunk/blender/source/blender/compositor/intern/COM_compositor.cpp
===================================================================
--- trunk/blender/source/blender/compositor/intern/COM_compositor.cpp	2012-09-03 12:35:32 UTC (rev 50347)
+++ trunk/blender/source/blender/compositor/intern/COM_compositor.cpp	2012-09-03 12:52:21 UTC (rev 50348)
@@ -36,24 +36,29 @@
 
 static ThreadMutex s_compositorMutex;
 static char is_compositorMutex_init = FALSE;
+
 void COM_execute(RenderData *rd, bNodeTree *editingtree, int rendering)
 {
-	if (is_compositorMutex_init == FALSE) { /// TODO: move to blender startup phase
-		memset(&s_compositorMutex, 0, sizeof(s_compositorMutex));
+	/* initialize mutex, TODO this mutex init is actually not thread safe and
+	 * should be done somewhere as part of blender startup, all the other
+	 * initializations can be done lazily */
+	if (is_compositorMutex_init == FALSE) {
 		BLI_mutex_init(&s_compositorMutex);
-		OCL_init();
-		WorkScheduler::initialize(); ///TODO: call workscheduler.deinitialize somewhere
 		is_compositorMutex_init = TRUE;
 	}
+
 	BLI_mutex_lock(&s_compositorMutex);
+
 	if (editingtree->test_break(editingtree->tbh)) {
 		// during editing multiple calls to this method can be triggered.
 		// make sure one the last one will be doing the work.
 		BLI_mutex_unlock(&s_compositorMutex);
 		return;
-
 	}
 
+	/* initialize workscheduler, will check if already done. TODO deinitialize somewhere */
+	bool use_opencl = (editingtree->flag & NTREE_COM_OPENCL);
+	WorkScheduler::initialize(use_opencl);
 
 	/* set progress bar to 0% and status to init compositing */
 	editingtree->progress(editingtree->prh, 0.0);
@@ -83,11 +88,12 @@
 
 void COM_deinitialize() 
 {
-	if (is_compositorMutex_init)
-	{
+	if (is_compositorMutex_init) {
 		BLI_mutex_lock(&s_compositorMutex);
+
 		deintializeDistortionCache();
 		WorkScheduler::deinitialize();
+
 		is_compositorMutex_init = FALSE;
 		BLI_mutex_unlock(&s_compositorMutex);
 		BLI_mutex_end(&s_compositorMutex);




More information about the Bf-blender-cvs mailing list