1 /*
2 * Copyright 2018 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
9 #include "include/gpu/GrContext.h"
10
11 #include "include/gpu/GrContextThreadSafeProxy.h"
12 #include "src/gpu/GrContextPriv.h"
13 #include "src/gpu/GrContextThreadSafeProxyPriv.h"
14 #include "src/gpu/GrGpu.h"
15
16 #include "src/gpu/effects/GrSkSLFP.h"
17 #include "src/gpu/gl/GrGLGpu.h"
18 #include "src/gpu/mock/GrMockGpu.h"
19 #include "src/gpu/text/GrStrikeCache.h"
20 #ifdef SK_METAL
21 #include "src/gpu/mtl/GrMtlTrampoline.h"
22 #endif
23 #ifdef SK_VULKAN
24 #include "src/gpu/vk/GrVkGpu.h"
25 #endif
26 #ifdef SK_DAWN
27 #include "src/gpu/dawn/GrDawnGpu.h"
28 #endif
29
30 #ifdef SK_DISABLE_REDUCE_OPLIST_SPLITTING
31 static const bool kDefaultReduceOpListSplitting = false;
32 #else
33 static const bool kDefaultReduceOpListSplitting = false;
34 #endif
35
36 class SK_API GrLegacyDirectContext : public GrContext {
37 public:
GrLegacyDirectContext(GrBackendApi backend,const GrContextOptions & options)38 GrLegacyDirectContext(GrBackendApi backend, const GrContextOptions& options)
39 : INHERITED(backend, options)
40 , fAtlasManager(nullptr) {
41 }
42
~GrLegacyDirectContext()43 ~GrLegacyDirectContext() override {
44 // this if-test protects against the case where the context is being destroyed
45 // before having been fully created
46 if (this->priv().getGpu()) {
47 this->flush();
48 }
49
50 delete fAtlasManager;
51 }
52
abandonContext()53 void abandonContext() override {
54 INHERITED::abandonContext();
55 fAtlasManager->freeAll();
56 }
57
releaseResourcesAndAbandonContext()58 void releaseResourcesAndAbandonContext() override {
59 INHERITED::releaseResourcesAndAbandonContext();
60 fAtlasManager->freeAll();
61 }
62
freeGpuResources()63 void freeGpuResources() override {
64 this->flush();
65 fAtlasManager->freeAll();
66
67 INHERITED::freeGpuResources();
68 }
69
70 protected:
init(sk_sp<const GrCaps> caps,sk_sp<GrSkSLFPFactoryCache> FPFactoryCache)71 bool init(sk_sp<const GrCaps> caps, sk_sp<GrSkSLFPFactoryCache> FPFactoryCache) override {
72 SkASSERT(caps && !FPFactoryCache);
73 SkASSERT(!fThreadSafeProxy);
74
75 FPFactoryCache.reset(new GrSkSLFPFactoryCache());
76 fThreadSafeProxy = GrContextThreadSafeProxyPriv::Make(this->backend(),
77 this->options(),
78 this->contextID(),
79 caps, FPFactoryCache);
80
81 if (!INHERITED::init(std::move(caps), std::move(FPFactoryCache))) {
82 return false;
83 }
84
85 bool reduceOpListSplitting = kDefaultReduceOpListSplitting;
86 if (GrContextOptions::Enable::kNo == this->options().fReduceOpListSplitting) {
87 reduceOpListSplitting = false;
88 } else if (GrContextOptions::Enable::kYes == this->options().fReduceOpListSplitting) {
89 reduceOpListSplitting = true;
90 }
91
92 this->setupDrawingManager(true, reduceOpListSplitting);
93
94 SkASSERT(this->caps());
95
96 GrDrawOpAtlas::AllowMultitexturing allowMultitexturing;
97 if (GrContextOptions::Enable::kNo == this->options().fAllowMultipleGlyphCacheTextures ||
98 // multitexturing supported only if range can represent the index + texcoords fully
99 !(this->caps()->shaderCaps()->floatIs32Bits() ||
100 this->caps()->shaderCaps()->integerSupport())) {
101 allowMultitexturing = GrDrawOpAtlas::AllowMultitexturing::kNo;
102 } else {
103 allowMultitexturing = GrDrawOpAtlas::AllowMultitexturing::kYes;
104 }
105
106 GrStrikeCache* glyphCache = this->priv().getGrStrikeCache();
107 GrProxyProvider* proxyProvider = this->priv().proxyProvider();
108
109 fAtlasManager = new GrAtlasManager(proxyProvider, glyphCache,
110 this->options().fGlyphCacheTextureMaximumBytes,
111 allowMultitexturing);
112 this->priv().addOnFlushCallbackObject(fAtlasManager);
113
114 return true;
115 }
116
onGetAtlasManager()117 GrAtlasManager* onGetAtlasManager() override { return fAtlasManager; }
118
119 private:
120 GrAtlasManager* fAtlasManager;
121
122 typedef GrContext INHERITED;
123 };
124
MakeGL(sk_sp<const GrGLInterface> interface)125 sk_sp<GrContext> GrContext::MakeGL(sk_sp<const GrGLInterface> interface) {
126 GrContextOptions defaultOptions;
127 return MakeGL(std::move(interface), defaultOptions);
128 }
129
MakeGL(const GrContextOptions & options)130 sk_sp<GrContext> GrContext::MakeGL(const GrContextOptions& options) {
131 return MakeGL(nullptr, options);
132 }
133
MakeGL()134 sk_sp<GrContext> GrContext::MakeGL() {
135 GrContextOptions defaultOptions;
136 return MakeGL(nullptr, defaultOptions);
137 }
138
MakeGL(sk_sp<const GrGLInterface> interface,const GrContextOptions & options)139 sk_sp<GrContext> GrContext::MakeGL(sk_sp<const GrGLInterface> interface,
140 const GrContextOptions& options) {
141 sk_sp<GrContext> context(new GrLegacyDirectContext(GrBackendApi::kOpenGL, options));
142
143 context->fGpu = GrGLGpu::Make(std::move(interface), options, context.get());
144 if (!context->fGpu) {
145 return nullptr;
146 }
147
148 if (!context->init(context->fGpu->refCaps(), nullptr)) {
149 return nullptr;
150 }
151 return context;
152 }
153
MakeMock(const GrMockOptions * mockOptions)154 sk_sp<GrContext> GrContext::MakeMock(const GrMockOptions* mockOptions) {
155 GrContextOptions defaultOptions;
156 return MakeMock(mockOptions, defaultOptions);
157 }
158
MakeMock(const GrMockOptions * mockOptions,const GrContextOptions & options)159 sk_sp<GrContext> GrContext::MakeMock(const GrMockOptions* mockOptions,
160 const GrContextOptions& options) {
161 sk_sp<GrContext> context(new GrLegacyDirectContext(GrBackendApi::kMock, options));
162
163 context->fGpu = GrMockGpu::Make(mockOptions, options, context.get());
164 if (!context->fGpu) {
165 return nullptr;
166 }
167
168 if (!context->init(context->fGpu->refCaps(), nullptr)) {
169 return nullptr;
170 }
171 return context;
172 }
173
MakeVulkan(const GrVkBackendContext & backendContext)174 sk_sp<GrContext> GrContext::MakeVulkan(const GrVkBackendContext& backendContext) {
175 #ifdef SK_VULKAN
176 GrContextOptions defaultOptions;
177 return MakeVulkan(backendContext, defaultOptions);
178 #else
179 return nullptr;
180 #endif
181 }
182
MakeVulkan(const GrVkBackendContext & backendContext,const GrContextOptions & options)183 sk_sp<GrContext> GrContext::MakeVulkan(const GrVkBackendContext& backendContext,
184 const GrContextOptions& options) {
185 #ifdef SK_VULKAN
186 GrContextOptions defaultOptions;
187 sk_sp<GrContext> context(new GrLegacyDirectContext(GrBackendApi::kVulkan, options));
188
189 context->fGpu = GrVkGpu::Make(backendContext, options, context.get());
190 if (!context->fGpu) {
191 return nullptr;
192 }
193
194 if (!context->init(context->fGpu->refCaps(), nullptr)) {
195 return nullptr;
196 }
197 return context;
198 #else
199 return nullptr;
200 #endif
201 }
202
203 #ifdef SK_METAL
MakeMetal(void * device,void * queue)204 sk_sp<GrContext> GrContext::MakeMetal(void* device, void* queue) {
205 GrContextOptions defaultOptions;
206 return MakeMetal(device, queue, defaultOptions);
207 }
208
MakeMetal(void * device,void * queue,const GrContextOptions & options)209 sk_sp<GrContext> GrContext::MakeMetal(void* device, void* queue, const GrContextOptions& options) {
210 sk_sp<GrContext> context(new GrLegacyDirectContext(GrBackendApi::kMetal, options));
211
212 context->fGpu = GrMtlTrampoline::MakeGpu(context.get(), options, device, queue);
213 if (!context->fGpu) {
214 return nullptr;
215 }
216
217 if (!context->init(context->fGpu->refCaps(), nullptr)) {
218 return nullptr;
219 }
220 return context;
221 }
222 #endif
223
224 #ifdef SK_DAWN
MakeDawn(const dawn::Device & device)225 sk_sp<GrContext> GrContext::MakeDawn(const dawn::Device& device) {
226 GrContextOptions defaultOptions;
227 return MakeDawn(device, defaultOptions);
228 }
229
MakeDawn(const dawn::Device & device,const GrContextOptions & options)230 sk_sp<GrContext> GrContext::MakeDawn(const dawn::Device& device, const GrContextOptions& options) {
231 sk_sp<GrContext> context(new GrLegacyDirectContext(GrBackendApi::kDawn, options));
232
233 context->fGpu = GrDawnGpu::Make(device, options, context.get());
234 if (!context->fGpu) {
235 return nullptr;
236 }
237
238 if (!context->init(context->fGpu->refCaps(), nullptr)) {
239 return nullptr;
240 }
241 return context;
242 }
243 #endif
244