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

// This test only works with the GPU backend.

#include "gm.h"

#if SK_SUPPORT_GPU

#include "GrDrawContextPriv.h"
#include "GrContext.h"
#include "SkBitmap.h"
#include "SkGr.h"
#include "SkGradientShader.h"
#include "batches/GrDrawBatch.h"
#include "batches/GrRectBatchFactory.h"
#include "effects/GrTextureDomain.h"

namespace skiagm {
/**
 * This GM directly exercises GrTextureDomainEffect.
 */
class TextureDomainEffect : public GM {
public:
    TextureDomainEffect() {
        this->setBGColor(0xFFFFFFFF);
    }

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

    SkISize onISize() override {
        const SkScalar canvasWidth = kDrawPad +
                (kTargetWidth + 2 * kDrawPad) * GrTextureDomain::kModeCount +
                kTestPad * GrTextureDomain::kModeCount;
        return SkISize::Make(SkScalarCeilToInt(canvasWidth), 800);
    }

    void onOnceBeforeDraw() override {
        fBmp.allocN32Pixels(kTargetWidth, kTargetHeight);
        SkCanvas canvas(fBmp);
        canvas.clear(0x00000000);
        SkPaint paint;

        SkColor colors1[] = { SK_ColorCYAN, SK_ColorLTGRAY, SK_ColorGRAY };
        paint.setShader(SkGradientShader::MakeSweep(65.f, 75.f, colors1, nullptr,
                                                    SK_ARRAY_COUNT(colors1)));
        canvas.drawOval(SkRect::MakeXYWH(-5.f, -5.f, fBmp.width() + 10.f, fBmp.height() + 10.f),
                        paint);

        SkColor colors2[] = { SK_ColorMAGENTA, SK_ColorLTGRAY, SK_ColorYELLOW };
        paint.setShader(SkGradientShader::MakeSweep(45.f, 55.f, colors2, nullptr,
                                                    SK_ARRAY_COUNT(colors2)));
        paint.setXfermodeMode(SkXfermode::kDarken_Mode);
        canvas.drawOval(SkRect::MakeXYWH(-5.f, -5.f, fBmp.width() + 10.f, fBmp.height() + 10.f),
                        paint);

        SkColor colors3[] = { SK_ColorBLUE, SK_ColorLTGRAY, SK_ColorGREEN };
        paint.setShader(SkGradientShader::MakeSweep(25.f, 35.f, colors3, nullptr,
                                                    SK_ARRAY_COUNT(colors3)));
        paint.setXfermodeMode(SkXfermode::kLighten_Mode);
        canvas.drawOval(SkRect::MakeXYWH(-5.f, -5.f, fBmp.width() + 10.f, fBmp.height() + 10.f),
                        paint);
    }

    void onDraw(SkCanvas* canvas) override {
        GrDrawContext* drawContext = canvas->internal_private_accessTopLayerDrawContext();
        if (!drawContext) {
            skiagm::GM::DrawGpuOnlyMessage(canvas);
            return;
        }

        GrContext* context = canvas->getGrContext();
        if (!context) {
            return;
        }

        SkAutoTUnref<GrTexture> texture(GrRefCachedBitmapTexture(context, fBmp,
                                                                 GrTextureParams::ClampNoFilter(),
                                                                 SkSourceGammaTreatment::kRespect));
        if (!texture) {
            return;
        }

        SkTArray<SkMatrix> textureMatrices;
        textureMatrices.push_back().setIDiv(texture->width(), texture->height());
        textureMatrices.push_back() = textureMatrices[0];
        textureMatrices.back().postScale(1.5f, 0.85f);
        textureMatrices.push_back() = textureMatrices[0];
        textureMatrices.back().preRotate(45.f, texture->width() / 2.f, texture->height() / 2.f);

        const SkIRect texelDomains[] = {
            fBmp.bounds(),
            SkIRect::MakeXYWH(fBmp.width() / 4,
                              fBmp.height() / 4,
                              fBmp.width() / 2,
                              fBmp.height() / 2),
        };

        SkRect renderRect = SkRect::Make(fBmp.bounds());
        renderRect.outset(kDrawPad, kDrawPad);

        SkScalar y = kDrawPad + kTestPad;
        for (int tm = 0; tm < textureMatrices.count(); ++tm) {
            for (size_t d = 0; d < SK_ARRAY_COUNT(texelDomains); ++d) {
                SkScalar x = kDrawPad + kTestPad;
                for (int m = 0; m < GrTextureDomain::kModeCount; ++m) {
                    GrTextureDomain::Mode mode = (GrTextureDomain::Mode) m;
                    GrPaint grPaint;
                    grPaint.setXPFactory(GrPorterDuffXPFactory::Make(SkXfermode::kSrc_Mode));
                    sk_sp<GrFragmentProcessor> fp(
                        GrTextureDomainEffect::Make(texture, textureMatrices[tm],
                                                GrTextureDomain::MakeTexelDomain(texture,
                                                                                 texelDomains[d]),
                                                mode, GrTextureParams::kNone_FilterMode));

                    if (!fp) {
                        continue;
                    }
                    const SkMatrix viewMatrix = SkMatrix::MakeTrans(x, y);
                    grPaint.addColorFragmentProcessor(std::move(fp));

                    SkAutoTUnref<GrDrawBatch> batch(
                            GrRectBatchFactory::CreateNonAAFill(GrColor_WHITE, viewMatrix,
                                                                renderRect, nullptr, nullptr));
                    drawContext->drawContextPriv().testingOnly_drawBatch(grPaint, batch);
                    x += renderRect.width() + kTestPad;
                }
                y += renderRect.height() + kTestPad;
            }
        }
    }

private:
    static const SkScalar kDrawPad;
    static const SkScalar kTestPad;
    static const int      kTargetWidth = 100;
    static const int      kTargetHeight = 100;
    SkBitmap fBmp;

    typedef GM INHERITED;
};

// Windows builds did not like SkScalar initialization in class :(
const SkScalar TextureDomainEffect::kDrawPad = 10.f;
const SkScalar TextureDomainEffect::kTestPad = 10.f;

DEF_GM(return new TextureDomainEffect;)
}

#endif
