blob: 4b027eaf3fe9ab71b25fee7acd05cc08f55c8b1d [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
Mike Kleinc0bd9f92019-04-23 12:05:21 -05009#include "include/gpu/GrContext.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
Brian Salomon57f211b2019-08-21 15:21:09 -040047class GrLegacyDirectContext : public GrContext {
Robert Phillipsa3457b82018-03-08 11:30:12 -050048public:
Robert Phillipse8345792019-02-07 10:48:24 -050049 GrLegacyDirectContext(GrBackendApi backend, const GrContextOptions& options)
Adlai Hollere219d1c2020-06-02 11:23:16 -040050 : INHERITED(GrContextThreadSafeProxyPriv::Make(backend, options))
Robert Phillipsa3457b82018-03-08 11:30:12 -050051 , fAtlasManager(nullptr) {
52 }
53
Robert Phillipse8345792019-02-07 10:48:24 -050054 ~GrLegacyDirectContext() override {
Robert Phillipsa3457b82018-03-08 11:30:12 -050055 // this if-test protects against the case where the context is being destroyed
56 // before having been fully created
Robert Phillips9da87e02019-02-04 13:26:26 -050057 if (this->priv().getGpu()) {
Greg Daniel0a2464f2020-05-14 15:45:44 -040058 this->flushAndSubmit();
Robert Phillipsa3457b82018-03-08 11:30:12 -050059 }
60
61 delete fAtlasManager;
62 }
63
64 void abandonContext() override {
65 INHERITED::abandonContext();
66 fAtlasManager->freeAll();
67 }
68
69 void releaseResourcesAndAbandonContext() override {
70 INHERITED::releaseResourcesAndAbandonContext();
71 fAtlasManager->freeAll();
72 }
73
74 void freeGpuResources() override {
Greg Daniel0a2464f2020-05-14 15:45:44 -040075 this->flushAndSubmit();
Robert Phillipsa3457b82018-03-08 11:30:12 -050076 fAtlasManager->freeAll();
77
78 INHERITED::freeGpuResources();
79 }
80
81protected:
Adlai Hollere219d1c2020-06-02 11:23:16 -040082 bool init() override {
83 const GrGpu* gpu = this->priv().getGpu();
84 if (!gpu) {
85 return false;
86 }
Robert Phillipsa3457b82018-03-08 11:30:12 -050087
Adlai Hollere219d1c2020-06-02 11:23:16 -040088 fThreadSafeProxy->priv().init(gpu->refCaps());
89 if (!INHERITED::init()) {
Robert Phillipsa3457b82018-03-08 11:30:12 -050090 return false;
91 }
92
Greg Danielf41b2bd2019-08-22 16:19:24 -040093 bool reduceOpsTaskSplitting = kDefaultReduceOpsTaskSplitting;
Greg Daniel93138742019-08-22 17:15:39 -040094 if (GrContextOptions::Enable::kNo == this->options().fReduceOpsTaskSplitting) {
Greg Danielf41b2bd2019-08-22 16:19:24 -040095 reduceOpsTaskSplitting = false;
Greg Daniel93138742019-08-22 17:15:39 -040096 } else if (GrContextOptions::Enable::kYes == this->options().fReduceOpsTaskSplitting) {
Greg Danielf41b2bd2019-08-22 16:19:24 -040097 reduceOpsTaskSplitting = true;
Robert Phillips6db27c22019-05-01 10:43:56 -040098 }
99
Greg Danielf41b2bd2019-08-22 16:19:24 -0400100 this->setupDrawingManager(true, reduceOpsTaskSplitting);
Robert Phillips56181ba2019-03-08 12:00:45 -0500101
Robert Phillipsa3457b82018-03-08 11:30:12 -0500102 GrDrawOpAtlas::AllowMultitexturing allowMultitexturing;
Robert Phillipsc1541ae2019-02-04 12:05:37 -0500103 if (GrContextOptions::Enable::kNo == this->options().fAllowMultipleGlyphCacheTextures ||
Robert Phillipsa3457b82018-03-08 11:30:12 -0500104 // multitexturing supported only if range can represent the index + texcoords fully
Robert Phillipsbb606772019-02-04 17:50:57 -0500105 !(this->caps()->shaderCaps()->floatIs32Bits() ||
106 this->caps()->shaderCaps()->integerSupport())) {
Robert Phillipsa3457b82018-03-08 11:30:12 -0500107 allowMultitexturing = GrDrawOpAtlas::AllowMultitexturing::kNo;
108 } else {
109 allowMultitexturing = GrDrawOpAtlas::AllowMultitexturing::kYes;
110 }
111
Robert Phillips9da87e02019-02-04 13:26:26 -0500112 GrProxyProvider* proxyProvider = this->priv().proxyProvider();
Robert Phillipsa3457b82018-03-08 11:30:12 -0500113
Robert Phillips207d24b2020-04-09 10:23:42 -0400114 fAtlasManager = new GrAtlasManager(proxyProvider,
Robert Phillipsc1541ae2019-02-04 12:05:37 -0500115 this->options().fGlyphCacheTextureMaximumBytes,
Robert Phillipsa3457b82018-03-08 11:30:12 -0500116 allowMultitexturing);
Robert Phillips9da87e02019-02-04 13:26:26 -0500117 this->priv().addOnFlushCallbackObject(fAtlasManager);
Robert Phillipsa3457b82018-03-08 11:30:12 -0500118
Robert Phillipsa3457b82018-03-08 11:30:12 -0500119 return true;
120 }
121
122 GrAtlasManager* onGetAtlasManager() override { return fAtlasManager; }
123
124private:
125 GrAtlasManager* fAtlasManager;
126
127 typedef GrContext INHERITED;
128};
129
John Rosascoa9b348f2019-11-08 13:18:15 -0800130#ifdef SK_GL
Jim Van Verth03b8ab22020-02-24 11:36:15 -0500131sk_sp<GrContext> GrContext::MakeGL(sk_sp<const GrGLInterface> glInterface) {
Robert Phillipsa3457b82018-03-08 11:30:12 -0500132 GrContextOptions defaultOptions;
Jim Van Verth03b8ab22020-02-24 11:36:15 -0500133 return MakeGL(std::move(glInterface), defaultOptions);
Robert Phillipsa3457b82018-03-08 11:30:12 -0500134}
135
Brian Salomonc1b9c102018-04-06 09:18:00 -0400136sk_sp<GrContext> GrContext::MakeGL(const GrContextOptions& options) {
137 return MakeGL(nullptr, options);
138}
139
140sk_sp<GrContext> GrContext::MakeGL() {
141 GrContextOptions defaultOptions;
142 return MakeGL(nullptr, defaultOptions);
143}
144
Brian Salomon24069eb2020-06-24 10:19:52 -0400145#if GR_TEST_UTILS
146GrGLFunction<GrGLGetErrorFn> make_get_error_with_random_oom(GrGLFunction<GrGLGetErrorFn> original) {
147 // A SkRandom and a GrGLFunction<GrGLGetErrorFn> are too big to be captured by a
148 // GrGLFunction<GrGLGetError> (surprise, surprise). So we make a context object and
149 // capture that by pointer. However, GrGLFunction doesn't support calling a destructor
150 // on the thing it captures. So we leak the context.
151 struct GetErrorContext {
152 SkRandom fRandom;
153 GrGLFunction<GrGLGetErrorFn> fGetError;
154 };
155
156 auto errorContext = new GetErrorContext;
157
158#if defined(SK_ENABLE_SCOPED_LSAN_SUPPRESSIONS)
159 __lsan_ignore_object(errorContext);
160#endif
161
162 errorContext->fGetError = original;
163
164 return GrGLFunction<GrGLGetErrorFn>([errorContext]() {
165 GrGLenum error = errorContext->fGetError();
166 if (error == GR_GL_NO_ERROR && (errorContext->fRandom.nextU() % 300) == 0) {
167 error = GR_GL_OUT_OF_MEMORY;
168 }
169 return error;
170 });
171}
172#endif
173
Jim Van Verth03b8ab22020-02-24 11:36:15 -0500174sk_sp<GrContext> GrContext::MakeGL(sk_sp<const GrGLInterface> glInterface,
Robert Phillipsa3457b82018-03-08 11:30:12 -0500175 const GrContextOptions& options) {
Robert Phillipse8345792019-02-07 10:48:24 -0500176 sk_sp<GrContext> context(new GrLegacyDirectContext(GrBackendApi::kOpenGL, options));
Brian Salomon24069eb2020-06-24 10:19:52 -0400177#if GR_TEST_UTILS
178 if (options.fRandomGLOOM) {
179 auto copy = sk_make_sp<GrGLInterface>(*glInterface);
180 copy->fFunctions.fGetError =
181 make_get_error_with_random_oom(glInterface->fFunctions.fGetError);
182#if GR_GL_CHECK_ERROR
183 // Suppress logging GL errors since we'll be synthetically generating them.
184 copy->suppressErrorLogging();
185#endif
186 glInterface = std::move(copy);
187 }
188#endif
Jim Van Verth03b8ab22020-02-24 11:36:15 -0500189 context->fGpu = GrGLGpu::Make(std::move(glInterface), options, context.get());
Adlai Hollere219d1c2020-06-02 11:23:16 -0400190 if (!context->init()) {
Robert Phillipsa3457b82018-03-08 11:30:12 -0500191 return nullptr;
192 }
193 return context;
194}
John Rosascoa9b348f2019-11-08 13:18:15 -0800195#endif
Robert Phillipsa3457b82018-03-08 11:30:12 -0500196
197sk_sp<GrContext> GrContext::MakeMock(const GrMockOptions* mockOptions) {
198 GrContextOptions defaultOptions;
199 return MakeMock(mockOptions, defaultOptions);
200}
201
202sk_sp<GrContext> GrContext::MakeMock(const GrMockOptions* mockOptions,
203 const GrContextOptions& options) {
Robert Phillipse8345792019-02-07 10:48:24 -0500204 sk_sp<GrContext> context(new GrLegacyDirectContext(GrBackendApi::kMock, options));
Robert Phillipsa3457b82018-03-08 11:30:12 -0500205
206 context->fGpu = GrMockGpu::Make(mockOptions, options, context.get());
Adlai Hollere219d1c2020-06-02 11:23:16 -0400207 if (!context->init()) {
Robert Phillipsa3457b82018-03-08 11:30:12 -0500208 return nullptr;
209 }
Chris Daltona378b452019-12-11 13:24:11 -0500210
Robert Phillipsa3457b82018-03-08 11:30:12 -0500211 return context;
212}
213
Mike Kleina55e2142018-10-03 16:34:11 +0000214sk_sp<GrContext> GrContext::MakeVulkan(const GrVkBackendContext& backendContext) {
Greg Danielb4d89562018-10-03 18:44:49 +0000215#ifdef SK_VULKAN
Greg Daniel10a83da2018-06-14 09:31:11 -0400216 GrContextOptions defaultOptions;
217 return MakeVulkan(backendContext, defaultOptions);
Greg Danielb4d89562018-10-03 18:44:49 +0000218#else
219 return nullptr;
220#endif
Greg Daniel10a83da2018-06-14 09:31:11 -0400221}
222
223sk_sp<GrContext> GrContext::MakeVulkan(const GrVkBackendContext& backendContext,
224 const GrContextOptions& options) {
Greg Danielb4d89562018-10-03 18:44:49 +0000225#ifdef SK_VULKAN
Robert Phillipse8345792019-02-07 10:48:24 -0500226 sk_sp<GrContext> context(new GrLegacyDirectContext(GrBackendApi::kVulkan, options));
Greg Daniel10a83da2018-06-14 09:31:11 -0400227
Greg Danielf730c182018-07-02 20:15:37 +0000228 context->fGpu = GrVkGpu::Make(backendContext, options, context.get());
Adlai Hollere219d1c2020-06-02 11:23:16 -0400229 if (!context->init()) {
Robert Phillipsa3457b82018-03-08 11:30:12 -0500230 return nullptr;
231 }
232
Robert Phillipsa3457b82018-03-08 11:30:12 -0500233 return context;
Greg Danielb4d89562018-10-03 18:44:49 +0000234#else
235 return nullptr;
Mike Kleina55e2142018-10-03 16:34:11 +0000236#endif
Greg Danielb4d89562018-10-03 18:44:49 +0000237}
Robert Phillipsa3457b82018-03-08 11:30:12 -0500238
239#ifdef SK_METAL
240sk_sp<GrContext> GrContext::MakeMetal(void* device, void* queue) {
241 GrContextOptions defaultOptions;
242 return MakeMetal(device, queue, defaultOptions);
243}
244
245sk_sp<GrContext> GrContext::MakeMetal(void* device, void* queue, const GrContextOptions& options) {
Robert Phillipse8345792019-02-07 10:48:24 -0500246 sk_sp<GrContext> context(new GrLegacyDirectContext(GrBackendApi::kMetal, options));
Robert Phillipsa3457b82018-03-08 11:30:12 -0500247
248 context->fGpu = GrMtlTrampoline::MakeGpu(context.get(), options, device, queue);
Adlai Hollere219d1c2020-06-02 11:23:16 -0400249 if (!context->init()) {
Robert Phillipsa3457b82018-03-08 11:30:12 -0500250 return nullptr;
251 }
Timothy Liang4e85e802018-06-28 16:37:18 -0400252
Robert Phillipsa3457b82018-03-08 11:30:12 -0500253 return context;
254}
255#endif
256
Jim Van Verthb01e12b2020-02-18 14:34:38 -0500257#ifdef SK_DIRECT3D
258sk_sp<GrContext> GrContext::MakeDirect3D(const GrD3DBackendContext& backendContext) {
259 GrContextOptions defaultOptions;
260 return MakeDirect3D(backendContext, defaultOptions);
261}
262
263sk_sp<GrContext> GrContext::MakeDirect3D(const GrD3DBackendContext& backendContext,
264 const GrContextOptions& options) {
Jim Van Verthd2d4c5e2020-02-19 14:57:58 -0500265 sk_sp<GrContext> context(new GrLegacyDirectContext(GrBackendApi::kDirect3D, options));
Jim Van Verthb01e12b2020-02-18 14:34:38 -0500266
Jim Van Verthd2d4c5e2020-02-19 14:57:58 -0500267 context->fGpu = GrD3DGpu::Make(backendContext, options, context.get());
Adlai Hollere219d1c2020-06-02 11:23:16 -0400268 if (!context->init()) {
Jim Van Verthd2d4c5e2020-02-19 14:57:58 -0500269 return nullptr;
270 }
Jim Van Verthb01e12b2020-02-18 14:34:38 -0500271
Jim Van Verthd2d4c5e2020-02-19 14:57:58 -0500272 return context;
Jim Van Verthb01e12b2020-02-18 14:34:38 -0500273}
274#endif
275
Stephen White985741a2019-07-18 11:43:45 -0400276#ifdef SK_DAWN
Stephen Whitea521c962019-12-04 09:57:48 -0500277sk_sp<GrContext> GrContext::MakeDawn(const wgpu::Device& device) {
Stephen White985741a2019-07-18 11:43:45 -0400278 GrContextOptions defaultOptions;
279 return MakeDawn(device, defaultOptions);
280}
281
Stephen Whitea521c962019-12-04 09:57:48 -0500282sk_sp<GrContext> GrContext::MakeDawn(const wgpu::Device& device, const GrContextOptions& options) {
Stephen White985741a2019-07-18 11:43:45 -0400283 sk_sp<GrContext> context(new GrLegacyDirectContext(GrBackendApi::kDawn, options));
284
285 context->fGpu = GrDawnGpu::Make(device, options, context.get());
Adlai Hollere219d1c2020-06-02 11:23:16 -0400286 if (!context->init()) {
Stephen White985741a2019-07-18 11:43:45 -0400287 return nullptr;
288 }
289
Stephen White985741a2019-07-18 11:43:45 -0400290 return context;
291}
292#endif