
/*
 * 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.h"
#if SK_SUPPORT_GPU
#include "GrFragmentProcessor.h"
#include "GrCoordTransform.h"
#include "effects/GrXfermodeFragmentProcessor.h"
#include "gl/GrGLProcessor.h"
#include "gl/builders/GrGLProgramBuilder.h"
#include "Resources.h"
#include "SkReadBuffer.h"
#include "SkShader.h"
#include "SkStream.h"
#include "SkTypeface.h"
#include "SkWriteBuffer.h"

namespace skiagm {

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

class DCShader : public SkShader {
public:
    DCShader(const SkMatrix& matrix) : fDeviceMatrix(matrix) {}

    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(DCShader);

    void flatten(SkWriteBuffer& buf) const override {
        buf.writeMatrix(fDeviceMatrix);
    }

    const GrFragmentProcessor* asFragmentProcessor(GrContext*,
                                                   const SkMatrix& viewM,
                                                   const SkMatrix* localMatrix,
                                                   SkFilterQuality) const override;

#ifndef SK_IGNORE_TO_STRING
    void toString(SkString* str) const override {
        str->appendf("DCShader: ()");
    }
#endif

private:
    const SkMatrix fDeviceMatrix;
};

SkFlattenable* DCShader::CreateProc(SkReadBuffer& buf) {
    SkMatrix matrix;
    buf.readMatrix(&matrix);
    return new DCShader(matrix);
}

class DCFP : public GrFragmentProcessor {
public:
    DCFP(const SkMatrix& m) : fDeviceTransform(kDevice_GrCoordSet, m) {
        this->addCoordTransform(&fDeviceTransform);
        this->initClassID<DCFP>();
    }

    GrGLFragmentProcessor* onCreateGLInstance() const override {
        class DCGLFP : public GrGLFragmentProcessor {
            void emitCode(EmitArgs& args) override {
                GrGLFragmentBuilder* fpb = args.fBuilder->getFragmentShaderBuilder();
                fpb->codeAppendf("vec2 c = %s;", fpb->ensureFSCoords2D(args.fCoords, 0).c_str());
                fpb->codeAppend("vec2 r = mod(c, vec2(20.0));");
                fpb->codeAppend("vec4 color = vec4(0.5*sin(c.x / 15.0) + 0.5,"
                                                    "0.5*cos((c.x + c.y) / 15.0) + 0.5,"
                                                    "(r.x + r.y) / 20.0,"
                                                    "distance(r, vec2(15.0)) / 20.0 + 0.2);");
                fpb->codeAppendf("color.rgb *= color.a;"
                                    "%s = color * %s;",
                                    args.fOutputColor, GrGLSLExpr4(args.fInputColor).c_str());
            }
            void onSetData(const GrGLProgramDataManager&, const GrProcessor&) override {}
        };
        return new DCGLFP;
    }

    const char* name() const override { return "DCFP"; }

    void onComputeInvariantOutput(GrInvariantOutput* inout) const override {
        inout->mulByUnknownFourComponents();
    }

private:
    void onGetGLProcessorKey(const GrGLSLCaps& caps,
                             GrProcessorKeyBuilder* b) const override {}

    bool onIsEqual(const GrFragmentProcessor&) const override { return true; }

    GrCoordTransform fDeviceTransform;
};

const GrFragmentProcessor* DCShader::asFragmentProcessor(GrContext*,
                                                         const SkMatrix& viewM,
                                                         const SkMatrix* localMatrix,
                                                         SkFilterQuality) const {
    SkAutoTUnref<const GrFragmentProcessor> inner(new DCFP(fDeviceMatrix));
    return GrFragmentProcessor::MulOutputByInputAlpha(inner);
}

class DCShaderGM : public GM {
public:
    DCShaderGM() {
        this->setBGColor(sk_tool_utils::color_to_565(0xFFAABBCC));
    }

    ~DCShaderGM() override {
        for (int i = 0; i < fPrims.count(); ++i) {
            delete fPrims[i];
        }
    }

protected:

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

    SkISize onISize() override { return SkISize::Make(1000, 900); }

    void onOnceBeforeDraw() override {
        struct Rect : public Prim {
            SkRect draw(SkCanvas* canvas, const SkPaint& paint) override {
                SkRect rect = SkRect::MakeXYWH(0, 0, 50, 50);
                canvas->drawRect(rect, paint);
                return rect;
            }
        };

        struct Circle : public Prim {
            SkRect draw(SkCanvas* canvas, const SkPaint& paint) override {
                static const SkScalar radius = 25;
                canvas->drawCircle(radius, radius, radius, paint);
                return SkRect::MakeXYWH(0, 0, 2 * radius, 2 * radius);
            }
        };

        struct RRect : public Prim {
            SkRect draw(SkCanvas* canvas, const SkPaint& paint) override {
                SkRRect rrect;
                rrect.setRectXY(SkRect::MakeXYWH(0, 0, 50, 50), 10, 10);
                canvas->drawRRect(rrect, paint);
                return rrect.getBounds();
            }
        };

        struct DRRect : public Prim {
            SkRect draw(SkCanvas* canvas, const SkPaint& paint) override {
                SkRRect outerRRect;
                outerRRect.setRectXY(SkRect::MakeXYWH(0, 0, 50, 50), 5, 5);
                SkRRect innerRRect;
                innerRRect.setRectXY(SkRect::MakeXYWH(5, 8, 35, 30), 8, 3);
                canvas->drawDRRect(outerRRect, innerRRect, paint);
                return outerRRect.getBounds();
            }
        };
        struct Path : public Prim {
            SkRect draw(SkCanvas* canvas, const SkPaint& paint) override {
                SkPath path;
                path.addCircle(15, 15, 10);
                path.addOval(SkRect::MakeXYWH(2, 2, 22, 37));
                path.setFillType(SkPath::kEvenOdd_FillType);
                canvas->drawPath(path, paint);
                return path.getBounds();
            }
        };

        struct Points : public Prim {
            Points(SkCanvas::PointMode mode) : fMode(mode) {}

            SkRect draw(SkCanvas* canvas, const SkPaint& paint) override {
                SkRandom random;
                SkPoint points[500];
                SkRect bounds = SkRect::MakeWH(50, 50);
                int count = SkToInt(SK_ARRAY_COUNT(points));
                if (SkCanvas::kPoints_PointMode != fMode) {
                    count = SkTMin(count, 10);
                }
                for (int p = 0; p < count; ++p) {
                    points[p].fX = random.nextUScalar1() * bounds.width();
                    points[p].fY = random.nextUScalar1() * bounds.width();
                }
                canvas->drawPoints(fMode, count, points, paint);
                return bounds;
            }
            SkCanvas::PointMode fMode;
        };

        struct Text : public Prim {
            SkRect draw(SkCanvas* canvas, const SkPaint& origPaint) override {
                SkPaint paint = origPaint;
                paint.setTextSize(30.f);
                this->setFont(&paint);
                const char* text = this->text();
                static const SkVector offset = SkVector::Make(10, 10);
                canvas->drawText(text, strlen(text), offset.fX, offset.fY, paint);
                SkRect bounds;
                paint.measureText(text, strlen(text), &bounds);
                bounds.offset(offset);
                return bounds;
            }

            virtual void setFont(SkPaint* paint) {
                sk_tool_utils::set_portable_typeface(paint);
            }

            virtual const char* text() const { return "Hello, Skia!"; }
        };

        fPrims.push_back(new Rect);
        fPrims.push_back(new Circle);
        fPrims.push_back(new RRect);
        fPrims.push_back(new DRRect);
        fPrims.push_back(new Path);
        fPrims.push_back(new Points(SkCanvas::kPoints_PointMode));
        fPrims.push_back(new Points(SkCanvas::kLines_PointMode));
        fPrims.push_back(new Points(SkCanvas::kPolygon_PointMode));
        fPrims.push_back(new Text);
    }

    void onDraw(SkCanvas* canvas) override {
        // This GM exists to test a specific feature of the GPU backend. It does not work with the
        // sw rasterizer, tile modes, etc.
        if (nullptr == canvas->getGrContext()) {
            skiagm::GM::DrawGpuOnlyMessage(canvas);
            return;
        }
        SkPaint paint;
        SkTArray<SkMatrix> devMats;
        devMats.push_back().reset();
        devMats.push_back().setRotate(45, 500, 500);
        devMats.push_back().setRotate(-30, 200, 200);
        devMats.back().setPerspX(-SK_Scalar1 / 2000);
        devMats.back().setPerspY(SK_Scalar1 / 1000);


        SkTArray<SkMatrix> viewMats;
        viewMats.push_back().setScale(0.75f, 0.75f);
        viewMats.push_back().setRotate(45, 50, 50);
        viewMats.back().postScale(0.5f, 1.1f);

        canvas->translate(10, 20);
        canvas->save();
        SkScalar tx = 0, maxTy = 0;
        static const SkScalar kW = 900;

        for (int aa = 0; aa < 2; ++aa) {
            for (int i = 0; i < fPrims.count(); ++i) {
                for (int j = 0; j < devMats.count(); ++j) {
                    for (int k = 0; k < viewMats.count(); ++k) {
                        paint.setShader(new DCShader(devMats[j]))->unref();
                        paint.setAntiAlias(SkToBool(aa));
                        canvas->save();
                        canvas->concat(viewMats[k]);
                        SkRect bounds = fPrims[i]->draw(canvas, paint);
                        canvas->restore();
                        viewMats[k].mapRect(&bounds);
                        // add margins
                        bounds.fRight += 20;
                        bounds.fBottom += 20;
                        canvas->translate(bounds.fRight, 0);
                        tx += bounds.fRight;
                        maxTy = SkTMax(bounds.fBottom, maxTy);
                        if (tx > kW) {
                            tx = 0;
                            canvas->restore();
                            canvas->translate(0, maxTy);
                            canvas->save();
                            maxTy = 0;
                        }
                    }
                }
            }
        }
        canvas->restore();
    }

private:
    struct Prim {
        virtual ~Prim() {}
        virtual SkRect draw(SkCanvas*, const SkPaint&) = 0;
    };

    SkTArray<Prim*> fPrims;

    typedef GM INHERITED;
};

DEF_GM(return new DCShaderGM;)
}
#endif
