blob: d25852f270fb485dacb92ebf4596161b18ee2ad1 [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 Phillipsa3457b82018-03-08 11:30:12 -05009#include "GrContext.h"
10
11#include "GrContextPriv.h"
12#include "GrGpu.h"
13
Ethan Nicholas00543112018-07-31 09:44:36 -040014#include "effects/GrSkSLFP.h"
Robert Phillipsa3457b82018-03-08 11:30:12 -050015#include "gl/GrGLGpu.h"
16#include "mock/GrMockGpu.h"
17#include "text/GrGlyphCache.h"
18#ifdef SK_METAL
19#include "mtl/GrMtlTrampoline.h"
20#endif
21#ifdef SK_VULKAN
22#include "vk/GrVkGpu.h"
23#endif
24
25class SK_API GrDirectContext : public GrContext {
26public:
Greg Danielbdf12ad2018-10-12 09:31:11 -040027 GrDirectContext(GrBackendApi backend)
Robert Phillipsa3457b82018-03-08 11:30:12 -050028 : INHERITED(backend)
29 , fAtlasManager(nullptr) {
30 }
31
32 ~GrDirectContext() override {
33 // this if-test protects against the case where the context is being destroyed
34 // before having been fully created
35 if (this->contextPriv().getGpu()) {
36 this->flush();
37 }
38
39 delete fAtlasManager;
40 }
41
42 void abandonContext() override {
43 INHERITED::abandonContext();
44 fAtlasManager->freeAll();
45 }
46
47 void releaseResourcesAndAbandonContext() override {
48 INHERITED::releaseResourcesAndAbandonContext();
49 fAtlasManager->freeAll();
50 }
51
52 void freeGpuResources() override {
53 this->flush();
54 fAtlasManager->freeAll();
55
56 INHERITED::freeGpuResources();
57 }
58
59protected:
60 bool init(const GrContextOptions& options) override {
61 SkASSERT(fCaps); // should've been set in ctor
62 SkASSERT(!fThreadSafeProxy);
Ethan Nicholas00543112018-07-31 09:44:36 -040063 SkASSERT(!fFPFactoryCache);
64 fFPFactoryCache.reset(new GrSkSLFPFactoryCache());
Robert Phillipsa3457b82018-03-08 11:30:12 -050065 fThreadSafeProxy.reset(new GrContextThreadSafeProxy(fCaps, this->uniqueID(),
Ethan Nicholas00543112018-07-31 09:44:36 -040066 fBackend, options, fFPFactoryCache));
Robert Phillipsa3457b82018-03-08 11:30:12 -050067
68 if (!INHERITED::initCommon(options)) {
69 return false;
70 }
71
72 GrDrawOpAtlas::AllowMultitexturing allowMultitexturing;
73 if (GrContextOptions::Enable::kNo == options.fAllowMultipleGlyphCacheTextures ||
74 // multitexturing supported only if range can represent the index + texcoords fully
75 !(fCaps->shaderCaps()->floatIs32Bits() || fCaps->shaderCaps()->integerSupport())) {
76 allowMultitexturing = GrDrawOpAtlas::AllowMultitexturing::kNo;
77 } else {
78 allowMultitexturing = GrDrawOpAtlas::AllowMultitexturing::kYes;
79 }
80
81 GrGlyphCache* glyphCache = this->contextPriv().getGlyphCache();
82 GrProxyProvider* proxyProvider = this->contextPriv().proxyProvider();
83
84 fAtlasManager = new GrAtlasManager(proxyProvider, glyphCache,
85 options.fGlyphCacheTextureMaximumBytes,
86 allowMultitexturing);
87 this->contextPriv().addOnFlushCallbackObject(fAtlasManager);
88
Robert Phillipsa3457b82018-03-08 11:30:12 -050089 return true;
90 }
91
92 GrAtlasManager* onGetAtlasManager() override { return fAtlasManager; }
93
94private:
95 GrAtlasManager* fAtlasManager;
96
97 typedef GrContext INHERITED;
98};
99
Robert Phillipsa3457b82018-03-08 11:30:12 -0500100sk_sp<GrContext> GrContext::MakeGL(sk_sp<const GrGLInterface> interface) {
101 GrContextOptions defaultOptions;
102 return MakeGL(std::move(interface), defaultOptions);
103}
104
Brian Salomonc1b9c102018-04-06 09:18:00 -0400105sk_sp<GrContext> GrContext::MakeGL(const GrContextOptions& options) {
106 return MakeGL(nullptr, options);
107}
108
109sk_sp<GrContext> GrContext::MakeGL() {
110 GrContextOptions defaultOptions;
111 return MakeGL(nullptr, defaultOptions);
112}
113
Robert Phillipsa3457b82018-03-08 11:30:12 -0500114sk_sp<GrContext> GrContext::MakeGL(sk_sp<const GrGLInterface> interface,
115 const GrContextOptions& options) {
Greg Danielbdf12ad2018-10-12 09:31:11 -0400116 sk_sp<GrContext> context(new GrDirectContext(GrBackendApi::kOpenGL));
Robert Phillipsa3457b82018-03-08 11:30:12 -0500117
118 context->fGpu = GrGLGpu::Make(std::move(interface), options, context.get());
119 if (!context->fGpu) {
120 return nullptr;
121 }
122
123 context->fCaps = context->fGpu->refCaps();
124 if (!context->init(options)) {
125 return nullptr;
126 }
127 return context;
128}
129
130sk_sp<GrContext> GrContext::MakeMock(const GrMockOptions* mockOptions) {
131 GrContextOptions defaultOptions;
132 return MakeMock(mockOptions, defaultOptions);
133}
134
135sk_sp<GrContext> GrContext::MakeMock(const GrMockOptions* mockOptions,
136 const GrContextOptions& options) {
Greg Danielbdf12ad2018-10-12 09:31:11 -0400137 sk_sp<GrContext> context(new GrDirectContext(GrBackendApi::kMock));
Robert Phillipsa3457b82018-03-08 11:30:12 -0500138
139 context->fGpu = GrMockGpu::Make(mockOptions, options, context.get());
140 if (!context->fGpu) {
141 return nullptr;
142 }
143
144 context->fCaps = context->fGpu->refCaps();
145 if (!context->init(options)) {
146 return nullptr;
147 }
148 return context;
149}
150
Mike Kleina55e2142018-10-03 16:34:11 +0000151sk_sp<GrContext> GrContext::MakeVulkan(const GrVkBackendContext& backendContext) {
Greg Danielb4d89562018-10-03 18:44:49 +0000152#ifdef SK_VULKAN
Greg Daniel10a83da2018-06-14 09:31:11 -0400153 GrContextOptions defaultOptions;
154 return MakeVulkan(backendContext, defaultOptions);
Greg Danielb4d89562018-10-03 18:44:49 +0000155#else
156 return nullptr;
157#endif
Greg Daniel10a83da2018-06-14 09:31:11 -0400158}
159
160sk_sp<GrContext> GrContext::MakeVulkan(const GrVkBackendContext& backendContext,
161 const GrContextOptions& options) {
Greg Danielb4d89562018-10-03 18:44:49 +0000162#ifdef SK_VULKAN
163 GrContextOptions defaultOptions;
Greg Danielbdf12ad2018-10-12 09:31:11 -0400164 sk_sp<GrContext> context(new GrDirectContext(GrBackendApi::kVulkan));
Greg Daniel10a83da2018-06-14 09:31:11 -0400165
Greg Danielf730c182018-07-02 20:15:37 +0000166 context->fGpu = GrVkGpu::Make(backendContext, options, context.get());
Robert Phillipsa3457b82018-03-08 11:30:12 -0500167 if (!context->fGpu) {
168 return nullptr;
169 }
170
171 context->fCaps = context->fGpu->refCaps();
172 if (!context->init(options)) {
173 return nullptr;
174 }
175 return context;
Greg Danielb4d89562018-10-03 18:44:49 +0000176#else
177 return nullptr;
Mike Kleina55e2142018-10-03 16:34:11 +0000178#endif
Greg Danielb4d89562018-10-03 18:44:49 +0000179}
Robert Phillipsa3457b82018-03-08 11:30:12 -0500180
181#ifdef SK_METAL
182sk_sp<GrContext> GrContext::MakeMetal(void* device, void* queue) {
183 GrContextOptions defaultOptions;
184 return MakeMetal(device, queue, defaultOptions);
185}
186
187sk_sp<GrContext> GrContext::MakeMetal(void* device, void* queue, const GrContextOptions& options) {
Greg Danielbdf12ad2018-10-12 09:31:11 -0400188 sk_sp<GrContext> context(new GrDirectContext(GrBackendApi::kMetal));
Robert Phillipsa3457b82018-03-08 11:30:12 -0500189
190 context->fGpu = GrMtlTrampoline::MakeGpu(context.get(), options, device, queue);
191 if (!context->fGpu) {
192 return nullptr;
193 }
Timothy Liang4e85e802018-06-28 16:37:18 -0400194
195 context->fCaps = context->fGpu->refCaps();
Robert Phillipsa3457b82018-03-08 11:30:12 -0500196 if (!context->init(options)) {
197 return nullptr;
198 }
199 return context;
200}
201#endif
202