/*
 * Copyright 2021 Google LLC
 *
 * 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/SkBitmap.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkPaint.h"
#include "include/core/SkSize.h"
#include "include/core/SkSurface.h"
#include "include/effects/SkRuntimeEffect.h"
#include "src/gpu/ganesh/GrCaps.h"
#include "src/gpu/ganesh/GrDirectContextPriv.h"
#include "tests/Test.h"
#include "tools/Resources.h"
#include "tools/RuntimeBlendUtils.h"
#include "tools/ToolUtils.h"

static bool nearly_equal(const SkColor& x, const SkColor& y) {
    const int kTolerance = 1;
    return abs((int)SkColorGetA(x) - (int)SkColorGetA(y)) <= kTolerance &&
           abs((int)SkColorGetR(x) - (int)SkColorGetR(y)) <= kTolerance &&
           abs((int)SkColorGetG(x) - (int)SkColorGetG(y)) <= kTolerance &&
           abs((int)SkColorGetB(x) - (int)SkColorGetB(y)) <= kTolerance;
}

static void test_blend(skiatest::Reporter* r, SkSurface* surface) {
    SkBitmap bitmap;
    REPORTER_ASSERT(r, bitmap.tryAllocPixels(surface->imageInfo()));

    for (int m = 0; m < kSkBlendModeCount; ++m) {
        SkBlendMode mode = (SkBlendMode)m;
        for (int alpha : {0x80, 0xFF}) {
            std::vector<SkColor> colors;
            for (bool useRuntimeBlend : {false, true}) {
                // Draw a solid red pixel.
                SkPaint paint;
                paint.setColor(SK_ColorRED);
                paint.setBlendMode(SkBlendMode::kSrc);
                surface->getCanvas()->drawRect(SkRect::MakeWH(1, 1), paint);

                // Draw a blue pixel on top of it, using the passed-in blend mode.
                paint.setColor(SkColorSetARGB(alpha, 0x00, 0x00, 0xFF));
                if (useRuntimeBlend) {
                    paint.setBlender(GetRuntimeBlendForBlendMode(mode));
                } else {
                    paint.setBlendMode(mode);
                }
                surface->getCanvas()->drawRect(SkRect::MakeWH(1, 1), paint);

                // Read back the red/blue blended pixel.
                REPORTER_ASSERT(r, surface->readPixels(bitmap.info(), bitmap.getPixels(),
                                                       bitmap.rowBytes(), /*srcX=*/0, /*srcY=*/0));
                colors.push_back(bitmap.getColor(/*x=*/0, /*y=*/0));
            }

            REPORTER_ASSERT(r, nearly_equal(colors[0], colors[1]),
                            "Expected: %s %s blend matches. Actual: Built-in "
                            "A=%02X R=%02X G=%02X B=%02X, Runtime A=%02X R=%02X G=%02X B=%02X",
                            SkBlendMode_Name(mode),
                            (alpha == 0xFF) ? "solid" : "transparent",
                            SkColorGetA(colors[0]),
                            SkColorGetR(colors[0]),
                            SkColorGetG(colors[0]),
                            SkColorGetB(colors[0]),
                            SkColorGetA(colors[1]),
                            SkColorGetR(colors[1]),
                            SkColorGetG(colors[1]),
                            SkColorGetB(colors[1]));
        }
    }
}

DEF_TEST(SkRuntimeBlender_CPU, r) {
    const SkImageInfo info = SkImageInfo::MakeN32Premul(/*width=*/1, /*height=*/1);
    sk_sp<SkSurface> surface(SkSurface::MakeRaster(info));

    test_blend(r, surface.get());
}

DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SkRuntimeBlender_GPU, r, ctxInfo) {
    const SkImageInfo info = SkImageInfo::MakeN32Premul(/*width=*/1, /*height=*/1);
    sk_sp<SkSurface> surface(SkSurface::MakeRenderTarget(ctxInfo.directContext(),
                                                         SkBudgeted::kNo, info));
    test_blend(r, surface.get());
}
