1/*
2 * Copyright 2017 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#ifndef GrBackendSemaphore_DEFINED
9#define GrBackendSemaphore_DEFINED
10
11#include "include/gpu/GrTypes.h"
12
13#include "include/gpu/gl/GrGLTypes.h"
14#include "include/gpu/mtl/GrMtlTypes.h"
15#include "include/gpu/vk/GrVkTypes.h"
16#ifdef SK_DIRECT3D
17#include "include/gpu/d3d/GrD3DTypesMinimal.h"
18#endif
19
20/**
21 * Wrapper class for passing into and receiving data from Ganesh about a backend semaphore object.
22 */
23class GrBackendSemaphore {
24public:
25 // For convenience we just set the backend here to OpenGL. The GrBackendSemaphore cannot be used
26 // until either initGL or initVulkan are called which will set the appropriate GrBackend.
27 GrBackendSemaphore()
28 : fBackend(GrBackendApi::kOpenGL), fGLSync(nullptr), fIsInitialized(false) {}
29
30#ifdef SK_DIRECT3D
31 // We only need to specify these if Direct3D is enabled, because it requires special copy
32 // characteristics.
33 ~GrBackendSemaphore();
34 GrBackendSemaphore(const GrBackendSemaphore&);
35 GrBackendSemaphore& operator=(const GrBackendSemaphore&);
36#endif
37
38 void initGL(GrGLsync sync) {
39 fBackend = GrBackendApi::kOpenGL;
40 fGLSync = sync;
41 fIsInitialized = true;
42 }
43
44 void initVulkan(VkSemaphore semaphore) {
45 fBackend = GrBackendApi::kVulkan;
46 fVkSemaphore = semaphore;
47#ifdef SK_VULKAN
48 fIsInitialized = true;
49#else
50 fIsInitialized = false;
51#endif
52 }
53
54 // It is the creator's responsibility to ref the MTLEvent passed in here, via __bridge_retained.
55 // The other end will wrap this BackendSemaphore and take the ref, via __bridge_transfer.
56 void initMetal(GrMTLHandle event, uint64_t value) {
57 fBackend = GrBackendApi::kMetal;
58 fMtlEvent = event;
59 fMtlValue = value;
60#ifdef SK_METAL
61 fIsInitialized = true;
62#else
63 fIsInitialized = false;
64#endif
65 }
66
67#ifdef SK_DIRECT3D
68 void initDirect3D(const GrD3DFenceInfo& info) {
69 fBackend = GrBackendApi::kDirect3D;
70 this->assignD3DFenceInfo(info);
71 fIsInitialized = true;
72 }
73#endif
74
75 bool isInitialized() const { return fIsInitialized; }
76
77 GrGLsync glSync() const {
78 if (!fIsInitialized || GrBackendApi::kOpenGL != fBackend) {
79 return nullptr;
80 }
81 return fGLSync;
82 }
83
84 VkSemaphore vkSemaphore() const {
85 if (!fIsInitialized || GrBackendApi::kVulkan != fBackend) {
86 return VK_NULL_HANDLE;
87 }
88 return fVkSemaphore;
89 }
90
91 GrMTLHandle mtlSemaphore() const {
92 if (!fIsInitialized || GrBackendApi::kMetal != fBackend) {
93 return nullptr;
94 }
95 return fMtlEvent;
96 }
97
98 uint64_t mtlValue() const {
99 if (!fIsInitialized || GrBackendApi::kMetal != fBackend) {
100 return 0;
101 }
102 return fMtlValue;
103 }
104
105#ifdef SK_DIRECT3D
106 bool getD3DFenceInfo(GrD3DFenceInfo* outInfo) const;
107#endif
108
109private:
110#ifdef SK_DIRECT3D
111 void assignD3DFenceInfo(const GrD3DFenceInfo& info);
112#endif
113
114 GrBackendApi fBackend;
115 union {
116 GrGLsync fGLSync;
117 VkSemaphore fVkSemaphore;
118 GrMTLHandle fMtlEvent; // Expected to be an id<MTLEvent>
119#ifdef SK_DIRECT3D
120 GrD3DFenceInfo* fD3DFenceInfo;
121#endif
122 };
123 uint64_t fMtlValue;
124 bool fIsInitialized;
125};
126
127#endif
128