/*
 * MVKSurface.mm
 *
 * Copyright (c) 2014-2019 The Brenwill Workshop Ltd. (http://www.brenwill.com)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "MVKSurface.h"
#include "MVKInstance.h"
#include "MVKFoundation.h"
#include "MVKLogging.h"
#include "MVKOSExtensions.h"
#import "MVKBlockObserver.h"

// We need to double-dereference the name to first convert to the platform symbol, then to a string.
#define STR_PLATFORM(NAME) #NAME
#define STR(NAME) STR_PLATFORM(NAME)


#pragma mark MVKSurface

MVKSurface::MVKSurface(MVKInstance* mvkInstance,
					   const VkMetalSurfaceCreateInfoEXT* pCreateInfo,
					   const VkAllocationCallbacks* pAllocator) : _mvkInstance(mvkInstance) {

	_mtlCAMetalLayer = (CAMetalLayer*)[pCreateInfo->pLayer retain];
	initLayerObserver();
}

// pCreateInfo->pView can be either a CAMetalLayer or a view (NSView/UIView).
MVKSurface::MVKSurface(MVKInstance* mvkInstance,
					   const Vk_PLATFORM_SurfaceCreateInfoMVK* pCreateInfo,
					   const VkAllocationCallbacks* pAllocator) : _mvkInstance(mvkInstance) {

	MVKLogInfo("%s(): This function is obsolete. Consider using the vkCreateMetalSurfaceEXT() function from the VK_EXT_metal_surface extension instead.", STR(vkCreate_PLATFORM_SurfaceMVK));

	// Get the platform object contained in pView
	id<NSObject> obj = (id<NSObject>)pCreateInfo->pView;

	// If it's a view (NSView/UIView), extract the layer, otherwise assume it's already a CAMetalLayer.
	if ([obj isKindOfClass: [PLATFORM_VIEW_CLASS class]]) {
		if ( !NSThread.isMainThread ) {
			MVKLogInfo("%s(): You are not calling this function from the main thread. %s should only be accessed from the main thread. When using this function outside the main thread, consider passing the CAMetalLayer itself in %s::pView, instead of the %s.",
					   STR(vkCreate_PLATFORM_SurfaceMVK), STR(PLATFORM_VIEW_CLASS), STR(Vk_PLATFORM_SurfaceCreateInfoMVK), STR(PLATFORM_VIEW_CLASS));
		}
		obj = ((PLATFORM_VIEW_CLASS*)obj).layer;
	}

	// Confirm that we were provided with a CAMetalLayer
	if ([obj isKindOfClass: [CAMetalLayer class]]) {
		_mtlCAMetalLayer = (CAMetalLayer*)[obj retain];		// retained
	} else {
		setConfigurationResult(reportError(VK_ERROR_INITIALIZATION_FAILED,
										   "%s(): On-screen rendering requires a layer of type CAMetalLayer.",
										   STR(vkCreate_PLATFORM_SurfaceMVK)));
		_mtlCAMetalLayer = nil;
	}

	initLayerObserver();
}

// Sometimes, the owning view can replace its CAMetalLayer. In that case, the client needs to recreate the surface.
void MVKSurface::initLayerObserver() {

	_layerObserver = nil;
	if ( ![_mtlCAMetalLayer.delegate isKindOfClass: [PLATFORM_VIEW_CLASS class]] ) { return; }

	_layerObserver = [MVKBlockObserver observerWithBlock: ^(NSString* path, id, NSDictionary*, void*) {
		if ( ![path isEqualToString: @"layer"] ) { return; }
		std::lock_guard<std::mutex> lock(this->_lock);
		[this->_mtlCAMetalLayer release];
		this->_mtlCAMetalLayer = nil;
		this->setConfigurationResult(VK_ERROR_SURFACE_LOST_KHR);
		[this->_layerObserver release];
		this->_layerObserver = nil;
	} forObject: _mtlCAMetalLayer.delegate atKeyPath: @"layer"];
}

MVKSurface::~MVKSurface() {
	std::lock_guard<std::mutex> lock(_lock);
	[_mtlCAMetalLayer release];
	[_layerObserver release];
}

