Move all non-AA fill rect ops off of GrLegacyMeshDrawOp.
[platform/upstream/libSkiaSharp.git] / gm / all_bitmap_configs.cpp
1 /*
2  * Copyright 2015 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 "SkSurface.h"
9 #include "Resources.h"
10 #include "gm.h"
11 #include "sk_tool_utils.h"
12
13 #include "SkMath.h"
14 #include "SkColorPriv.h"
15
16 static SkBitmap copy_bitmap(const SkBitmap& src, SkColorType colorType) {
17     const SkBitmap* srcPtr = &src;
18     SkBitmap tmp(src);
19     if (kRGB_565_SkColorType == colorType) {
20         tmp.setAlphaType(kOpaque_SkAlphaType);
21         srcPtr = &tmp;
22     }
23
24     SkBitmap copy;
25     sk_tool_utils::copy_to(&copy, colorType, *srcPtr);
26     copy.setImmutable();
27     return copy;
28 }
29
30 #define SCALE 128
31
32 // Make either A8 or gray8 bitmap.
33 static SkBitmap make_bitmap(SkColorType ct) {
34     SkBitmap bm;
35     switch (ct) {
36         case kAlpha_8_SkColorType:
37             bm.allocPixels(SkImageInfo::MakeA8(SCALE, SCALE));
38             break;
39         case kGray_8_SkColorType:
40             bm.allocPixels(
41                     SkImageInfo::Make(SCALE, SCALE, ct, kOpaque_SkAlphaType));
42             break;
43         default:
44             SkASSERT(false);
45             return bm;
46     }
47     uint8_t spectrum[256];
48     for (int y = 0; y < 256; ++y) {
49         spectrum[y] = y;
50     }
51     for (int y = 0; y < 128; ++y) {
52         // Shift over one byte each scanline.
53         memcpy(bm.getAddr8(0, y), &spectrum[y], 128);
54     }
55     bm.setImmutable();
56     return bm;
57 }
58
59 static void draw_center_letter(char c,
60                                SkPaint* p,
61                                SkColor color,
62                                SkScalar x,
63                                SkScalar y,
64                                SkCanvas* canvas) {
65     SkRect bounds;
66     p->setColor(color);
67     p->measureText(&c, 1, &bounds);
68     canvas->drawText(&c, 1, x - bounds.centerX(), y - bounds.centerY(), *p);
69 }
70
71 static void color_wheel_native(SkCanvas* canvas) {
72     SkAutoCanvasRestore autoCanvasRestore(canvas, true);
73     canvas->translate(0.5f * SCALE, 0.5f * SCALE);
74     SkPaint p;
75     p.setAntiAlias(false);
76     p.setColor(SK_ColorWHITE);
77     canvas->drawCircle(0.0f, 0.0f, SCALE * 0.5f, p);
78
79     const double sqrt_3_over_2 = 0.8660254037844387;
80     const SkScalar Z = 0.0f;
81     const SkScalar D = 0.3f * SkIntToScalar(SCALE);
82     const SkScalar X = SkDoubleToScalar(D * sqrt_3_over_2);
83     const SkScalar Y = D * SK_ScalarHalf;
84     sk_tool_utils::set_portable_typeface(&p, nullptr, SkFontStyle::FromOldStyle(SkTypeface::kBold));
85     p.setTextSize(0.28125f * SCALE);
86     draw_center_letter('K', &p, SK_ColorBLACK, Z, Z, canvas);
87     draw_center_letter('R', &p, SK_ColorRED, Z, D, canvas);
88     draw_center_letter('G', &p, SK_ColorGREEN, -X, -Y, canvas);
89     draw_center_letter('B', &p, SK_ColorBLUE, X, -Y, canvas);
90     draw_center_letter('C', &p, SK_ColorCYAN, Z, -D, canvas);
91     draw_center_letter('M', &p, SK_ColorMAGENTA, X, Y, canvas);
92     draw_center_letter('Y', &p, SK_ColorYELLOW, -X, Y, canvas);
93 }
94
95 template <typename T>
96 int find(T* array, int N, T item) {
97     for (int i = 0; i < N; ++i) {
98         if (array[i] == item) {
99             return i;
100         }
101     }
102     return -1;
103 }
104
105 static SkPMColor premultiply_color(SkColor c) {
106     return SkPremultiplyARGBInline(SkColorGetA(c), SkColorGetR(c),
107                                    SkColorGetG(c), SkColorGetB(c));
108 }
109
110 static SkBitmap indexed_bitmap() {
111     SkBitmap n32bitmap;
112     n32bitmap.allocN32Pixels(SCALE, SCALE);
113     n32bitmap.eraseColor(SK_ColorTRANSPARENT);
114
115     SkCanvas canvas(n32bitmap);
116     color_wheel_native(&canvas);
117     const SkColor colors[] = {
118             SK_ColorTRANSPARENT,
119             SK_ColorWHITE,
120             SK_ColorBLACK,
121             SK_ColorRED,
122             SK_ColorGREEN,
123             SK_ColorBLUE,
124             SK_ColorCYAN,
125             SK_ColorMAGENTA,
126             SK_ColorYELLOW,
127     };
128     SkPMColor pmColors[SK_ARRAY_COUNT(colors)];
129     for (size_t i = 0; i < SK_ARRAY_COUNT(colors); ++i) {
130         pmColors[i] = premultiply_color(colors[i]);
131     }
132     SkBitmap bm;
133     SkImageInfo info = SkImageInfo::Make(SCALE, SCALE, kIndex_8_SkColorType,
134                                          kPremul_SkAlphaType);
135     bm.allocPixels(info, SkColorTable::Make(pmColors, SK_ARRAY_COUNT(pmColors)));
136     for (int y = 0; y < SCALE; ++y) {
137         for (int x = 0; x < SCALE; ++x) {
138             SkPMColor c = *n32bitmap.getAddr32(x, y);
139             int idx = find(pmColors, SK_ARRAY_COUNT(pmColors), c);
140             *bm.getAddr8(x, y) = SkClampMax(idx, SK_ARRAY_COUNT(pmColors) - 1);
141         }
142     }
143     return bm;
144 }
145
146 static void draw(SkCanvas* canvas,
147                  const SkPaint& p,
148                  const SkBitmap& src,
149                  SkColorType colorType,
150                  const char text[]) {
151     SkASSERT(src.colorType() == colorType);
152     canvas->drawBitmap(src, 0.0f, 0.0f);
153     canvas->drawString(text, 0.0f, 12.0f, p);
154 }
155
156 DEF_SIMPLE_GM(all_bitmap_configs, canvas, SCALE, 6 * SCALE) {
157     SkAutoCanvasRestore autoCanvasRestore(canvas, true);
158     SkPaint p;
159     p.setColor(SK_ColorBLACK);
160     p.setAntiAlias(true);
161     sk_tool_utils::set_portable_typeface(&p, nullptr);
162
163     sk_tool_utils::draw_checkerboard(canvas, SK_ColorLTGRAY, SK_ColorWHITE, 8);
164
165     SkBitmap bitmap;
166     if (GetResourceAsBitmap("color_wheel.png", &bitmap)) {
167         bitmap.setImmutable();
168         draw(canvas, p, bitmap, kN32_SkColorType, "Native 32");
169
170         canvas->translate(0.0f, SkIntToScalar(SCALE));
171         SkBitmap copy565 = copy_bitmap(bitmap, kRGB_565_SkColorType);
172         p.setColor(SK_ColorRED);
173         draw(canvas, p, copy565, kRGB_565_SkColorType, "RGB 565");
174         p.setColor(SK_ColorBLACK);
175
176         canvas->translate(0.0f, SkIntToScalar(SCALE));
177         SkBitmap copy4444 = copy_bitmap(bitmap, kARGB_4444_SkColorType);
178         draw(canvas, p, copy4444, kARGB_4444_SkColorType, "ARGB 4444");
179     } else {
180         canvas->translate(0.0f, SkIntToScalar(2 * SCALE));
181     }
182
183     canvas->translate(0.0f, SkIntToScalar(SCALE));
184     SkBitmap bitmapIndexed = indexed_bitmap();
185     draw(canvas, p, bitmapIndexed, kIndex_8_SkColorType, "Index 8");
186
187     canvas->translate(0.0f, SkIntToScalar(SCALE));
188     SkBitmap bitmapA8 = make_bitmap(kAlpha_8_SkColorType);
189     draw(canvas, p, bitmapA8, kAlpha_8_SkColorType, "Alpha 8");
190
191     p.setColor(SK_ColorRED);
192     canvas->translate(0.0f, SkIntToScalar(SCALE));
193     SkBitmap bitmapG8 = make_bitmap(kGray_8_SkColorType);
194     draw(canvas, p, bitmapG8, kGray_8_SkColorType, "Gray 8");
195 }
196
197 sk_sp<SkImage> make_not_native32_color_wheel() {
198     SkBitmap n32bitmap, notN32bitmap;
199     n32bitmap.allocN32Pixels(SCALE, SCALE);
200     n32bitmap.eraseColor(SK_ColorTRANSPARENT);
201     SkCanvas n32canvas(n32bitmap);
202     color_wheel_native(&n32canvas);
203     n32canvas.flush();
204     #if SK_PMCOLOR_BYTE_ORDER(B,G,R,A)
205         const SkColorType ct = kRGBA_8888_SkColorType;
206     #elif SK_PMCOLOR_BYTE_ORDER(R,G,B,A)
207         const SkColorType ct = kBGRA_8888_SkColorType;
208     #endif
209     static_assert(ct != kN32_SkColorType, "BRGA!=RGBA");
210     SkAssertResult(sk_tool_utils::copy_to(&notN32bitmap, ct, n32bitmap));
211     SkASSERT(notN32bitmap.colorType() == ct);
212     return SkImage::MakeFromBitmap(notN32bitmap);
213 }
214
215 DEF_SIMPLE_GM(not_native32_bitmap_config, canvas, SCALE, SCALE) {
216     sk_sp<SkImage> notN32image(make_not_native32_color_wheel());
217     SkASSERT(notN32image);
218     sk_tool_utils::draw_checkerboard(canvas, SK_ColorLTGRAY, SK_ColorWHITE, 8);
219     canvas->drawImage(notN32image.get(), 0.0f, 0.0f);
220 }
221
222 static uint32_t make_pixel(int x, int y, SkAlphaType alphaType) {
223     SkASSERT(x >= 0 && x < SCALE);
224     SkASSERT(y >= 0 && y < SCALE);
225
226     SkScalar R = SCALE / 2.0f;
227
228     uint32_t alpha = 0x00;
229
230     if ((x - R) * (x - R) + (y - R) * (y - R) < R * R) {
231         alpha = 0xFF;
232     }
233
234     uint32_t component;
235     switch (alphaType) {
236         case kPremul_SkAlphaType:
237             component = alpha;
238             break;
239         case kUnpremul_SkAlphaType:
240             component = 0xFF;
241             break;
242         default:
243             SkFAIL("Should not get here - invalid alpha type");
244             return 0xFF000000;
245     }
246     return alpha << 24 | component;
247 }
248
249 static void make_color_test_bitmap_variant(
250     SkColorType colorType,
251     SkAlphaType alphaType,
252     sk_sp<SkColorSpace> colorSpace,
253     SkBitmap* bm)
254 {
255     SkASSERT(colorType == kRGBA_8888_SkColorType || colorType == kBGRA_8888_SkColorType);
256     SkASSERT(alphaType == kPremul_SkAlphaType || alphaType == kUnpremul_SkAlphaType);
257     bm->allocPixels(
258         SkImageInfo::Make(SCALE, SCALE, colorType, alphaType, colorSpace));
259     SkPixmap pm;
260     bm->peekPixels(&pm);
261     for (int y = 0; y < bm->height(); y++) {
262         for (int x = 0; x < bm->width(); x++) {
263             *pm.writable_addr32(x, y) = make_pixel(x, y, alphaType);
264         }
265     }
266 }
267
268 DEF_SIMPLE_GM(all_variants_8888, canvas, 4 * SCALE + 30, 2 * SCALE + 10) {
269     sk_tool_utils::draw_checkerboard(canvas, SK_ColorLTGRAY, SK_ColorWHITE, 8);
270
271     sk_sp<SkColorSpace> colorSpaces[] {
272         SkColorSpace::MakeSRGB(),
273         nullptr,
274     };
275     for (auto colorSpace : colorSpaces) {
276         canvas->save();
277         for (auto alphaType : {kPremul_SkAlphaType, kUnpremul_SkAlphaType}) {
278             canvas->save();
279             for (auto colorType : {kRGBA_8888_SkColorType, kBGRA_8888_SkColorType}) {
280                 SkBitmap bm;
281                 make_color_test_bitmap_variant(colorType, alphaType, colorSpace, &bm);
282                 canvas->drawBitmap(bm, 0.0f, 0.0f);
283                 canvas->translate(SCALE + 10, 0.0f);
284             }
285             canvas->restore();
286             canvas->translate(0.0f, SCALE + 10);
287         }
288         canvas->restore();
289         canvas->translate(2 * (SCALE + 10), 0.0f);
290     }
291 }