GrContextFactory.h revision dabdd9e71df4619db0260b9091c9bcc0d57b0a34
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 */
31class GrContextFactory  : GrNoncopyable {
32public:
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
48    GrContextFactory() {
49    }
50
51    ~GrContextFactory() {
52        for (int i = 0; i < fContexts.count(); ++i) {
53            fContexts[i].fGrContext->unref();
54            fContexts[i].fGLContext->unref();
55        }
56    }
57
58    /**
59     * Get a GrContext initalized with a type of GL context.
60     */
61    GrContext* get(GLContextType type) {
62
63        for (int i = 0; i < fContexts.count(); ++i) {
64            if (fContexts[i].fType == type) {
65                return fContexts[i].fGrContext;
66            }
67        }
68        SkAutoTUnref<SkGLContext> glCtx;
69        SkAutoTUnref<GrContext> grCtx;
70        switch (type) {
71            case kNative_GLContextType:
72                glCtx.reset(SkNEW(SkNativeGLContext));
73                break;
74#ifdef SK_ANGLE
75            case kANGLE_GLContextType:
76                glCtx.reset(SkNEW(SkANGLEGLContext));
77                break;
78#endif
79#ifdef SK_MESA
80            case kMESA_GLContextType:
81                glCtx.reset(SkNEW(SkMesaGLContext));
82                break;
83#endif
84            case kNull_GLContextType:
85                glCtx.reset(SkNEW(SkNullGLContext));
86                break;
87            case kDebug_GLContextType:
88                glCtx.reset(SkNEW(SkDebugGLContext));
89                break;
90        }
91        static const int kBogusSize = 1;
92        if (!glCtx.get()) {
93            return NULL;
94        }
95        if (!glCtx.get()->init(kBogusSize, kBogusSize)) {
96            return NULL;
97        }
98        GrPlatform3DContext p3dctx =
99            reinterpret_cast<GrPlatform3DContext>(glCtx.get()->gl());
100        grCtx.reset(GrContext::Create(kOpenGL_Shaders_GrEngine, p3dctx));
101        if (!grCtx.get()) {
102            return NULL;
103        }
104        GPUContext& ctx = fContexts.push_back();
105        ctx.fGLContext = glCtx.get();
106        ctx.fGLContext->ref();
107        ctx.fGrContext = grCtx.get();
108        ctx.fGrContext->ref();
109        ctx.fType = type;
110        return ctx.fGrContext;
111    }
112
113    // Returns the GLContext of the given type. If it has not been created yet,
114    // NULL is returned instead.
115    SkGLContext* getGLContext(GLContextType type) {
116        for (int i = 0; i < fContexts.count(); ++i) {
117            if (fContexts[i].fType == type) {
118                return fContexts[i].fGLContext;
119            }
120        }
121
122        return NULL;
123    }
124
125private:
126    struct GPUContext {
127        GLContextType             fType;
128        SkGLContext*              fGLContext;
129        GrContext*                fGrContext;
130    };
131    SkTArray<GPUContext, true> fContexts;
132};
133
134#endif
135