• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1
2/*
3 * Copyright 2019 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
9#include "include/gpu/vk/GrVkVulkan.h"
10
11#include "src/gpu/vk/GrVkInterface.h"
12#include "src/gpu/vk/GrVkUtil.h"
13
14#include "tools/gpu/vk/VkTestUtils.h"
15
16#include "include/third_party/vulkan/vulkan/vulkan_macos.h"
17#include "tools/sk_app/VulkanWindowContext.h"
18#include "tools/sk_app/mac/WindowContextFactory_mac.h"
19
20#import <MetalKit/MetalKit.h>
21
22namespace sk_app {
23
24class VulkanWindowContext_mac : public VulkanWindowContext {
25public:
26    VulkanWindowContext_mac(MTKView* mtkView,
27                            const DisplayParams& params,
28                            CreateVkSurfaceFn createVkSurface,
29                            CanPresentFn canPresent,
30                            PFN_vkGetInstanceProcAddr instProc,
31                            PFN_vkGetDeviceProcAddr devProc);
32
33    ~VulkanWindowContext_mac() override;
34
35    void resize(int w, int h) override;
36
37private:
38    MTKView*              fMTKView;
39
40    typedef VulkanWindowContext INHERITED;
41};
42
43VulkanWindowContext_mac::VulkanWindowContext_mac(MTKView* mtkView,
44                                                 const DisplayParams& params,
45                                                 CreateVkSurfaceFn createVkSurface,
46                                                 CanPresentFn canPresent,
47                                                 PFN_vkGetInstanceProcAddr instProc,
48                                                 PFN_vkGetDeviceProcAddr devProc)
49    : INHERITED(params, createVkSurface, canPresent, instProc, devProc)
50    , fMTKView(mtkView) {
51
52    // any config code here (particularly for msaa)?
53}
54
55VulkanWindowContext_mac::~VulkanWindowContext_mac() {
56    [fMTKView removeFromSuperview];
57    [fMTKView release];
58    fMTKView = nil;
59}
60
61void VulkanWindowContext_mac::resize(int w, int h) {
62    CGSize newSize;
63    newSize.width = w;
64    newSize.height = h;
65    fMTKView.drawableSize = newSize;
66    this->INHERITED::resize(w, h);
67}
68
69namespace window_context_factory {
70
71std::unique_ptr<WindowContext> MakeVulkanForMac(const MacWindowInfo& info,
72                                                const DisplayParams& displayParams) {
73    PFN_vkGetInstanceProcAddr instProc;
74    PFN_vkGetDeviceProcAddr devProc;
75    if (!sk_gpu_test::LoadVkLibraryAndGetProcAddrFuncs(&instProc, &devProc)) {
76        return nullptr;
77    }
78
79    // Create mtkview
80    NSRect rect = info.fMainView.frame;
81    MTKView* mtkView = [[MTKView alloc] initWithFrame:rect device:nil];
82    if (nil == mtkView) {
83        return nullptr;
84    }
85
86    mtkView.autoResizeDrawable = NO;
87    mtkView.colorPixelFormat = MTLPixelFormatBGRA8Unorm;
88    mtkView.drawableSize = rect.size;
89
90//    if (fDisplayParams.fMSAASampleCount > 1) {
91//        if (![fDevice supportsTextureSampleCount:fDisplayParams.fMSAASampleCount]) {
92//            return nullptr;
93//        }
94//    }
95//    mtkView.sampleCount = fDisplayParams.fMSAASampleCount;
96
97    // attach Metal view to main view
98    [mtkView setTranslatesAutoresizingMaskIntoConstraints:NO];
99
100    [info.fMainView addSubview:mtkView];
101    NSDictionary *views = NSDictionaryOfVariableBindings(mtkView);
102
103    [info.fMainView addConstraints:
104     [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[mtkView]|"
105                                             options:0
106                                             metrics:nil
107                                               views:views]];
108
109    [info.fMainView addConstraints:
110     [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[mtkView]|"
111                                             options:0
112                                             metrics:nil
113                                               views:views]];
114
115    auto createVkSurface = [mtkView, instProc](VkInstance instance) -> VkSurfaceKHR {
116        static PFN_vkCreateMacOSSurfaceMVK createMacOSSurfaceMVK = nullptr;
117        if (!createMacOSSurfaceMVK) {
118            createMacOSSurfaceMVK =
119                    (PFN_vkCreateMacOSSurfaceMVK) instProc(instance, "vkCreateMacOSSurfaceMVK");
120        }
121
122        VkSurfaceKHR surface;
123
124        VkMacOSSurfaceCreateInfoMVK surfaceCreateInfo;
125        memset(&surfaceCreateInfo, 0, sizeof(VkMacOSSurfaceCreateInfoMVK));
126        surfaceCreateInfo.sType = VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK;
127        surfaceCreateInfo.pNext = nullptr;
128        surfaceCreateInfo.flags = 0;
129        surfaceCreateInfo.pView = (__bridge void*)mtkView;
130
131        VkResult res = createMacOSSurfaceMVK(instance, &surfaceCreateInfo, nullptr, &surface);
132        if (VK_SUCCESS != res) {
133            return VK_NULL_HANDLE;
134        }
135
136        return surface;
137    };
138
139    auto canPresent = [](VkInstance instance, VkPhysicalDevice physDev, uint32_t queueFamilyIndex) {
140        return true;
141    };
142    std::unique_ptr<WindowContext> ctx(new VulkanWindowContext_mac(
143            mtkView, displayParams, createVkSurface, canPresent, instProc, devProc));
144    if (!ctx->isValid()) {
145        ctx = nullptr;
146        [mtkView removeFromSuperview];
147        [mtkView release];
148        return nullptr;
149    }
150    return ctx;
151}
152
153}  // namespace VulkanWindowContextFactory
154
155}  // namespace sk_app
156