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