blob: 59b984caa3fadd503860e1fc68c7885acc55ef62 [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
8#include "GrContext.h"
9
10#include "GrContextPriv.h"
11#include "GrGpu.h"
12
Ethan Nicholas00543112018-07-31 09:44:36 -040013#include "effects/GrSkSLFP.h"
Robert Phillipsa3457b82018-03-08 11:30:12 -050014#include "gl/GrGLGpu.h"
15#include "mock/GrMockGpu.h"
16#include "text/GrGlyphCache.h"
17#ifdef SK_METAL
18#include "mtl/GrMtlTrampoline.h"
19#endif
20#ifdef SK_VULKAN
21#include "vk/GrVkGpu.h"
22#endif
23
24class SK_API GrDirectContext : public GrContext {
25public:
26 GrDirectContext(GrBackend backend)
27 : INHERITED(backend)
28 , fAtlasManager(nullptr) {
29 }
30
31 ~GrDirectContext() override {
32 // this if-test protects against the case where the context is being destroyed
33 // before having been fully created
34 if (this->contextPriv().getGpu()) {
35 this->flush();
36 }
37
38 delete fAtlasManager;
39 }
40
41 void abandonContext() override {
42 INHERITED::abandonContext();
43 fAtlasManager->freeAll();
44 }
45
46 void releaseResourcesAndAbandonContext() override {
47 INHERITED::releaseResourcesAndAbandonContext();
48 fAtlasManager->freeAll();
49 }
50
51 void freeGpuResources() override {
52 this->flush();
53 fAtlasManager->freeAll();
54
55 INHERITED::freeGpuResources();
56 }
57
58protected:
59 bool init(const GrContextOptions& options) override {
60 SkASSERT(fCaps); // should've been set in ctor
61 SkASSERT(!fThreadSafeProxy);
Ethan Nicholas00543112018-07-31 09:44:36 -040062 SkASSERT(!fFPFactoryCache);
63 fFPFactoryCache.reset(new GrSkSLFPFactoryCache());
Robert Phillipsa3457b82018-03-08 11:30:12 -050064 fThreadSafeProxy.reset(new GrContextThreadSafeProxy(fCaps, this->uniqueID(),
Ethan Nicholas00543112018-07-31 09:44:36 -040065 fBackend, options, fFPFactoryCache));
Robert Phillipsa3457b82018-03-08 11:30:12 -050066
67 if (!INHERITED::initCommon(options)) {
68 return false;
69 }
70
71 GrDrawOpAtlas::AllowMultitexturing allowMultitexturing;
72 if (GrContextOptions::Enable::kNo == options.fAllowMultipleGlyphCacheTextures ||
73 // multitexturing supported only if range can represent the index + texcoords fully
74 !(fCaps->shaderCaps()->floatIs32Bits() || fCaps->shaderCaps()->integerSupport())) {
75 allowMultitexturing = GrDrawOpAtlas::AllowMultitexturing::kNo;
76 } else {
77 allowMultitexturing = GrDrawOpAtlas::AllowMultitexturing::kYes;
78 }
79
80 GrGlyphCache* glyphCache = this->contextPriv().getGlyphCache();
81 GrProxyProvider* proxyProvider = this->contextPriv().proxyProvider();
82
83 fAtlasManager = new GrAtlasManager(proxyProvider, glyphCache,
84 options.fGlyphCacheTextureMaximumBytes,
85 allowMultitexturing);
86 this->contextPriv().addOnFlushCallbackObject(fAtlasManager);
87
Robert Phillipsa3457b82018-03-08 11:30:12 -050088 return true;
89 }
90
91 GrAtlasManager* onGetAtlasManager() override { return fAtlasManager; }
92
93private:
94 GrAtlasManager* fAtlasManager;
95
96 typedef GrContext INHERITED;
97};
98
Robert Phillipsa3457b82018-03-08 11:30:12 -050099sk_sp<GrContext> GrContext::MakeGL(sk_sp<const GrGLInterface> interface) {
100 GrContextOptions defaultOptions;
101 return MakeGL(std::move(interface), defaultOptions);
102}
103
Brian Salomonc1b9c102018-04-06 09:18:00 -0400104sk_sp<GrContext> GrContext::MakeGL(const GrContextOptions& options) {
105 return MakeGL(nullptr, options);
106}
107
108sk_sp<GrContext> GrContext::MakeGL() {
109 GrContextOptions defaultOptions;
110 return MakeGL(nullptr, defaultOptions);
111}
112
Robert Phillipsa3457b82018-03-08 11:30:12 -0500113sk_sp<GrContext> GrContext::MakeGL(sk_sp<const GrGLInterface> interface,
114 const GrContextOptions& options) {
115 sk_sp<GrContext> context(new GrDirectContext(kOpenGL_GrBackend));
116
117 context->fGpu = GrGLGpu::Make(std::move(interface), options, context.get());
118 if (!context->fGpu) {
119 return nullptr;
120 }
121
122 context->fCaps = context->fGpu->refCaps();
123 if (!context->init(options)) {
124 return nullptr;
125 }
126 return context;
127}
128
129sk_sp<GrContext> GrContext::MakeMock(const GrMockOptions* mockOptions) {
130 GrContextOptions defaultOptions;
131 return MakeMock(mockOptions, defaultOptions);
132}
133
134sk_sp<GrContext> GrContext::MakeMock(const GrMockOptions* mockOptions,
135 const GrContextOptions& options) {
136 sk_sp<GrContext> context(new GrDirectContext(kMock_GrBackend));
137
138 context->fGpu = GrMockGpu::Make(mockOptions, options, context.get());
139 if (!context->fGpu) {
140 return nullptr;
141 }
142
143 context->fCaps = context->fGpu->refCaps();
144 if (!context->init(options)) {
145 return nullptr;
146 }
147 return context;
148}
149
Mike Kleina55e2142018-10-03 16:34:11 +0000150sk_sp<GrContext> GrContext::MakeVulkan(const GrVkBackendContext& backendContext) {
Greg Danielb4d89562018-10-03 18:44:49 +0000151#ifdef SK_VULKAN
Greg Daniel10a83da2018-06-14 09:31:11 -0400152 GrContextOptions defaultOptions;
153 return MakeVulkan(backendContext, defaultOptions);
Greg Danielb4d89562018-10-03 18:44:49 +0000154#else
155 return nullptr;
156#endif
Greg Daniel10a83da2018-06-14 09:31:11 -0400157}
158
159sk_sp<GrContext> GrContext::MakeVulkan(const GrVkBackendContext& backendContext,
160 const GrContextOptions& options) {
Greg Danielb4d89562018-10-03 18:44:49 +0000161#ifdef SK_VULKAN
162 GrContextOptions defaultOptions;
Greg Daniel10a83da2018-06-14 09:31:11 -0400163 sk_sp<GrContext> context(new GrDirectContext(kVulkan_GrBackend));
164
Greg Danielf730c182018-07-02 20:15:37 +0000165 context->fGpu = GrVkGpu::Make(backendContext, options, context.get());
Robert Phillipsa3457b82018-03-08 11:30:12 -0500166 if (!context->fGpu) {
167 return nullptr;
168 }
169
170 context->fCaps = context->fGpu->refCaps();
171 if (!context->init(options)) {
172 return nullptr;
173 }
174 return context;
Greg Danielb4d89562018-10-03 18:44:49 +0000175#else
176 return nullptr;
Mike Kleina55e2142018-10-03 16:34:11 +0000177#endif
Greg Danielb4d89562018-10-03 18:44:49 +0000178}
Robert Phillipsa3457b82018-03-08 11:30:12 -0500179
180#ifdef SK_METAL
181sk_sp<GrContext> GrContext::MakeMetal(void* device, void* queue) {
182 GrContextOptions defaultOptions;
183 return MakeMetal(device, queue, defaultOptions);
184}
185
186sk_sp<GrContext> GrContext::MakeMetal(void* device, void* queue, const GrContextOptions& options) {
187 sk_sp<GrContext> context(new GrDirectContext(kMetal_GrBackend));
188
189 context->fGpu = GrMtlTrampoline::MakeGpu(context.get(), options, device, queue);
190 if (!context->fGpu) {
191 return nullptr;
192 }
Timothy Liang4e85e802018-06-28 16:37:18 -0400193
194 context->fCaps = context->fGpu->refCaps();
Robert Phillipsa3457b82018-03-08 11:30:12 -0500195 if (!context->init(options)) {
196 return nullptr;
197 }
198 return context;
199}
200#endif
201