
/*
 * Copyright 2014 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "GrContextFactory.h"

#if SK_ANGLE
    #include "gl/angle/SkANGLEGLContext.h"
#endif
#if SK_COMMAND_BUFFER
    #include "gl/command_buffer/SkCommandBufferGLContext.h"
#endif
#include "gl/debug/SkDebugGLContext.h"
#if SK_MESA
    #include "gl/mesa/SkMesaGLContext.h"
#endif
#include "gl/SkGLContext.h"
#include "gl/SkNullGLContext.h"
#include "gl/GrGLGpu.h"
#include "GrCaps.h"

GrContextFactory::ContextInfo* GrContextFactory::getContextInfo(GLContextType type,
                                                                GrGLStandard forcedGpuAPI,
                                                                GLContextOptions options) {
    for (int i = 0; i < fContexts.count(); ++i) {
        if (fContexts[i]->fType == type &&
            fContexts[i]->fOptions == options &&
            (forcedGpuAPI == kNone_GrGLStandard ||
             forcedGpuAPI == fContexts[i]->fGLContext->gl()->fStandard)) {
            fContexts[i]->fGLContext->makeCurrent();
            return fContexts[i];
        }
    }

    SkAutoTUnref<SkGLContext> glCtx;
    SkAutoTUnref<GrContext> grCtx;
    switch (type) {
        case kNative_GLContextType:
            glCtx.reset(SkCreatePlatformGLContext(forcedGpuAPI));
            break;
#ifdef SK_ANGLE
        case kANGLE_GLContextType:
            glCtx.reset(SkANGLEGLContext::Create(forcedGpuAPI, false));
            break;
        case kANGLE_GL_GLContextType:
            glCtx.reset(SkANGLEGLContext::Create(forcedGpuAPI, true));
            break;
#endif
#ifdef SK_COMMAND_BUFFER
        case kCommandBuffer_GLContextType:
            glCtx.reset(SkCommandBufferGLContext::Create(forcedGpuAPI));
            break;
#endif
#ifdef SK_MESA
        case kMESA_GLContextType:
            glCtx.reset(SkMesaGLContext::Create(forcedGpuAPI));
            break;
#endif
        case kNull_GLContextType:
            glCtx.reset(SkNullGLContext::Create(forcedGpuAPI));
            break;
        case kDebug_GLContextType:
            glCtx.reset(SkDebugGLContext::Create(forcedGpuAPI));
            break;
    }
    if (nullptr == glCtx.get()) {
        return nullptr;
    }

    SkASSERT(glCtx->isValid());

    // Block NVPR from non-NVPR types.
    SkAutoTUnref<const GrGLInterface> glInterface(SkRef(glCtx->gl()));
    if (!(kEnableNVPR_GLContextOptions & options)) {
        glInterface.reset(GrGLInterfaceRemoveNVPR(glInterface));
        if (!glInterface) {
            return nullptr;
        }
    } else {
        if (!glInterface->hasExtension("GL_NV_path_rendering")) {
            return nullptr;
        }
    }

    glCtx->makeCurrent();
    GrBackendContext p3dctx = reinterpret_cast<GrBackendContext>(glInterface.get());
#ifdef SK_VULKAN
    grCtx.reset(GrContext::Create(kVulkan_GrBackend, p3dctx, fGlobalOptions));
#else
    grCtx.reset(GrContext::Create(kOpenGL_GrBackend, p3dctx, fGlobalOptions));
#endif
    if (!grCtx.get()) {
        return nullptr;
    }
    // Warn if path rendering support is not available for the NVPR type.
    if (kEnableNVPR_GLContextOptions & options) {
        if (!grCtx->caps()->shaderCaps()->pathRenderingSupport()) {
            GrGpu* gpu = grCtx->getGpu();
            const GrGLContext* ctx = gpu->glContextForTesting();
            if (ctx) {
                const GrGLubyte* verUByte;
                GR_GL_CALL_RET(ctx->interface(), verUByte, GetString(GR_GL_VERSION));
                const char* ver = reinterpret_cast<const char*>(verUByte);
                SkDebugf("\nWARNING: nvprmsaa config requested, but driver path rendering "
                         "support not available. Maybe update the driver? Your driver version "
                         "string: \"%s\"\n", ver);
            } else {
                SkDebugf("\nWARNING: nvprmsaa config requested, but driver path rendering "
                         "support not available.\n");
            }
        }
    }

    ContextInfo* ctx = fContexts.emplace_back(new ContextInfo);
    ctx->fGLContext = SkRef(glCtx.get());
    ctx->fGrContext = SkRef(grCtx.get());
    ctx->fType = type;
    ctx->fOptions = options;
    return ctx;
}
