Add fixes & test for isConfigTexturable and isConfigRenderable
[platform/upstream/libSkiaSharp.git] / gm / gaussianedge.cpp
1 /*
2  * Copyright 2016 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 "SkColorFilter.h"
10 #include "SkGaussianEdgeShader.h"
11 #include "SkRRect.h"
12
13 //#define VIZ 1
14
15 #ifdef VIZ
16 #include "SkStroke.h"
17
18 static void draw_stroke(SkCanvas* canvas, const SkRRect& rr, const SkPaint& p, SkColor color) {
19     SkPath output;
20
21     if (SkPaint::kFill_Style == p.getStyle()) {
22         output.addRRect(rr);
23     } else {
24         SkPath input;
25         input.addRRect(rr);
26
27         SkStroke stroke(p);
28         stroke.strokePath(input, &output);
29     }
30
31     SkPaint paint;
32     paint.setStyle(SkPaint::kStroke_Style);
33     paint.setColor(color);
34
35     canvas->drawPath(output, paint);
36 }
37
38 static void extract_pts(const SkBitmap& bm, SkTDArray<SkPoint>* pts,
39                         int xOff, int width) {
40     pts->rewind();
41
42     for (int x = 0; x < width; ++x) {
43         SkColor color = bm.getColor(xOff+x, 0);    
44
45         pts->append()->set(SkIntToScalar(x), 255.0f-SkColorGetB(color));
46         if (x > 0 && x < width-1) {
47             pts->append()->set(SkIntToScalar(x), 255.0f-SkColorGetB(color));
48         }
49     }
50 }
51
52 static void draw_row(SkCanvas* canvas, int row, int width) {
53     SkPaint paint;
54     paint.setAntiAlias(true);
55
56     SkBitmap readback;
57
58     if (!canvas->readPixels(SkIRect::MakeXYWH(0, row, width, 1), &readback)) {
59         return;
60     }
61
62     SkTDArray<SkPoint> pts;
63     pts.setReserve(width/3);
64
65     extract_pts(readback, &pts, 0, width/3);
66     paint.setColor(SK_ColorRED);
67     canvas->drawPoints(SkCanvas::kLines_PointMode, pts.count(), pts.begin(), paint);
68
69     extract_pts(readback, &pts, width/3, width/3);
70     paint.setColor(SK_ColorGREEN);
71     canvas->drawPoints(SkCanvas::kLines_PointMode, pts.count(), pts.begin(), paint);
72
73     extract_pts(readback, &pts, 2*width/3, width/3);
74     paint.setColor(SK_ColorBLUE);
75     canvas->drawPoints(SkCanvas::kLines_PointMode, pts.count(), pts.begin(), paint);
76 }
77 #endif
78
79 namespace skiagm {
80
81 // This GM exercises the SkGaussianEdgeShader.
82 // It draws three columns showing filled, stroked, and stroke and filled rendering.
83 // It draws three rows showing a blur radius smaller than, equal to
84 // and, finally, double the RRect's corner radius
85 // In VIZ mode an extra column is drawn showing the blur ramps (they should all line up).
86 class GaussianEdgeGM : public GM {
87 public:
88     GaussianEdgeGM() {
89         this->setBGColor(SK_ColorWHITE);
90     }
91
92 protected:
93
94     SkString onShortName() override {
95         return SkString("gaussianedge");
96     }
97
98     SkISize onISize() override {
99         int numCols = kNumBaseCols;
100 #ifdef VIZ
101         numCols++;
102 #endif
103
104         return SkISize::Make(kPad + numCols*(kCellWidth+kPad),
105                              kPad + kNumRows*(kCellWidth+kPad));
106     }
107
108     static void DrawRow(SkCanvas* canvas, int blurRad, int midLine) {
109         SkAutoCanvasRestore acr(canvas, true);
110
111         SkRRect rrects[kNumBaseCols];
112         SkPaint paints[kNumBaseCols];
113
114         {
115             const SkRect r = SkRect::MakeIWH(kRRSize, kRRSize);
116             const SkRRect baseRR = SkRRect::MakeRectXY(r,
117                                                        SkIntToScalar(kRRRad),
118                                                        SkIntToScalar(kRRRad));
119
120             SkPaint basePaint;
121             basePaint.setAntiAlias(true);
122             basePaint.setColor(SkColorSetARGB(255, (4 * blurRad) >> 8, (4 * blurRad) & 0xff, 0));
123             basePaint.setShader(SkGaussianEdgeShader::Make());
124             basePaint.setColorFilter(SkColorFilter::MakeModeFilter(SK_ColorRED,
125                                                                    SkBlendMode::kModulate));
126
127             //----
128             paints[0] = basePaint;
129             rrects[0] = baseRR;
130
131             //----
132             paints[1] = basePaint;
133             paints[1].setStyle(SkPaint::kStroke_Style);
134
135             rrects[1] = baseRR;
136             if (blurRad/2.0f < kRRRad) {
137                 rrects[1].inset(blurRad/2.0f, blurRad/2.0f);
138                 paints[1].setStrokeWidth(SkIntToScalar(blurRad));
139             } else {
140                 SkScalar inset = kRRRad - 0.5f;
141                 rrects[1].inset(inset, inset);
142                 SkScalar pad = blurRad/2.0f - inset;
143                 paints[1].setStrokeWidth(blurRad + 2.0f * pad);                
144                 paints[1].setColor(SkColorSetARGB(255, (4 * blurRad) >> 8, (4 * blurRad) & 0xff,
145                                                   (int)(4.0f*pad)));
146             }
147
148             //----
149             paints[2] = basePaint;
150             paints[2].setStyle(SkPaint::kStrokeAndFill_Style);
151
152             rrects[2] = baseRR;
153             if (blurRad/2.0f < kRRRad) {
154                 rrects[2].inset(blurRad/2.0f, blurRad/2.0f);
155                 paints[2].setStrokeWidth(SkIntToScalar(blurRad));
156             } else {
157                 SkScalar inset = kRRRad - 0.5f;
158                 rrects[2].inset(inset, inset);
159                 SkScalar pad = blurRad/2.0f - inset;
160                 paints[2].setStrokeWidth(blurRad + 2.0f * pad);                
161                 paints[2].setColor(SkColorSetARGB(255, (4 * blurRad) >> 8, (4 * blurRad) & 0xff,
162                                                   (int)(4.0f*pad)));
163             }
164         }
165
166         //----
167         canvas->save();
168             // draw the shadows
169             for (int i = 0; i < kNumBaseCols; ++i) {
170                 canvas->drawRRect(rrects[i], paints[i]);
171                 canvas->translate(SkIntToScalar(kCellWidth+kPad), 0.0f);
172             }
173
174 #ifdef VIZ
175             // draw the visualization of the shadow ramps
176             draw_row(canvas, midLine, 3*(kRRSize+kPad));
177 #endif
178         canvas->restore();
179
180 #ifdef VIZ
181         const SkColor colors[kNumBaseCols] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE };
182
183         // circle back and draw the stroked geometry (they would mess up the viz otherwise)
184         for (int i = 0; i < kNumBaseCols; ++i) {
185             draw_stroke(canvas, rrects[i], paints[i], colors[i]);
186             canvas->translate(SkIntToScalar(kCellWidth+kPad), 0.0f);
187         }
188 #endif
189     }
190
191     void onDraw(SkCanvas* canvas) override {
192         GrRenderTargetContext* renderTargetContext =
193             canvas->internal_private_accessTopLayerRenderTargetContext();
194         if (!renderTargetContext) {
195             skiagm::GM::DrawGpuOnlyMessage(canvas);
196             return;
197         }
198
199         const int blurRadii[kNumRows] = { kRRRad/2, kRRRad, 2*kRRRad };
200
201         canvas->translate(SkIntToScalar(kPad), SkIntToScalar(kPad));
202         for (int i = 0; i < kNumRows; ++i) {
203             DrawRow(canvas, blurRadii[i], kPad+(i*kRRSize)+kRRSize/2);
204             canvas->translate(0.0f, SkIntToScalar(kCellWidth+kPad));
205         }
206     }
207
208 private:
209     static const int kNumRows = 3;
210     static const int kNumBaseCols = 3;
211     static const int kPad = 5;
212     static const int kRRSize = 256;
213     static const int kRRRad = 64;
214     static const int kCellWidth = kRRSize;
215
216     typedef GM INHERITED;
217 };
218
219 //////////////////////////////////////////////////////////////////////////////
220
221 DEF_GM(return new GaussianEdgeGM;)
222 }