/*
 * Copyright 2017 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 *
 * This file implements many functions defined in Test.h that are required to be implemented by
 * test runners (such as DM) to support GPU backends.
 */

#include "include/gpu/GpuTypes.h"
#include "tests/Test.h"

#if defined(SK_GANESH)
#include "include/gpu/ganesh/GrDirectContext.h"
#endif

#if defined(SK_GRAPHITE)
#include "include/gpu/graphite/Context.h"
#include "tools/graphite/ContextFactory.h"
#endif

#if defined(SK_GANESH)
using sk_gpu_test::GrContextFactory;
using sk_gpu_test::ContextInfo;
#endif

#ifdef SK_GL
using sk_gpu_test::GLTestContext;
#endif

namespace skiatest {

bool IsGLContextType(skgpu::ContextType type) {
#if defined(SK_GANESH)
    return skgpu::ganesh::ContextTypeBackend(type) == GrBackendApi::kOpenGL;
#else
    return false;
#endif
}

bool IsVulkanContextType(skgpu::ContextType type) {
#if defined(SK_GANESH)
    return skgpu::ganesh::ContextTypeBackend(type) == GrBackendApi::kVulkan;
#elif defined(SK_GRAPHITE)
    return skgpu::graphite::ContextTypeBackend(type) == skgpu::BackendApi::kVulkan;
#else
    return false;
#endif
}

bool IsMetalContextType(skgpu::ContextType type) {
#if defined(SK_GANESH)
    return skgpu::ganesh::ContextTypeBackend(type) == GrBackendApi::kMetal;
#elif defined(SK_GRAPHITE)
    return skgpu::graphite::ContextTypeBackend(type) == skgpu::BackendApi::kMetal;
#else
    return false;
#endif
}

bool IsDirect3DContextType(skgpu::ContextType type) {
#if defined(SK_GANESH)
    return skgpu::ganesh::ContextTypeBackend(type) == GrBackendApi::kDirect3D;
#else
    return false;
#endif
}

bool IsDawnContextType(skgpu::ContextType type) {
#if defined(SK_GRAPHITE)
    return skgpu::graphite::ContextTypeBackend(type) == skgpu::BackendApi::kDawn;
#else
    return false;
#endif
}

bool IsMockContextType(skgpu::ContextType type) {
    return type == skgpu::ContextType::kMock;
}

#if defined(SK_GANESH)
void RunWithGaneshTestContexts(GrContextTestFn* testFn, ContextTypeFilterFn* filter,
                               Reporter* reporter, const GrContextOptions& options) {
#if defined(SK_BUILD_FOR_UNIX) || defined(SK_BUILD_FOR_WIN) || defined(SK_BUILD_FOR_MAC)
    static constexpr auto kNativeGLType = skgpu::ContextType::kGL;
#else
    static constexpr auto kNativeGLType = skgpu::ContextType::kGLES;
#endif

    for (int typeInt = 0; typeInt < skgpu::kContextTypeCount; ++typeInt) {
        skgpu::ContextType contextType = static_cast<skgpu::ContextType>(typeInt);
        // Use "native" instead of explicitly trying OpenGL and OpenGL ES. Do not use GLES on
        // desktop since tests do not account for not fixing skbug.com/40033921
        if (contextType == skgpu::ContextType::kGL ||
            contextType == skgpu::ContextType::kGLES) {
            if (contextType != kNativeGLType) {
                continue;
            }
        }
        // We destroy the factory and its associated contexts after each test. This is due to the
        // fact that the command buffer sits on top of the native GL windowing (cgl, wgl, ...) but
        // also tracks which of its contexts is current above that API and gets tripped up if the
        // native windowing API is used directly outside of the command buffer code.
        GrContextFactory factory(options);
        ContextInfo ctxInfo = factory.getContextInfo(contextType);
        if (filter && !(*filter)(contextType)) {
            continue;
        }

        ReporterContext ctx(reporter, SkString(skgpu::ContextTypeName(contextType)));
        if (ctxInfo.directContext()) {
            (*testFn)(reporter, ctxInfo);
            // In case the test changed the current context make sure we move it back before
            // calling flush.
            ctxInfo.testContext()->makeCurrent();
            // Sync so any release/finished procs get called.
            ctxInfo.directContext()->flushAndSubmit(GrSyncCpu::kYes);
        }
    }
}
#endif

#if defined(SK_GRAPHITE)

namespace graphite {

void RunWithGraphiteTestContexts(GraphiteTestFn* test,
                                 ContextTypeFilterFn* filter,
                                 Reporter* reporter,
                                 const skiatest::graphite::TestOptions& options) {
    ContextFactory factory(options);
    for (int typeInt = 0; typeInt < skgpu::kContextTypeCount; ++typeInt) {
        skgpu::ContextType contextType = static_cast<skgpu::ContextType>(typeInt);
        if (filter && !(*filter)(contextType)) {
            continue;
        }

        skiatest::graphite::ContextInfo ctxInfo = factory.getContextInfo(contextType);
        if (!ctxInfo.fContext) {
            continue;
        }

        ReporterContext ctx(reporter, SkString(skgpu::ContextTypeName(contextType)));
        (*test)(reporter, ctxInfo.fContext, ctxInfo.fTestContext, options);
    }
}

} // namespace graphite

#endif // SK_GRAPHITE

} // namespace skiatest
