12bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org/*
22bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org * Copyright 2014 Google Inc.
32bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org *
42bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org * Use of this source code is governed by a BSD-style license that can be
52bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org * found in the LICENSE file.
62bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org */
72bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org
82bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org#include "gm.h"
92bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org#include "SkColor.h"
102bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org#include "SkBitmapSource.h"
112bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org#include "SkBlurImageFilter.h"
122bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org#include "SkDisplacementMapEffect.h"
132bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org#include "SkDropShadowImageFilter.h"
142bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org#include "SkGradientShader.h"
151037d92bbc10cafb61d050638e8cbe5a3aa6706fcommit-bot@chromium.org#include "SkLightingImageFilter.h"
162bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org#include "SkMorphologyImageFilter.h"
17c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org#include "SkOffsetImageFilter.h"
1847d98c8e85924effc651b09df72027e6801c92a1senorblanco@chromium.org#include "SkPerlinNoiseShader.h"
1947d98c8e85924effc651b09df72027e6801c92a1senorblanco@chromium.org#include "SkRectShaderImageFilter.h"
20fd0ec2c76a27ce26a62da23eb75017839959e7cbsenorblanco@chromium.org#include "SkMatrixImageFilter.h"
212bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org#include "SkScalar.h"
222bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org
23897b73f62c012758bd8fef77c24d3573c847dbc3senorblanco@chromium.org#define RESIZE_FACTOR SkIntToScalar(4)
24897b73f62c012758bd8fef77c24d3573c847dbc3senorblanco@chromium.org
252bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.orgnamespace skiagm {
262bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org
272bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.orgclass ImageFiltersScaledGM : public GM {
282bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.orgpublic:
292bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org    ImageFiltersScaledGM() : fInitialized(false) {
302bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org        this->setBGColor(0x00000000);
312bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org    }
322bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org
332bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.orgprotected:
34a90c6803865766d28e92091f56f718f5e41fe80fcommit-bot@chromium.org    virtual uint32_t onGetFlags() const SK_OVERRIDE {
35a90c6803865766d28e92091f56f718f5e41fe80fcommit-bot@chromium.org        return kSkipTiled_Flag;
36a90c6803865766d28e92091f56f718f5e41fe80fcommit-bot@chromium.org    }
37a90c6803865766d28e92091f56f718f5e41fe80fcommit-bot@chromium.org
382bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org    virtual SkString onShortName() {
392bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org        return SkString("imagefiltersscaled");
402bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org    }
412bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org
422bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org    virtual SkISize onISize() {
43f539318f0d3dba743ec1886d5d9df0fb1be628a1tfarina        return SkISize::Make(1428, 500);
442bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org    }
452bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org
462bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org    void make_checkerboard() {
47eb9a46cbbb475e862a084aa2224ec18d4ac5e95breed@google.com        fCheckerboard.allocN32Pixels(64, 64);
48c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org        SkCanvas canvas(fCheckerboard);
492bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org        canvas.clear(0x00000000);
502bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org        SkPaint darkPaint;
512bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org        darkPaint.setColor(0xFF404040);
522bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org        SkPaint lightPaint;
532bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org        lightPaint.setColor(0xFFA0A0A0);
542bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org        for (int y = 0; y < 64; y += 16) {
552bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org          for (int x = 0; x < 64; x += 16) {
562bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org            canvas.save();
572bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org            canvas.translate(SkIntToScalar(x), SkIntToScalar(y));
582bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org            canvas.drawRect(SkRect::MakeXYWH(0, 0, 8, 8), darkPaint);
592bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org            canvas.drawRect(SkRect::MakeXYWH(8, 0, 8, 8), lightPaint);
602bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org            canvas.drawRect(SkRect::MakeXYWH(0, 8, 8, 8), lightPaint);
612bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org            canvas.drawRect(SkRect::MakeXYWH(8, 8, 8, 8), darkPaint);
622bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org            canvas.restore();
632bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org          }
642bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org        }
652bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org    }
662bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org
672bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org    void make_gradient_circle(int width, int height) {
682bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org        SkScalar x = SkIntToScalar(width / 2);
692bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org        SkScalar y = SkIntToScalar(height / 2);
702bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org        SkScalar radius = SkScalarMul(SkMinScalar(x, y), SkIntToScalar(4) / SkIntToScalar(5));
71eb9a46cbbb475e862a084aa2224ec18d4ac5e95breed@google.com        fGradientCircle.allocN32Pixels(width, height);
72c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org        SkCanvas canvas(fGradientCircle);
732bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org        canvas.clear(0x00000000);
742bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org        SkColor colors[2];
752bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org        colors[0] = SK_ColorWHITE;
762bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org        colors[1] = SK_ColorBLACK;
772bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org        SkAutoTUnref<SkShader> shader(
782bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org            SkGradientShader::CreateRadial(SkPoint::Make(x, y), radius, colors, NULL, 2,
792bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org                                           SkShader::kClamp_TileMode)
802bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org        );
812bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org        SkPaint paint;
822bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org        paint.setShader(shader);
832bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org        canvas.drawCircle(x, y, radius, paint);
842bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org    }
852bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org
862bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org    virtual void onDraw(SkCanvas* canvas) {
872bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org        if (!fInitialized) {
882bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org            this->make_checkerboard();
892bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org            this->make_gradient_circle(64, 64);
902bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org            fInitialized = true;
912bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org        }
922bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org        canvas->clear(0x00000000);
932bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org
94cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.org        SkAutoTUnref<SkImageFilter> gradient(SkBitmapSource::Create(fGradientCircle));
95cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.org        SkAutoTUnref<SkImageFilter> checkerboard(SkBitmapSource::Create(fCheckerboard));
9647d98c8e85924effc651b09df72027e6801c92a1senorblanco@chromium.org        SkAutoTUnref<SkShader> noise(SkPerlinNoiseShader::CreateFractalNoise(
9747d98c8e85924effc651b09df72027e6801c92a1senorblanco@chromium.org            SkDoubleToScalar(0.1), SkDoubleToScalar(0.05), 1, 0));
982bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org
991037d92bbc10cafb61d050638e8cbe5a3aa6706fcommit-bot@chromium.org        SkPoint3 pointLocation(0, 0, SkIntToScalar(10));
1001037d92bbc10cafb61d050638e8cbe5a3aa6706fcommit-bot@chromium.org        SkPoint3 spotLocation(SkIntToScalar(-10), SkIntToScalar(-10), SkIntToScalar(20));
1011037d92bbc10cafb61d050638e8cbe5a3aa6706fcommit-bot@chromium.org        SkPoint3 spotTarget(SkIntToScalar(40), SkIntToScalar(40), 0);
1021037d92bbc10cafb61d050638e8cbe5a3aa6706fcommit-bot@chromium.org        SkScalar spotExponent = SK_Scalar1;
1031037d92bbc10cafb61d050638e8cbe5a3aa6706fcommit-bot@chromium.org        SkScalar cutoffAngle = SkIntToScalar(15);
1041037d92bbc10cafb61d050638e8cbe5a3aa6706fcommit-bot@chromium.org        SkScalar kd = SkIntToScalar(2);
1051037d92bbc10cafb61d050638e8cbe5a3aa6706fcommit-bot@chromium.org        SkScalar surfaceScale = SkIntToScalar(1);
1061037d92bbc10cafb61d050638e8cbe5a3aa6706fcommit-bot@chromium.org        SkColor white(0xFFFFFFFF);
107fd0ec2c76a27ce26a62da23eb75017839959e7cbsenorblanco@chromium.org        SkMatrix resizeMatrix;
108fd0ec2c76a27ce26a62da23eb75017839959e7cbsenorblanco@chromium.org        resizeMatrix.setScale(RESIZE_FACTOR, RESIZE_FACTOR);
1091037d92bbc10cafb61d050638e8cbe5a3aa6706fcommit-bot@chromium.org
1102bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org        SkImageFilter* filters[] = {
111cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.org            SkBlurImageFilter::Create(SkIntToScalar(4), SkIntToScalar(4)),
112cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.org            SkDropShadowImageFilter::Create(SkIntToScalar(5), SkIntToScalar(10), SkIntToScalar(3),
113cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.org                                            SK_ColorYELLOW),
114cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.org            SkDisplacementMapEffect::Create(SkDisplacementMapEffect::kR_ChannelSelectorType,
115cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.org                                            SkDisplacementMapEffect::kR_ChannelSelectorType,
116cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.org                                            SkIntToScalar(12),
117cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.org                                            gradient.get(),
118cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.org                                            checkerboard.get()),
119cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.org            SkDilateImageFilter::Create(1, 1, checkerboard.get()),
120cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.org            SkErodeImageFilter::Create(1, 1, checkerboard.get()),
121cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.org            SkOffsetImageFilter::Create(SkIntToScalar(32), 0),
122fd0ec2c76a27ce26a62da23eb75017839959e7cbsenorblanco@chromium.org            SkMatrixImageFilter::Create(resizeMatrix, SkPaint::kNone_FilterLevel),
12347d98c8e85924effc651b09df72027e6801c92a1senorblanco@chromium.org            SkRectShaderImageFilter::Create(noise),
1241037d92bbc10cafb61d050638e8cbe5a3aa6706fcommit-bot@chromium.org            SkLightingImageFilter::CreatePointLitDiffuse(pointLocation, white, surfaceScale, kd),
1251037d92bbc10cafb61d050638e8cbe5a3aa6706fcommit-bot@chromium.org            SkLightingImageFilter::CreateSpotLitDiffuse(spotLocation, spotTarget, spotExponent,
1261037d92bbc10cafb61d050638e8cbe5a3aa6706fcommit-bot@chromium.org                                                        cutoffAngle, white, surfaceScale, kd),
1272bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org        };
1282bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org
1292bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org        SkVector scales[] = {
1302bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org            SkVector::Make(SkScalarInvert(2), SkScalarInvert(2)),
1312bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org            SkVector::Make(SkIntToScalar(1), SkIntToScalar(1)),
1322bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org            SkVector::Make(SkIntToScalar(1), SkIntToScalar(2)),
1332bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org            SkVector::Make(SkIntToScalar(2), SkIntToScalar(1)),
1342bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org            SkVector::Make(SkIntToScalar(2), SkIntToScalar(2)),
1352bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org        };
1362bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org
1372bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org        SkRect r = SkRect::MakeWH(SkIntToScalar(64), SkIntToScalar(64));
1382bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org        SkScalar margin = SkIntToScalar(16);
1392bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org        SkRect bounds = r;
1402bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org        bounds.outset(margin, margin);
1412bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org
1422bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org        for (size_t j = 0; j < SK_ARRAY_COUNT(scales); ++j) {
1432bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org            canvas->save();
1442bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org            for (size_t i = 0; i < SK_ARRAY_COUNT(filters); ++i) {
1452bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org                SkPaint paint;
1462bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org                paint.setColor(SK_ColorBLUE);
1472bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org                paint.setImageFilter(filters[i]);
1482bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org                paint.setAntiAlias(true);
1492bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org                canvas->save();
1502bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org                canvas->scale(scales[j].fX, scales[j].fY);
151c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org                if (5 == i) {
152c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org                    canvas->translate(SkIntToScalar(-32), 0);
153897b73f62c012758bd8fef77c24d3573c847dbc3senorblanco@chromium.org                } else if (6 == i) {
154897b73f62c012758bd8fef77c24d3573c847dbc3senorblanco@chromium.org                    canvas->scale(SkScalarInvert(RESIZE_FACTOR),
155897b73f62c012758bd8fef77c24d3573c847dbc3senorblanco@chromium.org                                  SkScalarInvert(RESIZE_FACTOR));
156c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org                }
1572bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org                canvas->drawCircle(r.centerX(), r.centerY(),
1582bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org                                   SkScalarDiv(r.width()*2, SkIntToScalar(5)), paint);
1592bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org                canvas->restore();
1602bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org                canvas->translate(r.width() * scales[j].fX + margin, 0);
1612bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org            }
1622bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org            canvas->restore();
1632bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org            canvas->translate(0, r.height() * scales[j].fY + margin);
1642bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org        }
1652bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org
1662bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org        for (size_t i = 0; i < SK_ARRAY_COUNT(filters); ++i) {
1672bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org            filters[i]->unref();
1682bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org        }
1692bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org    }
1702bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org
1712bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.orgprivate:
1722bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org    bool fInitialized;
1732bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org    SkBitmap fCheckerboard;
1742bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org    SkBitmap fGradientCircle;
1752bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org    typedef GM INHERITED;
1762bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org};
1772bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org
1782bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org//////////////////////////////////////////////////////////////////////////////
1792bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org
1802bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.orgstatic GM* MyFactory(void*) { return new ImageFiltersScaledGM; }
1812bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.orgstatic GMRegistry reg(MyFactory);
1822bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org
1832bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org}
184