[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