blob: 651f3fcde27a81d19ca46bdbf442bcf4c1eb6b2b [file] [log] [blame]
bsalomon3724e572016-03-30 18:56:19 -07001
djsollene4545212014-11-13 11:12:41 -08002/*
3 * Copyright 2014 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
9#include "GrContextFactory.h"
bsalomon273c0f52016-03-31 10:59:06 -070010#include "gl/GLTestContext.h"
djsollene4545212014-11-13 11:12:41 -080011
12#if SK_ANGLE
bsalomon273c0f52016-03-31 10:59:06 -070013 #include "gl/angle/GLTestContext_angle.h"
djsollene4545212014-11-13 11:12:41 -080014#endif
hendrikw885bf092015-08-27 10:38:39 -070015#if SK_COMMAND_BUFFER
bsalomon273c0f52016-03-31 10:59:06 -070016 #include "gl/command_buffer/GLTestContext_command_buffer.h"
hendrikw885bf092015-08-27 10:38:39 -070017#endif
bsalomon273c0f52016-03-31 10:59:06 -070018#include "gl/debug/DebugGLTestContext.h"
djsollene4545212014-11-13 11:12:41 -080019#if SK_MESA
bsalomon273c0f52016-03-31 10:59:06 -070020 #include "gl/mesa/GLTestContext_mesa.h"
djsollene4545212014-11-13 11:12:41 -080021#endif
bsalomon7c62b472016-04-01 07:42:05 -070022#if SK_VULKAN
23#include "vk/GrVkBackendContext.h"
24#endif
bsalomon273c0f52016-03-31 10:59:06 -070025#include "gl/null/NullGLTestContext.h"
kkinnunencfe62e32015-07-01 02:58:50 -070026#include "gl/GrGLGpu.h"
27#include "GrCaps.h"
djsollene4545212014-11-13 11:12:41 -080028
bsalomon3724e572016-03-30 18:56:19 -070029namespace sk_gpu_test {
kkinnunen34058002016-01-06 23:49:30 -080030GrContextFactory::GrContextFactory() { }
31
32GrContextFactory::GrContextFactory(const GrContextOptions& opts)
33 : fGlobalOptions(opts) {
34}
35
36GrContextFactory::~GrContextFactory() {
37 this->destroyContexts();
38}
39
40void GrContextFactory::destroyContexts() {
41 for (Context& context : fContexts) {
42 if (context.fGLContext) {
43 context.fGLContext->makeCurrent();
44 }
45 if (!context.fGrContext->unique()) {
bsalomondc0fcd42016-04-11 14:21:33 -070046 context.fGrContext->releaseResourcesAndAbandonContext();
47 context.fAbandoned = true;
kkinnunen34058002016-01-06 23:49:30 -080048 }
49 context.fGrContext->unref();
bsalomondc0fcd42016-04-11 14:21:33 -070050 delete context.fGLContext;
kkinnunen34058002016-01-06 23:49:30 -080051 }
52 fContexts.reset();
53}
54
55void GrContextFactory::abandonContexts() {
56 for (Context& context : fContexts) {
bsalomondc0fcd42016-04-11 14:21:33 -070057 if (!context.fAbandoned) {
58 if (context.fGLContext) {
59 context.fGLContext->makeCurrent();
60 context.fGLContext->testAbandon();
61 delete(context.fGLContext);
62 context.fGLContext = nullptr;
63 }
64 context.fGrContext->abandonContext();
65 context.fAbandoned = true;
kkinnunen34058002016-01-06 23:49:30 -080066 }
kkinnunen34058002016-01-06 23:49:30 -080067 }
68}
69
bsalomon6e2aad42016-04-01 11:54:31 -070070void GrContextFactory::releaseResourcesAndAbandonContexts() {
71 for (Context& context : fContexts) {
bsalomondc0fcd42016-04-11 14:21:33 -070072 if (!context.fAbandoned) {
73 if (context.fGLContext) {
74 context.fGLContext->makeCurrent();
75 }
bsalomon6e2aad42016-04-01 11:54:31 -070076 context.fGrContext->releaseResourcesAndAbandonContext();
bsalomondc0fcd42016-04-11 14:21:33 -070077 context.fAbandoned = true;
78 if (context.fGLContext) {
79 delete context.fGLContext;
80 context.fGLContext = nullptr;
81 }
bsalomon6e2aad42016-04-01 11:54:31 -070082 }
83 }
84}
85
bsalomon85b4b532016-04-05 11:06:27 -070086#if defined(SK_BUILD_FOR_UNIX) || defined(SK_BUILD_FOR_WIN) || defined(SK_BUILD_FOR_MAC)
87const GrContextFactory::ContextType GrContextFactory::kNativeGL_ContextType =
88 GrContextFactory::kGL_ContextType;
89#else
90const GrContextFactory::ContextType GrContextFactory::kNativeGL_ContextType =
91 GrContextFactory::kGLES_ContextType;
92#endif
93
bsalomonf2f1c172016-04-05 12:59:06 -070094ContextInfo GrContextFactory::getContextInfo(ContextType type, ContextOptions options) {
djsollene4545212014-11-13 11:12:41 -080095 for (int i = 0; i < fContexts.count(); ++i) {
kkinnunen34058002016-01-06 23:49:30 -080096 Context& context = fContexts[i];
kkinnunen34058002016-01-06 23:49:30 -080097 if (context.fType == type &&
bsalomondc0fcd42016-04-11 14:21:33 -070098 context.fOptions == options &&
99 !context.fAbandoned) {
100 if (context.fGLContext) {
101 context.fGLContext->makeCurrent();
102 }
kkinnunen34058002016-01-06 23:49:30 -0800103 return ContextInfo(context.fGrContext, context.fGLContext);
djsollene4545212014-11-13 11:12:41 -0800104 }
105 }
bsalomon273c0f52016-03-31 10:59:06 -0700106 SkAutoTDelete<GLTestContext> glCtx;
bsalomondc0fcd42016-04-11 14:21:33 -0700107 sk_sp<GrContext> grCtx;
108 GrBackendContext backendContext = 0;
109 sk_sp<const GrGLInterface> glInterface;
110#ifdef SK_VULKAN
111 sk_sp<const GrVkBackendContext> vkBackend;
kkinnunen3e980c32015-12-23 01:33:00 -0800112#endif
bsalomondc0fcd42016-04-11 14:21:33 -0700113 GrBackend backend = ContextTypeBackend(type);
114 switch (backend) {
115 case kOpenGL_GrBackend:
116 switch (type) {
117 case kGL_ContextType:
118 glCtx.reset(CreatePlatformGLTestContext(kGL_GrGLStandard));
119 break;
120 case kGLES_ContextType:
121 glCtx.reset(CreatePlatformGLTestContext(kGLES_GrGLStandard));
122 break;
123#if SK_ANGLE
124# ifdef SK_BUILD_FOR_WIN
125 case kANGLE_ContextType:
126 glCtx.reset(CreateANGLEDirect3DGLTestContext());
127 break;
128# endif
129 case kANGLE_GL_ContextType:
130 glCtx.reset(CreateANGLEOpenGLGLTestContext());
131 break;
djsollene4545212014-11-13 11:12:41 -0800132#endif
kkinnunen3e980c32015-12-23 01:33:00 -0800133#if SK_COMMAND_BUFFER
bsalomondc0fcd42016-04-11 14:21:33 -0700134 case kCommandBuffer_ContextType:
135 glCtx.reset(CommandBufferGLTestContext::Create());
136 break;
hendrikw885bf092015-08-27 10:38:39 -0700137#endif
kkinnunen3e980c32015-12-23 01:33:00 -0800138#if SK_MESA
bsalomondc0fcd42016-04-11 14:21:33 -0700139 case kMESA_ContextType:
140 glCtx.reset(CreateMesaGLTestContext());
141 break;
djsollene4545212014-11-13 11:12:41 -0800142#endif
bsalomondc0fcd42016-04-11 14:21:33 -0700143 case kNullGL_ContextType:
144 glCtx.reset(CreateNullGLTestContext());
145 break;
146 case kDebugGL_ContextType:
147 glCtx.reset(CreateDebugGLTestContext());
148 break;
149 default:
150 return ContextInfo();
151 }
152 if (nullptr == glCtx.get()) {
153 return ContextInfo();
154 }
155 glInterface.reset(SkRef(glCtx->gl()));
156 // Block NVPR from non-NVPR types.
157 if (!(kEnableNVPR_ContextOptions & options)) {
158 glInterface.reset(GrGLInterfaceRemoveNVPR(glInterface.get()));
159 if (!glInterface) {
160 return ContextInfo();
161 }
162 }
163 backendContext = reinterpret_cast<GrBackendContext>(glInterface.get());
164 glCtx->makeCurrent();
djsollene4545212014-11-13 11:12:41 -0800165 break;
jvanvertha50e17a2015-08-12 12:19:36 -0700166#ifdef SK_VULKAN
bsalomondc0fcd42016-04-11 14:21:33 -0700167 case kVulkan_GrBackend:
168 SkASSERT(kVulkan_ContextType == type);
169 if ((kEnableNVPR_ContextOptions & options) ||
170 (kRequireSRGBSupport_ContextOptions & options)) {
171 return ContextInfo();
172 }
173 vkBackend.reset(GrVkBackendContext::Create());
174 if (!vkBackend) {
175 return ContextInfo();
176 }
177 backendContext = reinterpret_cast<GrBackendContext>(vkBackend.get());
178 // There is some bug (either in Skia or the NV Vulkan driver) where VkDevice
179 // destruction will hang occaisonally. For some reason having an existing GL
180 // context fixes this.
181 if (!fSentinelGLContext) {
182 fSentinelGLContext.reset(CreatePlatformGLTestContext(kGL_GrGLStandard));
183 if (!fSentinelGLContext) {
184 fSentinelGLContext.reset(CreatePlatformGLTestContext(kGLES_GrGLStandard));
185 }
186 }
187 break;
jvanvertha50e17a2015-08-12 12:19:36 -0700188#endif
bsalomondc0fcd42016-04-11 14:21:33 -0700189 default:
190 return ContextInfo();
191 }
192
193 grCtx.reset(GrContext::Create(backend, backendContext, fGlobalOptions));
djsollene4545212014-11-13 11:12:41 -0800194 if (!grCtx.get()) {
kkinnunen34058002016-01-06 23:49:30 -0800195 return ContextInfo();
djsollene4545212014-11-13 11:12:41 -0800196 }
bsalomon85b4b532016-04-05 11:06:27 -0700197 if (kEnableNVPR_ContextOptions & options) {
kkinnunencfe62e32015-07-01 02:58:50 -0700198 if (!grCtx->caps()->shaderCaps()->pathRenderingSupport()) {
kkinnunen34058002016-01-06 23:49:30 -0800199 return ContextInfo();
kkinnunencfe62e32015-07-01 02:58:50 -0700200 }
201 }
bsalomon85b4b532016-04-05 11:06:27 -0700202 if (kRequireSRGBSupport_ContextOptions & options) {
brianosman61d3b082016-03-30 11:19:36 -0700203 if (!grCtx->caps()->srgbSupport()) {
204 return ContextInfo();
205 }
206 }
kkinnunencfe62e32015-07-01 02:58:50 -0700207
kkinnunen34058002016-01-06 23:49:30 -0800208 Context& context = fContexts.push_back();
mtklein18300a32016-03-16 13:53:35 -0700209 context.fGLContext = glCtx.release();
kkinnunen34058002016-01-06 23:49:30 -0800210 context.fGrContext = SkRef(grCtx.get());
211 context.fType = type;
212 context.fOptions = options;
bsalomondc0fcd42016-04-11 14:21:33 -0700213 context.fAbandoned = false;
kkinnunen34058002016-01-06 23:49:30 -0800214 return ContextInfo(context.fGrContext, context.fGLContext);
djsollene4545212014-11-13 11:12:41 -0800215}
bsalomon3724e572016-03-30 18:56:19 -0700216} // namespace sk_gpu_test