RectoriBench.cpp revision 1d2f63159416ceec0544f803aef80f6e0c09e85c
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright 2013 Google Inc.
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Use of this source code is governed by a BSD-style license that can be
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * found in the LICENSE file.
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "SkBenchmark.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "SkCanvas.h"
10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "SkPaint.h"
11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "SkRandom.h"
12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "SkBlurMaskFilter.h"
13a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "SkLayerDrawLooper.h"
145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// This bench replicates a problematic use case of a draw looper used
163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// to create an inner blurred rect
171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass RectoriBench : public SkBenchmark {
185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)public:
19116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    RectoriBench(void* param) : INHERITED(param) {}
20116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciprotected:
225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual const char* onGetName() {
245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        return "rectori";
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        SkMWCRandom Random;
29cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
30a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        for (int i = 0; i < N; i++) {
31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            SkScalar blurRad = Random.nextRangeScalar(1.5f, 25.0f);
32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            SkScalar size = Random.nextRangeScalar(20*blurRad, 50*blurRad);
33a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
34a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            SkScalar x = Random.nextRangeScalar(0.0f, W - size);
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            SkScalar y = Random.nextRangeScalar(0.0f, H - size);
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            SkRect inner = { x, y, x + size, y + size };
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            SkRect outer(inner);
40ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch            // outer is always outset either 2x or 4x the blur radius (we go with 2x)
41ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch            outer.outset(SkIntToScalar(2*blurRad), SkIntToScalar(2*blurRad));
42ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
43ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch            SkPath p;
44ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
45ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch            p.addRect(outer);
46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            p.addRect(inner);
47ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch            p.setFillType(SkPath::kEvenOdd_FillType);
48ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
49ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch            // This will be used to translate the normal draw outside the
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            // clip rect and translate the blurred version back inside
51ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch            SkScalar translate = 2.0f * size;
52ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
53ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch            SkPaint paint;
54ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch            paint.setLooper(this->createLooper(-translate, blurRad))->unref();
55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            paint.setColor(0xff000000 | Random.nextU());
56ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch            paint.setAntiAlias(true);
57ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
58ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch            canvas->save();
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            // clip always equals inner rect so we get the inside blur
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            canvas->clipRect(inner);
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            canvas->translate(translate, 0);
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            canvas->drawPath(p, paint);
634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            canvas->restore();
64a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        }
654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
66ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)private:
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    enum {
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        W = 640,
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        H = 480,
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    enum { N = SkBENCHLOOP(100) };
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkLayerDrawLooper* createLooper(SkScalar xOff, SkScalar radius) {
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        SkLayerDrawLooper* looper = new SkLayerDrawLooper;
774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        //-----------------------------------------------
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        SkLayerDrawLooper::LayerInfo info;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        info.fFlagsMask = 0;
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // TODO: add a color filter to better match what is seen in the wild
835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        info.fPaintBits = /* SkLayerDrawLooper::kColorFilter_Bit |*/
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          SkLayerDrawLooper::kMaskFilter_Bit;
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        info.fColorMode = SkXfermode::kDst_Mode;
86a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        info.fOffset.set(xOff, 0);
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        info.fPostTranslate = false;
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        SkPaint* paint = looper->addLayer(info);
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        SkMaskFilter* mf = SkBlurMaskFilter::Create(SkIntToScalar(radius),
92a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                                    SkBlurMaskFilter::kNormal_BlurStyle,
93cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                                    SkBlurMaskFilter::kHighQuality_BlurFlag);
94cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        paint->setMaskFilter(mf)->unref();
95cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
96effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        //-----------------------------------------------
97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        info.fPaintBits = 0;
98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        info.fOffset.set(0, 0);
99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        paint = looper->addLayer(info);
101effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        return looper;
102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    }
103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    typedef SkBenchmark INHERITED;
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DEF_BENCH( return SkNEW_ARGS(RectoriBench, (p)); )
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)