blob: a726e76b649b0660bee198f4b9fa89a40d67b95a [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#include "vk/GrVkVulkan.h"
9
Robert Phillipsa3457b82018-03-08 11:30:12 -050010#include "GrContext.h"
11
12#include "GrContextPriv.h"
13#include "GrGpu.h"
14
Ethan Nicholas00543112018-07-31 09:44:36 -040015#include "effects/GrSkSLFP.h"
Robert Phillipsa3457b82018-03-08 11:30:12 -050016#include "gl/GrGLGpu.h"
17#include "mock/GrMockGpu.h"
18#include "text/GrGlyphCache.h"
19#ifdef SK_METAL
20#include "mtl/GrMtlTrampoline.h"
21#endif
22#ifdef SK_VULKAN
23#include "vk/GrVkGpu.h"
24#endif
25
26class SK_API GrDirectContext : public GrContext {
27public:
Greg Danielbdf12ad2018-10-12 09:31:11 -040028 GrDirectContext(GrBackendApi backend)
Robert Phillipsa3457b82018-03-08 11:30:12 -050029 : INHERITED(backend)
30 , fAtlasManager(nullptr) {
31 }
32
33 ~GrDirectContext() override {
34 // this if-test protects against the case where the context is being destroyed
35 // before having been fully created
36 if (this->contextPriv().getGpu()) {
37 this->flush();
38 }
39
40 delete fAtlasManager;
41 }
42
43 void abandonContext() override {
44 INHERITED::abandonContext();
45 fAtlasManager->freeAll();
46 }
47
48 void releaseResourcesAndAbandonContext() override {
49 INHERITED::releaseResourcesAndAbandonContext();
50 fAtlasManager->freeAll();
51 }
52
53 void freeGpuResources() override {
54 this->flush();
55 fAtlasManager->freeAll();
56
57 INHERITED::freeGpuResources();
58 }
59
60protected:
61 bool init(const GrContextOptions& options) override {
62 SkASSERT(fCaps); // should've been set in ctor
63 SkASSERT(!fThreadSafeProxy);
Ethan Nicholas00543112018-07-31 09:44:36 -040064 SkASSERT(!fFPFactoryCache);
65 fFPFactoryCache.reset(new GrSkSLFPFactoryCache());
Robert Phillipsa3457b82018-03-08 11:30:12 -050066 fThreadSafeProxy.reset(new GrContextThreadSafeProxy(fCaps, this->uniqueID(),
Ethan Nicholas00543112018-07-31 09:44:36 -040067 fBackend, options, fFPFactoryCache));
Robert Phillipsa3457b82018-03-08 11:30:12 -050068
69 if (!INHERITED::initCommon(options)) {
70 return false;
71 }
72
73 GrDrawOpAtlas::AllowMultitexturing allowMultitexturing;
74 if (GrContextOptions::Enable::kNo == options.fAllowMultipleGlyphCacheTextures ||
75 // multitexturing supported only if range can represent the index + texcoords fully
76 !(fCaps->shaderCaps()->floatIs32Bits() || fCaps->shaderCaps()->integerSupport())) {
77 allowMultitexturing = GrDrawOpAtlas::AllowMultitexturing::kNo;
78 } else {
79 allowMultitexturing = GrDrawOpAtlas::AllowMultitexturing::kYes;
80 }
81
82 GrGlyphCache* glyphCache = this->contextPriv().getGlyphCache();
83 GrProxyProvider* proxyProvider = this->contextPriv().proxyProvider();
84
85 fAtlasManager = new GrAtlasManager(proxyProvider, glyphCache,
86 options.fGlyphCacheTextureMaximumBytes,
87 allowMultitexturing);
88 this->contextPriv().addOnFlushCallbackObject(fAtlasManager);
89
Robert Phillipsa3457b82018-03-08 11:30:12 -050090 return true;
91 }
92
93 GrAtlasManager* onGetAtlasManager() override { return fAtlasManager; }
94
95private:
96 GrAtlasManager* fAtlasManager;
97
98 typedef GrContext INHERITED;
99};
100
Robert Phillipsa3457b82018-03-08 11:30:12 -0500101sk_sp<GrContext> GrContext::MakeGL(sk_sp<const GrGLInterface> interface) {
102 GrContextOptions defaultOptions;
103 return MakeGL(std::move(interface), defaultOptions);
104}
105
Brian Salomonc1b9c102018-04-06 09:18:00 -0400106sk_sp<GrContext> GrContext::MakeGL(const GrContextOptions& options) {
107 return MakeGL(nullptr, options);
108}
109
110sk_sp<GrContext> GrContext::MakeGL() {
111 GrContextOptions defaultOptions;
112 return MakeGL(nullptr, defaultOptions);
113}
114
Robert Phillipsa3457b82018-03-08 11:30:12 -0500115sk_sp<GrContext> GrContext::MakeGL(sk_sp<const GrGLInterface> interface,
116 const GrContextOptions& options) {
Greg Danielbdf12ad2018-10-12 09:31:11 -0400117 sk_sp<GrContext> context(new GrDirectContext(GrBackendApi::kOpenGL));
Robert Phillipsa3457b82018-03-08 11:30:12 -0500118
119 context->fGpu = GrGLGpu::Make(std::move(interface), options, context.get());
120 if (!context->fGpu) {
121 return nullptr;
122 }
123
124 context->fCaps = context->fGpu->refCaps();
125 if (!context->init(options)) {
126 return nullptr;
127 }
128 return context;
129}
130
131sk_sp<GrContext> GrContext::MakeMock(const GrMockOptions* mockOptions) {
132 GrContextOptions defaultOptions;
133 return MakeMock(mockOptions, defaultOptions);
134}
135
136sk_sp<GrContext> GrContext::MakeMock(const GrMockOptions* mockOptions,
137 const GrContextOptions& options) {
Greg Danielbdf12ad2018-10-12 09:31:11 -0400138 sk_sp<GrContext> context(new GrDirectContext(GrBackendApi::kMock));
Robert Phillipsa3457b82018-03-08 11:30:12 -0500139
140 context->fGpu = GrMockGpu::Make(mockOptions, options, context.get());
141 if (!context->fGpu) {
142 return nullptr;
143 }
144
145 context->fCaps = context->fGpu->refCaps();
146 if (!context->init(options)) {
147 return nullptr;
148 }
149 return context;
150}
151
Mike Kleina55e2142018-10-03 16:34:11 +0000152sk_sp<GrContext> GrContext::MakeVulkan(const GrVkBackendContext& backendContext) {
Greg Danielb4d89562018-10-03 18:44:49 +0000153#ifdef SK_VULKAN
Greg Daniel10a83da2018-06-14 09:31:11 -0400154 GrContextOptions defaultOptions;
155 return MakeVulkan(backendContext, defaultOptions);
Greg Danielb4d89562018-10-03 18:44:49 +0000156#else
157 return nullptr;
158#endif
Greg Daniel10a83da2018-06-14 09:31:11 -0400159}
160
161sk_sp<GrContext> GrContext::MakeVulkan(const GrVkBackendContext& backendContext,
162 const GrContextOptions& options) {
Greg Danielb4d89562018-10-03 18:44:49 +0000163#ifdef SK_VULKAN
164 GrContextOptions defaultOptions;
Greg Danielbdf12ad2018-10-12 09:31:11 -0400165 sk_sp<GrContext> context(new GrDirectContext(GrBackendApi::kVulkan));
Greg Daniel10a83da2018-06-14 09:31:11 -0400166
Greg Danielf730c182018-07-02 20:15:37 +0000167 context->fGpu = GrVkGpu::Make(backendContext, options, context.get());
Robert Phillipsa3457b82018-03-08 11:30:12 -0500168 if (!context->fGpu) {
169 return nullptr;
170 }
171
172 context->fCaps = context->fGpu->refCaps();
173 if (!context->init(options)) {
174 return nullptr;
175 }
176 return context;
Greg Danielb4d89562018-10-03 18:44:49 +0000177#else
178 return nullptr;
Mike Kleina55e2142018-10-03 16:34:11 +0000179#endif
Greg Danielb4d89562018-10-03 18:44:49 +0000180}
Robert Phillipsa3457b82018-03-08 11:30:12 -0500181
182#ifdef SK_METAL
183sk_sp<GrContext> GrContext::MakeMetal(void* device, void* queue) {
184 GrContextOptions defaultOptions;
185 return MakeMetal(device, queue, defaultOptions);
186}
187
188sk_sp<GrContext> GrContext::MakeMetal(void* device, void* queue, const GrContextOptions& options) {
Greg Danielbdf12ad2018-10-12 09:31:11 -0400189 sk_sp<GrContext> context(new GrDirectContext(GrBackendApi::kMetal));
Robert Phillipsa3457b82018-03-08 11:30:12 -0500190
191 context->fGpu = GrMtlTrampoline::MakeGpu(context.get(), options, device, queue);
192 if (!context->fGpu) {
193 return nullptr;
194 }
Timothy Liang4e85e802018-06-28 16:37:18 -0400195
196 context->fCaps = context->fGpu->refCaps();
Robert Phillipsa3457b82018-03-08 11:30:12 -0500197 if (!context->init(options)) {
198 return nullptr;
199 }
200 return context;
201}
202#endif
203