OLD | NEW |
| (Empty) |
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 "SkCanvas.h" | |
10 #include "SkImageInfo.h" | |
11 #include "SkXfermode.h" | |
12 #include "SkPM4f.h" | |
13 | |
14 static void draw_rect(SkCanvas* canvas, const SkRect& r, SkColor c, SkColorProfi
leType profile, | |
15 const SkAlpha aa[]) { | |
16 const SkIRect ir = r.round(); | |
17 | |
18 SkBitmap bm; | |
19 bm.allocN32Pixels(ir.width(), ir.height()); | |
20 bm.eraseColor(0xFFFFFFFF); | |
21 SkPixmap pm; | |
22 bm.peekPixels(&pm); | |
23 | |
24 uint32_t flags = 0; | |
25 if (SkColorGetA(c) == 0xFF) { | |
26 flags |= SkXfermode::kSrcIsOpaque_PM4fFlag; | |
27 } | |
28 if (kSRGB_SkColorProfileType == profile) { | |
29 flags |= SkXfermode::kDstIsSRGB_PM4fFlag; | |
30 } | |
31 | |
32 const SkXfermode::PM4fState state { nullptr, flags }; | |
33 | |
34 const SkPM4f src = SkColor4f::FromColor(c).premul(); | |
35 auto proc1 = SkXfermode::GetPM4fProc1(SkXfermode::kSrcOver_Mode, flags); | |
36 for (int y = 0; y < ir.height()/2; ++y) { | |
37 proc1(state, pm.writable_addr32(0, y), src, ir.width(), aa); | |
38 } | |
39 | |
40 SkPM4f srcRow[1000]; | |
41 for (int i = 0; i < ir.width(); ++i) { | |
42 srcRow[i] = src; | |
43 } | |
44 auto procN = SkXfermode::GetPM4fProcN(SkXfermode::kSrcOver_Mode, flags); | |
45 // +1 to skip a row, so we can see the boundary between proc1 and procN | |
46 for (int y = ir.height()/2 + 1; y < ir.height(); ++y) { | |
47 procN(state, pm.writable_addr32(0, y), srcRow, ir.width(), aa); | |
48 } | |
49 | |
50 canvas->drawBitmap(bm, r.left(), r.top(), nullptr); | |
51 } | |
52 | |
53 /* | |
54 * Test SkXfer4fProcs directly for src-over, comparing them to current SkColor
blits. | |
55 */ | |
56 DEF_SIMPLE_GM(xfer4f_srcover, canvas, 580, 760) { | |
57 const int IW = 50; | |
58 const SkScalar W = IW; | |
59 const SkScalar H = 100; | |
60 | |
61 const int profiles[] = { | |
62 -1, | |
63 kLinear_SkColorProfileType, | |
64 kSRGB_SkColorProfileType, | |
65 }; | |
66 const SkColor colors[] = { | |
67 SK_ColorBLACK, SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, | |
68 0x88000000, 0x88FF0000, 0x8800FF00, 0x880000FF | |
69 }; | |
70 | |
71 uint8_t aa_scanline[IW]; | |
72 for (int i = 0; i < IW; ++i) { | |
73 aa_scanline[i] = i * 255 / (IW - 1); | |
74 } | |
75 uint8_t const* aa_table[] = { nullptr, aa_scanline }; | |
76 | |
77 SkBitmap mask; | |
78 mask.installPixels(SkImageInfo::MakeA8(IW, 1), aa_scanline, IW); | |
79 | |
80 canvas->translate(20, 20); | |
81 | |
82 const SkRect r = SkRect::MakeWH(W, H); | |
83 for (const uint8_t* aa : aa_table) { | |
84 canvas->save(); | |
85 for (auto profile : profiles) { | |
86 canvas->save(); | |
87 for (SkColor c : colors) { | |
88 if (profile < 0) { | |
89 SkPaint p; | |
90 p.setColor(c); | |
91 if (aa) { | |
92 canvas->drawBitmapRect(mask, r, &p); | |
93 } else { | |
94 canvas->drawRect(r, p); | |
95 } | |
96 } else { | |
97 draw_rect(canvas, r, c, (SkColorProfileType)profile, aa); | |
98 } | |
99 canvas->translate(W + 20, 0); | |
100 } | |
101 canvas->restore(); | |
102 canvas->translate(0, H + 20); | |
103 } | |
104 canvas->restore(); | |
105 canvas->translate(0, (H + 20) * SK_ARRAY_COUNT(profiles) + 20); | |
106 } | |
107 } | |
OLD | NEW |