/*
 * Copyright 2014 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/SkBlendMode.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkColor.h"
#include "include/core/SkColorSpace.h"
#include "include/core/SkFont.h"
#include "include/core/SkImage.h"
#include "include/core/SkImageInfo.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPoint.h"
#include "include/core/SkRect.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkScalar.h"
#include "include/core/SkShader.h"
#include "include/core/SkSize.h"
#include "include/core/SkString.h"
#include "include/core/SkSurface.h"
#include "include/core/SkSurfaceProps.h"
#include "include/core/SkTileMode.h"
#include "include/core/SkTypeface.h"
#include "include/core/SkTypes.h"
#include "include/effects/SkGradientShader.h"
#include "include/gpu/GrDirectContext.h"
#include "include/gpu/GrRecordingContext.h"
#include "include/utils/SkTextUtils.h"
#include "tools/ToolUtils.h"
#include "tools/gpu/BackendSurfaceFactory.h"

#define W 200
#define H 100

static sk_sp<SkShader> make_shader() {
    int a = 0x99;
    int b = 0xBB;
    SkPoint pts[] = { { 0, 0 }, { W, H } };
    SkColor colors[] = { SkColorSetRGB(a, a, a), SkColorSetRGB(b, b, b) };
    return SkGradientShader::MakeLinear(pts, colors, nullptr, 2, SkTileMode::kClamp);
}

static sk_sp<SkSurface> make_surface(GrRecordingContext* ctx,
                                     const SkImageInfo& info,
                                     SkPixelGeometry geo) {
    SkSurfaceProps props(0, geo);
    if (ctx) {
        return SkSurface::MakeRenderTarget(ctx, SkBudgeted::kNo, info, 0, &props);
    } else {
        return SkSurface::MakeRaster(info, &props);
    }
}

static void test_draw(SkCanvas* canvas, const char label[]) {
    SkPaint paint;

    paint.setAntiAlias(true);
    paint.setDither(true);

    paint.setShader(make_shader());
    canvas->drawRect(SkRect::MakeWH(W, H), paint);
    paint.setShader(nullptr);

    paint.setColor(SK_ColorWHITE);
    SkFont font(ToolUtils::create_portable_typeface(), 32);
    font.setEdging(SkFont::Edging::kSubpixelAntiAlias);
    SkTextUtils::DrawString(canvas, label, W / 2, H * 3 / 4, font, paint,
                            SkTextUtils::kCenter_Align);
}

class SurfacePropsGM : public skiagm::GM {
public:
    SurfacePropsGM() {}

protected:
    SkString onShortName() override {
        return SkString("surfaceprops");
    }

    SkISize onISize() override {
        return SkISize::Make(W, H * 5);
    }

    void onDraw(SkCanvas* canvas) override {
        auto ctx = canvas->recordingContext();

        // must be opaque to have a hope of testing LCD text
        const SkImageInfo info = SkImageInfo::MakeN32(W, H, kOpaque_SkAlphaType);

        const struct {
            SkPixelGeometry fGeo;
            const char*     fLabel;
        } recs[] = {
            { kUnknown_SkPixelGeometry, "Unknown" },
            { kRGB_H_SkPixelGeometry,   "RGB_H" },
            { kBGR_H_SkPixelGeometry,   "BGR_H" },
            { kRGB_V_SkPixelGeometry,   "RGB_V" },
            { kBGR_V_SkPixelGeometry,   "BGR_V" },
        };

        SkScalar x = 0;
        SkScalar y = 0;
        for (const auto& rec : recs) {
            auto surface(make_surface(ctx, info, rec.fGeo));
            if (!surface) {
                SkDebugf("failed to create surface! label: %s", rec.fLabel);
                continue;
            }
            test_draw(surface->getCanvas(), rec.fLabel);
            surface->draw(canvas, x, y);
            y += H;
        }
    }

private:
    using INHERITED = GM;
};
DEF_GM( return new SurfacePropsGM )

#ifdef SK_DEBUG
static bool equal(const SkSurfaceProps& a, const SkSurfaceProps& b) {
    return a.flags() == b.flags() && a.pixelGeometry() == b.pixelGeometry();
}
#endif

class NewSurfaceGM : public skiagm::GM {
public:
    NewSurfaceGM() {}

protected:
    SkString onShortName() override {
        return SkString("surfacenew");
    }

    SkISize onISize() override {
        return SkISize::Make(300, 140);
    }

    static void drawInto(SkCanvas* canvas) {
        canvas->drawColor(SK_ColorRED);
    }

    void onDraw(SkCanvas* canvas) override {
        SkImageInfo info = SkImageInfo::MakeN32Premul(100, 100);

        auto surf(ToolUtils::makeSurface(canvas, info, nullptr));
        drawInto(surf->getCanvas());

        sk_sp<SkImage> image(surf->makeImageSnapshot());
        canvas->drawImage(image, 10, 10);

        auto surf2(surf->makeSurface(info));
        drawInto(surf2->getCanvas());

        // Assert that the props were communicated transitively through the first image
        SkASSERT(equal(surf->props(), surf2->props()));

        sk_sp<SkImage> image2(surf2->makeImageSnapshot());
        canvas->drawImage(image2.get(), 10 + SkIntToScalar(image->width()) + 10, 10);
    }

private:
    using INHERITED = GM;
};
DEF_GM( return new NewSurfaceGM )

///////////////////////////////////////////////////////////////////////////////////////////////////

// The GPU backend may behave differently when images are snapped from wrapped textures and
// render targets compared.
namespace {
enum SurfaceType {
    kManaged,
    kBackendTexture,
    kBackendRenderTarget
};
}

static sk_sp<SkSurface> make_surface(const SkImageInfo& ii, SkCanvas* canvas, SurfaceType type) {
    GrDirectContext* direct = GrAsDirectContext(canvas->recordingContext());
    switch (type) {
        case kManaged:
            return ToolUtils::makeSurface(canvas, ii);
        case kBackendTexture:
            if (!direct) {
                return nullptr;
            }
            return sk_gpu_test::MakeBackendTextureSurface(direct, ii, kTopLeft_GrSurfaceOrigin, 1);
        case kBackendRenderTarget:
            return sk_gpu_test::MakeBackendRenderTargetSurface(direct,
                                                               ii,
                                                               kTopLeft_GrSurfaceOrigin,
                                                               1);
    }
    return nullptr;
}

using MakeSurfaceFn = std::function<sk_sp<SkSurface>(const SkImageInfo&)>;

#define DEF_BASIC_SURFACE_TEST(name, canvas, main, W, H)            \
    DEF_SIMPLE_GM(name, canvas, W, H) {                             \
        auto make = [canvas](const SkImageInfo& ii) {               \
            return make_surface(ii, canvas, SurfaceType::kManaged); \
        };                                                          \
        main(canvas, MakeSurfaceFn(make));                          \
    }

#define DEF_BACKEND_SURFACE_TEST(name, canvas, main, type, W, H)                                \
    DEF_SIMPLE_GM_CAN_FAIL(name, canvas, err_msg, W, H) {                                       \
        GrDirectContext* direct = GrAsDirectContext(canvas->recordingContext());                \
        if (!direct || direct->abandoned()) {                                                   \
            *err_msg = "Requires non-abandoned GrDirectContext";                                \
            return skiagm::DrawResult::kSkip;                                                   \
        }                                                                                       \
        auto make = [canvas](const SkImageInfo& ii) { return make_surface(ii, canvas, type); }; \
        main(canvas, MakeSurfaceFn(make));                                                      \
        return skiagm::DrawResult::kOk;                                                         \
    }

#define DEF_BET_SURFACE_TEST(name, canvas, main, W, H)                  \
    DEF_BACKEND_SURFACE_TEST(SK_MACRO_CONCAT(name, _bet), canvas, main, \
                             SurfaceType::kBackendTexture, W, H)

#define DEF_BERT_SURFACE_TEST(name, canvas, main, W, H)                  \
    DEF_BACKEND_SURFACE_TEST(SK_MACRO_CONCAT(name, _bert), canvas, main, \
                             SurfaceType::kBackendRenderTarget, W, H)

// This makes 3 GMs from the same code, normal, wrapped backend texture, and wrapped backend
// render target.
#define DEF_SURFACE_TESTS(name, canvas, W, H)                                  \
    static void SK_MACRO_CONCAT(name, _main)(SkCanvas*, const MakeSurfaceFn&); \
    DEF_BASIC_SURFACE_TEST(name, canvas, SK_MACRO_CONCAT(name, _main), W, H)   \
    DEF_BET_SURFACE_TEST  (name, canvas, SK_MACRO_CONCAT(name, _main), W, H)   \
    DEF_BERT_SURFACE_TEST (name, canvas, SK_MACRO_CONCAT(name, _main), W, H)   \
    static void SK_MACRO_CONCAT(name, _main)(SkCanvas * canvas, const MakeSurfaceFn& make)

DEF_SURFACE_TESTS(copy_on_write_retain, canvas, 256, 256) {
    const SkImageInfo info = SkImageInfo::MakeN32Premul(256, 256);
    sk_sp<SkSurface> surf = make(info);

    surf->getCanvas()->clear(SK_ColorRED);
    // its important that image survives longer than the next draw, so the surface will see
    // an outstanding image, and have to decide if it should retain or discard those pixels
    sk_sp<SkImage> image = surf->makeImageSnapshot();

    // normally a clear+opaque should trigger the discard optimization, but since we have a clip
    // it should not (we need the previous red pixels).
    surf->getCanvas()->clipRect(SkRect::MakeWH(128, 256));
    surf->getCanvas()->clear(SK_ColorBLUE);

    // expect to see two rects: blue | red
    canvas->drawImage(surf->makeImageSnapshot(), 0, 0);
}

// Like copy_on_write_retain but draws the snapped image back to the surface it was snapped from.
DEF_SURFACE_TESTS(copy_on_write_retain2, canvas, 256, 256) {
    const SkImageInfo info = SkImageInfo::MakeN32Premul(256, 256);
    sk_sp<SkSurface> surf = make(info);

    surf->getCanvas()->clear(SK_ColorBLUE);
    // its important that image survives longer than the next draw, so the surface will see
    // an outstanding image, and have to decide if it should retain or discard those pixels
    sk_sp<SkImage> image = surf->makeImageSnapshot();

    surf->getCanvas()->clear(SK_ColorRED);
    // normally a clear+opaque should trigger the discard optimization, but since we have a clip
    // it should not (we need the previous red pixels).
    surf->getCanvas()->clipRect(SkRect::MakeWH(128, 256));
    surf->getCanvas()->drawImage(image, 0, 0);

    // expect to see two rects: blue | red
    canvas->drawImage(surf->makeImageSnapshot(), 0, 0);
}

DEF_SURFACE_TESTS(simple_snap_image, canvas, 256, 256) {
    const SkImageInfo info = SkImageInfo::MakeN32Premul(256, 256);
    sk_sp<SkSurface> surf = make(info);

    surf->getCanvas()->clear(SK_ColorRED);
    sk_sp<SkImage> image = surf->makeImageSnapshot();
    // expect to see just red
    canvas->drawImage(std::move(image), 0, 0);
}

// Like simple_snap_image but the surface dies before the image.
DEF_SURFACE_TESTS(simple_snap_image2, canvas, 256, 256) {
    const SkImageInfo info = SkImageInfo::MakeN32Premul(256, 256);
    sk_sp<SkSurface> surf = make(info);

    surf->getCanvas()->clear(SK_ColorRED);
    sk_sp<SkImage> image = surf->makeImageSnapshot();
    surf.reset();
    // expect to see just red
    canvas->drawImage(std::move(image), 0, 0);
}

DEF_SURFACE_TESTS(copy_on_write_savelayer, canvas, 256, 256) {
    const SkImageInfo info = SkImageInfo::MakeN32Premul(256, 256);
    sk_sp<SkSurface> surf = make(info);
    surf->getCanvas()->clear(SK_ColorRED);
    // its important that image survives longer than the next draw, so the surface will see
    // an outstanding image, and have to decide if it should retain or discard those pixels
    sk_sp<SkImage> image = surf->makeImageSnapshot();

    // now draw into a full-screen layer. This should (a) trigger a copy-on-write, but it should
    // not trigger discard, even tho its alpha (SK_ColorBLUE) is opaque, since it is in a layer
    // with a non-opaque paint.
    SkPaint paint;
    paint.setAlphaf(0.25f);
    surf->getCanvas()->saveLayer({0, 0, 256, 256}, &paint);
    surf->getCanvas()->clear(SK_ColorBLUE);
    surf->getCanvas()->restore();

    // expect to see two rects: blue blended on red
    canvas->drawImage(surf->makeImageSnapshot(), 0, 0);
}

DEF_SURFACE_TESTS(surface_underdraw, canvas, 256, 256) {
    SkImageInfo info = SkImageInfo::MakeN32Premul(256, 256, nullptr);
    auto surf = make(info);

    const SkIRect subset = SkIRect::MakeLTRB(180, 0, 256, 256);

    // noisy background
    {
        SkPoint pts[] = {{0, 0}, {40, 50}};
        SkColor colors[] = {SK_ColorRED, SK_ColorBLUE};
        auto sh = SkGradientShader::MakeLinear(pts, colors, nullptr, 2, SkTileMode::kRepeat);
        SkPaint paint;
        paint.setShader(sh);
        surf->getCanvas()->drawPaint(paint);
    }

    // save away the right-hand strip, then clear it
    sk_sp<SkImage> saveImg = surf->makeImageSnapshot(subset);
    {
        SkPaint paint;
        paint.setBlendMode(SkBlendMode::kClear);
        surf->getCanvas()->drawRect(SkRect::Make(subset), paint);
    }

    // draw the "foreground"
    {
        SkPaint paint;
        paint.setColor(SK_ColorGREEN);
        SkRect r = { 0, 10, 256, 35 };
        while (r.fBottom < 256) {
            surf->getCanvas()->drawRect(r, paint);
            r.offset(0, r.height() * 2);
        }
    }

    // apply the "fade"
    {
        SkPoint pts[] = {{SkIntToScalar(subset.left()), 0}, {SkIntToScalar(subset.right()), 0}};
        SkColor colors[] = {0xFF000000, 0};
        auto sh = SkGradientShader::MakeLinear(pts, colors, nullptr, 2, SkTileMode::kClamp);
        SkPaint paint;
        paint.setShader(sh);
        paint.setBlendMode(SkBlendMode::kDstIn);
        surf->getCanvas()->drawRect(SkRect::Make(subset), paint);
    }

    // restore the original strip, drawing it "under" the current foreground
    {
        SkPaint paint;
        paint.setBlendMode(SkBlendMode::kDstOver);
        surf->getCanvas()->drawImage(saveImg,
                                     SkIntToScalar(subset.left()), SkIntToScalar(subset.top()),
                                     SkSamplingOptions(), &paint);
    }

    // show it on screen
   surf->draw(canvas, 0, 0);
}
