From: Ken Thomases ken@codeweavers.com
Signed-off-by: Ken Thomases ken@codeweavers.com Signed-off-by: Andrew Eikum aeikum@codeweavers.com ---
Note that this and the next patch need config.h.in to be re-generated, I don't recall if I'm supposed to do that or not.
configure.ac | 7 ++ dlls/winemac.drv/Makefile.in | 2 +- dlls/winemac.drv/cocoa_window.m | 141 ++++++++++++++++++++++++++++++++ dlls/winemac.drv/macdrv_cocoa.h | 10 +++ 4 files changed, 159 insertions(+), 1 deletion(-)
diff --git a/configure.ac b/configure.ac index 1db5a407fa..9ba9a28cc3 100644 --- a/configure.ac +++ b/configure.ac @@ -762,6 +762,9 @@ case $host_os in
darwin*|macosx*) AC_CHECK_HEADERS(libunwind.h) + AC_LANG_PUSH([Objective C]) + AC_CHECK_HEADERS(Metal/Metal.h) + AC_LANG_POP([Objective C]) LIBEXT="dylib" DLLFLAGS="$DLLFLAGS -fPIC" LDRPATH_INSTALL="-Wl,-rpath,@loader_path/`$(MAKEDEP) -R ${bindir} ${libdir}`" @@ -846,6 +849,10 @@ case $host_os in then AC_SUBST(CARBON_LIBS,"-framework Carbon") fi + if test "$ac_cv_header_Metal_Metal_h" = "yes" + then + AC_SUBST(METAL_LIBS,"-framework Metal -framework QuartzCore") + fi
dnl Enable Mac driver on Mac OS X 10.6 or later if test "$ac_cv_header_ApplicationServices_ApplicationServices_h" = "yes" diff --git a/dlls/winemac.drv/Makefile.in b/dlls/winemac.drv/Makefile.in index c160895c7d..33f4e2ee00 100644 --- a/dlls/winemac.drv/Makefile.in +++ b/dlls/winemac.drv/Makefile.in @@ -1,7 +1,7 @@ MODULE = winemac.drv IMPORTS = uuid user32 gdi32 advapi32 DELAYIMPORTS = ole32 shell32 imm32 -EXTRALIBS = -framework AppKit -framework Carbon -framework Security -framework OpenGL -framework IOKit -framework CoreVideo +EXTRALIBS = -framework AppKit -framework Carbon -framework Security -framework OpenGL -framework IOKit -framework CoreVideo $(METAL_LIBS)
C_SRCS = \ clipboard.c \ diff --git a/dlls/winemac.drv/cocoa_window.m b/dlls/winemac.drv/cocoa_window.m index 1e10c27ce8..4c59faf1f4 100644 --- a/dlls/winemac.drv/cocoa_window.m +++ b/dlls/winemac.drv/cocoa_window.m @@ -18,8 +18,14 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
+#include "config.h" + #import <Carbon/Carbon.h> #import <CoreVideo/CoreVideo.h> +#ifdef HAVE_METAL_METAL_H +#import <Metal/Metal.h> +#import <QuartzCore/QuartzCore.h> +#endif
#import "cocoa_window.h"
@@ -303,6 +309,18 @@ @interface WineBaseView : NSView @end
+#ifdef HAVE_METAL_METAL_H +@interface WineMetalView : WineBaseView +{ + id<MTLDevice> _device; +} + + - (id) initWithFrame:(NSRect)frame device:(id<MTLDevice>)device; + +@end +#endif + + @interface WineContentView : WineBaseView <NSTextInputClient> { NSMutableArray* glContexts; @@ -316,6 +334,10 @@ @interface WineContentView : WineBaseView <NSTextInputClient> NSRange markedTextSelection;
int backingSize[2]; + +#ifdef HAVE_METAL_METAL_H + WineMetalView *_metalView; +#endif }
@property (readonly, nonatomic) BOOL everHadGLContext; @@ -327,6 +349,10 @@ - (void) updateGLContexts; - (void) wine_getBackingSize:(int*)outBackingSize; - (void) wine_setBackingSize:(const int*)newBackingSize;
+#ifdef HAVE_METAL_METAL_H + - (WineMetalView*) newMetalViewWithDevice:(id<MTLDevice>)device; +#endif + @end
@@ -628,6 +654,23 @@ - (void) wine_setBackingSize:(const int*)newBackingSize } }
+#ifdef HAVE_METAL_METAL_H + - (WineMetalView*) newMetalViewWithDevice:(id<MTLDevice>)device + { + if (_metalView) return _metalView; + + WineMetalView* view = [[WineMetalView alloc] initWithFrame:[self bounds] device:device]; + [view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; + [self setAutoresizesSubviews:YES]; + [self addSubview:view positioned:NSWindowBelow relativeTo:nil]; + _metalView = view; + + [(WineWindow*)self.window windowDidDrawContent]; + + return _metalView; + } +#endif + - (void) setRetinaMode:(int)mode { double scale = mode ? 0.5 : 2.0; @@ -693,6 +736,10 @@ - (void) willRemoveSubview:(NSView*)subview if (!view->_cachedHasGLDescendantValid || view->_cachedHasGLDescendant) [self invalidateHasGLDescendant]; } +#ifdef HAVE_METAL_METAL_H + if (subview == _metalView) + _metalView = nil; +#endif [super willRemoveSubview:subview]; }
@@ -833,6 +880,53 @@ - (NSInteger) windowLevel @end
+#ifdef HAVE_METAL_METAL_H +@implementation WineMetalView + + - (id) initWithFrame:(NSRect)frame device:(id<MTLDevice>)device + { + self = [super initWithFrame:frame]; + if (self) + { + _device = [device retain]; + self.wantsLayer = YES; + self.layerContentsRedrawPolicy = NSViewLayerContentsRedrawNever; + } + return self; + } + + - (void) dealloc + { + [_device release]; + [super dealloc]; + } + + - (void) setRetinaMode:(int)mode + { + self.layer.contentsScale = mode ? 2.0 : 1.0; + [super setRetinaMode:mode]; + } + + - (CALayer*) makeBackingLayer + { + CAMetalLayer *layer = [CAMetalLayer layer]; + layer.device = _device; + layer.framebufferOnly = YES; + layer.magnificationFilter = kCAFilterNearest; + layer.backgroundColor = CGColorGetConstantColor(kCGColorBlack); + layer.contentsScale = retina_on ? 2.0 : 1.0; + return layer; + } + + - (BOOL) isOpaque + { + return YES; + } + +@end +#endif + + @implementation WineWindow
static WineWindow* causing_becomeKeyWindow; @@ -3492,6 +3586,7 @@ macdrv_view macdrv_create_view(CGRect rect)
view = [[WineContentView alloc] initWithFrame:NSRectFromCGRect(cgrect_mac_from_win(rect))]; [view setAutoresizesSubviews:NO]; + [view setAutoresizingMask:NSViewNotSizable]; [view setHidden:YES]; [nc addObserver:view selector:@selector(updateGLContexts) @@ -3679,6 +3774,52 @@ void macdrv_remove_view_opengl_context(macdrv_view v, macdrv_opengl_context c) [pool release]; }
+#ifdef HAVE_METAL_METAL_H +macdrv_metal_device macdrv_create_metal_device(void) +{ + macdrv_metal_device ret; + +#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_11 + if (MTLCreateSystemDefaultDevice == NULL) + return NULL; +#endif + + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + ret = (macdrv_metal_device)MTLCreateSystemDefaultDevice(); + [pool release]; + return ret; +} + +void macdrv_release_metal_device(macdrv_metal_device d) +{ + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + [(id<MTLDevice>)d release]; + [pool release]; +} + +macdrv_metal_view macdrv_view_create_metal_view(macdrv_view v, macdrv_metal_device d) +{ + id<MTLDevice> device = (id<MTLDevice>)d; + WineContentView* view = (WineContentView*)v; + __block WineMetalView *metalView; + + OnMainThread(^{ + metalView = [view newMetalViewWithDevice:device]; + }); + + return (macdrv_metal_view)metalView; +} + +void macdrv_view_release_metal_view(macdrv_metal_view v) +{ + WineMetalView* view = (WineMetalView*)v; + OnMainThread(^{ + [view removeFromSuperview]; + [view release]; + }); +} +#endif + int macdrv_get_view_backing_size(macdrv_view v, int backing_size[2]) { WineContentView* view = (WineContentView*)v; diff --git a/dlls/winemac.drv/macdrv_cocoa.h b/dlls/winemac.drv/macdrv_cocoa.h index a22b4c2917..acab5dfd92 100644 --- a/dlls/winemac.drv/macdrv_cocoa.h +++ b/dlls/winemac.drv/macdrv_cocoa.h @@ -138,6 +138,10 @@ typedef struct macdrv_opaque_event_queue* macdrv_event_queue; typedef struct macdrv_opaque_view* macdrv_view; typedef struct macdrv_opaque_opengl_context* macdrv_opengl_context; +#ifdef HAVE_METAL_METAL_H +typedef struct macdrv_opaque_metal_device* macdrv_metal_device; +typedef struct macdrv_opaque_metal_view* macdrv_metal_view; +#endif typedef struct macdrv_opaque_status_item* macdrv_status_item; struct macdrv_event; struct macdrv_query; @@ -527,6 +531,12 @@ extern void macdrv_set_window_color_key(macdrv_window w, CGFloat keyRed, CGFloat extern void macdrv_set_view_hidden(macdrv_view v, int hidden) DECLSPEC_HIDDEN; extern void macdrv_add_view_opengl_context(macdrv_view v, macdrv_opengl_context c) DECLSPEC_HIDDEN; extern void macdrv_remove_view_opengl_context(macdrv_view v, macdrv_opengl_context c) DECLSPEC_HIDDEN; +#ifdef HAVE_METAL_METAL_H +extern macdrv_metal_device macdrv_create_metal_device(void) DECLSPEC_HIDDEN; +extern void macdrv_release_metal_device(macdrv_metal_device d) DECLSPEC_HIDDEN; +extern macdrv_metal_view macdrv_view_create_metal_view(macdrv_view v, macdrv_metal_device d) DECLSPEC_HIDDEN; +extern void macdrv_view_release_metal_view(macdrv_metal_view v) DECLSPEC_HIDDEN; +#endif extern int macdrv_get_view_backing_size(macdrv_view v, int backing_size[2]) DECLSPEC_HIDDEN; extern void macdrv_set_view_backing_size(macdrv_view v, const int backing_size[2]) DECLSPEC_HIDDEN; extern uint32_t macdrv_window_background_color(void) DECLSPEC_HIDDEN;