
/*
 * Copyright 2019 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "vk/GrVkVulkan.h"

#include "vk/GrVkInterface.h"
#include "vk/GrVkUtil.h"

#include "vk/VkTestUtils.h"

#include "WindowContextFactory_mac.h"
#include "../VulkanWindowContext.h"
#include "vulkan/vulkan_macos.h"

#import <MetalKit/MetalKit.h>

namespace sk_app {

class VulkanWindowContext_mac : public VulkanWindowContext {
public:
    VulkanWindowContext_mac(MTKView* mtkView,
                            const DisplayParams& params,
                            CreateVkSurfaceFn createVkSurface,
                            CanPresentFn canPresent,
                            PFN_vkGetInstanceProcAddr instProc,
                            PFN_vkGetDeviceProcAddr devProc);

    ~VulkanWindowContext_mac() override;

private:
    MTKView*              fMTKView;

    typedef VulkanWindowContext INHERITED;
};

VulkanWindowContext_mac::VulkanWindowContext_mac(MTKView* mtkView,
                                                 const DisplayParams& params,
                                                 CreateVkSurfaceFn createVkSurface,
                                                 CanPresentFn canPresent,
                                                 PFN_vkGetInstanceProcAddr instProc,
                                                 PFN_vkGetDeviceProcAddr devProc)
    : INHERITED(params, createVkSurface, canPresent, instProc, devProc)
    , fMTKView(mtkView) {

    // any config code here (particularly for msaa)?
}

VulkanWindowContext_mac::~VulkanWindowContext_mac() {
    [fMTKView removeFromSuperview];
    [fMTKView release];
    fMTKView = nil;
}

namespace window_context_factory {

WindowContext* NewVulkanForMac(const MacWindowInfo& info, const DisplayParams& displayParams) {
    PFN_vkGetInstanceProcAddr instProc;
    PFN_vkGetDeviceProcAddr devProc;
    if (!sk_gpu_test::LoadVkLibraryAndGetProcAddrFuncs(&instProc, &devProc)) {
        return nullptr;
    }

    // Create mtkview
    NSRect rect = info.fMainView.frame;
    MTKView* mtkView = [[MTKView alloc] initWithFrame:rect device:nil];
    if (nil == mtkView) {
        return nullptr;
    }

    mtkView.colorPixelFormat = MTLPixelFormatBGRA8Unorm;

//    if (fDisplayParams.fMSAASampleCount > 1) {
//        if (![fDevice supportsTextureSampleCount:fDisplayParams.fMSAASampleCount]) {
//            return nullptr;
//        }
//    }
//    mtkView.sampleCount = fDisplayParams.fMSAASampleCount;

    // attach Metal view to main view
    [mtkView setTranslatesAutoresizingMaskIntoConstraints:NO];

    [info.fMainView addSubview:mtkView];
    NSDictionary *views = NSDictionaryOfVariableBindings(mtkView);

    [info.fMainView addConstraints:
     [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[mtkView]|"
                                             options:0
                                             metrics:nil
                                               views:views]];

    [info.fMainView addConstraints:
     [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[mtkView]|"
                                             options:0
                                             metrics:nil
                                               views:views]];

    auto createVkSurface = [mtkView, instProc](VkInstance instance) -> VkSurfaceKHR {
        static PFN_vkCreateMacOSSurfaceMVK createMacOSSurfaceMVK = nullptr;
        if (!createMacOSSurfaceMVK) {
            createMacOSSurfaceMVK =
                    (PFN_vkCreateMacOSSurfaceMVK) instProc(instance, "vkCreateMacOSSurfaceMVK");
        }

        VkSurfaceKHR surface;

        VkMacOSSurfaceCreateInfoMVK surfaceCreateInfo;
        memset(&surfaceCreateInfo, 0, sizeof(VkMacOSSurfaceCreateInfoMVK));
        surfaceCreateInfo.sType = VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK;
        surfaceCreateInfo.pNext = nullptr;
        surfaceCreateInfo.flags = 0;
        surfaceCreateInfo.pView = (__bridge void*)mtkView;

        VkResult res = createMacOSSurfaceMVK(instance, &surfaceCreateInfo, nullptr, &surface);
        if (VK_SUCCESS != res) {
            return VK_NULL_HANDLE;
        }

        return surface;
    };

    auto canPresent = [](VkInstance instance, VkPhysicalDevice physDev, uint32_t queueFamilyIndex) {
        return true;
    };
    WindowContext* context = new VulkanWindowContext_mac(mtkView, displayParams, createVkSurface,
                                                         canPresent, instProc, devProc);
    if (!context->isValid()) {
        delete context;
        [mtkView removeFromSuperview];
        [mtkView release];
        return nullptr;
    }
    return context;
}

}  // namespace VulkanWindowContextFactory

}  // namespace sk_app
