[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [58562] branches/soc-2013-viewport_fx: Added support for multiple EGL contexts.

Jason Wilkins Jason.A.Wilkins at gmail.com
Wed Jul 24 07:12:38 CEST 2013


Revision: 58562
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=58562
Author:   jwilkins
Date:     2013-07-24 05:12:38 +0000 (Wed, 24 Jul 2013)
Log Message:
-----------
Added support for multiple EGL contexts.

Modified Paths:
--------------
    branches/soc-2013-viewport_fx/CMakeLists.txt
    branches/soc-2013-viewport_fx/intern/ghost/intern/GHOST_WindowWin32.cpp
    branches/soc-2013-viewport_fx/intern/ghost/intern/GHOST_WindowWin32.h
    branches/soc-2013-viewport_fx/intern/ghost/intern/GHOST_WindowX11.cpp

Modified: branches/soc-2013-viewport_fx/CMakeLists.txt
===================================================================
--- branches/soc-2013-viewport_fx/CMakeLists.txt	2013-07-24 05:01:22 UTC (rev 58561)
+++ branches/soc-2013-viewport_fx/CMakeLists.txt	2013-07-24 05:12:38 UTC (rev 58562)
@@ -1995,6 +1995,8 @@
 		#set(SYSTEM_GL_INCLUDE_DIR "${ANGLE_INCLUDE_PATH}")
 		set(SYSTEM_GL_LIBRARIES   "${ANGLE_GLESv2_LIBRARY}")
 		list(APPEND SYSTEM_GL_LIBRARIES "${ANGLE_EGL_LIBRARY}")
+
+		set(GL_DEFINITIONS "${GL_DEFINITIONS} -DWITH_ANGLE")
 	else()
 		#set(SYSTEM_GL_INCLUDE_PATH "${OES2_INCLUDE_PATH}")
 		set(SYSTEM_GL_LIBRARIES    "${OES2_LIBRARY}")

Modified: branches/soc-2013-viewport_fx/intern/ghost/intern/GHOST_WindowWin32.cpp
===================================================================
--- branches/soc-2013-viewport_fx/intern/ghost/intern/GHOST_WindowWin32.cpp	2013-07-24 05:01:22 UTC (rev 58561)
+++ branches/soc-2013-viewport_fx/intern/ghost/intern/GHOST_WindowWin32.cpp	2013-07-24 05:12:38 UTC (rev 58562)
@@ -46,6 +46,7 @@
 
 #include <math.h>
 #include <string.h>
+#include <assert.h>
 
 const wchar_t *GHOST_WindowWin32::s_windowClassName = L"GHOST_WindowClass";
 const int GHOST_WindowWin32::s_maxTitleLength = 128;
@@ -94,6 +95,13 @@
 #endif
 
 #if defined(WITH_GL_SYSTEM_EMBEDDED)
+
+EGLContext GHOST_WindowWin32::s_egl_first_context = EGL_NO_CONTEXT;
+
+#if defined(ANGLE)
+EGLContext GHOST_WindowWin32::s_d3dcompiler = NULL;
+#endif
+
 static EGLint attribList[] = {
 	EGL_RED_SIZE,       8,
 	EGL_GREEN_SIZE,     8,
@@ -401,11 +409,10 @@
 
 GHOST_WindowWin32::~GHOST_WindowWin32()
 {
-	if (m_Bar)
-	{
+	if (m_Bar) {
 		m_Bar->SetProgressState(m_hWnd, TBPF_NOPROGRESS);
 		m_Bar->Release();
-	};
+	}
 
 	if (m_wintab) {
 		GHOST_WIN32_WTClose fpWTClose = (GHOST_WIN32_WTClose) ::GetProcAddress(m_wintab, "WTClose");
@@ -417,6 +424,7 @@
 			m_tabletData = NULL;
 		}
 	}
+
 	if (m_customCursor) {
 		DestroyCursor(m_customCursor);
 		m_customCursor = NULL;
@@ -425,7 +433,28 @@
 #if defined(WITH_GL_SYSTEM_DESKTOP) || defined(WITH_GL_SYSTEM_LEGACY)
 	::wglMakeCurrent(NULL, NULL);
 #elif defined(WITH_GL_SYSTEM_EMBEDDED)
-	::eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+	if (m_egl_display != EGL_NO_DISPLAY) {
+		::eglMakeCurrent(
+			m_egl_display,
+			EGL_NO_SURFACE,
+			EGL_NO_SURFACE,
+			EGL_NO_CONTEXT);
+
+		if (m_egl_context != EGL_NO_CONTEXT && m_egl_context != s_egl_first_context) {
+			EGLBoolean context_destroyed = ::eglDestroyContext(m_egl_display, m_egl_context);
+			assert(context_destroyed);
+		}
+
+		if (m_egl_surface != EGL_NO_SURFACE) {
+			EGLBoolean surface_destroyed = ::eglDestroySurface(m_egl_display, m_egl_surface);
+			assert(surface_destroyed);
+		}
+
+		{
+			EGLBoolean display_terminated = ::eglTerminate(m_egl_display);
+			assert(display_terminated);
+		}
+	}
 #else
 #error
 #endif
@@ -439,11 +468,13 @@
 		::ReleaseDC(m_hWnd, m_hDC);
 		m_hDC = 0;
 	}
-#else
+#elif defined(WITH_GL_SYSTEM_EMBEDDED)
 	if (m_hDC && m_hDC) {
 		::ReleaseDC(m_hWnd, m_hDC);
 		m_hDC = 0;
 	}
+#else
+#error
 #endif
 
 	if (m_hWnd) {
@@ -684,7 +715,7 @@
 
 	return ::SwapBuffers(hDC) == TRUE ? GHOST_kSuccess : GHOST_kFailure;
 #elif defined(WITH_GL_SYSTEM_EMBEDDED)
-	return ::eglSwapBuffers(egl_display, egl_surface) ? GHOST_kSuccess : GHOST_kFailure;
+	return ::eglSwapBuffers(m_egl_display, m_egl_surface) ? GHOST_kSuccess : GHOST_kFailure;
 #else
 #error
 #endif
@@ -694,6 +725,7 @@
 GHOST_TSuccess GHOST_WindowWin32::activateDrawingContext()
 {
 	GHOST_TSuccess success;
+
 	if (m_drawingContextType == GHOST_kDrawingContextTypeOpenGL) {
 #if defined(WITH_GL_SYSTEM_DESKTOP) || defined(WITH_GL_SYSTEM_LEGACY)
 		if (m_hDC && m_hGlRc) {
@@ -703,8 +735,16 @@
 			success = GHOST_kFailure;
 		}
 #elif defined(WITH_GL_SYSTEM_EMBEDDED)
-		if (m_hDC) {
-			success = ::eglMakeCurrent(egl_display, egl_surface, egl_surface, egl_context) ? GHOST_kSuccess : GHOST_kFailure;
+		if (m_egl_display != EGL_NO_DISPLAY &&
+			m_egl_surface != EGL_NO_SURFACE &&
+			m_egl_context != EGL_NO_CONTEXT)
+		{
+			success =
+				::eglMakeCurrent(
+					m_egl_display,
+					m_egl_surface,
+					m_egl_surface,
+					m_egl_context) ? GHOST_kSuccess : GHOST_kFailure;
 		}
 		else {
 			success = GHOST_kFailure;
@@ -972,50 +1012,56 @@
 			EGLint attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE, EGL_NONE };
 #endif
 
-			egl_display = ::eglGetDisplay((EGLNativeDisplayType)m_hDC);
+			success = GHOST_kFailure;
 
-			if(egl_display == EGL_NO_DISPLAY) {
-				success = GHOST_kFailure;
-				break;
+#if defined(WITH_ANGLE)
+			/*
+			ANGLE will reference existing d3dcompiler_##.dll that has already been loaded,
+			so load it here if it hasn't already.
+			*/
+
+			if (s_d3dcompiler == NULL) {
+				s_d3dcompiler = LoadLibrary(D3DCOMPILER);
+
+				if (s_d3dcompiler == NULL) {
+					printf("LoadLibrary(\"" D3DCOMPILER "\") failed!\n");
+					break;
+				}
 			}
+#endif
 
-			LoadLibrary(D3DCOMPILER);
+			m_egl_display = ::eglGetDisplay((EGLNativeDisplayType)m_hDC);
 
-			if(!::eglInitialize(egl_display, &major, &minor)) {
-				success = GHOST_kFailure;
+			if (m_egl_display == EGL_NO_DISPLAY)
 				break;
-			}
 
-			if(!::eglGetConfigs(egl_display, NULL, 0, &num_config)) {
-				success = GHOST_kFailure;
+			if (!::eglInitialize(m_egl_display, &major, &minor))
 				break;
-			}
 
-			if(!::eglChooseConfig(egl_display, attribList, &config, 1, &num_config)) {
-				success = GHOST_kFailure;
+			if (!::eglGetConfigs(m_egl_display, NULL, 0, &num_config))
 				break;
-			}
 
-			egl_surface = ::eglCreateWindowSurface(egl_display, config, (EGLNativeWindowType)m_hWnd, NULL);
+			if (!::eglChooseConfig(m_egl_display, attribList, &config, 1, &num_config))
+				break;
 
-			if (egl_surface == EGL_NO_SURFACE ) {
-				success = GHOST_kFailure;
+			m_egl_surface = ::eglCreateWindowSurface(m_egl_display, config, (EGLNativeWindowType)m_hWnd, NULL);
+
+			if (m_egl_surface == EGL_NO_SURFACE)
 				break;
-			}
 
-			egl_context = ::eglCreateContext(egl_display, config, EGL_NO_CONTEXT, attribs);
+			m_egl_context = ::eglCreateContext(m_egl_display, config, s_egl_first_context, attribs);
 
-			if (egl_context == EGL_NO_CONTEXT) {
-				success = GHOST_kFailure;
+			if (m_egl_context == EGL_NO_CONTEXT)
 				break;
-			}
 
-			if (!::eglMakeCurrent(egl_display, egl_surface, egl_surface, egl_context)) {
-				success = GHOST_kFailure;
+			if (s_egl_first_context == EGL_NO_CONTEXT)
+				s_egl_first_context = m_egl_context;
+
+			if (!::eglMakeCurrent(m_egl_display, m_egl_surface, m_egl_surface, m_egl_context))
 				break;
-			}
 
 			success = GHOST_kSuccess;
+
 			break;
 		}
 #else
@@ -1045,19 +1091,31 @@
 				success = ::wglDeleteContext(m_hGlRc) == TRUE ? GHOST_kSuccess : GHOST_kFailure;
 				m_hGlRc = 0;
 			}
-			else {
+			else { // XXX jwilkins: is it correct to fail in the case that this is the first context? maybe return success but not delete the context is better?
 				success = GHOST_kFailure;
 			}
 			break;
 #elif defined(WITH_GL_SYSTEM_EMBEDDED)
-			if (egl_context != NULL) {
-				if (eglDestroyContext(egl_display, egl_context)) {
-					egl_context = NULL;
-					success = GHOST_kSuccess;
+			if (m_egl_display != EGL_NO_DISPLAY) {
+				EGLBoolean context_destroyed;
+				EGLBoolean surface_destroyed;
+
+				if (m_egl_context != EGL_NO_CONTEXT && m_egl_context != s_egl_first_context) {
+					context_destroyed = ::eglDestroyContext(m_egl_display, m_egl_context);
 				}
 				else {
-					success = GHOST_kFailure;
+					context_destroyed = EGL_TRUE; /* not really gone, but giving up ownership */
 				}
+
+				m_egl_context = EGL_NO_CONTEXT;
+
+				if (m_egl_surface != EGL_NO_SURFACE) {
+					surface_destroyed = ::eglDestroySurface(m_egl_display, m_egl_surface);
+				}
+
+				m_egl_surface = EGL_NO_SURFACE;
+
+				success = context_destroyed && surface_destroyed ? GHOST_kSuccess : GHOST_kFailure;
 			}
 			else {
 				success = GHOST_kFailure;

Modified: branches/soc-2013-viewport_fx/intern/ghost/intern/GHOST_WindowWin32.h
===================================================================
--- branches/soc-2013-viewport_fx/intern/ghost/intern/GHOST_WindowWin32.h	2013-07-24 05:01:22 UTC (rev 58561)
+++ branches/soc-2013-viewport_fx/intern/ghost/intern/GHOST_WindowWin32.h	2013-07-24 05:12:38 UTC (rev 58562)
@@ -357,10 +357,16 @@
 	static HDC s_firstHDC;
 #endif
 #if defined(WITH_GL_SYSTEM_EMBEDDED)
-	EGLContext egl_context;
-	EGLSurface egl_surface;
-	EGLDisplay egl_display;
+	EGLContext m_egl_context;
+	EGLSurface m_egl_surface;
+	EGLDisplay m_egl_display;
+
+#if defined(WITH_ANGLE)
+	static HMODULE s_d3dcompiler;
 #endif
+
+	static EGLContext s_egl_first_context;
+#endif
 	/** Flag for if window has captured the mouse */
 	bool m_hasMouseCaptured;
 	/** Flag if an operator grabs the mouse with WM_cursor_grab_enable/ungrab() 

Modified: branches/soc-2013-viewport_fx/intern/ghost/intern/GHOST_WindowX11.cpp
===================================================================
--- branches/soc-2013-viewport_fx/intern/ghost/intern/GHOST_WindowX11.cpp	2013-07-24 05:01:22 UTC (rev 58561)
+++ branches/soc-2013-viewport_fx/intern/ghost/intern/GHOST_WindowX11.cpp	2013-07-24 05:12:38 UTC (rev 58562)
@@ -1299,7 +1299,7 @@
 				break;
 			}
 			gl_surface = eglCreateWindowSurface(gl_display, config, (EGLNativeWindowType)m_window, NULL);
-			if (gl_surface == EGL_NO_SURFACE )
+			if (gl_surface == EGL_NO_SURFACE)
 			{
 				success = GHOST_kFailure;
 				break;
@@ -1347,7 +1347,7 @@
     GHOST_TSuccess success = GHOST_kFailure;
 
 #ifndef GLEW_INC_EGL
-	if (m_context != NULL) {
+	if (m_context != NULL) { // XXX jwilkins: seems odd not to check if this is s_firstContext
 		glXDestroyContext(m_display, m_context);
 		m_context = NULL;
 		success = GHOST_kSuccess;




More information about the Bf-blender-cvs mailing list