blob: 2407da930aba3bb3f1fb93e9c53d9a33f8fe5bee [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
djsollen7e731082016-06-09 13:07:13 -070022#ifdef SK_VULKAN
bsalomon18a2f9d2016-05-11 10:09:18 -070023#include "vk/VkTestContext.h"
bsalomon7c62b472016-04-01 07:42:05 -070024#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) {
csmartdaltone0d36292016-07-29 08:14:20 -070034 // In this factory, instanced rendering is specified with kUseInstanced_ContextOptions.
35 SkASSERT(!fGlobalOptions.fEnableInstancedRendering);
kkinnunen34058002016-01-06 23:49:30 -080036}
37
38GrContextFactory::~GrContextFactory() {
39 this->destroyContexts();
40}
41
42void GrContextFactory::destroyContexts() {
43 for (Context& context : fContexts) {
bsalomon18a2f9d2016-05-11 10:09:18 -070044 if (context.fTestContext) {
45 context.fTestContext->makeCurrent();
kkinnunen34058002016-01-06 23:49:30 -080046 }
47 if (!context.fGrContext->unique()) {
bsalomondc0fcd42016-04-11 14:21:33 -070048 context.fGrContext->releaseResourcesAndAbandonContext();
49 context.fAbandoned = true;
kkinnunen34058002016-01-06 23:49:30 -080050 }
51 context.fGrContext->unref();
bsalomon18a2f9d2016-05-11 10:09:18 -070052 delete context.fTestContext;
kkinnunen34058002016-01-06 23:49:30 -080053 }
54 fContexts.reset();
55}
56
57void GrContextFactory::abandonContexts() {
58 for (Context& context : fContexts) {
bsalomondc0fcd42016-04-11 14:21:33 -070059 if (!context.fAbandoned) {
bsalomon18a2f9d2016-05-11 10:09:18 -070060 if (context.fTestContext) {
61 context.fTestContext->makeCurrent();
62 context.fTestContext->testAbandon();
63 delete(context.fTestContext);
64 context.fTestContext = nullptr;
bsalomondc0fcd42016-04-11 14:21:33 -070065 }
66 context.fGrContext->abandonContext();
67 context.fAbandoned = true;
kkinnunen34058002016-01-06 23:49:30 -080068 }
kkinnunen34058002016-01-06 23:49:30 -080069 }
70}
71
bsalomon6e2aad42016-04-01 11:54:31 -070072void GrContextFactory::releaseResourcesAndAbandonContexts() {
73 for (Context& context : fContexts) {
bsalomondc0fcd42016-04-11 14:21:33 -070074 if (!context.fAbandoned) {
bsalomon18a2f9d2016-05-11 10:09:18 -070075 if (context.fTestContext) {
76 context.fTestContext->makeCurrent();
bsalomondc0fcd42016-04-11 14:21:33 -070077 }
bsalomon6e2aad42016-04-01 11:54:31 -070078 context.fGrContext->releaseResourcesAndAbandonContext();
bsalomondc0fcd42016-04-11 14:21:33 -070079 context.fAbandoned = true;
bsalomon18a2f9d2016-05-11 10:09:18 -070080 if (context.fTestContext) {
81 delete context.fTestContext;
82 context.fTestContext = nullptr;
bsalomondc0fcd42016-04-11 14:21:33 -070083 }
bsalomon6e2aad42016-04-01 11:54:31 -070084 }
85 }
86}
87
bsalomon85b4b532016-04-05 11:06:27 -070088#if defined(SK_BUILD_FOR_UNIX) || defined(SK_BUILD_FOR_WIN) || defined(SK_BUILD_FOR_MAC)
89const GrContextFactory::ContextType GrContextFactory::kNativeGL_ContextType =
90 GrContextFactory::kGL_ContextType;
91#else
92const GrContextFactory::ContextType GrContextFactory::kNativeGL_ContextType =
93 GrContextFactory::kGLES_ContextType;
94#endif
95
bsalomonf2f1c172016-04-05 12:59:06 -070096ContextInfo GrContextFactory::getContextInfo(ContextType type, ContextOptions options) {
djsollene4545212014-11-13 11:12:41 -080097 for (int i = 0; i < fContexts.count(); ++i) {
kkinnunen34058002016-01-06 23:49:30 -080098 Context& context = fContexts[i];
kkinnunen34058002016-01-06 23:49:30 -080099 if (context.fType == type &&
bsalomondc0fcd42016-04-11 14:21:33 -0700100 context.fOptions == options &&
101 !context.fAbandoned) {
bsalomon18a2f9d2016-05-11 10:09:18 -0700102 context.fTestContext->makeCurrent();
103 return ContextInfo(context.fBackend, context.fTestContext, context.fGrContext);
djsollene4545212014-11-13 11:12:41 -0800104 }
105 }
bsalomon18a2f9d2016-05-11 10:09:18 -0700106 SkAutoTDelete<TestContext> testCtx;
bsalomondc0fcd42016-04-11 14:21:33 -0700107 sk_sp<GrContext> grCtx;
108 GrBackendContext backendContext = 0;
109 sk_sp<const GrGLInterface> glInterface;
bsalomondc0fcd42016-04-11 14:21:33 -0700110 GrBackend backend = ContextTypeBackend(type);
111 switch (backend) {
bsalomon18a2f9d2016-05-11 10:09:18 -0700112 case kOpenGL_GrBackend: {
113 GLTestContext* glCtx;
bsalomondc0fcd42016-04-11 14:21:33 -0700114 switch (type) {
115 case kGL_ContextType:
bsalomon18a2f9d2016-05-11 10:09:18 -0700116 glCtx = CreatePlatformGLTestContext(kGL_GrGLStandard);
bsalomondc0fcd42016-04-11 14:21:33 -0700117 break;
118 case kGLES_ContextType:
bsalomon18a2f9d2016-05-11 10:09:18 -0700119 glCtx = CreatePlatformGLTestContext(kGLES_GrGLStandard);
bsalomondc0fcd42016-04-11 14:21:33 -0700120 break;
121#if SK_ANGLE
122# ifdef SK_BUILD_FOR_WIN
123 case kANGLE_ContextType:
bsalomon18a2f9d2016-05-11 10:09:18 -0700124 glCtx = CreateANGLEDirect3DGLTestContext();
bsalomondc0fcd42016-04-11 14:21:33 -0700125 break;
126# endif
127 case kANGLE_GL_ContextType:
bsalomon18a2f9d2016-05-11 10:09:18 -0700128 glCtx = CreateANGLEOpenGLGLTestContext();
bsalomondc0fcd42016-04-11 14:21:33 -0700129 break;
djsollene4545212014-11-13 11:12:41 -0800130#endif
kkinnunen3e980c32015-12-23 01:33:00 -0800131#if SK_COMMAND_BUFFER
bsalomondc0fcd42016-04-11 14:21:33 -0700132 case kCommandBuffer_ContextType:
bsalomon18a2f9d2016-05-11 10:09:18 -0700133 glCtx = CommandBufferGLTestContext::Create();
bsalomondc0fcd42016-04-11 14:21:33 -0700134 break;
hendrikw885bf092015-08-27 10:38:39 -0700135#endif
kkinnunen3e980c32015-12-23 01:33:00 -0800136#if SK_MESA
bsalomondc0fcd42016-04-11 14:21:33 -0700137 case kMESA_ContextType:
bsalomon18a2f9d2016-05-11 10:09:18 -0700138 glCtx = CreateMesaGLTestContext();
bsalomondc0fcd42016-04-11 14:21:33 -0700139 break;
djsollene4545212014-11-13 11:12:41 -0800140#endif
bsalomondc0fcd42016-04-11 14:21:33 -0700141 case kNullGL_ContextType:
bsalomon18a2f9d2016-05-11 10:09:18 -0700142 glCtx = CreateNullGLTestContext(kEnableNVPR_ContextOptions & options);
bsalomondc0fcd42016-04-11 14:21:33 -0700143 break;
144 case kDebugGL_ContextType:
bsalomon18a2f9d2016-05-11 10:09:18 -0700145 glCtx = CreateDebugGLTestContext();
bsalomondc0fcd42016-04-11 14:21:33 -0700146 break;
147 default:
148 return ContextInfo();
149 }
bsalomon18a2f9d2016-05-11 10:09:18 -0700150 if (!glCtx) {
bsalomondc0fcd42016-04-11 14:21:33 -0700151 return ContextInfo();
152 }
bsalomon18a2f9d2016-05-11 10:09:18 -0700153 testCtx.reset(glCtx);
bsalomondc0fcd42016-04-11 14:21:33 -0700154 glInterface.reset(SkRef(glCtx->gl()));
csmartdaltone0d36292016-07-29 08:14:20 -0700155 // Block NVPR from non-NVPR types. We don't block NVPR from contexts that will use
156 // instanced rendering because that would prevent us from testing mixed samples.
157 if (!((kEnableNVPR_ContextOptions | kUseInstanced_ContextOptions) & options)) {
bsalomondc0fcd42016-04-11 14:21:33 -0700158 glInterface.reset(GrGLInterfaceRemoveNVPR(glInterface.get()));
159 if (!glInterface) {
160 return ContextInfo();
161 }
162 }
163 backendContext = reinterpret_cast<GrBackendContext>(glInterface.get());
djsollene4545212014-11-13 11:12:41 -0800164 break;
bsalomon18a2f9d2016-05-11 10:09:18 -0700165 }
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);
brianosmana56800a2016-05-23 10:11:07 -0700169 if (kEnableNVPR_ContextOptions & options) {
bsalomondc0fcd42016-04-11 14:21:33 -0700170 return ContextInfo();
171 }
bsalomon18a2f9d2016-05-11 10:09:18 -0700172 testCtx.reset(CreatePlatformVkTestContext());
173 if (!testCtx) {
bsalomondc0fcd42016-04-11 14:21:33 -0700174 return ContextInfo();
175 }
bsalomon18a2f9d2016-05-11 10:09:18 -0700176
bsalomondc0fcd42016-04-11 14:21:33 -0700177 // There is some bug (either in Skia or the NV Vulkan driver) where VkDevice
178 // destruction will hang occaisonally. For some reason having an existing GL
179 // context fixes this.
180 if (!fSentinelGLContext) {
181 fSentinelGLContext.reset(CreatePlatformGLTestContext(kGL_GrGLStandard));
182 if (!fSentinelGLContext) {
183 fSentinelGLContext.reset(CreatePlatformGLTestContext(kGLES_GrGLStandard));
184 }
185 }
bsalomon18a2f9d2016-05-11 10:09:18 -0700186 backendContext = testCtx->backendContext();
bsalomondc0fcd42016-04-11 14:21:33 -0700187 break;
jvanvertha50e17a2015-08-12 12:19:36 -0700188#endif
bsalomondc0fcd42016-04-11 14:21:33 -0700189 default:
190 return ContextInfo();
191 }
bsalomon18a2f9d2016-05-11 10:09:18 -0700192 testCtx->makeCurrent();
193 SkASSERT(testCtx && testCtx->backend() == backend);
csmartdaltone0d36292016-07-29 08:14:20 -0700194 GrContextOptions grOptions = fGlobalOptions;
195 if (kUseInstanced_ContextOptions & options) {
196 grOptions.fEnableInstancedRendering = true;
197 }
198 grCtx.reset(GrContext::Create(backend, backendContext, grOptions));
djsollene4545212014-11-13 11:12:41 -0800199 if (!grCtx.get()) {
kkinnunen34058002016-01-06 23:49:30 -0800200 return ContextInfo();
djsollene4545212014-11-13 11:12:41 -0800201 }
bsalomon85b4b532016-04-05 11:06:27 -0700202 if (kEnableNVPR_ContextOptions & options) {
kkinnunencfe62e32015-07-01 02:58:50 -0700203 if (!grCtx->caps()->shaderCaps()->pathRenderingSupport()) {
kkinnunen34058002016-01-06 23:49:30 -0800204 return ContextInfo();
kkinnunencfe62e32015-07-01 02:58:50 -0700205 }
206 }
csmartdaltone0d36292016-07-29 08:14:20 -0700207 if (kUseInstanced_ContextOptions & options) {
208 if (GrCaps::InstancedSupport::kNone == grCtx->caps()->instancedSupport()) {
209 return ContextInfo();
210 }
211 }
bsalomon85b4b532016-04-05 11:06:27 -0700212 if (kRequireSRGBSupport_ContextOptions & options) {
brianosman61d3b082016-03-30 11:19:36 -0700213 if (!grCtx->caps()->srgbSupport()) {
214 return ContextInfo();
215 }
216 }
kkinnunencfe62e32015-07-01 02:58:50 -0700217
kkinnunen34058002016-01-06 23:49:30 -0800218 Context& context = fContexts.push_back();
bsalomon18a2f9d2016-05-11 10:09:18 -0700219 context.fBackend = backend;
220 context.fTestContext = testCtx.release();
kkinnunen34058002016-01-06 23:49:30 -0800221 context.fGrContext = SkRef(grCtx.get());
222 context.fType = type;
223 context.fOptions = options;
bsalomondc0fcd42016-04-11 14:21:33 -0700224 context.fAbandoned = false;
bsalomon18a2f9d2016-05-11 10:09:18 -0700225 return ContextInfo(context.fBackend, context.fTestContext, context.fGrContext);
djsollene4545212014-11-13 11:12:41 -0800226}
bsalomon3724e572016-03-30 18:56:19 -0700227} // namespace sk_gpu_test