xref: /aosp_15_r20/external/skia/gm/graphitestart.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker  * Copyright 2021 Google LLC
3*c8dee2aaSAndroid Build Coastguard Worker  *
4*c8dee2aaSAndroid Build Coastguard Worker  * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker  * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker  */
7*c8dee2aaSAndroid Build Coastguard Worker 
8*c8dee2aaSAndroid Build Coastguard Worker #include "gm/gm.h"
9*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkBitmap.h"
10*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkCanvas.h"
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkColorFilter.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkColorSpace.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkImage.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPaint.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPath.h"
16*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRRect.h"
17*c8dee2aaSAndroid Build Coastguard Worker #include "include/effects/SkGradientShader.h"
18*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/GrRecordingContext.h"
19*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkColorFilterPriv.h"
20*c8dee2aaSAndroid Build Coastguard Worker #include "tools/DecodeUtils.h"
21*c8dee2aaSAndroid Build Coastguard Worker #include "tools/GpuToolUtils.h"
22*c8dee2aaSAndroid Build Coastguard Worker #include "tools/Resources.h"
23*c8dee2aaSAndroid Build Coastguard Worker #include "tools/ToolUtils.h"
24*c8dee2aaSAndroid Build Coastguard Worker 
25*c8dee2aaSAndroid Build Coastguard Worker namespace {
26*c8dee2aaSAndroid Build Coastguard Worker 
create_gradient_shader(SkRect r,const std::array<SkColor,3> & colors,const std::array<float,3> & offsets)27*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkShader> create_gradient_shader(SkRect r,
28*c8dee2aaSAndroid Build Coastguard Worker                                        const std::array<SkColor, 3>& colors,
29*c8dee2aaSAndroid Build Coastguard Worker                                        const std::array<float, 3>& offsets) {
30*c8dee2aaSAndroid Build Coastguard Worker     SkPoint pts[2] = { {r.fLeft, r.fTop}, {r.fRight, r.fTop} };
31*c8dee2aaSAndroid Build Coastguard Worker 
32*c8dee2aaSAndroid Build Coastguard Worker     return SkGradientShader::MakeLinear(pts, colors.data(), offsets.data(), std::size(colors),
33*c8dee2aaSAndroid Build Coastguard Worker                                         SkTileMode::kClamp);
34*c8dee2aaSAndroid Build Coastguard Worker }
35*c8dee2aaSAndroid Build Coastguard Worker 
create_image_shader(SkCanvas * destCanvas,SkTileMode tmX,SkTileMode tmY)36*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkShader> create_image_shader(SkCanvas* destCanvas, SkTileMode tmX, SkTileMode tmY) {
37*c8dee2aaSAndroid Build Coastguard Worker     SkBitmap bitmap;
38*c8dee2aaSAndroid Build Coastguard Worker 
39*c8dee2aaSAndroid Build Coastguard Worker     {
40*c8dee2aaSAndroid Build Coastguard Worker         SkImageInfo ii = SkImageInfo::Make(64, 64, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
41*c8dee2aaSAndroid Build Coastguard Worker         bitmap.allocPixels(ii);
42*c8dee2aaSAndroid Build Coastguard Worker         bitmap.eraseColor(SK_ColorWHITE);
43*c8dee2aaSAndroid Build Coastguard Worker 
44*c8dee2aaSAndroid Build Coastguard Worker         SkCanvas tmpCanvas(bitmap);
45*c8dee2aaSAndroid Build Coastguard Worker 
46*c8dee2aaSAndroid Build Coastguard Worker         SkColor colors[3][3] = {
47*c8dee2aaSAndroid Build Coastguard Worker                 { SK_ColorRED,    SK_ColorDKGRAY, SK_ColorBLUE },
48*c8dee2aaSAndroid Build Coastguard Worker                 { SK_ColorLTGRAY, SK_ColorCYAN,   SK_ColorYELLOW },
49*c8dee2aaSAndroid Build Coastguard Worker                 { SK_ColorGREEN,  SK_ColorWHITE,  SK_ColorMAGENTA }
50*c8dee2aaSAndroid Build Coastguard Worker         };
51*c8dee2aaSAndroid Build Coastguard Worker 
52*c8dee2aaSAndroid Build Coastguard Worker         for (int y = 0; y < 3; ++y) {
53*c8dee2aaSAndroid Build Coastguard Worker             for (int x = 0; x < 3; ++x) {
54*c8dee2aaSAndroid Build Coastguard Worker                 SkPaint paint;
55*c8dee2aaSAndroid Build Coastguard Worker                 paint.setColor(colors[y][x]);
56*c8dee2aaSAndroid Build Coastguard Worker                 tmpCanvas.drawRect(SkRect::MakeXYWH(x*21, y*21, 22, 22), paint);
57*c8dee2aaSAndroid Build Coastguard Worker             }
58*c8dee2aaSAndroid Build Coastguard Worker         }
59*c8dee2aaSAndroid Build Coastguard Worker 
60*c8dee2aaSAndroid Build Coastguard Worker         bitmap.setAlphaType(kOpaque_SkAlphaType);
61*c8dee2aaSAndroid Build Coastguard Worker         bitmap.setImmutable();
62*c8dee2aaSAndroid Build Coastguard Worker     }
63*c8dee2aaSAndroid Build Coastguard Worker 
64*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkImage> img = SkImages::RasterFromBitmap(bitmap);
65*c8dee2aaSAndroid Build Coastguard Worker     img = ToolUtils::MakeTextureImage(destCanvas, std::move(img));
66*c8dee2aaSAndroid Build Coastguard Worker     if (img) {
67*c8dee2aaSAndroid Build Coastguard Worker         return img->makeShader(tmX, tmY, SkSamplingOptions());
68*c8dee2aaSAndroid Build Coastguard Worker     } else {
69*c8dee2aaSAndroid Build Coastguard Worker         return nullptr;
70*c8dee2aaSAndroid Build Coastguard Worker     }
71*c8dee2aaSAndroid Build Coastguard Worker }
72*c8dee2aaSAndroid Build Coastguard Worker 
create_blend_shader(SkCanvas * destCanvas,SkBlendMode bm)73*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkShader> create_blend_shader(SkCanvas* destCanvas, SkBlendMode bm) {
74*c8dee2aaSAndroid Build Coastguard Worker     constexpr SkColor4f kTransYellow = {1.0f, 1.0f, 0.0f, 0.5f};
75*c8dee2aaSAndroid Build Coastguard Worker 
76*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkShader> dst = SkShaders::Color(kTransYellow, nullptr);
77*c8dee2aaSAndroid Build Coastguard Worker     return SkShaders::Blend(bm,
78*c8dee2aaSAndroid Build Coastguard Worker                             std::move(dst),
79*c8dee2aaSAndroid Build Coastguard Worker                             create_image_shader(destCanvas,
80*c8dee2aaSAndroid Build Coastguard Worker                                                 SkTileMode::kRepeat, SkTileMode::kRepeat));
81*c8dee2aaSAndroid Build Coastguard Worker }
82*c8dee2aaSAndroid Build Coastguard Worker 
create_grayscale_colorfilter()83*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkColorFilter> create_grayscale_colorfilter() {
84*c8dee2aaSAndroid Build Coastguard Worker     float matrix[20] = {};
85*c8dee2aaSAndroid Build Coastguard Worker     matrix[0] = matrix[5] = matrix[10] = 0.2126f;
86*c8dee2aaSAndroid Build Coastguard Worker     matrix[1] = matrix[6] = matrix[11] = 0.7152f;
87*c8dee2aaSAndroid Build Coastguard Worker     matrix[2] = matrix[7] = matrix[12] = 0.0722f;
88*c8dee2aaSAndroid Build Coastguard Worker     matrix[18] = 1.0f;
89*c8dee2aaSAndroid Build Coastguard Worker     return SkColorFilters::Matrix(matrix);
90*c8dee2aaSAndroid Build Coastguard Worker }
91*c8dee2aaSAndroid Build Coastguard Worker 
draw_image_shader_tile(SkCanvas * canvas,SkRect clipRect)92*c8dee2aaSAndroid Build Coastguard Worker void draw_image_shader_tile(SkCanvas* canvas, SkRect clipRect) {
93*c8dee2aaSAndroid Build Coastguard Worker     SkPaint p;
94*c8dee2aaSAndroid Build Coastguard Worker     p.setShader(create_image_shader(canvas, SkTileMode::kClamp, SkTileMode::kRepeat));
95*c8dee2aaSAndroid Build Coastguard Worker 
96*c8dee2aaSAndroid Build Coastguard Worker     SkPath path;
97*c8dee2aaSAndroid Build Coastguard Worker     path.moveTo(1,   1);
98*c8dee2aaSAndroid Build Coastguard Worker     path.lineTo(32,  127);
99*c8dee2aaSAndroid Build Coastguard Worker     path.lineTo(96,  127);
100*c8dee2aaSAndroid Build Coastguard Worker     path.lineTo(127, 1);
101*c8dee2aaSAndroid Build Coastguard Worker     path.lineTo(63,  32);
102*c8dee2aaSAndroid Build Coastguard Worker     path.close();
103*c8dee2aaSAndroid Build Coastguard Worker 
104*c8dee2aaSAndroid Build Coastguard Worker     canvas->save();
105*c8dee2aaSAndroid Build Coastguard Worker         canvas->clipRect(clipRect);
106*c8dee2aaSAndroid Build Coastguard Worker         canvas->scale(0.5f, 0.5f);
107*c8dee2aaSAndroid Build Coastguard Worker         canvas->drawPath(path, p);
108*c8dee2aaSAndroid Build Coastguard Worker 
109*c8dee2aaSAndroid Build Coastguard Worker         canvas->save();
110*c8dee2aaSAndroid Build Coastguard Worker             canvas->concat(SkMatrix::RotateDeg(90, {64, 64}));
111*c8dee2aaSAndroid Build Coastguard Worker             canvas->translate(128, 0);
112*c8dee2aaSAndroid Build Coastguard Worker             canvas->drawPath(path, p);
113*c8dee2aaSAndroid Build Coastguard Worker         canvas->restore();
114*c8dee2aaSAndroid Build Coastguard Worker     canvas->restore();
115*c8dee2aaSAndroid Build Coastguard Worker }
116*c8dee2aaSAndroid Build Coastguard Worker 
draw_gradient_tile(SkCanvas * canvas,SkRect clipRect)117*c8dee2aaSAndroid Build Coastguard Worker void draw_gradient_tile(SkCanvas* canvas, SkRect clipRect) {
118*c8dee2aaSAndroid Build Coastguard Worker     SkRect r{1, 1, 127, 127};
119*c8dee2aaSAndroid Build Coastguard Worker     SkPaint p;
120*c8dee2aaSAndroid Build Coastguard Worker     p.setShader(create_gradient_shader(r,
121*c8dee2aaSAndroid Build Coastguard Worker                                        { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE },
122*c8dee2aaSAndroid Build Coastguard Worker                                        { 0.0f, 0.75f, 1.0f }));
123*c8dee2aaSAndroid Build Coastguard Worker 
124*c8dee2aaSAndroid Build Coastguard Worker     canvas->save();
125*c8dee2aaSAndroid Build Coastguard Worker         canvas->clipRect(clipRect);
126*c8dee2aaSAndroid Build Coastguard Worker         canvas->translate(128, 0);
127*c8dee2aaSAndroid Build Coastguard Worker         canvas->scale(0.5f, 0.5f);
128*c8dee2aaSAndroid Build Coastguard Worker         canvas->drawRect(r, p);
129*c8dee2aaSAndroid Build Coastguard Worker 
130*c8dee2aaSAndroid Build Coastguard Worker         canvas->save();
131*c8dee2aaSAndroid Build Coastguard Worker             canvas->concat(SkMatrix::RotateDeg(90, {64, 64}));
132*c8dee2aaSAndroid Build Coastguard Worker             canvas->translate(128, 0);
133*c8dee2aaSAndroid Build Coastguard Worker             canvas->drawRect(r, p);
134*c8dee2aaSAndroid Build Coastguard Worker         canvas->restore();
135*c8dee2aaSAndroid Build Coastguard Worker     canvas->restore();
136*c8dee2aaSAndroid Build Coastguard Worker }
137*c8dee2aaSAndroid Build Coastguard Worker 
draw_colorfilter_swatches(SkCanvas * canvas,SkRect clipRect)138*c8dee2aaSAndroid Build Coastguard Worker void draw_colorfilter_swatches(SkCanvas* canvas, SkRect clipRect) {
139*c8dee2aaSAndroid Build Coastguard Worker     static constexpr int kNumTilesPerSide = 3;
140*c8dee2aaSAndroid Build Coastguard Worker 
141*c8dee2aaSAndroid Build Coastguard Worker     SkSize tileSize = { clipRect.width() / kNumTilesPerSide, clipRect.height() / kNumTilesPerSide };
142*c8dee2aaSAndroid Build Coastguard Worker 
143*c8dee2aaSAndroid Build Coastguard Worker     // Quantize to four colors
144*c8dee2aaSAndroid Build Coastguard Worker     uint8_t table1[256];
145*c8dee2aaSAndroid Build Coastguard Worker     for (int i = 0; i < 256; ++i) {
146*c8dee2aaSAndroid Build Coastguard Worker         table1[i] = (i/64) * 85;
147*c8dee2aaSAndroid Build Coastguard Worker     }
148*c8dee2aaSAndroid Build Coastguard Worker 
149*c8dee2aaSAndroid Build Coastguard Worker     // table2 is a band-pass filter for 85-170.
150*c8dee2aaSAndroid Build Coastguard Worker     // table3 re-expands that range to 0..255
151*c8dee2aaSAndroid Build Coastguard Worker     uint8_t table2[256], table3[256];
152*c8dee2aaSAndroid Build Coastguard Worker     for (int i = 0; i < 256; ++i) {
153*c8dee2aaSAndroid Build Coastguard Worker         if (i >= 85 && i <= 170) {
154*c8dee2aaSAndroid Build Coastguard Worker             table2[i] = i;
155*c8dee2aaSAndroid Build Coastguard Worker             table3[i] = ((i - 85) / 85.0f) * 255.0f;
156*c8dee2aaSAndroid Build Coastguard Worker         } else {
157*c8dee2aaSAndroid Build Coastguard Worker             table2[i] = 0;
158*c8dee2aaSAndroid Build Coastguard Worker             table3[i] = 0;
159*c8dee2aaSAndroid Build Coastguard Worker         }
160*c8dee2aaSAndroid Build Coastguard Worker     }
161*c8dee2aaSAndroid Build Coastguard Worker 
162*c8dee2aaSAndroid Build Coastguard Worker     constexpr SkColor SK_ColorGREY = SkColorSetARGB(0xFF, 0x80, 0x80, 0x80);
163*c8dee2aaSAndroid Build Coastguard Worker 
164*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkColorFilter> colorFilters[kNumTilesPerSide*kNumTilesPerSide];
165*c8dee2aaSAndroid Build Coastguard Worker     static const std::array<SkColor, 3> kGradientColors[kNumTilesPerSide*kNumTilesPerSide] = {
166*c8dee2aaSAndroid Build Coastguard Worker             { SK_ColorBLACK, SK_ColorGREY, SK_ColorWHITE },
167*c8dee2aaSAndroid Build Coastguard Worker             { SK_ColorBLACK, SK_ColorGREY, SK_ColorWHITE },
168*c8dee2aaSAndroid Build Coastguard Worker             { SK_ColorBLACK, SK_ColorGREY, SK_ColorWHITE },
169*c8dee2aaSAndroid Build Coastguard Worker             { SK_ColorBLACK, SK_ColorGREY, SK_ColorWHITE },
170*c8dee2aaSAndroid Build Coastguard Worker             { 0x00000000,    0x80000000,   0xFF000000    },  // the Gaussian CF uses alpha only
171*c8dee2aaSAndroid Build Coastguard Worker             { SK_ColorBLACK, SK_ColorGREY, SK_ColorWHITE },
172*c8dee2aaSAndroid Build Coastguard Worker             { SK_ColorBLACK, SK_ColorGREY, SK_ColorWHITE },
173*c8dee2aaSAndroid Build Coastguard Worker             { SK_ColorBLACK, SK_ColorGREY, SK_ColorWHITE },
174*c8dee2aaSAndroid Build Coastguard Worker             { SK_ColorBLACK, SK_ColorGREY, SK_ColorWHITE },
175*c8dee2aaSAndroid Build Coastguard Worker     };
176*c8dee2aaSAndroid Build Coastguard Worker 
177*c8dee2aaSAndroid Build Coastguard Worker     colorFilters[0] = SkColorFilters::Lighting(SK_ColorLTGRAY, 0xFF440000);
178*c8dee2aaSAndroid Build Coastguard Worker     colorFilters[1] = SkColorFilters::Table(table1);
179*c8dee2aaSAndroid Build Coastguard Worker     colorFilters[2] = SkColorFilters::Compose(SkColorFilters::TableARGB(nullptr, table3,
180*c8dee2aaSAndroid Build Coastguard Worker                                                                         table3, table3),
181*c8dee2aaSAndroid Build Coastguard Worker                                               SkColorFilters::TableARGB(nullptr, table2,
182*c8dee2aaSAndroid Build Coastguard Worker                                                                         table2, table2));
183*c8dee2aaSAndroid Build Coastguard Worker     colorFilters[3] = SkColorFilters::Blend(SK_ColorGREEN, SkBlendMode::kMultiply);
184*c8dee2aaSAndroid Build Coastguard Worker     colorFilters[4] = SkColorFilterPriv::MakeGaussian();
185*c8dee2aaSAndroid Build Coastguard Worker 
186*c8dee2aaSAndroid Build Coastguard Worker     colorFilters[5] = SkColorFilters::LinearToSRGBGamma();
187*c8dee2aaSAndroid Build Coastguard Worker     colorFilters[6] = SkColorFilters::SRGBToLinearGamma();
188*c8dee2aaSAndroid Build Coastguard Worker 
189*c8dee2aaSAndroid Build Coastguard Worker     SkPaint p;
190*c8dee2aaSAndroid Build Coastguard Worker 
191*c8dee2aaSAndroid Build Coastguard Worker     canvas->save();
192*c8dee2aaSAndroid Build Coastguard Worker         canvas->clipRect(clipRect);
193*c8dee2aaSAndroid Build Coastguard Worker         canvas->translate(clipRect.fLeft, clipRect.fTop);
194*c8dee2aaSAndroid Build Coastguard Worker 
195*c8dee2aaSAndroid Build Coastguard Worker         for (int y = 0; y < kNumTilesPerSide; ++y) {
196*c8dee2aaSAndroid Build Coastguard Worker             for (int x = 0; x < kNumTilesPerSide; ++x) {
197*c8dee2aaSAndroid Build Coastguard Worker                 SkRect r = SkRect::MakeXYWH(x * tileSize.width(), y * tileSize.height(),
198*c8dee2aaSAndroid Build Coastguard Worker                                             tileSize.width(), tileSize.height()).makeInset(1.0f,
199*c8dee2aaSAndroid Build Coastguard Worker                                                                                            1.0f);
200*c8dee2aaSAndroid Build Coastguard Worker                 int colorFilterIndex = x*kNumTilesPerSide+y;
201*c8dee2aaSAndroid Build Coastguard Worker                 p.setShader(create_gradient_shader(r,
202*c8dee2aaSAndroid Build Coastguard Worker                                                    kGradientColors[colorFilterIndex],
203*c8dee2aaSAndroid Build Coastguard Worker                                                    { 0.0f, 0.5f, 1.0f }));
204*c8dee2aaSAndroid Build Coastguard Worker                 p.setColorFilter(colorFilters[colorFilterIndex]);
205*c8dee2aaSAndroid Build Coastguard Worker                 canvas->drawRect(r, p);
206*c8dee2aaSAndroid Build Coastguard Worker             }
207*c8dee2aaSAndroid Build Coastguard Worker         }
208*c8dee2aaSAndroid Build Coastguard Worker 
209*c8dee2aaSAndroid Build Coastguard Worker     canvas->restore();
210*c8dee2aaSAndroid Build Coastguard Worker }
211*c8dee2aaSAndroid Build Coastguard Worker 
draw_blend_mode_swatches(SkCanvas * canvas,SkRect clipRect)212*c8dee2aaSAndroid Build Coastguard Worker void draw_blend_mode_swatches(SkCanvas* canvas, SkRect clipRect) {
213*c8dee2aaSAndroid Build Coastguard Worker     static const int kTileHeight = 16;
214*c8dee2aaSAndroid Build Coastguard Worker     static const int kTileWidth = 16;
215*c8dee2aaSAndroid Build Coastguard Worker     static const SkColor4f kOpaqueWhite { 1.0f, 1.0f, 1.0f, 1.0f };
216*c8dee2aaSAndroid Build Coastguard Worker     static const SkColor4f kTransBluish { 0.0f, 0.5f, 1.0f, 0.5f };
217*c8dee2aaSAndroid Build Coastguard Worker     static const SkColor4f kTransWhite { 1.0f, 1.0f, 1.0f, 0.75f };
218*c8dee2aaSAndroid Build Coastguard Worker 
219*c8dee2aaSAndroid Build Coastguard Worker     SkPaint dstPaint;
220*c8dee2aaSAndroid Build Coastguard Worker     dstPaint.setColor(kOpaqueWhite);
221*c8dee2aaSAndroid Build Coastguard Worker     dstPaint.setBlendMode(SkBlendMode::kSrc);
222*c8dee2aaSAndroid Build Coastguard Worker     dstPaint.setAntiAlias(false);
223*c8dee2aaSAndroid Build Coastguard Worker 
224*c8dee2aaSAndroid Build Coastguard Worker     SkPaint srcPaint;
225*c8dee2aaSAndroid Build Coastguard Worker     srcPaint.setColor(kTransBluish);
226*c8dee2aaSAndroid Build Coastguard Worker     srcPaint.setAntiAlias(false);
227*c8dee2aaSAndroid Build Coastguard Worker 
228*c8dee2aaSAndroid Build Coastguard Worker     SkRect r = SkRect::MakeXYWH(clipRect.fLeft, clipRect.fTop, kTileWidth, kTileHeight);
229*c8dee2aaSAndroid Build Coastguard Worker 
230*c8dee2aaSAndroid Build Coastguard Worker     // For the first pass we draw: transparent bluish on top of opaque white
231*c8dee2aaSAndroid Build Coastguard Worker     // For the second pass we draw: transparent white on top of transparent bluish
232*c8dee2aaSAndroid Build Coastguard Worker     for (int passes = 0; passes < 2; ++passes) {
233*c8dee2aaSAndroid Build Coastguard Worker         for (int i = 0; i <= (int)SkBlendMode::kLastCoeffMode; ++i) {
234*c8dee2aaSAndroid Build Coastguard Worker             if (r.fLeft+kTileWidth > clipRect.fRight) {
235*c8dee2aaSAndroid Build Coastguard Worker                 r.offsetTo(clipRect.fLeft, r.fTop+kTileHeight);
236*c8dee2aaSAndroid Build Coastguard Worker             }
237*c8dee2aaSAndroid Build Coastguard Worker 
238*c8dee2aaSAndroid Build Coastguard Worker             canvas->drawRect(r.makeInset(1.0f, 1.0f), dstPaint);
239*c8dee2aaSAndroid Build Coastguard Worker             srcPaint.setBlendMode(static_cast<SkBlendMode>(i));
240*c8dee2aaSAndroid Build Coastguard Worker             canvas->drawRect(r.makeInset(2.0f, 2.0f), srcPaint);
241*c8dee2aaSAndroid Build Coastguard Worker 
242*c8dee2aaSAndroid Build Coastguard Worker             r.offset(kTileWidth, 0.0f);
243*c8dee2aaSAndroid Build Coastguard Worker         }
244*c8dee2aaSAndroid Build Coastguard Worker 
245*c8dee2aaSAndroid Build Coastguard Worker         r.offsetTo(clipRect.fLeft, r.fTop+kTileHeight);
246*c8dee2aaSAndroid Build Coastguard Worker         srcPaint.setColor(kTransWhite);
247*c8dee2aaSAndroid Build Coastguard Worker         dstPaint.setColor(kTransBluish);
248*c8dee2aaSAndroid Build Coastguard Worker     }
249*c8dee2aaSAndroid Build Coastguard Worker }
250*c8dee2aaSAndroid Build Coastguard Worker 
251*c8dee2aaSAndroid Build Coastguard Worker } // anonymous namespace
252*c8dee2aaSAndroid Build Coastguard Worker 
253*c8dee2aaSAndroid Build Coastguard Worker namespace skiagm {
254*c8dee2aaSAndroid Build Coastguard Worker 
255*c8dee2aaSAndroid Build Coastguard Worker // This is just for bootstrapping Graphite.
256*c8dee2aaSAndroid Build Coastguard Worker class GraphiteStartGM : public GM {
257*c8dee2aaSAndroid Build Coastguard Worker public:
258*c8dee2aaSAndroid Build Coastguard Worker     GraphiteStartGM() = default;
259*c8dee2aaSAndroid Build Coastguard Worker 
260*c8dee2aaSAndroid Build Coastguard Worker protected:
261*c8dee2aaSAndroid Build Coastguard Worker     static constexpr int kTileWidth = 128;
262*c8dee2aaSAndroid Build Coastguard Worker     static constexpr int kTileHeight = 128;
263*c8dee2aaSAndroid Build Coastguard Worker     static constexpr int kWidth = 3 * kTileWidth;
264*c8dee2aaSAndroid Build Coastguard Worker     static constexpr int kHeight = 3 * kTileHeight;
265*c8dee2aaSAndroid Build Coastguard Worker     static constexpr int kClipInset = 4;
266*c8dee2aaSAndroid Build Coastguard Worker 
onOnceBeforeDraw()267*c8dee2aaSAndroid Build Coastguard Worker     void onOnceBeforeDraw() override {
268*c8dee2aaSAndroid Build Coastguard Worker         this->setBGColor(SK_ColorBLACK);
269*c8dee2aaSAndroid Build Coastguard Worker         ToolUtils::GetResourceAsBitmap("images/color_wheel.gif", &fBitmap);
270*c8dee2aaSAndroid Build Coastguard Worker     }
271*c8dee2aaSAndroid Build Coastguard Worker 
getName() const272*c8dee2aaSAndroid Build Coastguard Worker     SkString getName() const override { return SkString("graphitestart"); }
273*c8dee2aaSAndroid Build Coastguard Worker 
getISize()274*c8dee2aaSAndroid Build Coastguard Worker     SkISize getISize() override { return SkISize::Make(kWidth, kHeight); }
275*c8dee2aaSAndroid Build Coastguard Worker 
onDraw(SkCanvas * canvas)276*c8dee2aaSAndroid Build Coastguard Worker     void onDraw(SkCanvas* canvas) override {
277*c8dee2aaSAndroid Build Coastguard Worker 
278*c8dee2aaSAndroid Build Coastguard Worker         const SkRect clipRect = SkRect::MakeWH(kWidth, kHeight).makeInset(kClipInset, kClipInset);
279*c8dee2aaSAndroid Build Coastguard Worker 
280*c8dee2aaSAndroid Build Coastguard Worker         canvas->save();
281*c8dee2aaSAndroid Build Coastguard Worker         canvas->clipRRect(SkRRect::MakeRectXY(clipRect, 32.f, 32.f), true);
282*c8dee2aaSAndroid Build Coastguard Worker 
283*c8dee2aaSAndroid Build Coastguard Worker         // Upper-left corner
284*c8dee2aaSAndroid Build Coastguard Worker         draw_image_shader_tile(canvas, SkRect::MakeXYWH(0, 0, kTileWidth, kTileHeight));
285*c8dee2aaSAndroid Build Coastguard Worker 
286*c8dee2aaSAndroid Build Coastguard Worker         // Upper-middle tile
287*c8dee2aaSAndroid Build Coastguard Worker         draw_gradient_tile(canvas, SkRect::MakeXYWH(kTileWidth, 0, kTileWidth, kTileHeight));
288*c8dee2aaSAndroid Build Coastguard Worker 
289*c8dee2aaSAndroid Build Coastguard Worker         // Upper-right corner
290*c8dee2aaSAndroid Build Coastguard Worker         draw_colorfilter_swatches(canvas, SkRect::MakeXYWH(2*kTileWidth, 0,
291*c8dee2aaSAndroid Build Coastguard Worker                                                            kTileWidth, kTileWidth));
292*c8dee2aaSAndroid Build Coastguard Worker 
293*c8dee2aaSAndroid Build Coastguard Worker         // Middle-left tile
294*c8dee2aaSAndroid Build Coastguard Worker         {
295*c8dee2aaSAndroid Build Coastguard Worker             SkPaint p;
296*c8dee2aaSAndroid Build Coastguard Worker             p.setColor(SK_ColorRED);
297*c8dee2aaSAndroid Build Coastguard Worker 
298*c8dee2aaSAndroid Build Coastguard Worker             SkRect r = SkRect::MakeXYWH(0, kTileHeight, kTileWidth, kTileHeight);
299*c8dee2aaSAndroid Build Coastguard Worker             canvas->drawRect(r.makeInset(1.0f, 1.0f), p);
300*c8dee2aaSAndroid Build Coastguard Worker         }
301*c8dee2aaSAndroid Build Coastguard Worker 
302*c8dee2aaSAndroid Build Coastguard Worker         // Middle-middle tile
303*c8dee2aaSAndroid Build Coastguard Worker         {
304*c8dee2aaSAndroid Build Coastguard Worker             SkPaint p;
305*c8dee2aaSAndroid Build Coastguard Worker             p.setShader(create_blend_shader(canvas, SkBlendMode::kModulate));
306*c8dee2aaSAndroid Build Coastguard Worker 
307*c8dee2aaSAndroid Build Coastguard Worker             SkRect r = SkRect::MakeXYWH(kTileWidth, kTileHeight, kTileWidth, kTileHeight);
308*c8dee2aaSAndroid Build Coastguard Worker             canvas->drawRect(r.makeInset(1.0f, 1.0f), p);
309*c8dee2aaSAndroid Build Coastguard Worker         }
310*c8dee2aaSAndroid Build Coastguard Worker 
311*c8dee2aaSAndroid Build Coastguard Worker         // Middle-right tile
312*c8dee2aaSAndroid Build Coastguard Worker         {
313*c8dee2aaSAndroid Build Coastguard Worker             sk_sp<SkImage> image(ToolUtils::GetResourceAsImage("images/mandrill_128.png"));
314*c8dee2aaSAndroid Build Coastguard Worker             sk_sp<SkShader> shader;
315*c8dee2aaSAndroid Build Coastguard Worker 
316*c8dee2aaSAndroid Build Coastguard Worker             if (image) {
317*c8dee2aaSAndroid Build Coastguard Worker                 shader = image->makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat, {});
318*c8dee2aaSAndroid Build Coastguard Worker                 shader = shader->makeWithColorFilter(create_grayscale_colorfilter());
319*c8dee2aaSAndroid Build Coastguard Worker             }
320*c8dee2aaSAndroid Build Coastguard Worker 
321*c8dee2aaSAndroid Build Coastguard Worker             SkPaint p;
322*c8dee2aaSAndroid Build Coastguard Worker             p.setShader(std::move(shader));
323*c8dee2aaSAndroid Build Coastguard Worker 
324*c8dee2aaSAndroid Build Coastguard Worker             SkRect r = SkRect::MakeXYWH(2*kTileWidth, kTileHeight, kTileWidth, kTileHeight);
325*c8dee2aaSAndroid Build Coastguard Worker             canvas->drawRect(r.makeInset(1.0f, 1.0f), p);
326*c8dee2aaSAndroid Build Coastguard Worker         }
327*c8dee2aaSAndroid Build Coastguard Worker 
328*c8dee2aaSAndroid Build Coastguard Worker         canvas->restore();
329*c8dee2aaSAndroid Build Coastguard Worker 
330*c8dee2aaSAndroid Build Coastguard Worker         // Bottom-left corner
331*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_GRAPHITE)
332*c8dee2aaSAndroid Build Coastguard Worker         // TODO: failing serialize test on Linux, not sure what's going on
333*c8dee2aaSAndroid Build Coastguard Worker         canvas->writePixels(fBitmap, 0, 2*kTileHeight);
334*c8dee2aaSAndroid Build Coastguard Worker #endif
335*c8dee2aaSAndroid Build Coastguard Worker 
336*c8dee2aaSAndroid Build Coastguard Worker         // Bottom-middle tile
337*c8dee2aaSAndroid Build Coastguard Worker         draw_blend_mode_swatches(canvas, SkRect::MakeXYWH(kTileWidth, 2*kTileHeight,
338*c8dee2aaSAndroid Build Coastguard Worker                                                           kTileWidth, kTileHeight));
339*c8dee2aaSAndroid Build Coastguard Worker 
340*c8dee2aaSAndroid Build Coastguard Worker         // Bottom-right corner
341*c8dee2aaSAndroid Build Coastguard Worker         {
342*c8dee2aaSAndroid Build Coastguard Worker             const SkRect kTile = SkRect::MakeXYWH(2*kTileWidth, 2*kTileHeight,
343*c8dee2aaSAndroid Build Coastguard Worker                                                   kTileWidth, kTileHeight);
344*c8dee2aaSAndroid Build Coastguard Worker 
345*c8dee2aaSAndroid Build Coastguard Worker             SkPaint circlePaint;
346*c8dee2aaSAndroid Build Coastguard Worker             circlePaint.setColor(SK_ColorBLUE);
347*c8dee2aaSAndroid Build Coastguard Worker             circlePaint.setBlendMode(SkBlendMode::kSrc);
348*c8dee2aaSAndroid Build Coastguard Worker 
349*c8dee2aaSAndroid Build Coastguard Worker             canvas->clipRect(kTile);
350*c8dee2aaSAndroid Build Coastguard Worker             canvas->drawRect(kTile.makeInset(10, 20), circlePaint);
351*c8dee2aaSAndroid Build Coastguard Worker 
352*c8dee2aaSAndroid Build Coastguard Worker             SkPaint restorePaint;
353*c8dee2aaSAndroid Build Coastguard Worker             restorePaint.setBlendMode(SkBlendMode::kPlus);
354*c8dee2aaSAndroid Build Coastguard Worker 
355*c8dee2aaSAndroid Build Coastguard Worker             canvas->saveLayer(nullptr, &restorePaint);
356*c8dee2aaSAndroid Build Coastguard Worker                 circlePaint.setColor(SK_ColorRED);
357*c8dee2aaSAndroid Build Coastguard Worker                 circlePaint.setBlendMode(SkBlendMode::kSrc);
358*c8dee2aaSAndroid Build Coastguard Worker 
359*c8dee2aaSAndroid Build Coastguard Worker                 canvas->drawRect(kTile.makeInset(15, 25), circlePaint);
360*c8dee2aaSAndroid Build Coastguard Worker             canvas->restore();
361*c8dee2aaSAndroid Build Coastguard Worker         }
362*c8dee2aaSAndroid Build Coastguard Worker     }
363*c8dee2aaSAndroid Build Coastguard Worker 
364*c8dee2aaSAndroid Build Coastguard Worker private:
365*c8dee2aaSAndroid Build Coastguard Worker     SkBitmap fBitmap;
366*c8dee2aaSAndroid Build Coastguard Worker };
367*c8dee2aaSAndroid Build Coastguard Worker 
368*c8dee2aaSAndroid Build Coastguard Worker //////////////////////////////////////////////////////////////////////////////
369*c8dee2aaSAndroid Build Coastguard Worker 
370*c8dee2aaSAndroid Build Coastguard Worker DEF_GM(return new GraphiteStartGM;)
371*c8dee2aaSAndroid Build Coastguard Worker 
372*c8dee2aaSAndroid Build Coastguard Worker }  // namespace skiagm
373