megalooper.cpp revision 41570854703ae432c1c9bf335399727ff3eadb21
141570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com/* 241570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com * Copyright 2013 Google Inc. 341570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com * 441570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com * Use of this source code is governed by a BSD-style license that can be 541570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com * found in the LICENSE file. 641570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com */ 741570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com 841570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com#include "gm.h" 941570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com#include "SkCanvas.h" 1041570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com#include "SkBlurMaskFilter.h" 1141570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com#include "SkLayerDrawLooper.h" 1241570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com#include "SkColorFilter.h" 1341570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com 1441570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com// This GM tests 3 different ways of drawing four shadows around a square: 1541570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com// just using 4 blurred rects 1641570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com// using 4 1-level draw loopers 1741570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com// using 1 4-level draw looper 1841570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com// They all produce exactly the same pixels 1941570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.comclass MegaLooperGM : public skiagm::GM { 2041570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.compublic: 2141570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com // The types define "<# of loopers> x <# of stages per looper>" 2241570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com enum Type { 2341570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com k0x0_Type, // draw without loopers at all 2441570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com k4x1_Type, // a looper for each shadow 2541570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com k1x4_Type, // all four shadows in one looper 2641570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com }; 2741570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com 2841570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com MegaLooperGM(Type type) : fType(type) {} 2941570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com 3041570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.comprotected: 3141570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com virtual SkString onShortName() { 3241570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com switch (fType) { 3341570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com case k0x0_Type: 3441570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com return SkString("megalooper_0x0"); 3541570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com break; 3641570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com case k4x1_Type: 3741570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com return SkString("megalooper_4x1"); 3841570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com break; 3941570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com case k1x4_Type: // fall through 4041570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com default: 4141570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com return SkString("megalooper_1x4"); 4241570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com break; 4341570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com } 4441570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com } 4541570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com 4641570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com virtual SkISize onISize() { 4741570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com return SkISize::Make(kWidth, kHeight); 4841570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com } 4941570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com 5041570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com virtual void onDraw(SkCanvas* canvas) { 5141570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com for (int y = 100; y < kHeight; y += 200) { 5241570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com for (int x = 100; x < kWidth; x += 200) { 5341570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com switch (fType) { 5441570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com case k0x0_Type: 5541570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com draw0x0(canvas, SkIntToScalar(x), SkIntToScalar(y)); 5641570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com break; 5741570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com case k4x1_Type: 5841570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com draw4x1(canvas, SkIntToScalar(x), SkIntToScalar(y)); 5941570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com break; 6041570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com case k1x4_Type: // fall through 6141570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com default: 6241570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com draw1x4(canvas, SkIntToScalar(x), SkIntToScalar(y)); 6341570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com break; 6441570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com } 6541570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com } 6641570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com } 6741570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com } 6841570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com 6941570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.comprivate: 7041570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com static const int kWidth = 800; 7141570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com static const int kHeight = 800; 7241570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com static const int kHalfOuterClipSize = 100; 7341570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com static const int kHalfSquareSize = 50; 7441570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com static const int kOffsetToOutsideClip = kHalfSquareSize + kHalfOuterClipSize + 1; 7541570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com 7641570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com static const SkPoint gBlurOffsets[4]; 7741570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com static const SkColor gColors[4]; 7841570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com Type fType; 7941570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com 8041570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com // Just draw a blurred rect at each of the four corners of a square (centered at x,y). 8141570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com // Use two clips to define a rectori where we want pixels to appear. 8241570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com void draw0x0(SkCanvas* canvas, SkScalar x, SkScalar y) { 8341570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com SkRect innerClip = { -kHalfSquareSize, -kHalfSquareSize, kHalfSquareSize, kHalfSquareSize }; 8441570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com innerClip.offset(x, y); 8541570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com 8641570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com SkRect outerClip = { 8741570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com -kHalfOuterClipSize-kHalfSquareSize, -kHalfOuterClipSize-kHalfSquareSize, 8841570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com kHalfOuterClipSize+kHalfSquareSize, kHalfOuterClipSize+kHalfSquareSize 8941570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com }; 9041570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com outerClip.offset(x, y); 9141570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com 9241570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com canvas->save(); 9341570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com canvas->clipRect(outerClip, SkRegion::kIntersect_Op); 9441570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com canvas->clipRect(innerClip, SkRegion::kDifference_Op); 9541570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com 9641570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com SkPaint paint; 9741570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com paint.setAntiAlias(true); 9841570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com paint.setMaskFilter(createBlur())->unref(); 9941570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com 10041570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com for (int i = 0; i < 4; ++i) { 10141570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com paint.setColor(gColors[i]); 10241570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com 10341570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com SkRect rect = { -kHalfSquareSize, -kHalfSquareSize, kHalfSquareSize, kHalfSquareSize }; 10441570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com rect.offset(gBlurOffsets[i]); 10541570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com rect.offset(x, y); 10641570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com canvas->drawRect(rect, paint); 10741570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com } 10841570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com 10941570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com canvas->restore(); 11041570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com } 11141570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com 11241570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com SkMaskFilter* createBlur() { 11341570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com static const SkScalar kBlurRadius = 25.0f; 11441570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com 11541570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com return SkBlurMaskFilter::Create(kBlurRadius, 11641570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com SkBlurMaskFilter::kNormal_BlurStyle, 11741570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com SkBlurMaskFilter::kHighQuality_BlurFlag); 11841570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com } 11941570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com 12041570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com // This draws 4 blurred shadows around a single square (centered at x, y). 12141570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com // Each blur is offset +/- half the square's side in x & y from the original 12241570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com // (so each blurred rect is centered at one of the corners of the original). 12341570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com // For each blur a large outer clip is centered around the blurred rect 12441570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com // while a difference clip stays at the location of the original rect. 12541570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com // Each blurred rect is drawn with a draw looper where the original (non- 12641570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com // blurred rect) is offset to reside outside of the large outer clip (so 12741570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com // it never appears) but the offset in the draw looper is used to translate 12841570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com // the blurred version back into the clip. 12941570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com void draw4x1(SkCanvas* canvas, SkScalar x, SkScalar y) { 13041570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com 13141570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com for (int i = 0; i < 4; ++i) { 13241570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com SkPaint loopPaint; 13341570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com 13441570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com loopPaint.setLooper(create1Looper(-kOffsetToOutsideClip, 0, gColors[i])); 13541570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com loopPaint.setAntiAlias(true); 13641570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com 13741570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com SkRect outerClip = { 13841570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com -kHalfOuterClipSize, -kHalfOuterClipSize, 13941570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com kHalfOuterClipSize, kHalfOuterClipSize 14041570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com }; 14141570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com outerClip.offset(x, y); 14241570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com // center it on the blurred rect 14341570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com outerClip.offset(gBlurOffsets[i]); 14441570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com 14541570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com SkRect rect = { -kHalfSquareSize, -kHalfSquareSize, kHalfSquareSize, kHalfSquareSize }; 14641570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com rect.offset(x, y); 14741570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com 14841570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com canvas->save(); 14941570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com canvas->clipRect(outerClip, SkRegion::kIntersect_Op); 15041570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com canvas->clipRect(rect, SkRegion::kDifference_Op); 15141570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com 15241570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com // move the rect to where we want the blur to appear 15341570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com rect.offset(gBlurOffsets[i]); 15441570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com // then move it outside the clip (the blur stage of the draw 15541570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com // looper will undo this translation) 15641570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com rect.offset(SkIntToScalar(kOffsetToOutsideClip), 0); 15741570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com 15841570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com canvas->drawRect(rect, loopPaint); 15941570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com canvas->restore(); 16041570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com } 16141570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com } 16241570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com 16341570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com // Create a 1-tier drawlooper 16441570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com SkLayerDrawLooper* create1Looper(SkScalar xOff, SkScalar yOff, SkColor color) { 16541570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com SkLayerDrawLooper* looper = new SkLayerDrawLooper; 16641570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com SkLayerDrawLooper::LayerInfo info; 16741570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com 16841570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com info.fFlagsMask = 0; 16941570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com info.fPaintBits = SkLayerDrawLooper::kColorFilter_Bit | 17041570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com SkLayerDrawLooper::kMaskFilter_Bit; 17141570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com info.fColorMode = SkXfermode::kSrc_Mode; 17241570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com info.fOffset.set(xOff, yOff); 17341570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com info.fPostTranslate = false; 17441570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com 17541570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com SkPaint* paint = looper->addLayer(info); 17641570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com 17741570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com paint->setMaskFilter(this->createBlur())->unref(); 17841570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com 17941570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com SkColorFilter* cf = SkColorFilter::CreateModeFilter(color, SkXfermode::kSrcIn_Mode); 18041570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com paint->setColorFilter(cf)->unref(); 18141570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com 18241570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com return looper; 18341570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com } 18441570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com 18541570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com void draw1x4(SkCanvas* canvas, SkScalar x, SkScalar y) { 18641570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com SkRect rect = { -kHalfSquareSize, -kHalfSquareSize, kHalfSquareSize, kHalfSquareSize }; 18741570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com rect.offset(x, y); 18841570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com 18941570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com SkRect outerClip = { 19041570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com -kHalfOuterClipSize-kHalfSquareSize, -kHalfOuterClipSize-kHalfSquareSize, 19141570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com kHalfOuterClipSize+kHalfSquareSize, kHalfOuterClipSize+kHalfSquareSize 19241570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com }; 19341570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com outerClip.offset(x, y); 19441570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com 19541570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com SkPaint paint; 19641570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com paint.setAntiAlias(true); 19741570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com paint.setLooper(create4Looper(-kOffsetToOutsideClip-kHalfSquareSize, 0)); 19841570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com 19941570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com canvas->save(); 20041570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com canvas->clipRect(outerClip, SkRegion::kIntersect_Op); 20141570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com canvas->clipRect(rect, SkRegion::kDifference_Op); 20241570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com 20341570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com rect.offset(SkIntToScalar(kOffsetToOutsideClip+kHalfSquareSize), 0); 20441570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com canvas->drawRect(rect, paint); 20541570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com canvas->restore(); 20641570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com } 20741570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com 20841570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com // Create a 4-tier draw looper 20941570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com SkLayerDrawLooper* create4Looper(SkScalar xOff, SkScalar yOff) { 21041570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com SkLayerDrawLooper* looper = new SkLayerDrawLooper; 21141570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com SkLayerDrawLooper::LayerInfo info; 21241570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com 21341570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com info.fFlagsMask = 0; 21441570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com info.fPaintBits = SkLayerDrawLooper::kColorFilter_Bit | 21541570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com SkLayerDrawLooper::kMaskFilter_Bit; 21641570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com info.fColorMode = SkXfermode::kSrc_Mode; 21741570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com info.fPostTranslate = false; 21841570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com 21941570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com SkPaint* paint; 22041570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com 22141570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com for (int i = 3; i >= 0; --i) { 22241570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com info.fOffset.set(xOff+gBlurOffsets[i].fX, yOff+gBlurOffsets[i].fY); 22341570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com paint = looper->addLayer(info); 22441570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com 22541570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com paint->setMaskFilter(this->createBlur())->unref(); 22641570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com 22741570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com SkColorFilter* cf = SkColorFilter::CreateModeFilter(gColors[i], SkXfermode::kSrcIn_Mode); 22841570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com paint->setColorFilter(cf)->unref(); 22941570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com } 23041570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com 23141570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com return looper; 23241570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com } 23341570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com 23441570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com typedef GM INHERITED; 23541570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com}; 23641570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com 23741570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.comconst SkPoint MegaLooperGM::gBlurOffsets[4] = { 23841570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com { kHalfSquareSize, kHalfSquareSize }, 23941570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com { -kHalfSquareSize, kHalfSquareSize }, 24041570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com { kHalfSquareSize, -kHalfSquareSize }, 24141570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com { -kHalfSquareSize, -kHalfSquareSize } 24241570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com}; 24341570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com 24441570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.comconst SkColor MegaLooperGM::gColors[4] = { 24541570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com SK_ColorGREEN, SK_ColorYELLOW, SK_ColorBLUE, SK_ColorRED 24641570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com}; 24741570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.com 24841570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.comDEF_GM( return new MegaLooperGM(MegaLooperGM::k0x0_Type); ) 24941570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.comDEF_GM( return new MegaLooperGM(MegaLooperGM::k4x1_Type); ) 25041570854703ae432c1c9bf335399727ff3eadb21robertphillips@google.comDEF_GM( return new MegaLooperGM(MegaLooperGM::k1x4_Type); ) 251