RectoriBench.cpp revision 3361471a3504ecd0351ff70f4c42d8d6fee963d4
18e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels/* 28e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels * Copyright 2013 Google Inc. 38e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels * 48e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels * Use of this source code is governed by a BSD-style license that can be 58e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels * found in the LICENSE file. 68e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels */ 78e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 88e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include "SkBenchmark.h" 98e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include "SkCanvas.h" 108e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include "SkPaint.h" 118e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include "SkRandom.h" 128e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include "SkBlurMaskFilter.h" 138e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include "SkLayerDrawLooper.h" 148e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 158e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels// This bench replicates a problematic use case of a draw looper used 168e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels// to create an inner blurred rect 178e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsclass RectoriBench : public SkBenchmark { 188e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelspublic: 198e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels RectoriBench() {} 208e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 218e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsprotected: 228e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 238e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels virtual const char* onGetName() { 248e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels return "rectori"; 258e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels } 268e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 278e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels virtual void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE { 288e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels SkRandom Random; 298e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels 30 for (int i = 0; i < loops; i++) { 31 SkScalar blurSigma = Random.nextRangeScalar(1.5f, 25.0f); 32 SkScalar size = Random.nextRangeScalar(20*blurSigma, 50*blurSigma); 33 34 SkScalar x = Random.nextRangeScalar(0.0f, W - size); 35 SkScalar y = Random.nextRangeScalar(0.0f, H - size); 36 37 SkRect inner = { x, y, x + size, y + size }; 38 39 SkRect outer(inner); 40 // outer is always outset either 2x or 4x the blur radius (we go with 2x) 41 outer.outset(2*blurSigma, 2*blurSigma); 42 43 SkPath p; 44 45 p.addRect(outer); 46 p.addRect(inner); 47 p.setFillType(SkPath::kEvenOdd_FillType); 48 49 // This will be used to translate the normal draw outside the 50 // clip rect and translate the blurred version back inside 51 SkScalar translate = 2.0f * size; 52 53 SkPaint paint; 54 paint.setLooper(this->createLooper(-translate, blurSigma))->unref(); 55 paint.setColor(0xff000000 | Random.nextU()); 56 paint.setAntiAlias(true); 57 58 canvas->save(); 59 // clip always equals inner rect so we get the inside blur 60 canvas->clipRect(inner); 61 canvas->translate(translate, 0); 62 canvas->drawPath(p, paint); 63 canvas->restore(); 64 } 65 } 66 67private: 68 enum { 69 W = 640, 70 H = 480, 71 }; 72 73 SkLayerDrawLooper* createLooper(SkScalar xOff, SkScalar sigma) { 74 SkLayerDrawLooper* looper = new SkLayerDrawLooper; 75 76 //----------------------------------------------- 77 SkLayerDrawLooper::LayerInfo info; 78 79 info.fFlagsMask = 0; 80 // TODO: add a color filter to better match what is seen in the wild 81 info.fPaintBits = /* SkLayerDrawLooper::kColorFilter_Bit |*/ 82 SkLayerDrawLooper::kMaskFilter_Bit; 83 info.fColorMode = SkXfermode::kDst_Mode; 84 info.fOffset.set(xOff, 0); 85 info.fPostTranslate = false; 86 87 SkPaint* paint = looper->addLayer(info); 88 89 SkMaskFilter* mf = SkBlurMaskFilter::Create(SkBlurMaskFilter::kNormal_BlurStyle, 90 sigma, 91 SkBlurMaskFilter::kHighQuality_BlurFlag); 92 paint->setMaskFilter(mf)->unref(); 93 94 //----------------------------------------------- 95 info.fPaintBits = 0; 96 info.fOffset.set(0, 0); 97 98 paint = looper->addLayer(info); 99 return looper; 100 } 101 102 typedef SkBenchmark INHERITED; 103}; 104 105DEF_BENCH( return SkNEW_ARGS(RectoriBench, ()); ) 106