/*
 * Copyright 2012 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/SkBitmap.h"
#include "include/core/SkBlurTypes.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkColor.h"
#include "include/core/SkFont.h"
#include "include/core/SkMaskFilter.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPath.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/SkTileMode.h"
#include "include/core/SkTypeface.h"
#include "tools/ToolUtils.h"

namespace skiagm {

/**
 * Stress test the GPU samplers by rendering a textured glyph with a mask and
 * an AA clip
 */
class SamplerStressGM : public GM {
public:
    SamplerStressGM()
    : fTextureCreated(false)
    , fMaskFilter(nullptr) {
    }

protected:

    SkString onShortName() override {
        return SkString("gpusamplerstress");
    }

    SkISize onISize() override {
        return SkISize::Make(640, 480);
    }

    /**
     * Create a red & green stripes on black texture
     */
    void createTexture() {
        if (fTextureCreated) {
            return;
        }

        constexpr int xSize = 16;
        constexpr int ySize = 16;

        fTexture.allocN32Pixels(xSize, ySize);
        SkPMColor* addr = fTexture.getAddr32(0, 0);

        for (int y = 0; y < ySize; ++y) {
            for (int x = 0; x < xSize; ++x) {
                addr[y*xSize+x] = SkPreMultiplyColor(SK_ColorBLACK);

                if ((y % 5) == 0) {
                    addr[y*xSize+x] = SkPreMultiplyColor(SK_ColorRED);
                }
                if ((x % 7) == 0) {
                    addr[y*xSize+x] = SkPreMultiplyColor(SK_ColorGREEN);
                }
            }
        }

        fTextureCreated = true;
    }

    void createShader() {
        if (fShader) {
            return;
        }

        createTexture();

        fShader = fTexture.makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat,
                                      SkSamplingOptions());
    }

    void createMaskFilter() {
        if (fMaskFilter) {
            return;
        }

        const SkScalar sigma = 1;
        fMaskFilter = SkMaskFilter::MakeBlur(kNormal_SkBlurStyle, sigma);
    }

    void onDraw(SkCanvas* canvas) override {
        createShader();
        createMaskFilter();

        canvas->save();

        // draw a letter "M" with a green & red striped texture and a
        // stipple mask with a round rect soft clip
        SkPaint paint;
        paint.setAntiAlias(true);
        paint.setShader(fShader);
        paint.setMaskFilter(fMaskFilter);
        SkFont font(ToolUtils::create_portable_typeface(), 72);

        SkRect temp;
        temp.setLTRB(115, 75, 144, 110);

        SkPath path;
        path.addRoundRect(temp, SkIntToScalar(5), SkIntToScalar(5));

        canvas->clipPath(path, true); // AA is on

        canvas->drawString("M", 100.0f, 100.0f, font, paint);

        canvas->restore();

        // Now draw stroked versions of the "M" and the round rect so we can
        // see what is going on
        SkPaint paint2;
        paint2.setColor(SK_ColorBLACK);
        paint2.setAntiAlias(true);
        paint2.setStyle(SkPaint::kStroke_Style);
        paint2.setStrokeWidth(1);
        canvas->drawString("M", 100.0f, 100.0f, font, paint2);

        paint2.setColor(SK_ColorGRAY);

        canvas->drawPath(path, paint2);
    }

private:
    SkBitmap        fTexture;
    bool            fTextureCreated;
    sk_sp<SkShader> fShader;
    sk_sp<SkMaskFilter> fMaskFilter;

    using INHERITED = GM;
};

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

DEF_GM( return new SamplerStressGM; )

}  // namespace skiagm
