[Bf-blender-cvs] [ebe8935] soc-2014-viewport_fx: GHOST_ContextCGL

Jason Wilkins noreply at git.blender.org
Wed Jun 25 23:42:41 CEST 2014


Commit: ebe89356b50f8a32d333a4674df27ba1c9a6fa41
Author: Jason Wilkins
Date:   Wed Jun 25 10:15:35 2014 -0500
https://developer.blender.org/rBebe89356b50f8a32d333a4674df27ba1c9a6fa41

GHOST_ContextCGL

Initial pass at a re-factored OpenGL context for Cocoa.
This does not yet implement the same checks and warnings that the WGL and EGL contexts have.

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

M	intern/ghost/intern/GHOST_ContextCGL.h
M	intern/ghost/intern/GHOST_ContextCGL.mm
M	intern/ghost/intern/GHOST_SystemCocoa.mm
M	intern/ghost/intern/GHOST_WindowCocoa.h
M	intern/ghost/intern/GHOST_WindowCocoa.mm

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

diff --git a/intern/ghost/intern/GHOST_ContextCGL.h b/intern/ghost/intern/GHOST_ContextCGL.h
index c0c680c..02b8adf 100644
--- a/intern/ghost/intern/GHOST_ContextCGL.h
+++ b/intern/ghost/intern/GHOST_ContextCGL.h
@@ -38,10 +38,20 @@
 
 
 
+ at class NSWindow;
+ at class NSOpenGLView;
+ at class NSOpenGLContext;
+
+
+
 #ifndef GHOST_OPENGL_CGL_CONTEXT_FLAGS
 #define GHOST_OPENGL_CGL_CONTEXT_FLAGS 0
 #endif
 
+#ifndef GHOST_OPENGL_CGL_RESET_NOTIFICATION_STRATEGY
+#define GHOST_OPENGL_CGL_RESET_NOTIFICATION_STRATEGY 0
+#endif
+
 
 
 class GHOST_ContextCGL : public GHOST_Context
@@ -51,10 +61,17 @@ public:
 	 * Constructor.
 	 */
 	GHOST_ContextCGL(
-		int  contextProfileMask  = 0,
-		int  contextMajorVersion = 0,
-		int  contextMinorVersion = 0,
-		int  contextFlags        = GHOST_OPENGL_CGL_CONTEXT_FLAGS);
+		bool          stereoVisual,
+		GHOST_TUns16  numOfAASamples,
+		NSWindow     *window,
+		NSOpenGLView *openGLView,
+		int           contextProfileMask,
+		int           contextMajorVersion,
+		int           contextMinorVersion,
+		int           contextFlags,
+		int           contextResetNotificationStrategy
+	);
+
 
 	/**
 	 * Destructor.
@@ -82,12 +99,53 @@ public:
 	virtual GHOST_TSuccess initializeDrawingContext(bool stereoVisual = false, GHOST_TUns16 numOfAASamples = 0);
 
 	/**
+	 * Updates the drawing context of this window. Needed
+	 * whenever the window is changed.
+	 * \return Indication of success.
+	 */
+	virtual GHOST_TSuccess updateDrawingContext();
+
+	/**
 	 * Checks if it is OK for a remove the native display
 	 * \return Indication as to whether removal has succeeded.
 	 */
 	virtual GHOST_TSuccess releaseNativeHandles();
-};
 
+	/**
+	 * Sets the swap interval for swapBuffers.
+	 * \param interval The swap interval to use.
+	 * \return A boolean success indicator.
+	 */
+	virtual GHOST_TSuccess setSwapInterval(int interval);
+
+	/**
+	 * Gets the current swap interval for swapBuffers.
+	 * \return An integer.
+	 */
+	virtual int getSwapInterval();
+
+private:
+
+	/** The window containing the OpenGL view */
+	NSWindow *m_window;
+	
+	/** The openGL view */
+	NSOpenGLView *m_openGLView; 
+
+	int m_contextProfileMask;
+	int m_contextMajorVersion;
+	int m_contextMinorVersion;
+	int m_contextFlags;
+	int m_contextResetNotificationStrategy;
+
+	/** The opgnGL drawing context */
+	NSOpenGLContext *m_openGLContext;
+	
+	/** The first created OpenGL context (for sharing display lists) */
+	static NSOpenGLContext *s_sharedOpenGLContext;	
+	static int              s_sharedCount;
+
+};
 
 
 
diff --git a/intern/ghost/intern/GHOST_ContextCGL.mm b/intern/ghost/intern/GHOST_ContextCGL.mm
index 2d7e230..e45fe7e 100644
--- a/intern/ghost/intern/GHOST_ContextCGL.mm
+++ b/intern/ghost/intern/GHOST_ContextCGL.mm
@@ -32,48 +32,328 @@
 
 #include "GHOST_ContextCGL.h"
 
+#include <Cocoa/Cocoa.h>
+
+#ifdef GHOST_MULTITHREADED_OPENGL
+#include <OpenGL/OpenGL.h>
+#endif
+
+#include <vector>
+
+#include <cassert>
+
+
+
+NSOpenGLContext *GHOST_ContextCGL::s_sharedOpenGLContext = nil;	
+int              GHOST_ContextCGL::s_sharedCount         = 0;
+
 
 
 GHOST_ContextCGL::GHOST_ContextCGL(
-	int  contextProfileMask,
-	int  contextMajorVersion,
-	int  contextMinorVersion,
-	int  contextFlags)
+	bool          stereoVisual,
+	GHOST_TUns16  numOfAASamples,
+	NSWindow     *window,
+	NSOpenGLView *openGLView,
+	int           contextProfileMask,
+	int           contextMajorVersion,
+	int           contextMinorVersion,
+	int           contextFlags,
+	int           contextResetNotificationStrategy
+)
+	: GHOST_Context(stereoVisual, numOfAASamples)
+	, m_window    (window)
+	, m_openGLView(openGLView)
+	, m_contextProfileMask              (contextProfileMask)
+	, m_contextMajorVersion             (contextMajorVersion)
+	, m_contextMinorVersion             (contextMinorVersion)
+	, m_contextFlags                    (contextFlags)
+	, m_contextResetNotificationStrategy(contextResetNotificationStrategy)
+	, m_openGLContext(nil)
 {
-
+	assert(window != nil);
+	assert(openGLView != nil);
 }
 
 
 
 GHOST_ContextCGL::~GHOST_ContextCGL()
 {
+	if (m_openGLContext != nil) {
+		if (m_openGLContext == [NSOpenGLContext currentContext])
+			[NSOpenGLContext clearCurrentContext];
+			[m_openGLView clearGLContext];
+
+		if (m_openGLContext != s_sharedOpenGLContext || s_sharedCount == 1) {
+			assert(s_sharedCount > 0);
 
+			s_sharedCount--;
+
+			if (s_sharedCount == 0)
+				s_sharedOpenGLContext = nil;
+
+			[m_openGLContext release];
+		}
+	}
 }
 
 
 
 GHOST_TSuccess GHOST_ContextCGL::swapBuffers()
 {
-    return GHOST_kFailure;
+	if (m_openGLContext != nil) {
+		NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+		[m_openGLContext flushBuffer];
+		[pool drain];
+		return GHOST_kSuccess;
+	}
+	else {
+		return GHOST_kFailure;
+	}
+}
+
+
+
+GHOST_TSuccess GHOST_ContextCGL::setSwapInterval(int interval)
+{
+	if (m_openGLContext != nil) {
+		NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+		[m_openGLContext setValues:&interval forParameter:NSOpenGLCPSwapInterval];
+		[pool drain];
+		return GHOST_kSuccess;
+	}
+	else {
+		return GHOST_kFailure;
+	}
+}
+
+
+
+int GHOST_ContextCGL::getSwapInterval()
+{
+	if (m_openGLContext != nil) {
+		GLint interval = 1;
+		NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+		[m_openGLContext setValues:&interval forParameter:NSOpenGLCPSwapInterval];
+		[pool drain];
+		return interval;
+	}
+	else {
+		return 1; // XXX jwilkins: negative numbers are valid, large numbers could have unintended consequences
+	}
 }
 
 
 
 GHOST_TSuccess GHOST_ContextCGL::activateDrawingContext()
 {
-    return GHOST_kFailure;
+	if (m_openGLContext != nil) {
+		NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+		[m_openGLContext makeCurrentContext];
+
+		activateGLEW();
+
+		// Disable AA by default
+		// XXX jwilkins: shouldn't this be somewhere else?
+		if (m_numOfAASamples > 0)
+			glDisable(GL_MULTISAMPLE_ARB);
+
+		[pool drain];
+		return GHOST_kSuccess;
+	}
+	else {
+		return GHOST_kFailure;
+	}
+}
+
+
+
+GHOST_TSuccess GHOST_ContextCGL::updateDrawingContext()
+{
+	if (m_openGLContext != nil) {
+		NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+		[m_openGLContext update];
+		[pool drain];
+		return GHOST_kSuccess;
+	}
+	else {
+		return GHOST_kFailure;
+	}
+}
+
+
+
+static void makeAttribList(
+	std::vector<NSOpenGLPixelFormatAttribute>& attribs,
+	bool stereoVisual,
+	int  numOfAASamples,
+	bool needAlpha,
+	bool needStencil)
+{
+	// Pixel Format Attributes for the windowed NSOpenGLContext
+	attribs.push_back(NSOpenGLPFADoubleBuffer);
+	
+	// Guarantees the back buffer contents to be valid after a call to NSOpenGLContext object's flushBuffer
+	// needed for 'Draw Overlap' drawing method
+	attribs.push_back(NSOpenGLPFABackingStore);
+	
+	// Force software OpenGL, for debugging
+	if (getenv("BLENDER_SOFTWAREGL")) { // XXX jwilkins: fixed this to work on Intel macs? useful feature for Windows and Linux too?  Maybe a command line flag is better...
+		attribs.push_back(NSOpenGLPFARendererID);
+#if defined(__ppc__) || defined(__ppc64__)
+		attribs.push_back(kCGLRendererAppleSWID);
+#else
+		attribs.push_back(kCGLRendererGenericFloatID);
+#endif
+	}
+	else {
+		attribs.push_back(NSOpenGLPFAAccelerated);
+	}
+
+	//attribs.push_back(NSOpenGLPFAAllowOfflineRenderers);   // Removed to allow 10.4 builds, and 2 GPUs rendering is not used anyway
+
+	attribs.push_back(NSOpenGLPFADepthSize);
+	attribs.push_back((NSOpenGLPixelFormatAttribute) 32);
+
+	if (stereoVisual)
+		attribs.push_back(NSOpenGLPFAStereo);
+
+	if (needAlpha) {
+		attribs.push_back(NSOpenGLPFAAlphaSize);
+		attribs.push_back((NSOpenGLPixelFormatAttribute) 8);
+	}
+
+	if (needStencil) {
+		attribs.push_back(NSOpenGLPFAStencilSize);
+		attribs.push_back((NSOpenGLPixelFormatAttribute) 8);
+	}
+
+	if (numOfAASamples > 0) {
+		// Multisample anti-aliasing
+		attribs.push_back(NSOpenGLPFAMultisample);
+		
+		attribs.push_back(NSOpenGLPFASampleBuffers);
+		attribs.push_back((NSOpenGLPixelFormatAttribute) 1);
+		
+		attribs.push_back(NSOpenGLPFASamples);
+		attribs.push_back((NSOpenGLPixelFormatAttribute) numOfAASamples);
+		
+		attribs.push_back(NSOpenGLPFANoRecovery);
+	}
+
+	attribs.push_back((NSOpenGLPixelFormatAttribute) 0);
 }
 
 
 
 GHOST_TSuccess GHOST_ContextCGL::initializeDrawingContext(bool stereoVisual, GHOST_TUns16 numOfAASamples)
 {
-    return GHOST_kFailure;
+	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+
+	std::vector<NSOpenGLPixelFormatAttribute> attribs;
+	attribs.reserve(40);
+
+	NSOpenGLContext *prev_openGLContext = [m_openGLView openGLContext];
+
+#ifdef GHOST_OPENGL_ALPHA
+	static const bool needAlpha   = true;
+#else
+	static const bool needAlpha   = false;
+#endif
+
+#ifdef GHOST_OPENGL_STENCIL
+	static const bool needStencil = true;
+#else
+	static const bool needStencil = false;
+#endif
+
+	makeAttribList(attribs, stereoVisual, numOfAASamples, needAlpha, needStencil);
+
+	NSOpenGLPixelFormat *pixelFormat;
+
+	pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:&attribs[0]];
+
+	// Fall back to no multisampling if Antialiasing init failed
+	if (numOfAASamples > 0 && pixelFormat == nil) {
+		// XXX jwilkins: Does CGL only succeed when it makes an exact match on the number of samples?
+		// Does this need to explicitly try for a lesser match before giving up?
+		// (Now that I think about it, does WGL really require the code that it has for finding a lesser match?)
+
+		attribs.clear();
+		makeAttribList(attribs, stereoVisual, 0, needAlpha, needStencil);
+		pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:&attribs[0]];
+	}
+
+	if (pixelFormat == nil)
+		goto error;
+
+	if (numOfAASamples > 0) { //Set m_numOfAASamples to the actual value
+		GLint actualSamples;
+		[pixelFormat getValues:&actualSamples forAttribute:NSOpenGLPFASamples forVirtualScreen:0];
+
+		if (numOfAASamples != (GHOST_TUns16)actualSamples) {
+			fprintf(
+				stderr,
+				"Warning! Unable to find a multisample pixel format that supports exactly %d samples. Substituting one that uses %d samples.\n",
+				numOfAASamples,
+				actualSamples);
+
+			m_numOfAASamples = (GHOST_TUns16)actualSamples;
+		}
+	}
+
+	[m_openGLView setPixelFormat:pix

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list