blob: 0707b37d2a8de6b7834293b3a6ed71162c1f163c [file] [log] [blame]
/*
* 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/GrTypes.h"
#include "tests/CtsEnforcement.h"
#include "tests/Test.h"
#include "tools/gpu/vk/VkTestHelper.h"
#if defined(SK_GANESH)
#include "include/gpu/GrBackendSurface.h"
#include "include/gpu/GrDirectContext.h"
#endif
#if defined(SK_GRAPHITE)
#include "include/gpu/graphite/BackendTexture.h"
#include "include/gpu/graphite/Recorder.h"
#include "include/gpu/graphite/TextureInfo.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(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));
}
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(10, 10, kRGBA_8888_SkColorType,
kPremul_SkAlphaType, SkColorSpace::MakeSRGB());
surface->asyncRescaleAndReadPixelsYUV420(kIdentity_SkYUVColorSpace, SkColorSpace::MakeSRGB(),
imageInfo.bounds(), imageInfo.dimensions(),
SkSurface::RescaleGamma::kSrc,
SkSurface::RescaleMode::kNearest,
&async_callback, &cbContext);
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