17839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger/*
27839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * Copyright 2013 Google Inc.
37839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger *
47839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * Use of this source code is governed by a BSD-style license that can be
57839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * found in the LICENSE file.
67839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger */
77839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#include "SkBenchmark.h"
80a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger#include "SkBitmapDevice.h"
97839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#include "SkBitmapSource.h"
107839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#include "SkCanvas.h"
117839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#include "SkDisplacementMapEffect.h"
127839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
137839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#define FILTER_WIDTH_SMALL  32
147839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#define FILTER_HEIGHT_SMALL 32
157839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#define FILTER_WIDTH_LARGE  256
167839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#define FILTER_HEIGHT_LARGE 256
177839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
187839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerclass DisplacementBaseBench : public SkBenchmark {
197839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerpublic:
200a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    DisplacementBaseBench(bool small) :
210a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        fInitialized(false), fIsSmall(small) {
227839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
237839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
247839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerprotected:
257839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    virtual void onPreDraw() SK_OVERRIDE {
267839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        if (!fInitialized) {
270a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            this->makeBitmap();
280a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            this->makeCheckerboard();
297839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            fInitialized = true;
307839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        }
317839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
327839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
330a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    void makeBitmap() {
340a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        const int w = this->isSmall() ? FILTER_WIDTH_SMALL : FILTER_WIDTH_LARGE;
350a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        const int h = this->isSmall() ? FILTER_HEIGHT_LARGE : FILTER_HEIGHT_LARGE;
367839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        fBitmap.setConfig(SkBitmap::kARGB_8888_Config, w, h);
377839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        fBitmap.allocPixels();
380a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        SkBitmapDevice device(fBitmap);
397839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        SkCanvas canvas(&device);
407839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        canvas.clear(0x00000000);
417839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        SkPaint paint;
427839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        paint.setAntiAlias(true);
437839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        paint.setColor(0xFF884422);
447839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        paint.setTextSize(SkIntToScalar(96));
457839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        const char* str = "g";
467839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        canvas.drawText(str, strlen(str), SkIntToScalar(15), SkIntToScalar(55), paint);
477839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
487839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
490a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    void makeCheckerboard() {
500a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        const int w = this->isSmall() ? FILTER_WIDTH_SMALL : FILTER_WIDTH_LARGE;
510a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        const int h = this->isSmall() ? FILTER_HEIGHT_LARGE : FILTER_HEIGHT_LARGE;
527839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        fCheckerboard.setConfig(SkBitmap::kARGB_8888_Config, w, h);
537839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        fCheckerboard.allocPixels();
540a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        SkBitmapDevice device(fCheckerboard);
557839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        SkCanvas canvas(&device);
567839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        canvas.clear(0x00000000);
577839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        SkPaint darkPaint;
587839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        darkPaint.setColor(0xFF804020);
597839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        SkPaint lightPaint;
607839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        lightPaint.setColor(0xFF244484);
617839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        for (int y = 0; y < h; y += 16) {
627839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            for (int x = 0; x < w; x += 16) {
637839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                canvas.save();
647839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                canvas.translate(SkIntToScalar(x), SkIntToScalar(y));
657839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                canvas.drawRect(SkRect::MakeXYWH(0, 0, 8, 8), darkPaint);
667839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                canvas.drawRect(SkRect::MakeXYWH(8, 0, 8, 8), lightPaint);
677839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                canvas.drawRect(SkRect::MakeXYWH(0, 8, 8, 8), lightPaint);
687839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                canvas.drawRect(SkRect::MakeXYWH(8, 8, 8, 8), darkPaint);
697839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                canvas.restore();
707839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            }
717839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        }
727839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
737839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
747839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    void drawClippedBitmap(SkCanvas* canvas, int x, int y, const SkPaint& paint) {
757839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        canvas->save();
767839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        canvas->clipRect(SkRect::MakeXYWH(SkIntToScalar(x), SkIntToScalar(y),
770a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                                          SkIntToScalar(fBitmap.width()),
780a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                                          SkIntToScalar(fBitmap.height())));
797839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        canvas->drawBitmap(fBitmap, SkIntToScalar(x), SkIntToScalar(y), &paint);
807839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        canvas->restore();
817839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
827839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
837839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    inline bool isSmall() const { return fIsSmall; }
847839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
857839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkBitmap fBitmap, fCheckerboard;
867839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerprivate:
877839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    bool fInitialized;
887839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    bool fIsSmall;
897839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    typedef SkBenchmark INHERITED;
907839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger};
917839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
927839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerclass DisplacementZeroBench : public DisplacementBaseBench {
937839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerpublic:
940a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    DisplacementZeroBench(bool small) : INHERITED(small) {
957839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
967839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
977839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerprotected:
987839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    virtual const char* onGetName() SK_OVERRIDE {
990a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        return this->isSmall() ? "displacement_zero_small" : "displacement_zero_large";
1007839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
1017839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
102910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger    virtual void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE {
1037839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        SkPaint paint;
1047839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        SkAutoTUnref<SkImageFilter> displ(SkNEW_ARGS(SkBitmapSource, (fCheckerboard)));
1057839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        // No displacement effect
1067839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        paint.setImageFilter(SkNEW_ARGS(SkDisplacementMapEffect,
1077839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            (SkDisplacementMapEffect::kR_ChannelSelectorType,
1087839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger             SkDisplacementMapEffect::kG_ChannelSelectorType, 0.0f, displ)))->unref();
1090a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
110910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger        for (int i = 0; i < loops; i++) {
1110a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            this->drawClippedBitmap(canvas, 0, 0, paint);
1120a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        }
1137839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
1147839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
1157839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerprivate:
1167839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    typedef DisplacementBaseBench INHERITED;
1177839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger};
1187839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
1197839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerclass DisplacementAlphaBench : public DisplacementBaseBench {
1207839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerpublic:
1210a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    DisplacementAlphaBench(bool small) : INHERITED(small) {
1227839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
1237839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
1247839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerprotected:
1257839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    virtual const char* onGetName() SK_OVERRIDE {
1267839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        return isSmall() ? "displacement_alpha_small" : "displacement_alpha_large";
1277839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
1287839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
129910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger    virtual void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE {
1307839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        SkPaint paint;
1317839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        SkAutoTUnref<SkImageFilter> displ(SkNEW_ARGS(SkBitmapSource, (fCheckerboard)));
1327839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        // Displacement, with 1 alpha component (which isn't pre-multiplied)
1337839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        paint.setImageFilter(SkNEW_ARGS(SkDisplacementMapEffect,
1347839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            (SkDisplacementMapEffect::kB_ChannelSelectorType,
1357839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger             SkDisplacementMapEffect::kA_ChannelSelectorType, 16.0f, displ)))->unref();
136910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger        for (int i = 0; i < loops; i++) {
1370a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            drawClippedBitmap(canvas, 100, 0, paint);
1380a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        }
1397839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
1407839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
1417839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerprivate:
1427839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    typedef DisplacementBaseBench INHERITED;
1437839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger};
1447839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
1457839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerclass DisplacementFullBench : public DisplacementBaseBench {
1467839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerpublic:
1470a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    DisplacementFullBench(bool small) : INHERITED(small) {
1487839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
1497839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
1507839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerprotected:
1517839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    virtual const char* onGetName() SK_OVERRIDE {
1527839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        return isSmall() ? "displacement_full_small" : "displacement_full_large";
1537839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
1547839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
155910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger    virtual void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE {
1567839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        SkPaint paint;
1577839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        SkAutoTUnref<SkImageFilter> displ(SkNEW_ARGS(SkBitmapSource, (fCheckerboard)));
1587839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        // Displacement, with 2 non-alpha components
1597839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        paint.setImageFilter(SkNEW_ARGS(SkDisplacementMapEffect,
1607839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            (SkDisplacementMapEffect::kR_ChannelSelectorType,
1617839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger             SkDisplacementMapEffect::kB_ChannelSelectorType, 32.0f, displ)))->unref();
162910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger        for (int i = 0; i < loops; ++i) {
1630a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            this->drawClippedBitmap(canvas, 200, 0, paint);
1640a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        }
1657839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
1667839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
1677839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerprivate:
1687839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    typedef DisplacementBaseBench INHERITED;
1697839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger};
1707839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
1717839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger///////////////////////////////////////////////////////////////////////////////
1727839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
1730a657bbc2c6fc9daf699942e023050536d5ec95fDerek SollenbergerDEF_BENCH( return new DisplacementZeroBench(true); )
1740a657bbc2c6fc9daf699942e023050536d5ec95fDerek SollenbergerDEF_BENCH( return new DisplacementAlphaBench(true); )
1750a657bbc2c6fc9daf699942e023050536d5ec95fDerek SollenbergerDEF_BENCH( return new DisplacementFullBench(true); )
1760a657bbc2c6fc9daf699942e023050536d5ec95fDerek SollenbergerDEF_BENCH( return new DisplacementZeroBench(false); )
1770a657bbc2c6fc9daf699942e023050536d5ec95fDerek SollenbergerDEF_BENCH( return new DisplacementAlphaBench(false); )
1780a657bbc2c6fc9daf699942e023050536d5ec95fDerek SollenbergerDEF_BENCH( return new DisplacementFullBench(false); )
179