1e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen/*
2e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen * Copyright 2012 Google Inc.
3e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen *
4e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen * Use of this source code is governed by a BSD-style license that can be
5e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen * found in the LICENSE file.
6e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen */
7e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen
8e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen#ifndef GrContextFactory_DEFINED
9e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen#define GrContextFactory_DEFINED
10e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen
11e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen#include "GrContext.h"
12e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen
13e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen#include "gl/SkGLContext.h"
14e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen#include "SkTArray.h"
15e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen
16e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen/**
17e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen * This is a simple class that is useful in test apps that use different
18e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen * GrContexts backed by different types of GL contexts. It manages creating the
19e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen * GL context and a GrContext that uses it. The GL/Gr contexts persist until the
20e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen * factory is destroyed (though the caller can always grab a ref on the returned
21e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen * Gr and GL contexts to make them outlive the factory).
22e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen */
23e4545210c950f98d9fa20f51bc1be6c5591534bddjsollenclass GrContextFactory : SkNoncopyable {
24e4545210c950f98d9fa20f51bc1be6c5591534bddjsollenpublic:
25e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen    /**
26e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen     * Types of GL contexts supported. For historical and testing reasons the native GrContext will
27e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen     * not use "GL_NV_path_rendering" even when the driver supports it. There is a separate context
28e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen     * type that does not remove NVPR support and which will fail when the driver does not support
29e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen     * the extension.
30e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen     */
31e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen    enum GLContextType {
32e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen      kNative_GLContextType,
33e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen#if SK_ANGLE
34e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen      kANGLE_GLContextType,
35e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen#endif
36e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen#if SK_MESA
37e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen      kMESA_GLContextType,
38e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen#endif
39e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen      /** Similar to kNative but does not filter NVPR. It will fail if the GL driver does not
40e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen          support NVPR */
41e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen      kNVPR_GLContextType,
42e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen      kNull_GLContextType,
43e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen      kDebug_GLContextType,
44e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen
45e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen      kLastGLContextType = kDebug_GLContextType
46e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen    };
47e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen
48e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen    static const int kGLContextTypeCnt = kLastGLContextType + 1;
49e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen
50e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen    static bool IsRenderingGLContext(GLContextType type) {
51e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen        switch (type) {
52e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen            case kNull_GLContextType:
53e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen            case kDebug_GLContextType:
54e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen                return false;
55e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen            default:
56e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen                return true;
57e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen        }
58e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen    }
59e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen
60e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen    static const char* GLContextTypeName(GLContextType type) {
61e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen        switch (type) {
62e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen            case kNative_GLContextType:
63e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen                return "native";
64e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen            case kNull_GLContextType:
65e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen                return "null";
66e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen#if SK_ANGLE
67e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen            case kANGLE_GLContextType:
68e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen                return "angle";
69e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen#endif
70e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen#if SK_MESA
71e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen            case kMESA_GLContextType:
72e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen                return "mesa";
73e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen#endif
74e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen            case kNVPR_GLContextType:
75e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen                return "nvpr";
76e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen            case kDebug_GLContextType:
77e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen                return "debug";
78e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen            default:
79e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen                SkFAIL("Unknown GL Context type.");
80e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen        }
81e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen    }
82e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen
83e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen    explicit GrContextFactory(const GrContext::Options& opts) : fGlobalOptions(opts) { }
84e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen    GrContextFactory() { }
85e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen
86e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen    ~GrContextFactory() { this->destroyContexts(); }
87e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen
88e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen    void destroyContexts() {
89e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen        for (int i = 0; i < fContexts.count(); ++i) {
90e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen            if (fContexts[i].fGLContext) {  //  could be abandoned.
91e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen                fContexts[i].fGLContext->makeCurrent();
92e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen            }
93e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen            fContexts[i].fGrContext->unref();
94e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen            if (fContexts[i].fGLContext) {
95e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen                fContexts[i].fGLContext->unref();
96e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen            }
97e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen        }
98e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen        fContexts.reset();
99e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen    }
100e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen
101e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen    void abandonContexts() {
102e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen        for (int i = 0; i < fContexts.count(); ++i) {
103e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen            if (fContexts[i].fGLContext) {
104e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen                fContexts[i].fGLContext->testAbandon();
105e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen                SkSafeSetNull(fContexts[i].fGLContext);
106e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen            }
107e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen            fContexts[i].fGrContext->abandonContext();
108e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen        }
109e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen    }
110e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen
111e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen    /**
112e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen     * Get a GrContext initialized with a type of GL context. It also makes the GL context current.
113e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen     */
114e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen    GrContext* get(GLContextType type, GrGLStandard forcedGpuAPI = kNone_GrGLStandard);
115e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen
116e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen
117e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen    // Returns the GLContext of the given type. If it has not been created yet,
118e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen    // NULL is returned instead.
119e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen    SkGLContext* getGLContext(GLContextType type) {
120e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen        for (int i = 0; i < fContexts.count(); ++i) {
121e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen            if (fContexts[i].fType == type) {
122e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen                return fContexts[i].fGLContext;
123e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen            }
124e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen        }
125e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen
126e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen        return NULL;
127e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen    }
128e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen
129e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen    const GrContext::Options& getGlobalOptions() const { return fGlobalOptions; }
130e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen
131e4545210c950f98d9fa20f51bc1be6c5591534bddjsollenprivate:
132e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen    struct GPUContext {
133e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen        GLContextType             fType;
134e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen        SkGLContext*              fGLContext;
135e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen        GrContext*                fGrContext;
136e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen    };
137e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen    SkTArray<GPUContext, true>    fContexts;
138e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen    const GrContext::Options      fGlobalOptions;
139e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen};
140e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen
141e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen#endif
142