src/video/cocoa/SDL_cocoametalview.m
changeset 11365 a9bd2625fa01
child 11367 e8fc755a89e8
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/video/cocoa/SDL_cocoametalview.m	Sun Aug 27 22:15:57 2017 -0400
     1.3 @@ -0,0 +1,124 @@
     1.4 +/*
     1.5 + Simple DirectMedia Layer
     1.6 + Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
     1.7 + 
     1.8 + This software is provided 'as-is', without any express or implied
     1.9 + warranty.  In no event will the authors be held liable for any damages
    1.10 + arising from the use of this software.
    1.11 + 
    1.12 + Permission is granted to anyone to use this software for any purpose,
    1.13 + including commercial applications, and to alter it and redistribute it
    1.14 + freely, subject to the following restrictions:
    1.15 + 
    1.16 + 1. The origin of this software must not be misrepresented; you must not
    1.17 + claim that you wrote the original software. If you use this software
    1.18 + in a product, an acknowledgment in the product documentation would be
    1.19 + appreciated but is not required.
    1.20 + 2. Altered source versions must be plainly marked as such, and must not be
    1.21 + misrepresented as being the original software.
    1.22 + 3. This notice may not be removed or altered from any source distribution.
    1.23 + */
    1.24 +
    1.25 +/*
    1.26 + * @author Mark Callow, www.edgewise-consulting.com.
    1.27 + *
    1.28 + * Thanks to Alex Szpakowski, @slime73 on GitHub, for his gist showing
    1.29 + * how to add a CAMetalLayer backed view.
    1.30 + */
    1.31 +
    1.32 +/* this is (currently) only used with Vulkan. Remove this #if when that changes! */
    1.33 +#if SDL_VIDEO_VULKAN_SURFACE && SDL_VIDEO_DRIVER_COCOA
    1.34 +
    1.35 +#import "SDL_cocoametalview.h"
    1.36 +
    1.37 +#include "SDL_assert.h"
    1.38 +#include "SDL_loadso.h"
    1.39 +#include <dlfcn.h>
    1.40 +
    1.41 +@implementation SDL_cocoametalview
    1.42 +
    1.43 +/* The synthesized getter should be called by super's viewWithTag. */
    1.44 +@synthesize tag = _tag;
    1.45 +
    1.46 +/* Return a Metal-compatible layer. */
    1.47 ++ (Class)layerClass
    1.48 +{
    1.49 +  return [CAMetalLayer class];
    1.50 +}
    1.51 +
    1.52 +/* Indicate the view wants to draw using a backing layer instead of drawRect. */
    1.53 +-(BOOL) wantsUpdateLayer { return YES; }
    1.54 +
    1.55 +/* When the wantsLayer property is set to YES, this method will be invoked to
    1.56 + * return a layer instance.
    1.57 + */
    1.58 +-(CALayer*) makeBackingLayer { return [self.class.layerClass layer]; }
    1.59 +
    1.60 +- (instancetype)initWithFrame:(NSRect)frame
    1.61 +                   useHighDPI:(bool)useHighDPI
    1.62 +{
    1.63 +  if ((self = [super initWithFrame:frame])) {
    1.64 +    
    1.65 +    /* Allow resize. */
    1.66 +    self.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable;
    1.67 +    _tag = METALVIEW_TAG;
    1.68 +      
    1.69 +    _useHighDPI = useHighDPI;
    1.70 +    [self updateDrawableSize];
    1.71 +  }
    1.72 +  
    1.73 +  return self;
    1.74 +}
    1.75 +
    1.76 +/* Set the size of the metal drawables when the view is resized. */
    1.77 +- (void)resizeSubviewsWithOldSize:(NSSize)oldSize {
    1.78 +    [super resizeSubviewsWithOldSize:oldSize];
    1.79 +    [self updateDrawableSize];
    1.80 +}
    1.81 +
    1.82 +- (void)updateDrawableSize
    1.83 +{
    1.84 +    if (_useHighDPI) {
    1.85 +        NSSize size = [self convertRectToBacking:[self bounds]].size;
    1.86 +         /* Isn't there a better way to convert from NSSize to CGSize? */
    1.87 +        CGSize cgsize = *(CGSize*)&size;
    1.88 +        ((CAMetalLayer *) self.layer).drawableSize = cgsize;
    1.89 +    }
    1.90 +}
    1.91 +
    1.92 +@end
    1.93 +
    1.94 +SDL_cocoametalview*
    1.95 +Cocoa_Mtl_AddMetalView(SDL_Window* window)
    1.96 +{
    1.97 +    SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
    1.98 +    NSView *view = data->nswindow.contentView;
    1.99 +
   1.100 +    SDL_cocoametalview *metalview
   1.101 +        = [[SDL_cocoametalview alloc] initWithFrame:view.frame
   1.102 +                       useHighDPI:(window->flags & SDL_WINDOW_ALLOW_HIGHDPI)];
   1.103 +    [view addSubview:metalview];
   1.104 +  
   1.105 +    return metalview;
   1.106 +}
   1.107 +
   1.108 +void
   1.109 +Cocoa_Mtl_GetDrawableSize(SDL_Window * window, int * w, int * h)
   1.110 +{
   1.111 +    SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata;
   1.112 +    NSView *view = data->nswindow.contentView;
   1.113 +    SDL_cocoametalview* metalview = [view viewWithTag:METALVIEW_TAG];
   1.114 +    if (metalview) {
   1.115 +        CAMetalLayer *layer = (CAMetalLayer*)metalview.layer;
   1.116 +        assert(layer != NULL);
   1.117 +        if (w)
   1.118 +            *w = layer.drawableSize.width;
   1.119 +        if (h)
   1.120 +            *h = layer.drawableSize.height;
   1.121 +    }
   1.122 +}
   1.123 +
   1.124 +#endif
   1.125 +
   1.126 +/* vi: set ts=4 sw=4 expandtab: */
   1.127 +