• 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->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