/*
 * MVKSync.mm
 *
 * Copyright (c) 2015-2022 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 "MVKSync.h"
#include "MVKFoundation.h"

using namespace std;


#pragma mark -
#pragma mark MVKSemaphoreImpl

bool MVKSemaphoreImpl::release() {
	lock_guard<mutex> lock(_lock);
    if (isClear()) { return true; }

    // Either decrement the reservation counter, or clear it altogether
    if (_shouldWaitAll) {
		if (_reservationCount > 0) { _reservationCount--; }
    } else {
        _reservationCount = 0;
    }
    // If all reservations have been released, unblock all waiting threads
    if ( isClear() ) { _blocker.notify_all(); }
    return isClear();
}

void MVKSemaphoreImpl::reserve() {
	lock_guard<mutex> lock(_lock);
	_reservationCount++;
}

bool MVKSemaphoreImpl::isReserved() {
	lock_guard<mutex> lock(_lock);
	return !isClear();
}

bool MVKSemaphoreImpl::wait(uint64_t timeout, bool reserveAgain) {
    unique_lock<mutex> lock(_lock);

    bool isDone;
    if (timeout == 0) {
		isDone = isClear();
	} else if (timeout == UINT64_MAX) {
		_blocker.wait(lock, [this]{ return isClear(); });
		isDone = true;
	} else {
        // Limit timeout to avoid overflow since wait_for() uses wait_until()
        uint64_t nanoTimeout = min(timeout, kMVKUndefinedLargeUInt64);
        chrono::nanoseconds nanos(nanoTimeout);
        isDone = _blocker.wait_for(lock, nanos, [this]{ return isClear(); });
    }

	if (reserveAgain) { _reservationCount++; }
    return isDone;
}

MVKSemaphoreImpl::~MVKSemaphoreImpl() {
    // Acquire the lock to ensure proper ordering.
    lock_guard<mutex> lock(_lock);
}


#pragma mark -
#pragma mark MVKSemaphoreMTLFence

// Could use any encoder. Assume BLIT is fastest and lightest.
// Nil mtlCmdBuff will do nothing.
void MVKSemaphoreMTLFence::encodeWait(id<MTLCommandBuffer> mtlCmdBuff, uint64_t) {
	id<MTLBlitCommandEncoder> mtlCmdEnc = mtlCmdBuff.blitCommandEncoder;
	[mtlCmdEnc waitForFence: _mtlFence];
	[mtlCmdEnc endEncoding];
}

// Could use any encoder. Assume BLIT is fastest and lightest.
// Nil mtlCmdBuff will do nothing.
void MVKSemaphoreMTLFence::encodeSignal(id<MTLCommandBuffer> mtlCmdBuff, uint64_t) {
	id<MTLBlitCommandEncoder> mtlCmdEnc = mtlCmdBuff.blitCommandEncoder;
	[mtlCmdEnc updateFence: _mtlFence];
	[mtlCmdEnc endEncoding];
}

uint64_t MVKSemaphoreMTLFence::deferSignal() {
	return 0;
}

void MVKSemaphoreMTLFence::encodeDeferredSignal(id<MTLCommandBuffer> mtlCmdBuff, uint64_t) {
	encodeSignal(mtlCmdBuff, 0);
}

MVKSemaphoreMTLFence::MVKSemaphoreMTLFence(MVKDevice* device,
										   const VkSemaphoreCreateInfo* pCreateInfo,
										   const VkExportMetalObjectCreateInfoEXT* pExportInfo,
										   const VkImportMetalSharedEventInfoEXT* pImportInfo) : MVKSemaphore(device, pCreateInfo) {

	_mtlFence = [device->getMTLDevice() newFence];		//retained

	if ((pImportInfo && pImportInfo->mtlSharedEvent) || (pExportInfo && pExportInfo->exportObjectType == VK_EXPORT_METAL_OBJECT_TYPE_METAL_SHARED_EVENT_BIT_EXT)) {
		setConfigurationResult(reportError(VK_ERROR_INITIALIZATION_FAILED, "vkCreateEvent(): MTLSharedEvent is not available with VkSemaphores that use MTLFence."));
	}
}

MVKSemaphoreMTLFence::~MVKSemaphoreMTLFence() {
	[_mtlFence release];
}


#pragma mark -
#pragma mark MVKSemaphoreMTLEvent

void MVKSemaphoreMTLEvent::encodeWait(id<MTLCommandBuffer> mtlCmdBuff, uint64_t) {
	if (mtlCmdBuff) { [mtlCmdBuff encodeWaitForEvent: _mtlEvent value: _mtlEventValue++]; }
}

void MVKSemaphoreMTLEvent::encodeSignal(id<MTLCommandBuffer> mtlCmdBuff, uint64_t) {
	if (mtlCmdBuff) { [mtlCmdBuff encodeSignalEvent: _mtlEvent value: _mtlEventValue]; }
}

uint64_t MVKSemaphoreMTLEvent::deferSignal() {
	return _mtlEventValue;
}

void MVKSemaphoreMTLEvent::encodeDeferredSignal(id<MTLCommandBuffer> mtlCmdBuff, uint64_t deferToken) {
	if (mtlCmdBuff) { [mtlCmdBuff encodeSignalEvent: _mtlEvent value: deferToken]; }
}

MVKSemaphoreMTLEvent::MVKSemaphoreMTLEvent(MVKDevice* device,
										   const VkSemaphoreCreateInfo* pCreateInfo,
										   const VkExportMetalObjectCreateInfoEXT* pExportInfo,
										   const VkImportMetalSharedEventInfoEXT* pImportInfo) : MVKSemaphore(device, pCreateInfo) {
	// In order of preference, import a MTLSharedEvent,
	// create a MTLSharedEvent, or create a MTLEvent.
	if (pImportInfo && pImportInfo->mtlSharedEvent) {
		_mtlEvent = [pImportInfo->mtlSharedEvent retain];		// retained
		_mtlEventValue = pImportInfo->mtlSharedEvent.signaledValue + 1;
	} else if (pExportInfo && pExportInfo->exportObjectType == VK_EXPORT_METAL_OBJECT_TYPE_METAL_SHARED_EVENT_BIT_EXT) {
		_mtlEvent = [device->getMTLDevice() newSharedEvent];	//retained
		_mtlEventValue = ((id<MTLSharedEvent>)_mtlEvent).signaledValue + 1;
	} else {
		_mtlEvent = [device->getMTLDevice() newEvent];			//retained
		_mtlEventValue = 1;
	}
}

MVKSemaphoreMTLEvent::~MVKSemaphoreMTLEvent() {
    [_mtlEvent release];
}


#pragma mark -
#pragma mark MVKSemaphoreEmulated

void MVKSemaphoreEmulated::encodeWait(id<MTLCommandBuffer> mtlCmdBuff, uint64_t) {
	if ( !mtlCmdBuff ) {
		_device->addSemaphore(&_blocker);
		_blocker.wait(UINT64_MAX, true);
		_device->removeSemaphore(&_blocker);
	}
}

void MVKSemaphoreEmulated::encodeSignal(id<MTLCommandBuffer> mtlCmdBuff, uint64_t) {
	if ( !mtlCmdBuff ) { _blocker.release(); }
}

uint64_t MVKSemaphoreEmulated::deferSignal() {
	return 0;
}

void MVKSemaphoreEmulated::encodeDeferredSignal(id<MTLCommandBuffer> mtlCmdBuff, uint64_t) {
	encodeSignal(mtlCmdBuff, 0);
}

MVKSemaphoreEmulated::MVKSemaphoreEmulated(MVKDevice* device,
										   const VkSemaphoreCreateInfo* pCreateInfo,
										   const VkExportMetalObjectCreateInfoEXT* pExportInfo,
										   const VkImportMetalSharedEventInfoEXT* pImportInfo) :
	MVKSemaphore(device, pCreateInfo),
	_blocker(false, 1) {

	if ((pImportInfo && pImportInfo->mtlSharedEvent) || (pExportInfo && pExportInfo->exportObjectType == VK_EXPORT_METAL_OBJECT_TYPE_METAL_SHARED_EVENT_BIT_EXT)) {
		setConfigurationResult(reportError(VK_ERROR_INITIALIZATION_FAILED, "vkCreateEvent(): MTLSharedEvent is not available with VkSemaphores that use CPU emulation."));
	}
}


#pragma mark -
#pragma mark MVKTimelineSemaphoreMTLEvent

// Nil mtlCmdBuff will do nothing.
void MVKTimelineSemaphoreMTLEvent::encodeWait(id<MTLCommandBuffer> mtlCmdBuff, uint64_t value) {
	[mtlCmdBuff encodeWaitForEvent: _mtlEvent value: value];
}

// Nil mtlCmdBuff will do nothing.
void MVKTimelineSemaphoreMTLEvent::encodeSignal(id<MTLCommandBuffer> mtlCmdBuff, uint64_t value) {
	[mtlCmdBuff encodeSignalEvent: _mtlEvent value: value];
}

void MVKTimelineSemaphoreMTLEvent::signal(const VkSemaphoreSignalInfo* pSignalInfo) {
	_mtlEvent.signaledValue = pSignalInfo->value;
}

bool MVKTimelineSemaphoreMTLEvent::registerWait(MVKFenceSitter* sitter, const VkSemaphoreWaitInfo* pWaitInfo, uint32_t index) {
	if (_mtlEvent.signaledValue >= pWaitInfo->pValues[index]) { return true; }
	lock_guard<mutex> lock(_lock);
	sitter->await();
	auto addRslt = _sitters.insert(sitter);
	if (addRslt.second) {
		retain();
		_device->addSemaphore(&sitter->_blocker);
		[_mtlEvent notifyListener: sitter->getMTLSharedEventListener()
						  atValue: pWaitInfo->pValues[index]
							block: ^(id<MTLSharedEvent>, uint64_t) {
			lock_guard<mutex> blockLock(_lock);
			if (_sitters.count(sitter)) { sitter->signaled(); }
			release();
		}];
	}
	return false;
}

void MVKTimelineSemaphoreMTLEvent::unregisterWait(MVKFenceSitter* sitter) {
	lock_guard<mutex> lock(_lock);
	_device->removeSemaphore(&sitter->_blocker);
	_sitters.erase(sitter);
}

MVKTimelineSemaphoreMTLEvent::MVKTimelineSemaphoreMTLEvent(MVKDevice* device,
														   const VkSemaphoreCreateInfo* pCreateInfo,
														   const VkSemaphoreTypeCreateInfo* pTypeCreateInfo,
														   const VkExportMetalObjectCreateInfoEXT* pExportInfo,
														   const VkImportMetalSharedEventInfoEXT* pImportInfo) : MVKTimelineSemaphore(device, pCreateInfo) {

	// Import or create a Metal event
	_mtlEvent = (pImportInfo && pImportInfo->mtlSharedEvent
				 ? [pImportInfo->mtlSharedEvent retain]
				 : [device->getMTLDevice() newSharedEvent]);	//retained

	if (pTypeCreateInfo) {
		_mtlEvent.signaledValue = pTypeCreateInfo->initialValue;
	}
}

MVKTimelineSemaphoreMTLEvent::~MVKTimelineSemaphoreMTLEvent() {
    [_mtlEvent release];
}


#pragma mark -
#pragma mark MVKTimelineSemaphoreEmulated

void MVKTimelineSemaphoreEmulated::encodeWait(id<MTLCommandBuffer> mtlCmdBuff, uint64_t value) {
	unique_lock<mutex> lock(_lock);
	if ( !mtlCmdBuff ) {
		_device->addTimelineSemaphore(this, value);
		_blocker.wait(lock, [=]() { return _value >= value; });
		_device->removeTimelineSemaphore(this, value);
	}
}

void MVKTimelineSemaphoreEmulated::encodeSignal(id<MTLCommandBuffer> mtlCmdBuff, uint64_t value) {
	lock_guard<mutex> lock(_lock);
	if ( !mtlCmdBuff ) { signalImpl(value); }
}

void MVKTimelineSemaphoreEmulated::signal(const VkSemaphoreSignalInfo* pSignalInfo) {
	lock_guard<mutex> lock(_lock);
	signalImpl(pSignalInfo->value);
}

void MVKTimelineSemaphoreEmulated::signalImpl(uint64_t value) {
	if (value > _value) {
		_value = value;
		_blocker.notify_all();
		for (auto& sittersForValue : _sitters) {
			if (sittersForValue.first > value) { continue; }
			for (auto* sitter : sittersForValue.second) {
				sitter->signaled();
			}
		}
	}
}

bool MVKTimelineSemaphoreEmulated::registerWait(MVKFenceSitter* sitter, const VkSemaphoreWaitInfo* pWaitInfo, uint32_t index) {
	lock_guard<mutex> lock(_lock);
	if (pWaitInfo->pValues[index] >= _value) { return true; }
	uint64_t value = pWaitInfo->pValues[index];
	if (!_sitters.count(value)) { _sitters.emplace(make_pair(value, unordered_set<MVKFenceSitter*>())); }
	auto addRslt = _sitters[value].insert(sitter);
	if (addRslt.second) {
		_device->addSemaphore(&sitter->_blocker);
		sitter->await();
	}
	return false;
}

void MVKTimelineSemaphoreEmulated::unregisterWait(MVKFenceSitter* sitter) {
	MVKSmallVector<uint64_t> emptySets;
	for (auto& sittersForValue : _sitters) {
		_device->removeSemaphore(&sitter->_blocker);
		sittersForValue.second.erase(sitter);
		// Can't destroy while iterating...
		if (sittersForValue.second.empty()) {
			emptySets.push_back(sittersForValue.first);
		}
	}
	for (auto value : emptySets) { _sitters.erase(value); }
}

MVKTimelineSemaphoreEmulated::MVKTimelineSemaphoreEmulated(MVKDevice* device,
														   const VkSemaphoreCreateInfo* pCreateInfo,
														   const VkSemaphoreTypeCreateInfo* pTypeCreateInfo,
														   const VkExportMetalObjectCreateInfoEXT* pExportInfo,
														   const VkImportMetalSharedEventInfoEXT* pImportInfo) :
	MVKTimelineSemaphore(device, pCreateInfo),
	_value(pTypeCreateInfo ? pTypeCreateInfo->initialValue : 0) {

	if ((pImportInfo && pImportInfo->mtlSharedEvent) || (pExportInfo && pExportInfo->exportObjectType == VK_EXPORT_METAL_OBJECT_TYPE_METAL_SHARED_EVENT_BIT_EXT)) {
		setConfigurationResult(reportError(VK_ERROR_INITIALIZATION_FAILED, "vkCreateEvent(): MTLSharedEvent is not available on this platform."));
	}
}


#pragma mark -
#pragma mark MVKFence

void MVKFence::addSitter(MVKFenceSitter* fenceSitter) {
	lock_guard<mutex> lock(_lock);

	// We only care about unsignaled fences. If already signaled,
	// don't add myself to the sitter and don't signal the sitter.
	if (_isSignaled) { return; }

	// Ensure each fence only added once to each fence sitter
	auto addRslt = _fenceSitters.insert(fenceSitter);	// pair with second element true if was added
	if (addRslt.second) {
		_device->addSemaphore(&fenceSitter->_blocker);
		fenceSitter->await();
	}
}

void MVKFence::removeSitter(MVKFenceSitter* fenceSitter) {
	lock_guard<mutex> lock(_lock);

	_device->removeSemaphore(&fenceSitter->_blocker);
	_fenceSitters.erase(fenceSitter);
}

void MVKFence::signal() {
	lock_guard<mutex> lock(_lock);

	if (_isSignaled) { return; }	// Only signal once
	_isSignaled = true;

	// Notify all the fence sitters, and clear them from this instance.
    for (auto& fs : _fenceSitters) {
        fs->signaled();
    }
	_fenceSitters.clear();
}

void MVKFence::reset() {
	lock_guard<mutex> lock(_lock);

	_isSignaled = false;
	_fenceSitters.clear();
}

bool MVKFence::getIsSignaled() {
	lock_guard<mutex> lock(_lock);

	return _isSignaled;
}


#pragma mark -
#pragma mark MVKFenceSitter

MTLSharedEventListener* MVKFenceSitter::getMTLSharedEventListener() {
	// TODO: Use dispatch queue from device?
	if (!_listener) { _listener = [MTLSharedEventListener new]; }
	return _listener;
}


#pragma mark -
#pragma mark MVKEventNative

// Odd == set / Even == reset.
bool MVKEventNative::isSet() { return _mtlEvent.signaledValue & 1; }

void MVKEventNative::signal(bool status) {
	if (isSet() != status) {
		_mtlEvent.signaledValue += 1;
	}
}

void MVKEventNative::encodeSignal(id<MTLCommandBuffer> mtlCmdBuff, bool status) {
	if (isSet() != status) {
		[mtlCmdBuff encodeSignalEvent: _mtlEvent value: _mtlEvent.signaledValue + 1];
	}
}

void MVKEventNative::encodeWait(id<MTLCommandBuffer> mtlCmdBuff) {
	if ( !isSet() ) {
		[mtlCmdBuff encodeWaitForEvent: _mtlEvent value: _mtlEvent.signaledValue + 1];
	}
}

MVKEventNative::MVKEventNative(MVKDevice* device,
							   const VkEventCreateInfo* pCreateInfo,
							   const VkExportMetalObjectCreateInfoEXT* pExportInfo,
							   const VkImportMetalSharedEventInfoEXT* pImportInfo) :
	MVKEvent(device, pCreateInfo, pExportInfo, pImportInfo) {

	// Import or create a Metal event
	_mtlEvent = (pImportInfo
				 ? [pImportInfo->mtlSharedEvent retain]
				 : [device->getMTLDevice() newSharedEvent]);	//retained
}

MVKEventNative::~MVKEventNative() {
	[_mtlEvent release];
}


#pragma mark -
#pragma mark MVKEventEmulated

bool MVKEventEmulated::isSet() { return !_blocker.isReserved(); }

void MVKEventEmulated::signal(bool status) {
	if (status) {
		_blocker.release();
	} else {
		_blocker.reserve();
	}
}

void MVKEventEmulated::encodeSignal(id<MTLCommandBuffer> mtlCmdBuff, bool status) {
	if (status) {
		[mtlCmdBuff addCompletedHandler: ^(id<MTLCommandBuffer> mcb) { _blocker.release(); }];
	} else {
		_blocker.reserve();
	}

	// An encoded signal followed by an encoded wait should cause the wait to be skipped.
	// However, because encoding a signal will not release the blocker until the command buffer
	// is finished executing (so the CPU can tell when it really is done) it is possible that
	// the encoded wait will block when it shouldn't. To avoid that, we keep track of whether
	// the most recent encoded signal was set or reset, so the next encoded wait knows whether
	// to really wait or not.
	_inlineSignalStatus = status;
}

void MVKEventEmulated::encodeWait(id<MTLCommandBuffer> mtlCmdBuff) {
	if ( !_inlineSignalStatus ) {
		_device->addSemaphore(&_blocker);
		_blocker.wait();
		_device->removeSemaphore(&_blocker);
	}
}

MVKEventEmulated::MVKEventEmulated(MVKDevice* device,
								   const VkEventCreateInfo* pCreateInfo,
								   const VkExportMetalObjectCreateInfoEXT* pExportInfo,
								   const VkImportMetalSharedEventInfoEXT* pImportInfo) :
	MVKEvent(device, pCreateInfo, pExportInfo, pImportInfo), _blocker(false, 1), _inlineSignalStatus(false) {

	if (pExportInfo && pExportInfo->exportObjectType == VK_EXPORT_METAL_OBJECT_TYPE_METAL_SHARED_EVENT_BIT_EXT) {
		setConfigurationResult(reportError(VK_ERROR_INITIALIZATION_FAILED, "vkCreateEvent(): MTLSharedEvent is not available on this platform."));
	}
}


#pragma mark -
#pragma mark Support functions

VkResult mvkResetFences(uint32_t fenceCount, const VkFence* pFences) {
	for (uint32_t i = 0; i < fenceCount; i++) {
		((MVKFence*)pFences[i])->reset();
	}
	return VK_SUCCESS;
}

// Create a blocking fence sitter, add it to each fence, wait, then remove it.
VkResult mvkWaitForFences(MVKDevice* device,
						  uint32_t fenceCount,
						  const VkFence* pFences,
						  VkBool32 waitAll,
						  uint64_t timeout) {

	if (device->getConfigurationResult() != VK_SUCCESS) {
		return device->getConfigurationResult();
	}

	VkResult rslt = VK_SUCCESS;
	MVKFenceSitter fenceSitter(waitAll);

	for (uint32_t i = 0; i < fenceCount; i++) {
		((MVKFence*)pFences[i])->addSitter(&fenceSitter);
	}

	bool finished = fenceSitter.wait(timeout);
	if (device->getConfigurationResult() != VK_SUCCESS) {
		rslt = device->getConfigurationResult();
	} else if ( !finished ) {
		rslt = VK_TIMEOUT;
	}

	for (uint32_t i = 0; i < fenceCount; i++) {
		((MVKFence*)pFences[i])->removeSitter(&fenceSitter);
	}

	return rslt;
}

// Create a blocking fence sitter, add it to each semaphore, wait, then remove it.
VkResult mvkWaitSemaphores(MVKDevice* device,
						   const VkSemaphoreWaitInfo* pWaitInfo,
						   uint64_t timeout) {

	if (device->getConfigurationResult() != VK_SUCCESS) {
		return device->getConfigurationResult();
	}

	VkResult rslt = VK_SUCCESS;
	bool waitAny = mvkIsAnyFlagEnabled(pWaitInfo->flags, VK_SEMAPHORE_WAIT_ANY_BIT);
	bool alreadySignaled = false;
	MVKFenceSitter fenceSitter(!waitAny);

	for (uint32_t i = 0; i < pWaitInfo->semaphoreCount; i++) {
		if (((MVKTimelineSemaphore*)pWaitInfo->pSemaphores[i])->registerWait(&fenceSitter, pWaitInfo, i) && waitAny) {
			// In this case, we don't need to wait.
			alreadySignaled = true;
			break;
		}
	}

	bool finished = alreadySignaled || fenceSitter.wait(timeout);
	if (device->getConfigurationResult() != VK_SUCCESS) {
		rslt = device->getConfigurationResult();
	} else if ( !finished ) {
		rslt = VK_TIMEOUT;
	}

	for (uint32_t i = 0; i < pWaitInfo->semaphoreCount; i++) {
		((MVKTimelineSemaphore*)pWaitInfo->pSemaphores[i])->unregisterWait(&fenceSitter);
	}

	return rslt;
}


#pragma mark -
#pragma mark MVKMetalCompiler

// Create a compiled object by dispatching the block to the default global dispatch queue, and waiting only as long
// as the MVKConfiguration::metalCompileTimeout value. If the timeout is triggered, a Vulkan error is created.
// This approach is used to limit the lengthy time (30+ seconds!) consumed by Metal when it's internal compiler fails.
// The thread dispatch is needed because even the sync portion of the async Metal compilation methods can take well
// over a second to return when a compiler failure occurs!
void MVKMetalCompiler::compile(unique_lock<mutex>& lock, dispatch_block_t block) {
	MVKAssert( _startTime == 0, "%s compile occurred already in this instance. Instances of %s should only be used for a single compile activity.", _compilerType.c_str(), getClassName().c_str());

	MVKDevice* mvkDev = _owner->getDevice();
	_startTime = mvkDev->getPerformanceTimestamp();

	dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ @autoreleasepool { block(); } });

	// Limit timeout to avoid overflow since wait_for() uses wait_until()
	chrono::nanoseconds nanoTimeout(min(mvkConfig().metalCompileTimeout, kMVKUndefinedLargeUInt64));
	_blocker.wait_for(lock, nanoTimeout, [this]{ return _isCompileDone; });

	if ( !_isCompileDone ) {
		@autoreleasepool {
			NSString* errDesc = [NSString stringWithFormat: @"Timeout after %.3f milliseconds. Likely internal Metal compiler error", (double)nanoTimeout.count() / 1e6];
			_compileError = [[NSError alloc] initWithDomain: @"MoltenVK" code: 1 userInfo: @{NSLocalizedDescriptionKey : errDesc}];	// retained
		}
	}

	if (_compileError) { handleError(); }

	mvkDev->addActivityPerformance(*_pPerformanceTracker, _startTime);
}

void MVKMetalCompiler::handleError() {
	_owner->setConfigurationResult(reportError(VK_ERROR_INITIALIZATION_FAILED,
											   "%s compile failed (Error code %li):\n%s.",
											   _compilerType.c_str(), (long)_compileError.code,
											   _compileError.localizedDescription.UTF8String));
}

// Returns whether the compilation came in late, after the compiler was destroyed.
bool MVKMetalCompiler::endCompile(NSError* compileError) {
	_compileError = [compileError retain];		// retained
	_isCompileDone = true;
	_blocker.notify_all();
	return _isDestroyed;
}

void MVKMetalCompiler::destroy() {
	if (markDestroyed()) { MVKBaseObject::destroy(); }
}

// Marks this object as destroyed, and returns whether the compilation is complete.
bool MVKMetalCompiler::markDestroyed() {
	lock_guard<mutex> lock(_completionLock);

	_isDestroyed = true;
	return _isCompileDone;
}


#pragma mark Construction

MVKMetalCompiler::~MVKMetalCompiler() {
	[_compileError release];
}



