• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 : public SkNoncopyable {
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 
IsRenderingGLContext(GLContextType type)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 
GLContextTypeName(GLContextType type)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 
GrContextFactory()83     GrContextFactory() {
84     }
85 
~GrContextFactory()86     ~GrContextFactory() { this->destroyContexts(); }
87 
destroyContexts()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      */
get(GLContextType type)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.
getGLContext(GLContextType type)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