ContextInfo GrContextFactory::getContextInfo(ContextType type, ContextOptions options) { for (int i = 0; i < fContexts.count(); ++i) { Context& context = fContexts[i]; if (context.fType == type && context.fOptions == options && !context.fAbandoned) { if (context.fGLContext) { context.fGLContext->makeCurrent(); } return ContextInfo(context.fGrContext, context.fGLContext); } } SkAutoTDelete<GLTestContext> glCtx; sk_sp<GrContext> grCtx; GrBackendContext backendContext = 0; sk_sp<const GrGLInterface> glInterface; #ifdef SK_VULKAN sk_sp<const GrVkBackendContext> vkBackend; #endif GrBackend backend = ContextTypeBackend(type); switch (backend) { case kOpenGL_GrBackend: switch (type) { case kGL_ContextType: glCtx.reset(CreatePlatformGLTestContext(kGL_GrGLStandard)); break; case kGLES_ContextType: glCtx.reset(CreatePlatformGLTestContext(kGLES_GrGLStandard)); break; #if SK_ANGLE # ifdef SK_BUILD_FOR_WIN case kANGLE_ContextType: glCtx.reset(CreateANGLEDirect3DGLTestContext()); break; # endif case kANGLE_GL_ContextType: glCtx.reset(CreateANGLEOpenGLGLTestContext()); break; #endif #if SK_COMMAND_BUFFER case kCommandBuffer_ContextType: glCtx.reset(CommandBufferGLTestContext::Create()); break; #endif #if SK_MESA case kMESA_ContextType: glCtx.reset(CreateMesaGLTestContext()); break; #endif case kNullGL_ContextType: glCtx.reset(CreateNullGLTestContext()); break; case kDebugGL_ContextType: glCtx.reset(CreateDebugGLTestContext()); break; default: return ContextInfo(); } if (nullptr == glCtx.get()) { return ContextInfo(); } glInterface.reset(SkRef(glCtx->gl())); // Block NVPR from non-NVPR types. if (!(kEnableNVPR_ContextOptions & options)) { glInterface.reset(GrGLInterfaceRemoveNVPR(glInterface.get())); if (!glInterface) { return ContextInfo(); } } backendContext = reinterpret_cast<GrBackendContext>(glInterface.get()); glCtx->makeCurrent(); break; #ifdef SK_VULKAN case kVulkan_GrBackend: SkASSERT(kVulkan_ContextType == type); if ((kEnableNVPR_ContextOptions & options) || (kRequireSRGBSupport_ContextOptions & options)) { return ContextInfo(); } vkBackend.reset(GrVkBackendContext::Create()); if (!vkBackend) { return ContextInfo(); } backendContext = reinterpret_cast<GrBackendContext>(vkBackend.get()); // There is some bug (either in Skia or the NV Vulkan driver) where VkDevice // destruction will hang occaisonally. For some reason having an existing GL // context fixes this. if (!fSentinelGLContext) { fSentinelGLContext.reset(CreatePlatformGLTestContext(kGL_GrGLStandard)); if (!fSentinelGLContext) { fSentinelGLContext.reset(CreatePlatformGLTestContext(kGLES_GrGLStandard)); } } break; #endif default: return ContextInfo(); } grCtx.reset(GrContext::Create(backend, backendContext, fGlobalOptions)); if (!grCtx.get()) { return ContextInfo(); } if (kEnableNVPR_ContextOptions & options) { if (!grCtx->caps()->shaderCaps()->pathRenderingSupport()) { return ContextInfo(); } } if (kRequireSRGBSupport_ContextOptions & options) { if (!grCtx->caps()->srgbSupport()) { return ContextInfo(); } } Context& context = fContexts.push_back(); context.fGLContext = glCtx.release(); context.fGrContext = SkRef(grCtx.get()); context.fType = type; context.fOptions = options; context.fAbandoned = false; return ContextInfo(context.fGrContext, context.fGLContext); }