blob: 7a5fad0e596f9c78b36991a9315ca8ecdc383eb0 [file] [log] [blame]
Robert Phillipsa3457b82018-03-08 11:30:12 -05001/*
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
Greg Daniel54bfb182018-11-20 17:12:36 -05008
Robert Phillipsa3457b82018-03-08 11:30:12 -05009#include "GrContext.h"
10
11#include "GrContextPriv.h"
Robert Phillipsa0bc39d2019-01-29 13:14:47 -050012#include "GrContextThreadSafeProxy.h"
Robert Phillipsbb606772019-02-04 17:50:57 -050013#include "GrContextThreadSafeProxyPriv.h"
Robert Phillipsa3457b82018-03-08 11:30:12 -050014#include "GrGpu.h"
15
Ethan Nicholas00543112018-07-31 09:44:36 -040016#include "effects/GrSkSLFP.h"
Robert Phillipsa3457b82018-03-08 11:30:12 -050017#include "gl/GrGLGpu.h"
18#include "mock/GrMockGpu.h"
Herb Derby081e6f32019-01-16 13:46:02 -050019#include "text/GrStrikeCache.h"
Robert Phillipsa3457b82018-03-08 11:30:12 -050020#ifdef SK_METAL
21#include "mtl/GrMtlTrampoline.h"
22#endif
23#ifdef SK_VULKAN
24#include "vk/GrVkGpu.h"
25#endif
26
Robert Phillips88b93da2019-03-11 14:45:43 -040027#ifdef SK_DISABLE_OPLIST_SORTING
28static const bool kDefaultSortOpLists = false;
29#else
30static const bool kDefaultSortOpLists = true;
31#endif
32
Robert Phillipse8345792019-02-07 10:48:24 -050033class SK_API GrLegacyDirectContext : public GrContext {
Robert Phillipsa3457b82018-03-08 11:30:12 -050034public:
Robert Phillipse8345792019-02-07 10:48:24 -050035 GrLegacyDirectContext(GrBackendApi backend, const GrContextOptions& options)
Robert Phillipsc1541ae2019-02-04 12:05:37 -050036 : INHERITED(backend, options)
Robert Phillipsa3457b82018-03-08 11:30:12 -050037 , fAtlasManager(nullptr) {
38 }
39
Robert Phillipse8345792019-02-07 10:48:24 -050040 ~GrLegacyDirectContext() override {
Robert Phillipsa3457b82018-03-08 11:30:12 -050041 // this if-test protects against the case where the context is being destroyed
42 // before having been fully created
Robert Phillips9da87e02019-02-04 13:26:26 -050043 if (this->priv().getGpu()) {
Robert Phillipsa3457b82018-03-08 11:30:12 -050044 this->flush();
45 }
46
47 delete fAtlasManager;
48 }
49
50 void abandonContext() override {
51 INHERITED::abandonContext();
52 fAtlasManager->freeAll();
53 }
54
55 void releaseResourcesAndAbandonContext() override {
56 INHERITED::releaseResourcesAndAbandonContext();
57 fAtlasManager->freeAll();
58 }
59
60 void freeGpuResources() override {
61 this->flush();
62 fAtlasManager->freeAll();
63
64 INHERITED::freeGpuResources();
65 }
66
67protected:
Robert Phillipsbb606772019-02-04 17:50:57 -050068 bool init(sk_sp<const GrCaps> caps, sk_sp<GrSkSLFPFactoryCache> FPFactoryCache) override {
69 SkASSERT(caps && !FPFactoryCache);
Robert Phillipsa3457b82018-03-08 11:30:12 -050070 SkASSERT(!fThreadSafeProxy);
Robert Phillipsa3457b82018-03-08 11:30:12 -050071
Robert Phillipsbb606772019-02-04 17:50:57 -050072 FPFactoryCache.reset(new GrSkSLFPFactoryCache());
73 fThreadSafeProxy = GrContextThreadSafeProxyPriv::Make(this->backend(),
74 this->options(),
75 this->contextID(),
76 caps, FPFactoryCache);
77
78 if (!INHERITED::init(std::move(caps), std::move(FPFactoryCache))) {
Robert Phillipsa3457b82018-03-08 11:30:12 -050079 return false;
80 }
81
Robert Phillips88b93da2019-03-11 14:45:43 -040082 bool sortOpLists = kDefaultSortOpLists;
Robert Phillips56181ba2019-03-08 12:00:45 -050083 if (GrContextOptions::Enable::kNo == this->options().fSortRenderTargets) {
84 sortOpLists = false;
85 } else if (GrContextOptions::Enable::kYes == this->options().fSortRenderTargets) {
86 sortOpLists = true;
87 }
88
Robert Phillips2cce8052019-03-11 14:01:39 -040089 // For now, this is only turned on for direct rendering when explicitly enabled.
90 // Once predictive intermediate flushes are implemented it should be enabled whenever
91 // sorting is enabled.
92 bool reduceOpListSplitting = false; // sortOpLists
93 if (GrContextOptions::Enable::kNo == this->options().fReduceOpListSplitting) {
94 reduceOpListSplitting = false;
95 } else if (GrContextOptions::Enable::kYes == this->options().fReduceOpListSplitting) {
96 reduceOpListSplitting = true;
97 }
98
99 this->setupDrawingManager(this->explicitlyAllocateGPUResources(),
100 sortOpLists, reduceOpListSplitting);
Robert Phillips56181ba2019-03-08 12:00:45 -0500101
Robert Phillipsbb606772019-02-04 17:50:57 -0500102 SkASSERT(this->caps());
103
Robert Phillipsa3457b82018-03-08 11:30:12 -0500104 GrDrawOpAtlas::AllowMultitexturing allowMultitexturing;
Robert Phillipsc1541ae2019-02-04 12:05:37 -0500105 if (GrContextOptions::Enable::kNo == this->options().fAllowMultipleGlyphCacheTextures ||
Robert Phillipsa3457b82018-03-08 11:30:12 -0500106 // multitexturing supported only if range can represent the index + texcoords fully
Robert Phillipsbb606772019-02-04 17:50:57 -0500107 !(this->caps()->shaderCaps()->floatIs32Bits() ||
108 this->caps()->shaderCaps()->integerSupport())) {
Robert Phillipsa3457b82018-03-08 11:30:12 -0500109 allowMultitexturing = GrDrawOpAtlas::AllowMultitexturing::kNo;
110 } else {
111 allowMultitexturing = GrDrawOpAtlas::AllowMultitexturing::kYes;
112 }
113
Herb Derbya00da612019-03-04 17:10:01 -0500114 GrStrikeCache* glyphCache = this->priv().getGrStrikeCache();
Robert Phillips9da87e02019-02-04 13:26:26 -0500115 GrProxyProvider* proxyProvider = this->priv().proxyProvider();
Robert Phillipsa3457b82018-03-08 11:30:12 -0500116
117 fAtlasManager = new GrAtlasManager(proxyProvider, glyphCache,
Robert Phillipsc1541ae2019-02-04 12:05:37 -0500118 this->options().fGlyphCacheTextureMaximumBytes,
Robert Phillipsa3457b82018-03-08 11:30:12 -0500119 allowMultitexturing);
Robert Phillips9da87e02019-02-04 13:26:26 -0500120 this->priv().addOnFlushCallbackObject(fAtlasManager);
Robert Phillipsa3457b82018-03-08 11:30:12 -0500121
Robert Phillipsa3457b82018-03-08 11:30:12 -0500122 return true;
123 }
124
125 GrAtlasManager* onGetAtlasManager() override { return fAtlasManager; }
126
127private:
128 GrAtlasManager* fAtlasManager;
129
130 typedef GrContext INHERITED;
131};
132
Robert Phillipsa3457b82018-03-08 11:30:12 -0500133sk_sp<GrContext> GrContext::MakeGL(sk_sp<const GrGLInterface> interface) {
134 GrContextOptions defaultOptions;
135 return MakeGL(std::move(interface), defaultOptions);
136}
137
Brian Salomonc1b9c102018-04-06 09:18:00 -0400138sk_sp<GrContext> GrContext::MakeGL(const GrContextOptions& options) {
139 return MakeGL(nullptr, options);
140}
141
142sk_sp<GrContext> GrContext::MakeGL() {
143 GrContextOptions defaultOptions;
144 return MakeGL(nullptr, defaultOptions);
145}
146
Robert Phillipsa3457b82018-03-08 11:30:12 -0500147sk_sp<GrContext> GrContext::MakeGL(sk_sp<const GrGLInterface> interface,
148 const GrContextOptions& options) {
Robert Phillipse8345792019-02-07 10:48:24 -0500149 sk_sp<GrContext> context(new GrLegacyDirectContext(GrBackendApi::kOpenGL, options));
Robert Phillipsa3457b82018-03-08 11:30:12 -0500150
151 context->fGpu = GrGLGpu::Make(std::move(interface), options, context.get());
152 if (!context->fGpu) {
153 return nullptr;
154 }
155
Robert Phillipsbb606772019-02-04 17:50:57 -0500156 if (!context->init(context->fGpu->refCaps(), nullptr)) {
Robert Phillipsa3457b82018-03-08 11:30:12 -0500157 return nullptr;
158 }
159 return context;
160}
161
162sk_sp<GrContext> GrContext::MakeMock(const GrMockOptions* mockOptions) {
163 GrContextOptions defaultOptions;
164 return MakeMock(mockOptions, defaultOptions);
165}
166
167sk_sp<GrContext> GrContext::MakeMock(const GrMockOptions* mockOptions,
168 const GrContextOptions& options) {
Robert Phillipse8345792019-02-07 10:48:24 -0500169 sk_sp<GrContext> context(new GrLegacyDirectContext(GrBackendApi::kMock, options));
Robert Phillipsa3457b82018-03-08 11:30:12 -0500170
171 context->fGpu = GrMockGpu::Make(mockOptions, options, context.get());
172 if (!context->fGpu) {
173 return nullptr;
174 }
175
Robert Phillipsbb606772019-02-04 17:50:57 -0500176 if (!context->init(context->fGpu->refCaps(), nullptr)) {
Robert Phillipsa3457b82018-03-08 11:30:12 -0500177 return nullptr;
178 }
179 return context;
180}
181
Mike Kleina55e2142018-10-03 16:34:11 +0000182sk_sp<GrContext> GrContext::MakeVulkan(const GrVkBackendContext& backendContext) {
Greg Danielb4d89562018-10-03 18:44:49 +0000183#ifdef SK_VULKAN
Greg Daniel10a83da2018-06-14 09:31:11 -0400184 GrContextOptions defaultOptions;
185 return MakeVulkan(backendContext, defaultOptions);
Greg Danielb4d89562018-10-03 18:44:49 +0000186#else
187 return nullptr;
188#endif
Greg Daniel10a83da2018-06-14 09:31:11 -0400189}
190
191sk_sp<GrContext> GrContext::MakeVulkan(const GrVkBackendContext& backendContext,
192 const GrContextOptions& options) {
Greg Danielb4d89562018-10-03 18:44:49 +0000193#ifdef SK_VULKAN
194 GrContextOptions defaultOptions;
Robert Phillipse8345792019-02-07 10:48:24 -0500195 sk_sp<GrContext> context(new GrLegacyDirectContext(GrBackendApi::kVulkan, options));
Greg Daniel10a83da2018-06-14 09:31:11 -0400196
Greg Danielf730c182018-07-02 20:15:37 +0000197 context->fGpu = GrVkGpu::Make(backendContext, options, context.get());
Robert Phillipsa3457b82018-03-08 11:30:12 -0500198 if (!context->fGpu) {
199 return nullptr;
200 }
201
Robert Phillipsbb606772019-02-04 17:50:57 -0500202 if (!context->init(context->fGpu->refCaps(), nullptr)) {
Robert Phillipsa3457b82018-03-08 11:30:12 -0500203 return nullptr;
204 }
205 return context;
Greg Danielb4d89562018-10-03 18:44:49 +0000206#else
207 return nullptr;
Mike Kleina55e2142018-10-03 16:34:11 +0000208#endif
Greg Danielb4d89562018-10-03 18:44:49 +0000209}
Robert Phillipsa3457b82018-03-08 11:30:12 -0500210
211#ifdef SK_METAL
212sk_sp<GrContext> GrContext::MakeMetal(void* device, void* queue) {
213 GrContextOptions defaultOptions;
214 return MakeMetal(device, queue, defaultOptions);
215}
216
217sk_sp<GrContext> GrContext::MakeMetal(void* device, void* queue, const GrContextOptions& options) {
Robert Phillipse8345792019-02-07 10:48:24 -0500218 sk_sp<GrContext> context(new GrLegacyDirectContext(GrBackendApi::kMetal, options));
Robert Phillipsa3457b82018-03-08 11:30:12 -0500219
220 context->fGpu = GrMtlTrampoline::MakeGpu(context.get(), options, device, queue);
221 if (!context->fGpu) {
222 return nullptr;
223 }
Timothy Liang4e85e802018-06-28 16:37:18 -0400224
Robert Phillipsbb606772019-02-04 17:50:57 -0500225 if (!context->init(context->fGpu->refCaps(), nullptr)) {
Robert Phillipsa3457b82018-03-08 11:30:12 -0500226 return nullptr;
227 }
228 return context;
229}
230#endif
231