blob: 8bfb239f590b61b7023769945dcb6f33af03ec06 [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
Jim Van Verth03b8ab22020-02-24 11:36:15 -0500120sk_sp<GrContext> GrContext::MakeGL(sk_sp<const GrGLInterface> glInterface) {
Robert Phillipsa3457b82018-03-08 11:30:12 -0500121 GrContextOptions defaultOptions;
Jim Van Verth03b8ab22020-02-24 11:36:15 -0500122 return MakeGL(std::move(glInterface), defaultOptions);
Robert Phillipsa3457b82018-03-08 11:30:12 -0500123}
124
Brian Salomonc1b9c102018-04-06 09:18:00 -0400125sk_sp<GrContext> GrContext::MakeGL(const GrContextOptions& options) {
126 return MakeGL(nullptr, options);
127}
128
129sk_sp<GrContext> GrContext::MakeGL() {
130 GrContextOptions defaultOptions;
131 return MakeGL(nullptr, defaultOptions);
132}
133
Brian Salomon24069eb2020-06-24 10:19:52 -0400134#if GR_TEST_UTILS
135GrGLFunction<GrGLGetErrorFn> make_get_error_with_random_oom(GrGLFunction<GrGLGetErrorFn> original) {
136 // A SkRandom and a GrGLFunction<GrGLGetErrorFn> are too big to be captured by a
137 // GrGLFunction<GrGLGetError> (surprise, surprise). So we make a context object and
138 // capture that by pointer. However, GrGLFunction doesn't support calling a destructor
139 // on the thing it captures. So we leak the context.
140 struct GetErrorContext {
141 SkRandom fRandom;
142 GrGLFunction<GrGLGetErrorFn> fGetError;
143 };
144
145 auto errorContext = new GetErrorContext;
146
147#if defined(SK_ENABLE_SCOPED_LSAN_SUPPRESSIONS)
148 __lsan_ignore_object(errorContext);
149#endif
150
151 errorContext->fGetError = original;
152
153 return GrGLFunction<GrGLGetErrorFn>([errorContext]() {
154 GrGLenum error = errorContext->fGetError();
155 if (error == GR_GL_NO_ERROR && (errorContext->fRandom.nextU() % 300) == 0) {
156 error = GR_GL_OUT_OF_MEMORY;
157 }
158 return error;
159 });
160}
161#endif
162
Adlai Holler3d0359a2020-07-09 15:35:55 -0400163// CONTEXT TODO: Make* functions should return an sk_sp<GrDirectContext>
Jim Van Verth03b8ab22020-02-24 11:36:15 -0500164sk_sp<GrContext> GrContext::MakeGL(sk_sp<const GrGLInterface> glInterface,
Robert Phillipsa3457b82018-03-08 11:30:12 -0500165 const GrContextOptions& options) {
Adlai Holler3d0359a2020-07-09 15:35:55 -0400166 auto direct = new GrDirectContext(GrBackendApi::kOpenGL, options);
Brian Salomon24069eb2020-06-24 10:19:52 -0400167#if GR_TEST_UTILS
168 if (options.fRandomGLOOM) {
169 auto copy = sk_make_sp<GrGLInterface>(*glInterface);
170 copy->fFunctions.fGetError =
171 make_get_error_with_random_oom(glInterface->fFunctions.fGetError);
172#if GR_GL_CHECK_ERROR
173 // Suppress logging GL errors since we'll be synthetically generating them.
174 copy->suppressErrorLogging();
175#endif
176 glInterface = std::move(copy);
177 }
178#endif
Adlai Holler3d0359a2020-07-09 15:35:55 -0400179 direct->fGpu = GrGLGpu::Make(std::move(glInterface), options, direct);
180 sk_sp<GrContext> context(direct);
Adlai Hollere219d1c2020-06-02 11:23:16 -0400181 if (!context->init()) {
Robert Phillipsa3457b82018-03-08 11:30:12 -0500182 return nullptr;
183 }
184 return context;
185}
John Rosascoa9b348f2019-11-08 13:18:15 -0800186#endif
Robert Phillipsa3457b82018-03-08 11:30:12 -0500187
188sk_sp<GrContext> GrContext::MakeMock(const GrMockOptions* mockOptions) {
189 GrContextOptions defaultOptions;
190 return MakeMock(mockOptions, defaultOptions);
191}
192
193sk_sp<GrContext> GrContext::MakeMock(const GrMockOptions* mockOptions,
194 const GrContextOptions& options) {
Adlai Holler3d0359a2020-07-09 15:35:55 -0400195 auto direct = new GrDirectContext(GrBackendApi::kMock, options);
Robert Phillipsa3457b82018-03-08 11:30:12 -0500196
Adlai Holler3d0359a2020-07-09 15:35:55 -0400197 direct->fGpu = GrMockGpu::Make(mockOptions, options, direct);
198 sk_sp<GrContext> context(direct);
Adlai Hollere219d1c2020-06-02 11:23:16 -0400199 if (!context->init()) {
Robert Phillipsa3457b82018-03-08 11:30:12 -0500200 return nullptr;
201 }
Chris Daltona378b452019-12-11 13:24:11 -0500202
Robert Phillipsa3457b82018-03-08 11:30:12 -0500203 return context;
204}
205
Mike Kleina55e2142018-10-03 16:34:11 +0000206sk_sp<GrContext> GrContext::MakeVulkan(const GrVkBackendContext& backendContext) {
Greg Danielb4d89562018-10-03 18:44:49 +0000207#ifdef SK_VULKAN
Greg Daniel10a83da2018-06-14 09:31:11 -0400208 GrContextOptions defaultOptions;
209 return MakeVulkan(backendContext, defaultOptions);
Greg Danielb4d89562018-10-03 18:44:49 +0000210#else
211 return nullptr;
212#endif
Greg Daniel10a83da2018-06-14 09:31:11 -0400213}
214
215sk_sp<GrContext> GrContext::MakeVulkan(const GrVkBackendContext& backendContext,
216 const GrContextOptions& options) {
Greg Danielb4d89562018-10-03 18:44:49 +0000217#ifdef SK_VULKAN
Adlai Holler3d0359a2020-07-09 15:35:55 -0400218 auto direct = new GrDirectContext(GrBackendApi::kVulkan, options);
Greg Daniel10a83da2018-06-14 09:31:11 -0400219
Adlai Holler3d0359a2020-07-09 15:35:55 -0400220 direct->fGpu = GrVkGpu::Make(backendContext, options, direct);
221 sk_sp<GrContext> context(direct);
Adlai Hollere219d1c2020-06-02 11:23:16 -0400222 if (!context->init()) {
Robert Phillipsa3457b82018-03-08 11:30:12 -0500223 return nullptr;
224 }
225
Robert Phillipsa3457b82018-03-08 11:30:12 -0500226 return context;
Greg Danielb4d89562018-10-03 18:44:49 +0000227#else
228 return nullptr;
Mike Kleina55e2142018-10-03 16:34:11 +0000229#endif
Greg Danielb4d89562018-10-03 18:44:49 +0000230}
Robert Phillipsa3457b82018-03-08 11:30:12 -0500231
232#ifdef SK_METAL
233sk_sp<GrContext> GrContext::MakeMetal(void* device, void* queue) {
234 GrContextOptions defaultOptions;
235 return MakeMetal(device, queue, defaultOptions);
236}
237
238sk_sp<GrContext> GrContext::MakeMetal(void* device, void* queue, const GrContextOptions& options) {
Adlai Holler3d0359a2020-07-09 15:35:55 -0400239 auto direct = new GrDirectContext(GrBackendApi::kMetal, options);
Robert Phillipsa3457b82018-03-08 11:30:12 -0500240
Adlai Holler3d0359a2020-07-09 15:35:55 -0400241 direct->fGpu = GrMtlTrampoline::MakeGpu(direct, options, device, queue);
242 sk_sp<GrContext> context(direct);
Adlai Hollere219d1c2020-06-02 11:23:16 -0400243 if (!context->init()) {
Robert Phillipsa3457b82018-03-08 11:30:12 -0500244 return nullptr;
245 }
Timothy Liang4e85e802018-06-28 16:37:18 -0400246
Robert Phillipsa3457b82018-03-08 11:30:12 -0500247 return context;
248}
249#endif
250
Jim Van Verthb01e12b2020-02-18 14:34:38 -0500251#ifdef SK_DIRECT3D
252sk_sp<GrContext> GrContext::MakeDirect3D(const GrD3DBackendContext& backendContext) {
253 GrContextOptions defaultOptions;
254 return MakeDirect3D(backendContext, defaultOptions);
255}
256
257sk_sp<GrContext> GrContext::MakeDirect3D(const GrD3DBackendContext& backendContext,
258 const GrContextOptions& options) {
Adlai Holler3d0359a2020-07-09 15:35:55 -0400259 auto direct = new GrDirectContext(GrBackendApi::kDirect3D, options);
Jim Van Verthb01e12b2020-02-18 14:34:38 -0500260
Adlai Holler3d0359a2020-07-09 15:35:55 -0400261 direct->fGpu = GrD3DGpu::Make(backendContext, options, direct);
262 sk_sp<GrContext> context(direct);
Adlai Hollere219d1c2020-06-02 11:23:16 -0400263 if (!context->init()) {
Jim Van Verthd2d4c5e2020-02-19 14:57:58 -0500264 return nullptr;
265 }
Jim Van Verthb01e12b2020-02-18 14:34:38 -0500266
Jim Van Verthd2d4c5e2020-02-19 14:57:58 -0500267 return context;
Jim Van Verthb01e12b2020-02-18 14:34:38 -0500268}
269#endif
270
Stephen White985741a2019-07-18 11:43:45 -0400271#ifdef SK_DAWN
Stephen Whitea521c962019-12-04 09:57:48 -0500272sk_sp<GrContext> GrContext::MakeDawn(const wgpu::Device& device) {
Stephen White985741a2019-07-18 11:43:45 -0400273 GrContextOptions defaultOptions;
274 return MakeDawn(device, defaultOptions);
275}
276
Stephen Whitea521c962019-12-04 09:57:48 -0500277sk_sp<GrContext> GrContext::MakeDawn(const wgpu::Device& device, const GrContextOptions& options) {
Adlai Holler3d0359a2020-07-09 15:35:55 -0400278 auto direct = new GrDirectContext(GrBackendApi::kDawn, options);
Stephen White985741a2019-07-18 11:43:45 -0400279
Adlai Holler3d0359a2020-07-09 15:35:55 -0400280 direct->fGpu = GrDawnGpu::Make(device, options, direct);
281 sk_sp<GrContext> context(direct);
Adlai Hollere219d1c2020-06-02 11:23:16 -0400282 if (!context->init()) {
Stephen White985741a2019-07-18 11:43:45 -0400283 return nullptr;
284 }
285
Stephen White985741a2019-07-18 11:43:45 -0400286 return context;
287}
288#endif