2 * Copyright 2020 Google LLC
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
10 // This test only works with the Vulkan backend.
13 #include "include/core/SkCanvas.h"
14 #include "include/core/SkColorSpace.h"
15 #include "include/core/SkImage.h"
16 #include "include/core/SkPaint.h"
17 #include "include/core/SkSize.h"
18 #include "include/core/SkString.h"
19 #include "include/gpu/GrDirectContext.h"
20 #include "tools/gpu/vk/VkYcbcrSamplerHelper.h"
22 static void release_ycbcrhelper(void* releaseContext) {
23 VkYcbcrSamplerHelper* ycbcrHelper = reinterpret_cast<VkYcbcrSamplerHelper*>(releaseContext);
29 // This GM exercises the native YCbCr image format on Vulkan
30 class YCbCrImageGM : public GM {
33 this->setBGColor(0xFFCCCCCC);
38 SkString onShortName() override {
39 return SkString("ycbcrimage");
42 SkISize onISize() override {
43 return SkISize::Make(2*kPad+kImageSize, 2*kPad+kImageSize);
46 DrawResult createYCbCrImage(GrDirectContext* dContext, SkString* errorMsg) {
47 std::unique_ptr<VkYcbcrSamplerHelper> ycbcrHelper(new VkYcbcrSamplerHelper(dContext));
49 if (!ycbcrHelper->isYCbCrSupported()) {
50 *errorMsg = "YCbCr sampling not supported.";
51 return skiagm::DrawResult::kSkip;
54 if (!ycbcrHelper->createBackendTexture(kImageSize, kImageSize)) {
55 *errorMsg = "Failed to create I420 backend texture.";
56 return skiagm::DrawResult::kFail;
59 SkASSERT(!fYCbCrImage);
60 fYCbCrImage = SkImage::MakeFromTexture(dContext, ycbcrHelper->backendTexture(),
61 kTopLeft_GrSurfaceOrigin, kRGB_888x_SkColorType,
62 kPremul_SkAlphaType, nullptr,
63 release_ycbcrhelper, ycbcrHelper.get());
64 ycbcrHelper.release();
66 *errorMsg = "Failed to create I420 image.";
67 return DrawResult::kFail;
70 return DrawResult::kOk;
73 DrawResult onGpuSetup(GrDirectContext* dContext, SkString* errorMsg) override {
74 if (!dContext || dContext->abandoned()) {
75 return DrawResult::kSkip;
78 if (dContext->backend() != GrBackendApi::kVulkan) {
79 *errorMsg = "This GM requires a Vulkan context.";
80 return DrawResult::kSkip;
83 DrawResult result = this->createYCbCrImage(dContext, errorMsg);
84 if (result != DrawResult::kOk) {
88 return DrawResult::kOk;
91 void onGpuTeardown() override {
92 fYCbCrImage = nullptr;
95 DrawResult onDraw(SkCanvas* canvas, SkString*) override {
96 SkASSERT(fYCbCrImage);
98 canvas->drawImage(fYCbCrImage, kPad, kPad, SkSamplingOptions(SkFilterMode::kLinear));
99 return DrawResult::kOk;
103 static const int kImageSize = 112;
104 static const int kPad = 8;
106 sk_sp<SkImage> fYCbCrImage;
108 using INHERITED = GpuGM;
111 //////////////////////////////////////////////////////////////////////////////
113 DEF_GM(return new YCbCrImageGM;)
115 } // namespace skiagm