Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / include / gpu / GrContextFactory.h
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  * Gr and GL contexts to make them outlive the factory).
30  */
31 class GrContextFactory : SkNoncopyable {
32 public:
33     /**
34      * Types of GL contexts supported. For historical and testing reasons the native GrContext will
35      * not use "GL_NV_path_rendering" even when the driver supports it. There is a separate context
36      * type that does not remove NVPR support and which will fail when the driver does not support
37      * the extension.
38      */
39     enum GLContextType {
40       kNative_GLContextType,
41 #if SK_ANGLE
42       kANGLE_GLContextType,
43 #endif
44 #if SK_MESA
45       kMESA_GLContextType,
46 #endif
47       /** Similar to kNative but does not filter NVPR. It will fail if the GL driver does not
48           support NVPR */
49       kNVPR_GLContextType,
50       kNull_GLContextType,
51       kDebug_GLContextType,
52
53       kLastGLContextType = kDebug_GLContextType
54     };
55
56     static const int kGLContextTypeCnt = kLastGLContextType + 1;
57
58     static bool IsRenderingGLContext(GLContextType type) {
59         switch (type) {
60             case kNull_GLContextType:
61             case kDebug_GLContextType:
62                 return false;
63             default:
64                 return true;
65         }
66     }
67
68     static const char* GLContextTypeName(GLContextType type) {
69         switch (type) {
70             case kNative_GLContextType:
71                 return "native";
72             case kNull_GLContextType:
73                 return "null";
74 #if SK_ANGLE
75             case kANGLE_GLContextType:
76                 return "angle";
77 #endif
78 #if SK_MESA
79             case kMESA_GLContextType:
80                 return "mesa";
81 #endif
82             case kNVPR_GLContextType:
83                 return "nvpr";
84             case kDebug_GLContextType:
85                 return "debug";
86             default:
87                 SkFAIL("Unknown GL Context type.");
88         }
89     }
90
91     GrContextFactory() {
92     }
93
94     ~GrContextFactory() { this->destroyContexts(); }
95
96     void destroyContexts() {
97         for (int i = 0; i < fContexts.count(); ++i) {
98             fContexts[i].fGLContext->makeCurrent();
99             fContexts[i].fGrContext->unref();
100             fContexts[i].fGLContext->unref();
101         }
102         fContexts.reset();
103     }
104
105     /**
106      * Get a GrContext initialized with a type of GL context. It also makes the GL context current.
107      */
108     GrContext* get(GLContextType type) {
109
110         for (int i = 0; i < fContexts.count(); ++i) {
111             if (fContexts[i].fType == type) {
112                 fContexts[i].fGLContext->makeCurrent();
113                 return fContexts[i].fGrContext;
114             }
115         }
116         SkAutoTUnref<SkGLContextHelper> glCtx;
117         SkAutoTUnref<GrContext> grCtx;
118         switch (type) {
119             case kNVPR_GLContextType: // fallthru
120             case kNative_GLContextType:
121                 glCtx.reset(SkNEW(SkNativeGLContext));
122                 break;
123 #ifdef SK_ANGLE
124             case kANGLE_GLContextType:
125                 glCtx.reset(SkNEW(SkANGLEGLContext));
126                 break;
127 #endif
128 #ifdef SK_MESA
129             case kMESA_GLContextType:
130                 glCtx.reset(SkNEW(SkMesaGLContext));
131                 break;
132 #endif
133             case kNull_GLContextType:
134                 glCtx.reset(SkNEW(SkNullGLContext));
135                 break;
136             case kDebug_GLContextType:
137                 glCtx.reset(SkNEW(SkDebugGLContext));
138                 break;
139         }
140         static const int kBogusSize = 1;
141         if (!glCtx.get()) {
142             return NULL;
143         }
144         if (!glCtx.get()->init(kBogusSize, kBogusSize)) {
145             return NULL;
146         }
147
148         // Ensure NVPR is available for the NVPR type and block it from other types.
149         SkAutoTUnref<const GrGLInterface> glInterface(SkRef(glCtx.get()->gl()));
150         if (kNVPR_GLContextType == type) {
151             if (!glInterface->hasExtension("GL_NV_path_rendering")) {
152                 return NULL;
153             }
154         } else {
155             glInterface.reset(GrGLInterfaceRemoveNVPR(glInterface));
156             if (!glInterface) {
157                 return NULL;
158             }
159         }
160
161         glCtx->makeCurrent();
162         GrBackendContext p3dctx = reinterpret_cast<GrBackendContext>(glInterface.get());
163         grCtx.reset(GrContext::Create(kOpenGL_GrBackend, p3dctx));
164         if (!grCtx.get()) {
165             return NULL;
166         }
167         GPUContext& ctx = fContexts.push_back();
168         ctx.fGLContext = glCtx.get();
169         ctx.fGLContext->ref();
170         ctx.fGrContext = grCtx.get();
171         ctx.fGrContext->ref();
172         ctx.fType = type;
173         return ctx.fGrContext;
174     }
175
176     // Returns the GLContext of the given type. If it has not been created yet,
177     // NULL is returned instead.
178     SkGLContextHelper* getGLContext(GLContextType type) {
179         for (int i = 0; i < fContexts.count(); ++i) {
180             if (fContexts[i].fType == type) {
181                 return fContexts[i].fGLContext;
182             }
183         }
184
185         return NULL;
186     }
187
188 private:
189     struct GPUContext {
190         GLContextType             fType;
191         SkGLContextHelper*        fGLContext;
192         GrContext*                fGrContext;
193     };
194     SkTArray<GPUContext, true> fContexts;
195 };
196
197 #endif