blob: 5f50b100baeca83467a0c45608bade9c5a9264a9 [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 Phillipse19babf2020-04-06 13:57:30 -040019#include "src/gpu/text/GrAtlasManager.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050020#include "src/gpu/text/GrStrikeCache.h"
Robert Phillipsa3457b82018-03-08 11:30:12 -050021#ifdef SK_METAL
Mike Kleinc0bd9f92019-04-23 12:05:21 -050022#include "src/gpu/mtl/GrMtlTrampoline.h"
Robert Phillipsa3457b82018-03-08 11:30:12 -050023#endif
24#ifdef SK_VULKAN
Mike Kleinc0bd9f92019-04-23 12:05:21 -050025#include "src/gpu/vk/GrVkGpu.h"
Robert Phillipsa3457b82018-03-08 11:30:12 -050026#endif
Jim Van Verthd2d4c5e2020-02-19 14:57:58 -050027#ifdef SK_DIRECT3D
28#include "src/gpu/d3d/GrD3DGpu.h"
29#endif
Stephen White985741a2019-07-18 11:43:45 -040030#ifdef SK_DAWN
Mike Klein52337de2019-07-25 09:00:52 -050031#include "src/gpu/dawn/GrDawnGpu.h"
Stephen White985741a2019-07-18 11:43:45 -040032#endif
Robert Phillipsa3457b82018-03-08 11:30:12 -050033
Brian Salomon24069eb2020-06-24 10:19:52 -040034#if GR_TEST_UTILS
35# include "include/utils/SkRandom.h"
36# if defined(SK_ENABLE_SCOPED_LSAN_SUPPRESSIONS)
37# include <sanitizer/lsan_interface.h>
38# endif
39#endif
40
Robert Phillips6db27c22019-05-01 10:43:56 -040041#ifdef SK_DISABLE_REDUCE_OPLIST_SPLITTING
Greg Danielf41b2bd2019-08-22 16:19:24 -040042static const bool kDefaultReduceOpsTaskSplitting = false;
Robert Phillips6db27c22019-05-01 10:43:56 -040043#else
Greg Danielf41b2bd2019-08-22 16:19:24 -040044static const bool kDefaultReduceOpsTaskSplitting = false;
Robert Phillips6db27c22019-05-01 10:43:56 -040045#endif
46
Robert Phillipsad248452020-06-30 09:27:52 -040047GrDirectContext::GrDirectContext(GrBackendApi backend, const GrContextOptions& options)
48 : INHERITED(GrContextThreadSafeProxyPriv::Make(backend, options))
49 , fAtlasManager(nullptr) {
50}
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
55 if (this->priv().getGpu()) {
Greg Daniel0a2464f2020-05-14 15:45:44 -040056 this->flushAndSubmit();
Robert Phillipsa3457b82018-03-08 11:30:12 -050057 }
58
Robert Phillipsad248452020-06-30 09:27:52 -040059 delete fAtlasManager;
60}
Robert Phillipsa3457b82018-03-08 11:30:12 -050061
Robert Phillipsad248452020-06-30 09:27:52 -040062void GrDirectContext::abandonContext() {
63 INHERITED::abandonContext();
64 fAtlasManager->freeAll();
65}
Robert Phillipsa3457b82018-03-08 11:30:12 -050066
Robert Phillipsad248452020-06-30 09:27:52 -040067void GrDirectContext::releaseResourcesAndAbandonContext() {
68 INHERITED::releaseResourcesAndAbandonContext();
69 fAtlasManager->freeAll();
70}
Robert Phillips6db27c22019-05-01 10:43:56 -040071
Robert Phillipsad248452020-06-30 09:27:52 -040072void GrDirectContext::freeGpuResources() {
73 this->flushAndSubmit();
74 fAtlasManager->freeAll();
Robert Phillips56181ba2019-03-08 12:00:45 -050075
Robert Phillipsad248452020-06-30 09:27:52 -040076 INHERITED::freeGpuResources();
77}
Robert Phillipsa3457b82018-03-08 11:30:12 -050078
Robert Phillipsad248452020-06-30 09:27:52 -040079bool GrDirectContext::init() {
80 const GrGpu* gpu = this->priv().getGpu();
81 if (!gpu) {
82 return false;
Robert Phillipsa3457b82018-03-08 11:30:12 -050083 }
84
Robert Phillipsad248452020-06-30 09:27:52 -040085 fThreadSafeProxy->priv().init(gpu->refCaps());
86 if (!INHERITED::init()) {
87 return false;
88 }
Robert Phillipsa3457b82018-03-08 11:30:12 -050089
Robert Phillipsad248452020-06-30 09:27:52 -040090 bool reduceOpsTaskSplitting = kDefaultReduceOpsTaskSplitting;
91 if (GrContextOptions::Enable::kNo == this->options().fReduceOpsTaskSplitting) {
92 reduceOpsTaskSplitting = false;
93 } else if (GrContextOptions::Enable::kYes == this->options().fReduceOpsTaskSplitting) {
94 reduceOpsTaskSplitting = true;
95 }
Robert Phillipsa3457b82018-03-08 11:30:12 -050096
Robert Phillipsad248452020-06-30 09:27:52 -040097 this->setupDrawingManager(true, reduceOpsTaskSplitting);
98
99 GrDrawOpAtlas::AllowMultitexturing allowMultitexturing;
100 if (GrContextOptions::Enable::kNo == this->options().fAllowMultipleGlyphCacheTextures ||
101 // multitexturing supported only if range can represent the index + texcoords fully
102 !(this->caps()->shaderCaps()->floatIs32Bits() ||
103 this->caps()->shaderCaps()->integerSupport())) {
104 allowMultitexturing = GrDrawOpAtlas::AllowMultitexturing::kNo;
105 } else {
106 allowMultitexturing = GrDrawOpAtlas::AllowMultitexturing::kYes;
107 }
108
109 GrProxyProvider* proxyProvider = this->priv().proxyProvider();
110
111 fAtlasManager = new GrAtlasManager(proxyProvider,
112 this->options().fGlyphCacheTextureMaximumBytes,
113 allowMultitexturing);
114 this->priv().addOnFlushCallbackObject(fAtlasManager);
115
116 return true;
117}
Robert Phillipsa3457b82018-03-08 11:30:12 -0500118
John Rosascoa9b348f2019-11-08 13:18:15 -0800119#ifdef SK_GL
Robert Phillipsf4f80112020-07-13 16:13:31 -0400120/*************************************************************************************************/
Jim Van Verth03b8ab22020-02-24 11:36:15 -0500121sk_sp<GrContext> GrContext::MakeGL(sk_sp<const GrGLInterface> glInterface) {
Robert Phillipsf4f80112020-07-13 16:13:31 -0400122 return GrDirectContext::MakeGL(std::move(glInterface));
123}
124
125sk_sp<GrContext> GrContext::MakeGL(const GrContextOptions& options) {
126 return GrDirectContext::MakeGL(options);
127}
128
129sk_sp<GrContext> GrContext::MakeGL() {
130 return GrDirectContext::MakeGL();
131}
132
133sk_sp<GrContext> GrContext::MakeGL(sk_sp<const GrGLInterface> glInterface,
134 const GrContextOptions& options) {
135 return GrDirectContext::MakeGL(std::move(glInterface), options);
136}
137
138/*************************************************************************************************/
139sk_sp<GrDirectContext> GrDirectContext::MakeGL(sk_sp<const GrGLInterface> glInterface) {
Robert Phillipsa3457b82018-03-08 11:30:12 -0500140 GrContextOptions defaultOptions;
Jim Van Verth03b8ab22020-02-24 11:36:15 -0500141 return MakeGL(std::move(glInterface), defaultOptions);
Robert Phillipsa3457b82018-03-08 11:30:12 -0500142}
143
Robert Phillipsf4f80112020-07-13 16:13:31 -0400144sk_sp<GrDirectContext> GrDirectContext::MakeGL(const GrContextOptions& options) {
Brian Salomonc1b9c102018-04-06 09:18:00 -0400145 return MakeGL(nullptr, options);
146}
147
Robert Phillipsf4f80112020-07-13 16:13:31 -0400148sk_sp<GrDirectContext> GrDirectContext::MakeGL() {
Brian Salomonc1b9c102018-04-06 09:18:00 -0400149 GrContextOptions defaultOptions;
150 return MakeGL(nullptr, defaultOptions);
151}
152
Brian Salomon24069eb2020-06-24 10:19:52 -0400153#if GR_TEST_UTILS
154GrGLFunction<GrGLGetErrorFn> make_get_error_with_random_oom(GrGLFunction<GrGLGetErrorFn> original) {
155 // A SkRandom and a GrGLFunction<GrGLGetErrorFn> are too big to be captured by a
156 // GrGLFunction<GrGLGetError> (surprise, surprise). So we make a context object and
157 // capture that by pointer. However, GrGLFunction doesn't support calling a destructor
158 // on the thing it captures. So we leak the context.
159 struct GetErrorContext {
160 SkRandom fRandom;
161 GrGLFunction<GrGLGetErrorFn> fGetError;
162 };
163
164 auto errorContext = new GetErrorContext;
165
166#if defined(SK_ENABLE_SCOPED_LSAN_SUPPRESSIONS)
167 __lsan_ignore_object(errorContext);
168#endif
169
170 errorContext->fGetError = original;
171
172 return GrGLFunction<GrGLGetErrorFn>([errorContext]() {
173 GrGLenum error = errorContext->fGetError();
174 if (error == GR_GL_NO_ERROR && (errorContext->fRandom.nextU() % 300) == 0) {
175 error = GR_GL_OUT_OF_MEMORY;
176 }
177 return error;
178 });
179}
180#endif
181
Robert Phillipsf4f80112020-07-13 16:13:31 -0400182sk_sp<GrDirectContext> GrDirectContext::MakeGL(sk_sp<const GrGLInterface> glInterface,
183 const GrContextOptions& options) {
184 sk_sp<GrDirectContext> direct(new GrDirectContext(GrBackendApi::kOpenGL, options));
Brian Salomon24069eb2020-06-24 10:19:52 -0400185#if GR_TEST_UTILS
186 if (options.fRandomGLOOM) {
187 auto copy = sk_make_sp<GrGLInterface>(*glInterface);
188 copy->fFunctions.fGetError =
189 make_get_error_with_random_oom(glInterface->fFunctions.fGetError);
190#if GR_GL_CHECK_ERROR
191 // Suppress logging GL errors since we'll be synthetically generating them.
192 copy->suppressErrorLogging();
193#endif
194 glInterface = std::move(copy);
195 }
196#endif
Robert Phillipsf4f80112020-07-13 16:13:31 -0400197 direct->fGpu = GrGLGpu::Make(std::move(glInterface), options, direct.get());
198 if (!direct->init()) {
Robert Phillipsa3457b82018-03-08 11:30:12 -0500199 return nullptr;
200 }
Robert Phillipsf4f80112020-07-13 16:13:31 -0400201 return direct;
Robert Phillipsa3457b82018-03-08 11:30:12 -0500202}
John Rosascoa9b348f2019-11-08 13:18:15 -0800203#endif
Robert Phillipsa3457b82018-03-08 11:30:12 -0500204
Robert Phillipsf4f80112020-07-13 16:13:31 -0400205/*************************************************************************************************/
Robert Phillipsa3457b82018-03-08 11:30:12 -0500206sk_sp<GrContext> GrContext::MakeMock(const GrMockOptions* mockOptions) {
Robert Phillipsf4f80112020-07-13 16:13:31 -0400207 return GrDirectContext::MakeMock(mockOptions);
Robert Phillipsa3457b82018-03-08 11:30:12 -0500208}
209
210sk_sp<GrContext> GrContext::MakeMock(const GrMockOptions* mockOptions,
211 const GrContextOptions& options) {
Robert Phillipsf4f80112020-07-13 16:13:31 -0400212 return GrDirectContext::MakeMock(mockOptions, options);
213}
Robert Phillipsa3457b82018-03-08 11:30:12 -0500214
Robert Phillipsf4f80112020-07-13 16:13:31 -0400215/*************************************************************************************************/
216sk_sp<GrDirectContext> GrDirectContext::MakeMock(const GrMockOptions* mockOptions) {
217 GrContextOptions defaultOptions;
218 return MakeMock(mockOptions, defaultOptions);
219}
220
221sk_sp<GrDirectContext> GrDirectContext::MakeMock(const GrMockOptions* mockOptions,
222 const GrContextOptions& options) {
223 sk_sp<GrDirectContext> direct(new GrDirectContext(GrBackendApi::kMock, options));
224
225 direct->fGpu = GrMockGpu::Make(mockOptions, options, direct.get());
226 if (!direct->init()) {
Robert Phillipsa3457b82018-03-08 11:30:12 -0500227 return nullptr;
228 }
Chris Daltona378b452019-12-11 13:24:11 -0500229
Robert Phillipsf4f80112020-07-13 16:13:31 -0400230 return direct;
Robert Phillipsa3457b82018-03-08 11:30:12 -0500231}
232
Greg Danielb4d89562018-10-03 18:44:49 +0000233#ifdef SK_VULKAN
Robert Phillipsf4f80112020-07-13 16:13:31 -0400234/*************************************************************************************************/
235sk_sp<GrContext> GrContext::MakeVulkan(const GrVkBackendContext& backendContext) {
236 return GrDirectContext::MakeVulkan(backendContext);
Greg Daniel10a83da2018-06-14 09:31:11 -0400237}
238
239sk_sp<GrContext> GrContext::MakeVulkan(const GrVkBackendContext& backendContext,
240 const GrContextOptions& options) {
Robert Phillipsf4f80112020-07-13 16:13:31 -0400241 return GrDirectContext::MakeVulkan(backendContext, options);
242}
Greg Daniel10a83da2018-06-14 09:31:11 -0400243
Robert Phillipsf4f80112020-07-13 16:13:31 -0400244/*************************************************************************************************/
245sk_sp<GrDirectContext> GrDirectContext::MakeVulkan(const GrVkBackendContext& backendContext) {
246 GrContextOptions defaultOptions;
247 return MakeVulkan(backendContext, defaultOptions);
248}
249
250sk_sp<GrDirectContext> GrDirectContext::MakeVulkan(const GrVkBackendContext& backendContext,
251 const GrContextOptions& options) {
252 sk_sp<GrDirectContext> direct(new GrDirectContext(GrBackendApi::kVulkan, options));
253
254 direct->fGpu = GrVkGpu::Make(backendContext, options, direct.get());
255 if (!direct->init()) {
Robert Phillipsa3457b82018-03-08 11:30:12 -0500256 return nullptr;
257 }
258
Robert Phillipsf4f80112020-07-13 16:13:31 -0400259 return direct;
Greg Danielb4d89562018-10-03 18:44:49 +0000260}
Robert Phillipsf4f80112020-07-13 16:13:31 -0400261#endif
Robert Phillipsa3457b82018-03-08 11:30:12 -0500262
263#ifdef SK_METAL
Robert Phillipsf4f80112020-07-13 16:13:31 -0400264/*************************************************************************************************/
Robert Phillipsa3457b82018-03-08 11:30:12 -0500265sk_sp<GrContext> GrContext::MakeMetal(void* device, void* queue) {
Robert Phillipsf4f80112020-07-13 16:13:31 -0400266 return GrDirectContext::MakeMetal(device, queue);
267}
268
269sk_sp<GrContext> GrContext::MakeMetal(void* device, void* queue, const GrContextOptions& options) {
270 return GrDirectContext::MakeMetal(device, queue, options);
271}
272
273/*************************************************************************************************/
274sk_sp<GrDirectContext> GrDirectContext::MakeMetal(void* device, void* queue) {
Robert Phillipsa3457b82018-03-08 11:30:12 -0500275 GrContextOptions defaultOptions;
276 return MakeMetal(device, queue, defaultOptions);
277}
278
Robert Phillipsf4f80112020-07-13 16:13:31 -0400279sk_sp<GrDirectContext> GrDirectContext::MakeMetal(void* device, void* queue,
280 const GrContextOptions& options) {
281 sk_sp<GrDirectContext> direct(new GrDirectContext(GrBackendApi::kMetal, options));
Robert Phillipsa3457b82018-03-08 11:30:12 -0500282
Robert Phillipsf4f80112020-07-13 16:13:31 -0400283 direct->fGpu = GrMtlTrampoline::MakeGpu(direct.get(), options, device, queue);
284 if (!direct->init()) {
Robert Phillipsa3457b82018-03-08 11:30:12 -0500285 return nullptr;
286 }
Timothy Liang4e85e802018-06-28 16:37:18 -0400287
Robert Phillipsf4f80112020-07-13 16:13:31 -0400288 return direct;
Robert Phillipsa3457b82018-03-08 11:30:12 -0500289}
290#endif
291
Jim Van Verthb01e12b2020-02-18 14:34:38 -0500292#ifdef SK_DIRECT3D
Robert Phillipsf4f80112020-07-13 16:13:31 -0400293/*************************************************************************************************/
Jim Van Verthb01e12b2020-02-18 14:34:38 -0500294sk_sp<GrContext> GrContext::MakeDirect3D(const GrD3DBackendContext& backendContext) {
Robert Phillipsf4f80112020-07-13 16:13:31 -0400295 return GrDirectContext::MakeDirect3D(backendContext);
Jim Van Verthb01e12b2020-02-18 14:34:38 -0500296}
297
298sk_sp<GrContext> GrContext::MakeDirect3D(const GrD3DBackendContext& backendContext,
299 const GrContextOptions& options) {
Robert Phillipsf4f80112020-07-13 16:13:31 -0400300 return GrDirectContext::MakeDirect3D(backendContext, options);
301}
Jim Van Verthb01e12b2020-02-18 14:34:38 -0500302
Robert Phillipsf4f80112020-07-13 16:13:31 -0400303/*************************************************************************************************/
304sk_sp<GrDirectContext> GrDirectContext::MakeDirect3D(const GrD3DBackendContext& backendContext) {
305 GrContextOptions defaultOptions;
306 return MakeDirect3D(backendContext, defaultOptions);
307}
308
309sk_sp<GrDirectContext> GrDirectContext::MakeDirect3D(const GrD3DBackendContext& backendContext,
310 const GrContextOptions& options) {
311 sk_sp<GrDirectContext> direct(new GrDirectContext(GrBackendApi::kDirect3D, options));
312
313 direct->fGpu = GrD3DGpu::Make(backendContext, options, direct.get());
314 if (!direct->init()) {
Jim Van Verthd2d4c5e2020-02-19 14:57:58 -0500315 return nullptr;
316 }
Jim Van Verthb01e12b2020-02-18 14:34:38 -0500317
Robert Phillipsf4f80112020-07-13 16:13:31 -0400318 return direct;
Jim Van Verthb01e12b2020-02-18 14:34:38 -0500319}
320#endif
321
Stephen White985741a2019-07-18 11:43:45 -0400322#ifdef SK_DAWN
Robert Phillipsf4f80112020-07-13 16:13:31 -0400323/*************************************************************************************************/
Stephen Whitea521c962019-12-04 09:57:48 -0500324sk_sp<GrContext> GrContext::MakeDawn(const wgpu::Device& device) {
Robert Phillipsf4f80112020-07-13 16:13:31 -0400325 return GrDirectContext::MakeDawn(device);
326}
327
328sk_sp<GrContext> GrContext::MakeDawn(const wgpu::Device& device, const GrContextOptions& options) {
329 return GrDirectContext::MakeDawn(device, options);
330}
331
332/*************************************************************************************************/
333sk_sp<GrDirectContext> GrDirectContext::MakeDawn(const wgpu::Device& device) {
Stephen White985741a2019-07-18 11:43:45 -0400334 GrContextOptions defaultOptions;
335 return MakeDawn(device, defaultOptions);
336}
337
Robert Phillipsf4f80112020-07-13 16:13:31 -0400338sk_sp<GrDirectContext> GrDirectContext::MakeDawn(const wgpu::Device& device,
339 const GrContextOptions& options) {
340 sk_sp<GrDirectContext> direct(new GrDirectContext(GrBackendApi::kDawn, options));
Stephen White985741a2019-07-18 11:43:45 -0400341
Robert Phillipsf4f80112020-07-13 16:13:31 -0400342 direct->fGpu = GrDawnGpu::Make(device, options, direct.get());
343 if (!direct->init()) {
Stephen White985741a2019-07-18 11:43:45 -0400344 return nullptr;
345 }
346
Robert Phillipsf4f80112020-07-13 16:13:31 -0400347 return direct;
Stephen White985741a2019-07-18 11:43:45 -0400348}
Robert Phillipsf4f80112020-07-13 16:13:31 -0400349
Stephen White985741a2019-07-18 11:43:45 -0400350#endif