gfx/skia/trunk/include/gpu/GrContextFactory.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gfx/skia/trunk/include/gpu/GrContextFactory.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,197 @@
     1.4 +/*
     1.5 + * Copyright 2012 Google Inc.
     1.6 + *
     1.7 + * Use of this source code is governed by a BSD-style license that can be
     1.8 + * found in the LICENSE file.
     1.9 + */
    1.10 +
    1.11 +#ifndef GrContextFactory_DEFINED
    1.12 +#define GrContextFactory_DEFINED
    1.13 +
    1.14 +#if SK_ANGLE
    1.15 +    #include "gl/SkANGLEGLContext.h"
    1.16 +#endif
    1.17 +#include "gl/SkDebugGLContext.h"
    1.18 +#if SK_MESA
    1.19 +    #include "gl/SkMesaGLContext.h"
    1.20 +#endif
    1.21 +#include "gl/SkNativeGLContext.h"
    1.22 +#include "gl/SkNullGLContext.h"
    1.23 +
    1.24 +#include "GrContext.h"
    1.25 +#include "SkTArray.h"
    1.26 +
    1.27 +/**
    1.28 + * This is a simple class that is useful in test apps that use different
    1.29 + * GrContexts backed by different types of GL contexts. It manages creating the
    1.30 + * GL context and a GrContext that uses it. The GL/Gr contexts persist until the
    1.31 + * factory is destroyed (though the caller can always grab a ref on the returned
    1.32 + * Gr and GL contexts to make them outlive the factory).
    1.33 + */
    1.34 +class GrContextFactory : public SkNoncopyable {
    1.35 +public:
    1.36 +    /**
    1.37 +     * Types of GL contexts supported. For historical and testing reasons the native GrContext will
    1.38 +     * not use "GL_NV_path_rendering" even when the driver supports it. There is a separate context
    1.39 +     * type that does not remove NVPR support and which will fail when the driver does not support
    1.40 +     * the extension.
    1.41 +     */
    1.42 +    enum GLContextType {
    1.43 +      kNative_GLContextType,
    1.44 +#if SK_ANGLE
    1.45 +      kANGLE_GLContextType,
    1.46 +#endif
    1.47 +#if SK_MESA
    1.48 +      kMESA_GLContextType,
    1.49 +#endif
    1.50 +      /** Similar to kNative but does not filter NVPR. It will fail if the GL driver does not
    1.51 +          support NVPR */
    1.52 +      kNVPR_GLContextType,
    1.53 +      kNull_GLContextType,
    1.54 +      kDebug_GLContextType,
    1.55 +
    1.56 +      kLastGLContextType = kDebug_GLContextType
    1.57 +    };
    1.58 +
    1.59 +    static const int kGLContextTypeCnt = kLastGLContextType + 1;
    1.60 +
    1.61 +    static bool IsRenderingGLContext(GLContextType type) {
    1.62 +        switch (type) {
    1.63 +            case kNull_GLContextType:
    1.64 +            case kDebug_GLContextType:
    1.65 +                return false;
    1.66 +            default:
    1.67 +                return true;
    1.68 +        }
    1.69 +    }
    1.70 +
    1.71 +    static const char* GLContextTypeName(GLContextType type) {
    1.72 +        switch (type) {
    1.73 +            case kNative_GLContextType:
    1.74 +                return "native";
    1.75 +            case kNull_GLContextType:
    1.76 +                return "null";
    1.77 +#if SK_ANGLE
    1.78 +            case kANGLE_GLContextType:
    1.79 +                return "angle";
    1.80 +#endif
    1.81 +#if SK_MESA
    1.82 +            case kMESA_GLContextType:
    1.83 +                return "mesa";
    1.84 +#endif
    1.85 +            case kNVPR_GLContextType:
    1.86 +                return "nvpr";
    1.87 +            case kDebug_GLContextType:
    1.88 +                return "debug";
    1.89 +            default:
    1.90 +                GrCrash("Unknown GL Context type.");
    1.91 +        }
    1.92 +    }
    1.93 +
    1.94 +    GrContextFactory() {
    1.95 +    }
    1.96 +
    1.97 +    ~GrContextFactory() { this->destroyContexts(); }
    1.98 +
    1.99 +    void destroyContexts() {
   1.100 +        for (int i = 0; i < fContexts.count(); ++i) {
   1.101 +            fContexts[i].fGLContext->makeCurrent();
   1.102 +            fContexts[i].fGrContext->unref();
   1.103 +            fContexts[i].fGLContext->unref();
   1.104 +        }
   1.105 +        fContexts.reset();
   1.106 +    }
   1.107 +
   1.108 +    /**
   1.109 +     * Get a GrContext initialized with a type of GL context. It also makes the GL context current.
   1.110 +     */
   1.111 +    GrContext* get(GLContextType type) {
   1.112 +
   1.113 +        for (int i = 0; i < fContexts.count(); ++i) {
   1.114 +            if (fContexts[i].fType == type) {
   1.115 +                fContexts[i].fGLContext->makeCurrent();
   1.116 +                return fContexts[i].fGrContext;
   1.117 +            }
   1.118 +        }
   1.119 +        SkAutoTUnref<SkGLContextHelper> glCtx;
   1.120 +        SkAutoTUnref<GrContext> grCtx;
   1.121 +        switch (type) {
   1.122 +            case kNVPR_GLContextType: // fallthru
   1.123 +            case kNative_GLContextType:
   1.124 +                glCtx.reset(SkNEW(SkNativeGLContext));
   1.125 +                break;
   1.126 +#ifdef SK_ANGLE
   1.127 +            case kANGLE_GLContextType:
   1.128 +                glCtx.reset(SkNEW(SkANGLEGLContext));
   1.129 +                break;
   1.130 +#endif
   1.131 +#ifdef SK_MESA
   1.132 +            case kMESA_GLContextType:
   1.133 +                glCtx.reset(SkNEW(SkMesaGLContext));
   1.134 +                break;
   1.135 +#endif
   1.136 +            case kNull_GLContextType:
   1.137 +                glCtx.reset(SkNEW(SkNullGLContext));
   1.138 +                break;
   1.139 +            case kDebug_GLContextType:
   1.140 +                glCtx.reset(SkNEW(SkDebugGLContext));
   1.141 +                break;
   1.142 +        }
   1.143 +        static const int kBogusSize = 1;
   1.144 +        if (!glCtx.get()) {
   1.145 +            return NULL;
   1.146 +        }
   1.147 +        if (!glCtx.get()->init(kBogusSize, kBogusSize)) {
   1.148 +            return NULL;
   1.149 +        }
   1.150 +
   1.151 +        // Ensure NVPR is available for the NVPR type and block it from other types.
   1.152 +        SkAutoTUnref<const GrGLInterface> glInterface(SkRef(glCtx.get()->gl()));
   1.153 +        if (kNVPR_GLContextType == type) {
   1.154 +            if (!glInterface->hasExtension("GL_NV_path_rendering")) {
   1.155 +                return NULL;
   1.156 +            }
   1.157 +        } else {
   1.158 +            glInterface.reset(GrGLInterfaceRemoveNVPR(glInterface));
   1.159 +            if (!glInterface) {
   1.160 +                return NULL;
   1.161 +            }
   1.162 +        }
   1.163 +
   1.164 +        glCtx->makeCurrent();
   1.165 +        GrBackendContext p3dctx = reinterpret_cast<GrBackendContext>(glInterface.get());
   1.166 +        grCtx.reset(GrContext::Create(kOpenGL_GrBackend, p3dctx));
   1.167 +        if (!grCtx.get()) {
   1.168 +            return NULL;
   1.169 +        }
   1.170 +        GPUContext& ctx = fContexts.push_back();
   1.171 +        ctx.fGLContext = glCtx.get();
   1.172 +        ctx.fGLContext->ref();
   1.173 +        ctx.fGrContext = grCtx.get();
   1.174 +        ctx.fGrContext->ref();
   1.175 +        ctx.fType = type;
   1.176 +        return ctx.fGrContext;
   1.177 +    }
   1.178 +
   1.179 +    // Returns the GLContext of the given type. If it has not been created yet,
   1.180 +    // NULL is returned instead.
   1.181 +    SkGLContextHelper* getGLContext(GLContextType type) {
   1.182 +        for (int i = 0; i < fContexts.count(); ++i) {
   1.183 +            if (fContexts[i].fType == type) {
   1.184 +                return fContexts[i].fGLContext;
   1.185 +            }
   1.186 +        }
   1.187 +
   1.188 +        return NULL;
   1.189 +    }
   1.190 +
   1.191 +private:
   1.192 +    struct GPUContext {
   1.193 +        GLContextType             fType;
   1.194 +        SkGLContextHelper*        fGLContext;
   1.195 +        GrContext*                fGrContext;
   1.196 +    };
   1.197 +    SkTArray<GPUContext, true> fContexts;
   1.198 +};
   1.199 +
   1.200 +#endif

mercurial