Home | History | Annotate | Download | only in gpu
      1 /*
      2  * Copyright 2012 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #ifndef GrContextFactory_DEFINED
      9 #define GrContextFactory_DEFINED
     10 
     11 #include "GrContext.h"
     12 
     13 #include "gl/SkGLContext.h"
     14 #include "SkTArray.h"
     15 
     16 /**
     17  * This is a simple class that is useful in test apps that use different
     18  * GrContexts backed by different types of GL contexts. It manages creating the
     19  * GL context and a GrContext that uses it. The GL/Gr contexts persist until the
     20  * factory is destroyed (though the caller can always grab a ref on the returned
     21  * Gr and GL contexts to make them outlive the factory).
     22  */
     23 class GrContextFactory : SkNoncopyable {
     24 public:
     25     /**
     26      * Types of GL contexts supported. For historical and testing reasons the native GrContext will
     27      * not use "GL_NV_path_rendering" even when the driver supports it. There is a separate context
     28      * type that does not remove NVPR support and which will fail when the driver does not support
     29      * the extension.
     30      */
     31     enum GLContextType {
     32       kNative_GLContextType,
     33 #if SK_ANGLE
     34       kANGLE_GLContextType,
     35 #endif
     36 #if SK_MESA
     37       kMESA_GLContextType,
     38 #endif
     39       /** Similar to kNative but does not filter NVPR. It will fail if the GL driver does not
     40           support NVPR */
     41       kNVPR_GLContextType,
     42       kNull_GLContextType,
     43       kDebug_GLContextType,
     44 
     45       kLastGLContextType = kDebug_GLContextType
     46     };
     47 
     48     static const int kGLContextTypeCnt = kLastGLContextType + 1;
     49 
     50     static bool IsRenderingGLContext(GLContextType type) {
     51         switch (type) {
     52             case kNull_GLContextType:
     53             case kDebug_GLContextType:
     54                 return false;
     55             default:
     56                 return true;
     57         }
     58     }
     59 
     60     static const char* GLContextTypeName(GLContextType type) {
     61         switch (type) {
     62             case kNative_GLContextType:
     63                 return "native";
     64             case kNull_GLContextType:
     65                 return "null";
     66 #if SK_ANGLE
     67             case kANGLE_GLContextType:
     68                 return "angle";
     69 #endif
     70 #if SK_MESA
     71             case kMESA_GLContextType:
     72                 return "mesa";
     73 #endif
     74             case kNVPR_GLContextType:
     75                 return "nvpr";
     76             case kDebug_GLContextType:
     77                 return "debug";
     78             default:
     79                 SkFAIL("Unknown GL Context type.");
     80         }
     81     }
     82 
     83     explicit GrContextFactory(const GrContext::Options& opts) : fGlobalOptions(opts) { }
     84     GrContextFactory() { }
     85 
     86     ~GrContextFactory() { this->destroyContexts(); }
     87 
     88     void destroyContexts() {
     89         for (int i = 0; i < fContexts.count(); ++i) {
     90             if (fContexts[i].fGLContext) {  //  could be abandoned.
     91                 fContexts[i].fGLContext->makeCurrent();
     92             }
     93             fContexts[i].fGrContext->unref();
     94             if (fContexts[i].fGLContext) {
     95                 fContexts[i].fGLContext->unref();
     96             }
     97         }
     98         fContexts.reset();
     99     }
    100 
    101     void abandonContexts() {
    102         for (int i = 0; i < fContexts.count(); ++i) {
    103             if (fContexts[i].fGLContext) {
    104                 fContexts[i].fGLContext->testAbandon();
    105                 SkSafeSetNull(fContexts[i].fGLContext);
    106             }
    107             fContexts[i].fGrContext->abandonContext();
    108         }
    109     }
    110 
    111     /**
    112      * Get a GrContext initialized with a type of GL context. It also makes the GL context current.
    113      */
    114     GrContext* get(GLContextType type, GrGLStandard forcedGpuAPI = kNone_GrGLStandard);
    115 
    116 
    117     // Returns the GLContext of the given type. If it has not been created yet,
    118     // NULL is returned instead.
    119     SkGLContext* getGLContext(GLContextType type) {
    120         for (int i = 0; i < fContexts.count(); ++i) {
    121             if (fContexts[i].fType == type) {
    122                 return fContexts[i].fGLContext;
    123             }
    124         }
    125 
    126         return NULL;
    127     }
    128 
    129     const GrContext::Options& getGlobalOptions() const { return fGlobalOptions; }
    130 
    131 private:
    132     struct GPUContext {
    133         GLContextType             fType;
    134         SkGLContext*              fGLContext;
    135         GrContext*                fGrContext;
    136     };
    137     SkTArray<GPUContext, true>    fContexts;
    138     const GrContext::Options      fGlobalOptions;
    139 };
    140 
    141 #endif
    142