1/*
2 * Copyright 2019 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "src/gpu/mtl/GrMtlGpu.h"
9#include "src/gpu/mtl/GrMtlSemaphore.h"
10
11#if !__has_feature(objc_arc)
12#error This file must be compiled with Arc. Use -fobjc-arc flag
13#endif
14
15sk_sp<GrMtlSemaphore> GrMtlSemaphore::Make(GrMtlGpu* gpu, bool isOwned) {
16    if (@available(macOS 10.14, iOS 12.0, *)) {
17        id<MTLEvent> event = [gpu->device() newEvent];
18        uint64_t value = 1; // seems like a reasonable starting point
19        return sk_sp<GrMtlSemaphore>(new GrMtlSemaphore(gpu, event, value, isOwned));
20    } else {
21        return nullptr;
22    }
23}
24
25sk_sp<GrMtlSemaphore> GrMtlSemaphore::MakeWrapped(GrMtlGpu* gpu,
26                                                  GrMTLHandle event,
27                                                  uint64_t value,
28                                                  GrWrapOwnership ownership) {
29    // The GrMtlSemaphore will have strong ownership at this point.
30    // The GrMTLHandle will subsequently only have weak ownership.
31    if (@available(macOS 10.14, iOS 12.0, *)) {
32        id<MTLEvent> mtlEvent = (__bridge_transfer id<MTLEvent>)event;
33        auto sema = sk_sp<GrMtlSemaphore>(new GrMtlSemaphore(gpu, mtlEvent, value,
34                                                             kBorrow_GrWrapOwnership != ownership));
35        return sema;
36    } else {
37        return nullptr;
38    }
39}
40
41GrMtlSemaphore::GrMtlSemaphore(GrMtlGpu* gpu, id<MTLEvent> event, uint64_t value, bool isOwned)
42        : INHERITED(gpu), fEvent(event), fValue(value) {
43    isOwned ? this->registerWithCache(SkBudgeted::kNo)
44            : this->registerWithCacheWrapped(GrWrapCacheable::kNo);
45}
46
47void GrMtlSemaphore::onRelease() {
48    if (@available(macOS 10.14, iOS 12.0, *)) {
49        fEvent = nil;
50    }
51    INHERITED::onRelease();
52}
53
54void GrMtlSemaphore::onAbandon() {
55    if (@available(macOS 10.14, iOS 12.0, *)) {
56        fEvent = nil;
57    }
58    INHERITED::onAbandon();
59}
60
61GrBackendSemaphore GrMtlSemaphore::backendSemaphore() const {
62    GrBackendSemaphore backendSemaphore;
63    // The GrMtlSemaphore and the GrBackendSemaphore will have strong ownership at this point.
64    // Whoever uses the GrBackendSemaphore will subsquently steal this ref (see MakeWrapped, above).
65    if (@available(macOS 10.14, iOS 12.0, *)) {
66        GrMTLHandle handle = (__bridge_retained GrMTLHandle)(fEvent);
67        backendSemaphore.initMetal(handle, fValue);
68    }
69    return backendSemaphore;
70}
71