RectoriBench.cpp revision 48f31bdbb3346e3003581229395022bf44828b13
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"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "SkPaint.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "SkRandom.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "SkBlurMaskFilter.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "SkLayerDrawLooper.h"
14116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// This bench replicates a problematic use case of a draw looper used
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to create an inner blurred rect
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class RectoriBench : public SkBenchmark {
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)public:
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RectoriBench() {}
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)protected:
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    virtual const char* onGetName() {
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return "rectori";
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE {
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        SkRandom Random;
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        for (int i = 0; i < loops; i++) {
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            SkScalar blurSigma = Random.nextRangeScalar(1.5f, 25.0f);
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            SkScalar size = Random.nextRangeScalar(20*blurSigma, 50*blurSigma);
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (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)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            SkRect outer(inner);
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            // outer is always outset either 2x or 4x the blur radius (we go with 2x)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            outer.outset(2*blurSigma, 2*blurSigma);
425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            SkPath p;
44a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            p.addRect(outer);
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            p.addRect(inner);
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            p.setFillType(SkPath::kEvenOdd_FillType);
485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            // This will be used to translate the normal draw outside the
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            // clip rect and translate the blurred version back inside
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            SkScalar translate = 2.0f * size;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            SkPaint paint;
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            paint.setLooper(this->createLooper(-translate, blurSigma))->unref();
555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            paint.setColor(0xff000000 | Random.nextU());
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            paint.setAntiAlias(true);
57a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            canvas->save();
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            // clip always equals inner rect so we get the inside blur
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            canvas->clipRect(inner);
615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            canvas->translate(translate, 0);
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            canvas->drawPath(p, paint);
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            canvas->restore();
64116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        }
65116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    }
66116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
67116680a4aac90f2aa7413d9095a592090648e557Ben Murdochprivate:
68116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    enum {
69116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        W = 640,
70116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        H = 480,
71116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    };
72116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
73116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    SkLayerDrawLooper* createLooper(SkScalar xOff, SkScalar sigma) {
74116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        SkLayerDrawLooper* looper = new SkLayerDrawLooper;
75116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
76116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        //-----------------------------------------------
77116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        SkLayerDrawLooper::LayerInfo info;
78116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // TODO: add a color filter to better match what is seen in the wild
805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        info.fPaintBits = /* SkLayerDrawLooper::kColorFilter_Bit |*/
815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                          SkLayerDrawLooper::kMaskFilter_Bit;
825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        info.fColorMode = SkXfermode::kDst_Mode;
835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        info.fOffset.set(xOff, 0);
845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        info.fPostTranslate = false;
855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        SkPaint* paint = looper->addLayer(info);
875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        SkMaskFilter* mf = SkBlurMaskFilter::Create(SkBlurMaskFilter::kNormal_BlurStyle,
895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                                    sigma,
905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                                    SkBlurMaskFilter::kHighQuality_BlurFlag);
915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        paint->setMaskFilter(mf)->unref();
925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        //-----------------------------------------------
945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        info.fPaintBits = 0;
955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        info.fOffset.set(0, 0);
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        paint = looper->addLayer(info);
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return looper;
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    typedef SkBenchmark INHERITED;
1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci};
1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DEF_BENCH( return SkNEW_ARGS(RectoriBench, ()); )
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)