Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'intern/ghost/intern/GHOST_ContextCGL.mm')
-rw-r--r--intern/ghost/intern/GHOST_ContextCGL.mm175
1 files changed, 108 insertions, 67 deletions
diff --git a/intern/ghost/intern/GHOST_ContextCGL.mm b/intern/ghost/intern/GHOST_ContextCGL.mm
index dd800ef52a3..488aa58aa59 100644
--- a/intern/ghost/intern/GHOST_ContextCGL.mm
+++ b/intern/ghost/intern/GHOST_ContextCGL.mm
@@ -58,12 +58,6 @@ GHOST_ContextCGL::GHOST_ContextCGL(bool stereoVisual,
m_defaultFramebufferMetalTexture(nil),
m_debug(false)
{
-#if defined(WITH_GL_PROFILE_CORE)
- m_coreProfile = true;
-#else
- m_coreProfile = false;
-#endif
-
if (m_metalView) {
metalInit();
}
@@ -197,17 +191,17 @@ GHOST_TSuccess GHOST_ContextCGL::updateDrawingContext()
}
static void makeAttribList(std::vector<NSOpenGLPixelFormatAttribute> &attribs,
- bool coreProfile,
bool stereoVisual,
bool needAlpha,
- bool softwareGL)
+ bool softwareGL,
+ bool increasedSamplerLimit)
{
attribs.clear();
attribs.push_back(NSOpenGLPFAOpenGLProfile);
- attribs.push_back(coreProfile ? NSOpenGLProfileVersion3_2Core : NSOpenGLProfileVersionLegacy);
+ attribs.push_back(NSOpenGLProfileVersion3_2Core);
- /* Pixel Format Attributes for the windowed NSOpenGLContext. */
+ /* Pixel Format Attributes for the windowed #NSOpenGLContext. */
attribs.push_back(NSOpenGLPFADoubleBuffer);
if (softwareGL) {
@@ -217,6 +211,12 @@ static void makeAttribList(std::vector<NSOpenGLPixelFormatAttribute> &attribs,
else {
attribs.push_back(NSOpenGLPFAAccelerated);
attribs.push_back(NSOpenGLPFANoRecovery);
+
+ /* Attempt to initialize device with extended sampler limit.
+ * Resolves EEVEE purple rendering artifacts on macOS. */
+ if (increasedSamplerLimit) {
+ attribs.push_back((NSOpenGLPixelFormatAttribute)400);
+ }
}
if (stereoVisual)
@@ -232,82 +232,123 @@ static void makeAttribList(std::vector<NSOpenGLPixelFormatAttribute> &attribs,
GHOST_TSuccess GHOST_ContextCGL::initializeDrawingContext()
{
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ @autoreleasepool {
#ifdef GHOST_OPENGL_ALPHA
- static const bool needAlpha = true;
+ static const bool needAlpha = true;
#else
- static const bool needAlpha = false;
+ static const bool needAlpha = false;
#endif
- /* Command-line argument would be better. */
- static bool softwareGL = getenv("BLENDER_SOFTWAREGL");
-
- std::vector<NSOpenGLPixelFormatAttribute> attribs;
- attribs.reserve(40);
- makeAttribList(attribs, m_coreProfile, m_stereoVisual, needAlpha, softwareGL);
+ /* Command-line argument would be better. */
+ static bool softwareGL = getenv("BLENDER_SOFTWAREGL");
+
+ NSOpenGLPixelFormat *pixelFormat = nil;
+ std::vector<NSOpenGLPixelFormatAttribute> attribs;
+ bool increasedSamplerLimit = false;
+
+ /* Attempt to initialize device with increased sampler limit.
+ * If this is unsupported and initialization fails, initialize GL Context as normal.
+ *
+ * NOTE: This is not available when using the SoftwareGL path, or for Intel-based
+ * platforms. */
+ if (!softwareGL) {
+ if (@available(macos 11.0, *)) {
+ increasedSamplerLimit = true;
+ }
+ }
+ const int max_ctx_attempts = increasedSamplerLimit ? 2 : 1;
+ for (int ctx_create_attempt = 0; ctx_create_attempt < max_ctx_attempts; ctx_create_attempt++) {
+
+ attribs.clear();
+ attribs.reserve(40);
+ makeAttribList(attribs, m_stereoVisual, needAlpha, softwareGL, increasedSamplerLimit);
+
+ pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:&attribs[0]];
+ if (pixelFormat == nil) {
+ /* If pixel format creation fails when testing increased sampler limit,
+ * attempt initialization again with feature disabled, otherwise, fail. */
+ if (increasedSamplerLimit) {
+ increasedSamplerLimit = false;
+ continue;
+ }
+ return GHOST_kFailure;
+ }
- NSOpenGLPixelFormat *pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:&attribs[0]];
- if (pixelFormat == nil) {
- goto error;
- }
+ /* Attempt to create context. */
+ m_openGLContext = [[NSOpenGLContext alloc] initWithFormat:pixelFormat
+ shareContext:s_sharedOpenGLContext];
+ [pixelFormat release];
+
+ if (m_openGLContext == nil) {
+ /* If context creation fails when testing increased sampler limit,
+ * attempt re-creation with feature disabled. Otherwise, error. */
+ if (increasedSamplerLimit) {
+ increasedSamplerLimit = false;
+ continue;
+ }
+
+ /* Default context creation attempt failed. */
+ return GHOST_kFailure;
+ }
- m_openGLContext = [[NSOpenGLContext alloc] initWithFormat:pixelFormat
- shareContext:s_sharedOpenGLContext];
- [pixelFormat release];
+ /* Created GL context successfully, activate. */
+ [m_openGLContext makeCurrentContext];
- [m_openGLContext makeCurrentContext];
+ /* When increasing sampler limit, verify created context is a supported configuration. */
+ if (increasedSamplerLimit) {
+ const char *vendor = (const char *)glGetString(GL_VENDOR);
+ const char *renderer = (const char *)glGetString(GL_RENDERER);
+
+ /* If generated context type is unsupported, release existing context and
+ * fallback to creating a normal context below. */
+ if (strstr(vendor, "Intel") || strstr(renderer, "Software")) {
+ [m_openGLContext release];
+ m_openGLContext = nil;
+ increasedSamplerLimit = false;
+ continue;
+ }
+ }
+ }
- if (m_debug) {
- GLint major = 0, minor = 0;
- glGetIntegerv(GL_MAJOR_VERSION, &major);
- glGetIntegerv(GL_MINOR_VERSION, &minor);
- fprintf(stderr, "OpenGL version %d.%d%s\n", major, minor, softwareGL ? " (software)" : "");
- fprintf(stderr, "Renderer: %s\n", glGetString(GL_RENDERER));
- }
+ if (m_debug) {
+ GLint major = 0, minor = 0;
+ glGetIntegerv(GL_MAJOR_VERSION, &major);
+ glGetIntegerv(GL_MINOR_VERSION, &minor);
+ fprintf(stderr, "OpenGL version %d.%d%s\n", major, minor, softwareGL ? " (software)" : "");
+ fprintf(stderr, "Renderer: %s\n", glGetString(GL_RENDERER));
+ }
#ifdef GHOST_WAIT_FOR_VSYNC
- {
- GLint swapInt = 1;
- /* Wait for vertical-sync, to avoid tearing artifacts. */
- [m_openGLContext setValues:&swapInt forParameter:NSOpenGLCPSwapInterval];
- }
+ {
+ GLint swapInt = 1;
+ /* Wait for vertical-sync, to avoid tearing artifacts. */
+ [m_openGLContext setValues:&swapInt forParameter:NSOpenGLCPSwapInterval];
+ }
#endif
- initContextGLEW();
-
- if (m_metalView) {
- if (m_defaultFramebuffer == 0) {
- /* Create a virtual frame-buffer. */
- [m_openGLContext makeCurrentContext];
- metalInitFramebuffer();
+ if (m_metalView) {
+ if (m_defaultFramebuffer == 0) {
+ /* Create a virtual frame-buffer. */
+ [m_openGLContext makeCurrentContext];
+ metalInitFramebuffer();
+ initClearGL();
+ }
+ }
+ else if (m_openGLView) {
+ [m_openGLView setOpenGLContext:m_openGLContext];
+ [m_openGLContext setView:m_openGLView];
initClearGL();
}
- }
- else if (m_openGLView) {
- [m_openGLView setOpenGLContext:m_openGLContext];
- [m_openGLContext setView:m_openGLView];
- initClearGL();
- }
-
- [m_openGLContext flushBuffer];
- if (s_sharedCount == 0)
- s_sharedOpenGLContext = m_openGLContext;
+ [m_openGLContext flushBuffer];
- s_sharedCount++;
-
- [pool drain];
+ if (s_sharedCount == 0)
+ s_sharedOpenGLContext = m_openGLContext;
+ s_sharedCount++;
+ }
return GHOST_kSuccess;
-
-error:
-
- [pixelFormat release];
-
- [pool drain];
-
- return GHOST_kFailure;
}
GHOST_TSuccess GHOST_ContextCGL::releaseNativeHandles()