1e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com/*
2e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com * Copyright 2013 Google Inc.
3e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com *
4e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com * Use of this source code is governed by a BSD-style license that can be
5e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com * found in the LICENSE file.
6e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com */
7e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com
8e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com#include "gm.h"
9e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com#include "SkPerlinNoiseShader.h"
10e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com
11a501a64827ca3d67d45441e42bc377207eb5041breed@google.comclass PerlinNoiseGM : public skiagm::GM {
12e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.compublic:
13e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com    PerlinNoiseGM() {
14e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com        this->setBGColor(0xFF000000);
15e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com        fSize = SkISize::Make(80, 80);
16e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com    }
17e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com
18e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.comprotected:
19e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com    virtual SkString onShortName() {
20e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com        return SkString("perlinnoise");
21e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com    }
22e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com
23e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com    virtual SkISize onISize() {
24a501a64827ca3d67d45441e42bc377207eb5041breed@google.com        return SkISize::Make(200, 500);
25e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com    }
26e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com
27ce6a354e121915c2925e545e7df2929492d69d50senorblanco    void drawRect(SkCanvas* canvas, int x, int y, const SkPaint& paint, const SkISize& size) {
28e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com        canvas->save();
29ce6a354e121915c2925e545e7df2929492d69d50senorblanco        canvas->translate(SkIntToScalar(x), SkIntToScalar(y));
30ce6a354e121915c2925e545e7df2929492d69d50senorblanco        SkRect r = SkRect::MakeWH(SkIntToScalar(size.width()),
31ce6a354e121915c2925e545e7df2929492d69d50senorblanco                                  SkIntToScalar(size.height()));
32e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com        canvas->drawRect(r, paint);
33e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com        canvas->restore();
34e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com    }
35e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com
36e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com    void test(SkCanvas* canvas, int x, int y, SkPerlinNoiseShader::Type type,
37e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com              float baseFrequencyX, float baseFrequencyY, int numOctaves, float seed,
384775cba7b37e24e8480bd2d96e297fd0828fb5c3sugoi@google.com              bool stitchTiles) {
39ce6a354e121915c2925e545e7df2929492d69d50senorblanco        SkISize tileSize = SkISize::Make(fSize.width() / 2, fSize.height() / 2);
40e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com        SkShader* shader = (type == SkPerlinNoiseShader::kFractalNoise_Type) ?
41e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com            SkPerlinNoiseShader::CreateFractalNoise(baseFrequencyX, baseFrequencyY, numOctaves,
42ce6a354e121915c2925e545e7df2929492d69d50senorblanco                                                   seed, stitchTiles ? &tileSize : NULL) :
439fbbcca1c958e6df2cff24d3ccdb7ebd89b8486bcommit-bot@chromium.org            SkPerlinNoiseShader::CreateTurbulence(baseFrequencyX, baseFrequencyY, numOctaves,
44ce6a354e121915c2925e545e7df2929492d69d50senorblanco                                                seed, stitchTiles ? &tileSize : NULL);
45e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com        SkPaint paint;
46e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com        paint.setShader(shader)->unref();
47ce6a354e121915c2925e545e7df2929492d69d50senorblanco        if (stitchTiles) {
48ce6a354e121915c2925e545e7df2929492d69d50senorblanco            drawRect(canvas, x, y, paint, tileSize);
49ce6a354e121915c2925e545e7df2929492d69d50senorblanco            x += tileSize.width();
50ce6a354e121915c2925e545e7df2929492d69d50senorblanco            drawRect(canvas, x, y, paint, tileSize);
51ce6a354e121915c2925e545e7df2929492d69d50senorblanco            y += tileSize.width();
52ce6a354e121915c2925e545e7df2929492d69d50senorblanco            drawRect(canvas, x, y, paint, tileSize);
53ce6a354e121915c2925e545e7df2929492d69d50senorblanco            x -= tileSize.width();
54ce6a354e121915c2925e545e7df2929492d69d50senorblanco            drawRect(canvas, x, y, paint, tileSize);
55ce6a354e121915c2925e545e7df2929492d69d50senorblanco        } else {
56ce6a354e121915c2925e545e7df2929492d69d50senorblanco            drawRect(canvas, x, y, paint, fSize);
57ce6a354e121915c2925e545e7df2929492d69d50senorblanco        }
58e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com    }
59e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com
60e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com    virtual void onDraw(SkCanvas* canvas) {
61e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com        canvas->clear(0x00000000);
62c2a0ea6418988d4bcc0719f99b1a110cecd08679commit-bot@chromium.org        test(canvas,   0,   0, SkPerlinNoiseShader::kFractalNoise_Type,
63c2a0ea6418988d4bcc0719f99b1a110cecd08679commit-bot@chromium.org             0.1f, 0.1f, 0, 0, false);
64c2a0ea6418988d4bcc0719f99b1a110cecd08679commit-bot@chromium.org        test(canvas, 100,   0, SkPerlinNoiseShader::kTurbulence_Type,
65c2a0ea6418988d4bcc0719f99b1a110cecd08679commit-bot@chromium.org             0.1f, 0.1f, 0, 0, false);
66cff0243b0ff1de25b3d99e2bf15a30c0e0a31261skia.committer@gmail.com
67c2a0ea6418988d4bcc0719f99b1a110cecd08679commit-bot@chromium.org        test(canvas,   0, 100, SkPerlinNoiseShader::kFractalNoise_Type,
68e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com             0.1f, 0.1f, 2, 0, false);
69c2a0ea6418988d4bcc0719f99b1a110cecd08679commit-bot@chromium.org        test(canvas, 100, 100, SkPerlinNoiseShader::kFractalNoise_Type,
70ce6a354e121915c2925e545e7df2929492d69d50senorblanco             0.05f, 0.1f, 1, 0, true);
71e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com
72c2a0ea6418988d4bcc0719f99b1a110cecd08679commit-bot@chromium.org        test(canvas,   0, 200, SkPerlinNoiseShader::kTurbulence_Type,
73ce6a354e121915c2925e545e7df2929492d69d50senorblanco             0.1f, 0.1f, 1, 0, true);
74c2a0ea6418988d4bcc0719f99b1a110cecd08679commit-bot@chromium.org        test(canvas, 100, 200, SkPerlinNoiseShader::kTurbulence_Type,
75e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com             0.2f, 0.4f, 5, 0, false);
76e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com
77c2a0ea6418988d4bcc0719f99b1a110cecd08679commit-bot@chromium.org        test(canvas,   0, 300, SkPerlinNoiseShader::kFractalNoise_Type,
78e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com             0.1f, 0.1f, 3, 1, false);
79c2a0ea6418988d4bcc0719f99b1a110cecd08679commit-bot@chromium.org        test(canvas, 100, 300, SkPerlinNoiseShader::kFractalNoise_Type,
80e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com             0.1f, 0.1f, 3, 4, false);
81e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com
824b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org        canvas->scale(0.75f, 1.0f);
83e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com
84c2a0ea6418988d4bcc0719f99b1a110cecd08679commit-bot@chromium.org        test(canvas,   0, 400, SkPerlinNoiseShader::kFractalNoise_Type,
85e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com             0.1f, 0.1f, 2, 0, false);
86c2a0ea6418988d4bcc0719f99b1a110cecd08679commit-bot@chromium.org        test(canvas, 100, 400, SkPerlinNoiseShader::kFractalNoise_Type,
87ce6a354e121915c2925e545e7df2929492d69d50senorblanco             0.1f, 0.05f, 1, 0, true);
88e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com    }
89e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com
90e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.comprivate:
91e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com    typedef GM INHERITED;
92e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com    SkISize fSize;
93e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com};
94e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com
95a501a64827ca3d67d45441e42bc377207eb5041breed@google.comclass PerlinNoiseGM2 : public skiagm::GM {
96a501a64827ca3d67d45441e42bc377207eb5041breed@google.compublic:
97a501a64827ca3d67d45441e42bc377207eb5041breed@google.com    PerlinNoiseGM2() {
98a501a64827ca3d67d45441e42bc377207eb5041breed@google.com        fSize = SkISize::Make(80, 80);
99a501a64827ca3d67d45441e42bc377207eb5041breed@google.com    }
100e92c68f7d7398e8a510b7157a38747b23cb883aeskia.committer@gmail.com
101a501a64827ca3d67d45441e42bc377207eb5041breed@google.comprotected:
102a501a64827ca3d67d45441e42bc377207eb5041breed@google.com    virtual SkString onShortName() {
103a501a64827ca3d67d45441e42bc377207eb5041breed@google.com        return SkString("perlinnoise_localmatrix");
104a501a64827ca3d67d45441e42bc377207eb5041breed@google.com    }
105e92c68f7d7398e8a510b7157a38747b23cb883aeskia.committer@gmail.com
106a501a64827ca3d67d45441e42bc377207eb5041breed@google.com    virtual SkISize onISize() {
107a501a64827ca3d67d45441e42bc377207eb5041breed@google.com        return SkISize::Make(640, 480);
108a501a64827ca3d67d45441e42bc377207eb5041breed@google.com    }
109e92c68f7d7398e8a510b7157a38747b23cb883aeskia.committer@gmail.com
110a501a64827ca3d67d45441e42bc377207eb5041breed@google.com    void install(SkPaint* paint, SkPerlinNoiseShader::Type type,
111a501a64827ca3d67d45441e42bc377207eb5041breed@google.com              float baseFrequencyX, float baseFrequencyY, int numOctaves, float seed,
112a501a64827ca3d67d45441e42bc377207eb5041breed@google.com              bool stitchTiles) {
113a501a64827ca3d67d45441e42bc377207eb5041breed@google.com        SkShader* shader = (type == SkPerlinNoiseShader::kFractalNoise_Type) ?
114a501a64827ca3d67d45441e42bc377207eb5041breed@google.com        SkPerlinNoiseShader::CreateFractalNoise(baseFrequencyX, baseFrequencyY, numOctaves,
115a501a64827ca3d67d45441e42bc377207eb5041breed@google.com                                                seed, stitchTiles ? &fSize : NULL) :
116a501a64827ca3d67d45441e42bc377207eb5041breed@google.com        SkPerlinNoiseShader::CreateTurbulence(baseFrequencyX, baseFrequencyY, numOctaves,
117a501a64827ca3d67d45441e42bc377207eb5041breed@google.com                                              seed, stitchTiles ? &fSize : NULL);
118a501a64827ca3d67d45441e42bc377207eb5041breed@google.com        paint->setShader(shader)->unref();
119a501a64827ca3d67d45441e42bc377207eb5041breed@google.com    }
120e92c68f7d7398e8a510b7157a38747b23cb883aeskia.committer@gmail.com
121a501a64827ca3d67d45441e42bc377207eb5041breed@google.com    virtual void onDraw(SkCanvas* canvas) {
122a501a64827ca3d67d45441e42bc377207eb5041breed@google.com        canvas->translate(10, 10);
123a501a64827ca3d67d45441e42bc377207eb5041breed@google.com
124a501a64827ca3d67d45441e42bc377207eb5041breed@google.com        SkPaint paint;
125a501a64827ca3d67d45441e42bc377207eb5041breed@google.com        install(&paint, SkPerlinNoiseShader::kFractalNoise_Type, 0.1f, 0.1f, 2, 0, false);
126a501a64827ca3d67d45441e42bc377207eb5041breed@google.com
127a501a64827ca3d67d45441e42bc377207eb5041breed@google.com        const SkScalar w = SkIntToScalar(fSize.width());
128a501a64827ca3d67d45441e42bc377207eb5041breed@google.com        const SkScalar h = SkIntToScalar(fSize.height());
129a501a64827ca3d67d45441e42bc377207eb5041breed@google.com
130a501a64827ca3d67d45441e42bc377207eb5041breed@google.com        SkRect r = SkRect::MakeWH(w, h);
131a501a64827ca3d67d45441e42bc377207eb5041breed@google.com        canvas->drawRect(r, paint);
132a501a64827ca3d67d45441e42bc377207eb5041breed@google.com
133a501a64827ca3d67d45441e42bc377207eb5041breed@google.com        canvas->save();
134a501a64827ca3d67d45441e42bc377207eb5041breed@google.com        canvas->translate(w * 5/4, 0);
135a501a64827ca3d67d45441e42bc377207eb5041breed@google.com        canvas->drawRect(r, paint);
136a501a64827ca3d67d45441e42bc377207eb5041breed@google.com        canvas->restore();
137e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com
138a501a64827ca3d67d45441e42bc377207eb5041breed@google.com        canvas->save();
139a501a64827ca3d67d45441e42bc377207eb5041breed@google.com        canvas->translate(0, h + 10);
140a501a64827ca3d67d45441e42bc377207eb5041breed@google.com        canvas->scale(2, 2);
141a501a64827ca3d67d45441e42bc377207eb5041breed@google.com        canvas->drawRect(r, paint);
142a501a64827ca3d67d45441e42bc377207eb5041breed@google.com        canvas->restore();
143e92c68f7d7398e8a510b7157a38747b23cb883aeskia.committer@gmail.com
144a501a64827ca3d67d45441e42bc377207eb5041breed@google.com        canvas->save();
145a501a64827ca3d67d45441e42bc377207eb5041breed@google.com        canvas->translate(w + 100, h + 10);
146a501a64827ca3d67d45441e42bc377207eb5041breed@google.com        canvas->scale(2, 2);
147a501a64827ca3d67d45441e42bc377207eb5041breed@google.com        canvas->drawRect(r, paint);
148a501a64827ca3d67d45441e42bc377207eb5041breed@google.com        canvas->restore();
149a501a64827ca3d67d45441e42bc377207eb5041breed@google.com
150a501a64827ca3d67d45441e42bc377207eb5041breed@google.com        // The next row should draw the same as the previous, even though we are using a local
151a501a64827ca3d67d45441e42bc377207eb5041breed@google.com        // matrix instead of the canvas.
152a501a64827ca3d67d45441e42bc377207eb5041breed@google.com
153a501a64827ca3d67d45441e42bc377207eb5041breed@google.com        canvas->translate(0, h * 2 + 10);
154a501a64827ca3d67d45441e42bc377207eb5041breed@google.com
155a501a64827ca3d67d45441e42bc377207eb5041breed@google.com        SkMatrix lm;
156a501a64827ca3d67d45441e42bc377207eb5041breed@google.com        lm.setScale(2, 2);
1575970f625e96cdc007c563ae72f343ae0d71719a1commit-bot@chromium.org        paint.setShader(SkShader::CreateLocalMatrixShader(paint.getShader(), lm))->unref();
158a501a64827ca3d67d45441e42bc377207eb5041breed@google.com        r.fRight += r.width();
159a501a64827ca3d67d45441e42bc377207eb5041breed@google.com        r.fBottom += r.height();
160a501a64827ca3d67d45441e42bc377207eb5041breed@google.com
161a501a64827ca3d67d45441e42bc377207eb5041breed@google.com        canvas->save();
162a501a64827ca3d67d45441e42bc377207eb5041breed@google.com        canvas->translate(0, h + 10);
163a501a64827ca3d67d45441e42bc377207eb5041breed@google.com        canvas->drawRect(r, paint);
164a501a64827ca3d67d45441e42bc377207eb5041breed@google.com        canvas->restore();
165e92c68f7d7398e8a510b7157a38747b23cb883aeskia.committer@gmail.com
166a501a64827ca3d67d45441e42bc377207eb5041breed@google.com        canvas->save();
167a501a64827ca3d67d45441e42bc377207eb5041breed@google.com        canvas->translate(w + 100, h + 10);
168a501a64827ca3d67d45441e42bc377207eb5041breed@google.com        canvas->drawRect(r, paint);
169a501a64827ca3d67d45441e42bc377207eb5041breed@google.com        canvas->restore();
170a501a64827ca3d67d45441e42bc377207eb5041breed@google.com    }
171e92c68f7d7398e8a510b7157a38747b23cb883aeskia.committer@gmail.com
172a501a64827ca3d67d45441e42bc377207eb5041breed@google.comprivate:
173a501a64827ca3d67d45441e42bc377207eb5041breed@google.com    typedef GM INHERITED;
174a501a64827ca3d67d45441e42bc377207eb5041breed@google.com    SkISize fSize;
175a501a64827ca3d67d45441e42bc377207eb5041breed@google.com};
176a501a64827ca3d67d45441e42bc377207eb5041breed@google.com
177a501a64827ca3d67d45441e42bc377207eb5041breed@google.com//////////////////////////////////////////////////////////////////////////////
178e3b4c5097a6fd9b6c09d2ffbc3db170a287fdd99sugoi@google.com
179a501a64827ca3d67d45441e42bc377207eb5041breed@google.comDEF_GM( return new PerlinNoiseGM; )
180a501a64827ca3d67d45441e42bc377207eb5041breed@google.comDEF_GM( return new PerlinNoiseGM2; )
181