Chromium Code Reviews| 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 |