• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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