RectoriBench.cpp revision 0431b87a98f2f3721d8e5dba04bf81a2fd8b5d1c
11d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com/*
21d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com * Copyright 2013 Google Inc.
31d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com *
41d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com * Use of this source code is governed by a BSD-style license that can be
51d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com * found in the LICENSE file.
61d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com */
71d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com
81d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com#include "SkBenchmark.h"
91d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com#include "SkCanvas.h"
101d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com#include "SkPaint.h"
111d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com#include "SkRandom.h"
121d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com#include "SkBlurMaskFilter.h"
131d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com#include "SkLayerDrawLooper.h"
141d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com
151d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com// This bench replicates a problematic use case of a draw looper used
161d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com// to create an inner blurred rect
171d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.comclass RectoriBench : public SkBenchmark {
181d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.compublic:
191d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com    RectoriBench(void* param) : INHERITED(param) {}
201d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com
211d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.comprotected:
221d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com
231d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com    virtual const char* onGetName() {
241d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com        return "rectori";
251d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com    }
261d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com
271d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com    virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
281d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com        SkMWCRandom Random;
291d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com
301d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com        for (int i = 0; i < N; i++) {
311d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com            SkScalar blurRad = Random.nextRangeScalar(1.5f, 25.0f);
321d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com            SkScalar size = Random.nextRangeScalar(20*blurRad, 50*blurRad);
331d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com
341d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com            SkScalar x = Random.nextRangeScalar(0.0f, W - size);
351d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com            SkScalar y = Random.nextRangeScalar(0.0f, H - size);
361d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com
371d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com            SkRect inner = { x, y, x + size, y + size };
381d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com
391d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com            SkRect outer(inner);
401d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com            // outer is always outset either 2x or 4x the blur radius (we go with 2x)
4163a3f6f5d98711f1d83967ed10e5e972b586ae6erobertphillips@google.com            outer.outset(2*blurRad, 2*blurRad);
421d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com
431d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com            SkPath p;
441d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com
451d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com            p.addRect(outer);
461d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com            p.addRect(inner);
471d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com            p.setFillType(SkPath::kEvenOdd_FillType);
481d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com
491d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com            // This will be used to translate the normal draw outside the
501d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com            // clip rect and translate the blurred version back inside
511d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com            SkScalar translate = 2.0f * size;
521d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com
531d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com            SkPaint paint;
541d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com            paint.setLooper(this->createLooper(-translate, blurRad))->unref();
551d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com            paint.setColor(0xff000000 | Random.nextU());
561d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com            paint.setAntiAlias(true);
571d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com
581d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com            canvas->save();
591d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com            // clip always equals inner rect so we get the inside blur
601d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com            canvas->clipRect(inner);
611d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com            canvas->translate(translate, 0);
621d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com            canvas->drawPath(p, paint);
631d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com            canvas->restore();
641d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com        }
651d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com    }
661d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com
671d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.comprivate:
681d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com    enum {
691d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com        W = 640,
701d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com        H = 480,
711d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com    };
721d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com
731d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com    enum { N = SkBENCHLOOP(100) };
741d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com
751d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com    SkLayerDrawLooper* createLooper(SkScalar xOff, SkScalar radius) {
761d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com        SkLayerDrawLooper* looper = new SkLayerDrawLooper;
771d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com
781d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com        //-----------------------------------------------
791d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com        SkLayerDrawLooper::LayerInfo info;
801d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com
811d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com        info.fFlagsMask = 0;
821d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com        // TODO: add a color filter to better match what is seen in the wild
830431b87a98f2f3721d8e5dba04bf81a2fd8b5d1cskia.committer@gmail.com        info.fPaintBits = /* SkLayerDrawLooper::kColorFilter_Bit |*/
841d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com                          SkLayerDrawLooper::kMaskFilter_Bit;
851d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com        info.fColorMode = SkXfermode::kDst_Mode;
861d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com        info.fOffset.set(xOff, 0);
871d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com        info.fPostTranslate = false;
881d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com
891d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com        SkPaint* paint = looper->addLayer(info);
901d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com
9163a3f6f5d98711f1d83967ed10e5e972b586ae6erobertphillips@google.com        SkMaskFilter* mf = SkBlurMaskFilter::Create(radius,
921d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com                                                    SkBlurMaskFilter::kNormal_BlurStyle,
931d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com                                                    SkBlurMaskFilter::kHighQuality_BlurFlag);
941d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com        paint->setMaskFilter(mf)->unref();
951d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com
961d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com        //-----------------------------------------------
971d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com        info.fPaintBits = 0;
981d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com        info.fOffset.set(0, 0);
991d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com
1001d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com        paint = looper->addLayer(info);
1011d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com        return looper;
1021d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com    }
1031d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com
1041d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com    typedef SkBenchmark INHERITED;
1051d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com};
1061d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com
1071d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.com
1081d2f63159416ceec0544f803aef80f6e0c09e85crobertphillips@google.comDEF_BENCH( return SkNEW_ARGS(RectoriBench, (p)); )
109