Robert Phillips | de2bca2 | 2020-06-11 12:34:03 -0400 | [diff] [blame] | 1 | /* |
| 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" |
| 14 | #include "include/core/SkImage.h" |
| 15 | #include "include/core/SkPaint.h" |
| 16 | #include "include/core/SkSize.h" |
| 17 | #include "include/core/SkString.h" |
Robert Phillips | b87b39b | 2020-07-01 14:45:24 -0400 | [diff] [blame] | 18 | #include "include/gpu/GrDirectContext.h" |
Robert Phillips | de2bca2 | 2020-06-11 12:34:03 -0400 | [diff] [blame] | 19 | #include "tools/gpu/vk/VkYcbcrSamplerHelper.h" |
| 20 | |
Robert Phillips | 5f0cda4 | 2020-06-15 14:26:58 -0400 | [diff] [blame] | 21 | static void release_ycbcrhelper(void* releaseContext) { |
| 22 | VkYcbcrSamplerHelper* ycbcrHelper = reinterpret_cast<VkYcbcrSamplerHelper*>(releaseContext); |
| 23 | delete ycbcrHelper; |
| 24 | } |
Robert Phillips | de2bca2 | 2020-06-11 12:34:03 -0400 | [diff] [blame] | 25 | |
| 26 | namespace skiagm { |
| 27 | |
| 28 | // This GM exercises the native YCbCr image format on Vulkan |
| 29 | class YCbCrImageGM : public GpuGM { |
| 30 | public: |
| 31 | YCbCrImageGM() { |
| 32 | this->setBGColor(0xFFCCCCCC); |
| 33 | } |
| 34 | |
| 35 | protected: |
| 36 | |
| 37 | SkString onShortName() override { |
| 38 | return SkString("ycbcrimage"); |
| 39 | } |
| 40 | |
| 41 | SkISize onISize() override { |
| 42 | return SkISize::Make(2*kPad+kImageSize, 2*kPad+kImageSize); |
| 43 | } |
| 44 | |
Robert Phillips | 057c33f | 2020-07-17 11:59:01 -0400 | [diff] [blame] | 45 | DrawResult createYCbCrImage(GrDirectContext* dContext, SkString* errorMsg) { |
| 46 | std::unique_ptr<VkYcbcrSamplerHelper> ycbcrHelper(new VkYcbcrSamplerHelper(dContext)); |
Robert Phillips | 5f0cda4 | 2020-06-15 14:26:58 -0400 | [diff] [blame] | 47 | |
| 48 | if (!ycbcrHelper->isYCbCrSupported()) { |
| 49 | *errorMsg = "YCbCr sampling not supported."; |
| 50 | return skiagm::DrawResult::kSkip; |
| 51 | } |
| 52 | |
| 53 | if (!ycbcrHelper->createBackendTexture(kImageSize, kImageSize)) { |
| 54 | *errorMsg = "Failed to create I420 backend texture."; |
| 55 | return skiagm::DrawResult::kFail; |
| 56 | } |
| 57 | |
| 58 | SkASSERT(!fYCbCrImage); |
Robert Phillips | 057c33f | 2020-07-17 11:59:01 -0400 | [diff] [blame] | 59 | fYCbCrImage = SkImage::MakeFromTexture(dContext, ycbcrHelper->backendTexture(), |
Robert Phillips | 5f0cda4 | 2020-06-15 14:26:58 -0400 | [diff] [blame] | 60 | kTopLeft_GrSurfaceOrigin, kRGB_888x_SkColorType, |
| 61 | kPremul_SkAlphaType, nullptr, |
| 62 | release_ycbcrhelper, ycbcrHelper.get()); |
| 63 | if (!fYCbCrImage) { |
| 64 | *errorMsg = "Failed to create I420 image."; |
| 65 | return DrawResult::kFail; |
| 66 | } |
| 67 | |
| 68 | ycbcrHelper.release(); |
| 69 | return DrawResult::kOk; |
| 70 | } |
| 71 | |
Robert Phillips | b87b39b | 2020-07-01 14:45:24 -0400 | [diff] [blame] | 72 | DrawResult onGpuSetup(GrDirectContext* context, SkString* errorMsg) override { |
Robert Phillips | c869ff7 | 2020-06-19 09:50:33 -0400 | [diff] [blame] | 73 | if (!context || context->abandoned()) { |
Robert Phillips | 889d613 | 2020-06-16 11:11:33 -0400 | [diff] [blame] | 74 | return DrawResult::kSkip; |
| 75 | } |
| 76 | |
Robert Phillips | 5f0cda4 | 2020-06-15 14:26:58 -0400 | [diff] [blame] | 77 | if (context->backend() != GrBackendApi::kVulkan) { |
| 78 | *errorMsg = "This GM requires a Vulkan context."; |
| 79 | return DrawResult::kSkip; |
| 80 | } |
| 81 | |
| 82 | DrawResult result = this->createYCbCrImage(context, errorMsg); |
| 83 | if (result != DrawResult::kOk) { |
| 84 | return result; |
| 85 | } |
| 86 | |
| 87 | return DrawResult::kOk; |
| 88 | } |
| 89 | |
Robert Phillips | b795bea | 2020-06-25 12:38:53 -0400 | [diff] [blame] | 90 | void onGpuTeardown() override { |
| 91 | fYCbCrImage = nullptr; |
| 92 | } |
| 93 | |
Robert Phillips | 95c250c | 2020-06-29 15:36:12 -0400 | [diff] [blame] | 94 | DrawResult onDraw(GrRecordingContext*, GrRenderTargetContext*, |
| 95 | SkCanvas* canvas, SkString*) override { |
Robert Phillips | 5f0cda4 | 2020-06-15 14:26:58 -0400 | [diff] [blame] | 96 | SkASSERT(fYCbCrImage); |
Robert Phillips | de2bca2 | 2020-06-11 12:34:03 -0400 | [diff] [blame] | 97 | |
| 98 | SkPaint paint; |
| 99 | paint.setFilterQuality(kLow_SkFilterQuality); |
| 100 | |
Robert Phillips | 5f0cda4 | 2020-06-15 14:26:58 -0400 | [diff] [blame] | 101 | canvas->drawImage(fYCbCrImage, kPad, kPad, &paint); |
Robert Phillips | de2bca2 | 2020-06-11 12:34:03 -0400 | [diff] [blame] | 102 | return DrawResult::kOk; |
| 103 | } |
| 104 | |
| 105 | private: |
| 106 | static const int kImageSize = 112; |
| 107 | static const int kPad = 8; |
| 108 | |
Robert Phillips | 5f0cda4 | 2020-06-15 14:26:58 -0400 | [diff] [blame] | 109 | sk_sp<SkImage> fYCbCrImage; |
| 110 | |
John Stiles | 7571f9e | 2020-09-02 22:42:33 -0400 | [diff] [blame] | 111 | using INHERITED = GpuGM; |
Robert Phillips | de2bca2 | 2020-06-11 12:34:03 -0400 | [diff] [blame] | 112 | }; |
| 113 | |
| 114 | ////////////////////////////////////////////////////////////////////////////// |
| 115 | |
| 116 | DEF_GM(return new YCbCrImageGM;) |
| 117 | |
John Stiles | a6841be | 2020-08-06 14:11:56 -0400 | [diff] [blame] | 118 | } // namespace skiagm |
Robert Phillips | de2bca2 | 2020-06-11 12:34:03 -0400 | [diff] [blame] | 119 | |
| 120 | #endif // SK_VULKAN |