xref: /aosp_15_r20/external/skia/gm/ducky_yuv_blend.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1 /*
2  * Copyright 2019 Google Inc.
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 #include "include/core/SkCanvas.h"
10 #include "include/core/SkPaint.h"
11 #include "include/gpu/ganesh/GrRecordingContext.h"
12 #include "src/core/SkCachedData.h"
13 #include "src/image/SkImage_Base.h"
14 #include "tools/DecodeUtils.h"
15 #include "tools/Resources.h"
16 #include "tools/ToolUtils.h"
17 #include "tools/gpu/YUVUtils.h"
18 
19 // Modeled on the layout test css3/blending/background-blend-mode-image-image.html to reproduce
20 // skbug.com/9619
21 DEF_SIMPLE_GM_CAN_FAIL(ducky_yuv_blend, canvas, errorMsg, 560, 1130) {
22     sk_sp<SkImage> duckyBG = ToolUtils::GetResourceAsImage("images/ducky.png");
23     sk_sp<SkImage> duckyFG[2] = {ToolUtils::GetResourceAsImage("images/ducky.jpg"), nullptr};
24     if (!duckyFG[0] || !duckyBG) {
25         *errorMsg = "Image(s) failed to load.";
26         return skiagm::DrawResult::kFail;
27     }
28 
29     // If we're on the GPU we do a second round of draws where the source image is YUV planes.
30     // Otherwise we just draw the original again,
31     if (auto* rContext = canvas->recordingContext(); rContext && !rContext->abandoned()) {
32         auto lazyYUV = sk_gpu_test::LazyYUVImage::Make(GetResourceAsData("images/ducky.jpg"),
33                                                        skgpu::Mipmapped::kYes);
34         if (lazyYUV) {
35             duckyFG[1] = lazyYUV->refImage(rContext, sk_gpu_test::LazyYUVImage::Type::kFromPixmaps);
36         }
37         if (!duckyFG[1]) {
38             return skiagm::DrawResult::kFail;
39         }
40     } else {
41         duckyFG[1] = duckyFG[0];
42     }
43 
44     static constexpr int kNumPerRow = 4;
45     static constexpr int kPad = 10;
46     static constexpr auto kDstRect = SkRect::MakeWH(130, 130);
47     int rowCnt = 0;
48     canvas->translate(kPad, kPad);
49     canvas->save();
__anon6bb07ed90102null50     auto newRow = [&] {
51         canvas->restore();
52         canvas->translate(0, kDstRect.height() + kPad);
53         canvas->save();
54         rowCnt = 0;
55     };
56     SkSamplingOptions sampling(SkFilterMode::kLinear,
57                                SkMipmapMode::kNearest);
58     ToolUtils::draw_checkerboard(
59             canvas, SK_ColorDKGRAY, SK_ColorLTGRAY, (kDstRect.height() + kPad)/5);
60     for (auto& fg : duckyFG) {
61         for (int bm = static_cast<int>(SkBlendMode::kLastCoeffMode) + 1;
62              bm < static_cast<int>(SkBlendMode::kLastMode);
63              ++bm) {
64             canvas->drawImageRect(duckyBG, kDstRect, sampling, nullptr);
65             SkPaint paint;
66             paint.setBlendMode(static_cast<SkBlendMode>(bm));
67             canvas->drawImageRect(fg, kDstRect, sampling, &paint);
68             canvas->translate(kDstRect.width() + kPad, 0);
69             if (++rowCnt == kNumPerRow) {
70                 newRow();
71             }
72         }
73         // Force a new row between the two foreground images
74         newRow();
75     }
76     canvas->restore();
77     return skiagm::DrawResult::kOk;
78 }
79