blob: 055cb67e0e21af739ebad3d8b46911075d6b6c93 [file] [log] [blame]
Robert Phillipsde2bca22020-06-11 12:34:03 -04001/*
2 * Copyright 2020 Google LLC
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "gm/gm.h"
9
10// This test only works with the Vulkan backend.
11#ifdef SK_VULKAN
12
13#include "include/core/SkCanvas.h"
Kevin Lubick5e8f45f2022-03-31 15:07:44 -040014#include "include/core/SkColorSpace.h"
Robert Phillipsde2bca22020-06-11 12:34:03 -040015#include "include/core/SkImage.h"
16#include "include/core/SkPaint.h"
17#include "include/core/SkSize.h"
18#include "include/core/SkString.h"
Robert Phillipsb87b39b2020-07-01 14:45:24 -040019#include "include/gpu/GrDirectContext.h"
Kevin Lubick77472bf2023-03-24 07:11:17 -040020#include "include/gpu/ganesh/SkImageGanesh.h"
Robert Phillipsde2bca22020-06-11 12:34:03 -040021#include "tools/gpu/vk/VkYcbcrSamplerHelper.h"
22
Robert Phillips5f0cda42020-06-15 14:26:58 -040023static void release_ycbcrhelper(void* releaseContext) {
24 VkYcbcrSamplerHelper* ycbcrHelper = reinterpret_cast<VkYcbcrSamplerHelper*>(releaseContext);
25 delete ycbcrHelper;
26}
Robert Phillipsde2bca22020-06-11 12:34:03 -040027
28namespace skiagm {
29
30// This GM exercises the native YCbCr image format on Vulkan
Robert Phillipsedcd4312021-06-03 10:14:16 -040031class YCbCrImageGM : public GM {
Robert Phillipsde2bca22020-06-11 12:34:03 -040032public:
33 YCbCrImageGM() {
34 this->setBGColor(0xFFCCCCCC);
35 }
36
37protected:
Leandro Lovisolo24fa2112023-08-15 19:05:17 +000038 SkString getName() const override { return SkString("ycbcrimage"); }
Robert Phillipsde2bca22020-06-11 12:34:03 -040039
Leandro Lovisolo8f023882023-08-15 21:13:52 +000040 SkISize getISize() override {
Robert Phillipsde2bca22020-06-11 12:34:03 -040041 return SkISize::Make(2*kPad+kImageSize, 2*kPad+kImageSize);
42 }
43
Robert Phillips057c33f2020-07-17 11:59:01 -040044 DrawResult createYCbCrImage(GrDirectContext* dContext, SkString* errorMsg) {
45 std::unique_ptr<VkYcbcrSamplerHelper> ycbcrHelper(new VkYcbcrSamplerHelper(dContext));
Robert Phillips5f0cda42020-06-15 14:26:58 -040046
47 if (!ycbcrHelper->isYCbCrSupported()) {
48 *errorMsg = "YCbCr sampling not supported.";
49 return skiagm::DrawResult::kSkip;
50 }
51
52 if (!ycbcrHelper->createBackendTexture(kImageSize, kImageSize)) {
53 *errorMsg = "Failed to create I420 backend texture.";
54 return skiagm::DrawResult::kFail;
55 }
56
57 SkASSERT(!fYCbCrImage);
Kevin Lubick77472bf2023-03-24 07:11:17 -040058 fYCbCrImage = SkImages::BorrowTextureFrom(dContext,
59 ycbcrHelper->backendTexture(),
60 kTopLeft_GrSurfaceOrigin,
61 kRGB_888x_SkColorType,
62 kPremul_SkAlphaType,
63 nullptr,
64 release_ycbcrhelper,
65 ycbcrHelper.get());
Peng Huanga42ed482021-03-05 09:44:43 -050066 ycbcrHelper.release();
Robert Phillips5f0cda42020-06-15 14:26:58 -040067 if (!fYCbCrImage) {
68 *errorMsg = "Failed to create I420 image.";
69 return DrawResult::kFail;
70 }
71
Robert Phillips5f0cda42020-06-15 14:26:58 -040072 return DrawResult::kOk;
73 }
74
Brian Salomonc759bbf2023-12-05 11:11:27 -050075 DrawResult onGpuSetup(SkCanvas* canvas, SkString* errorMsg, GraphiteTestContext*) override {
Jim Van Vertha8624432023-02-13 16:48:09 -050076 GrDirectContext* dContext = GrAsDirectContext(canvas->recordingContext());
Robert Phillipsedcd4312021-06-03 10:14:16 -040077 if (!dContext || dContext->abandoned()) {
Robert Phillips889d6132020-06-16 11:11:33 -040078 return DrawResult::kSkip;
79 }
80
Robert Phillipsedcd4312021-06-03 10:14:16 -040081 if (dContext->backend() != GrBackendApi::kVulkan) {
Robert Phillips5f0cda42020-06-15 14:26:58 -040082 *errorMsg = "This GM requires a Vulkan context.";
83 return DrawResult::kSkip;
84 }
85
Robert Phillipsedcd4312021-06-03 10:14:16 -040086 DrawResult result = this->createYCbCrImage(dContext, errorMsg);
Robert Phillips5f0cda42020-06-15 14:26:58 -040087 if (result != DrawResult::kOk) {
88 return result;
89 }
90
91 return DrawResult::kOk;
92 }
93
Robert Phillipsb795bea2020-06-25 12:38:53 -040094 void onGpuTeardown() override {
95 fYCbCrImage = nullptr;
96 }
97
Robert Phillipsedcd4312021-06-03 10:14:16 -040098 DrawResult onDraw(SkCanvas* canvas, SkString*) override {
Robert Phillips5f0cda42020-06-15 14:26:58 -040099 SkASSERT(fYCbCrImage);
Robert Phillipsde2bca22020-06-11 12:34:03 -0400100
Mike Reed9ced5e62021-01-28 13:22:05 -0500101 canvas->drawImage(fYCbCrImage, kPad, kPad, SkSamplingOptions(SkFilterMode::kLinear));
Robert Phillipsde2bca22020-06-11 12:34:03 -0400102 return DrawResult::kOk;
103 }
104
105private:
106 static const int kImageSize = 112;
107 static const int kPad = 8;
108
Robert Phillips5f0cda42020-06-15 14:26:58 -0400109 sk_sp<SkImage> fYCbCrImage;
110
John Stiles7571f9e2020-09-02 22:42:33 -0400111 using INHERITED = GpuGM;
Robert Phillipsde2bca22020-06-11 12:34:03 -0400112};
113
114//////////////////////////////////////////////////////////////////////////////
115
116DEF_GM(return new YCbCrImageGM;)
117
John Stilesa6841be2020-08-06 14:11:56 -0400118} // namespace skiagm
Robert Phillipsde2bca22020-06-11 12:34:03 -0400119
120#endif // SK_VULKAN