blob: 84b6c597e6d57d8c7df108f5e236e88647cca849 [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"
12#include "src/gpu/GrContextPriv.h"
13#include "src/gpu/GrContextThreadSafeProxyPriv.h"
14#include "src/gpu/GrGpu.h"
Robert Phillipsa3457b82018-03-08 11:30:12 -050015
Mike Kleinc0bd9f92019-04-23 12:05:21 -050016#include "src/gpu/effects/GrSkSLFP.h"
17#include "src/gpu/gl/GrGLGpu.h"
18#include "src/gpu/mock/GrMockGpu.h"
Robert Phillips5edf5102020-08-10 16:30:36 -040019#include "src/gpu/ops/GrSmallPathAtlasMgr.h"
Robert Phillipse19babf2020-04-06 13:57:30 -040020#include "src/gpu/text/GrAtlasManager.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050021#include "src/gpu/text/GrStrikeCache.h"
Robert Phillipsa3457b82018-03-08 11:30:12 -050022#ifdef SK_METAL
Mike Kleinc0bd9f92019-04-23 12:05:21 -050023#include "src/gpu/mtl/GrMtlTrampoline.h"
Robert Phillipsa3457b82018-03-08 11:30:12 -050024#endif
25#ifdef SK_VULKAN
Mike Kleinc0bd9f92019-04-23 12:05:21 -050026#include "src/gpu/vk/GrVkGpu.h"
Robert Phillipsa3457b82018-03-08 11:30:12 -050027#endif
Jim Van Verthd2d4c5e2020-02-19 14:57:58 -050028#ifdef SK_DIRECT3D
29#include "src/gpu/d3d/GrD3DGpu.h"
30#endif
Stephen White985741a2019-07-18 11:43:45 -040031#ifdef SK_DAWN
Mike Klein52337de2019-07-25 09:00:52 -050032#include "src/gpu/dawn/GrDawnGpu.h"
Stephen White985741a2019-07-18 11:43:45 -040033#endif
Robert Phillipsa3457b82018-03-08 11:30:12 -050034
Brian Salomon24069eb2020-06-24 10:19:52 -040035#if GR_TEST_UTILS
36# include "include/utils/SkRandom.h"
37# if defined(SK_ENABLE_SCOPED_LSAN_SUPPRESSIONS)
38# include <sanitizer/lsan_interface.h>
39# endif
40#endif
41
Robert Phillips6db27c22019-05-01 10:43:56 -040042#ifdef SK_DISABLE_REDUCE_OPLIST_SPLITTING
Greg Danielf41b2bd2019-08-22 16:19:24 -040043static const bool kDefaultReduceOpsTaskSplitting = false;
Robert Phillips6db27c22019-05-01 10:43:56 -040044#else
Greg Danielf41b2bd2019-08-22 16:19:24 -040045static const bool kDefaultReduceOpsTaskSplitting = false;
Robert Phillips6db27c22019-05-01 10:43:56 -040046#endif
47
Robert Phillipsad248452020-06-30 09:27:52 -040048GrDirectContext::GrDirectContext(GrBackendApi backend, const GrContextOptions& options)
Robert Phillips3262bc82020-08-10 12:11:58 -040049 : INHERITED(GrContextThreadSafeProxyPriv::Make(backend, options)) {
Robert Phillipsad248452020-06-30 09:27:52 -040050}
Robert Phillipsa3457b82018-03-08 11:30:12 -050051
Robert Phillipsad248452020-06-30 09:27:52 -040052GrDirectContext::~GrDirectContext() {
53 // this if-test protects against the case where the context is being destroyed
54 // before having been fully created
Jim Van Verthe9b9c3b2020-10-08 21:00:25 +000055 if (this->priv().getGpu()) {
Greg Daniel0a2464f2020-05-14 15:45:44 -040056 this->flushAndSubmit();
Robert Phillipsa3457b82018-03-08 11:30:12 -050057 }
Robert Phillipsad248452020-06-30 09:27:52 -040058}
Robert Phillipsa3457b82018-03-08 11:30:12 -050059
Robert Phillipsad248452020-06-30 09:27:52 -040060void GrDirectContext::abandonContext() {
61 INHERITED::abandonContext();
Robert Phillips079455c2020-08-11 15:18:46 -040062 if (fSmallPathAtlasMgr) {
63 fSmallPathAtlasMgr->reset();
64 }
Robert Phillipsad248452020-06-30 09:27:52 -040065 fAtlasManager->freeAll();
66}
Robert Phillipsa3457b82018-03-08 11:30:12 -050067
Robert Phillipsad248452020-06-30 09:27:52 -040068void GrDirectContext::releaseResourcesAndAbandonContext() {
69 INHERITED::releaseResourcesAndAbandonContext();
Robert Phillips079455c2020-08-11 15:18:46 -040070 if (fSmallPathAtlasMgr) {
71 fSmallPathAtlasMgr->reset();
72 }
Robert Phillipsad248452020-06-30 09:27:52 -040073 fAtlasManager->freeAll();
74}
Robert Phillips6db27c22019-05-01 10:43:56 -040075
Robert Phillipsad248452020-06-30 09:27:52 -040076void GrDirectContext::freeGpuResources() {
77 this->flushAndSubmit();
Robert Phillips079455c2020-08-11 15:18:46 -040078 if (fSmallPathAtlasMgr) {
79 fSmallPathAtlasMgr->reset();
80 }
Robert Phillipsad248452020-06-30 09:27:52 -040081 fAtlasManager->freeAll();
Robert Phillips56181ba2019-03-08 12:00:45 -050082
Robert Phillipsad248452020-06-30 09:27:52 -040083 INHERITED::freeGpuResources();
84}
Robert Phillipsa3457b82018-03-08 11:30:12 -050085
Robert Phillipsad248452020-06-30 09:27:52 -040086bool GrDirectContext::init() {
Jim Van Verthe9b9c3b2020-10-08 21:00:25 +000087 const GrGpu* gpu = this->priv().getGpu();
88 if (!gpu) {
Robert Phillipsad248452020-06-30 09:27:52 -040089 return false;
Robert Phillipsa3457b82018-03-08 11:30:12 -050090 }
91
Jim Van Verthe9b9c3b2020-10-08 21:00:25 +000092 fThreadSafeProxy->priv().init(gpu->refCaps());
Robert Phillipsad248452020-06-30 09:27:52 -040093 if (!INHERITED::init()) {
94 return false;
95 }
Robert Phillipsa3457b82018-03-08 11:30:12 -050096
Robert Phillipsad248452020-06-30 09:27:52 -040097 bool reduceOpsTaskSplitting = kDefaultReduceOpsTaskSplitting;
98 if (GrContextOptions::Enable::kNo == this->options().fReduceOpsTaskSplitting) {
99 reduceOpsTaskSplitting = false;
100 } else if (GrContextOptions::Enable::kYes == this->options().fReduceOpsTaskSplitting) {
101 reduceOpsTaskSplitting = true;
102 }
Robert Phillipsa3457b82018-03-08 11:30:12 -0500103
Robert Phillipsad248452020-06-30 09:27:52 -0400104 this->setupDrawingManager(true, reduceOpsTaskSplitting);
105
106 GrDrawOpAtlas::AllowMultitexturing allowMultitexturing;
107 if (GrContextOptions::Enable::kNo == this->options().fAllowMultipleGlyphCacheTextures ||
108 // multitexturing supported only if range can represent the index + texcoords fully
109 !(this->caps()->shaderCaps()->floatIs32Bits() ||
110 this->caps()->shaderCaps()->integerSupport())) {
111 allowMultitexturing = GrDrawOpAtlas::AllowMultitexturing::kNo;
112 } else {
113 allowMultitexturing = GrDrawOpAtlas::AllowMultitexturing::kYes;
114 }
115
116 GrProxyProvider* proxyProvider = this->priv().proxyProvider();
117
Robert Phillips3262bc82020-08-10 12:11:58 -0400118 fAtlasManager = std::make_unique<GrAtlasManager>(proxyProvider,
119 this->options().fGlyphCacheTextureMaximumBytes,
120 allowMultitexturing);
121 this->priv().addOnFlushCallbackObject(fAtlasManager.get());
Robert Phillipsad248452020-06-30 09:27:52 -0400122
123 return true;
124}
Robert Phillipsa3457b82018-03-08 11:30:12 -0500125
Robert Phillips5edf5102020-08-10 16:30:36 -0400126GrSmallPathAtlasMgr* GrDirectContext::onGetSmallPathAtlasMgr() {
Robert Phillips079455c2020-08-11 15:18:46 -0400127 if (!fSmallPathAtlasMgr) {
128 fSmallPathAtlasMgr = std::make_unique<GrSmallPathAtlasMgr>();
129
130 this->priv().addOnFlushCallbackObject(fSmallPathAtlasMgr.get());
131 }
132
133 if (!fSmallPathAtlasMgr->initAtlas(this->proxyProvider(), this->caps())) {
134 return nullptr;
135 }
136
137 return fSmallPathAtlasMgr.get();
Robert Phillips5edf5102020-08-10 16:30:36 -0400138}
139
John Rosascoa9b348f2019-11-08 13:18:15 -0800140#ifdef SK_GL
Robert Phillipsc7228c62020-07-14 12:57:39 -0400141
Robert Phillipsf4f80112020-07-13 16:13:31 -0400142/*************************************************************************************************/
143sk_sp<GrDirectContext> GrDirectContext::MakeGL(sk_sp<const GrGLInterface> glInterface) {
Robert Phillipsa3457b82018-03-08 11:30:12 -0500144 GrContextOptions defaultOptions;
Jim Van Verth03b8ab22020-02-24 11:36:15 -0500145 return MakeGL(std::move(glInterface), defaultOptions);
Robert Phillipsa3457b82018-03-08 11:30:12 -0500146}
147
Robert Phillipsf4f80112020-07-13 16:13:31 -0400148sk_sp<GrDirectContext> GrDirectContext::MakeGL(const GrContextOptions& options) {
Brian Salomonc1b9c102018-04-06 09:18:00 -0400149 return MakeGL(nullptr, options);
150}
151
Robert Phillipsf4f80112020-07-13 16:13:31 -0400152sk_sp<GrDirectContext> GrDirectContext::MakeGL() {
Brian Salomonc1b9c102018-04-06 09:18:00 -0400153 GrContextOptions defaultOptions;
154 return MakeGL(nullptr, defaultOptions);
155}
156
Brian Salomon24069eb2020-06-24 10:19:52 -0400157#if GR_TEST_UTILS
158GrGLFunction<GrGLGetErrorFn> make_get_error_with_random_oom(GrGLFunction<GrGLGetErrorFn> original) {
159 // A SkRandom and a GrGLFunction<GrGLGetErrorFn> are too big to be captured by a
160 // GrGLFunction<GrGLGetError> (surprise, surprise). So we make a context object and
161 // capture that by pointer. However, GrGLFunction doesn't support calling a destructor
162 // on the thing it captures. So we leak the context.
163 struct GetErrorContext {
164 SkRandom fRandom;
165 GrGLFunction<GrGLGetErrorFn> fGetError;
166 };
167
168 auto errorContext = new GetErrorContext;
169
170#if defined(SK_ENABLE_SCOPED_LSAN_SUPPRESSIONS)
171 __lsan_ignore_object(errorContext);
172#endif
173
174 errorContext->fGetError = original;
175
176 return GrGLFunction<GrGLGetErrorFn>([errorContext]() {
177 GrGLenum error = errorContext->fGetError();
178 if (error == GR_GL_NO_ERROR && (errorContext->fRandom.nextU() % 300) == 0) {
179 error = GR_GL_OUT_OF_MEMORY;
180 }
181 return error;
182 });
183}
184#endif
185
Robert Phillipsf4f80112020-07-13 16:13:31 -0400186sk_sp<GrDirectContext> GrDirectContext::MakeGL(sk_sp<const GrGLInterface> glInterface,
187 const GrContextOptions& options) {
188 sk_sp<GrDirectContext> direct(new GrDirectContext(GrBackendApi::kOpenGL, options));
Brian Salomon24069eb2020-06-24 10:19:52 -0400189#if GR_TEST_UTILS
190 if (options.fRandomGLOOM) {
191 auto copy = sk_make_sp<GrGLInterface>(*glInterface);
192 copy->fFunctions.fGetError =
193 make_get_error_with_random_oom(glInterface->fFunctions.fGetError);
194#if GR_GL_CHECK_ERROR
195 // Suppress logging GL errors since we'll be synthetically generating them.
196 copy->suppressErrorLogging();
197#endif
198 glInterface = std::move(copy);
199 }
200#endif
Robert Phillipsf4f80112020-07-13 16:13:31 -0400201 direct->fGpu = GrGLGpu::Make(std::move(glInterface), options, direct.get());
202 if (!direct->init()) {
Robert Phillipsa3457b82018-03-08 11:30:12 -0500203 return nullptr;
204 }
Robert Phillipsf4f80112020-07-13 16:13:31 -0400205 return direct;
Robert Phillipsa3457b82018-03-08 11:30:12 -0500206}
John Rosascoa9b348f2019-11-08 13:18:15 -0800207#endif
Robert Phillipsa3457b82018-03-08 11:30:12 -0500208
Robert Phillipsf4f80112020-07-13 16:13:31 -0400209/*************************************************************************************************/
Robert Phillipsf4f80112020-07-13 16:13:31 -0400210sk_sp<GrDirectContext> GrDirectContext::MakeMock(const GrMockOptions* mockOptions) {
211 GrContextOptions defaultOptions;
212 return MakeMock(mockOptions, defaultOptions);
213}
214
215sk_sp<GrDirectContext> GrDirectContext::MakeMock(const GrMockOptions* mockOptions,
216 const GrContextOptions& options) {
217 sk_sp<GrDirectContext> direct(new GrDirectContext(GrBackendApi::kMock, options));
218
219 direct->fGpu = GrMockGpu::Make(mockOptions, options, direct.get());
220 if (!direct->init()) {
Robert Phillipsa3457b82018-03-08 11:30:12 -0500221 return nullptr;
222 }
Chris Daltona378b452019-12-11 13:24:11 -0500223
Robert Phillipsf4f80112020-07-13 16:13:31 -0400224 return direct;
Robert Phillipsa3457b82018-03-08 11:30:12 -0500225}
226
Greg Danielb4d89562018-10-03 18:44:49 +0000227#ifdef SK_VULKAN
Robert Phillipsf4f80112020-07-13 16:13:31 -0400228/*************************************************************************************************/
Robert Phillipsf4f80112020-07-13 16:13:31 -0400229sk_sp<GrDirectContext> GrDirectContext::MakeVulkan(const GrVkBackendContext& backendContext) {
230 GrContextOptions defaultOptions;
231 return MakeVulkan(backendContext, defaultOptions);
232}
233
234sk_sp<GrDirectContext> GrDirectContext::MakeVulkan(const GrVkBackendContext& backendContext,
235 const GrContextOptions& options) {
236 sk_sp<GrDirectContext> direct(new GrDirectContext(GrBackendApi::kVulkan, options));
237
238 direct->fGpu = GrVkGpu::Make(backendContext, options, direct.get());
239 if (!direct->init()) {
Robert Phillipsa3457b82018-03-08 11:30:12 -0500240 return nullptr;
241 }
242
Robert Phillipsf4f80112020-07-13 16:13:31 -0400243 return direct;
Greg Danielb4d89562018-10-03 18:44:49 +0000244}
Robert Phillipsf4f80112020-07-13 16:13:31 -0400245#endif
Robert Phillipsa3457b82018-03-08 11:30:12 -0500246
247#ifdef SK_METAL
Robert Phillipsf4f80112020-07-13 16:13:31 -0400248/*************************************************************************************************/
Robert Phillipsf4f80112020-07-13 16:13:31 -0400249sk_sp<GrDirectContext> GrDirectContext::MakeMetal(void* device, void* queue) {
Robert Phillipsa3457b82018-03-08 11:30:12 -0500250 GrContextOptions defaultOptions;
251 return MakeMetal(device, queue, defaultOptions);
252}
253
Robert Phillipsf4f80112020-07-13 16:13:31 -0400254sk_sp<GrDirectContext> GrDirectContext::MakeMetal(void* device, void* queue,
255 const GrContextOptions& options) {
256 sk_sp<GrDirectContext> direct(new GrDirectContext(GrBackendApi::kMetal, options));
Robert Phillipsa3457b82018-03-08 11:30:12 -0500257
Robert Phillipsf4f80112020-07-13 16:13:31 -0400258 direct->fGpu = GrMtlTrampoline::MakeGpu(direct.get(), options, device, queue);
259 if (!direct->init()) {
Robert Phillipsa3457b82018-03-08 11:30:12 -0500260 return nullptr;
261 }
Timothy Liang4e85e802018-06-28 16:37:18 -0400262
Robert Phillipsf4f80112020-07-13 16:13:31 -0400263 return direct;
Robert Phillipsa3457b82018-03-08 11:30:12 -0500264}
265#endif
266
Jim Van Verthb01e12b2020-02-18 14:34:38 -0500267#ifdef SK_DIRECT3D
Robert Phillipsf4f80112020-07-13 16:13:31 -0400268/*************************************************************************************************/
Robert Phillipsf4f80112020-07-13 16:13:31 -0400269sk_sp<GrDirectContext> GrDirectContext::MakeDirect3D(const GrD3DBackendContext& backendContext) {
270 GrContextOptions defaultOptions;
271 return MakeDirect3D(backendContext, defaultOptions);
272}
273
274sk_sp<GrDirectContext> GrDirectContext::MakeDirect3D(const GrD3DBackendContext& backendContext,
275 const GrContextOptions& options) {
276 sk_sp<GrDirectContext> direct(new GrDirectContext(GrBackendApi::kDirect3D, options));
277
278 direct->fGpu = GrD3DGpu::Make(backendContext, options, direct.get());
279 if (!direct->init()) {
Jim Van Verthd2d4c5e2020-02-19 14:57:58 -0500280 return nullptr;
281 }
Jim Van Verthb01e12b2020-02-18 14:34:38 -0500282
Robert Phillipsf4f80112020-07-13 16:13:31 -0400283 return direct;
Jim Van Verthb01e12b2020-02-18 14:34:38 -0500284}
285#endif
286
Stephen White985741a2019-07-18 11:43:45 -0400287#ifdef SK_DAWN
Robert Phillipsf4f80112020-07-13 16:13:31 -0400288/*************************************************************************************************/
Robert Phillipsf4f80112020-07-13 16:13:31 -0400289sk_sp<GrDirectContext> GrDirectContext::MakeDawn(const wgpu::Device& device) {
Stephen White985741a2019-07-18 11:43:45 -0400290 GrContextOptions defaultOptions;
291 return MakeDawn(device, defaultOptions);
292}
293
Robert Phillipsf4f80112020-07-13 16:13:31 -0400294sk_sp<GrDirectContext> GrDirectContext::MakeDawn(const wgpu::Device& device,
295 const GrContextOptions& options) {
296 sk_sp<GrDirectContext> direct(new GrDirectContext(GrBackendApi::kDawn, options));
Stephen White985741a2019-07-18 11:43:45 -0400297
Robert Phillipsf4f80112020-07-13 16:13:31 -0400298 direct->fGpu = GrDawnGpu::Make(device, options, direct.get());
299 if (!direct->init()) {
Stephen White985741a2019-07-18 11:43:45 -0400300 return nullptr;
301 }
302
Robert Phillipsf4f80112020-07-13 16:13:31 -0400303 return direct;
Stephen White985741a2019-07-18 11:43:45 -0400304}
Robert Phillipsf4f80112020-07-13 16:13:31 -0400305
Stephen White985741a2019-07-18 11:43:45 -0400306#endif