• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/core/SkYUVAIndex.h"
12 #include "include/core/SkYUVASizeInfo.h"
13 #include "src/core/SkCachedData.h"
14 #include "src/image/SkImage_Base.h"
15 #include "tools/Resources.h"
16 #include "tools/ToolUtils.h"
17 
18 // Modeled on the layout test css3/blending/background-blend-mode-image-image.html to reproduce
19 // skbug.com/9619
20 DEF_SIMPLE_GM_CAN_FAIL(ducky_yuv_blend, canvas, errorMsg, 560, 1130) {
21     sk_sp<SkImage> duckyBG = GetResourceAsImage("ducky.png");
22     sk_sp<SkImage> duckyFG[2] = {GetResourceAsImage("ducky.jpg"), nullptr};
23     if (!duckyFG[0] || !duckyBG) {
24         *errorMsg = "Image(s) failed to load.";
25         return skiagm::DrawResult::kFail;
26     }
27 
28     // If we're on the GPU we do a second round of draws where the source image is YUV planes.
29     // Otherwise we just draw the original again,
30     if (auto* context = canvas->getGrContext()) {
31         SkYUVASizeInfo info;
32         SkYUVAIndex indices[4];
33         SkYUVColorSpace yuvColorSpace;
34         const void* planes[4];
35         auto data = as_IB(duckyFG[0])->getPlanes(&info, indices, &yuvColorSpace, planes);
36         SkPixmap pixmaps[4];
37         for (int i = 0; i < 4; ++i) {
38             if (indices[i].fIndex >= 0) {
39                 pixmaps[i].reset(
40                         SkImageInfo::MakeA8(info.fSizes[i]), planes[i], info.fWidthBytes[i]);
41             }
42         }
43         duckyFG[1] = SkImage::MakeFromYUVAPixmaps(context,
44                                                   yuvColorSpace,
45                                                   pixmaps,
46                                                   indices,
47                                                   duckyFG[0]->dimensions(),
48                                                   kTopLeft_GrSurfaceOrigin,
49                                                   true);
50     } else {
51         duckyFG[1] = duckyFG[0];
52     }
53 
54     static constexpr int kNumPerRow = 4;
55     static constexpr int kPad = 10;
56     static constexpr auto kDstRect = SkRect::MakeWH(130, 130);
57     int rowCnt = 0;
58     canvas->translate(kPad, kPad);
59     canvas->save();
__anon0d5802ae0102null60     auto newRow = [&] {
61         canvas->restore();
62         canvas->translate(0, kDstRect.height() + kPad);
63         canvas->save();
64         rowCnt = 0;
65     };
66     ToolUtils::draw_checkerboard(
67             canvas, SK_ColorDKGRAY, SK_ColorLTGRAY, (kDstRect.height() + kPad)/5);
68     for (auto& fg : duckyFG) {
69         for (int bm = static_cast<int>(SkBlendMode::kLastCoeffMode) + 1;
70              bm < static_cast<int>(SkBlendMode::kLastMode);
71              ++bm) {
72             auto mode = static_cast<SkBlendMode>(bm);
73             SkPaint paint;
74             paint.setFilterQuality(kMedium_SkFilterQuality);
75             canvas->drawImageRect(duckyBG, kDstRect, &paint);
76             paint.setBlendMode(mode);
77             canvas->drawImageRect(fg, kDstRect, &paint);
78             canvas->translate(kDstRect.width() + kPad, 0);
79             if (++rowCnt == kNumPerRow) {
80                 newRow();
81             }
82         }
83         // Force a new row between the two foreground images
84         newRow();
85     }
86     canvas->restore();
87     return skiagm::DrawResult::kOk;
88 }
89