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