RectoriBench.cpp revision b7061176c7f414616fe2e79e832b3e0abe326af6
1/* 2 * Copyright 2013 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8#include "SkBenchmark.h" 9#include "SkCanvas.h" 10#include "SkPaint.h" 11#include "SkRandom.h" 12#include "SkBlurMaskFilter.h" 13#include "SkLayerDrawLooper.h" 14 15// This bench replicates a problematic use case of a draw looper used 16// to create an inner blurred rect 17class RectoriBench : public SkBenchmark { 18public: 19 RectoriBench(void* param) : INHERITED(param) {} 20 21protected: 22 23 virtual const char* onGetName() { 24 return "rectori"; 25 } 26 27 virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE { 28 SkMWCRandom Random; 29 30 for (int i = 0; i < N; 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 enum { N = SkBENCHLOOP(100) }; 74 75 SkLayerDrawLooper* createLooper(SkScalar xOff, SkScalar sigma) { 76 SkLayerDrawLooper* looper = new SkLayerDrawLooper; 77 78 //----------------------------------------------- 79 SkLayerDrawLooper::LayerInfo info; 80 81 info.fFlagsMask = 0; 82 // TODO: add a color filter to better match what is seen in the wild 83 info.fPaintBits = /* SkLayerDrawLooper::kColorFilter_Bit |*/ 84 SkLayerDrawLooper::kMaskFilter_Bit; 85 info.fColorMode = SkXfermode::kDst_Mode; 86 info.fOffset.set(xOff, 0); 87 info.fPostTranslate = false; 88 89 SkPaint* paint = looper->addLayer(info); 90 91 SkMaskFilter* mf = SkBlurMaskFilter::Create(SkBlurMaskFilter::kNormal_BlurStyle, 92 sigma, 93 SkBlurMaskFilter::kHighQuality_BlurFlag); 94 paint->setMaskFilter(mf)->unref(); 95 96 //----------------------------------------------- 97 info.fPaintBits = 0; 98 info.fOffset.set(0, 0); 99 100 paint = looper->addLayer(info); 101 return looper; 102 } 103 104 typedef SkBenchmark INHERITED; 105}; 106 107 108DEF_BENCH( return SkNEW_ARGS(RectoriBench, (p)); ) 109