
/*
 * 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 "include/gpu/GrDirectContext.h"
#include "src/gpu/GrDirectContextPriv.h"
#include "tools/gpu/GrContextFactory.h"
#ifdef SK_GL
#include "tools/gpu/gl/GLTestContext.h"
#endif

#if SK_ANGLE
#include "tools/gpu/gl/angle/GLTestContext_angle.h"
#endif
#include "tools/gpu/gl/command_buffer/GLTestContext_command_buffer.h"
#ifdef SK_VULKAN
#include "tools/gpu/vk/VkTestContext.h"
#endif
#ifdef SK_METAL
#include "tools/gpu/mtl/MtlTestContext.h"
#endif
#ifdef SK_DIRECT3D
#include "tools/gpu/d3d/D3DTestContext.h"
#endif
#ifdef SK_DAWN
#include "tools/gpu/dawn/DawnTestContext.h"
#endif
#include "src/gpu/GrCaps.h"
#include "tools/gpu/mock/MockTestContext.h"

#if defined(SK_BUILD_FOR_WIN) && defined(SK_ENABLE_DISCRETE_GPU)
extern "C" {
    // NVIDIA documents that the presence and value of this symbol programmatically enable the high
    // performance GPU in laptops with switchable graphics.
    //   https://docs.nvidia.com/gameworks/content/technologies/desktop/optimus.htm
    // From testing, including this symbol, even if it is set to 0, we still get the NVIDIA GPU.
    _declspec(dllexport) unsigned long NvOptimusEnablement = 0x00000001;

    // AMD has a similar mechanism, although I don't have an AMD laptop, so this is untested.
    //   https://community.amd.com/thread/169965
    __declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1;
}
#endif

namespace sk_gpu_test {
GrContextFactory::GrContextFactory() { }

GrContextFactory::GrContextFactory(const GrContextOptions& opts)
    : fGlobalOptions(opts) {
}

GrContextFactory::~GrContextFactory() {
    this->destroyContexts();
}

void GrContextFactory::destroyContexts() {
    // We must delete the test contexts in reverse order so that any child context is finished and
    // deleted before a parent context. This relies on the fact that when we make a new context we
    // append it to the end of fContexts array.
    // TODO: Look into keeping a dependency dag for contexts and deletion order
    for (int i = fContexts.count() - 1; i >= 0; --i) {
        Context& context = fContexts[i];
        SkScopeExit restore(nullptr);
        if (context.fTestContext) {
            restore = context.fTestContext->makeCurrentAndAutoRestore();
        }
        if (!context.fGrContext->unique()) {
            context.fGrContext->releaseResourcesAndAbandonContext();
            context.fAbandoned = true;
        }
        context.fGrContext->unref();
        delete context.fTestContext;
    }
    fContexts.reset();
}

void GrContextFactory::abandonContexts() {
    // We must abandon the test contexts in reverse order so that any child context is finished and
    // abandoned before a parent context. This relies on the fact that when we make a new context we
    // append it to the end of fContexts array.
    // TODO: Look into keeping a dependency dag for contexts and deletion order
    for (int i = fContexts.count() - 1; i >= 0; --i) {
        Context& context = fContexts[i];
        if (!context.fAbandoned) {
            if (context.fTestContext) {
                auto restore = context.fTestContext->makeCurrentAndAutoRestore();
                context.fTestContext->testAbandon();
            }
            GrBackendApi api = context.fGrContext->backend();
            bool requiresEarlyAbandon = api == GrBackendApi::kVulkan || api == GrBackendApi::kDawn;
            if (requiresEarlyAbandon) {
                context.fGrContext->abandonContext();
            }
            if (context.fTestContext) {
                delete(context.fTestContext);
                context.fTestContext = nullptr;
            }
            if (!requiresEarlyAbandon) {
                context.fGrContext->abandonContext();
            }
            context.fAbandoned = true;
        }
    }
}

void GrContextFactory::releaseResourcesAndAbandonContexts() {
    // We must abandon the test contexts in reverse order so that any child context is finished and
    // abandoned before a parent context. This relies on the fact that when we make a new context we
    // append it to the end of fContexts array.
    // TODO: Look into keeping a dependency dag for contexts and deletion order
    for (int i = fContexts.count() - 1; i >= 0; --i) {
        Context& context = fContexts[i];
        SkScopeExit restore(nullptr);
        if (!context.fAbandoned) {
            if (context.fTestContext) {
                restore = context.fTestContext->makeCurrentAndAutoRestore();
            }
            context.fGrContext->releaseResourcesAndAbandonContext();
            if (context.fTestContext) {
                delete context.fTestContext;
                context.fTestContext = nullptr;
            }
            context.fAbandoned = true;
        }
    }
}

GrDirectContext* GrContextFactory::get(ContextType type, ContextOverrides overrides) {
    return this->getContextInfo(type, overrides).directContext();
}

ContextInfo GrContextFactory::getContextInfoInternal(ContextType type, ContextOverrides overrides,
                                                     GrDirectContext* shareContext,
                                                     uint32_t shareIndex) {
    // (shareIndex != 0) -> (shareContext != nullptr)
    SkASSERT((shareIndex == 0) || (shareContext != nullptr));

    for (int i = 0; i < fContexts.count(); ++i) {
        Context& context = fContexts[i];
        if (context.fType == type &&
            context.fOverrides == overrides &&
            context.fShareContext == shareContext &&
            context.fShareIndex == shareIndex &&
            !context.fAbandoned) {
            context.fTestContext->makeCurrent();
            return ContextInfo(context.fType, context.fTestContext, context.fGrContext,
                               context.fOptions);
        }
    }

    // If we're trying to create a context in a share group, find the primary context
    Context* primaryContext = nullptr;
    if (shareContext) {
        for (int i = 0; i < fContexts.count(); ++i) {
            if (!fContexts[i].fAbandoned && fContexts[i].fGrContext == shareContext) {
                primaryContext = &fContexts[i];
                break;
            }
        }
        SkASSERT(primaryContext && primaryContext->fType == type);
    }

    std::unique_ptr<TestContext> testCtx;
    GrBackendApi backend = ContextTypeBackend(type);
    switch (backend) {
#ifdef SK_GL
        case GrBackendApi::kOpenGL: {
            GLTestContext* glShareContext = primaryContext
                    ? static_cast<GLTestContext*>(primaryContext->fTestContext) : nullptr;
            GLTestContext* glCtx;
            switch (type) {
                case kGL_ContextType:
                    glCtx = CreatePlatformGLTestContext(kGL_GrGLStandard, glShareContext);
                    break;
                case kGLES_ContextType:
                    glCtx = CreatePlatformGLTestContext(kGLES_GrGLStandard, glShareContext);
                    break;
#if SK_ANGLE
                case kANGLE_D3D9_ES2_ContextType:
                    glCtx = MakeANGLETestContext(ANGLEBackend::kD3D9, ANGLEContextVersion::kES2,
                                                 glShareContext).release();
                    // Chrome will only run on D3D9 with NVIDIA for 2012 and earlier drivers.
                    // (<= 269.73). We get shader link failures when testing on recent drivers
                    // using this backend.
                    if (glCtx) {
                        GrGLDriverInfo info = GrGLGetDriverInfo(glCtx->gl());
                        if (info.fANGLEVendor == GrGLVendor::kNVIDIA) {
                            delete glCtx;
                            return ContextInfo();
                        }
                    }
                    break;
                case kANGLE_D3D11_ES2_ContextType:
                    glCtx = MakeANGLETestContext(ANGLEBackend::kD3D11, ANGLEContextVersion::kES2,
                                                 glShareContext).release();
                    break;
                case kANGLE_D3D11_ES3_ContextType:
                    glCtx = MakeANGLETestContext(ANGLEBackend::kD3D11, ANGLEContextVersion::kES3,
                                                 glShareContext).release();
                    break;
                case kANGLE_GL_ES2_ContextType:
                    glCtx = MakeANGLETestContext(ANGLEBackend::kOpenGL, ANGLEContextVersion::kES2,
                                                 glShareContext).release();
                    break;
                case kANGLE_GL_ES3_ContextType:
                    glCtx = MakeANGLETestContext(ANGLEBackend::kOpenGL, ANGLEContextVersion::kES3,
                                                 glShareContext).release();
                    break;
#endif
#ifndef SK_NO_COMMAND_BUFFER
                case kCommandBuffer_ES2_ContextType:
                    glCtx = CommandBufferGLTestContext::Create(2, glShareContext);
                    break;
                case kCommandBuffer_ES3_ContextType:
                    glCtx = CommandBufferGLTestContext::Create(3, glShareContext);
                    break;
#endif
                default:
                    return ContextInfo();
            }
            if (!glCtx) {
                return ContextInfo();
            }
            if (glCtx->gl()->fStandard == kGLES_GrGLStandard &&
                (overrides & ContextOverrides::kFakeGLESVersionAs2)) {
                glCtx->overrideVersion("OpenGL ES 2.0", "OpenGL ES GLSL ES 1.00");
            }
            testCtx.reset(glCtx);
            break;
        }
#endif  // SK_GL
#ifdef SK_VULKAN
        case GrBackendApi::kVulkan: {
            VkTestContext* vkSharedContext = primaryContext
                    ? static_cast<VkTestContext*>(primaryContext->fTestContext) : nullptr;
            SkASSERT(kVulkan_ContextType == type);
            testCtx.reset(CreatePlatformVkTestContext(vkSharedContext));
            if (!testCtx) {
                return ContextInfo();
            }

            // We previously had an issue where the VkDevice destruction would occasionally hang
            // on systems with NVIDIA GPUs and having an existing GL context fixed it. Now (March
            // 2020) we still need the GL context to keep Vulkan/TSAN bots from running incredibly
            // slow. Perhaps this prevents repeated driver loading/unloading? Note that keeping
            // a persistent VkTestContext around instead was tried and did not work.
            if (!fSentinelGLContext) {
                fSentinelGLContext.reset(CreatePlatformGLTestContext(kGL_GrGLStandard));
                if (!fSentinelGLContext) {
                    fSentinelGLContext.reset(CreatePlatformGLTestContext(kGLES_GrGLStandard));
                }
            }
            break;
        }
#endif
#ifdef SK_METAL
        case GrBackendApi::kMetal: {
            MtlTestContext* mtlSharedContext = primaryContext
                    ? static_cast<MtlTestContext*>(primaryContext->fTestContext) : nullptr;
            SkASSERT(kMetal_ContextType == type);
            testCtx.reset(CreatePlatformMtlTestContext(mtlSharedContext));
            if (!testCtx) {
                return ContextInfo();
            }
            break;
        }
#endif
#ifdef SK_DIRECT3D
        case GrBackendApi::kDirect3D: {
            D3DTestContext* d3dSharedContext = primaryContext
                    ? static_cast<D3DTestContext*>(primaryContext->fTestContext) : nullptr;
            SkASSERT(kDirect3D_ContextType == type);
            testCtx.reset(CreatePlatformD3DTestContext(d3dSharedContext));
            if (!testCtx) {
                return ContextInfo();
            }
            break;
        }
#endif
#ifdef SK_DAWN
        case GrBackendApi::kDawn: {
            DawnTestContext* dawnSharedContext = primaryContext
                    ? static_cast<DawnTestContext*>(primaryContext->fTestContext) : nullptr;
            testCtx.reset(CreatePlatformDawnTestContext(dawnSharedContext));
            if (!testCtx) {
                return ContextInfo();
            }
            break;
        }
#endif
        case GrBackendApi::kMock: {
            TestContext* sharedContext = primaryContext ? primaryContext->fTestContext : nullptr;
            SkASSERT(kMock_ContextType == type);
            testCtx.reset(CreateMockTestContext(sharedContext));
            if (!testCtx) {
                return ContextInfo();
            }
            break;
        }
        default:
            return ContextInfo();
    }

    SkASSERT(testCtx && testCtx->backend() == backend);
    GrContextOptions grOptions = fGlobalOptions;
    if (ContextOverrides::kAvoidStencilBuffers & overrides) {
        grOptions.fAvoidStencilBuffers = true;
    }
    if (ContextOverrides::kReducedShaders & overrides) {
        grOptions.fReducedShaderVariations = true;
    }
    sk_sp<GrDirectContext> grCtx;
    {
        auto restore = testCtx->makeCurrentAndAutoRestore();
        grCtx = testCtx->makeContext(grOptions);
    }
    if (!grCtx) {
        return ContextInfo();
    }

    if (shareContext) {
        SkASSERT(grCtx->directContextID() != shareContext->directContextID());
    }

    // We must always add new contexts by pushing to the back so that when we delete them we delete
    // them in reverse order in which they were made.
    Context& context = fContexts.push_back();
    context.fBackend = backend;
    context.fTestContext = testCtx.release();
    context.fGrContext = SkRef(grCtx.get());
    context.fType = type;
    context.fOverrides = overrides;
    context.fAbandoned = false;
    context.fShareContext = shareContext;
    context.fShareIndex = shareIndex;
    context.fOptions = grOptions;
    context.fTestContext->makeCurrent();
    return ContextInfo(context.fType, context.fTestContext, context.fGrContext, context.fOptions);
}

ContextInfo GrContextFactory::getContextInfo(ContextType type, ContextOverrides overrides) {
    return this->getContextInfoInternal(type, overrides, nullptr, 0);
}

ContextInfo GrContextFactory::getSharedContextInfo(GrDirectContext* shareContext,
                                                   uint32_t shareIndex) {
    SkASSERT(shareContext);
    for (int i = 0; i < fContexts.count(); ++i) {
        if (!fContexts[i].fAbandoned && fContexts[i].fGrContext == shareContext) {
            return this->getContextInfoInternal(fContexts[i].fType, fContexts[i].fOverrides,
                                                shareContext, shareIndex);
        }
    }

    return ContextInfo();
}

}  // namespace sk_gpu_test
