blob: 239ae4aa41ce52f0001d1876297da2834ed2cf50 [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 Phillipsb7bfbc22020-07-01 12:55:01 -04009#include "include/gpu/GrDirectContext.h"
Robert Phillipsa3457b82018-03-08 11:30:12 -050010
Mike Kleinc0bd9f92019-04-23 12:05:21 -050011#include "include/gpu/GrContextThreadSafeProxy.h"
Adlai Holler9555f292020-10-09 09:41:14 -040012#include "src/core/SkTaskGroup.h"
13#include "src/gpu/GrClientMappedBufferManager.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050014#include "src/gpu/GrContextPriv.h"
15#include "src/gpu/GrContextThreadSafeProxyPriv.h"
16#include "src/gpu/GrGpu.h"
Adlai Holler9555f292020-10-09 09:41:14 -040017#include "src/gpu/GrResourceProvider.h"
18#include "src/gpu/GrShaderUtils.h"
Robert Phillipsa3457b82018-03-08 11:30:12 -050019
Mike Kleinc0bd9f92019-04-23 12:05:21 -050020#include "src/gpu/effects/GrSkSLFP.h"
21#include "src/gpu/gl/GrGLGpu.h"
22#include "src/gpu/mock/GrMockGpu.h"
Robert Phillips5edf5102020-08-10 16:30:36 -040023#include "src/gpu/ops/GrSmallPathAtlasMgr.h"
Robert Phillipse19babf2020-04-06 13:57:30 -040024#include "src/gpu/text/GrAtlasManager.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050025#include "src/gpu/text/GrStrikeCache.h"
Robert Phillipsa3457b82018-03-08 11:30:12 -050026#ifdef SK_METAL
Mike Kleinc0bd9f92019-04-23 12:05:21 -050027#include "src/gpu/mtl/GrMtlTrampoline.h"
Robert Phillipsa3457b82018-03-08 11:30:12 -050028#endif
29#ifdef SK_VULKAN
Mike Kleinc0bd9f92019-04-23 12:05:21 -050030#include "src/gpu/vk/GrVkGpu.h"
Robert Phillipsa3457b82018-03-08 11:30:12 -050031#endif
Jim Van Verthd2d4c5e2020-02-19 14:57:58 -050032#ifdef SK_DIRECT3D
33#include "src/gpu/d3d/GrD3DGpu.h"
34#endif
Stephen White985741a2019-07-18 11:43:45 -040035#ifdef SK_DAWN
Mike Klein52337de2019-07-25 09:00:52 -050036#include "src/gpu/dawn/GrDawnGpu.h"
Stephen White985741a2019-07-18 11:43:45 -040037#endif
Robert Phillipsa3457b82018-03-08 11:30:12 -050038
Brian Salomon24069eb2020-06-24 10:19:52 -040039#if GR_TEST_UTILS
40# include "include/utils/SkRandom.h"
41# if defined(SK_ENABLE_SCOPED_LSAN_SUPPRESSIONS)
42# include <sanitizer/lsan_interface.h>
43# endif
44#endif
45
Robert Phillips6db27c22019-05-01 10:43:56 -040046#ifdef SK_DISABLE_REDUCE_OPLIST_SPLITTING
Greg Danielf41b2bd2019-08-22 16:19:24 -040047static const bool kDefaultReduceOpsTaskSplitting = false;
Robert Phillips6db27c22019-05-01 10:43:56 -040048#else
Greg Danielf41b2bd2019-08-22 16:19:24 -040049static const bool kDefaultReduceOpsTaskSplitting = false;
Robert Phillips6db27c22019-05-01 10:43:56 -040050#endif
51
Adlai Holler9555f292020-10-09 09:41:14 -040052#define ASSERT_SINGLE_OWNER GR_ASSERT_SINGLE_OWNER(this->singleOwner())
53
Robert Phillipsad248452020-06-30 09:27:52 -040054GrDirectContext::GrDirectContext(GrBackendApi backend, const GrContextOptions& options)
Robert Phillips3262bc82020-08-10 12:11:58 -040055 : INHERITED(GrContextThreadSafeProxyPriv::Make(backend, options)) {
Robert Phillipsad248452020-06-30 09:27:52 -040056}
Robert Phillipsa3457b82018-03-08 11:30:12 -050057
Robert Phillipsad248452020-06-30 09:27:52 -040058GrDirectContext::~GrDirectContext() {
Adlai Holler9555f292020-10-09 09:41:14 -040059 ASSERT_SINGLE_OWNER
Robert Phillipsad248452020-06-30 09:27:52 -040060 // this if-test protects against the case where the context is being destroyed
61 // before having been fully created
Adlai Holler9555f292020-10-09 09:41:14 -040062 if (fGpu) {
Greg Daniel0a2464f2020-05-14 15:45:44 -040063 this->flushAndSubmit();
Robert Phillipsa3457b82018-03-08 11:30:12 -050064 }
Adlai Holler9555f292020-10-09 09:41:14 -040065
66 this->destroyDrawingManager();
67 fMappedBufferManager.reset();
68
69 // Ideally we could just let the ptr drop, but resource cache queries this ptr in releaseAll.
70 if (fResourceCache) {
71 fResourceCache->releaseAll();
72 }
Robert Phillipsad248452020-06-30 09:27:52 -040073}
Robert Phillipsa3457b82018-03-08 11:30:12 -050074
Robert Phillipsad248452020-06-30 09:27:52 -040075void GrDirectContext::abandonContext() {
76 INHERITED::abandonContext();
Robert Phillips079455c2020-08-11 15:18:46 -040077 if (fSmallPathAtlasMgr) {
78 fSmallPathAtlasMgr->reset();
79 }
Robert Phillipsad248452020-06-30 09:27:52 -040080 fAtlasManager->freeAll();
81}
Robert Phillipsa3457b82018-03-08 11:30:12 -050082
Robert Phillipsad248452020-06-30 09:27:52 -040083void GrDirectContext::releaseResourcesAndAbandonContext() {
84 INHERITED::releaseResourcesAndAbandonContext();
Robert Phillips079455c2020-08-11 15:18:46 -040085 if (fSmallPathAtlasMgr) {
86 fSmallPathAtlasMgr->reset();
87 }
Robert Phillipsad248452020-06-30 09:27:52 -040088 fAtlasManager->freeAll();
89}
Robert Phillips6db27c22019-05-01 10:43:56 -040090
Robert Phillipsad248452020-06-30 09:27:52 -040091void GrDirectContext::freeGpuResources() {
92 this->flushAndSubmit();
Robert Phillips079455c2020-08-11 15:18:46 -040093 if (fSmallPathAtlasMgr) {
94 fSmallPathAtlasMgr->reset();
95 }
Robert Phillipsad248452020-06-30 09:27:52 -040096 fAtlasManager->freeAll();
Robert Phillips56181ba2019-03-08 12:00:45 -050097
Robert Phillipsad248452020-06-30 09:27:52 -040098 INHERITED::freeGpuResources();
99}
Robert Phillipsa3457b82018-03-08 11:30:12 -0500100
Robert Phillipsad248452020-06-30 09:27:52 -0400101bool GrDirectContext::init() {
Adlai Holler9555f292020-10-09 09:41:14 -0400102 ASSERT_SINGLE_OWNER
103 if (!fGpu) {
Robert Phillipsad248452020-06-30 09:27:52 -0400104 return false;
Robert Phillipsa3457b82018-03-08 11:30:12 -0500105 }
106
Adlai Holler9555f292020-10-09 09:41:14 -0400107 fThreadSafeProxy->priv().init(fGpu->refCaps());
Robert Phillipsad248452020-06-30 09:27:52 -0400108 if (!INHERITED::init()) {
109 return false;
110 }
Robert Phillipsa3457b82018-03-08 11:30:12 -0500111
Adlai Holler9555f292020-10-09 09:41:14 -0400112 SkASSERT(this->getTextBlobCache());
113 SkASSERT(this->threadSafeCache());
114
115 fStrikeCache = std::make_unique<GrStrikeCache>();
116 fResourceCache = std::make_unique<GrResourceCache>(this->caps(), this->singleOwner(),
117 this->contextID());
118 fResourceCache->setProxyProvider(this->proxyProvider());
119 fResourceCache->setThreadSafeCache(this->threadSafeCache());
120 fResourceProvider = std::make_unique<GrResourceProvider>(fGpu.get(), fResourceCache.get(),
121 this->singleOwner());
122 fMappedBufferManager = std::make_unique<GrClientMappedBufferManager>(this->contextID());
123
124 fDidTestPMConversions = false;
125
126 // DDL TODO: we need to think through how the task group & persistent cache
127 // get passed on to/shared between all the DDLRecorders created with this context.
128 if (this->options().fExecutor) {
129 fTaskGroup = std::make_unique<SkTaskGroup>(*this->options().fExecutor);
130 }
131
132 fPersistentCache = this->options().fPersistentCache;
133 fShaderErrorHandler = this->options().fShaderErrorHandler;
134 if (!fShaderErrorHandler) {
135 fShaderErrorHandler = GrShaderUtils::DefaultShaderErrorHandler();
136 }
137
Robert Phillipsad248452020-06-30 09:27:52 -0400138 bool reduceOpsTaskSplitting = kDefaultReduceOpsTaskSplitting;
139 if (GrContextOptions::Enable::kNo == this->options().fReduceOpsTaskSplitting) {
140 reduceOpsTaskSplitting = false;
141 } else if (GrContextOptions::Enable::kYes == this->options().fReduceOpsTaskSplitting) {
142 reduceOpsTaskSplitting = true;
143 }
Robert Phillipsa3457b82018-03-08 11:30:12 -0500144
Robert Phillipsad248452020-06-30 09:27:52 -0400145 this->setupDrawingManager(true, reduceOpsTaskSplitting);
146
147 GrDrawOpAtlas::AllowMultitexturing allowMultitexturing;
148 if (GrContextOptions::Enable::kNo == this->options().fAllowMultipleGlyphCacheTextures ||
149 // multitexturing supported only if range can represent the index + texcoords fully
150 !(this->caps()->shaderCaps()->floatIs32Bits() ||
151 this->caps()->shaderCaps()->integerSupport())) {
152 allowMultitexturing = GrDrawOpAtlas::AllowMultitexturing::kNo;
153 } else {
154 allowMultitexturing = GrDrawOpAtlas::AllowMultitexturing::kYes;
155 }
156
157 GrProxyProvider* proxyProvider = this->priv().proxyProvider();
158
Robert Phillips3262bc82020-08-10 12:11:58 -0400159 fAtlasManager = std::make_unique<GrAtlasManager>(proxyProvider,
160 this->options().fGlyphCacheTextureMaximumBytes,
161 allowMultitexturing);
162 this->priv().addOnFlushCallbackObject(fAtlasManager.get());
Robert Phillipsad248452020-06-30 09:27:52 -0400163
164 return true;
165}
Robert Phillipsa3457b82018-03-08 11:30:12 -0500166
Robert Phillips5edf5102020-08-10 16:30:36 -0400167GrSmallPathAtlasMgr* GrDirectContext::onGetSmallPathAtlasMgr() {
Robert Phillips079455c2020-08-11 15:18:46 -0400168 if (!fSmallPathAtlasMgr) {
169 fSmallPathAtlasMgr = std::make_unique<GrSmallPathAtlasMgr>();
170
171 this->priv().addOnFlushCallbackObject(fSmallPathAtlasMgr.get());
172 }
173
174 if (!fSmallPathAtlasMgr->initAtlas(this->proxyProvider(), this->caps())) {
175 return nullptr;
176 }
177
178 return fSmallPathAtlasMgr.get();
Robert Phillips5edf5102020-08-10 16:30:36 -0400179}
180
John Rosascoa9b348f2019-11-08 13:18:15 -0800181#ifdef SK_GL
Robert Phillipsc7228c62020-07-14 12:57:39 -0400182
Robert Phillipsf4f80112020-07-13 16:13:31 -0400183/*************************************************************************************************/
184sk_sp<GrDirectContext> GrDirectContext::MakeGL(sk_sp<const GrGLInterface> glInterface) {
Robert Phillipsa3457b82018-03-08 11:30:12 -0500185 GrContextOptions defaultOptions;
Jim Van Verth03b8ab22020-02-24 11:36:15 -0500186 return MakeGL(std::move(glInterface), defaultOptions);
Robert Phillipsa3457b82018-03-08 11:30:12 -0500187}
188
Robert Phillipsf4f80112020-07-13 16:13:31 -0400189sk_sp<GrDirectContext> GrDirectContext::MakeGL(const GrContextOptions& options) {
Brian Salomonc1b9c102018-04-06 09:18:00 -0400190 return MakeGL(nullptr, options);
191}
192
Robert Phillipsf4f80112020-07-13 16:13:31 -0400193sk_sp<GrDirectContext> GrDirectContext::MakeGL() {
Brian Salomonc1b9c102018-04-06 09:18:00 -0400194 GrContextOptions defaultOptions;
195 return MakeGL(nullptr, defaultOptions);
196}
197
Brian Salomon24069eb2020-06-24 10:19:52 -0400198#if GR_TEST_UTILS
199GrGLFunction<GrGLGetErrorFn> make_get_error_with_random_oom(GrGLFunction<GrGLGetErrorFn> original) {
200 // A SkRandom and a GrGLFunction<GrGLGetErrorFn> are too big to be captured by a
201 // GrGLFunction<GrGLGetError> (surprise, surprise). So we make a context object and
202 // capture that by pointer. However, GrGLFunction doesn't support calling a destructor
203 // on the thing it captures. So we leak the context.
204 struct GetErrorContext {
205 SkRandom fRandom;
206 GrGLFunction<GrGLGetErrorFn> fGetError;
207 };
208
209 auto errorContext = new GetErrorContext;
210
211#if defined(SK_ENABLE_SCOPED_LSAN_SUPPRESSIONS)
212 __lsan_ignore_object(errorContext);
213#endif
214
215 errorContext->fGetError = original;
216
217 return GrGLFunction<GrGLGetErrorFn>([errorContext]() {
218 GrGLenum error = errorContext->fGetError();
219 if (error == GR_GL_NO_ERROR && (errorContext->fRandom.nextU() % 300) == 0) {
220 error = GR_GL_OUT_OF_MEMORY;
221 }
222 return error;
223 });
224}
225#endif
226
Robert Phillipsf4f80112020-07-13 16:13:31 -0400227sk_sp<GrDirectContext> GrDirectContext::MakeGL(sk_sp<const GrGLInterface> glInterface,
228 const GrContextOptions& options) {
229 sk_sp<GrDirectContext> direct(new GrDirectContext(GrBackendApi::kOpenGL, options));
Brian Salomon24069eb2020-06-24 10:19:52 -0400230#if GR_TEST_UTILS
231 if (options.fRandomGLOOM) {
232 auto copy = sk_make_sp<GrGLInterface>(*glInterface);
233 copy->fFunctions.fGetError =
234 make_get_error_with_random_oom(glInterface->fFunctions.fGetError);
235#if GR_GL_CHECK_ERROR
236 // Suppress logging GL errors since we'll be synthetically generating them.
237 copy->suppressErrorLogging();
238#endif
239 glInterface = std::move(copy);
240 }
241#endif
Robert Phillipsf4f80112020-07-13 16:13:31 -0400242 direct->fGpu = GrGLGpu::Make(std::move(glInterface), options, direct.get());
243 if (!direct->init()) {
Robert Phillipsa3457b82018-03-08 11:30:12 -0500244 return nullptr;
245 }
Robert Phillipsf4f80112020-07-13 16:13:31 -0400246 return direct;
Robert Phillipsa3457b82018-03-08 11:30:12 -0500247}
John Rosascoa9b348f2019-11-08 13:18:15 -0800248#endif
Robert Phillipsa3457b82018-03-08 11:30:12 -0500249
Robert Phillipsf4f80112020-07-13 16:13:31 -0400250/*************************************************************************************************/
Robert Phillipsf4f80112020-07-13 16:13:31 -0400251sk_sp<GrDirectContext> GrDirectContext::MakeMock(const GrMockOptions* mockOptions) {
252 GrContextOptions defaultOptions;
253 return MakeMock(mockOptions, defaultOptions);
254}
255
256sk_sp<GrDirectContext> GrDirectContext::MakeMock(const GrMockOptions* mockOptions,
257 const GrContextOptions& options) {
258 sk_sp<GrDirectContext> direct(new GrDirectContext(GrBackendApi::kMock, options));
259
260 direct->fGpu = GrMockGpu::Make(mockOptions, options, direct.get());
261 if (!direct->init()) {
Robert Phillipsa3457b82018-03-08 11:30:12 -0500262 return nullptr;
263 }
Chris Daltona378b452019-12-11 13:24:11 -0500264
Robert Phillipsf4f80112020-07-13 16:13:31 -0400265 return direct;
Robert Phillipsa3457b82018-03-08 11:30:12 -0500266}
267
Greg Danielb4d89562018-10-03 18:44:49 +0000268#ifdef SK_VULKAN
Robert Phillipsf4f80112020-07-13 16:13:31 -0400269/*************************************************************************************************/
Robert Phillipsf4f80112020-07-13 16:13:31 -0400270sk_sp<GrDirectContext> GrDirectContext::MakeVulkan(const GrVkBackendContext& backendContext) {
271 GrContextOptions defaultOptions;
272 return MakeVulkan(backendContext, defaultOptions);
273}
274
275sk_sp<GrDirectContext> GrDirectContext::MakeVulkan(const GrVkBackendContext& backendContext,
276 const GrContextOptions& options) {
277 sk_sp<GrDirectContext> direct(new GrDirectContext(GrBackendApi::kVulkan, options));
278
279 direct->fGpu = GrVkGpu::Make(backendContext, options, direct.get());
280 if (!direct->init()) {
Robert Phillipsa3457b82018-03-08 11:30:12 -0500281 return nullptr;
282 }
283
Robert Phillipsf4f80112020-07-13 16:13:31 -0400284 return direct;
Greg Danielb4d89562018-10-03 18:44:49 +0000285}
Robert Phillipsf4f80112020-07-13 16:13:31 -0400286#endif
Robert Phillipsa3457b82018-03-08 11:30:12 -0500287
288#ifdef SK_METAL
Robert Phillipsf4f80112020-07-13 16:13:31 -0400289/*************************************************************************************************/
Robert Phillipsf4f80112020-07-13 16:13:31 -0400290sk_sp<GrDirectContext> GrDirectContext::MakeMetal(void* device, void* queue) {
Robert Phillipsa3457b82018-03-08 11:30:12 -0500291 GrContextOptions defaultOptions;
292 return MakeMetal(device, queue, defaultOptions);
293}
294
Robert Phillipsf4f80112020-07-13 16:13:31 -0400295sk_sp<GrDirectContext> GrDirectContext::MakeMetal(void* device, void* queue,
296 const GrContextOptions& options) {
297 sk_sp<GrDirectContext> direct(new GrDirectContext(GrBackendApi::kMetal, options));
Robert Phillipsa3457b82018-03-08 11:30:12 -0500298
Robert Phillipsf4f80112020-07-13 16:13:31 -0400299 direct->fGpu = GrMtlTrampoline::MakeGpu(direct.get(), options, device, queue);
300 if (!direct->init()) {
Robert Phillipsa3457b82018-03-08 11:30:12 -0500301 return nullptr;
302 }
Timothy Liang4e85e802018-06-28 16:37:18 -0400303
Robert Phillipsf4f80112020-07-13 16:13:31 -0400304 return direct;
Robert Phillipsa3457b82018-03-08 11:30:12 -0500305}
306#endif
307
Jim Van Verthb01e12b2020-02-18 14:34:38 -0500308#ifdef SK_DIRECT3D
Robert Phillipsf4f80112020-07-13 16:13:31 -0400309/*************************************************************************************************/
Robert Phillipsf4f80112020-07-13 16:13:31 -0400310sk_sp<GrDirectContext> GrDirectContext::MakeDirect3D(const GrD3DBackendContext& backendContext) {
311 GrContextOptions defaultOptions;
312 return MakeDirect3D(backendContext, defaultOptions);
313}
314
315sk_sp<GrDirectContext> GrDirectContext::MakeDirect3D(const GrD3DBackendContext& backendContext,
316 const GrContextOptions& options) {
317 sk_sp<GrDirectContext> direct(new GrDirectContext(GrBackendApi::kDirect3D, options));
318
319 direct->fGpu = GrD3DGpu::Make(backendContext, options, direct.get());
320 if (!direct->init()) {
Jim Van Verthd2d4c5e2020-02-19 14:57:58 -0500321 return nullptr;
322 }
Jim Van Verthb01e12b2020-02-18 14:34:38 -0500323
Robert Phillipsf4f80112020-07-13 16:13:31 -0400324 return direct;
Jim Van Verthb01e12b2020-02-18 14:34:38 -0500325}
326#endif
327
Stephen White985741a2019-07-18 11:43:45 -0400328#ifdef SK_DAWN
Robert Phillipsf4f80112020-07-13 16:13:31 -0400329/*************************************************************************************************/
Robert Phillipsf4f80112020-07-13 16:13:31 -0400330sk_sp<GrDirectContext> GrDirectContext::MakeDawn(const wgpu::Device& device) {
Stephen White985741a2019-07-18 11:43:45 -0400331 GrContextOptions defaultOptions;
332 return MakeDawn(device, defaultOptions);
333}
334
Robert Phillipsf4f80112020-07-13 16:13:31 -0400335sk_sp<GrDirectContext> GrDirectContext::MakeDawn(const wgpu::Device& device,
336 const GrContextOptions& options) {
337 sk_sp<GrDirectContext> direct(new GrDirectContext(GrBackendApi::kDawn, options));
Stephen White985741a2019-07-18 11:43:45 -0400338
Robert Phillipsf4f80112020-07-13 16:13:31 -0400339 direct->fGpu = GrDawnGpu::Make(device, options, direct.get());
340 if (!direct->init()) {
Stephen White985741a2019-07-18 11:43:45 -0400341 return nullptr;
342 }
343
Robert Phillipsf4f80112020-07-13 16:13:31 -0400344 return direct;
Stephen White985741a2019-07-18 11:43:45 -0400345}
Robert Phillipsf4f80112020-07-13 16:13:31 -0400346
Stephen White985741a2019-07-18 11:43:45 -0400347#endif