Reland "Add less granular version of GrFence for older Metal versions."

This is a reland of 1e946aa24b

Original change's description:
> Add less granular version of GrFence for older Metal versions.
> 
> Rather than use MTLSharedEvent, we create a semaphore and
> signal it within the current command buffer's completion handler.
> The pointer to the semaphore is cast as GrFence and returned.
> The waitFence method recasts it and waits on the semaphore.
> 
> Bug: skia:8243
> Change-Id: I2c854c65a62786fe8031794008eb6844974ebefd
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/245583
> Reviewed-by: Greg Daniel <egdaniel@google.com>
> Commit-Queue: Jim Van Verth <jvanverth@google.com>

Bug: skia:8243
Change-Id: I63872c26b8f5c29cba6e618f418b291cf5ffac54
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/246016
Reviewed-by: Jim Van Verth <jvanverth@google.com>
Commit-Queue: Jim Van Verth <jvanverth@google.com>
This commit is contained in:
Jim Van Verth 2019-10-03 14:31:14 -04:00 committed by Skia Commit-Bot
parent 9bd947ddb1
commit 4187e0a416
2 changed files with 43 additions and 26 deletions

View File

@ -250,6 +250,7 @@ void GrMtlCaps::initGrCaps(const id<MTLDevice> device) {
fMixedSamplesSupport = false;
fGpuTracingSupport = false;
fFenceSyncSupport = true;
bool supportsMTLEvent = false;
#ifdef GR_METAL_SDK_SUPPORTS_EVENTS
// TODO: this may be redundant
@ -263,7 +264,6 @@ void GrMtlCaps::initGrCaps(const id<MTLDevice> device) {
#endif
}
#endif
fFenceSyncSupport = supportsMTLEvent;
fSemaphoreSupport = supportsMTLEvent;
fCrossContextTextureSupport = false;

View File

@ -1215,45 +1215,62 @@ bool GrMtlGpu::readOrTransferPixels(GrSurface* surface, int left, int top, int w
}
GrFence SK_WARN_UNUSED_RESULT GrMtlGpu::insertFence() {
GrMtlCommandBuffer* cmdBuffer = this->commandBuffer();
#ifdef GR_METAL_SDK_SUPPORTS_EVENTS
if (@available(macOS 10.14, iOS 12.0, *)) {
if (this->caps()->fenceSyncSupport()) {
GrMtlCommandBuffer* cmdBuffer = this->commandBuffer();
++fLatestEvent;
cmdBuffer->encodeSignalEvent(fSharedEvent, fLatestEvent);
++fLatestEvent;
cmdBuffer->encodeSignalEvent(fSharedEvent, fLatestEvent);
return fLatestEvent;
}
return fLatestEvent;
}
#endif
return 0;
// If MTLSharedEvent isn't available, we create a semaphore and signal it
// within the current command buffer's completion handler.
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
cmdBuffer->addCompletedHandler(^(id <MTLCommandBuffer>commandBuffer) {
dispatch_semaphore_signal(semaphore);
});
const void* cfFence = (__bridge_retained const void*) semaphore;
return (GrFence) cfFence;
}
bool GrMtlGpu::waitFence(GrFence value, uint64_t timeout) {
bool GrMtlGpu::waitFence(GrFence fence, uint64_t timeout) {
dispatch_semaphore_t semaphore;
#ifdef GR_METAL_SDK_SUPPORTS_EVENTS
if (@available(macOS 10.14, iOS 12.0, *)) {
if (this->caps()->fenceSyncSupport()) {
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
semaphore = dispatch_semaphore_create(0);
// Add listener for this particular value or greater
__block dispatch_semaphore_t block_sema = semaphore;
[fSharedEvent notifyListener: fSharedEventListener
atValue: value
block: ^(id<MTLSharedEvent> sharedEvent, uint64_t value) {
dispatch_semaphore_signal(block_sema);
}];
// Add listener for this particular value or greater
__block dispatch_semaphore_t block_sema = semaphore;
[fSharedEvent notifyListener: fSharedEventListener
atValue: fence
block: ^(id<MTLSharedEvent> sharedEvent, uint64_t value) {
dispatch_semaphore_signal(block_sema);
}];
long result = dispatch_semaphore_wait(semaphore, timeout);
return !result;
}
}
} else
#endif
return true;
{
const void* cfFence = (const void*) fence;
semaphore = (__bridge dispatch_semaphore_t)cfFence;
}
long result = dispatch_semaphore_wait(semaphore, timeout);
return !result;
}
void GrMtlGpu::deleteFence(GrFence) const {
// nothing to delete
void GrMtlGpu::deleteFence(GrFence fence) const {
#ifdef GR_METAL_SDK_SUPPORTS_EVENTS
if (@available(macOS 10.14, iOS 12.0, *)) {
// nothing to delete
} else
#endif
{
const void* cfFence = (const void*) fence;
// In this case it's easier to release in CoreFoundation than depend on ARC
CFRelease(cfFence);
}
}
sk_sp<GrSemaphore> SK_WARN_UNUSED_RESULT GrMtlGpu::makeSemaphore(bool isOwned) {