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->options().fPlotOldThreshold);
113 this->priv().addOnFlushCallbackObject(fAtlasManager);
114
115 return true;
116 }
117
onGetAtlasManager()118 GrAtlasManager* onGetAtlasManager() override { return fAtlasManager; }
119
120 private:
121 GrAtlasManager* fAtlasManager;
122
123 typedef GrContext INHERITED;
124 };
125
MakeGL(sk_sp<const GrGLInterface> interface)126 sk_sp<GrContext> GrContext::MakeGL(sk_sp<const GrGLInterface> interface) {
127 GrContextOptions defaultOptions;
128 return MakeGL(std::move(interface), defaultOptions);
129 }
130
MakeGL(const GrContextOptions & options)131 sk_sp<GrContext> GrContext::MakeGL(const GrContextOptions& options) {
132 return MakeGL(nullptr, options);
133 }
134
MakeGL()135 sk_sp<GrContext> GrContext::MakeGL() {
136 GrContextOptions defaultOptions;
137 return MakeGL(nullptr, defaultOptions);
138 }
139
MakeGL(sk_sp<const GrGLInterface> interface,const GrContextOptions & options)140 sk_sp<GrContext> GrContext::MakeGL(sk_sp<const GrGLInterface> interface,
141 const GrContextOptions& options) {
142 sk_sp<GrContext> context(new GrLegacyDirectContext(GrBackendApi::kOpenGL, options));
143
144 context->fGpu = GrGLGpu::Make(std::move(interface), options, context.get());
145 if (!context->fGpu) {
146 return nullptr;
147 }
148
149 if (!context->init(context->fGpu->refCaps(), nullptr)) {
150 return nullptr;
151 }
152 return context;
153 }
154
MakeMock(const GrMockOptions * mockOptions)155 sk_sp<GrContext> GrContext::MakeMock(const GrMockOptions* mockOptions) {
156 GrContextOptions defaultOptions;
157 return MakeMock(mockOptions, defaultOptions);
158 }
159
MakeMock(const GrMockOptions * mockOptions,const GrContextOptions & options)160 sk_sp<GrContext> GrContext::MakeMock(const GrMockOptions* mockOptions,
161 const GrContextOptions& options) {
162 sk_sp<GrContext> context(new GrLegacyDirectContext(GrBackendApi::kMock, options));
163
164 context->fGpu = GrMockGpu::Make(mockOptions, options, context.get());
165 if (!context->fGpu) {
166 return nullptr;
167 }
168
169 if (!context->init(context->fGpu->refCaps(), nullptr)) {
170 return nullptr;
171 }
172 return context;
173 }
174
MakeVulkan(const GrVkBackendContext & backendContext)175 sk_sp<GrContext> GrContext::MakeVulkan(const GrVkBackendContext& backendContext) {
176 #ifdef SK_VULKAN
177 GrContextOptions defaultOptions;
178 return MakeVulkan(backendContext, defaultOptions);
179 #else
180 return nullptr;
181 #endif
182 }
183
MakeVulkan(const GrVkBackendContext & backendContext,const GrContextOptions & options)184 sk_sp<GrContext> GrContext::MakeVulkan(const GrVkBackendContext& backendContext,
185 const GrContextOptions& options) {
186 #ifdef SK_VULKAN
187 GrContextOptions defaultOptions;
188 sk_sp<GrContext> context(new GrLegacyDirectContext(GrBackendApi::kVulkan, options));
189
190 context->fGpu = GrVkGpu::Make(backendContext, options, context.get());
191 if (!context->fGpu) {
192 return nullptr;
193 }
194
195 if (!context->init(context->fGpu->refCaps(), nullptr)) {
196 return nullptr;
197 }
198 return context;
199 #else
200 return nullptr;
201 #endif
202 }
203
204 #ifdef SK_METAL
MakeMetal(void * device,void * queue)205 sk_sp<GrContext> GrContext::MakeMetal(void* device, void* queue) {
206 GrContextOptions defaultOptions;
207 return MakeMetal(device, queue, defaultOptions);
208 }
209
MakeMetal(void * device,void * queue,const GrContextOptions & options)210 sk_sp<GrContext> GrContext::MakeMetal(void* device, void* queue, const GrContextOptions& options) {
211 sk_sp<GrContext> context(new GrLegacyDirectContext(GrBackendApi::kMetal, options));
212
213 context->fGpu = GrMtlTrampoline::MakeGpu(context.get(), options, device, queue);
214 if (!context->fGpu) {
215 return nullptr;
216 }
217
218 if (!context->init(context->fGpu->refCaps(), nullptr)) {
219 return nullptr;
220 }
221 return context;
222 }
223 #endif
224
225 #ifdef SK_DAWN
MakeDawn(const dawn::Device & device)226 sk_sp<GrContext> GrContext::MakeDawn(const dawn::Device& device) {
227 GrContextOptions defaultOptions;
228 return MakeDawn(device, defaultOptions);
229 }
230
MakeDawn(const dawn::Device & device,const GrContextOptions & options)231 sk_sp<GrContext> GrContext::MakeDawn(const dawn::Device& device, const GrContextOptions& options) {
232 sk_sp<GrContext> context(new GrLegacyDirectContext(GrBackendApi::kDawn, options));
233
234 context->fGpu = GrDawnGpu::Make(device, options, context.get());
235 if (!context->fGpu) {
236 return nullptr;
237 }
238
239 if (!context->init(context->fGpu->refCaps(), nullptr)) {
240 return nullptr;
241 }
242 return context;
243 }
244 #endif
245