/*
 * 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 defined(SK_VULKAN)

#include "include/core/SkAlphaType.h"
#include "include/core/SkBlendMode.h"
#include "include/core/SkBlurTypes.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkColor.h"
#include "include/core/SkColorSpace.h"
#include "include/core/SkColorType.h"
#include "include/core/SkImageInfo.h"
#include "include/core/SkMaskFilter.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPath.h"
#include "include/core/SkRect.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkSurface.h"
#include "include/gpu/GpuTypes.h"
#include "include/gpu/ganesh/GrTypes.h"
#include "tests/CtsEnforcement.h"
#include "tests/Test.h"
#include "tools/gpu/vk/VkTestHelper.h"

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

#if defined(SK_GRAPHITE)
#include "include/gpu/graphite/BackendTexture.h"
#include "include/gpu/graphite/Context.h"
#include "include/gpu/graphite/Recorder.h"
#include "include/gpu/graphite/TextureInfo.h"
#include "include/gpu/graphite/vk/VulkanGraphiteTypes.h"
#endif

#include <memory>
#include <utility>

struct GrContextOptions;

static const int kSize = 8;

namespace {

void create_nonprotected_context(skiatest::Reporter* reporter, skiatest::TestType testType) {
    std::unique_ptr<VkTestHelper> helper = VkTestHelper::Make(testType, /* isProtected= */ false);
    REPORTER_ASSERT(reporter, helper);
}

} // anonymous namespace

DEF_GANESH_TEST(VkProtectedContext_CreateNonprotectedContext,
                reporter,
                options,
                CtsEnforcement::kNever) {
    create_nonprotected_context(reporter, skiatest::TestType::kGanesh);
}

#if defined(SK_GRAPHITE)

DEF_GRAPHITE_TEST(VkProtectedContext_CreateNonprotectedContext_Graphite,
                  reporter,
                  CtsEnforcement::kApiLevel_V) {
    create_nonprotected_context(reporter, skiatest::TestType::kGraphite);
}

#endif

DEF_GANESH_TEST(VkProtectedContext_CreateProtectedContext,
                reporter,
                options,
                CtsEnforcement::kNever) {
    std::unique_ptr<VkTestHelper> helper = VkTestHelper::Make(skiatest::TestType::kGanesh,
                                                              /* isProtected= */ true);
}

DEF_GRAPHITE_TEST(VkProtectedContext_CreateProtectedContext_Graphite,
                  reporter,
                  CtsEnforcement::kApiLevel_V) {
    std::unique_ptr<VkTestHelper> helper = VkTestHelper::Make(skiatest::TestType::kGraphite,
                                                              /* isProtected= */ true);
}

namespace {

void create_protected_surface(skiatest::Reporter* reporter, skiatest::TestType testType) {

    std::unique_ptr<VkTestHelper> helper = VkTestHelper::Make(testType, /* isProtected= */ true);
    if (!helper) {
        return;
    }

    REPORTER_ASSERT(reporter, helper->isValid());

    sk_sp<SkSurface> textureable = helper->createSurface({ kSize, kSize },
                                                         /* textureable= */ true,
                                                         /* isProtected= */ true);
    REPORTER_ASSERT(reporter, textureable);

    sk_sp<SkSurface> untextureable = helper->createSurface({ kSize, kSize },
                                                           /* textureable= */ false,
                                                           /* isProtected= */ true);
    REPORTER_ASSERT(reporter, untextureable);
}

} // anonymous namespace

DEF_GANESH_TEST(VkProtectedContext_CreateProtectedSkSurface,
                reporter,
                options,
                CtsEnforcement::kNever) {
    create_protected_surface(reporter, skiatest::TestType::kGanesh);
}

DEF_GRAPHITE_TEST(VkProtectedContext_CreateProtectedSkSurface_Graphite,
                  reporter,
                  CtsEnforcement::kApiLevel_V) {
    create_protected_surface(reporter, skiatest::TestType::kGraphite);
}

namespace {

void create_backend_texture_ganesh(skiatest::Reporter* reporter,
                                   bool contextIsProtected,
                                   bool beTexIsProtected) {

    std::unique_ptr<VkTestHelper> helper = VkTestHelper::Make(skiatest::TestType::kGanesh,
                                                              contextIsProtected);
    if (!helper) {
        return;
    }

    REPORTER_ASSERT(reporter, helper->isValid());
    GrDirectContext* dContext = helper->directContext();

    GrBackendTexture backendTex = dContext->createBackendTexture(kSize,
                                                                 kSize,
                                                                 kRGBA_8888_SkColorType,
                                                                 skgpu::Mipmapped::kNo,
                                                                 GrRenderable::kNo,
                                                                 GrProtected(beTexIsProtected));

    REPORTER_ASSERT(reporter, backendTex.isValid() == (contextIsProtected == beTexIsProtected));
    if (backendTex.isValid()) {
        REPORTER_ASSERT(reporter, backendTex.isProtected() == beTexIsProtected);
    }

    dContext->deleteBackendTexture(backendTex);
}

} // anonymous namespace

DEF_GANESH_TEST(VkProtectedContext_CreateBackendTextures,
                reporter,
                options,
                CtsEnforcement::kNever) {
    for (bool contextIsProtected : { true, false }) {
        for (bool beTexIsProtected : { true, false }) {
            create_backend_texture_ganesh(reporter, contextIsProtected, beTexIsProtected);
        }
    }
}

#if defined(SK_GRAPHITE)

namespace {

void create_backend_texture_graphite(skiatest::Reporter* reporter,
                                     bool contextIsProtected,
                                     bool beTexIsProtected) {
    using namespace skgpu::graphite;

    std::unique_ptr<VkTestHelper> helper = VkTestHelper::Make(skiatest::TestType::kGraphite,
                                                              contextIsProtected);
    if (!helper) {
        return;
    }

    REPORTER_ASSERT(reporter, helper->isValid());

    VulkanTextureInfo vkTextureInfo;
    vkTextureInfo.fFlags = beTexIsProtected ? VK_IMAGE_CREATE_PROTECTED_BIT : 0;
    vkTextureInfo.fFormat = VK_FORMAT_R8G8B8A8_UNORM;
    vkTextureInfo.fImageUsageFlags = VK_IMAGE_USAGE_SAMPLED_BIT |
                                     VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
                                     VK_IMAGE_USAGE_TRANSFER_DST_BIT;
    TextureInfo textureInfo = TextureInfos::MakeVulkan(vkTextureInfo);

    BackendTexture backendTex = helper->recorder()->createBackendTexture({ kSize, kSize },
                                                                         textureInfo);
    REPORTER_ASSERT(reporter, backendTex.isValid() == (contextIsProtected == beTexIsProtected));
    if (backendTex.isValid()) {
        REPORTER_ASSERT(reporter,
                        backendTex.info().isProtected() == skgpu::Protected(beTexIsProtected));
    }

    helper->recorder()->deleteBackendTexture(backendTex);
}

} // anonymous namespace

DEF_GRAPHITE_TEST(VkProtectedContext_CreateBackendTextures_Graphite,
                  reporter,
                  CtsEnforcement::kApiLevel_V) {
    for (bool contextIsProtected : { true, false }) {
        for (bool beTexIsProtected : { true, false }) {
            create_backend_texture_graphite(reporter, contextIsProtected, beTexIsProtected);
        }
    }
}

#endif // SK_GRAPHITE

DEF_GANESH_TEST(VkProtectedContext_ReadFromProtectedSurface,
                reporter,
                options,
                CtsEnforcement::kNever) {
    std::unique_ptr<VkTestHelper> helper = VkTestHelper::Make(skiatest::TestType::kGanesh,
                                                              /* isProtected= */ true);
    if (!helper) {
        return;
    }

    REPORTER_ASSERT(reporter, helper->isValid());

    sk_sp<SkSurface> surface = helper->createSurface({ kSize, kSize },
                                                     /* textureable= */ true,
                                                     /* isProtected= */ true);
    REPORTER_ASSERT(reporter, surface);
    REPORTER_ASSERT(reporter, !surface->readPixels(SkImageInfo(), nullptr, 8, 0, 0));
}

namespace {

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

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;
}

void async_read_from_protected_surface(skiatest::Reporter* reporter, skiatest::TestType testType) {
    std::unique_ptr<VkTestHelper> helper = VkTestHelper::Make(testType, /* isProtected= */ true);
    if (!helper) {
        return;
    }

    REPORTER_ASSERT(reporter, helper->isValid());

    sk_sp<SkSurface> surface = helper->createSurface({ kSize, kSize },
                                                     /* textureable= */ true,
                                                     /* isProtected= */ true);
    REPORTER_ASSERT(reporter, surface);
    AsyncContext cbContext;
    const SkImageInfo imageInfo = SkImageInfo::Make(6, 6, kRGBA_8888_SkColorType,
                                                    kPremul_SkAlphaType, SkColorSpace::MakeSRGB());

    if (testType == skiatest::TestType::kGanesh) {
        surface->asyncRescaleAndReadPixelsYUV420(kIdentity_SkYUVColorSpace,
                                                 SkColorSpace::MakeSRGB(),
                                                 imageInfo.bounds(),
                                                 imageInfo.dimensions(),
                                                 SkSurface::RescaleGamma::kSrc,
                                                 SkSurface::RescaleMode::kNearest,
                                                 &async_callback,
                                                 &cbContext);
    }
#if defined(SK_GRAPHITE)
    else {
        // Graphite deprecates SkSurface::asyncRescaleAndReadPixelsYUVA420 in favor of
        // Context::asyncRescaleAndReadPixelsYUV420.
        skgpu::graphite::Context* context = helper->context();

        context->asyncRescaleAndReadPixelsYUV420(surface.get(),
                                                 kIdentity_SkYUVColorSpace,
                                                 SkColorSpace::MakeSRGB(),
                                                 imageInfo.bounds(),
                                                 imageInfo.dimensions(),
                                                 SkSurface::RescaleGamma::kSrc,
                                                 SkSurface::RescaleMode::kNearest,
                                                 &async_callback,
                                                 &cbContext);
    }
#endif

    helper->submitAndWaitForCompletion(&cbContext.fCalled);
    REPORTER_ASSERT(reporter, !cbContext.fResult);
}

}  // anonymous namespace

DEF_GANESH_TEST(VkProtectedContext_AsyncReadFromProtectedSurface,
                reporter,
                options,
                CtsEnforcement::kNever) {
    async_read_from_protected_surface(reporter, skiatest::TestType::kGanesh);
}

DEF_GRAPHITE_TEST(VkProtectedContext_AsyncReadFromProtectedSurface_Graphite,
                  reporter,
                  CtsEnforcement::kApiLevel_V) {
    async_read_from_protected_surface(reporter, skiatest::TestType::kGraphite);
}

namespace {

void draw_rectangle(skiatest::Reporter* reporter, skiatest::TestType testType) {
    std::unique_ptr<VkTestHelper> helper = VkTestHelper::Make(testType, /* isProtected= */ true);
    if (!helper) {
        return;
    }

    REPORTER_ASSERT(reporter, helper->isValid());

    sk_sp<SkSurface> surface = helper->createSurface({ kSize, kSize },
                                                     /* textureable= */ true,
                                                     /* isProtected= */ true);
    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);
}

}  // anonymous namespace

DEF_GANESH_TEST(VkProtectedContext_DrawRectangle,
                reporter,
                options,
                CtsEnforcement::kNever) {
    draw_rectangle(reporter, skiatest::TestType::kGanesh);
}

DEF_GRAPHITE_TEST(VkProtectedContext_DrawRectangle_Graphite,
                  reporter,
                  CtsEnforcement::kApiLevel_V) {
    draw_rectangle(reporter, skiatest::TestType::kGraphite);
}

namespace {

void draw_rectangle_with_aa(skiatest::Reporter* reporter, skiatest::TestType testType) {
    std::unique_ptr<VkTestHelper> helper = VkTestHelper::Make(testType, /* isProtected= */ true);
    if (!helper) {
        return;
    }

    REPORTER_ASSERT(reporter, helper->isValid());

    sk_sp<SkSurface> surface = helper->createSurface({ kSize, kSize },
                                                     /* textureable= */ true,
                                                     /* isProtected= */ true);
    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);
}

}  // anonymous namespace

DEF_GANESH_TEST(VkProtectedContext_DrawRectangleWithAntiAlias,
                reporter,
                options,
                CtsEnforcement::kNever) {
    draw_rectangle_with_aa(reporter, skiatest::TestType::kGanesh);
}

DEF_GRAPHITE_TEST(VkProtectedContext_DrawRectangleWithAntiAlias_Graphite,
                  reporter,
                  CtsEnforcement::kApiLevel_V) {
    draw_rectangle_with_aa(reporter, skiatest::TestType::kGraphite);
}

namespace {

void draw_rectangle_with_blendmode(skiatest::Reporter* reporter, skiatest::TestType testType) {
    std::unique_ptr<VkTestHelper> helper = VkTestHelper::Make(testType, /* isProtected= */ true);
    if (!helper) {
        return;
    }

    REPORTER_ASSERT(reporter, helper->isValid());

    sk_sp<SkSurface> surface = helper->createSurface({ kSize, kSize },
                                                     /* textureable= */ true,
                                                     /* isProtected= */ true);
    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);
}

}  // anonymous namespace

DEF_GANESH_TEST(VkProtectedContext_DrawRectangleWithBlendMode,
                reporter,
                options,
                CtsEnforcement::kNever) {
    draw_rectangle_with_blendmode(reporter, skiatest::TestType::kGanesh);
}

DEF_GRAPHITE_TEST(VkProtectedContext_DrawRectangleWithBlendMode_Graphite,
                  reporter,
                  CtsEnforcement::kApiLevel_V) {
    draw_rectangle_with_blendmode(reporter, skiatest::TestType::kGraphite);
}

namespace {

void draw_rectangle_with_filter(skiatest::Reporter* reporter, skiatest::TestType testType) {
    std::unique_ptr<VkTestHelper> helper = VkTestHelper::Make(testType, /* isProtected= */ true);
    if (!helper) {
        return;
    }

    REPORTER_ASSERT(reporter, helper->isValid());

    sk_sp<SkSurface> surface = helper->createSurface({ kSize, kSize },
                                                     /* textureable= */ true,
                                                     /* isProtected= */ true);
    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, 30.0f));
    canvas->drawRect(SkRect::MakeWH(4, 4), paint);
}

}  // anonymous namespace

DEF_GANESH_TEST(VkProtectedContext_DrawRectangleWithFilter,
                reporter,
                options,
                CtsEnforcement::kNever) {
    draw_rectangle_with_filter(reporter, skiatest::TestType::kGanesh);
}

DEF_GRAPHITE_TEST(VkProtectedContext_DrawRectangleWithFilter_Graphite,
                  reporter,
                  CtsEnforcement::kApiLevel_V) {
    draw_rectangle_with_filter(reporter, skiatest::TestType::kGraphite);
}

namespace {

void draw_thin_path(skiatest::Reporter* reporter, skiatest::TestType testType) {
    constexpr bool kIsProtected = true;

    std::unique_ptr<VkTestHelper> helper = VkTestHelper::Make(testType, kIsProtected);
    if (!helper) {
        return;
    }

    REPORTER_ASSERT(reporter, helper->isValid());

    sk_sp<SkSurface> surface = helper->createSurface({ kSize, kSize },
                                                     /* textureable= */ true,
                                                     kIsProtected);
    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);
}

}  // anonymous namespace

DEF_GANESH_TEST(VkProtectedContext_DrawThinPath,
                reporter,
                options,
                CtsEnforcement::kNever) {
    draw_thin_path(reporter, skiatest::TestType::kGanesh);
}

DEF_GRAPHITE_TEST(VkProtectedContext_DrawThinPath_Graphite,
                  reporter,
                  CtsEnforcement::kApiLevel_V) {
    draw_thin_path(reporter, skiatest::TestType::kGraphite);
}

namespace {

void save_layer(skiatest::Reporter* reporter, skiatest::TestType testType) {
    std::unique_ptr<VkTestHelper> helper = VkTestHelper::Make(testType, /* isProtected= */ true);
    if (!helper) {
        return;
    }

    REPORTER_ASSERT(reporter, helper->isValid());

    sk_sp<SkSurface> surface = helper->createSurface({ kSize, kSize },
                                                     /* textureable= */ true,
                                                     /* isProtected= */ true);
    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();
}

}  // anonymous namespace

DEF_GANESH_TEST(VkProtectedContext_SaveLayer,
                reporter,
                options,
                CtsEnforcement::kNever) {
    save_layer(reporter, skiatest::TestType::kGanesh);
}

DEF_GRAPHITE_TEST(VkProtectedContext_SaveLayer_Graphite,
                  reporter,
                  CtsEnforcement::kApiLevel_V) {
    save_layer(reporter, skiatest::TestType::kGraphite);
}

namespace {

void draw_protected_image_on_protected_surface(skiatest::Reporter* reporter,
                                               skiatest::TestType testType) {
    constexpr bool kIsProtected = true;

    std::unique_ptr<VkTestHelper> helper = VkTestHelper::Make(testType, kIsProtected);
    if (!helper) {
        return;
    }

    REPORTER_ASSERT(reporter, helper->isValid());

    // Create protected image.
    sk_sp<SkSurface> surface1 = helper->createSurface({ kSize, kSize },
                                                      /* textureable= */ true,
                                                      kIsProtected);
    REPORTER_ASSERT(reporter, surface1);
    sk_sp<SkImage> image = surface1->makeImageSnapshot();
    REPORTER_ASSERT(reporter, image);
    REPORTER_ASSERT(reporter, image->isProtected() == kIsProtected);

    // Create protected canvas.
    sk_sp<SkSurface> surface2 = helper->createSurface({ kSize, kSize },
                                                      /* textureable= */ true,
                                                      kIsProtected);
    REPORTER_ASSERT(reporter, surface2);
    SkCanvas* canvas = surface2->getCanvas();
    REPORTER_ASSERT(reporter, canvas);

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

}  // anonymous namespace

DEF_GANESH_TEST(VkProtectedContext_DrawProtectedImageOnProtectedSurface,
                reporter,
                options,
                CtsEnforcement::kNever) {
    draw_protected_image_on_protected_surface(reporter, skiatest::TestType::kGanesh);
}

DEF_GRAPHITE_TEST(VkProtectedContext_DrawProtectedImageOnProtectedSurface_Graphite,
                  reporter,
                  CtsEnforcement::kApiLevel_V) {
    draw_protected_image_on_protected_surface(reporter, skiatest::TestType::kGraphite);
}

#endif  // SK_VULKAN
