Home | History | Annotate | Download | only in gpu
      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