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