/* * Copyright 2019 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "gm/gm.h" #include "include/core/SkCanvas.h" #include "include/core/SkPaint.h" #include "include/core/SkYUVAIndex.h" #include "include/core/SkYUVASizeInfo.h" #include "src/core/SkCachedData.h" #include "src/image/SkImage_Base.h" #include "tools/Resources.h" #include "tools/ToolUtils.h" // Modeled on the layout test css3/blending/background-blend-mode-image-image.html to reproduce // skbug.com/9619 DEF_SIMPLE_GM_CAN_FAIL(ducky_yuv_blend, canvas, errorMsg, 560, 1130) { sk_sp duckyBG = GetResourceAsImage("ducky.png"); sk_sp duckyFG[2] = {GetResourceAsImage("ducky.jpg"), nullptr}; if (!duckyFG[0] || !duckyBG) { *errorMsg = "Image(s) failed to load."; return skiagm::DrawResult::kFail; } // If we're on the GPU we do a second round of draws where the source image is YUV planes. // Otherwise we just draw the original again, if (auto* context = canvas->getGrContext()) { SkYUVASizeInfo info; SkYUVAIndex indices[4]; SkYUVColorSpace yuvColorSpace; const void* planes[4]; auto data = as_IB(duckyFG[0])->getPlanes(&info, indices, &yuvColorSpace, planes); SkPixmap pixmaps[4]; for (int i = 0; i < 4; ++i) { if (indices[i].fIndex >= 0) { pixmaps[i].reset( SkImageInfo::MakeA8(info.fSizes[i]), planes[i], info.fWidthBytes[i]); } } duckyFG[1] = SkImage::MakeFromYUVAPixmaps(context, yuvColorSpace, pixmaps, indices, duckyFG[0]->dimensions(), kTopLeft_GrSurfaceOrigin, true); } else { duckyFG[1] = duckyFG[0]; } static constexpr int kNumPerRow = 4; static constexpr int kPad = 10; static constexpr auto kDstRect = SkRect::MakeWH(130, 130); int rowCnt = 0; canvas->translate(kPad, kPad); canvas->save(); auto newRow = [&] { canvas->restore(); canvas->translate(0, kDstRect.height() + kPad); canvas->save(); rowCnt = 0; }; ToolUtils::draw_checkerboard( canvas, SK_ColorDKGRAY, SK_ColorLTGRAY, (kDstRect.height() + kPad)/5); for (auto& fg : duckyFG) { for (int bm = static_cast(SkBlendMode::kLastCoeffMode) + 1; bm < static_cast(SkBlendMode::kLastMode); ++bm) { auto mode = static_cast(bm); SkPaint paint; paint.setFilterQuality(kMedium_SkFilterQuality); canvas->drawImageRect(duckyBG, kDstRect, &paint); paint.setBlendMode(mode); canvas->drawImageRect(fg, kDstRect, &paint); canvas->translate(kDstRect.width() + kPad, 0); if (++rowCnt == kNumPerRow) { newRow(); } } // Force a new row between the two foreground images newRow(); } canvas->restore(); return skiagm::DrawResult::kOk; }