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

// This is a Vulkan protected memory specific test.

#include "include/core/SkTypes.h"

#if SK_SUPPORT_GPU && defined(SK_VULKAN)

#include "include/core/SkCanvas.h"
#include "include/core/SkMaskFilter.h"
#include "include/core/SkPaint.h"
#include "include/core/SkSurface.h"
#include "include/gpu/GrBackendSurface.h"
#include "include/gpu/vk/GrVkBackendContext.h"
#include "include/gpu/vk/GrVkExtensions.h"
#include "tests/Test.h"
#include "tools/gpu/GrContextFactory.h"
#include "tools/gpu/vk/VkTestUtils.h"

namespace {

#define DECLARE_VK_PROC(name) PFN_vk##name fVk##name

#define ACQUIRE_INST_VK_PROC(name)                                                           \
    fVk##name = reinterpret_cast<PFN_vk##name>(getProc("vk" #name, fBackendContext.fInstance,\
                                                       VK_NULL_HANDLE));                     \
    if (fVk##name == nullptr) {                                                              \
        ERRORF(reporter, "Function ptr for vk%s could not be acquired\n", #name);            \
        return false;                                                                        \
    }

#define ACQUIRE_DEVICE_VK_PROC(name)                                                          \
    fVk##name = reinterpret_cast<PFN_vk##name>(getProc("vk" #name, VK_NULL_HANDLE, fDevice)); \
    if (fVk##name == nullptr) {                                                               \
        ERRORF(reporter, "Function ptr for vk%s could not be acquired\n", #name);             \
        return false;                                                                         \
    }

class VulkanTestHelper {
public:
    VulkanTestHelper(bool isProtected) : fIsProtected(isProtected) {}

    ~VulkanTestHelper() {
        cleanup();
    }

    bool init(skiatest::Reporter* reporter);

    GrContext* grContext() { return fGrContext.get(); }

    sk_sp<SkSurface> createSkSurface(skiatest::Reporter* reporter);

   private:
    void cleanup();

    DECLARE_VK_PROC(DestroyInstance);
    DECLARE_VK_PROC(DeviceWaitIdle);
    DECLARE_VK_PROC(DestroyDevice);

    bool fIsProtected = false;
    VkDevice fDevice = VK_NULL_HANDLE;

    GrVkExtensions* fExtensions = nullptr;
    VkPhysicalDeviceFeatures2* fFeatures = nullptr;
    VkDebugReportCallbackEXT fDebugCallback = VK_NULL_HANDLE;
    PFN_vkDestroyDebugReportCallbackEXT fDestroyDebugCallback = nullptr;
    GrVkBackendContext fBackendContext;
    sk_sp<GrContext> fGrContext;
};

} // namespace

bool VulkanTestHelper::init(skiatest::Reporter* reporter) {
    PFN_vkGetInstanceProcAddr instProc;
    PFN_vkGetDeviceProcAddr devProc;
    if (!sk_gpu_test::LoadVkLibraryAndGetProcAddrFuncs(&instProc, &devProc)) {
        return false;
    }
    auto getProc = [&instProc, &devProc](const char* proc_name,
                                         VkInstance instance, VkDevice device) {
        if (device != VK_NULL_HANDLE) {
            return devProc(device, proc_name);
        }
        return instProc(instance, proc_name);
    };

    fExtensions = new GrVkExtensions();
    fFeatures = new VkPhysicalDeviceFeatures2;
    memset(fFeatures, 0, sizeof(VkPhysicalDeviceFeatures2));
    fFeatures->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
    fFeatures->pNext = nullptr;

    fBackendContext.fInstance = VK_NULL_HANDLE;
    fBackendContext.fDevice = VK_NULL_HANDLE;

    if (!sk_gpu_test::CreateVkBackendContext(getProc, &fBackendContext, fExtensions,
                                             fFeatures, &fDebugCallback, nullptr,
                                             sk_gpu_test::CanPresentFn(), fIsProtected)) {
        return false;
    }
    fDevice = fBackendContext.fDevice;

    if (fDebugCallback != VK_NULL_HANDLE) {
        fDestroyDebugCallback = (PFN_vkDestroyDebugReportCallbackEXT) instProc(
                fBackendContext.fInstance, "vkDestroyDebugReportCallbackEXT");
    }
    ACQUIRE_INST_VK_PROC(DestroyInstance)
    ACQUIRE_INST_VK_PROC(DeviceWaitIdle)
    ACQUIRE_INST_VK_PROC(DestroyDevice)

    fGrContext = GrContext::MakeVulkan(fBackendContext);
    if (!fGrContext) {
        return false;
    }

    return true;
}

void VulkanTestHelper::cleanup() {
    fGrContext.reset();

    fBackendContext.fMemoryAllocator.reset();
    if (fDevice != VK_NULL_HANDLE) {
        fVkDeviceWaitIdle(fDevice);
        fVkDestroyDevice(fDevice, nullptr);
        fDevice = VK_NULL_HANDLE;
    }
    if (fDebugCallback != VK_NULL_HANDLE) {
        fDestroyDebugCallback(fBackendContext.fInstance, fDebugCallback, nullptr);
    }

    if (fBackendContext.fInstance != VK_NULL_HANDLE) {
        fVkDestroyInstance(fBackendContext.fInstance, nullptr);
        fBackendContext.fInstance = VK_NULL_HANDLE;
    }

    delete fExtensions;

    sk_gpu_test::FreeVulkanFeaturesStructs(fFeatures);
    delete fFeatures;
}

sk_sp<SkSurface> VulkanTestHelper::createSkSurface(skiatest::Reporter* reporter) {
    const int kW = 8;
    const int kH = 8;
    GrBackendTexture backendTex = this->grContext()->createBackendTexture(
        kW, kH, kRGBA_8888_SkColorType, GrMipMapped::kNo, GrRenderable::kYes,
        fIsProtected ? GrProtected::kYes : GrProtected::kNo);
    REPORTER_ASSERT(reporter, backendTex.isValid());
    REPORTER_ASSERT(reporter, backendTex.isProtected() == fIsProtected);

    SkSurfaceProps surfaceProps =
        SkSurfaceProps(0, SkSurfaceProps::kLegacyFontHost_InitType);
    sk_sp<SkSurface> surface = SkSurface::MakeFromBackendTexture(
        this->grContext(), backendTex, kTopLeft_GrSurfaceOrigin, 1,
        kRGBA_8888_SkColorType, nullptr, &surfaceProps);
    REPORTER_ASSERT(reporter, surface);
    return surface;
}

DEF_GPUTEST(VkProtectedContext_CreateNonprotectedContext, reporter, options) {
    auto nonprotectedTestHelper = std::make_unique<VulkanTestHelper>(false);
    REPORTER_ASSERT(reporter, nonprotectedTestHelper->init(reporter));
}


DEF_GPUTEST(VkProtectedContext_CreateProtectedContext, reporter, options) {
    auto protectedTestHelper = std::make_unique<VulkanTestHelper>(true);
    if (!protectedTestHelper->init(reporter)) {
        return;
    }
}

DEF_GPUTEST(VkProtectedContext_CreateProtectedSkSurface, reporter, options) {
    auto protectedTestHelper = std::make_unique<VulkanTestHelper>(true);
    if (!protectedTestHelper->init(reporter)) {
        return;
    }
    REPORTER_ASSERT(reporter, protectedTestHelper->grContext() != nullptr);

    const int kW = 8;
    const int kH = 8;
    GrBackendTexture backendTex =
        protectedTestHelper->grContext()->createBackendTexture(
            kW, kH, kRGBA_8888_SkColorType, GrMipMapped::kNo, GrRenderable::kNo,
            GrProtected::kYes);
    REPORTER_ASSERT(reporter, backendTex.isValid());
    REPORTER_ASSERT(reporter, backendTex.isProtected());

    SkSurfaceProps surfaceProps =
        SkSurfaceProps(0, SkSurfaceProps::kLegacyFontHost_InitType);
    sk_sp<SkSurface> surface = SkSurface::MakeFromBackendTextureAsRenderTarget(
        protectedTestHelper->grContext(), backendTex, kTopLeft_GrSurfaceOrigin, 1,
        kRGBA_8888_SkColorType, nullptr, &surfaceProps);
    REPORTER_ASSERT(reporter, surface);

    protectedTestHelper->grContext()->deleteBackendTexture(backendTex);
}

DEF_GPUTEST(VkProtectedContext_CreateNonprotectedTextureInProtectedContext, reporter, options) {
    auto protectedTestHelper = std::make_unique<VulkanTestHelper>(true);
    if (!protectedTestHelper->init(reporter)) {
        return;
    }
    REPORTER_ASSERT(reporter, protectedTestHelper->grContext() != nullptr);

    const int kW = 8;
    const int kH = 8;
    GrBackendTexture backendTex =
        protectedTestHelper->grContext()->createBackendTexture(
            kW, kH, kRGBA_8888_SkColorType, GrMipMapped::kNo, GrRenderable::kNo,
            GrProtected::kNo);
    REPORTER_ASSERT(reporter, !backendTex.isValid());
}

DEF_GPUTEST(VkProtectedContext_CreateProtectedTextureInNonprotectedContext, reporter, options) {
    auto protectedTestHelper = std::make_unique<VulkanTestHelper>(false);
    if (!protectedTestHelper->init(reporter)) {
        return;
    }
    REPORTER_ASSERT(reporter, protectedTestHelper->grContext() != nullptr);

    const int kW = 8;
    const int kH = 8;
    GrBackendTexture backendTex =
        protectedTestHelper->grContext()->createBackendTexture(
            kW, kH, kRGBA_8888_SkColorType, GrMipMapped::kNo, GrRenderable::kNo,
            GrProtected::kYes);
    REPORTER_ASSERT(reporter, !backendTex.isValid());
}

DEF_GPUTEST(VkProtectedContext_ReadFromProtectedSurface, reporter, options) {
    auto protectedTestHelper = std::make_unique<VulkanTestHelper>(true);
    if (!protectedTestHelper->init(reporter)) {
        return;
    }
    REPORTER_ASSERT(reporter, protectedTestHelper->grContext() != nullptr);

    auto surface = protectedTestHelper->createSkSurface(reporter);
    REPORTER_ASSERT(reporter, surface);
    REPORTER_ASSERT(reporter,
                    !surface->readPixels(SkImageInfo(), nullptr, 8, 0, 0));

    protectedTestHelper->grContext()->deleteBackendTexture(
        surface->getBackendTexture(SkSurface::kFlushRead_BackendHandleAccess));
}

namespace {

struct AsyncContext {
    bool fCalled = false;
    std::unique_ptr<const SkSurface::AsyncReadResult> fResult;
};

static void async_callback(void* c, std::unique_ptr<const SkSurface::AsyncReadResult> result) {
    auto context = static_cast<AsyncContext*>(c);
    context->fResult = std::move(result);
    context->fCalled = true;
};

}  // anonymous namespace

DEF_GPUTEST(VkProtectedContext_AsyncReadFromProtectedSurface, reporter, options) {
    auto protectedTestHelper = std::make_unique<VulkanTestHelper>(true);
    if (!protectedTestHelper->init(reporter)) {
        return;
    }
    REPORTER_ASSERT(reporter, protectedTestHelper->grContext() != nullptr);

    auto surface = protectedTestHelper->createSkSurface(reporter);
    REPORTER_ASSERT(reporter, surface);
    AsyncContext cbContext;
    const auto image_info = SkImageInfo::Make(10, 10, kRGBA_8888_SkColorType, kPremul_SkAlphaType,
                                      SkColorSpace::MakeSRGB());
    surface->asyncRescaleAndReadPixelsYUV420(kIdentity_SkYUVColorSpace, SkColorSpace::MakeSRGB(),
                                             image_info.bounds(), image_info.dimensions(),
                                             SkSurface::RescaleGamma::kSrc, kNone_SkFilterQuality,
                                             &async_callback, &cbContext);
    surface->getContext()->submit();
    while (!cbContext.fCalled) {
        surface->getCanvas()->getGrContext()->checkAsyncWorkCompletion();
    }
    REPORTER_ASSERT(reporter, !cbContext.fResult);

    protectedTestHelper->grContext()->deleteBackendTexture(
        surface->getBackendTexture(SkSurface::kFlushRead_BackendHandleAccess));
}

DEF_GPUTEST(VkProtectedContext_DrawRectangle, reporter, options) {
    auto protectedTestHelper = std::make_unique<VulkanTestHelper>(true);
    if (!protectedTestHelper->init(reporter)) {
        return;
    }
    REPORTER_ASSERT(reporter, protectedTestHelper->grContext() != nullptr);

    auto surface = protectedTestHelper->createSkSurface(reporter);
    REPORTER_ASSERT(reporter, surface);
    SkCanvas* canvas = surface->getCanvas();
    REPORTER_ASSERT(reporter, canvas);
    SkPaint paint;
    paint.setColor(SK_ColorBLACK);
    canvas->drawRect(SkRect::MakeWH(4, 4), paint);

    GrFlushInfo flushInfo;
    flushInfo.fFlags = kSyncCpu_GrFlushFlag;
    surface->flush(SkSurface::BackendSurfaceAccess::kNoAccess, flushInfo);
    surface->getContext()->submit(true);
    protectedTestHelper->grContext()->deleteBackendTexture(
        surface->getBackendTexture(SkSurface::kFlushRead_BackendHandleAccess));
}

DEF_GPUTEST(VkProtectedContext_DrawRectangleWithAntiAlias, reporter, options) {
    auto protectedTestHelper = std::make_unique<VulkanTestHelper>(true);
    if (!protectedTestHelper->init(reporter)) {
        return;
    }
    REPORTER_ASSERT(reporter, protectedTestHelper->grContext() != nullptr);

    auto surface = protectedTestHelper->createSkSurface(reporter);
    REPORTER_ASSERT(reporter, surface);
    SkCanvas* canvas = surface->getCanvas();
    REPORTER_ASSERT(reporter, canvas);
    SkPaint paint;
    paint.setColor(SK_ColorBLACK);
    paint.setAntiAlias(true);
    canvas->drawRect(SkRect::MakeWH(4, 4), paint);

    GrFlushInfo flushInfo;
    flushInfo.fFlags = kSyncCpu_GrFlushFlag;
    surface->flush(SkSurface::BackendSurfaceAccess::kNoAccess, flushInfo);
    surface->getContext()->submit(true);
    protectedTestHelper->grContext()->deleteBackendTexture(
        surface->getBackendTexture(SkSurface::kFlushRead_BackendHandleAccess));
}

DEF_GPUTEST(VkProtectedContext_DrawRectangleWithBlendMode, reporter, options) {
    auto protectedTestHelper = std::make_unique<VulkanTestHelper>(true);
    if (!protectedTestHelper->init(reporter)) {
        return;
    }
    REPORTER_ASSERT(reporter, protectedTestHelper->grContext() != nullptr);

    auto surface = protectedTestHelper->createSkSurface(reporter);
    REPORTER_ASSERT(reporter, surface);
    SkCanvas* canvas = surface->getCanvas();
    REPORTER_ASSERT(reporter, canvas);
    SkPaint paint;
    paint.setColor(SK_ColorBLACK);
    paint.setBlendMode(SkBlendMode::kColorDodge);
    canvas->drawRect(SkRect::MakeWH(4, 4), paint);

    GrFlushInfo flushInfo;
    flushInfo.fFlags = kSyncCpu_GrFlushFlag;
    surface->flush(SkSurface::BackendSurfaceAccess::kNoAccess, flushInfo);
    surface->getContext()->submit(true);
    protectedTestHelper->grContext()->deleteBackendTexture(
        surface->getBackendTexture(SkSurface::kFlushRead_BackendHandleAccess));
}

DEF_GPUTEST(VkProtectedContext_DrawRectangleWithFilter, reporter, options) {
    auto protectedTestHelper = std::make_unique<VulkanTestHelper>(true);
    if (!protectedTestHelper->init(reporter)) {
        return;
    }
    REPORTER_ASSERT(reporter, protectedTestHelper->grContext() != nullptr);

    auto surface = protectedTestHelper->createSkSurface(reporter);
    REPORTER_ASSERT(reporter, surface);
    SkCanvas* canvas = surface->getCanvas();
    REPORTER_ASSERT(reporter, canvas);
    SkPaint paint;
    paint.setColor(SK_ColorBLACK);
    paint.setStyle(SkPaint::kFill_Style);
    paint.setMaskFilter(SkMaskFilter::MakeBlur(
          SkBlurStyle::kOuter_SkBlurStyle, 1.1f));
    canvas->drawRect(SkRect::MakeWH(4, 4), paint);

    GrFlushInfo flushInfo;
    flushInfo.fFlags = kSyncCpu_GrFlushFlag;
    surface->flush(SkSurface::BackendSurfaceAccess::kNoAccess, flushInfo);
    surface->getContext()->submit(true);
    protectedTestHelper->grContext()->deleteBackendTexture(
        surface->getBackendTexture(SkSurface::kFlushRead_BackendHandleAccess));
}

DEF_GPUTEST(VkProtectedContext_DrawThinPath, reporter, options) {
    auto protectedTestHelper = std::make_unique<VulkanTestHelper>(true);
    if (!protectedTestHelper->init(reporter)) {
        return;
    }
    REPORTER_ASSERT(reporter, protectedTestHelper->grContext() != nullptr);

    auto surface = protectedTestHelper->createSkSurface(reporter);
    REPORTER_ASSERT(reporter, surface);
    SkCanvas* canvas = surface->getCanvas();
    REPORTER_ASSERT(reporter, canvas);
    SkPaint paint;
    paint.setColor(SK_ColorBLACK);
    paint.setStyle(SkPaint::kStroke_Style);
    paint.setAntiAlias(true);
    paint.setStrokeWidth(.4f);
    canvas->drawPath(SkPath().moveTo(4, 4).lineTo(6, 6), paint);

    GrFlushInfo flushInfo;
    flushInfo.fFlags = kSyncCpu_GrFlushFlag;
    surface->flush(SkSurface::BackendSurfaceAccess::kNoAccess, flushInfo);
    surface->getContext()->submit(true);
    protectedTestHelper->grContext()->deleteBackendTexture(
        surface->getBackendTexture(SkSurface::kFlushRead_BackendHandleAccess));
}

DEF_GPUTEST(VkProtectedContext_SaveLayer, reporter, options) {
    auto protectedTestHelper = std::make_unique<VulkanTestHelper>(true);
    if (!protectedTestHelper->init(reporter)) {
        return;
    }
    REPORTER_ASSERT(reporter, protectedTestHelper->grContext() != nullptr);

    auto surface = protectedTestHelper->createSkSurface(reporter);
    REPORTER_ASSERT(reporter, surface);
    SkCanvas* canvas = surface->getCanvas();
    REPORTER_ASSERT(reporter, canvas);
    canvas->saveLayer(nullptr, nullptr);
    SkPaint paint;
    paint.setColor(SK_ColorBLACK);
    canvas->drawRect(SkRect::MakeWH(4, 4), paint);
    canvas->restore();

    GrFlushInfo flushInfo;
    flushInfo.fFlags = kSyncCpu_GrFlushFlag;
    surface->flush(SkSurface::BackendSurfaceAccess::kNoAccess, flushInfo);
    surface->getContext()->submit(true);
    protectedTestHelper->grContext()->deleteBackendTexture(
        surface->getBackendTexture(SkSurface::kFlushRead_BackendHandleAccess));
}


DEF_GPUTEST(VkProtectedContext_DrawProtectedImageOnProtectedSurface, reporter, options) {
    auto protectedTestHelper = std::make_unique<VulkanTestHelper>(true);
    if (!protectedTestHelper->init(reporter)) {
        return;
    }
    REPORTER_ASSERT(reporter, protectedTestHelper->grContext() != nullptr);

    // Create protected image.
    auto surface1 = protectedTestHelper->createSkSurface(reporter);
    REPORTER_ASSERT(reporter, surface1);
    auto image = surface1->makeImageSnapshot();
    REPORTER_ASSERT(reporter, image);

    // Create protected canvas.
    auto surface2 = protectedTestHelper->createSkSurface(reporter);
    REPORTER_ASSERT(reporter, surface2);
    SkCanvas* canvas = surface2->getCanvas();
    REPORTER_ASSERT(reporter, canvas);

    canvas->drawImage(image, 0, 0);

    GrFlushInfo flushInfo;
    flushInfo.fFlags = kSyncCpu_GrFlushFlag;
    surface1->flush(SkSurface::BackendSurfaceAccess::kNoAccess, flushInfo);
    surface1->getContext()->submit(true);
    protectedTestHelper->grContext()->deleteBackendTexture(
        surface1->getBackendTexture(SkSurface::kFlushRead_BackendHandleAccess));
    surface2->flush(SkSurface::BackendSurfaceAccess::kNoAccess, flushInfo);
    surface2->getContext()->submit(true);
    protectedTestHelper->grContext()->deleteBackendTexture(
        surface2->getBackendTexture(SkSurface::kFlushRead_BackendHandleAccess));
}

//////////////////////////////////////////////////////////////////////////////////////////////////
// Test out DDLs using a protected Vulkan context

void DDLMakeRenderTargetTestImpl(GrContext* context, skiatest::Reporter* reporter);

DEF_GPUTEST(VkProtectedContext_DDLMakeRenderTargetTest, reporter, ctxInfo) {
    auto protectedTestHelper = std::make_unique<VulkanTestHelper>(true);
    if (!protectedTestHelper->init(reporter)) {
        return;
    }
    REPORTER_ASSERT(reporter, protectedTestHelper->grContext() != nullptr);

    DDLMakeRenderTargetTestImpl(protectedTestHelper->grContext(), reporter);
}

void DDLSurfaceCharacterizationTestImpl(GrContext* context, skiatest::Reporter* reporter);

DEF_GPUTEST(VkProtectedContext_DDLSurfaceCharacterizationTest, reporter, ctxInfo) {
    auto protectedTestHelper = std::make_unique<VulkanTestHelper>(true);
    if (!protectedTestHelper->init(reporter)) {
        return;
    }
    REPORTER_ASSERT(reporter, protectedTestHelper->grContext() != nullptr);

    DDLSurfaceCharacterizationTestImpl(protectedTestHelper->grContext(), reporter);
}

#endif  // SK_SUPPORT_GPU && defined(SK_VULKAN)
