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 #if SK_ANGLE
     12     #include "gl/SkANGLEGLContext.h"
     13 #endif
     14 #include "gl/SkDebugGLContext.h"
     15 #if SK_MESA
     16     #include "gl/SkMesaGLContext.h"
     17 #endif
     18 #include "gl/SkNativeGLContext.h"
     19 #include "gl/SkNullGLContext.h"
     20 
     21 #include "GrContext.h"
     22 #include "SkTArray.h"
     23 
     24 /**
     25  * This is a simple class that is useful in test apps that use different
     26  * GrContexts backed by different types of GL contexts. It manages creating the
     27  * GL context and a GrContext that uses it. The GL/Gr contexts persist until the
     28  * factory is destroyed (though the caller can always grab a ref on the returned
     29  * GrContext to make it outlive the factory).
     30  */
     31 class GrContextFactory : GrNoncopyable {
     32 public:
     33     /**
     34      * Types of GL contexts supported.
     35      */
     36     enum GLContextType {
     37       kNative_GLContextType,
     38 #if SK_ANGLE
     39       kANGLE_GLContextType,
     40 #endif
     41 #if SK_MESA
     42       kMESA_GLContextType,
     43 #endif
     44       kNull_GLContextType,
     45       kDebug_GLContextType,
     46 
     47       kLastGLContextType = kDebug_GLContextType
     48     };
     49 
     50     static const int kGLContextTypeCnt = kLastGLContextType + 1;
     51 
     52     static bool IsRenderingGLContext(GLContextType type) {
     53         switch (type) {
     54             case kNull_GLContextType:
     55             case kDebug_GLContextType:
     56                 return false;
     57             default:
     58                 return true;
     59         }
     60     }
     61 
     62     static const char* GLContextTypeName(GLContextType type) {
     63         switch (type) {
     64             case kNative_GLContextType:
     65                 return "native";
     66             case kNull_GLContextType:
     67                 return "null";
     68 #if SK_ANGLE
     69             case kANGLE_GLContextType:
     70                 return "angle";
     71 #endif
     72 #if SK_MESA
     73             case kMESA_GLContextType:
     74                 return "mesa";
     75 #endif
     76             case kDebug_GLContextType:
     77                 return "debug";
     78             default:
     79                 GrCrash("Unknown GL Context type.");
     80         }
     81     }
     82 
     83     GrContextFactory() {
     84     }
     85 
     86     ~GrContextFactory() { this->destroyContexts(); }
     87 
     88     void destroyContexts() {
     89         for (int i = 0; i < fContexts.count(); ++i) {
     90             fContexts[i].fGrContext->unref();
     91             fContexts[i].fGLContext->unref();
     92         }
     93         fContexts.reset();
     94     }
     95 
     96     /**
     97      * Get a GrContext initialized with a type of GL context. It also makes the GL context current.
     98      */
     99     GrContext* get(GLContextType type) {
    100 
    101         for (int i = 0; i < fContexts.count(); ++i) {
    102             if (fContexts[i].fType == type) {
    103                 fContexts[i].fGLContext->makeCurrent();
    104                 return fContexts[i].fGrContext;
    105             }
    106         }
    107         SkAutoTUnref<SkGLContextHelper> glCtx;
    108         SkAutoTUnref<GrContext> grCtx;
    109         switch (type) {
    110             case kNative_GLContextType:
    111                 glCtx.reset(SkNEW(SkNativeGLContext));
    112                 break;
    113 #ifdef SK_ANGLE
    114             case kANGLE_GLContextType:
    115                 glCtx.reset(SkNEW(SkANGLEGLContext));
    116                 break;
    117 #endif
    118 #ifdef SK_MESA
    119             case kMESA_GLContextType:
    120                 glCtx.reset(SkNEW(SkMesaGLContext));
    121                 break;
    122 #endif
    123             case kNull_GLContextType:
    124                 glCtx.reset(SkNEW(SkNullGLContext));
    125                 break;
    126             case kDebug_GLContextType:
    127                 glCtx.reset(SkNEW(SkDebugGLContext));
    128                 break;
    129         }
    130         static const int kBogusSize = 1;
    131         if (!glCtx.get()) {
    132             return NULL;
    133         }
    134         if (!glCtx.get()->init(kBogusSize, kBogusSize)) {
    135             return NULL;
    136         }
    137         GrBackendContext p3dctx = reinterpret_cast<GrBackendContext>(glCtx.get()->gl());
    138         grCtx.reset(GrContext::Create(kOpenGL_GrBackend, p3dctx));
    139         if (!grCtx.get()) {
    140             return NULL;
    141         }
    142         GPUContext& ctx = fContexts.push_back();
    143         ctx.fGLContext = glCtx.get();
    144         ctx.fGLContext->ref();
    145         ctx.fGrContext = grCtx.get();
    146         ctx.fGrContext->ref();
    147         ctx.fType = type;
    148         return ctx.fGrContext;
    149     }
    150 
    151     // Returns the GLContext of the given type. If it has not been created yet,
    152     // NULL is returned instead.
    153     SkGLContextHelper* getGLContext(GLContextType type) {
    154         for (int i = 0; i < fContexts.count(); ++i) {
    155             if (fContexts[i].fType == type) {
    156                 return fContexts[i].fGLContext;
    157             }
    158         }
    159 
    160         return NULL;
    161     }
    162 
    163 private:
    164     struct GPUContext {
    165         GLContextType             fType;
    166         SkGLContextHelper*        fGLContext;
    167         GrContext*                fGrContext;
    168     };
    169     SkTArray<GPUContext, true> fContexts;
    170 };
    171 
    172 #endif
    173