/*
 * Copyright 2018 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include <memory>

#include "bench/Benchmark.h"
#include "bench/GpuTools.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkColorSpace.h"
#include "include/core/SkImage.h"
#include "include/core/SkSurface.h"
#include "include/private/base/SkTemplates.h"
#include "src/base/SkRandom.h"

using namespace skia_private;

enum class ClampingMode {
    // Submit image set entries with the fast constraint
    kAlwaysFast,
    // Submit image set entries with the strict constraint
    kAlwaysStrict,
    // Submit non-right/bottom tiles as fast, the bottom-right corner as strict, and bottom or right
    // edge tiles as strict with geometry modification to match content area. These will be
    // submitted from left-to-right, top-to-bottom so will necessarily be split into many batches.
    kChromeTiling_RowMajor,
    // As above, but group all fast tiles first, then bottom and right edge tiles in a second batch.
    kChromeTiling_Optimal
};

enum class TransformMode {
    // Tiles will be axis aligned on integer pixels
    kNone,
    // Subpixel, tiles will be axis aligned but adjusted to subpixel coordinates
    kSubpixel,
    // Rotated, tiles will be rotated globally; they won't overlap but their device space bounds may
    kRotated,
    // Perspective, tiles will have global perspective
    kPerspective
};

/**
 * Simulates drawing layers images in a grid a la a tile based compositor.
 */
class CompositingImages : public Benchmark {
public:
    CompositingImages(SkISize imageSize, SkISize tileSize, SkISize tileGridSize,
                      ClampingMode clampMode, TransformMode transformMode, int layerCnt)
            : fImageSize(imageSize)
            , fTileSize(tileSize)
            , fTileGridSize(tileGridSize)
            , fClampMode(clampMode)
            , fTransformMode(transformMode)
            , fLayerCnt(layerCnt) {
        fName.appendf("compositing_images_tile_size_%dx%d_grid_%dx%d_layers_%d",
                      fTileSize.fWidth, fTileSize.fHeight, fTileGridSize.fWidth,
                      fTileGridSize.fHeight, fLayerCnt);
        if (imageSize != tileSize) {
            fName.appendf("_image_%dx%d", imageSize.fWidth, imageSize.fHeight);
        }
        switch(clampMode) {
            case ClampingMode::kAlwaysFast:
                fName.append("_fast");
                break;
            case ClampingMode::kAlwaysStrict:
                fName.append("_strict");
                break;
            case ClampingMode::kChromeTiling_RowMajor:
                fName.append("_chrome");
                break;
            case ClampingMode::kChromeTiling_Optimal:
                fName.append("_chrome_optimal");
                break;
        }
        switch(transformMode) {
            case TransformMode::kNone:
                break;
            case TransformMode::kSubpixel:
                fName.append("_subpixel");
                break;
            case TransformMode::kRotated:
                fName.append("_rotated");
                break;
            case TransformMode::kPerspective:
                fName.append("_persp");
                break;
        }
    }

    bool isSuitableFor(Backend backend) override { return kGPU_Backend == backend; }

protected:
    const char* onGetName() override { return fName.c_str(); }

    void onPerCanvasPreDraw(SkCanvas* canvas) override {
        // Use image size, which may be larger than the tile size (emulating how Chrome specifies
        // their tiles).
        auto ii = SkImageInfo::Make(fImageSize.fWidth, fImageSize.fHeight, kRGBA_8888_SkColorType,
                                    kPremul_SkAlphaType, nullptr);
        SkRandom random;
        int numImages = fLayerCnt * fTileGridSize.fWidth * fTileGridSize.fHeight;
        fImages = std::make_unique<sk_sp<SkImage>[]>(numImages);
        for (int i = 0; i < numImages; ++i) {
            auto surf = canvas->makeSurface(ii);
            SkColor color = random.nextU();
            surf->getCanvas()->clear(color);
            SkPaint paint;
            paint.setColor(~color);
            paint.setBlendMode(SkBlendMode::kSrc);
            // While the image may be bigger than fTileSize, prepare its content as if fTileSize
            // is what will be visible.
            surf->getCanvas()->drawRect(
                    SkRect::MakeLTRB(3, 3, fTileSize.fWidth - 3, fTileSize.fHeight - 3), paint);
            fImages[i] = surf->makeImageSnapshot();
        }
    }

    void onPerCanvasPostDraw(SkCanvas*) override { fImages.reset(); }

    void onDraw(int loops, SkCanvas* canvas) override {
        SkPaint paint;
        paint.setAntiAlias(true);
        SkSamplingOptions sampling(SkFilterMode::kLinear);

        canvas->save();
        canvas->concat(this->getTransform());

        for (int loop = 0; loop < loops; ++loop) {
            for (int l = 0; l < fLayerCnt; ++l) {
                AutoTArray<SkCanvas::ImageSetEntry> set(
                        fTileGridSize.fWidth * fTileGridSize.fHeight);

                if (fClampMode == ClampingMode::kAlwaysFast ||
                    fClampMode == ClampingMode::kAlwaysStrict) {
                    // Simple 2D for loop, submit everything as a single batch
                    int i = 0;
                    for (int y = 0; y < fTileGridSize.fHeight; ++y) {
                        for (int x = 0; x < fTileGridSize.fWidth; ++x) {
                            set[i++] = this->getEntry(x, y, l);
                        }
                    }

                    SkCanvas::SrcRectConstraint constraint =
                            fClampMode == ClampingMode::kAlwaysFast
                                    ? SkCanvas::kFast_SrcRectConstraint
                                    : SkCanvas::kStrict_SrcRectConstraint;
                    canvas->experimental_DrawEdgeAAImageSet(set.get(), i, nullptr, nullptr,
                                                            sampling, &paint, constraint);
                } else if (fClampMode == ClampingMode::kChromeTiling_RowMajor) {
                    // Same tile order, but break batching between fast and strict sections, and
                    // adjust bottom and right tiles to encode content area distinct from src rect.
                    int i = 0;
                    for (int y = 0; y < fTileGridSize.fHeight - 1; ++y) {
                        int rowStart = i;
                        for (int x = 0; x < fTileGridSize.fWidth - 1; ++x) {
                            set[i++] = this->getEntry(x, y, l);
                        }
                        // Flush "fast" horizontal row
                        canvas->experimental_DrawEdgeAAImageSet(set.get() + rowStart,
                                fTileGridSize.fWidth - 1, nullptr, nullptr, sampling, &paint,
                                SkCanvas::kFast_SrcRectConstraint);
                        // Then flush a single adjusted entry for the right edge
                        SkPoint dstQuad[4];
                        set[i++] = this->getAdjustedEntry(fTileGridSize.fWidth - 1, y, l, dstQuad);
                        canvas->experimental_DrawEdgeAAImageSet(
                                set.get() + fTileGridSize.fWidth - 1, 1, dstQuad, nullptr, sampling,
                                &paint, SkCanvas::kStrict_SrcRectConstraint);
                    }
                    // For last row, accumulate it as a single strict batch
                    int rowStart = i;
                    AutoTArray<SkPoint> dstQuads(4 * (fTileGridSize.fWidth - 1));
                    for (int x = 0; x < fTileGridSize.fWidth - 1; ++x) {
                        set[i++] = this->getAdjustedEntry(x, fTileGridSize.fHeight - 1, l,
                                                          dstQuads.get() + x * 4);
                    }
                    // The corner can use conventional strict mode without geometric adjustment
                    set[i++] = this->getEntry(
                            fTileGridSize.fWidth - 1, fTileGridSize.fHeight - 1, l);
                    canvas->experimental_DrawEdgeAAImageSet(set.get() + rowStart,
                            fTileGridSize.fWidth, dstQuads.get(), nullptr, sampling, &paint,
                            SkCanvas::kStrict_SrcRectConstraint);
                } else {
                    SkASSERT(fClampMode == ClampingMode::kChromeTiling_Optimal);
                    int i = 0;
                    // Interior fast tiles
                    for (int y = 0; y < fTileGridSize.fHeight - 1; ++y) {
                        for (int x = 0; x < fTileGridSize.fWidth - 1; ++x) {
                            set[i++] = this->getEntry(x, y, l);
                        }
                    }
                    canvas->experimental_DrawEdgeAAImageSet(set.get(), i, nullptr, nullptr,
                                                            sampling, &paint,
                                                            SkCanvas::kFast_SrcRectConstraint);

                    // Right edge
                    int strictStart = i;
                    AutoTArray<SkPoint> dstQuads(
                            4 * (fTileGridSize.fWidth + fTileGridSize.fHeight - 2));
                    for (int y = 0; y < fTileGridSize.fHeight - 1; ++y) {
                        set[i++] = this->getAdjustedEntry(fTileGridSize.fWidth - 1, y, l,
                                                          dstQuads.get() + y * 4);
                    }
                    canvas->experimental_DrawEdgeAAImageSet(set.get() + strictStart,
                            i - strictStart, dstQuads.get(), nullptr, sampling, &paint,
                            SkCanvas::kStrict_SrcRectConstraint);
                    int quadStart = 4 * (fTileGridSize.fHeight - 1);
                    strictStart = i;
                    for (int x = 0; x < fTileGridSize.fWidth - 1; ++x) {
                        set[i++] = this->getAdjustedEntry(x, fTileGridSize.fHeight - 1, l,
                                                          dstQuads.get() + quadStart + x * 4);
                    }
                    set[i++] = this->getEntry(
                            fTileGridSize.fWidth - 1, fTileGridSize.fHeight - 1, l);
                    canvas->experimental_DrawEdgeAAImageSet(set.get() + strictStart,
                            i - strictStart, dstQuads.get() + quadStart, nullptr, sampling, &paint,
                            SkCanvas::kStrict_SrcRectConstraint);
                }
            }
            // Prevent any batching between composited "frames".
            skgpu::Flush(canvas->getSurface());
        }
        canvas->restore();
    }

private:
    SkMatrix getTransform() const {
        SkMatrix m;
        switch(fTransformMode) {
            case TransformMode::kNone:
                m.setIdentity();
                break;
            case TransformMode::kSubpixel:
                m.setTranslate(0.5f, 0.5f);
                break;
            case TransformMode::kRotated:
                m.setRotate(15.f);
                break;
            case TransformMode::kPerspective: {
                m.setIdentity();
                m.setPerspY(0.001f);
                m.setSkewX(SkIntToScalar(8) / 25);
                break;
            }
        }
        return m;
    }

    SkIPoint onGetSize() override {
        SkRect size = SkRect::MakeWH(1.25f * fTileSize.fWidth * fTileGridSize.fWidth,
                                     1.25f * fTileSize.fHeight * fTileGridSize.fHeight);
        this->getTransform().mapRect(&size);
        return SkIPoint::Make(SkScalarCeilToInt(size.width()), SkScalarCeilToInt(size.height()));
    }

    unsigned getEdgeFlags(int x, int y) const {
        unsigned flags = SkCanvas::kNone_QuadAAFlags;
        if (x == 0) {
            flags |= SkCanvas::kLeft_QuadAAFlag;
        } else if (x == fTileGridSize.fWidth - 1) {
            flags |= SkCanvas::kRight_QuadAAFlag;
        }

        if (y == 0) {
            flags |= SkCanvas::kTop_QuadAAFlag;
        } else if (y == fTileGridSize.fHeight - 1) {
            flags |= SkCanvas::kBottom_QuadAAFlag;
        }
        return flags;
    }

    SkCanvas::ImageSetEntry getEntry(int x, int y, int layer) const {
        int imageIdx =
                fTileGridSize.fWidth * fTileGridSize.fHeight * layer + fTileGridSize.fWidth * y + x;
        SkRect srcRect = SkRect::Make(fTileSize);
        // Make a non-identity transform between src and dst so bilerp isn't disabled.
        float dstWidth = srcRect.width() * 1.25f;
        float dstHeight = srcRect.height() * 1.25f;
        SkRect dstRect = SkRect::MakeXYWH(dstWidth * x, dstHeight * y, dstWidth, dstHeight);
        return SkCanvas::ImageSetEntry(fImages[imageIdx], srcRect, dstRect, 1.f,
                                       this->getEdgeFlags(x, y));
    }

    SkCanvas::ImageSetEntry getAdjustedEntry(int x, int y, int layer, SkPoint dstQuad[4]) const {
        SkASSERT(x == fTileGridSize.fWidth - 1 || y == fTileGridSize.fHeight - 1);

        SkCanvas::ImageSetEntry entry = this->getEntry(x, y, layer);
        SkRect contentRect = SkRect::Make(fImageSize);
        if (x == fTileGridSize.fWidth - 1) {
            // Right edge, so restrict horizontal content to tile width
            contentRect.fRight = fTileSize.fWidth;
        }
        if (y == fTileGridSize.fHeight - 1) {
            // Bottom edge, so restrict vertical content to tile height
            contentRect.fBottom = fTileSize.fHeight;
        }

        SkMatrix srcToDst = SkMatrix::RectToRect(entry.fSrcRect, entry.fDstRect);

        // Story entry's dstRect into dstQuad, and use contentRect and contentDst as its src and dst
        entry.fDstRect.toQuad(dstQuad);
        entry.fSrcRect = contentRect;
        entry.fDstRect = srcToDst.mapRect(contentRect);
        entry.fHasClip = true;

        return entry;
    }

    std::unique_ptr<sk_sp<SkImage>[]> fImages;
    SkString fName;
    SkISize fImageSize;
    SkISize fTileSize;
    SkISize fTileGridSize;
    ClampingMode fClampMode;
    TransformMode fTransformMode;
    int fLayerCnt;

    using INHERITED = Benchmark;
};

// Subpixel = false; all of the draw commands align with integer pixels so AA will be automatically
// turned off within the operation
DEF_BENCH(return new CompositingImages({256, 256}, {256, 256}, {8, 8}, ClampingMode::kAlwaysFast, TransformMode::kNone, 1));
DEF_BENCH(return new CompositingImages({512, 512}, {512, 512}, {4, 4}, ClampingMode::kAlwaysFast, TransformMode::kNone, 1));
DEF_BENCH(return new CompositingImages({1024, 512}, {1024, 512}, {2, 4}, ClampingMode::kAlwaysFast, TransformMode::kNone, 1));

DEF_BENCH(return new CompositingImages({256, 256}, {256, 256}, {8, 8}, ClampingMode::kAlwaysFast, TransformMode::kNone, 4));
DEF_BENCH(return new CompositingImages({512, 512}, {512, 512}, {4, 4}, ClampingMode::kAlwaysFast, TransformMode::kNone, 4));
DEF_BENCH(return new CompositingImages({1024, 512}, {1024, 512}, {2, 4}, ClampingMode::kAlwaysFast, TransformMode::kNone, 4));

DEF_BENCH(return new CompositingImages({256, 256}, {256, 256}, {8, 8}, ClampingMode::kAlwaysFast, TransformMode::kNone, 16));
DEF_BENCH(return new CompositingImages({512, 512}, {512, 512}, {4, 4}, ClampingMode::kAlwaysFast, TransformMode::kNone, 16));
DEF_BENCH(return new CompositingImages({1024, 512}, {1024, 512}, {2, 4}, ClampingMode::kAlwaysFast, TransformMode::kNone, 16));

// Subpixel = true; force the draw commands to not align with pixels exactly so AA remains on
DEF_BENCH(return new CompositingImages({256, 256}, {256, 256}, {8, 8}, ClampingMode::kAlwaysFast, TransformMode::kSubpixel, 1));
DEF_BENCH(return new CompositingImages({512, 512}, {512, 512}, {4, 4}, ClampingMode::kAlwaysFast, TransformMode::kSubpixel, 1));
DEF_BENCH(return new CompositingImages({1024, 512}, {1024, 512}, {2, 4}, ClampingMode::kAlwaysFast, TransformMode::kSubpixel, 1));

DEF_BENCH(return new CompositingImages({256, 256}, {256, 256}, {8, 8}, ClampingMode::kAlwaysFast, TransformMode::kSubpixel, 4));
DEF_BENCH(return new CompositingImages({512, 512}, {512, 512}, {4, 4}, ClampingMode::kAlwaysFast, TransformMode::kSubpixel, 4));
DEF_BENCH(return new CompositingImages({1024, 512}, {1024, 512}, {2, 4}, ClampingMode::kAlwaysFast, TransformMode::kSubpixel, 4));

DEF_BENCH(return new CompositingImages({256, 256}, {256, 256}, {8, 8}, ClampingMode::kAlwaysFast, TransformMode::kSubpixel, 16));
DEF_BENCH(return new CompositingImages({512, 512}, {512, 512}, {4, 4}, ClampingMode::kAlwaysFast, TransformMode::kSubpixel, 16));
DEF_BENCH(return new CompositingImages({1024, 512}, {1024, 512}, {2, 4}, ClampingMode::kAlwaysFast, TransformMode::kSubpixel, 16));

// Test different tiling scenarios inspired by Chrome's compositor
DEF_BENCH(return new CompositingImages({512, 512}, {380, 380}, {5, 5}, ClampingMode::kAlwaysFast, TransformMode::kNone, 1));
DEF_BENCH(return new CompositingImages({512, 512}, {380, 380}, {5, 5}, ClampingMode::kAlwaysStrict, TransformMode::kNone, 1));
DEF_BENCH(return new CompositingImages({512, 512}, {380, 380}, {5, 5}, ClampingMode::kChromeTiling_RowMajor, TransformMode::kNone, 1));
DEF_BENCH(return new CompositingImages({512, 512}, {380, 380}, {5, 5}, ClampingMode::kChromeTiling_Optimal, TransformMode::kNone, 1));

DEF_BENCH(return new CompositingImages({512, 512}, {380, 380}, {5, 5}, ClampingMode::kAlwaysFast, TransformMode::kSubpixel, 1));
DEF_BENCH(return new CompositingImages({512, 512}, {380, 380}, {5, 5}, ClampingMode::kAlwaysStrict, TransformMode::kSubpixel, 1));
DEF_BENCH(return new CompositingImages({512, 512}, {380, 380}, {5, 5}, ClampingMode::kChromeTiling_RowMajor, TransformMode::kSubpixel, 1));
DEF_BENCH(return new CompositingImages({512, 512}, {380, 380}, {5, 5}, ClampingMode::kChromeTiling_Optimal, TransformMode::kSubpixel, 1));

DEF_BENCH(return new CompositingImages({512, 512}, {380, 380}, {5, 5}, ClampingMode::kAlwaysFast, TransformMode::kRotated, 1));
DEF_BENCH(return new CompositingImages({512, 512}, {380, 380}, {5, 5}, ClampingMode::kAlwaysStrict, TransformMode::kRotated, 1));
DEF_BENCH(return new CompositingImages({512, 512}, {380, 380}, {5, 5}, ClampingMode::kChromeTiling_RowMajor, TransformMode::kRotated, 1));
DEF_BENCH(return new CompositingImages({512, 512}, {380, 380}, {5, 5}, ClampingMode::kChromeTiling_Optimal, TransformMode::kRotated, 1));

DEF_BENCH(return new CompositingImages({512, 512}, {380, 380}, {5, 5}, ClampingMode::kAlwaysFast, TransformMode::kPerspective, 1));
DEF_BENCH(return new CompositingImages({512, 512}, {380, 380}, {5, 5}, ClampingMode::kAlwaysStrict, TransformMode::kPerspective, 1));
DEF_BENCH(return new CompositingImages({512, 512}, {380, 380}, {5, 5}, ClampingMode::kChromeTiling_RowMajor, TransformMode::kPerspective, 1));
DEF_BENCH(return new CompositingImages({512, 512}, {380, 380}, {5, 5}, ClampingMode::kChromeTiling_Optimal, TransformMode::kPerspective, 1));
