Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(785)

Side by Side Diff: gm/megalooper.cpp

Issue 16004011: Added megalooper GM (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: Cleaned up & converted to 1x4 & 4x1 (instead of 1x4 and 4x2) Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | gyp/gmslides.gypi » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
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 "gm.h"
9 #include "SkCanvas.h"
10 #include "SkBlurMaskFilter.h"
11 #include "SkLayerDrawLooper.h"
12 #include "SkColorFilter.h"
13
14 // This GM tests 3 different ways of drawing four shadows around a square:
15 // just using 4 blurred rects
16 // using 4 1-level draw loopers
17 // using 1 4-level draw looper
18 // They all produce exactly the same pixels
19 class MegaLooperGM : public skiagm::GM {
20 public:
21 // The types define "<# of loopers> x <# of stages per looper>"
22 enum Type {
23 k0x0_Type, // draw without loopers at all
24 k4x1_Type, // a looper for each shadow
25 k1x4_Type, // all four shadows in one looper
26 };
27
28 MegaLooperGM(Type type) : fType(type) {}
29
30 protected:
31 virtual SkString onShortName() {
32 switch (fType) {
33 case k0x0_Type:
34 return SkString("megalooper_0x0");
35 break;
36 case k4x1_Type:
37 return SkString("megalooper_4x1");
38 break;
39 case k1x4_Type: // fall through
40 default:
41 return SkString("megalooper_1x4");
42 break;
43 }
44 }
45
46 virtual SkISize onISize() {
47 return SkISize::Make(kWidth, kHeight);
48 }
49
50 virtual void onDraw(SkCanvas* canvas) {
51 for (int y = 100; y < kHeight; y += 200) {
52 for (int x = 100; x < kWidth; x += 200) {
53 switch (fType) {
54 case k0x0_Type:
55 draw0x0(canvas, SkIntToScalar(x), SkIntToScalar(y));
56 break;
57 case k4x1_Type:
58 draw4x1(canvas, SkIntToScalar(x), SkIntToScalar(y));
59 break;
60 case k1x4_Type: // fall through
61 default:
62 draw1x4(canvas, SkIntToScalar(x), SkIntToScalar(y));
63 break;
64 }
65 }
66 }
67 }
68
69 private:
70 static const int kWidth = 800;
71 static const int kHeight = 800;
72 static const int kHalfOuterClipSize = 100;
73 static const int kHalfSquareSize = 50;
74 static const int kOffsetToOutsideClip = kHalfSquareSize + kHalfOuterClipSize + 1;
75
76 static const SkPoint gBlurOffsets[4];
77 static const SkColor gColors[4];
78 Type fType;
79
80 // Just draw a blurred rect at each of the four corners of a square (centere d at x,y).
81 // Use two clips to define a rectori where we want pixels to appear.
82 void draw0x0(SkCanvas* canvas, SkScalar x, SkScalar y) {
83 SkRect innerClip = { -kHalfSquareSize, -kHalfSquareSize, kHalfSquareSize , kHalfSquareSize };
84 innerClip.offset(x, y);
85
86 SkRect outerClip = {
87 -kHalfOuterClipSize-kHalfSquareSize, -kHalfOuterClipSize-kHalfSquare Size,
88 kHalfOuterClipSize+kHalfSquareSize, kHalfOuterClipSize+kHalfSquare Size
89 };
90 outerClip.offset(x, y);
91
92 canvas->save();
93 canvas->clipRect(outerClip, SkRegion::kIntersect_Op);
94 canvas->clipRect(innerClip, SkRegion::kDifference_Op);
95
96 SkPaint paint;
97 paint.setAntiAlias(true);
98 paint.setMaskFilter(createBlur())->unref();
99
100 for (int i = 0; i < 4; ++i) {
101 paint.setColor(gColors[i]);
102
103 SkRect rect = { -kHalfSquareSize, -kHalfSquareSize, kHalfSquareSize, kHalfSquareSize };
104 rect.offset(gBlurOffsets[i]);
105 rect.offset(x, y);
106 canvas->drawRect(rect, paint);
107 }
108
109 canvas->restore();
110 }
111
112 SkMaskFilter* createBlur() {
113 static const SkScalar kBlurRadius = 25.0f;
114
115 return SkBlurMaskFilter::Create(kBlurRadius,
116 SkBlurMaskFilter::kNormal_BlurStyle,
117 SkBlurMaskFilter::kHighQuality_BlurFlag) ;
118 }
119
120 // This draws 4 blurred shadows around a single square (centered at x, y).
121 // Each blur is offset +/- half the square's side in x & y from the original
122 // (so each blurred rect is centered at one of the corners of the original).
123 // For each blur a large outer clip is centered around the blurred rect
124 // while a difference clip stays at the location of the original rect.
125 // Each blurred rect is drawn with a draw looper where the original (non-
126 // blurred rect) is offset to reside outside of the large outer clip (so
127 // it never appears) but the offset in the draw looper is used to translate
128 // the blurred version back into the clip.
129 void draw4x1(SkCanvas* canvas, SkScalar x, SkScalar y) {
130
131 for (int i = 0; i < 4; ++i) {
132 SkPaint loopPaint;
133
134 loopPaint.setLooper(create1Looper(-kOffsetToOutsideClip, 0, gColors[ i]));
135 loopPaint.setAntiAlias(true);
136
137 SkRect outerClip = {
138 -kHalfOuterClipSize, -kHalfOuterClipSize,
139 kHalfOuterClipSize, kHalfOuterClipSize
140 };
141 outerClip.offset(x, y);
142 // center it on the blurred rect
143 outerClip.offset(gBlurOffsets[i]);
144
145 SkRect rect = { -kHalfSquareSize, -kHalfSquareSize, kHalfSquareSize, kHalfSquareSize };
146 rect.offset(x, y);
147
148 canvas->save();
149 canvas->clipRect(outerClip, SkRegion::kIntersect_Op);
150 canvas->clipRect(rect, SkRegion::kDifference_Op);
151
152 // move the rect to where we want the blur to appear
153 rect.offset(gBlurOffsets[i]);
154 // then move it outside the clip (the blur stage of the draw
155 // looper will undo this translation)
156 rect.offset(SkIntToScalar(kOffsetToOutsideClip), 0);
157
158 canvas->drawRect(rect, loopPaint);
159 canvas->restore();
160 }
161 }
162
163 // Create a 1-tier drawlooper
164 SkLayerDrawLooper* create1Looper(SkScalar xOff, SkScalar yOff, SkColor color ) {
165 SkLayerDrawLooper* looper = new SkLayerDrawLooper;
166 SkLayerDrawLooper::LayerInfo info;
167
168 info.fFlagsMask = 0;
169 info.fPaintBits = SkLayerDrawLooper::kColorFilter_Bit |
170 SkLayerDrawLooper::kMaskFilter_Bit;
171 info.fColorMode = SkXfermode::kSrc_Mode;
172 info.fOffset.set(xOff, yOff);
173 info.fPostTranslate = false;
174
175 SkPaint* paint = looper->addLayer(info);
176
177 paint->setMaskFilter(this->createBlur())->unref();
178
179 SkColorFilter* cf = SkColorFilter::CreateModeFilter(color, SkXfermode::k SrcIn_Mode);
180 paint->setColorFilter(cf)->unref();
181
182 return looper;
183 }
184
185 void draw1x4(SkCanvas* canvas, SkScalar x, SkScalar y) {
186 SkRect rect = { -kHalfSquareSize, -kHalfSquareSize, kHalfSquareSize, kHa lfSquareSize };
187 rect.offset(x, y);
188
189 SkRect outerClip = {
190 -kHalfOuterClipSize-kHalfSquareSize, -kHalfOuterClipSize-kHalfSquare Size,
191 kHalfOuterClipSize+kHalfSquareSize, kHalfOuterClipSize+kHalfSquare Size
192 };
193 outerClip.offset(x, y);
194
195 SkPaint paint;
196 paint.setAntiAlias(true);
197 paint.setLooper(create4Looper(-kOffsetToOutsideClip-kHalfSquareSize, 0)) ;
198
199 canvas->save();
200 canvas->clipRect(outerClip, SkRegion::kIntersect_Op);
201 canvas->clipRect(rect, SkRegion::kDifference_Op);
202
203 rect.offset(SkIntToScalar(kOffsetToOutsideClip+kHalfSquareSize), 0);
204 canvas->drawRect(rect, paint);
205 canvas->restore();
206 }
207
208 // Create a 4-tier draw looper
209 SkLayerDrawLooper* create4Looper(SkScalar xOff, SkScalar yOff) {
210 SkLayerDrawLooper* looper = new SkLayerDrawLooper;
211 SkLayerDrawLooper::LayerInfo info;
212
213 info.fFlagsMask = 0;
214 info.fPaintBits = SkLayerDrawLooper::kColorFilter_Bit |
215 SkLayerDrawLooper::kMaskFilter_Bit;
216 info.fColorMode = SkXfermode::kSrc_Mode;
217 info.fPostTranslate = false;
218
219 SkPaint* paint;
220
221 for (int i = 3; i >= 0; --i) {
222 info.fOffset.set(xOff+gBlurOffsets[i].fX, yOff+gBlurOffsets[i].fY);
223 paint = looper->addLayer(info);
224
225 paint->setMaskFilter(this->createBlur())->unref();
226
227 SkColorFilter* cf = SkColorFilter::CreateModeFilter(gColors[i], SkXf ermode::kSrcIn_Mode);
228 paint->setColorFilter(cf)->unref();
229 }
230
231 return looper;
232 }
233
234 typedef GM INHERITED;
235 };
236
237 const SkPoint MegaLooperGM::gBlurOffsets[4] = {
238 { kHalfSquareSize, kHalfSquareSize },
239 { -kHalfSquareSize, kHalfSquareSize },
240 { kHalfSquareSize, -kHalfSquareSize },
241 { -kHalfSquareSize, -kHalfSquareSize }
242 };
243
244 const SkColor MegaLooperGM::gColors[4] = {
245 SK_ColorGREEN, SK_ColorYELLOW, SK_ColorBLUE, SK_ColorRED
246 };
247
248 DEF_GM( return new MegaLooperGM(MegaLooperGM::k0x0_Type); )
249 DEF_GM( return new MegaLooperGM(MegaLooperGM::k4x1_Type); )
250 DEF_GM( return new MegaLooperGM(MegaLooperGM::k1x4_Type); )
OLDNEW
« no previous file with comments | « no previous file | gyp/gmslides.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698