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