/*
 * 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/SkBitmap.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"
#include "include/gpu/ganesh/SkSurfaceGanesh.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::kNextRelease) {
    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::kNextRelease) {
    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::kNextRelease) {
    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::kNextRelease) {
    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));
}

// Graphite does not perform Copy-on-Write which is why there is no DEF_GRAPHITE_TEST correlate
DEF_GANESH_TEST(VkProtectedContext_CopyOnWrite,
                reporter,
                options,
                CtsEnforcement::kNever) {
    std::unique_ptr<VkTestHelper> helper = VkTestHelper::Make(skiatest::TestType::kGanesh,
                                                              /* isProtected= */ true);
    if (!helper) {
        return;
    }

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

    GrDirectContext* dContext = helper->directContext();

    SkImageInfo ii = SkImageInfo::Make({ kSize, kSize },
                                       kRGBA_8888_SkColorType,
                                       kPremul_SkAlphaType);

    // We can't use VkTestHelper::createSurface here bc that will wrap a backend
    // texture which blocks the copy-on-write-behavior
    sk_sp<SkSurface> surface = SkSurfaces::RenderTarget(dContext,
                                                        skgpu::Budgeted::kNo,
                                                        ii,
                                                        /* sampleCount= */ 1,
                                                        kBottomLeft_GrSurfaceOrigin,
                                                        /* surfaceProps= */ nullptr,
                                                        /* shouldCreateWithMips= */ false,
                                                        /* isProtected= */ true);


    REPORTER_ASSERT(reporter, surface);
    SkCanvas* canvas = surface->getCanvas();
    REPORTER_ASSERT(reporter, canvas);

    sk_sp<SkImage> imageBefore = surface->makeImageSnapshot();
    REPORTER_ASSERT(reporter, imageBefore);
    REPORTER_ASSERT(reporter, imageBefore->isProtected());

    SkPaint paint;
    paint.setColor(SK_ColorBLACK);
    canvas->drawRect(SkRect::MakeWH(4, 4), paint);

    sk_sp<SkImage> imageAfter = surface->makeImageSnapshot();
    REPORTER_ASSERT(reporter, imageAfter);
    REPORTER_ASSERT(reporter, imageAfter->isProtected());

    REPORTER_ASSERT(reporter, imageBefore != imageAfter);

    SkBitmap readback;
    readback.allocPixels(imageAfter->imageInfo());
    REPORTER_ASSERT(reporter, !imageAfter->readPixels(dContext, readback.pixmap(), 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::kNextRelease) {
    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::kNextRelease) {
    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::kNextRelease) {
    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::kNextRelease) {
    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::kNextRelease) {
    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::kNextRelease) {
    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::kNextRelease) {
    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::kNextRelease) {
    draw_protected_image_on_protected_surface(reporter, skiatest::TestType::kGraphite);
}

#endif  // SK_VULKAN
