1 2 /* 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" 10 11 #if SK_ANGLE 12 #include "gl/angle/SkANGLEGLContext.h" 13 #endif 14 #if SK_COMMAND_BUFFER 15 #include "gl/command_buffer/SkCommandBufferGLContext.h" 16 #endif 17 #include "gl/debug/SkDebugGLContext.h" 18 #if SK_MESA 19 #include "gl/mesa/SkMesaGLContext.h" 20 #endif 21 #include "gl/SkGLContext.h" 22 #include "gl/SkNullGLContext.h" 23 #include "gl/GrGLGpu.h" 24 #include "GrCaps.h" 25 26 GrContextFactory::GrContextFactory() { } 27 28 GrContextFactory::GrContextFactory(const GrContextOptions& opts) 29 : fGlobalOptions(opts) { 30 } 31 32 GrContextFactory::~GrContextFactory() { 33 this->destroyContexts(); 34 } 35 36 void GrContextFactory::destroyContexts() { 37 for (Context& context : fContexts) { 38 if (context.fGLContext) { 39 context.fGLContext->makeCurrent(); 40 } 41 if (!context.fGrContext->unique()) { 42 context.fGrContext->abandonContext(); 43 } 44 context.fGrContext->unref(); 45 delete(context.fGLContext); 46 } 47 fContexts.reset(); 48 } 49 50 void GrContextFactory::abandonContexts() { 51 for (Context& context : fContexts) { 52 if (context.fGLContext) { 53 context.fGLContext->makeCurrent(); 54 context.fGLContext->testAbandon(); 55 delete(context.fGLContext); 56 context.fGLContext = nullptr; 57 } 58 context.fGrContext->abandonContext(); 59 } 60 } 61 62 GrContextFactory::ContextInfo GrContextFactory::getContextInfo(GLContextType type, 63 GLContextOptions options) { 64 for (int i = 0; i < fContexts.count(); ++i) { 65 Context& context = fContexts[i]; 66 if (!context.fGLContext) { 67 continue; 68 } 69 if (context.fType == type && 70 context.fOptions == options) { 71 context.fGLContext->makeCurrent(); 72 return ContextInfo(context.fGrContext, context.fGLContext); 73 } 74 } 75 SkAutoTDelete<SkGLContext> glCtx; 76 SkAutoTUnref<GrContext> grCtx; 77 switch (type) { 78 case kNative_GLContextType: 79 glCtx.reset(SkCreatePlatformGLContext(kNone_GrGLStandard)); 80 break; 81 case kGL_GLContextType: 82 glCtx.reset(SkCreatePlatformGLContext(kGL_GrGLStandard)); 83 break; 84 case kGLES_GLContextType: 85 glCtx.reset(SkCreatePlatformGLContext(kGLES_GrGLStandard)); 86 break; 87 #if SK_ANGLE 88 #ifdef SK_BUILD_FOR_WIN 89 case kANGLE_GLContextType: 90 glCtx.reset(SkANGLEGLContext::CreateDirectX()); 91 break; 92 #endif 93 case kANGLE_GL_GLContextType: 94 glCtx.reset(SkANGLEGLContext::CreateOpenGL()); 95 break; 96 #endif 97 #if SK_COMMAND_BUFFER 98 case kCommandBufferES2_GLContextType: 99 glCtx.reset(SkCommandBufferGLContext::CreateES2()); 100 break; 101 case kCommandBufferES3_GLContextType: 102 glCtx.reset(SkCommandBufferGLContext::CreateES3()); 103 break; 104 #endif 105 #if SK_MESA 106 case kMESA_GLContextType: 107 glCtx.reset(SkMesaGLContext::Create()); 108 break; 109 #endif 110 case kNull_GLContextType: 111 glCtx.reset(SkNullGLContext::Create()); 112 break; 113 case kDebug_GLContextType: 114 glCtx.reset(SkDebugGLContext::Create()); 115 break; 116 } 117 if (nullptr == glCtx.get()) { 118 return ContextInfo(); 119 } 120 121 SkASSERT(glCtx->isValid()); 122 123 // Block NVPR from non-NVPR types. 124 SkAutoTUnref<const GrGLInterface> glInterface(SkRef(glCtx->gl())); 125 if (!(kEnableNVPR_GLContextOptions & options)) { 126 glInterface.reset(GrGLInterfaceRemoveNVPR(glInterface)); 127 if (!glInterface) { 128 return ContextInfo(); 129 } 130 } 131 132 glCtx->makeCurrent(); 133 GrBackendContext p3dctx = reinterpret_cast<GrBackendContext>(glInterface.get()); 134 #ifdef SK_VULKAN 135 grCtx.reset(GrContext::Create(kVulkan_GrBackend, p3dctx, fGlobalOptions)); 136 #else 137 grCtx.reset(GrContext::Create(kOpenGL_GrBackend, p3dctx, fGlobalOptions)); 138 #endif 139 if (!grCtx.get()) { 140 return ContextInfo(); 141 } 142 if (kEnableNVPR_GLContextOptions & options) { 143 if (!grCtx->caps()->shaderCaps()->pathRenderingSupport()) { 144 return ContextInfo(); 145 } 146 } 147 148 Context& context = fContexts.push_back(); 149 context.fGLContext = glCtx.detach(); 150 context.fGrContext = SkRef(grCtx.get()); 151 context.fType = type; 152 context.fOptions = options; 153 return ContextInfo(context.fGrContext, context.fGLContext); 154 } 155