[Bf-blender-cvs] [0e5f97a3a1b] blender2.8: Fix T58816: Color management Display Device other than sRGB crashes

Sergey Sharybin noreply at git.blender.org
Thu Dec 6 11:03:36 CET 2018


Commit: 0e5f97a3a1b3ad2bc49b2e553345bd191b2e06cf
Author: Sergey Sharybin
Date:   Thu Dec 6 10:55:31 2018 +0100
Branches: blender2.8
https://developer.blender.org/rB0e5f97a3a1b3ad2bc49b2e553345bd191b2e06cf

Fix T58816: Color management Display Device other than sRGB crashes

This fixes our workaround for until proper solution is accepted
in upstream.

Now, when default view behaves same as it was supposed to (and
as it behaves in OCIO-1.0.9) it is obvious that our configuration
violates own design -- default view  is used for cases when
images don't want to be displays using "render" settings.

===================================================================

M	intern/opencolorio/ocio_impl.cc

===================================================================

diff --git a/intern/opencolorio/ocio_impl.cc b/intern/opencolorio/ocio_impl.cc
index 4a6645f57b3..4c9115af810 100644
--- a/intern/opencolorio/ocio_impl.cc
+++ b/intern/opencolorio/ocio_impl.cc
@@ -64,7 +64,16 @@ using namespace OCIO_NAMESPACE;
  * For until then we use first usable display instead. */
 #define DEFAULT_DISPLAY_WORKAROUND
 #ifdef DEFAULT_DISPLAY_WORKAROUND
+#  include <algorithm>
+#  include <map>
 #  include <mutex>
+#  include <vector>
+#  include <string>
+#  include <set>
+using std::vector;
+using std::set;
+using std::string;
+using std::map;
 #endif
 
 static void OCIO_reportError(const char *err)
@@ -268,30 +277,89 @@ const char *OCIOImpl::configGetDisplay(OCIO_ConstConfigRcPtr *config, int index)
 	return NULL;
 }
 
+#ifdef DEFAULT_DISPLAY_WORKAROUND
+namespace {
+
+void splitStringEnvStyle(vector<string>* tokens, const string& str)
+{
+	tokens->clear();
+	const int len = str.length();
+	int token_start = 0, token_length = 0;
+	for (int i = 0; i < len; ++i) {
+		const char ch = str[i];
+		if (ch != ',' && ch != ':') {
+			/* Append non-separator char to a token. */
+			++token_length;
+		} else {
+			/* Append current token to the list (if any). */
+			if (token_length > 0) {
+				string token = str.substr(token_start, token_length);
+				tokens->push_back(token);
+			}
+			/* Re-set token pointers. */
+			token_start = i + 1;
+			token_length = 0;
+		}
+	}
+	/* Append token which might be at the end of the string. */
+	if (token_length != 0) {
+		string token = str.substr(token_start, token_length);
+		tokens->push_back(token);
+	}
+}
+
+string stringToLower(const string& str) {
+	string lower = str;
+	std::transform(lower.begin(), lower.end(), lower.begin(), tolower);
+	return lower;
+}
+
+}  // namespace
+#endif
+
 const char *OCIOImpl::configGetDefaultView(OCIO_ConstConfigRcPtr *config, const char *display)
 {
 #ifdef DEFAULT_DISPLAY_WORKAROUND
 	/* NOTE: We assume that first active view always exists for a default
 	 * display. */
 	if (getenv("OCIO_ACTIVE_VIEWS") == NULL) {
-		const char *active_views =
-		        (*(ConstConfigRcPtr *) config)->getActiveViews();
-		if (active_views[0] != '\0') {
-			const char *separator_pos = strchr(active_views, ',');
-			if (separator_pos == NULL) {
-				return active_views;
-			}
-			static std::string active_view;
-			/* NOTE: Configuration is shared and is never changed during runtime,
-			* so we only guarantee two threads don't initialize at the same. */
+		ConstConfigRcPtr config_ptr = *((ConstConfigRcPtr *) config);
+		const char *active_views_encoded = config_ptr->getActiveViews();
+		if (active_views_encoded[0] != '\0') {
+			const string display_lower = stringToLower(display);
+			static map<string, string> default_display_views;
 			static std::mutex mutex;
 			mutex.lock();
-			if (active_view.empty()) {
-				active_view = active_views;
-				active_view[separator_pos - active_views] = '\0';
+			/* Check if the view is already known. */
+			map<string, string>::const_iterator it =
+			        default_display_views.find(display_lower);
+			if (it != default_display_views.end()) {
+				mutex.unlock();
+				return it->second.c_str();
+			}
+			/* Active views. */
+			vector<string> active_views;
+			splitStringEnvStyle(&active_views, active_views_encoded);
+			/* Get all views supported by tge display. */
+			set<string> display_views;
+			const int num_display_views = config_ptr->getNumViews(display);
+			for (int view_index = 0;
+			     view_index < num_display_views;
+			     ++view_index)
+			{
+				const char *view = config_ptr->getView(display, view_index);
+				display_views.insert(stringToLower(view));
+			}
+			/* Get first view which is supported by tge display. */
+			for (const string& view : active_views) {
+				const string view_lower = stringToLower(view);
+				if (display_views.find(view_lower) != display_views.end()) {
+					default_display_views[display_lower] = view;
+					mutex.unlock();
+					return default_display_views[display_lower].c_str();
+				}
 			}
 			mutex.unlock();
-			return active_view.c_str();
 		}
 	}
 #endif



More information about the Bf-blender-cvs mailing list