blob: 79489f4590a0324b208c98159dad9d835cc74195 [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
mtklein605d9522016-09-21 14:01:32 -070015#include "gl/command_buffer/GLTestContext_command_buffer.h"
bsalomon273c0f52016-03-31 10:59:06 -070016#include "gl/debug/DebugGLTestContext.h"
djsollene4545212014-11-13 11:12:41 -080017#if SK_MESA
bsalomon273c0f52016-03-31 10:59:06 -070018 #include "gl/mesa/GLTestContext_mesa.h"
djsollene4545212014-11-13 11:12:41 -080019#endif
djsollen7e731082016-06-09 13:07:13 -070020#ifdef SK_VULKAN
bsalomon18a2f9d2016-05-11 10:09:18 -070021#include "vk/VkTestContext.h"
bsalomon7c62b472016-04-01 07:42:05 -070022#endif
bsalomon273c0f52016-03-31 10:59:06 -070023#include "gl/null/NullGLTestContext.h"
kkinnunencfe62e32015-07-01 02:58:50 -070024#include "gl/GrGLGpu.h"
25#include "GrCaps.h"
djsollene4545212014-11-13 11:12:41 -080026
bsalomon3724e572016-03-30 18:56:19 -070027namespace sk_gpu_test {
kkinnunen34058002016-01-06 23:49:30 -080028GrContextFactory::GrContextFactory() { }
29
30GrContextFactory::GrContextFactory(const GrContextOptions& opts)
31 : fGlobalOptions(opts) {
csmartdalton6270e552016-09-13 10:41:49 -070032 // In this factory, instanced rendering is specified with ContextOptions::kUseInstanced.
csmartdaltone0d36292016-07-29 08:14:20 -070033 SkASSERT(!fGlobalOptions.fEnableInstancedRendering);
kkinnunen34058002016-01-06 23:49:30 -080034}
35
36GrContextFactory::~GrContextFactory() {
37 this->destroyContexts();
38}
39
40void GrContextFactory::destroyContexts() {
41 for (Context& context : fContexts) {
bsalomon18a2f9d2016-05-11 10:09:18 -070042 if (context.fTestContext) {
43 context.fTestContext->makeCurrent();
kkinnunen34058002016-01-06 23:49:30 -080044 }
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();
bsalomon18a2f9d2016-05-11 10:09:18 -070050 delete context.fTestContext;
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) {
bsalomon18a2f9d2016-05-11 10:09:18 -070058 if (context.fTestContext) {
59 context.fTestContext->makeCurrent();
60 context.fTestContext->testAbandon();
61 delete(context.fTestContext);
62 context.fTestContext = nullptr;
bsalomondc0fcd42016-04-11 14:21:33 -070063 }
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) {
bsalomon18a2f9d2016-05-11 10:09:18 -070073 if (context.fTestContext) {
74 context.fTestContext->makeCurrent();
bsalomondc0fcd42016-04-11 14:21:33 -070075 }
bsalomon6e2aad42016-04-01 11:54:31 -070076 context.fGrContext->releaseResourcesAndAbandonContext();
bsalomondc0fcd42016-04-11 14:21:33 -070077 context.fAbandoned = true;
bsalomon18a2f9d2016-05-11 10:09:18 -070078 if (context.fTestContext) {
79 delete context.fTestContext;
80 context.fTestContext = nullptr;
bsalomondc0fcd42016-04-11 14:21:33 -070081 }
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) {
bsalomon18a2f9d2016-05-11 10:09:18 -0700100 context.fTestContext->makeCurrent();
101 return ContextInfo(context.fBackend, context.fTestContext, context.fGrContext);
djsollene4545212014-11-13 11:12:41 -0800102 }
103 }
Ben Wagner145dbcd2016-11-03 14:40:50 -0400104 std::unique_ptr<TestContext> testCtx;
bsalomondc0fcd42016-04-11 14:21:33 -0700105 sk_sp<GrContext> grCtx;
106 GrBackendContext backendContext = 0;
107 sk_sp<const GrGLInterface> glInterface;
bsalomondc0fcd42016-04-11 14:21:33 -0700108 GrBackend backend = ContextTypeBackend(type);
109 switch (backend) {
bsalomon18a2f9d2016-05-11 10:09:18 -0700110 case kOpenGL_GrBackend: {
111 GLTestContext* glCtx;
bsalomondc0fcd42016-04-11 14:21:33 -0700112 switch (type) {
113 case kGL_ContextType:
bsalomon18a2f9d2016-05-11 10:09:18 -0700114 glCtx = CreatePlatformGLTestContext(kGL_GrGLStandard);
bsalomondc0fcd42016-04-11 14:21:33 -0700115 break;
116 case kGLES_ContextType:
bsalomon18a2f9d2016-05-11 10:09:18 -0700117 glCtx = CreatePlatformGLTestContext(kGLES_GrGLStandard);
bsalomondc0fcd42016-04-11 14:21:33 -0700118 break;
119#if SK_ANGLE
bsalomon11abd8d2016-10-14 08:13:48 -0700120 case kANGLE_D3D9_ES2_ContextType:
121 glCtx = CreateANGLETestContext(ANGLEBackend::kD3D9, ANGLEContextVersion::kES2);
bsalomondc0fcd42016-04-11 14:21:33 -0700122 break;
bsalomon11abd8d2016-10-14 08:13:48 -0700123 case kANGLE_D3D11_ES2_ContextType:
124 glCtx = CreateANGLETestContext(ANGLEBackend::kD3D11,
125 ANGLEContextVersion::kES2);
126 break;
127 case kANGLE_D3D11_ES3_ContextType:
128 glCtx = CreateANGLETestContext(ANGLEBackend::kD3D11,
129 ANGLEContextVersion::kES3);
130 break;
131 case kANGLE_GL_ES2_ContextType:
132 glCtx = CreateANGLETestContext(ANGLEBackend::kOpenGL,
133 ANGLEContextVersion::kES2);
134 break;
135 case kANGLE_GL_ES3_ContextType:
136 glCtx = CreateANGLETestContext(ANGLEBackend::kOpenGL,
137 ANGLEContextVersion::kES3);
bsalomondc0fcd42016-04-11 14:21:33 -0700138 break;
djsollene4545212014-11-13 11:12:41 -0800139#endif
bsalomondc0fcd42016-04-11 14:21:33 -0700140 case kCommandBuffer_ContextType:
bsalomon18a2f9d2016-05-11 10:09:18 -0700141 glCtx = CommandBufferGLTestContext::Create();
bsalomondc0fcd42016-04-11 14:21:33 -0700142 break;
kkinnunen3e980c32015-12-23 01:33:00 -0800143#if SK_MESA
bsalomondc0fcd42016-04-11 14:21:33 -0700144 case kMESA_ContextType:
bsalomon18a2f9d2016-05-11 10:09:18 -0700145 glCtx = CreateMesaGLTestContext();
bsalomondc0fcd42016-04-11 14:21:33 -0700146 break;
djsollene4545212014-11-13 11:12:41 -0800147#endif
bsalomondc0fcd42016-04-11 14:21:33 -0700148 case kNullGL_ContextType:
csmartdalton6270e552016-09-13 10:41:49 -0700149 glCtx = CreateNullGLTestContext(ContextOptions::kEnableNVPR & options);
bsalomondc0fcd42016-04-11 14:21:33 -0700150 break;
151 case kDebugGL_ContextType:
bsalomon18a2f9d2016-05-11 10:09:18 -0700152 glCtx = CreateDebugGLTestContext();
bsalomondc0fcd42016-04-11 14:21:33 -0700153 break;
154 default:
155 return ContextInfo();
156 }
bsalomon18a2f9d2016-05-11 10:09:18 -0700157 if (!glCtx) {
bsalomondc0fcd42016-04-11 14:21:33 -0700158 return ContextInfo();
159 }
bsalomon18a2f9d2016-05-11 10:09:18 -0700160 testCtx.reset(glCtx);
bsalomondc0fcd42016-04-11 14:21:33 -0700161 glInterface.reset(SkRef(glCtx->gl()));
csmartdaltone0d36292016-07-29 08:14:20 -0700162 // Block NVPR from non-NVPR types. We don't block NVPR from contexts that will use
163 // instanced rendering because that would prevent us from testing mixed samples.
csmartdalton6270e552016-09-13 10:41:49 -0700164 if (!((ContextOptions::kEnableNVPR | ContextOptions::kUseInstanced) & options)) {
bsalomondc0fcd42016-04-11 14:21:33 -0700165 glInterface.reset(GrGLInterfaceRemoveNVPR(glInterface.get()));
166 if (!glInterface) {
167 return ContextInfo();
168 }
169 }
170 backendContext = reinterpret_cast<GrBackendContext>(glInterface.get());
djsollene4545212014-11-13 11:12:41 -0800171 break;
bsalomon18a2f9d2016-05-11 10:09:18 -0700172 }
jvanvertha50e17a2015-08-12 12:19:36 -0700173#ifdef SK_VULKAN
bsalomondc0fcd42016-04-11 14:21:33 -0700174 case kVulkan_GrBackend:
175 SkASSERT(kVulkan_ContextType == type);
csmartdalton6270e552016-09-13 10:41:49 -0700176 if (ContextOptions::kEnableNVPR & options) {
bsalomondc0fcd42016-04-11 14:21:33 -0700177 return ContextInfo();
178 }
bsalomon18a2f9d2016-05-11 10:09:18 -0700179 testCtx.reset(CreatePlatformVkTestContext());
180 if (!testCtx) {
bsalomondc0fcd42016-04-11 14:21:33 -0700181 return ContextInfo();
182 }
bsalomon18a2f9d2016-05-11 10:09:18 -0700183
bsalomondc0fcd42016-04-11 14:21:33 -0700184 // There is some bug (either in Skia or the NV Vulkan driver) where VkDevice
185 // destruction will hang occaisonally. For some reason having an existing GL
186 // context fixes this.
187 if (!fSentinelGLContext) {
188 fSentinelGLContext.reset(CreatePlatformGLTestContext(kGL_GrGLStandard));
189 if (!fSentinelGLContext) {
190 fSentinelGLContext.reset(CreatePlatformGLTestContext(kGLES_GrGLStandard));
191 }
192 }
bsalomon18a2f9d2016-05-11 10:09:18 -0700193 backendContext = testCtx->backendContext();
bsalomondc0fcd42016-04-11 14:21:33 -0700194 break;
jvanvertha50e17a2015-08-12 12:19:36 -0700195#endif
bsalomondc0fcd42016-04-11 14:21:33 -0700196 default:
197 return ContextInfo();
198 }
bsalomon18a2f9d2016-05-11 10:09:18 -0700199 testCtx->makeCurrent();
200 SkASSERT(testCtx && testCtx->backend() == backend);
csmartdaltone0d36292016-07-29 08:14:20 -0700201 GrContextOptions grOptions = fGlobalOptions;
csmartdalton6270e552016-09-13 10:41:49 -0700202 if (ContextOptions::kUseInstanced & options) {
csmartdaltone0d36292016-07-29 08:14:20 -0700203 grOptions.fEnableInstancedRendering = true;
204 }
205 grCtx.reset(GrContext::Create(backend, backendContext, grOptions));
djsollene4545212014-11-13 11:12:41 -0800206 if (!grCtx.get()) {
kkinnunen34058002016-01-06 23:49:30 -0800207 return ContextInfo();
djsollene4545212014-11-13 11:12:41 -0800208 }
csmartdalton6270e552016-09-13 10:41:49 -0700209 if (ContextOptions::kEnableNVPR & options) {
kkinnunencfe62e32015-07-01 02:58:50 -0700210 if (!grCtx->caps()->shaderCaps()->pathRenderingSupport()) {
kkinnunen34058002016-01-06 23:49:30 -0800211 return ContextInfo();
kkinnunencfe62e32015-07-01 02:58:50 -0700212 }
213 }
csmartdalton6270e552016-09-13 10:41:49 -0700214 if (ContextOptions::kUseInstanced & options) {
csmartdaltone0d36292016-07-29 08:14:20 -0700215 if (GrCaps::InstancedSupport::kNone == grCtx->caps()->instancedSupport()) {
216 return ContextInfo();
217 }
218 }
csmartdalton6270e552016-09-13 10:41:49 -0700219 if (ContextOptions::kRequireSRGBSupport & options) {
brianosman61d3b082016-03-30 11:19:36 -0700220 if (!grCtx->caps()->srgbSupport()) {
221 return ContextInfo();
222 }
223 }
kkinnunencfe62e32015-07-01 02:58:50 -0700224
kkinnunen34058002016-01-06 23:49:30 -0800225 Context& context = fContexts.push_back();
bsalomon18a2f9d2016-05-11 10:09:18 -0700226 context.fBackend = backend;
227 context.fTestContext = testCtx.release();
kkinnunen34058002016-01-06 23:49:30 -0800228 context.fGrContext = SkRef(grCtx.get());
229 context.fType = type;
230 context.fOptions = options;
bsalomondc0fcd42016-04-11 14:21:33 -0700231 context.fAbandoned = false;
bsalomon18a2f9d2016-05-11 10:09:18 -0700232 return ContextInfo(context.fBackend, context.fTestContext, context.fGrContext);
djsollene4545212014-11-13 11:12:41 -0800233}
bsalomon3724e572016-03-30 18:56:19 -0700234} // namespace sk_gpu_test