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_WindowCocoa.mm')
-rw-r--r--intern/ghost/intern/GHOST_WindowCocoa.mm78
1 files changed, 65 insertions, 13 deletions
diff --git a/intern/ghost/intern/GHOST_WindowCocoa.mm b/intern/ghost/intern/GHOST_WindowCocoa.mm
index 33d9921cdec..45ea3c85005 100644
--- a/intern/ghost/intern/GHOST_WindowCocoa.mm
+++ b/intern/ghost/intern/GHOST_WindowCocoa.mm
@@ -29,6 +29,8 @@
#endif
#include <Cocoa/Cocoa.h>
+#include <QuartzCore/QuartzCore.h>
+#include <Metal/Metal.h>
#include <sys/sysctl.h>
@@ -263,7 +265,17 @@
@end
/* NSView for handling input and drawing. */
+#define COCOA_VIEW_CLASS CocoaOpenGLView
+#define COCOA_VIEW_BASE_CLASS NSOpenGLView
#include "GHOST_WindowViewCocoa.h"
+#undef COCOA_VIEW_CLASS
+#undef COCOA_VIEW_BASE_CLASS
+
+#define COCOA_VIEW_CLASS CocoaMetalView
+#define COCOA_VIEW_BASE_CLASS NSView
+#include "GHOST_WindowViewCocoa.h"
+#undef COCOA_VIEW_CLASS
+#undef COCOA_VIEW_BASE_CLASS
#pragma mark initialization / finalization
@@ -281,6 +293,8 @@ GHOST_WindowCocoa::GHOST_WindowCocoa(GHOST_SystemCocoa *systemCocoa,
bool is_debug)
: GHOST_Window(width, height, state, stereoVisual, false),
m_openGLView(nil),
+ m_metalView(nil),
+ m_metalLayer(nil),
m_systemCocoa(systemCocoa),
m_customCursor(0),
m_immediateDraw(false),
@@ -318,21 +332,44 @@ GHOST_WindowCocoa::GHOST_WindowCocoa(GHOST_SystemCocoa *systemCocoa,
minSize.height = 240;
[m_window setContentMinSize:minSize];
- // Creates the OpenGL View inside the window
- m_openGLView = [[CocoaOpenGLView alloc] initWithFrame:rect];
+ // Create NSView inside the window
+ id<MTLDevice> metalDevice = MTLCreateSystemDefaultDevice();
+ NSView *view;
+
+ if (metalDevice) {
+ // Create metal layer and view if supported
+ m_metalLayer = [[CAMetalLayer alloc] init];
+ [m_metalLayer setEdgeAntialiasingMask:0];
+ [m_metalLayer setMasksToBounds:NO];
+ [m_metalLayer setOpaque:YES];
+ [m_metalLayer setFramebufferOnly:YES];
+ [m_metalLayer setPresentsWithTransaction:NO];
+ [m_metalLayer removeAllAnimations];
+ [m_metalLayer setDevice:metalDevice];
+
+ m_metalView = [[CocoaMetalView alloc] initWithFrame:rect];
+ [m_metalView setWantsLayer:YES];
+ [m_metalView setLayer:m_metalLayer];
+ [m_metalView setSystemAndWindowCocoa:systemCocoa windowCocoa:this];
+ view = m_metalView;
+ }
+ else {
+ // Fallback to OpenGL view if there is no Metal support
+ m_openGLView = [[CocoaOpenGLView alloc] initWithFrame:rect];
+ [m_openGLView setSystemAndWindowCocoa:systemCocoa windowCocoa:this];
+ view = m_openGLView;
+ }
if (m_systemCocoa->m_nativePixel) {
// Needs to happen early when building with the 10.14 SDK, otherwise
// has no effect until resizeing the window.
- if ([m_openGLView respondsToSelector:@selector(setWantsBestResolutionOpenGLSurface:)]) {
- [m_openGLView setWantsBestResolutionOpenGLSurface:YES];
+ if ([view respondsToSelector:@selector(setWantsBestResolutionOpenGLSurface:)]) {
+ [view setWantsBestResolutionOpenGLSurface:YES];
}
}
- [m_openGLView setSystemAndWindowCocoa:systemCocoa windowCocoa:this];
-
- [m_window setContentView:m_openGLView];
- [m_window setInitialFirstResponder:m_openGLView];
+ [m_window setContentView:view];
+ [m_window setInitialFirstResponder:view];
[m_window makeKeyAndOrderFront:nil];
@@ -381,7 +418,18 @@ GHOST_WindowCocoa::~GHOST_WindowCocoa()
releaseNativeHandles();
- [m_openGLView release];
+ if (m_openGLView) {
+ [m_openGLView release];
+ m_openGLView = nil;
+ }
+ if (m_metalView) {
+ [m_metalView release];
+ m_metalView = nil;
+ }
+ if (m_metalLayer) {
+ [m_metalLayer release];
+ m_metalLayer = nil;
+ }
if (m_window) {
[m_window close];
@@ -405,7 +453,8 @@ GHOST_WindowCocoa::~GHOST_WindowCocoa()
bool GHOST_WindowCocoa::getValid() const
{
- return GHOST_Window::getValid() && m_window != NULL && m_openGLView != NULL;
+ NSView *view = (m_openGLView) ? m_openGLView : m_metalView;
+ return GHOST_Window::getValid() && m_window != NULL && view != NULL;
}
void *GHOST_WindowCocoa::getOSWindow() const
@@ -669,7 +718,8 @@ NSScreen *GHOST_WindowCocoa::getScreen()
/* called for event, when window leaves monitor to another */
void GHOST_WindowCocoa::setNativePixelSize(void)
{
- NSRect backingBounds = [m_openGLView convertRectToBacking:[m_openGLView bounds]];
+ NSView *view = (m_openGLView) ? m_openGLView : m_metalView;
+ NSRect backingBounds = [view convertRectToBacking:[view bounds]];
GHOST_Rect rect;
getClientBounds(rect);
@@ -763,7 +813,8 @@ GHOST_Context *GHOST_WindowCocoa::newDrawingContext(GHOST_TDrawingContextType ty
{
if (type == GHOST_kDrawingContextTypeOpenGL) {
- GHOST_Context *context = new GHOST_ContextCGL(m_wantStereoVisual, m_openGLView);
+ GHOST_Context *context = new GHOST_ContextCGL(
+ m_wantStereoVisual, m_metalView, m_metalLayer, m_openGLView);
if (context->initializeDrawingContext())
return context;
@@ -780,7 +831,8 @@ GHOST_TSuccess GHOST_WindowCocoa::invalidate()
{
GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::invalidate(): window invalid");
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- [m_openGLView setNeedsDisplay:YES];
+ NSView *view = (m_openGLView) ? m_openGLView : m_metalView;
+ [view setNeedsDisplay:YES];
[pool drain];
return GHOST_kSuccess;
}