[PATCH 2/3] winemac: Implement WineMetalView class
Andrew Eikum
aeikum at codeweavers.com
Fri Jul 13 09:27:44 CDT 2018
From: Ken Thomases <ken at codeweavers.com>
Signed-off-by: Ken Thomases <ken at codeweavers.com>
Signed-off-by: Andrew Eikum <aeikum at 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, at 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
+ at interface WineMetalView : WineBaseView
+{
+ id<MTLDevice> _device;
+}
+
+ - (id) initWithFrame:(NSRect)frame device:(id<MTLDevice>)device;
+
+ at 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
+ at 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;
+ }
+
+ at 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;
--
2.18.0
More information about the wine-devel
mailing list