blob: 86aee1710c1c3333bc94944c5711ae3454cbbfbf [file] [log] [blame]
commit-bot@chromium.org103f2d02013-08-08 21:13:38 +00001/*
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 */
reed48eb08a2015-12-25 12:56:03 -08007
commit-bot@chromium.org103f2d02013-08-08 21:13:38 +00008#include "gm.h"
Mike Klein33d20552017-03-22 13:47:51 -04009#include "sk_tool_utils.h"
commit-bot@chromium.org103f2d02013-08-08 21:13:38 +000010#include "SkBitmap.h"
11#include "SkGradientShader.h"
reed48eb08a2015-12-25 12:56:03 -080012#include "SkSurface.h"
Mike Reedd4706732016-11-15 16:44:34 -050013#include "SkBlendModePriv.h"
commit-bot@chromium.org103f2d02013-08-08 21:13:38 +000014#include "SkColorPriv.h"
Mike Reed331ccfd2018-10-25 12:36:06 -040015#include "SkTextUtils.h"
commit-bot@chromium.org103f2d02013-08-08 21:13:38 +000016#include "GrContext.h"
commit-bot@chromium.org103f2d02013-08-08 21:13:38 +000017
18namespace skiagm {
19
20/**
21 * This tests drawing device-covering rects with solid colors and bitmap shaders over a
22 * checkerboard background using different xfermodes.
23 */
24class Xfermodes3GM : public GM {
25public:
Chris Dalton21ca3702019-02-01 12:15:42 -070026 Xfermodes3GM() { this->setBGColor(sk_tool_utils::color_to_565(0xFF70D0E0)); }
commit-bot@chromium.org103f2d02013-08-08 21:13:38 +000027
28protected:
mtklein36352bf2015-03-25 18:17:31 -070029 SkString onShortName() override {
commit-bot@chromium.org103f2d02013-08-08 21:13:38 +000030 return SkString("xfermodes3");
31 }
32
mtklein36352bf2015-03-25 18:17:31 -070033 SkISize onISize() override {
tfarinaf5393182014-06-09 23:59:03 -070034 return SkISize::Make(630, 1215);
commit-bot@chromium.org103f2d02013-08-08 21:13:38 +000035 }
36
mtklein36352bf2015-03-25 18:17:31 -070037 void onDraw(SkCanvas* canvas) override {
commit-bot@chromium.org103f2d02013-08-08 21:13:38 +000038 canvas->translate(SkIntToScalar(10), SkIntToScalar(20));
39
Hal Canarydf2d27e2019-01-08 09:38:02 -050040 SkFont font(sk_tool_utils::create_portable_typeface());
commit-bot@chromium.org103f2d02013-08-08 21:13:38 +000041 SkPaint labelP;
commit-bot@chromium.org103f2d02013-08-08 21:13:38 +000042
mtkleindbfd7ab2016-09-01 11:24:54 -070043 constexpr SkColor kSolidColors[] = {
commit-bot@chromium.org103f2d02013-08-08 21:13:38 +000044 SK_ColorTRANSPARENT,
45 SK_ColorBLUE,
46 0x80808000
47 };
48
mtkleindbfd7ab2016-09-01 11:24:54 -070049 constexpr SkColor kBmpAlphas[] = {
commit-bot@chromium.org103f2d02013-08-08 21:13:38 +000050 0xff,
51 0x80,
52 };
53
Ben Wagnerd3c84ff2018-04-25 14:38:24 -040054 auto tempSurface(this->makeTempSurface(canvas, kSize, kSize));
commit-bot@chromium.org103f2d02013-08-08 21:13:38 +000055
56 int test = 0;
57 int x = 0, y = 0;
mtkleindbfd7ab2016-09-01 11:24:54 -070058 constexpr struct { SkPaint::Style fStyle; SkScalar fWidth; } kStrokes[] = {
commit-bot@chromium.orgde1559c2013-08-14 19:20:45 +000059 {SkPaint::kFill_Style, 0},
60 {SkPaint::kStroke_Style, SkIntToScalar(kSize) / 2},
61 };
62 for (size_t s = 0; s < SK_ARRAY_COUNT(kStrokes); ++s) {
Mike Reedd4706732016-11-15 16:44:34 -050063 for (size_t m = 0; m <= (size_t)SkBlendMode::kLastMode; ++m) {
reed374772b2016-10-05 17:33:02 -070064 SkBlendMode mode = static_cast<SkBlendMode>(m);
Cary Clark2a475ea2017-04-28 15:35:12 -040065 canvas->drawString(SkBlendMode_Name(mode),
Hal Canarydf2d27e2019-01-08 09:38:02 -050066 SkIntToScalar(x),
67 SkIntToScalar(y + kSize + 3) + font.getSize(),
68 font, labelP);
commit-bot@chromium.orgde1559c2013-08-14 19:20:45 +000069 for (size_t c = 0; c < SK_ARRAY_COUNT(kSolidColors); ++c) {
70 SkPaint modePaint;
reed374772b2016-10-05 17:33:02 -070071 modePaint.setBlendMode(mode);
commit-bot@chromium.orgde1559c2013-08-14 19:20:45 +000072 modePaint.setColor(kSolidColors[c]);
73 modePaint.setStyle(kStrokes[s].fStyle);
74 modePaint.setStrokeWidth(kStrokes[s].fWidth);
commit-bot@chromium.org103f2d02013-08-08 21:13:38 +000075
reede8f30622016-03-23 18:59:25 -070076 this->drawMode(canvas, x, y, kSize, kSize, modePaint, tempSurface.get());
commit-bot@chromium.org103f2d02013-08-08 21:13:38 +000077
commit-bot@chromium.orgde1559c2013-08-14 19:20:45 +000078 ++test;
79 x += kSize + 10;
80 if (!(test % kTestsPerRow)) {
81 x = 0;
82 y += kSize + 30;
83 }
commit-bot@chromium.org103f2d02013-08-08 21:13:38 +000084 }
commit-bot@chromium.orgde1559c2013-08-14 19:20:45 +000085 for (size_t a = 0; a < SK_ARRAY_COUNT(kBmpAlphas); ++a) {
86 SkPaint modePaint;
reed374772b2016-10-05 17:33:02 -070087 modePaint.setBlendMode(mode);
commit-bot@chromium.orgde1559c2013-08-14 19:20:45 +000088 modePaint.setAlpha(kBmpAlphas[a]);
89 modePaint.setShader(fBmpShader);
90 modePaint.setStyle(kStrokes[s].fStyle);
91 modePaint.setStrokeWidth(kStrokes[s].fWidth);
commit-bot@chromium.org103f2d02013-08-08 21:13:38 +000092
reede8f30622016-03-23 18:59:25 -070093 this->drawMode(canvas, x, y, kSize, kSize, modePaint, tempSurface.get());
commit-bot@chromium.org103f2d02013-08-08 21:13:38 +000094
commit-bot@chromium.orgde1559c2013-08-14 19:20:45 +000095 ++test;
96 x += kSize + 10;
97 if (!(test % kTestsPerRow)) {
98 x = 0;
99 y += kSize + 30;
100 }
commit-bot@chromium.org103f2d02013-08-08 21:13:38 +0000101 }
102 }
103 }
104 }
105
106private:
107 /**
108 * GrContext has optimizations around full rendertarget draws that can be replaced with clears.
109 * We are trying to test those. We could use saveLayer() to create small SkGpuDevices but
110 * saveLayer() uses the texture cache. This means that the actual render target may be larger
111 * than the layer. Because the clip will contain the layer's bounds, no draws will be full-RT.
Ben Wagnerd3c84ff2018-04-25 14:38:24 -0400112 * So explicitly create a temporary canvas with dimensions exactly the layer size.
commit-bot@chromium.org103f2d02013-08-08 21:13:38 +0000113 */
Ben Wagnerd3c84ff2018-04-25 14:38:24 -0400114 sk_sp<SkSurface> makeTempSurface(SkCanvas* baseCanvas, int w, int h) {
bsalomonafe30052015-01-16 07:32:33 -0800115 SkImageInfo baseInfo = baseCanvas->imageInfo();
116 SkImageInfo info = SkImageInfo::Make(w, h, baseInfo.colorType(), baseInfo.alphaType(),
Mike Reed693fdbd2017-01-12 10:13:40 -0500117 baseInfo.refColorSpace());
Ben Wagnerd3c84ff2018-04-25 14:38:24 -0400118 return baseCanvas->makeSurface(info);
commit-bot@chromium.org103f2d02013-08-08 21:13:38 +0000119 }
120
121 void drawMode(SkCanvas* canvas,
122 int x, int y, int w, int h,
reed48eb08a2015-12-25 12:56:03 -0800123 const SkPaint& modePaint, SkSurface* surface) {
commit-bot@chromium.org103f2d02013-08-08 21:13:38 +0000124 canvas->save();
commit-bot@chromium.org103f2d02013-08-08 21:13:38 +0000125 canvas->translate(SkIntToScalar(x), SkIntToScalar(y));
126
127 SkRect r = SkRect::MakeWH(SkIntToScalar(w), SkIntToScalar(h));
128
129 SkCanvas* modeCanvas;
reed48eb08a2015-12-25 12:56:03 -0800130 if (nullptr == surface) {
halcanary96fcdcc2015-08-27 07:41:13 -0700131 canvas->saveLayer(&r, nullptr);
Ben Wagnerd3c84ff2018-04-25 14:38:24 -0400132 canvas->clipRect(r);
commit-bot@chromium.org103f2d02013-08-08 21:13:38 +0000133 modeCanvas = canvas;
134 } else {
reed48eb08a2015-12-25 12:56:03 -0800135 modeCanvas = surface->getCanvas();
commit-bot@chromium.org103f2d02013-08-08 21:13:38 +0000136 }
137
138 SkPaint bgPaint;
139 bgPaint.setAntiAlias(false);
140 bgPaint.setShader(fBGShader);
141 modeCanvas->drawRect(r, bgPaint);
142 modeCanvas->drawRect(r, modePaint);
halcanary96fcdcc2015-08-27 07:41:13 -0700143 modeCanvas = nullptr;
commit-bot@chromium.org103f2d02013-08-08 21:13:38 +0000144
reed48eb08a2015-12-25 12:56:03 -0800145 if (nullptr == surface) {
commit-bot@chromium.org103f2d02013-08-08 21:13:38 +0000146 canvas->restore();
147 } else {
reed48eb08a2015-12-25 12:56:03 -0800148 surface->draw(canvas, 0, 0, nullptr);
commit-bot@chromium.org103f2d02013-08-08 21:13:38 +0000149 }
150
151 r.inset(-SK_ScalarHalf, -SK_ScalarHalf);
152 SkPaint borderPaint;
153 borderPaint.setStyle(SkPaint::kStroke_Style);
154 canvas->drawRect(r, borderPaint);
155
156 canvas->restore();
157 }
158
mtklein36352bf2015-03-25 18:17:31 -0700159 void onOnceBeforeDraw() override {
mtkleindbfd7ab2016-09-01 11:24:54 -0700160 const uint32_t kCheckData[] = {
caryclark4ec1ac62015-07-21 07:42:45 -0700161 SkPackARGB32(0xFF, 0x42, 0x41, 0x42),
162 SkPackARGB32(0xFF, 0xD6, 0xD3, 0xD6),
163 SkPackARGB32(0xFF, 0xD6, 0xD3, 0xD6),
164 SkPackARGB32(0xFF, 0x42, 0x41, 0x42)
commit-bot@chromium.org103f2d02013-08-08 21:13:38 +0000165 };
166 SkBitmap bg;
reed@google.comeb9a46c2014-01-25 16:46:20 +0000167 bg.allocN32Pixels(2, 2, true);
commit-bot@chromium.org103f2d02013-08-08 21:13:38 +0000168 memcpy(bg.getPixels(), kCheckData, sizeof(kCheckData));
commit-bot@chromium.org103f2d02013-08-08 21:13:38 +0000169
commit-bot@chromium.org103f2d02013-08-08 21:13:38 +0000170 SkMatrix lm;
171 lm.setScale(SkIntToScalar(kCheckSize), SkIntToScalar(kCheckSize));
reed1a9b9642016-03-13 14:13:58 -0700172 fBGShader = SkShader::MakeBitmapShader(bg, SkShader::kRepeat_TileMode,
173 SkShader::kRepeat_TileMode, &lm);
commit-bot@chromium.org103f2d02013-08-08 21:13:38 +0000174
175 SkPaint bmpPaint;
reed1a9b9642016-03-13 14:13:58 -0700176 const SkPoint kCenter = { SkIntToScalar(kSize) / 2, SkIntToScalar(kSize) / 2 };
177 const SkColor kColors[] = {
178 SK_ColorTRANSPARENT, 0x80800000, 0xF020F060, SK_ColorWHITE
179 };
180 bmpPaint.setShader(SkGradientShader::MakeRadial(kCenter, 3 * SkIntToScalar(kSize) / 4,
181 kColors, nullptr, SK_ARRAY_COUNT(kColors),
182 SkShader::kRepeat_TileMode));
commit-bot@chromium.org103f2d02013-08-08 21:13:38 +0000183
184 SkBitmap bmp;
reed@google.comeb9a46c2014-01-25 16:46:20 +0000185 bmp.allocN32Pixels(kSize, kSize);
commit-bot@chromium.org103f2d02013-08-08 21:13:38 +0000186 SkCanvas bmpCanvas(bmp);
187
188 bmpCanvas.clear(SK_ColorTRANSPARENT);
189 SkRect rect = { SkIntToScalar(kSize) / 8, SkIntToScalar(kSize) / 8,
190 7 * SkIntToScalar(kSize) / 8, 7 * SkIntToScalar(kSize) / 8};
191 bmpCanvas.drawRect(rect, bmpPaint);
192
reed1a9b9642016-03-13 14:13:58 -0700193 fBmpShader = SkShader::MakeBitmapShader(bmp, SkShader::kClamp_TileMode,
194 SkShader::kClamp_TileMode);
commit-bot@chromium.org103f2d02013-08-08 21:13:38 +0000195 }
196
197 enum {
198 kCheckSize = 8,
199 kSize = 30,
200 kTestsPerRow = 15,
201 };
202
reed1a9b9642016-03-13 14:13:58 -0700203 sk_sp<SkShader> fBGShader;
204 sk_sp<SkShader> fBmpShader;
commit-bot@chromium.org103f2d02013-08-08 21:13:38 +0000205
206 typedef GM INHERITED;
207};
208
209//////////////////////////////////////////////////////////////////////////////
210
211DEF_GM(return new Xfermodes3GM;)
212
213}