Upstream version 10.39.225.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     explicit GrContextFactory(const GrContext::Options& opts) : fGlobalOptions(opts) { }
92     GrContextFactory() { }
93
94     ~GrContextFactory() { this->destroyContexts(); }
95
96     void destroyContexts() {
97         for (int i = 0; i < fContexts.count(); ++i) {
98             if (fContexts[i].fGLContext) {  //  could be abandoned.
99                 fContexts[i].fGLContext->makeCurrent();
100             }
101             fContexts[i].fGrContext->unref();
102             if (fContexts[i].fGLContext) {
103                 fContexts[i].fGLContext->unref();
104             }
105         }
106         fContexts.reset();
107     }
108
109     void abandonContexts() {
110         for (int i = 0; i < fContexts.count(); ++i) {
111             if (fContexts[i].fGLContext) {
112                 fContexts[i].fGLContext->testAbandon();
113                 SkSafeSetNull(fContexts[i].fGLContext);
114             }
115             fContexts[i].fGrContext->abandonContext();
116         }
117     }
118
119     /**
120      * Get a GrContext initialized with a type of GL context. It also makes the GL context current.
121      */
122     GrContext* get(GLContextType type, GrGLStandard forcedGpuAPI = kNone_GrGLStandard) {
123         for (int i = 0; i < fContexts.count(); ++i) {
124             if (forcedGpuAPI != kNone_GrGLStandard &&
125                 forcedGpuAPI != fContexts[i].fGLContext->gl()->fStandard)
126                 continue;
127
128             if (fContexts[i].fType == type) {
129                 fContexts[i].fGLContext->makeCurrent();
130                 return fContexts[i].fGrContext;
131             }
132         }
133         SkAutoTUnref<SkGLContextHelper> glCtx;
134         SkAutoTUnref<GrContext> grCtx;
135         switch (type) {
136             case kNVPR_GLContextType: // fallthru
137             case kNative_GLContextType:
138                 glCtx.reset(SkNEW(SkNativeGLContext));
139                 break;
140 #ifdef SK_ANGLE
141             case kANGLE_GLContextType:
142                 glCtx.reset(SkNEW(SkANGLEGLContext));
143                 break;
144 #endif
145 #ifdef SK_MESA
146             case kMESA_GLContextType:
147                 glCtx.reset(SkNEW(SkMesaGLContext));
148                 break;
149 #endif
150             case kNull_GLContextType:
151                 glCtx.reset(SkNEW(SkNullGLContext));
152                 break;
153             case kDebug_GLContextType:
154                 glCtx.reset(SkNEW(SkDebugGLContext));
155                 break;
156         }
157         static const int kBogusSize = 1;
158         if (!glCtx.get()) {
159             return NULL;
160         }
161         if (!glCtx.get()->init(forcedGpuAPI, kBogusSize, kBogusSize)) {
162             return NULL;
163         }
164
165         // Ensure NVPR is available for the NVPR type and block it from other types.
166         SkAutoTUnref<const GrGLInterface> glInterface(SkRef(glCtx.get()->gl()));
167         if (kNVPR_GLContextType == type) {
168             if (!glInterface->hasExtension("GL_NV_path_rendering")) {
169                 return NULL;
170             }
171         } else {
172             glInterface.reset(GrGLInterfaceRemoveNVPR(glInterface));
173             if (!glInterface) {
174                 return NULL;
175             }
176         }
177
178         glCtx->makeCurrent();
179         GrBackendContext p3dctx = reinterpret_cast<GrBackendContext>(glInterface.get());
180         grCtx.reset(GrContext::Create(kOpenGL_GrBackend, p3dctx, &fGlobalOptions));
181         if (!grCtx.get()) {
182             return NULL;
183         }
184         GPUContext& ctx = fContexts.push_back();
185         ctx.fGLContext = glCtx.get();
186         ctx.fGLContext->ref();
187         ctx.fGrContext = grCtx.get();
188         ctx.fGrContext->ref();
189         ctx.fType = type;
190         return ctx.fGrContext;
191     }
192
193     // Returns the GLContext of the given type. If it has not been created yet,
194     // NULL is returned instead.
195     SkGLContextHelper* getGLContext(GLContextType type) {
196         for (int i = 0; i < fContexts.count(); ++i) {
197             if (fContexts[i].fType == type) {
198                 return fContexts[i].fGLContext;
199             }
200         }
201
202         return NULL;
203     }
204
205     const GrContext::Options& getGlobalOptions() const { return fGlobalOptions; }
206
207 private:
208     struct GPUContext {
209         GLContextType             fType;
210         SkGLContextHelper*        fGLContext;
211         GrContext*                fGrContext;
212     };
213     SkTArray<GPUContext, true>    fContexts;
214     const GrContext::Options      fGlobalOptions;
215 };
216
217 #endif