OLD | NEW |
---|---|
(Empty) | |
1 | |
2 /* | |
3 * Copyright 2013 Google Inc. | |
4 * | |
5 * Use of this source code is governed by a BSD-style license that can be | |
6 * found in the LICENSE file. | |
7 */ | |
8 #include "gm.h" | |
9 #include "SkBitmap.h" | |
10 #include "SkGradientShader.h" | |
11 #include "SkXfermode.h" | |
12 #include "SkColorPriv.h" | |
13 | |
14 #if SK_SUPPORT_GPU | |
15 #include "GrContext.h" | |
16 #include "SkGpuDevice.h" | |
17 #endif | |
18 | |
19 namespace skiagm { | |
20 | |
21 /** | |
22 * This tests drawing device-covering rects with solid colors and bitmap shaders over a | |
23 * checkerboard background using different xfermodes. | |
24 */ | |
25 class Xfermodes3GM : public GM { | |
26 public: | |
27 Xfermodes3GM() {} | |
28 | |
29 protected: | |
30 virtual SkString onShortName() SK_OVERRIDE { | |
31 return SkString("xfermodes3"); | |
32 } | |
33 | |
34 virtual SkISize onISize() SK_OVERRIDE { | |
35 return make_isize(630, 620); | |
36 } | |
37 | |
38 virtual void onDrawBackground(SkCanvas* canvas) SK_OVERRIDE { | |
39 SkPaint bgPaint; | |
40 bgPaint.setColor(0xFF70D0E0); | |
41 canvas->drawPaint(bgPaint); | |
42 } | |
43 | |
44 virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE { | |
45 canvas->translate(SkIntToScalar(10), SkIntToScalar(20)); | |
46 | |
47 SkPaint labelP; | |
48 labelP.setAntiAlias(true); | |
49 | |
50 static const SkColor kSolidColors[] = { | |
51 SK_ColorTRANSPARENT, | |
52 SK_ColorBLUE, | |
53 0x80808000 | |
54 }; | |
55 | |
56 static const SkColor kBmpAlphas[] = { | |
57 0xff, | |
58 0x80, | |
59 }; | |
60 | |
61 SkAutoTUnref<SkCanvas> tempCanvas(this->possiblyCreateTempCanvas(canvas, kSize, kSize)); | |
62 | |
63 int test = 0; | |
64 int x = 0, y = 0; | |
robertphillips
2013/08/07 23:16:14
++m
bsalomon
2013/08/08 21:00:37
Done.
| |
65 for (size_t m = 0; m <= SkXfermode::kLastMode; m++) { | |
66 SkXfermode::Mode mode = static_cast<SkXfermode::Mode>(m); | |
67 canvas->drawText(SkXfermode::ModeName(mode), | |
68 strlen(SkXfermode::ModeName(mode)), | |
69 SkIntToScalar(x), | |
70 SkIntToScalar(y + kSize + 3) + labelP.getTextSize() , | |
71 labelP); | |
72 for (size_t c = 0; c < SK_ARRAY_COUNT(kSolidColors); ++c) { | |
73 SkPaint modePaint; | |
74 modePaint.setXfermodeMode(mode); | |
75 modePaint.setColor(kSolidColors[c]); | |
76 | |
77 this->drawMode(canvas, x, y, kSize, kSize, modePaint, tempCanvas .get()); | |
78 | |
79 ++test; | |
80 x += kSize + 10; | |
81 if (!(test % kTestsPerRow)) { | |
82 x = 0; | |
83 y += kSize + 30; | |
84 } | |
85 } | |
86 for (size_t a = 0; a < SK_ARRAY_COUNT(kBmpAlphas); ++a) { | |
87 SkPaint modePaint; | |
88 modePaint.setXfermodeMode(mode); | |
89 modePaint.setAlpha(kBmpAlphas[a]); | |
90 modePaint.setShader(fBmpShader); | |
91 | |
92 this->drawMode(canvas, x, y, kSize, kSize, modePaint, tempCanvas .get()); | |
93 | |
94 ++test; | |
95 x += kSize + 10; | |
96 if (!(test % kTestsPerRow)) { | |
97 x = 0; | |
98 y += kSize + 30; | |
99 } | |
100 } | |
101 } | |
102 } | |
103 | |
104 private: | |
105 /** | |
106 * GrContext has optimizations around full rendertarget draws that can be re placed with clears. | |
107 * We are trying to test those. We could use saveLayer() to create small SkG puDevices but | |
108 * saveLayer() uses the texture cache. This means that the actual render tar get may be larger | |
109 * than the layer. Because the clip will contain the layer's bounds, no draw s will be full-RT. | |
110 * So when running on a GPU canvas we explicitly create a temporary canvas u sing a texture with | |
111 * dimensions exactly matching the layer size. | |
112 */ | |
113 SkCanvas* possiblyCreateTempCanvas(SkCanvas* baseCanvas, int w, int h) { | |
114 SkCanvas* tempCanvas = NULL; | |
115 #if SK_SUPPORT_GPU | |
116 GrRenderTarget* rt = baseCanvas->getDevice()->accessRenderTarget(); | |
117 if (NULL != rt) { | |
118 GrContext* context = rt->getContext(); | |
119 GrTextureDesc desc; | |
120 desc.fWidth = w; | |
121 desc.fHeight = h; | |
122 desc.fConfig = rt->config(); | |
123 desc.fFlags = kRenderTarget_GrTextureFlagBit; | |
124 SkAutoTUnref<GrSurface> surface(context->createUncachedTexture(desc, NULL, 0)); | |
125 SkAutoTUnref<SkDevice> device(SkGpuDevice::Create(surface.get())); | |
126 if (NULL != device.get()) { | |
127 tempCanvas = SkNEW_ARGS(SkCanvas, (device.get())); | |
128 } | |
129 } | |
130 #endif | |
131 return tempCanvas; | |
132 } | |
133 | |
134 void drawMode(SkCanvas* canvas, | |
135 int x, int y, int w, int h, | |
robertphillips
2013/08/07 23:16:14
const SkPaint& ?
bsalomon
2013/08/08 21:00:37
Done.
| |
136 SkPaint& modePaint, SkCanvas* layerCanvas) { | |
137 canvas->save(); | |
138 | |
139 canvas->translate(SkIntToScalar(x), SkIntToScalar(y)); | |
140 | |
141 SkRect r = SkRect::MakeWH(SkIntToScalar(w), SkIntToScalar(h)); | |
142 | |
143 SkCanvas* modeCanvas; | |
144 if (NULL == layerCanvas) { | |
145 canvas->saveLayer(&r, NULL, SkCanvas::kARGB_ClipLayer_SaveFlag); | |
146 modeCanvas = canvas; | |
147 } else { | |
148 modeCanvas = layerCanvas; | |
149 } | |
150 | |
151 SkPaint bgPaint; | |
152 bgPaint.setAntiAlias(false); | |
153 bgPaint.setShader(fBG); | |
154 modeCanvas->drawRect(r, bgPaint); | |
155 modeCanvas->drawRect(r, modePaint); | |
156 modeCanvas = NULL; | |
157 | |
158 if (NULL == layerCanvas) { | |
159 canvas->restore(); | |
160 } else { | |
161 SkBitmap bitmap = layerCanvas->getDevice()->accessBitmap(false); | |
162 canvas->drawBitmap(bitmap, 0, 0); | |
163 } | |
164 | |
165 r.inset(-SK_ScalarHalf, -SK_ScalarHalf); | |
166 SkPaint borderPaint; | |
167 borderPaint.setStyle(SkPaint::kStroke_Style); | |
168 canvas->drawRect(r, borderPaint); | |
169 | |
170 canvas->restore(); | |
171 } | |
172 | |
173 virtual void onOnceBeforeDraw() SK_OVERRIDE { | |
174 static const uint32_t kCheckData[] = { | |
175 SkPackARGB32(0xFF, 0x40, 0x40, 0x40), | |
176 SkPackARGB32(0xFF, 0xD0, 0xD0, 0xD0), | |
177 SkPackARGB32(0xFF, 0xD0, 0xD0, 0xD0), | |
178 SkPackARGB32(0xFF, 0x40, 0x40, 0x40) | |
179 }; | |
180 SkBitmap bg; | |
181 bg.setConfig(SkBitmap::kARGB_8888_Config, 2, 2); | |
182 bg.allocPixels(); | |
183 SkAutoLockPixels bgAlp(bg); | |
184 memcpy(bg.getPixels(), kCheckData, sizeof(kCheckData)); | |
185 bg.setIsOpaque(true); | |
186 | |
187 fBG.reset(SkShader::CreateBitmapShader(bg, | |
188 SkShader::kRepeat_TileMode, | |
189 SkShader::kRepeat_TileMode)); | |
190 SkMatrix lm; | |
191 lm.setScale(SkIntToScalar(kCheckSize), SkIntToScalar(kCheckSize)); | |
192 fBG->setLocalMatrix(lm); | |
193 | |
194 SkBitmap bmp; | |
195 bmp.setConfig(SkBitmap::kARGB_8888_Config, kSize, kSize); | |
196 bmp.allocPixels(); | |
197 | |
198 SkPaint bmpPaint; | |
199 static const SkPoint kCenter = { SkIntToScalar(kSize) / 2, SkIntToScalar (kSize) / 2 }; | |
200 static const SkColor kColors[] = { SK_ColorTRANSPARENT, 0x80800000, | |
201 0xF020F060, SK_ColorWHITE }; | |
202 bmpPaint.setShader(SkGradientShader::CreateRadial(kCenter, | |
203 3 * SkIntToScalar(kSiz e) / 4, | |
204 kColors, | |
205 NULL, | |
206 SK_ARRAY_COUNT(kColors ), | |
207 SkShader::kRepeat_Tile Mode))->unref(); | |
robertphillips
2013/08/07 23:16:14
Move creation & alloc of bmp to right before use i
bsalomon
2013/08/08 21:00:37
Done.
| |
208 SkCanvas bmpCanvas(bmp); | |
209 bmpCanvas.clear(SK_ColorTRANSPARENT); | |
210 SkRect rect = { SkIntToScalar(kSize) / 8, SkIntToScalar(kSize) / 8, | |
211 7 * SkIntToScalar(kSize) / 8, 7 * SkIntToScalar(kSize) / 8}; | |
212 bmpCanvas.drawRect(rect, bmpPaint); | |
213 | |
robertphillips
2013/08/07 23:16:14
Is there a better name then fBmpShader? fGradShade
bsalomon
2013/08/08 21:00:37
It is a bmp shader. I'm testing drawing a screen f
| |
214 fBmpShader.reset(SkShader::CreateBitmapShader(bmp, | |
215 SkShader::kClamp_TileMode, | |
216 SkShader::kClamp_TileMode) ); | |
217 } | |
218 | |
219 enum { | |
220 kCheckSize = 8, | |
221 kSize = 30, | |
222 kTestsPerRow = 15, | |
223 }; | |
224 | |
robertphillips
2013/08/07 23:16:14
fBGShader?
bsalomon
2013/08/08 21:00:37
Done.
| |
225 SkAutoTUnref<SkShader> fBG; | |
226 SkAutoTUnref<SkShader> fBmpShader; | |
227 | |
228 typedef GM INHERITED; | |
229 }; | |
230 | |
231 ////////////////////////////////////////////////////////////////////////////// | |
232 | |
robertphillips
2013/08/07 23:16:14
DEF_GM?
| |
233 static GM* MyFactory(void*) { return new Xfermodes3GM; } | |
234 static GMRegistry reg(MyFactory); | |
235 | |
236 } | |
OLD | NEW |