| Index: tools/gpu/GrContextFactory.cpp
|
| diff --git a/tools/gpu/GrContextFactory.cpp b/tools/gpu/GrContextFactory.cpp
|
| index f54aa90c6c6dcdbb00c35a551089c434d9da8a67..651f3fcde27a81d19ca46bdbf442bcf4c1eb6b2b 100755
|
| --- a/tools/gpu/GrContextFactory.cpp
|
| +++ b/tools/gpu/GrContextFactory.cpp
|
| @@ -43,33 +43,42 @@ void GrContextFactory::destroyContexts() {
|
| context.fGLContext->makeCurrent();
|
| }
|
| if (!context.fGrContext->unique()) {
|
| - context.fGrContext->abandonContext();
|
| + context.fGrContext->releaseResourcesAndAbandonContext();
|
| + context.fAbandoned = true;
|
| }
|
| context.fGrContext->unref();
|
| - delete(context.fGLContext);
|
| + delete context.fGLContext;
|
| }
|
| fContexts.reset();
|
| }
|
|
|
| void GrContextFactory::abandonContexts() {
|
| for (Context& context : fContexts) {
|
| - if (context.fGLContext) {
|
| - context.fGLContext->makeCurrent();
|
| - context.fGLContext->testAbandon();
|
| - delete(context.fGLContext);
|
| - context.fGLContext = nullptr;
|
| + if (!context.fAbandoned) {
|
| + if (context.fGLContext) {
|
| + context.fGLContext->makeCurrent();
|
| + context.fGLContext->testAbandon();
|
| + delete(context.fGLContext);
|
| + context.fGLContext = nullptr;
|
| + }
|
| + context.fGrContext->abandonContext();
|
| + context.fAbandoned = true;
|
| }
|
| - context.fGrContext->abandonContext();
|
| }
|
| }
|
|
|
| void GrContextFactory::releaseResourcesAndAbandonContexts() {
|
| for (Context& context : fContexts) {
|
| - if (context.fGLContext) {
|
| - context.fGLContext->makeCurrent();
|
| + if (!context.fAbandoned) {
|
| + if (context.fGLContext) {
|
| + context.fGLContext->makeCurrent();
|
| + }
|
| context.fGrContext->releaseResourcesAndAbandonContext();
|
| - delete(context.fGLContext);
|
| - context.fGLContext = nullptr;
|
| + context.fAbandoned = true;
|
| + if (context.fGLContext) {
|
| + delete context.fGLContext;
|
| + context.fGLContext = nullptr;
|
| + }
|
| }
|
| }
|
| }
|
| @@ -85,78 +94,103 @@ const GrContextFactory::ContextType GrContextFactory::kNativeGL_ContextType =
|
| ContextInfo GrContextFactory::getContextInfo(ContextType type, ContextOptions options) {
|
| for (int i = 0; i < fContexts.count(); ++i) {
|
| Context& context = fContexts[i];
|
| - if (!context.fGLContext) {
|
| - continue;
|
| - }
|
| if (context.fType == type &&
|
| - context.fOptions == options) {
|
| - context.fGLContext->makeCurrent();
|
| + context.fOptions == options &&
|
| + !context.fAbandoned) {
|
| + if (context.fGLContext) {
|
| + context.fGLContext->makeCurrent();
|
| + }
|
| return ContextInfo(context.fGrContext, context.fGLContext);
|
| }
|
| }
|
| SkAutoTDelete<GLTestContext> glCtx;
|
| - SkAutoTUnref<GrContext> grCtx;
|
| - 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;
|
| + sk_sp<GrContext> grCtx;
|
| + GrBackendContext backendContext = 0;
|
| + sk_sp<const GrGLInterface> glInterface;
|
| +#ifdef SK_VULKAN
|
| + sk_sp<const GrVkBackendContext> vkBackend;
|
| #endif
|
| - case kANGLE_GL_ContextType:
|
| - glCtx.reset(CreateANGLEOpenGLGLTestContext());
|
| - break;
|
| + 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;
|
| + case kCommandBuffer_ContextType:
|
| + glCtx.reset(CommandBufferGLTestContext::Create());
|
| + break;
|
| #endif
|
| #if SK_MESA
|
| - case kMESA_ContextType:
|
| - glCtx.reset(CreateMesaGLTestContext());
|
| - break;
|
| + case kMESA_ContextType:
|
| + glCtx.reset(CreateMesaGLTestContext());
|
| + break;
|
| #endif
|
| - case kNullGL_ContextType:
|
| - glCtx.reset(CreateNullGLTestContext());
|
| + 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;
|
| - case kDebugGL_ContextType:
|
| - glCtx.reset(CreateDebugGLTestContext());
|
| +#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;
|
| - }
|
| - if (nullptr == glCtx.get()) {
|
| - return ContextInfo();
|
| - }
|
| -
|
| - SkASSERT(glCtx->isValid());
|
| -
|
| - // Block NVPR from non-NVPR types.
|
| - SkAutoTUnref<const GrGLInterface> glInterface(SkRef(glCtx->gl()));
|
| - if (!(kEnableNVPR_ContextOptions & options)) {
|
| - glInterface.reset(GrGLInterfaceRemoveNVPR(glInterface));
|
| - if (!glInterface) {
|
| +#endif
|
| + default:
|
| return ContextInfo();
|
| - }
|
| }
|
|
|
| - glCtx->makeCurrent();
|
| -#ifdef SK_VULKAN
|
| - if (kEnableNVPR_ContextOptions & options) {
|
| - return ContextInfo();
|
| - } else {
|
| - GrBackendContext p3dctx = reinterpret_cast<GrBackendContext>(GrVkBackendContext::Create());
|
| - grCtx.reset(GrContext::Create(kVulkan_GrBackend, p3dctx, fGlobalOptions));
|
| - }
|
| -#else
|
| - GrBackendContext p3dctx = reinterpret_cast<GrBackendContext>(glInterface.get());
|
| - grCtx.reset(GrContext::Create(kOpenGL_GrBackend, p3dctx, fGlobalOptions));
|
| -#endif
|
| + grCtx.reset(GrContext::Create(backend, backendContext, fGlobalOptions));
|
| if (!grCtx.get()) {
|
| return ContextInfo();
|
| }
|
| @@ -176,6 +210,7 @@ ContextInfo GrContextFactory::getContextInfo(ContextType type, ContextOptions op
|
| context.fGrContext = SkRef(grCtx.get());
|
| context.fType = type;
|
| context.fOptions = options;
|
| + context.fAbandoned = false;
|
| return ContextInfo(context.fGrContext, context.fGLContext);
|
| }
|
| } // namespace sk_gpu_test
|
|
|