/*
 * 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 "src/core/SkCachedData.h"
#include "src/image/SkImage_Base.h"
#include "tools/DecodeUtils.h"
#include "tools/Resources.h"
#include "tools/ToolUtils.h"

#if defined(SK_GANESH)
#include "include/gpu/ganesh/GrRecordingContext.h"
#include "tools/gpu/YUVUtils.h"
#endif

// Modeled on the layout test css3/blending/background-blend-mode-image-image.html to reproduce
// skbug.com/40040948
DEF_SIMPLE_GM_CAN_FAIL(ducky_yuv_blend, canvas, errorMsg, 560, 1130) {
    sk_sp<SkImage> duckyBG = ToolUtils::GetResourceAsImage("images/ducky.png");
    sk_sp<SkImage> duckyFG[2] = {ToolUtils::GetResourceAsImage("images/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 defined(SK_GANESH)
    if (auto* rContext = canvas->recordingContext(); rContext && !rContext->abandoned()) {
        auto lazyYUV = sk_gpu_test::LazyYUVImage::Make(GetResourceAsData("images/ducky.jpg"),
                                                       skgpu::Mipmapped::kYes);
        if (lazyYUV) {
            duckyFG[1] = lazyYUV->refImage(rContext, sk_gpu_test::LazyYUVImage::Type::kFromPixmaps);
        }
        if (!duckyFG[1]) {
            return skiagm::DrawResult::kFail;
        }
    } else
#endif  // SK_GANESH
    {
        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;
    };
    SkSamplingOptions sampling(SkFilterMode::kLinear,
                               SkMipmapMode::kNearest);
    ToolUtils::draw_checkerboard(
            canvas, SK_ColorDKGRAY, SK_ColorLTGRAY, (kDstRect.height() + kPad)/5);
    for (auto& fg : duckyFG) {
        for (int bm = static_cast<int>(SkBlendMode::kLastCoeffMode) + 1;
             bm < static_cast<int>(SkBlendMode::kLastMode);
             ++bm) {
            canvas->drawImageRect(duckyBG, kDstRect, sampling, nullptr);
            SkPaint paint;
            paint.setBlendMode(static_cast<SkBlendMode>(bm));
            canvas->drawImageRect(fg, kDstRect, sampling, &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;
}
