/*
 * 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 "include/core/SkCanvas.h"
#include "include/core/SkImage.h"
#include "include/core/SkSurface.h"
#include "include/private/SkTemplates.h"
#include "include/utils/SkRandom.h"

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.setFilterQuality(kLow_SkFilterQuality);
        paint.setAntiAlias(true);

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

        for (int i = 0; i < loops; ++i) {
            for (int l = 0; l < fLayerCnt; ++l) {
                SkAutoTArray<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, &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, &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, &paint,
                                SkCanvas::kStrict_SrcRectConstraint);
                    }
                    // For last row, accumulate it as a single strict batch
                    int rowStart = i;
                    SkAutoTArray<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, &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, &paint,
                                                            SkCanvas::kFast_SrcRectConstraint);

                    // Right edge
                    int strictStart = i;
                    SkAutoTArray<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, &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, &paint,
                            SkCanvas::kStrict_SrcRectConstraint);
                }
            }
            // Prevent any batching between composited "frames".
            canvas->flush();
        }
        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::MakeRectToRect(entry.fSrcRect, entry.fDstRect,
                                                     SkMatrix::kFill_ScaleToFit);

        // 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));
